skia_safe/core/
drawable.rs

1use std::fmt;
2
3use skia_bindings::{self as sb, SkDrawable, SkFlattenable, SkRefCntBase};
4
5use crate::{prelude::*, Canvas, Matrix, NativeFlattenable, Picture, Point, Rect};
6
7pub type Drawable = RCHandle<SkDrawable>;
8
9impl NativeRefCountedBase for SkDrawable {
10    type Base = SkRefCntBase;
11}
12
13impl NativeFlattenable for SkDrawable {
14    fn native_flattenable(&self) -> &SkFlattenable {
15        unsafe { &*(self as *const SkDrawable as *const SkFlattenable) }
16    }
17
18    fn native_deserialize(data: &[u8]) -> *mut Self {
19        unsafe { sb::C_SkDrawable_Deserialize(data.as_ptr() as _, data.len()) }
20    }
21}
22
23impl fmt::Debug for Drawable {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        f.debug_struct("Drawable")
26            // TODO: clarify why &self has to be mut here.
27            // .field("generation_id", &self.generation_id())
28            // .field("bounds", &self.bounds())
29            .finish()
30    }
31}
32
33impl Drawable {
34    pub fn draw(&mut self, canvas: &Canvas, matrix: Option<&Matrix>) {
35        unsafe {
36            self.native_mut()
37                .draw(canvas.native_mut(), matrix.native_ptr_or_null())
38        }
39    }
40
41    pub fn draw_at(&mut self, canvas: &Canvas, point: impl Into<Point>) {
42        let point = point.into();
43        unsafe {
44            self.native_mut()
45                .draw1(canvas.native_mut(), point.x, point.y)
46        }
47    }
48
49    #[cfg(feature = "gpu")]
50    pub fn snap_gpu_draw_handler(
51        &mut self,
52        api: crate::gpu::BackendAPI,
53        matrix: &Matrix,
54        clip_bounds: impl Into<crate::IRect>,
55        buffer_info: &crate::ImageInfo,
56    ) -> Option<gpu_draw_handler::GPUDrawHandler> {
57        gpu_draw_handler::GPUDrawHandler::from_ptr(unsafe {
58            sb::C_SkDrawable_snapGpuDrawHandler(
59                self.native_mut(),
60                api,
61                matrix.native(),
62                clip_bounds.into().native(),
63                buffer_info.native(),
64            )
65        })
66    }
67
68    pub fn make_picture_snapshot(&mut self) -> Picture {
69        Picture::from_ptr(unsafe { sb::C_SkDrawable_makePictureSnapshot(self.native_mut()) })
70            .expect("Internal error: SkDrawable::makePictureSnapshot returned null")
71    }
72
73    pub fn generation_id(&mut self) -> u32 {
74        unsafe { self.native_mut().getGenerationID() }
75    }
76
77    pub fn bounds(&mut self) -> Rect {
78        Rect::construct(|r| unsafe { sb::C_SkDrawable_getBounds(self.native_mut(), r) })
79    }
80
81    pub fn approximate_bytes_used(&mut self) -> usize {
82        unsafe { self.native_mut().approximateBytesUsed() }
83    }
84
85    pub fn notify_drawing_changed(&mut self) {
86        unsafe { self.native_mut().notifyDrawingChanged() }
87    }
88}
89
90#[cfg(feature = "gpu")]
91pub use gpu_draw_handler::*;
92
93#[cfg(feature = "gpu")]
94pub mod gpu_draw_handler {
95    use std::fmt;
96
97    use skia_bindings::{self as sb, SkDrawable_GpuDrawHandler};
98
99    use crate::prelude::*;
100
101    pub type GPUDrawHandler = RefHandle<SkDrawable_GpuDrawHandler>;
102
103    impl NativeDrop for SkDrawable_GpuDrawHandler {
104        fn drop(&mut self) {
105            unsafe { sb::C_SkDrawable_GpuDrawHandler_delete(self) }
106        }
107    }
108
109    impl fmt::Debug for GPUDrawHandler {
110        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111            f.debug_struct("GPUDrawHandler").finish()
112        }
113    }
114
115    #[cfg(feature = "vulkan")]
116    impl GPUDrawHandler {
117        pub fn draw(&mut self, info: &crate::gpu::vk::BackendDrawableInfo) {
118            unsafe {
119                sb::C_SkDrawable_GpuDrawHandler_draw(self.native_mut(), info.native());
120            }
121        }
122    }
123}