Skip to main content

path_kit/
rrect.rs

1//! 圆角矩形,支持四角独立半径。
2//! Rounded rectangle with per-corner radii.
3
4use crate::pathkit;
5use crate::rect::Rect;
6use crate::rect_corner::RectCorner;
7
8/// 圆角矩形,支持四角独立半径。
9/// Rounded rectangle with per-corner radii (each corner can have different x/y).
10pub struct RRect {
11    inner: pathkit::SkRRect,
12}
13
14/// 单角半径 (x, y)。Corner radii (x, y).
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct Radii {
17    pub x: f32,
18    pub y: f32,
19}
20
21impl RRect {
22    /// 创建空圆角矩形。Creates an empty RRect.
23    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    /// 从矩形创建(直角)。Creates RRect from rect (sharp corners).
44    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    /// 从椭圆边界创建。Creates oval (ellipse) bounded by rect.
54    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    /// 从矩形与统一圆角创建。Creates rounded rect with uniform radii.
64    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    /// 从矩形与四角半径创建。Creates RRect with per-corner radii.
74    ///
75    /// `radii` 顺序:UpperLeft, UpperRight, LowerRight, LowerLeft。
76    /// Radii order: UpperLeft, UpperRight, LowerRight, LowerLeft.
77    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    /// 边界矩形。Returns the bounding rect.
105    pub fn rect(&self) -> Rect {
106        self.inner.fRect.into()
107    }
108
109    /// 宽度。Returns width.
110    pub fn width(&self) -> f32 {
111        self.inner.fRect.fRight - self.inner.fRect.fLeft
112    }
113
114    /// 高度。Returns height.
115    pub fn height(&self) -> f32 {
116        self.inner.fRect.fBottom - self.inner.fRect.fTop
117    }
118
119    /// 是否为空。Returns true if empty.
120    pub fn is_empty(&self) -> bool {
121        self.inner.fType == pathkit::SkRRect_Type::kEmpty_Type as i32
122    }
123
124    /// 是否为普通矩形。Returns true if sharp corners (no rounding).
125    pub fn is_rect(&self) -> bool {
126        self.inner.fType == pathkit::SkRRect_Type::kRect_Type as i32
127    }
128
129    /// 是否为椭圆。Returns true if oval.
130    pub fn is_oval(&self) -> bool {
131        self.inner.fType == pathkit::SkRRect_Type::kOval_Type as i32
132    }
133
134    /// 是否所有角半径相同。Returns true if uniform radii (simple type).
135    pub fn is_simple(&self) -> bool {
136        self.inner.fType == pathkit::SkRRect_Type::kSimple_Type as i32
137    }
138
139    /// 获取某角半径。Returns radii for corner (UpperLeft, UpperRight, LowerRight, LowerLeft).
140    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    /// 数据是否有效。Returns true if valid.
149    pub fn is_valid(&self) -> bool {
150        unsafe { self.inner.isValid() }
151    }
152
153    /// 从 SkRRect 创建(仅 crate 内使用)。Internal use only.
154    pub(crate) fn from_raw(inner: pathkit::SkRRect) -> Self {
155        Self { inner }
156    }
157
158    /// 内部 SkRRect 引用(仅 crate 内使用)。Internal use only.
159    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}