Skip to main content

path_kit/
path_measure.rs

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