skia_safe/core/
rrect.rs

1use crate::{interop, prelude::*, scalar, Matrix, Rect, Vector};
2use skia_bindings::{self as sb, SkRRect};
3use std::{fmt, mem, ptr};
4
5pub use skia_bindings::SkRRect_Type as Type;
6variant_name!(Type::Complex);
7
8pub use skia_bindings::SkRRect_Corner as Corner;
9variant_name!(Corner::LowerLeft);
10
11#[derive(Copy, Clone)]
12#[repr(transparent)]
13pub struct RRect(SkRRect);
14
15native_transmutable!(SkRRect, RRect, rrect_layout);
16
17impl PartialEq for RRect {
18    fn eq(&self, rhs: &Self) -> bool {
19        unsafe { sb::C_SkRRect_Equals(self.native(), rhs.native()) }
20    }
21}
22
23impl Default for RRect {
24    fn default() -> Self {
25        Self::new()
26    }
27}
28
29impl fmt::Debug for RRect {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        f.debug_struct("RRect")
32            .field("rect", &self.rect())
33            .field(
34                "radii",
35                &[
36                    self.radii(Corner::UpperLeft),
37                    self.radii(Corner::UpperRight),
38                    self.radii(Corner::LowerRight),
39                    self.radii(Corner::LowerLeft),
40                ],
41            )
42            .field("type", &self.get_type())
43            .finish()
44    }
45}
46
47impl AsRef<RRect> for RRect {
48    fn as_ref(&self) -> &RRect {
49        self
50    }
51}
52
53impl RRect {
54    pub fn new() -> Self {
55        RRect::construct(|rr| unsafe { sb::C_SkRRect_Construct(rr) })
56    }
57
58    pub fn get_type(&self) -> Type {
59        unsafe { sb::C_SkRRect_getType(self.native()) }
60    }
61
62    pub fn is_empty(&self) -> bool {
63        self.get_type() == Type::Empty
64    }
65
66    pub fn is_rect(&self) -> bool {
67        self.get_type() == Type::Rect
68    }
69
70    pub fn is_oval(&self) -> bool {
71        self.get_type() == Type::Oval
72    }
73
74    pub fn is_simple(&self) -> bool {
75        self.get_type() == Type::Simple
76    }
77
78    pub fn is_nine_patch(&self) -> bool {
79        self.get_type() == Type::NinePatch
80    }
81
82    pub fn is_complex(&self) -> bool {
83        self.get_type() == Type::Complex
84    }
85
86    pub fn width(&self) -> scalar {
87        self.rect().width()
88    }
89
90    pub fn height(&self) -> scalar {
91        self.rect().height()
92    }
93
94    pub fn simple_radii(&self) -> Vector {
95        self.radii(Corner::UpperLeft)
96    }
97
98    pub fn set_empty(&mut self) {
99        *self = Self::new()
100    }
101
102    pub fn set_rect(&mut self, rect: impl AsRef<Rect>) {
103        unsafe { sb::C_SkRRect_setRect(self.native_mut(), rect.as_ref().native()) }
104    }
105
106    pub fn new_empty() -> Self {
107        Self::new()
108    }
109
110    // TODO: consider to rename all the following new_* function to from_* functions?
111    //       is it possible to find a proper convention here (new_ vs from_?)?
112
113    pub fn new_rect(rect: impl AsRef<Rect>) -> Self {
114        let mut rr = Self::default();
115        rr.set_rect(rect);
116        rr
117    }
118
119    pub fn new_oval(oval: impl AsRef<Rect>) -> Self {
120        let mut rr = Self::default();
121        rr.set_oval(oval);
122        rr
123    }
124
125    pub fn new_rect_xy(rect: impl AsRef<Rect>, x_rad: scalar, y_rad: scalar) -> Self {
126        let mut rr = Self::default();
127        rr.set_rect_xy(rect.as_ref(), x_rad, y_rad);
128        rr
129    }
130
131    pub fn new_nine_patch(
132        rect: impl AsRef<Rect>,
133        left_rad: scalar,
134        top_rad: scalar,
135        right_rad: scalar,
136        bottom_rad: scalar,
137    ) -> Self {
138        let mut r = Self::default();
139        unsafe {
140            r.native_mut().setNinePatch(
141                rect.as_ref().native(),
142                left_rad,
143                top_rad,
144                right_rad,
145                bottom_rad,
146            )
147        }
148        r
149    }
150
151    pub fn new_rect_radii(rect: impl AsRef<Rect>, radii: &[Vector; 4]) -> Self {
152        let mut r = Self::default();
153        unsafe {
154            r.native_mut()
155                .setRectRadii(rect.as_ref().native(), radii.native().as_ptr())
156        }
157        r
158    }
159
160    pub fn set_oval(&mut self, oval: impl AsRef<Rect>) {
161        unsafe { self.native_mut().setOval(oval.as_ref().native()) }
162    }
163
164    pub fn set_rect_xy(&mut self, rect: impl AsRef<Rect>, x_rad: scalar, y_rad: scalar) {
165        unsafe {
166            self.native_mut()
167                .setRectXY(rect.as_ref().native(), x_rad, y_rad)
168        }
169    }
170
171    pub fn set_nine_patch(
172        &mut self,
173        rect: impl AsRef<Rect>,
174        left_rad: scalar,
175        top_rad: scalar,
176        right_rad: scalar,
177        bottom_rad: scalar,
178    ) {
179        unsafe {
180            self.native_mut().setNinePatch(
181                rect.as_ref().native(),
182                left_rad,
183                top_rad,
184                right_rad,
185                bottom_rad,
186            )
187        }
188    }
189
190    pub fn set_rect_radii(&mut self, rect: impl AsRef<Rect>, radii: &[Vector; 4]) {
191        unsafe {
192            self.native_mut()
193                .setRectRadii(rect.as_ref().native(), radii.native().as_ptr())
194        }
195    }
196
197    pub fn rect(&self) -> &Rect {
198        Rect::from_native_ref(&self.native().fRect)
199    }
200
201    pub fn radii(&self, corner: Corner) -> Vector {
202        Vector::from_native_c(self.native().fRadii[corner as usize])
203    }
204
205    pub fn radii_ref(&self) -> &[Vector; 4] {
206        Vector::from_native_array_ref(&self.native().fRadii)
207    }
208
209    pub fn bounds(&self) -> &Rect {
210        self.rect()
211    }
212
213    pub fn inset(&mut self, delta: impl Into<Vector>) {
214        *self = self.with_inset(delta)
215    }
216
217    #[must_use]
218    pub fn with_inset(&self, delta: impl Into<Vector>) -> Self {
219        let delta = delta.into();
220        let mut r = Self::default();
221        unsafe { self.native().inset(delta.x, delta.y, r.native_mut()) };
222        r
223    }
224
225    pub fn outset(&mut self, delta: impl Into<Vector>) {
226        *self = self.with_outset(delta)
227    }
228
229    #[must_use]
230    pub fn with_outset(&self, delta: impl Into<Vector>) -> Self {
231        self.with_inset(-delta.into())
232    }
233
234    pub fn offset(&mut self, delta: impl Into<Vector>) {
235        Rect::from_native_ref_mut(&mut self.native_mut().fRect).offset(delta)
236    }
237
238    #[must_use]
239    pub fn with_offset(&self, delta: impl Into<Vector>) -> Self {
240        let mut copied = *self;
241        copied.offset(delta);
242        copied
243    }
244
245    pub fn contains(&self, rect: impl AsRef<Rect>) -> bool {
246        unsafe { self.native().contains(rect.as_ref().native()) }
247    }
248
249    pub fn is_valid(&self) -> bool {
250        unsafe { self.native().isValid() }
251    }
252
253    pub const SIZE_IN_MEMORY: usize = mem::size_of::<Self>();
254
255    pub fn write_to_memory(&self, buffer: &mut Vec<u8>) {
256        unsafe {
257            let size = self.native().writeToMemory(ptr::null_mut());
258            buffer.resize(size, 0);
259            let written = self.native().writeToMemory(buffer.as_mut_ptr() as _);
260            debug_assert_eq!(written, size);
261        }
262    }
263
264    pub fn read_from_memory(&mut self, buffer: &[u8]) -> usize {
265        unsafe {
266            self.native_mut()
267                .readFromMemory(buffer.as_ptr() as _, buffer.len())
268        }
269    }
270
271    #[must_use]
272    pub fn transform(&self, matrix: &Matrix) -> Option<Self> {
273        let mut r = Self::default();
274        unsafe { self.native().transform(matrix.native(), r.native_mut()) }.if_true_some(r)
275    }
276
277    pub fn dump(&self, as_hex: impl Into<Option<bool>>) {
278        unsafe { self.native().dump(as_hex.into().unwrap_or_default()) }
279    }
280
281    pub fn dump_to_string(&self, as_hex: bool) -> String {
282        let mut str = interop::String::default();
283        unsafe { sb::C_SkRRect_dumpToString(self.native(), as_hex, str.native_mut()) }
284        str.to_string()
285    }
286
287    pub fn dump_hex(&self) {
288        self.dump(true)
289    }
290}