1use crate::pathkit;
5use crate::rect::Rect;
6use crate::rect_corner::RectCorner;
7
8pub struct RRect {
11 inner: pathkit::SkRRect,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct Radii {
17 pub x: f32,
18 pub y: f32,
19}
20
21impl RRect {
22 pub fn new() -> Self {
24 Self {
25 inner: pathkit::SkRRect {
26 fRect: pathkit::SkRect {
27 fLeft: 0.0,
28 fTop: 0.0,
29 fRight: 0.0,
30 fBottom: 0.0,
31 },
32 fRadii: [
33 pathkit::SkPoint { fX: 0.0, fY: 0.0 },
34 pathkit::SkPoint { fX: 0.0, fY: 0.0 },
35 pathkit::SkPoint { fX: 0.0, fY: 0.0 },
36 pathkit::SkPoint { fX: 0.0, fY: 0.0 },
37 ],
38 fType: pathkit::SkRRect_Type::kEmpty_Type as i32,
39 },
40 }
41 }
42
43 pub fn from_rect(rect: &Rect) -> Self {
45 let mut rr = Self::new();
46 let r: pathkit::SkRect = (*rect).into();
47 unsafe {
48 rr.inner.setRectXY(&r as *const _, 0.0, 0.0);
49 }
50 rr
51 }
52
53 pub fn from_oval(rect: &Rect) -> Self {
55 let mut rr = Self::new();
56 let r: pathkit::SkRect = (*rect).into();
57 unsafe {
58 rr.inner.setOval(&r as *const _);
59 }
60 rr
61 }
62
63 pub fn from_rect_xy(rect: &Rect, rx: f32, ry: f32) -> Self {
65 let mut rr = Self::new();
66 let r: pathkit::SkRect = (*rect).into();
67 unsafe {
68 rr.inner.setRectXY(&r as *const _, rx, ry);
69 }
70 rr
71 }
72
73 pub fn from_rect_radii(rect: &Rect, radii: &[Radii; 4]) -> Self {
78 let mut rr = Self::new();
79 let r: pathkit::SkRect = (*rect).into();
80 let r4: [pathkit::SkPoint; 4] = [
81 pathkit::SkPoint {
82 fX: radii[0].x,
83 fY: radii[0].y,
84 },
85 pathkit::SkPoint {
86 fX: radii[1].x,
87 fY: radii[1].y,
88 },
89 pathkit::SkPoint {
90 fX: radii[2].x,
91 fY: radii[2].y,
92 },
93 pathkit::SkPoint {
94 fX: radii[3].x,
95 fY: radii[3].y,
96 },
97 ];
98 unsafe {
99 rr.inner.setRectRadii(&r as *const _, r4.as_ptr());
100 }
101 rr
102 }
103
104 pub fn rect(&self) -> Rect {
106 self.inner.fRect.into()
107 }
108
109 pub fn width(&self) -> f32 {
111 self.inner.fRect.fRight - self.inner.fRect.fLeft
112 }
113
114 pub fn height(&self) -> f32 {
116 self.inner.fRect.fBottom - self.inner.fRect.fTop
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.inner.fType == pathkit::SkRRect_Type::kEmpty_Type as i32
122 }
123
124 pub fn is_rect(&self) -> bool {
126 self.inner.fType == pathkit::SkRRect_Type::kRect_Type as i32
127 }
128
129 pub fn is_oval(&self) -> bool {
131 self.inner.fType == pathkit::SkRRect_Type::kOval_Type as i32
132 }
133
134 pub fn is_simple(&self) -> bool {
136 self.inner.fType == pathkit::SkRRect_Type::kSimple_Type as i32
137 }
138
139 pub fn radii(&self, corner: RectCorner) -> Radii {
141 let idx = corner as usize;
142 Radii {
143 x: self.inner.fRadii[idx].fX,
144 y: self.inner.fRadii[idx].fY,
145 }
146 }
147
148 pub fn is_valid(&self) -> bool {
150 unsafe { self.inner.isValid() }
151 }
152
153 pub(crate) fn from_raw(inner: pathkit::SkRRect) -> Self {
155 Self { inner }
156 }
157
158 pub(crate) fn as_raw(&self) -> &pathkit::SkRRect {
160 &self.inner
161 }
162}
163
164impl Default for RRect {
165 fn default() -> Self {
166 Self::new()
167 }
168}
169
170impl Clone for RRect {
171 fn clone(&self) -> Self {
172 Self {
173 inner: pathkit::SkRRect {
174 fRect: self.inner.fRect,
175 fRadii: self.inner.fRadii,
176 fType: self.inner.fType,
177 },
178 }
179 }
180}