1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use crate::prelude::*;
use crate::{BBHFactory, Canvas, Drawable, Picture, Rect};
use skia_bindings as sb;
use skia_bindings::{SkPictureRecorder, SkRect};
use std::ptr;

bitflags! {
    pub struct RecordFlags: u32 {
        const PLAYBACK_DRAW_PICTURE = sb::SkPictureRecorder_RecordFlags_kPlaybackDrawPicture_RecordFlag as _;
    }
}

pub type PictureRecorder = Handle<SkPictureRecorder>;

impl NativeDrop for SkPictureRecorder {
    fn drop(&mut self) {
        unsafe {
            sb::C_SkPictureRecorder_destruct(self);
        }
    }
}

// TODO: why is the word "recording" used in all the functions, should we
// remove it?

impl Handle<SkPictureRecorder> {
    pub fn new() -> Self {
        Self::from_native(unsafe { SkPictureRecorder::new() })
    }

    pub fn begin_recording(
        &mut self,
        bounds: impl AsRef<Rect>,
        mut bbh_factory: Option<&mut BBHFactory>,
        record_flags: impl Into<Option<RecordFlags>>,
    ) -> &mut Canvas {
        let canvas_ref = unsafe {
            &mut *self.native_mut().beginRecording(
                bounds.as_ref().native(),
                bbh_factory.native_ptr_or_null_mut(),
                record_flags
                    .into()
                    .unwrap_or_else(RecordFlags::empty)
                    .bits(),
            )
        };

        Canvas::borrow_from_native(canvas_ref)
    }

    pub fn recording_canvas(&mut self) -> &mut Canvas {
        let canvas_ref = unsafe { &mut *self.native_mut().getRecordingCanvas() };

        Canvas::borrow_from_native(canvas_ref)
    }

    pub fn finish_recording_as_picture(&mut self, cull_rect: Option<&Rect>) -> Option<Picture> {
        let cull_rect_ptr: *const SkRect =
            cull_rect.map(|r| r.native() as _).unwrap_or(ptr::null());

        let picture_ptr = unsafe {
            sb::C_SkPictureRecorder_finishRecordingAsPicture(self.native_mut(), cull_rect_ptr)
        };

        Picture::from_ptr(picture_ptr)
    }

    pub fn finish_recording_as_drawable(&mut self) -> Option<Drawable> {
        Drawable::from_ptr(unsafe {
            sb::C_SkPictureRecorder_finishRecordingAsDrawable(self.native_mut())
        })
    }
}