Skip to main content

path_kit/
bridge.rs

1#[cxx::bridge]
2pub(crate) mod ffi {
3    //! cxx 与 PathKit C++ 的共享类型及 `pk_*` 声明(仅 crate 内使用)。
4    //! Shared cxx types and `pk_*` bindings (crate-internal only).
5
6    /// 路径布尔运算,与 `pk::SkPathOp` 取值一致。
7    /// Path boolean op; matches `pk::SkPathOp`.
8    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
9    #[repr(u32)]
10    pub enum PathOp {
11        /// 差集 (one \\ two)。Difference.
12        Difference = 0,
13        /// 交集。Intersection.
14        Intersect = 1,
15        /// 并集。Union.
16        Union = 2,
17        /// 异或。XOR.
18        Xor = 3,
19        /// 反色差集。Reverse difference.
20        ReverseDifference = 4,
21    }
22
23    /// 路径方向,与 `pk::SkPathDirection` 一致。
24    /// Path contour direction; matches `pk::SkPathDirection`.
25    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
26    #[repr(u32)]
27    pub enum Direction {
28        /// 顺时针。Clockwise.
29        Cw = 0,
30        /// 逆时针。Counter-clockwise.
31        Ccw = 1,
32    }
33
34    /// 填充规则低位,与 `pk::SkPathFillType` 一致。
35    /// Fill rule; matches `pk::SkPathFillType`.
36    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
37    #[repr(u8)]
38    pub enum PathFillType {
39        /// 环绕规则。Non-zero winding.
40        Winding = 0,
41        /// 奇偶规则。Even-odd.
42        EvenOdd = 1,
43        /// 反色环绕。Inverse winding.
44        InverseWinding = 2,
45        /// 反色奇偶。Inverse even-odd.
46        InverseEvenOdd = 3,
47    }
48
49    /// 矩形起始角,与 `SkPath::addRect` 角索引一致。
50    /// Rect start corner index for `addRect`.
51    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
52    #[repr(u32)]
53    pub enum RectCorner {
54        /// 左上。Upper-left.
55        UpperLeft = 0,
56        /// 右上。Upper-right.
57        UpperRight = 1,
58        /// 右下。Lower-right.
59        LowerRight = 2,
60        /// 左下。Lower-left.
61        LowerLeft = 3,
62    }
63
64    /// 圆角矩形分类,与 `pk::SkRRect::Type` 一致。
65    /// RRect specialization; matches `pk::SkRRect::Type`.
66    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
67    #[repr(i32)]
68    pub enum RRectType {
69        /// 空或无面积。Empty.
70        Empty = 0,
71        /// 直角矩形。Axis rect, zero radii.
72        Rect = 1,
73        /// 椭圆。Oval.
74        Oval = 2,
75        /// 四角等径圆角。Simple (uniform radii).
76        Simple = 3,
77        /// 轴对齐不等径。Nine-patch-style radii.
78        NinePatch = 4,
79        /// 一般圆角矩形。Complex.
80        Complex = 5,
81    }
82
83    /// 路径动词,与 `pk::SkPath::Verb` 一致。
84    /// Path verb; matches `pk::SkPath::Verb`.
85    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
86    #[repr(u32)]
87    pub enum PathVerb {
88        /// Move。Move.
89        Move = 0,
90        /// Line。Line.
91        Line = 1,
92        /// 二次曲线。Quadratic.
93        Quad = 2,
94        /// 圆锥曲线。Conic.
95        Conic = 3,
96        /// 三次曲线。Cubic.
97        Cubic = 4,
98        /// 闭合。Close.
99        Close = 5,
100        /// 迭代结束。Iterator done.
101        Done = 6,
102    }
103
104    /// 绘图样式,与 `pk::SkPaint::Style` 一致。
105    /// Paint style; matches `pk::SkPaint::Style`.
106    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
107    #[repr(u8)]
108    pub enum PaintStyle {
109        /// 仅填充。Fill.
110        Fill = 0,
111        /// 仅描边。Stroke.
112        Stroke = 1,
113        /// 描边+填充。Stroke and fill.
114        StrokeAndFill = 2,
115    }
116
117    /// 线端样式,与 `pk::SkPaint::Cap` / `SkStrokeRec` 一致。
118    /// Stroke cap; matches `pk::SkPaint::Cap`.
119    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
120    #[repr(u32)]
121    pub enum StrokeCap {
122        /// 平头。Butt.
123        Butt = 0,
124        /// 圆头。Round.
125        Round = 1,
126        /// 方头。Square.
127        Square = 2,
128    }
129
130    /// 转角连接,与 `pk::SkPaint::Join` / `SkStrokeRec` 一致。
131    /// Stroke join; matches `pk::SkPaint::Join`.
132    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
133    #[repr(u8)]
134    pub enum StrokeJoin {
135        /// 尖角(斜接)。Miter.
136        Miter = 0,
137        /// 圆角。Round.
138        Round = 1,
139        /// 斜切。Bevel.
140        Bevel = 2,
141    }
142
143    /// `SkStrokeRec` 初始样式(`pk::SkStrokeRec::InitStyle`)。
144    /// Initial style for `stroke_rec_new`.
145    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
146    #[repr(u32)]
147    pub enum StrokeRecInit {
148        /// 极细线。Hairline.
149        Hairline = 0,
150        /// 填充。Fill.
151        Fill = 1,
152    }
153
154    /// `SkStrokeRec::getStyle` 返回值。
155    /// Result of `SkStrokeRec::getStyle`.
156    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
157    #[repr(u32)]
158    pub enum StrokeRecStyleTag {
159        /// 极细线。Hairline.
160        Hairline = 0,
161        /// 填充。Fill.
162        Fill = 1,
163        /// 描边。Stroke.
164        Stroke = 2,
165        /// 描边+填充。Stroke and fill.
166        StrokeAndFill = 3,
167    }
168
169    /// cxx 共享 `SkPoint` 布局。
170    /// Shared `SkPoint` layout for FFI.
171    #[derive(Clone, Copy, Debug)]
172    #[cxx_name = "SkPoint"]
173    struct Point {
174        /// X 坐标。X coordinate.
175        fX: f32,
176        /// Y 坐标。Y coordinate.
177        fY: f32,
178    }
179
180    /// cxx 共享 `SkRect` 布局。
181    /// Shared `SkRect` layout for FFI.
182    #[derive(Clone, Copy, Debug)]
183    #[cxx_name = "SkRect"]
184    struct Rect {
185        /// 左。Left.
186        fLeft: f32,
187        /// 上。Top.
188        fTop: f32,
189        /// 右。Right.
190        fRight: f32,
191        /// 下。Bottom.
192        fBottom: f32,
193    }
194
195    /// cxx 共享 `SkRRect` 布局(外接矩形 + 四角半径 + 类型)。
196    /// Shared `SkRRect` layout (bounds, corner radii, type).
197    #[derive(Clone, Copy, Debug)]
198    #[cxx_name = "SkRRect"]
199    struct RRect {
200        /// 外接矩形。Bounds.
201        fRect: Rect,
202        /// 四角 (UL, UR, LR, LL) 半径点。Corner radii (upper-left … lower-left).
203        fRadii: [Point; 4],
204        /// 分类枚举。`SkRRect::Type`.
205        fType: RRectType,
206    }
207
208    unsafe extern "C++" {
209        include!("include/pathkit_cxx_decl.h");
210
211        /// `pk::SkPath` 不透明句柄。Opaque `pk::SkPath` handle.
212        #[cxx_name = "SkPath"]
213        #[namespace = "pk"]
214        type Path;
215
216        /// `SkPath::Iter` 包装。Wraps `SkPath::Iter`.
217        type PathIterInner;
218        /// `SkPathMeasure` 包装。Wraps `SkPathMeasure`.
219        type PathMeasureHolder;
220        /// `SkPaint` 包装。Wraps `SkPaint`.
221        type PaintHolder;
222        /// `SkStrokeRec` 包装。Wraps `SkStrokeRec`.
223        type StrokeRecHolder;
224        /// `SkPathEffect` 的 `sk_sp` 包装。Wraps `sk_sp<SkPathEffect>`.
225        type PathEffectHolder;
226        /// `SkOpBuilder` 包装。Wraps `SkOpBuilder`.
227        type OpBuilderHolder;
228        /// `SkPathBuilder` 包装。Wraps `SkPathBuilder`.
229        type PathBuilderHolder;
230
231        /// 新建空路径。Create empty path.
232        #[cxx_name = "pk_path_new"]
233        fn path_new() -> UniquePtr<Path>;
234        /// 克隆路径。Clone path.
235        #[cxx_name = "pk_path_clone"]
236        fn path_clone(p: &Path) -> UniquePtr<Path>;
237        /// 重置为空。Reset path to empty.
238        #[cxx_name = "pk_path_reset"]
239        fn path_reset(p: Pin<&mut Path>);
240
241        /// 点数。Point count.
242        #[cxx_name = "pk_path_count_points"]
243        fn path_count_points(p: &Path) -> i32;
244        /// 动词数。Verb count.
245        #[cxx_name = "pk_path_count_verbs"]
246        fn path_count_verbs(p: &Path) -> i32;
247        /// 写入第 `index` 个点。Write point at index.
248        #[cxx_name = "pk_path_get_point"]
249        fn path_get_point(p: &Path, index: i32, out: &mut Point);
250        /// 紧密轴对齐包围盒。Tight bounds (control points).
251        #[cxx_name = "pk_path_compute_tight_bounds"]
252        fn path_compute_tight_bounds(p: &Path, out: &mut Rect);
253        /// 末轮廓是否闭合。Last contour closed.
254        #[cxx_name = "pk_path_is_last_contour_closed"]
255        fn path_is_last_contour_closed(p: &Path) -> bool;
256        /// 保守包含判断。Conservative rect containment.
257        #[cxx_name = "pk_path_conservatively_contains_rect"]
258        fn path_conservatively_contains_rect(p: &Path, r: &Rect) -> bool;
259        /// 若路径为矩形则写出边界与方向。Detect axis rect.
260        #[cxx_name = "pk_path_is_rect"]
261        fn path_is_rect(
262            p: &Path,
263            rect: &mut Rect,
264            is_closed: &mut bool,
265            direction: &mut Direction,
266        ) -> bool;
267        /// 填充内点判断(当前 fill type)。Contains (x,y) in fill.
268        #[cxx_name = "pk_path_contains"]
269        fn path_contains(p: &Path, x: f32, y: f32) -> bool;
270        /// 当前填充类型。Current fill type.
271        #[cxx_name = "pk_path_fill_type_bits"]
272        fn path_fill_type_bits(p: &Path) -> PathFillType;
273        /// 设置填充类型。Set fill type.
274        #[cxx_name = "pk_path_set_fill_type_bits"]
275        fn path_set_fill_type_bits(p: Pin<&mut Path>, v: PathFillType);
276        /// 切换反色填充位。Toggle inverse fill.
277        #[cxx_name = "pk_path_toggle_inverse_fill_type"]
278        fn path_toggle_inverse_fill_type(p: Pin<&mut Path>);
279
280        /// `SkPath::rewind`:清空几何但保留缓冲区。
281        #[cxx_name = "pk_path_rewind"]
282        fn path_rewind(p: Pin<&mut Path>);
283        /// `SkPath::getBounds`(控制点轴对齐包围盒,可能缓存)。
284        #[cxx_name = "pk_path_get_bounds"]
285        fn path_get_bounds(p: &Path, out: &mut Rect);
286        #[cxx_name = "pk_path_is_finite"]
287        fn path_is_finite(p: &Path) -> bool;
288        #[cxx_name = "pk_path_is_convex"]
289        fn path_is_convex(p: &Path) -> bool;
290        #[cxx_name = "pk_path_is_oval"]
291        fn path_is_oval(p: &Path, bounds: &mut Rect) -> bool;
292        #[cxx_name = "pk_path_is_line"]
293        fn path_is_line(p: &Path, p0: &mut Point, p1: &mut Point) -> bool;
294        #[cxx_name = "pk_path_get_points_copy"]
295        fn path_get_points_copy(p: &Path, out: &mut Vec<Point>);
296        #[cxx_name = "pk_path_get_verbs_copy"]
297        fn path_get_verbs_copy(p: &Path, out: &mut Vec<u8>);
298        #[cxx_name = "pk_path_inc_reserve"]
299        fn path_inc_reserve(p: Pin<&mut Path>, extra_pt_count: i32);
300        #[cxx_name = "pk_path_is_interpolatable"]
301        fn path_is_interpolatable(a: &Path, b: &Path) -> bool;
302        #[cxx_name = "pk_path_interpolate"]
303        fn path_interpolate(
304            start: &Path,
305            end: &Path,
306            weight: f32,
307            out: Pin<&mut Path>,
308        ) -> bool;
309        #[cxx_name = "pk_path_get_last_pt"]
310        fn path_get_last_pt(p: &Path, out: &mut Point) -> bool;
311        #[cxx_name = "pk_path_set_last_pt"]
312        fn path_set_last_pt(p: Pin<&mut Path>, x: f32, y: f32);
313        #[cxx_name = "pk_path_segment_masks"]
314        fn path_segment_masks(p: &Path) -> u32;
315        #[cxx_name = "pk_path_has_multiple_contours"]
316        fn path_has_multiple_contours(p: &Path) -> bool;
317        #[cxx_name = "pk_path_add_path_offset"]
318        fn path_add_path_offset(p: Pin<&mut Path>, src: &Path, dx: f32, dy: f32, extend: bool);
319        #[cxx_name = "pk_path_reverse_add_path"]
320        fn path_reverse_add_path(p: Pin<&mut Path>, src: &Path);
321
322        /// `SkPath::transform(matrix, this)`,就地变换。
323        #[cxx_name = "pk_path_transform"]
324        fn path_transform(p: Pin<&mut Path>, mat9: &[f32]);
325        /// `SkPath::transform(matrix, &dst)`,写入 `dst`。
326        #[cxx_name = "pk_path_transform_to"]
327        fn path_transform_to(src: &Path, mat9: &[f32], dst: Pin<&mut Path>);
328
329        // --- `pk::SkMatrix`(9 floats,get9 顺序)---
330        #[cxx_name = "pk_matrix_reset"]
331        fn matrix_reset(m: &mut [f32]);
332        #[cxx_name = "pk_matrix_set_all"]
333        fn matrix_set_all(
334            m: &mut [f32],
335            v0: f32,
336            v1: f32,
337            v2: f32,
338            v3: f32,
339            v4: f32,
340            v5: f32,
341            v6: f32,
342            v7: f32,
343            v8: f32,
344        );
345        #[cxx_name = "pk_matrix_set_translate"]
346        fn matrix_set_translate(m: &mut [f32], dx: f32, dy: f32);
347        #[cxx_name = "pk_matrix_set_scale"]
348        fn matrix_set_scale(m: &mut [f32], sx: f32, sy: f32);
349        #[cxx_name = "pk_matrix_set_scale_pivot"]
350        fn matrix_set_scale_pivot(m: &mut [f32], sx: f32, sy: f32, px: f32, py: f32);
351        #[cxx_name = "pk_matrix_set_rotate"]
352        fn matrix_set_rotate(m: &mut [f32], degrees: f32);
353        #[cxx_name = "pk_matrix_set_rotate_pivot"]
354        fn matrix_set_rotate_pivot(m: &mut [f32], degrees: f32, px: f32, py: f32);
355        #[cxx_name = "pk_matrix_set_sin_cos"]
356        fn matrix_set_sin_cos(m: &mut [f32], sin_v: f32, cos_v: f32);
357        #[cxx_name = "pk_matrix_set_sin_cos_pivot"]
358        fn matrix_set_sin_cos_pivot(m: &mut [f32], sin_v: f32, cos_v: f32, px: f32, py: f32);
359        #[cxx_name = "pk_matrix_set_skew"]
360        fn matrix_set_skew(m: &mut [f32], kx: f32, ky: f32);
361        #[cxx_name = "pk_matrix_set_skew_pivot"]
362        fn matrix_set_skew_pivot(m: &mut [f32], kx: f32, ky: f32, px: f32, py: f32);
363        #[cxx_name = "pk_matrix_set_scale_translate"]
364        fn matrix_set_scale_translate(m: &mut [f32], sx: f32, sy: f32, tx: f32, ty: f32);
365        #[cxx_name = "pk_matrix_set_concat"]
366        fn matrix_set_concat(out: &mut [f32], a: &[f32], b: &[f32]);
367        #[cxx_name = "pk_matrix_pre_translate"]
368        fn matrix_pre_translate(m: &mut [f32], dx: f32, dy: f32);
369        #[cxx_name = "pk_matrix_pre_scale"]
370        fn matrix_pre_scale(m: &mut [f32], sx: f32, sy: f32);
371        #[cxx_name = "pk_matrix_pre_scale_pivot"]
372        fn matrix_pre_scale_pivot(m: &mut [f32], sx: f32, sy: f32, px: f32, py: f32);
373        #[cxx_name = "pk_matrix_pre_rotate"]
374        fn matrix_pre_rotate(m: &mut [f32], degrees: f32);
375        #[cxx_name = "pk_matrix_pre_rotate_pivot"]
376        fn matrix_pre_rotate_pivot(m: &mut [f32], degrees: f32, px: f32, py: f32);
377        #[cxx_name = "pk_matrix_pre_skew"]
378        fn matrix_pre_skew(m: &mut [f32], kx: f32, ky: f32);
379        #[cxx_name = "pk_matrix_pre_skew_pivot"]
380        fn matrix_pre_skew_pivot(m: &mut [f32], kx: f32, ky: f32, px: f32, py: f32);
381        #[cxx_name = "pk_matrix_pre_concat"]
382        fn matrix_pre_concat(m: &mut [f32], other: &[f32]);
383        #[cxx_name = "pk_matrix_post_translate"]
384        fn matrix_post_translate(m: &mut [f32], dx: f32, dy: f32);
385        #[cxx_name = "pk_matrix_post_scale"]
386        fn matrix_post_scale(m: &mut [f32], sx: f32, sy: f32);
387        #[cxx_name = "pk_matrix_post_scale_pivot"]
388        fn matrix_post_scale_pivot(m: &mut [f32], sx: f32, sy: f32, px: f32, py: f32);
389        #[cxx_name = "pk_matrix_post_rotate"]
390        fn matrix_post_rotate(m: &mut [f32], degrees: f32);
391        #[cxx_name = "pk_matrix_post_rotate_pivot"]
392        fn matrix_post_rotate_pivot(m: &mut [f32], degrees: f32, px: f32, py: f32);
393        #[cxx_name = "pk_matrix_post_skew"]
394        fn matrix_post_skew(m: &mut [f32], kx: f32, ky: f32);
395        #[cxx_name = "pk_matrix_post_skew_pivot"]
396        fn matrix_post_skew_pivot(m: &mut [f32], kx: f32, ky: f32, px: f32, py: f32);
397        #[cxx_name = "pk_matrix_post_concat"]
398        fn matrix_post_concat(m: &mut [f32], other: &[f32]);
399        #[cxx_name = "pk_matrix_set_rect_to_rect"]
400        fn matrix_set_rect_to_rect(m: &mut [f32], src: &Rect, dst: &Rect, scale_to_fit: i32) -> bool;
401
402        #[cxx_name = "pk_matrix_get_type"]
403        fn matrix_get_type(m: &[f32]) -> u32;
404        #[cxx_name = "pk_matrix_is_identity"]
405        fn matrix_is_identity(m: &[f32]) -> bool;
406        #[cxx_name = "pk_matrix_is_scale_translate"]
407        fn matrix_is_scale_translate_matrix(m: &[f32]) -> bool;
408        #[cxx_name = "pk_matrix_rect_stays_rect"]
409        fn matrix_rect_stays_rect(m: &[f32]) -> bool;
410        #[cxx_name = "pk_matrix_has_perspective"]
411        fn matrix_has_perspective(m: &[f32]) -> bool;
412        #[cxx_name = "pk_matrix_is_finite_matrix"]
413        fn matrix_is_finite_matrix(m: &[f32]) -> bool;
414        #[cxx_name = "pk_matrix_invert"]
415        fn matrix_invert(src: &[f32], dst: &mut [f32]) -> bool;
416        #[cxx_name = "pk_matrix_map_xy"]
417        fn matrix_map_xy(m: &[f32], x: f32, y: f32, out: &mut Point);
418        #[cxx_name = "pk_matrix_map_rect"]
419        fn matrix_map_rect(m: &[f32], src: &Rect, dst: &mut Rect) -> bool;
420        #[cxx_name = "pk_matrix_map_rect_scale_translate"]
421        fn matrix_map_rect_scale_translate(m: &[f32], src: &Rect, dst: &mut Rect);
422        #[cxx_name = "pk_matrix_map_origin"]
423        fn matrix_map_origin(m: &[f32], out: &mut Point);
424        #[cxx_name = "pk_matrix_get_min_scale"]
425        fn matrix_get_min_scale(m: &[f32]) -> f32;
426        #[cxx_name = "pk_matrix_get_max_scale"]
427        fn matrix_get_max_scale(m: &[f32]) -> f32;
428        #[cxx_name = "pk_matrix_get_min_max_scales"]
429        fn matrix_get_min_max_scales(m: &[f32], min_s: &mut f32, max_s: &mut f32) -> bool;
430        #[cxx_name = "pk_matrix_equals"]
431        fn matrix_equals(a: &[f32], b: &[f32]) -> bool;
432        #[cxx_name = "pk_matrix_write_to_memory"]
433        fn matrix_write_to_memory(m: &[f32], buf: &mut [u8]) -> usize;
434        #[cxx_name = "pk_matrix_read_from_memory"]
435        fn matrix_read_from_memory(m: &mut [f32], buf: &[u8]) -> usize;
436
437        /// moveTo。moveTo.
438        #[cxx_name = "pk_path_move_to"]
439        fn path_move_to(p: Pin<&mut Path>, x: f32, y: f32);
440        /// lineTo。lineTo.
441        #[cxx_name = "pk_path_line_to"]
442        fn path_line_to(p: Pin<&mut Path>, x: f32, y: f32);
443        /// quadTo。quadTo.
444        #[cxx_name = "pk_path_quad_to"]
445        fn path_quad_to(p: Pin<&mut Path>, x1: f32, y1: f32, x2: f32, y2: f32);
446        /// cubicTo。cubicTo.
447        #[cxx_name = "pk_path_cubic_to"]
448        fn path_cubic_to(
449            p: Pin<&mut Path>,
450            x1: f32,
451            y1: f32,
452            x2: f32,
453            y2: f32,
454            x3: f32,
455            y3: f32,
456        );
457        #[cxx_name = "pk_path_conic_to"]
458        fn path_conic_to(
459            p: Pin<&mut Path>,
460            x1: f32,
461            y1: f32,
462            x2: f32,
463            y2: f32,
464            w: f32,
465        );
466        #[cxx_name = "pk_path_arc_to"]
467        fn path_arc_to(p: Pin<&mut Path>, x1: f32, y1: f32, x2: f32, y2: f32, radius: f32);
468        /// close。close.
469        #[cxx_name = "pk_path_close"]
470        fn path_close(p: Pin<&mut Path>);
471        #[cxx_name = "pk_path_add_poly"]
472        fn path_add_poly(p: Pin<&mut Path>, pts: &[Point], close: bool);
473
474        /// addRect。addRect.
475        #[cxx_name = "pk_path_add_rect"]
476        fn path_add_rect(p: Pin<&mut Path>, rect: &Rect, dir: Direction, start: RectCorner);
477        /// addOval。addOval.
478        #[cxx_name = "pk_path_add_oval"]
479        fn path_add_oval(p: Pin<&mut Path>, rect: &Rect, dir: Direction);
480        #[cxx_name = "pk_path_add_oval_start"]
481        fn path_add_oval_start(
482            p: Pin<&mut Path>,
483            rect: &Rect,
484            dir: Direction,
485            start: RectCorner,
486        );
487        /// addCircle。addCircle.
488        #[cxx_name = "pk_path_add_circle"]
489        fn path_add_circle(p: Pin<&mut Path>, cx: f32, cy: f32, radius: f32, dir: Direction);
490        /// addRoundRect。addRoundRect.
491        #[cxx_name = "pk_path_add_round_rect"]
492        fn path_add_round_rect(
493            p: Pin<&mut Path>,
494            rect: &Rect,
495            rx: f32,
496            ry: f32,
497            dir: Direction,
498        );
499        /// addRRect。addRRect.
500        #[cxx_name = "pk_path_add_rrect"]
501        fn path_add_rrect(p: Pin<&mut Path>, rr: &RRect, dir: Direction);
502        /// addRRect 指定起点角。addRRect with start index.
503        #[cxx_name = "pk_path_add_rrect_start"]
504        fn path_add_rrect_start(
505            p: Pin<&mut Path>,
506            rr: &RRect,
507            dir: Direction,
508            start: RectCorner,
509        );
510        /// 若路径为 RRect 则写出。isRRect.
511        #[cxx_name = "pk_path_is_rrect"]
512        fn path_is_rrect(p: &Path, out: &mut RRect) -> bool;
513        /// 与 `SkPath::operator==` 相同:填充类型 + 动词/点/圆锥权重。
514        /// Same as `SkPath::operator==` (fill type, verbs, points, conic weights).
515        #[cxx_name = "pk_path_equals"]
516        fn path_equals(a: &Path, b: &Path) -> bool;
517
518        /// 新建 `SkPathBuilder`。New path builder.
519        #[cxx_name = "pk_path_builder_new"]
520        fn path_builder_new() -> UniquePtr<PathBuilderHolder>;
521        /// reset。reset.
522        #[cxx_name = "pk_path_builder_reset"]
523        fn path_builder_reset(b: Pin<&mut PathBuilderHolder>);
524        /// 当前填充类型。Builder fill type.
525        #[cxx_name = "pk_path_builder_fill_type"]
526        fn path_builder_fill_type(b: &PathBuilderHolder) -> PathFillType;
527        /// 设置填充类型。Set builder fill type.
528        #[cxx_name = "pk_path_builder_set_fill_type"]
529        fn path_builder_set_fill_type(b: Pin<&mut PathBuilderHolder>, ft: PathFillType);
530        /// 切换反色填充。Toggle inverse fill on builder.
531        #[cxx_name = "pk_path_builder_toggle_inverse_fill_type"]
532        fn path_builder_toggle_inverse_fill_type(b: Pin<&mut PathBuilderHolder>);
533        /// snapshot → 路径副本。Snapshot (builder unchanged).
534        #[cxx_name = "pk_path_builder_snapshot"]
535        fn path_builder_snapshot(b: &PathBuilderHolder) -> UniquePtr<Path>;
536        /// detach → 取路径并清空 builder。Detach (resets builder).
537        #[cxx_name = "pk_path_builder_detach"]
538        fn path_builder_detach(b: Pin<&mut PathBuilderHolder>) -> UniquePtr<Path>;
539        /// Builder moveTo。Builder moveTo.
540        #[cxx_name = "pk_path_builder_move_to"]
541        fn path_builder_move_to(b: Pin<&mut PathBuilderHolder>, x: f32, y: f32);
542        /// Builder lineTo。Builder lineTo.
543        #[cxx_name = "pk_path_builder_line_to"]
544        fn path_builder_line_to(b: Pin<&mut PathBuilderHolder>, x: f32, y: f32);
545        /// Builder quadTo。Builder quadTo.
546        #[cxx_name = "pk_path_builder_quad_to"]
547        fn path_builder_quad_to(b: Pin<&mut PathBuilderHolder>, x1: f32, y1: f32, x2: f32, y2: f32);
548        /// Builder cubicTo。Builder cubicTo.
549        #[cxx_name = "pk_path_builder_cubic_to"]
550        fn path_builder_cubic_to(
551            b: Pin<&mut PathBuilderHolder>,
552            x1: f32,
553            y1: f32,
554            x2: f32,
555            y2: f32,
556            x3: f32,
557            y3: f32,
558        );
559        /// Builder close。Builder close.
560        #[cxx_name = "pk_path_builder_close"]
561        fn path_builder_close(b: Pin<&mut PathBuilderHolder>);
562        /// Builder addRect。Builder addRect.
563        #[cxx_name = "pk_path_builder_add_rect"]
564        fn path_builder_add_rect(
565            b: Pin<&mut PathBuilderHolder>,
566            rect: &Rect,
567            dir: Direction,
568            start: RectCorner,
569        );
570        /// Builder addOval。Builder addOval.
571        #[cxx_name = "pk_path_builder_add_oval"]
572        fn path_builder_add_oval(b: Pin<&mut PathBuilderHolder>, rect: &Rect, dir: Direction);
573        /// Builder addCircle。Builder addCircle.
574        #[cxx_name = "pk_path_builder_add_circle"]
575        fn path_builder_add_circle(
576            b: Pin<&mut PathBuilderHolder>,
577            cx: f32,
578            cy: f32,
579            radius: f32,
580            dir: Direction,
581        );
582        /// Builder addRoundRect。Builder addRoundRect.
583        #[cxx_name = "pk_path_builder_add_round_rect"]
584        fn path_builder_add_round_rect(
585            b: Pin<&mut PathBuilderHolder>,
586            rect: &Rect,
587            rx: f32,
588            ry: f32,
589            dir: Direction,
590        );
591        /// Builder addRRect。Builder addRRect.
592        #[cxx_name = "pk_path_builder_add_rrect"]
593        fn path_builder_add_rrect(b: Pin<&mut PathBuilderHolder>, rr: &RRect, dir: Direction);
594        /// Builder addRRect 带起点。Builder addRRect with start.
595        #[cxx_name = "pk_path_builder_add_rrect_start"]
596        fn path_builder_add_rrect_start(
597            b: Pin<&mut PathBuilderHolder>,
598            rr: &RRect,
599            dir: Direction,
600            start: RectCorner,
601        );
602        /// Builder 追加路径几何。Builder addPath.
603        #[cxx_name = "pk_path_builder_add_path"]
604        fn path_builder_add_path(b: Pin<&mut PathBuilderHolder>, src: &Path);
605
606        /// 新建路径迭代器。New path iterator.
607        #[cxx_name = "pk_path_iter_new"]
608        fn path_iter_new(path: &Path, force_close: bool) -> UniquePtr<PathIterInner>;
609        /// 下一步动词与点。Next verb (fills `p0`…`p3`).
610        #[cxx_name = "pk_path_iter_next"]
611        fn path_iter_next(
612            it: Pin<&mut PathIterInner>,
613            p0: &mut Point,
614            p1: &mut Point,
615            p2: &mut Point,
616            p3: &mut Point,
617        ) -> PathVerb;
618
619        /// 空 `PathMeasure`。Empty measure.
620        #[cxx_name = "pk_measure_new"]
621        fn measure_new() -> UniquePtr<PathMeasureHolder>;
622        /// 绑定路径的测量器。Measure from path.
623        #[cxx_name = "pk_measure_from_path"]
624        fn measure_from_path(path: &Path, force_closed: bool, res_scale: f32)
625            -> UniquePtr<PathMeasureHolder>;
626        /// 重新绑定路径。Reset measure path.
627        #[cxx_name = "pk_measure_set_path"]
628        fn measure_set_path(m: Pin<&mut PathMeasureHolder>, path: &Path, force_closed: bool);
629        /// 当前轮廓长度。Contour length.
630        #[cxx_name = "pk_measure_length"]
631        fn measure_length(m: Pin<&mut PathMeasureHolder>) -> f32;
632        /// 距离处位姿与切线。getPosTan.
633        #[cxx_name = "pk_measure_get_pos_tan"]
634        fn measure_get_pos_tan(
635            m: Pin<&mut PathMeasureHolder>,
636            distance: f32,
637            position: &mut Point,
638            tangent: &mut Point,
639        ) -> bool;
640        /// 提取子段到 `dst`。getSegment.
641        #[cxx_name = "pk_measure_get_segment"]
642        fn measure_get_segment(
643            m: Pin<&mut PathMeasureHolder>,
644            start_d: f32,
645            stop_d: f32,
646            dst: Pin<&mut Path>,
647            start_with_move_to: bool,
648        ) -> bool;
649        /// 当前轮廓是否闭合。isClosed.
650        #[cxx_name = "pk_measure_is_closed"]
651        fn measure_is_closed(m: Pin<&mut PathMeasureHolder>) -> bool;
652        /// 下一轮廓。nextContour.
653        #[cxx_name = "pk_measure_next_contour"]
654        fn measure_next_contour(m: Pin<&mut PathMeasureHolder>) -> bool;
655
656        /// 新建 `SkPaint`。New paint.
657        #[cxx_name = "pk_paint_new"]
658        fn paint_new() -> UniquePtr<PaintHolder>;
659        /// 克隆 `SkPaint`。Clone paint.
660        #[cxx_name = "pk_paint_clone"]
661        fn paint_clone(p: &PaintHolder) -> UniquePtr<PaintHolder>;
662        /// setStyle(Fill)。Set fill style.
663        #[cxx_name = "pk_paint_set_fill"]
664        fn paint_set_fill(p: Pin<&mut PaintHolder>);
665        /// 开启/关闭描边。Enable stroke.
666        #[cxx_name = "pk_paint_set_stroke"]
667        fn paint_set_stroke(p: Pin<&mut PaintHolder>, enable: bool);
668        /// 设置 `PaintStyle`。Set paint style.
669        #[cxx_name = "pk_paint_set_style"]
670        fn paint_set_style(p: Pin<&mut PaintHolder>, style: PaintStyle);
671        /// 描边宽度。Stroke width.
672        #[cxx_name = "pk_paint_set_stroke_width"]
673        fn paint_set_stroke_width(p: Pin<&mut PaintHolder>, width: f32);
674        /// Miter 限制。Miter limit.
675        #[cxx_name = "pk_paint_set_stroke_miter"]
676        fn paint_set_stroke_miter(p: Pin<&mut PaintHolder>, miter: f32);
677        /// 线端。Stroke cap.
678        #[cxx_name = "pk_paint_set_stroke_cap"]
679        fn paint_set_stroke_cap(p: Pin<&mut PaintHolder>, cap: StrokeCap);
680        /// 转角。Stroke join.
681        #[cxx_name = "pk_paint_set_stroke_join"]
682        fn paint_set_stroke_join(p: Pin<&mut PaintHolder>, join: StrokeJoin);
683        /// 描边/填充后的填充路径。getFillPath.
684        #[cxx_name = "pk_paint_get_fill_path"]
685        fn paint_get_fill_path(
686            p: &PaintHolder,
687            src: &Path,
688            dst: Pin<&mut Path>,
689        ) -> bool;
690
691        /// 新建 `SkStrokeRec`。New stroke rec.
692        #[cxx_name = "pk_stroke_rec_new"]
693        fn stroke_rec_new(init: StrokeRecInit) -> UniquePtr<StrokeRecHolder>;
694        /// setFillStyle。setFillStyle.
695        #[cxx_name = "pk_stroke_rec_set_fill"]
696        fn stroke_rec_set_fill(p: Pin<&mut StrokeRecHolder>);
697        /// setHairlineStyle。setHairlineStyle.
698        #[cxx_name = "pk_stroke_rec_set_hairline"]
699        fn stroke_rec_set_hairline(p: Pin<&mut StrokeRecHolder>);
700        /// setStrokeStyle。setStrokeStyle.
701        #[cxx_name = "pk_stroke_rec_set_stroke_style"]
702        fn stroke_rec_set_stroke_style(p: Pin<&mut StrokeRecHolder>, width: f32, saf: bool);
703        /// getStyle。getStyle.
704        #[cxx_name = "pk_stroke_rec_get_style"]
705        fn stroke_rec_get_style(p: &StrokeRecHolder) -> StrokeRecStyleTag;
706        /// getWidth。getWidth.
707        #[cxx_name = "pk_stroke_rec_width"]
708        fn stroke_rec_width(p: &StrokeRecHolder) -> f32;
709        /// getCap。getCap.
710        #[cxx_name = "pk_stroke_rec_cap"]
711        fn stroke_rec_cap(p: &StrokeRecHolder) -> StrokeCap;
712        /// setCap(保留 join/miter)。set cap.
713        #[cxx_name = "pk_stroke_rec_set_cap"]
714        fn stroke_rec_set_cap(p: Pin<&mut StrokeRecHolder>, cap: StrokeCap);
715        /// getJoin。getJoin.
716        #[cxx_name = "pk_stroke_rec_join"]
717        fn stroke_rec_join(p: &StrokeRecHolder) -> StrokeJoin;
718        /// setJoin。setJoin.
719        #[cxx_name = "pk_stroke_rec_set_join"]
720        fn stroke_rec_set_join(p: Pin<&mut StrokeRecHolder>, join: StrokeJoin);
721        /// getMiter。getMiter.
722        #[cxx_name = "pk_stroke_rec_miter_limit"]
723        fn stroke_rec_miter_limit(p: &StrokeRecHolder) -> f32;
724        /// setStrokeParams。setStrokeParams.
725        #[cxx_name = "pk_stroke_rec_set_stroke_params"]
726        fn stroke_rec_set_stroke_params(
727            p: Pin<&mut StrokeRecHolder>,
728            cap: StrokeCap,
729            join: StrokeJoin,
730            miter_limit: f32,
731        );
732        /// 描边向外膨胀半径。Inflation radius.
733        #[cxx_name = "pk_stroke_rec_inflation_radius"]
734        fn stroke_rec_inflation_radius(p: &StrokeRecHolder) -> f32;
735        /// 描边到填充路径。applyToPath.
736        #[cxx_name = "pk_stroke_rec_apply_to_path"]
737        fn stroke_rec_apply_to_path(
738            p: &StrokeRecHolder,
739            dst: Pin<&mut Path>,
740            src: &Path,
741        ) -> bool;
742
743        /// 两路径布尔运算写入 `result`。PathOp on two paths.
744        #[cxx_name = "pk_op"]
745        fn boolean_path_op(one: &Path, two: &Path, op: PathOp, result: Pin<&mut Path>) -> bool;
746
747        /// 新建 `SkOpBuilder`。New op builder.
748        #[cxx_name = "pk_op_builder_new"]
749        fn op_builder_new() -> UniquePtr<OpBuilderHolder>;
750        /// add(path, op)。Add path to op builder.
751        #[cxx_name = "pk_op_builder_add"]
752        fn op_builder_add(h: Pin<&mut OpBuilderHolder>, path: &Path, op: PathOp);
753        /// resolve → `result`。Resolve op chain.
754        #[cxx_name = "pk_op_builder_resolve"]
755        fn op_builder_resolve(h: Pin<&mut OpBuilderHolder>, result: Pin<&mut Path>) -> bool;
756
757        /// PathOps 简化。Simplify path.
758        #[cxx_name = "pk_simplify"]
759        fn simplify_path(path: &Path, result: Pin<&mut Path>) -> bool;
760        /// PathOps 紧密包围盒。Tight bounds (pathops).
761        #[cxx_name = "pk_tight_bounds"]
762        fn pathops_tight_bounds(path: &Path, out: &mut Rect) -> bool;
763
764        /// 空 RRect。Empty RRect.
765        #[cxx_name = "pk_rrect_new_empty"]
766        fn rrect_new_empty(out: &mut RRect);
767        /// setRectXY。setRectXY.
768        #[cxx_name = "pk_rrect_set_rect_xy"]
769        fn rrect_set_rect_xy(rr: &mut RRect, rect: &Rect, rx: f32, ry: f32);
770        /// setOval。setOval.
771        #[cxx_name = "pk_rrect_set_oval"]
772        fn rrect_set_oval(rr: &mut RRect, rect: &Rect);
773        /// setRectRadii。setRectRadii.
774        #[cxx_name = "pk_rrect_set_rect_radii"]
775        fn rrect_set_rect_radii(rr: &mut RRect, rect: &Rect, radii: &[Point]);
776        /// isValid。isValid.
777        #[cxx_name = "pk_rrect_is_valid"]
778        fn rrect_is_valid(rr: &RRect) -> bool;
779
780        /// `SkCornerPathEffect`。Corner path effect.
781        #[cxx_name = "pk_corner_effect_make"]
782        fn corner_effect_make(radius: f32) -> UniquePtr<PathEffectHolder>;
783        /// `SkDashPathEffect`。Dash path effect.
784        #[cxx_name = "pk_dash_effect_make"]
785        fn dash_effect_make(intervals: &[f32], phase: f32) -> UniquePtr<PathEffectHolder>;
786        /// PathEffect::filterPath + stroke rec + cull rect。Filter path effect.
787        #[cxx_name = "pk_path_effect_filter"]
788        fn path_effect_filter(
789            e: &PathEffectHolder,
790            dst: Pin<&mut Path>,
791            src: &Path,
792            rec: Pin<&mut StrokeRecHolder>,
793            cull: &Rect,
794        ) -> bool;
795    }
796}