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: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&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
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 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