skia_safe/utils/
camera.rs

1#![allow(deprecated)]
2use crate::{prelude::*, scalar, Canvas, Matrix, M44, V3};
3use skia_bindings::{self as sb, Sk3DView, SkCamera3D, SkPatch3D};
4use std::fmt;
5
6#[deprecated(
7    since = "0.30.0",
8    note = "Skia now has support for a 4x matrix (core::M44) in core::Canvas."
9)]
10#[derive(Clone, PartialEq, Debug)]
11#[repr(C)]
12pub struct Patch3D {
13    pub u: V3,
14    pub v: V3,
15    pub origin: V3,
16}
17
18native_transmutable!(SkPatch3D, Patch3D, patch_3d_layout);
19
20impl Default for Patch3D {
21    fn default() -> Self {
22        Patch3D::from_native_c(unsafe { SkPatch3D::new() })
23    }
24}
25
26impl Patch3D {
27    pub fn reset(&mut self) -> &mut Self {
28        unsafe { self.native_mut().reset() }
29        self
30    }
31
32    #[must_use]
33    pub fn transform(&self, m: &M44) -> Self {
34        let mut dst = Patch3D::default();
35        unsafe { self.native().transform(m.native(), dst.native_mut()) }
36        dst
37    }
38
39    pub fn dot_with(&self, v: impl Into<V3>) -> scalar {
40        let v = v.into();
41        unsafe { self.native().dotWith(v.x, v.y, v.z) }
42    }
43}
44
45#[deprecated(
46    since = "0.30.0",
47    note = "Skia now has support for a 4x matrix (core::M44) in core::Canvas."
48)]
49#[derive(Clone, PartialEq, Debug)]
50#[repr(C)]
51pub struct Camera3D {
52    pub location: V3,
53    pub axis: V3,
54    pub zenith: V3,
55    pub observer: V3,
56    orientation: Matrix,
57    need_to_update: bool,
58}
59
60native_transmutable!(SkCamera3D, Camera3D, camera_3d_layout);
61
62impl Default for Camera3D {
63    fn default() -> Self {
64        Camera3D::from_native_c(unsafe { SkCamera3D::new() })
65    }
66}
67
68impl Camera3D {
69    pub fn reset(&mut self) -> &mut Self {
70        unsafe { self.native_mut().reset() }
71        self
72    }
73
74    pub fn update(&mut self) -> &mut Self {
75        unsafe { self.native_mut().update() }
76        self
77    }
78
79    pub fn patch_to_matrix(&self, quilt: &Patch3D) -> Matrix {
80        let mut matrix = Matrix::default();
81        unsafe {
82            self.native()
83                .patchToMatrix(quilt.native(), matrix.native_mut())
84        }
85        matrix
86    }
87}
88
89// Note: original name is Sk3DView not SkView3D
90// Also note that the implementation uses interior pointers,
91// so we let Skia do the allocation.
92
93#[deprecated(
94    since = "0.30.0",
95    note = "Skia now has support for a 4x matrix (core::M44) in core::Canvas."
96)]
97pub type View3D = RefHandle<Sk3DView>;
98unsafe_send_sync!(View3D);
99
100impl Default for View3D {
101    fn default() -> Self {
102        Self::new()
103    }
104}
105
106impl NativeDrop for Sk3DView {
107    fn drop(&mut self) {
108        unsafe { sb::C_Sk3DView_delete(self) }
109    }
110}
111
112impl fmt::Debug for View3D {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        f.debug_struct("View3D").finish()
115    }
116}
117
118impl RefHandle<Sk3DView> {
119    pub fn new() -> Self {
120        View3D::from_ptr(unsafe { sb::C_Sk3DView_new() }).unwrap()
121    }
122
123    pub fn save(&mut self) -> &mut Self {
124        unsafe { self.native_mut().save() }
125        self
126    }
127
128    pub fn restore(&mut self) -> &mut Self {
129        unsafe { self.native_mut().restore() }
130        self
131    }
132
133    pub fn translate(&mut self, d: impl Into<V3>) -> &mut Self {
134        let d = d.into();
135        unsafe { self.native_mut().translate(d.x, d.y, d.z) }
136        self
137    }
138
139    pub fn rotate_x(&mut self, deg: scalar) -> &mut Self {
140        unsafe { self.native_mut().rotateX(deg) }
141        self
142    }
143
144    pub fn rotate_y(&mut self, deg: scalar) -> &mut Self {
145        unsafe { self.native_mut().rotateY(deg) }
146        self
147    }
148
149    pub fn rotate_z(&mut self, deg: scalar) -> &mut Self {
150        unsafe { self.native_mut().rotateZ(deg) }
151        self
152    }
153
154    pub fn matrix(&self) -> Matrix {
155        let mut m = Matrix::default();
156        unsafe { self.native().getMatrix(m.native_mut()) }
157        m
158    }
159
160    pub fn apply_to_canvas(&self, canvas: &Canvas) -> &Self {
161        unsafe { self.native().applyToCanvas(canvas.native_mut()) }
162        self
163    }
164
165    pub fn dot_with_normal(&self, d: impl Into<V3>) -> scalar {
166        let d = d.into();
167        unsafe { self.native().dotWithNormal(d.x, d.y, d.z) }
168    }
169}
170
171#[test]
172fn test_canvas_passing_syntax() {
173    use crate::utils::new_null_canvas;
174    use crate::Surface;
175
176    let null_canvas = new_null_canvas();
177    let view = View3D::default();
178    // as mutable reference
179    view.apply_to_canvas(&null_canvas);
180
181    // and one with a mutable reference to a shared Canvas:
182    let mut surface = Surface::new_raster_n32_premul((100, 100)).unwrap();
183    view.apply_to_canvas(surface.canvas());
184}