1use crate::bridge::ffi;
5use crate::rect::Rect;
6use crate::RectCorner;
7
8pub struct RRect {
11 inner: ffi::RRect,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq)]
17pub struct Radii {
18 pub x: f32,
20 pub y: f32,
22}
23
24impl RRect {
25 pub fn new() -> Self {
27 let mut inner = ffi::RRect {
28 fRect: ffi::Rect {
29 fLeft: 0.0,
30 fTop: 0.0,
31 fRight: 0.0,
32 fBottom: 0.0,
33 },
34 fRadii: [ffi::Point { fX: 0.0, fY: 0.0 }; 4],
35 fType: ffi::RRectType::Empty,
36 };
37 ffi::rrect_new_empty(&mut inner);
38 Self { inner }
39 }
40
41 pub fn from_rect(rect: &Rect) -> Self {
43 let mut rr = Self::new();
44 let r: ffi::Rect = (*rect).into();
45 ffi::rrect_set_rect_xy(&mut rr.inner, &r, 0.0, 0.0);
46 rr
47 }
48
49 pub fn from_oval(rect: &Rect) -> Self {
51 let mut rr = Self::new();
52 let r: ffi::Rect = (*rect).into();
53 ffi::rrect_set_oval(&mut rr.inner, &r);
54 rr
55 }
56
57 pub fn from_rect_xy(rect: &Rect, rx: f32, ry: f32) -> Self {
59 let mut rr = Self::new();
60 let r: ffi::Rect = (*rect).into();
61 ffi::rrect_set_rect_xy(&mut rr.inner, &r, rx, ry);
62 rr
63 }
64
65 pub fn from_rect_radii(rect: &Rect, radii: &[Radii; 4]) -> Self {
70 let mut rr = Self::new();
71 let r: ffi::Rect = (*rect).into();
72 let pts: [ffi::Point; 4] = [
73 ffi::Point {
74 fX: radii[0].x,
75 fY: radii[0].y,
76 },
77 ffi::Point {
78 fX: radii[1].x,
79 fY: radii[1].y,
80 },
81 ffi::Point {
82 fX: radii[2].x,
83 fY: radii[2].y,
84 },
85 ffi::Point {
86 fX: radii[3].x,
87 fY: radii[3].y,
88 },
89 ];
90 ffi::rrect_set_rect_radii(&mut rr.inner, &r, &pts);
91 rr
92 }
93
94 pub fn rect(&self) -> Rect {
96 self.inner.fRect.into()
97 }
98
99 pub fn width(&self) -> f32 {
101 self.inner.fRect.fRight - self.inner.fRect.fLeft
102 }
103
104 pub fn height(&self) -> f32 {
106 self.inner.fRect.fBottom - self.inner.fRect.fTop
107 }
108
109 pub fn is_empty(&self) -> bool {
111 self.inner.fType == ffi::RRectType::Empty
112 }
113
114 pub fn is_rect(&self) -> bool {
116 self.inner.fType == ffi::RRectType::Rect
117 }
118
119 pub fn is_oval(&self) -> bool {
121 self.inner.fType == ffi::RRectType::Oval
122 }
123
124 pub fn is_simple(&self) -> bool {
126 self.inner.fType == ffi::RRectType::Simple
127 }
128
129 pub fn radii(&self, corner: RectCorner) -> Radii {
131 let idx = match corner {
132 RectCorner::UpperLeft => 0usize,
133 RectCorner::UpperRight => 1,
134 RectCorner::LowerRight => 2,
135 RectCorner::LowerLeft => 3,
136 _ => 0,
137 };
138 Radii {
139 x: self.inner.fRadii[idx].fX,
140 y: self.inner.fRadii[idx].fY,
141 }
142 }
143
144 pub fn is_valid(&self) -> bool {
146 ffi::rrect_is_valid(&self.inner)
147 }
148
149 pub(crate) fn from_ffi(inner: ffi::RRect) -> Self {
151 Self { inner }
152 }
153
154 pub(crate) fn as_ffi(&self) -> ffi::RRect {
156 self.inner
157 }
158}
159
160impl Default for RRect {
161 fn default() -> Self {
162 Self::new()
163 }
164}
165
166impl Clone for RRect {
167 fn clone(&self) -> Self {
168 Self { inner: self.inner }
169 }
170}