1use crate::path::Path;
4use crate::point::Point;
5use crate::pathkit;
6
7pub struct PathMeasure {
13 inner: pathkit::SkPathMeasure,
14}
15
16impl PathMeasure {
17 pub fn new() -> Self {
19 Self {
20 inner: unsafe { pathkit::SkPathMeasure::new() },
21 }
22 }
23
24 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 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 pub fn length(&mut self) -> f32 {
46 unsafe { self.inner.getLength() }
47 }
48
49 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 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 pub fn is_closed(&mut self) -> bool {
87 unsafe { self.inner.isClosed() }
88 }
89
90 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}