skia_safe/core/
path_iter.rs

1use std::{fmt, marker::PhantomData};
2
3use skia_bindings::{
4    self as sb, SkPath, SkPathContourIter, SkPathContourIter_Rec, SkPathIter, SkPathIter_Rec,
5};
6
7use crate::{prelude::*, PathVerb, Point};
8
9#[repr(transparent)]
10pub struct PathIter<'a>(SkPathIter, PhantomData<&'a Handle<SkPath>>);
11
12impl NativeAccess for PathIter<'_> {
13    type Native = SkPathIter;
14
15    fn native(&self) -> &SkPathIter {
16        &self.0
17    }
18    fn native_mut(&mut self) -> &mut SkPathIter {
19        &mut self.0
20    }
21}
22
23impl Drop for PathIter<'_> {
24    fn drop(&mut self) {
25        unsafe { sb::C_SkPathIter_destruct(&mut self.0) }
26    }
27}
28
29impl fmt::Debug for PathIter<'_> {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        f.debug_struct("PathIter").finish()
32    }
33}
34
35#[derive(Copy, Clone)]
36#[repr(transparent)]
37pub struct PathIterRec<'a>(SkPathIter_Rec, PhantomData<&'a ()>);
38
39impl NativeAccess for PathIterRec<'_> {
40    type Native = SkPathIter_Rec;
41
42    fn native(&self) -> &Self::Native {
43        &self.0
44    }
45
46    fn native_mut(&mut self) -> &mut Self::Native {
47        &mut self.0
48    }
49}
50
51impl fmt::Debug for PathIterRec<'_> {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        f.debug_struct("PathIterRec")
54            .field("points", &self.points())
55            .field("conic_weight", &self.conic_weight())
56            .field("verb", &self.verb())
57            .finish()
58    }
59}
60
61impl PathIterRec<'_> {
62    pub fn points(&self) -> &[Point] {
63        unsafe {
64            safer::from_raw_parts(
65                Point::from_native_ptr(self.native().fPoints.fPtr),
66                self.native().fPoints.fSize,
67            )
68        }
69    }
70
71    pub fn conic_weight(&self) -> f32 {
72        self.native().fConicWeight
73    }
74
75    pub fn verb(&self) -> PathVerb {
76        self.native().fVerb
77    }
78}
79
80impl<'a> PathIter<'a> {
81    pub fn new(points: &'a [Point], verbs: &'a [PathVerb], conics: &'a [f32]) -> Self {
82        let iter: SkPathIter = construct(|iter| unsafe {
83            sb::C_SkPathIter_Construct(
84                points.native().as_ptr(),
85                points.len(),
86                verbs.as_ptr(),
87                verbs.len(),
88                conics.as_ptr(),
89                conics.len(),
90                iter,
91            )
92        });
93        Self(iter, PhantomData)
94    }
95
96    pub(crate) fn from_native_c(native: SkPathIter) -> Self {
97        Self(native, PhantomData)
98    }
99}
100
101impl<'a> Iterator for PathIter<'a> {
102    type Item = PathIterRec<'a>;
103
104    /// Holds the current verb, and its associated points
105    /// move:  `points()[0]`
106    /// line:  `points()[0..1]`
107    /// quad:  `points()[0..2]`
108    /// conic: `points()[0..2]` `conic_weight()`
109    /// cubic: `points()[0..3]`
110    /// close: `points()[0..1]` ... as if close were a line from `pts[0]` to `pts[1]`
111    fn next(&mut self) -> Option<Self::Item> {
112        try_construct(|r| unsafe { sb::C_SkPathIter_next(self.native_mut(), r) })
113            .map(|r| PathIterRec(r.into_inner(), PhantomData))
114    }
115}
116
117impl PathIter<'_> {
118    pub fn peek_next_verb(&mut self) -> Option<PathVerb> {
119        let mut verb = PathVerb::Close;
120        unsafe { sb::C_SkPathIter_peekNextVerb(self.native_mut(), &mut verb) }.then_some(verb)
121    }
122}
123
124#[repr(transparent)]
125pub struct PathContourIter<'a>(SkPathContourIter, PhantomData<&'a Handle<SkPath>>);
126
127impl NativeAccess for PathContourIter<'_> {
128    type Native = SkPathContourIter;
129
130    fn native(&self) -> &SkPathContourIter {
131        &self.0
132    }
133    fn native_mut(&mut self) -> &mut SkPathContourIter {
134        &mut self.0
135    }
136}
137
138impl Drop for PathContourIter<'_> {
139    fn drop(&mut self) {
140        unsafe { sb::C_SkPathContourIter_destruct(&mut self.0) }
141    }
142}
143
144impl fmt::Debug for PathContourIter<'_> {
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        f.debug_struct("PathContourIter").finish()
147    }
148}
149
150#[derive(Copy, Clone)]
151#[repr(transparent)]
152pub struct PathContourIterRec<'a>(SkPathContourIter_Rec, PhantomData<&'a ()>);
153
154impl NativeAccess for PathContourIterRec<'_> {
155    type Native = SkPathContourIter_Rec;
156
157    fn native(&self) -> &Self::Native {
158        &self.0
159    }
160
161    fn native_mut(&mut self) -> &mut Self::Native {
162        &mut self.0
163    }
164}
165
166impl fmt::Debug for PathContourIterRec<'_> {
167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168        f.debug_struct("PathContourIterRec")
169            .field("points", &self.points())
170            .field("verb", &self.verbs())
171            .field("conics", &self.conics())
172            .finish()
173    }
174}
175
176impl PathContourIterRec<'_> {
177    pub fn points(&self) -> &[Point] {
178        unsafe {
179            safer::from_raw_parts(
180                Point::from_native_ptr(self.native().fPoints.fPtr),
181                self.native().fPoints.fSize,
182            )
183        }
184    }
185
186    pub fn verbs(&self) -> &[PathVerb] {
187        unsafe { safer::from_raw_parts(self.native().fVerbs.fPtr, self.native().fVerbs.fSize) }
188    }
189
190    pub fn conics(&self) -> &[f32] {
191        unsafe { safer::from_raw_parts(self.native().fConics.fPtr, self.native().fConics.fSize) }
192    }
193}
194
195impl<'a> PathContourIter<'a> {
196    pub fn new(points: &'a [Point], verbs: &'a [PathVerb], conics: &'a [f32]) -> Self {
197        let iter: SkPathContourIter = construct(|iter| unsafe {
198            sb::C_SkPathContourIter_Construct(
199                points.native().as_ptr(),
200                points.len(),
201                verbs.as_ptr(),
202                verbs.len(),
203                conics.as_ptr(),
204                conics.len(),
205                iter,
206            )
207        });
208        Self(iter, PhantomData)
209    }
210
211    #[allow(unused)]
212    pub(crate) fn from_native_c(native: SkPathContourIter) -> Self {
213        Self(native, PhantomData)
214    }
215}
216
217impl<'a> Iterator for PathContourIter<'a> {
218    type Item = PathContourIterRec<'a>;
219
220    fn next(&mut self) -> Option<Self::Item> {
221        try_construct(|r| unsafe { sb::C_SkPathContourIter_next(self.native_mut(), r) })
222            .map(|r| PathContourIterRec(r.into_inner(), PhantomData))
223    }
224}