1 | use crate::{interop, prelude::*, scalar, Matrix, Rect, Vector}; |
2 | use skia_bindings::{self as sb, SkRRect}; |
3 | use std::{fmt, mem, ptr}; |
4 | |
5 | pub use skia_bindings::SkRRect_Type as Type; |
6 | variant_name!(Type::Complex); |
7 | |
8 | pub use skia_bindings::SkRRect_Corner as Corner; |
9 | variant_name!(Corner::LowerLeft); |
10 | |
11 | #[derive (Copy, Clone)] |
12 | #[repr (transparent)] |
13 | pub struct RRect(SkRRect); |
14 | |
15 | native_transmutable!(SkRRect, RRect, rrect_layout); |
16 | |
17 | impl PartialEq for RRect { |
18 | fn eq(&self, rhs: &Self) -> bool { |
19 | unsafe { sb::C_SkRRect_Equals(self.native(), rhs:rhs.native()) } |
20 | } |
21 | } |
22 | |
23 | impl Default for RRect { |
24 | fn default() -> Self { |
25 | Self::new() |
26 | } |
27 | } |
28 | |
29 | impl fmt::Debug for RRect { |
30 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
31 | f&mut DebugStruct<'_, '_>.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(name:"type" , &self.get_type()) |
43 | .finish() |
44 | } |
45 | } |
46 | |
47 | impl AsRef<RRect> for RRect { |
48 | fn as_ref(&self) -> &RRect { |
49 | self |
50 | } |
51 | } |
52 | |
53 | impl 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 bounds(&self) -> &Rect { |
206 | self.rect() |
207 | } |
208 | |
209 | pub fn inset(&mut self, delta: impl Into<Vector>) { |
210 | *self = self.with_inset(delta) |
211 | } |
212 | |
213 | #[must_use ] |
214 | pub fn with_inset(&self, delta: impl Into<Vector>) -> Self { |
215 | let delta = delta.into(); |
216 | let mut r = Self::default(); |
217 | unsafe { self.native().inset(delta.x, delta.y, r.native_mut()) }; |
218 | r |
219 | } |
220 | |
221 | pub fn outset(&mut self, delta: impl Into<Vector>) { |
222 | *self = self.with_outset(delta) |
223 | } |
224 | |
225 | #[must_use ] |
226 | pub fn with_outset(&self, delta: impl Into<Vector>) -> Self { |
227 | self.with_inset(-delta.into()) |
228 | } |
229 | |
230 | pub fn offset(&mut self, delta: impl Into<Vector>) { |
231 | Rect::from_native_ref_mut(&mut self.native_mut().fRect).offset(delta) |
232 | } |
233 | |
234 | #[must_use ] |
235 | pub fn with_offset(&self, delta: impl Into<Vector>) -> Self { |
236 | let mut copied = *self; |
237 | copied.offset(delta); |
238 | copied |
239 | } |
240 | |
241 | pub fn contains(&self, rect: impl AsRef<Rect>) -> bool { |
242 | unsafe { self.native().contains(rect.as_ref().native()) } |
243 | } |
244 | |
245 | pub fn is_valid(&self) -> bool { |
246 | unsafe { self.native().isValid() } |
247 | } |
248 | |
249 | pub const SIZE_IN_MEMORY: usize = mem::size_of::<Self>(); |
250 | |
251 | pub fn write_to_memory(&self, buffer: &mut Vec<u8>) { |
252 | unsafe { |
253 | let size = self.native().writeToMemory(ptr::null_mut()); |
254 | buffer.resize(size, 0); |
255 | let written = self.native().writeToMemory(buffer.as_mut_ptr() as _); |
256 | debug_assert_eq!(written, size); |
257 | } |
258 | } |
259 | |
260 | pub fn read_from_memory(&mut self, buffer: &[u8]) -> usize { |
261 | unsafe { |
262 | self.native_mut() |
263 | .readFromMemory(buffer.as_ptr() as _, buffer.len()) |
264 | } |
265 | } |
266 | |
267 | #[must_use ] |
268 | pub fn transform(&self, matrix: &Matrix) -> Option<Self> { |
269 | let mut r = Self::default(); |
270 | unsafe { self.native().transform(matrix.native(), r.native_mut()) }.if_true_some(r) |
271 | } |
272 | |
273 | pub fn dump(&self, as_hex: impl Into<Option<bool>>) { |
274 | unsafe { self.native().dump(as_hex.into().unwrap_or_default()) } |
275 | } |
276 | |
277 | pub fn dump_to_string(&self, as_hex: bool) -> String { |
278 | let mut str = interop::String::default(); |
279 | unsafe { sb::C_SkRRect_dumpToString(self.native(), as_hex, str.native_mut()) } |
280 | str.to_string() |
281 | } |
282 | |
283 | pub fn dump_hex(&self) { |
284 | self.dump(true) |
285 | } |
286 | } |
287 | |