Skip to main content

path_kit/
path_measure.rs

1//! 路径测量。PathMeasure - measure path length and sample position/tangent.
2
3use crate::path::Path;
4use crate::point::Point;
5use crate::pathkit;
6
7/// 路径测量器,用于获取路径长度、沿路径的位置和切线。
8/// PathMeasure - measures path length and samples position/tangent along path.
9///
10/// 支持多轮廓路径,通过 `next_contour` 遍历。
11/// Supports multi-contour paths; use `next_contour` to iterate.
12pub struct PathMeasure {
13    inner: pathkit::SkPathMeasure,
14}
15
16impl PathMeasure {
17    /// 创建空测量器。Creates empty path measure (no path).
18    pub fn new() -> Self {
19        Self {
20            inner: unsafe { pathkit::SkPathMeasure::new() },
21        }
22    }
23
24    /// 从路径创建测量器。
25    /// Creates path measure from path.
26    ///
27    /// `force_closed` 为 true 时,开放轮廓按闭合计算长度。
28    /// `res_scale` 控制精度,> 1 提高精度(可能变慢)。
29    pub fn from_path(path: &Path, force_closed: bool, res_scale: f32) -> Self {
30        let inner = unsafe {
31            pathkit::SkPathMeasure::new1(path.as_raw() as *const _, force_closed, res_scale)
32        };
33        Self { inner }
34    }
35
36    /// 重置为指定路径。Resets with given path.
37    pub fn set_path(&mut self, path: &Path, force_closed: bool) {
38        unsafe {
39            self.inner.setPath(path.as_raw() as *const _, force_closed);
40        }
41    }
42
43    /// 当前轮廓的总长度,无路径时返回 0。
44    /// Total length of current contour, or 0 if no path.
45    pub fn length(&mut self) -> f32 {
46        unsafe { self.inner.getLength() }
47    }
48
49    /// 在指定距离处的位置和切线。
50    /// Position and tangent at given distance along path.
51    ///
52    /// 距离会被限制在 [0, length] 内。
53    pub fn pos_tan(&mut self, distance: f32) -> Option<(Point, Point)> {
54        let mut position = pathkit::SkPoint { fX: 0.0, fY: 0.0 };
55        let mut tangent = pathkit::SkPoint { fX: 0.0, fY: 0.0 };
56        let ok = unsafe {
57            self.inner.getPosTan(
58                distance,
59                &mut position as *mut _ as *mut pathkit::SkPoint,
60                &mut tangent as *mut _ as *mut pathkit::SkVector,
61            )
62        };
63        if ok {
64            Some((position.into(), tangent.into()))
65        } else {
66            None
67        }
68    }
69
70    /// 提取路径的 [start_d, stop_d] 段。
71    /// Extracts path segment between start_d and stop_d.
72    ///
73    /// `start_with_move_to` 为 true 时,段以 moveTo 开始。
74    pub fn get_segment(&mut self, start_d: f32, stop_d: f32, dst: &mut Path, start_with_move_to: bool) -> bool {
75        unsafe {
76            self.inner.getSegment(
77                start_d,
78                stop_d,
79                dst.as_raw_mut() as *mut _,
80                start_with_move_to,
81            )
82        }
83    }
84
85    /// 当前轮廓是否闭合。Whether current contour is closed.
86    pub fn is_closed(&mut self) -> bool {
87        unsafe { self.inner.isClosed() }
88    }
89
90    /// 移动到下一个轮廓,返回是否还有更多。
91    /// Move to next contour; returns true if more exist.
92    pub fn next_contour(&mut self) -> bool {
93        unsafe { self.inner.nextContour() }
94    }
95}
96
97impl Default for PathMeasure {
98    fn default() -> Self {
99        Self::new()
100    }
101}
102
103impl Drop for PathMeasure {
104    fn drop(&mut self) {
105        unsafe {
106            self.inner.destruct();
107        }
108    }
109}