Skip to main content

path_kit/
path_builder.rs

1//! 路径构建器,基于 `pk::SkPathBuilder`(`snapshot` / `detach` 语义与 Skia 一致)。
2//! Path builder backed by `pk::SkPathBuilder` (`snapshot` leaves builder unchanged; `detach` resets it).
3
4use crate::bridge::ffi;
5use crate::path::Path;
6use crate::path_fill_type::PathFillType;
7use crate::rect::Rect;
8use crate::rrect::RRect;
9use crate::{Direction, RectCorner};
10use cxx::UniquePtr;
11
12/// 可增量构建路径;完成后用 [`Self::snapshot`] 或 [`Self::detach`] 得到 [`Path`]。
13/// Incremental path construction; finish with [`Self::snapshot`] or [`Self::detach`] into a [`Path`].
14pub struct PathBuilder {
15    inner: UniquePtr<ffi::PathBuilderHolder>,
16}
17
18impl PathBuilder {
19    /// 创建空构建器。Creates an empty builder.
20    pub fn new() -> Self {
21        Self {
22            inner: ffi::path_builder_new(),
23        }
24    }
25
26    /// 清空内容(与 SkPathBuilder::reset 一致)。Clears the builder.
27    pub fn reset(&mut self) -> &mut Self {
28        ffi::path_builder_reset(self.inner.pin_mut());
29        self
30    }
31
32    /// 当前填充规则。Fill rule used when producing a path.
33    pub fn fill_type(&self) -> PathFillType {
34        ffi::path_builder_fill_type(self.as_holder())
35    }
36
37    /// 设置填充规则。Sets fill rule for the built path.
38    pub fn set_fill_type(&mut self, ft: PathFillType) -> &mut Self {
39        ffi::path_builder_set_fill_type(self.inner.pin_mut(), ft);
40        self
41    }
42
43    /// 在普通 / 反色填充之间切换。Toggles inverse fill (same as SkPathBuilder).
44    pub fn toggle_inverse_fill_type(&mut self) -> &mut Self {
45        ffi::path_builder_toggle_inverse_fill_type(self.inner.pin_mut());
46        self
47    }
48
49    /// 生成路径副本,构建器保持不变。Builds a copy; builder is unchanged.
50    pub fn snapshot(&self) -> Path {
51        Path::from_unique_ptr(ffi::path_builder_snapshot(self.as_holder()))
52    }
53
54    /// 取出路径并将构建器重置为空。Takes the path and resets the builder to empty.
55    pub fn detach(&mut self) -> Path {
56        Path::from_unique_ptr(ffi::path_builder_detach(self.inner.pin_mut()))
57    }
58
59    /// 移动到 (x, y)。Moves to (x, y).
60    pub fn move_to(&mut self, x: f32, y: f32) -> &mut Self {
61        ffi::path_builder_move_to(self.inner.pin_mut(), x, y);
62        self
63    }
64
65    /// 直线到 (x, y)。Line to (x, y).
66    pub fn line_to(&mut self, x: f32, y: f32) -> &mut Self {
67        ffi::path_builder_line_to(self.inner.pin_mut(), x, y);
68        self
69    }
70
71    /// 二次贝塞尔。Quadratic bezier.
72    pub fn quad_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32) -> &mut Self {
73        ffi::path_builder_quad_to(self.inner.pin_mut(), x1, y1, x2, y2);
74        self
75    }
76
77    /// 三次贝塞尔。Cubic bezier.
78    pub fn cubic_to(
79        &mut self,
80        x1: f32,
81        y1: f32,
82        x2: f32,
83        y2: f32,
84        x3: f32,
85        y3: f32,
86    ) -> &mut Self {
87        ffi::path_builder_cubic_to(self.inner.pin_mut(), x1, y1, x2, y2, x3, y3);
88        self
89    }
90
91    /// 闭合当前轮廓。Closes the current contour.
92    pub fn close(&mut self) -> &mut Self {
93        ffi::path_builder_close(self.inner.pin_mut());
94        self
95    }
96
97    /// 添加矩形。Adds a rectangle contour.
98    pub fn add_rect(&mut self, rect: &Rect, dir: Direction, start: RectCorner) -> &mut Self {
99        let r: ffi::Rect = (*rect).into();
100        ffi::path_builder_add_rect(self.inner.pin_mut(), &r, dir, start);
101        self
102    }
103
104    /// 添加椭圆。Adds an oval.
105    pub fn add_oval(&mut self, rect: &Rect, dir: Direction) -> &mut Self {
106        let r: ffi::Rect = (*rect).into();
107        ffi::path_builder_add_oval(self.inner.pin_mut(), &r, dir);
108        self
109    }
110
111    /// 添加圆。Adds a circle.
112    pub fn add_circle(&mut self, cx: f32, cy: f32, radius: f32, dir: Direction) -> &mut Self {
113        ffi::path_builder_add_circle(self.inner.pin_mut(), cx, cy, radius, dir);
114        self
115    }
116
117    /// 添加圆角矩形(统一 rx/ry)。Adds round rect.
118    pub fn add_round_rect(
119        &mut self,
120        rect: &Rect,
121        rx: f32,
122        ry: f32,
123        dir: Direction,
124    ) -> &mut Self {
125        let r: ffi::Rect = (*rect).into();
126        ffi::path_builder_add_round_rect(self.inner.pin_mut(), &r, rx, ry, dir);
127        self
128    }
129
130    /// 添加 RRect。Adds RRect.
131    pub fn add_rrect(&mut self, rrect: &RRect, dir: Direction) -> &mut Self {
132        let rr = rrect.as_ffi();
133        ffi::path_builder_add_rrect(self.inner.pin_mut(), &rr, dir);
134        self
135    }
136
137    /// 添加 RRect 并指定起始角。Adds RRect with start corner.
138    pub fn add_rrect_with_start(
139        &mut self,
140        rrect: &RRect,
141        dir: Direction,
142        start: RectCorner,
143    ) -> &mut Self {
144        let rr = rrect.as_ffi();
145        ffi::path_builder_add_rrect_start(self.inner.pin_mut(), &rr, dir, start);
146        self
147    }
148
149    /// 追加已有路径的几何。Appends another path's geometry.
150    pub fn add_path(&mut self, path: &Path) -> &mut Self {
151        ffi::path_builder_add_path(self.inner.pin_mut(), path.as_raw());
152        self
153    }
154
155    fn as_holder(&self) -> &ffi::PathBuilderHolder {
156        self.inner.as_ref().expect("PathBuilder")
157    }
158}
159
160impl Default for PathBuilder {
161    fn default() -> Self {
162        Self::new()
163    }
164}