1use crate::bridge::ffi;
4use crate::path::Path;
5use crate::point::Point;
6use cxx::UniquePtr;
7
8pub use crate::bridge::ffi::PathVerb;
11
12#[derive(Debug, Clone)]
14pub enum PathVerbItem {
15 Move(Point),
17 Line(Point, Point),
19 Quad(Point, Point),
21 Conic(Point, Point, f32),
23 Cubic(Point, Point, Point),
25 Close,
27}
28
29impl PathVerbItem {
30 pub fn verb(&self) -> PathVerb {
32 match self {
33 PathVerbItem::Move(_) => PathVerb::Move,
34 PathVerbItem::Line(_, _) => PathVerb::Line,
35 PathVerbItem::Quad(_, _) => PathVerb::Quad,
36 PathVerbItem::Conic(_, _, _) => PathVerb::Conic,
37 PathVerbItem::Cubic(_, _, _) => PathVerb::Cubic,
38 PathVerbItem::Close => PathVerb::Close,
39 }
40 }
41}
42
43pub struct PathIter<'a> {
45 _path: &'a Path,
46 inner: UniquePtr<ffi::PathIterInner>,
47 p0: ffi::Point,
48 p1: ffi::Point,
49 p2: ffi::Point,
50 p3: ffi::Point,
51}
52
53impl<'a> PathIter<'a> {
54 pub(crate) fn new(path: &'a Path, force_close: bool) -> Self {
55 let inner = ffi::path_iter_new(path.as_raw(), force_close);
56 let z = ffi::Point { fX: 0.0, fY: 0.0 };
57 Self {
58 _path: path,
59 inner,
60 p0: z,
61 p1: z,
62 p2: z,
63 p3: z,
64 }
65 }
66}
67
68impl<'a> Iterator for PathIter<'a> {
69 type Item = PathVerbItem;
70
71 fn next(&mut self) -> Option<Self::Item> {
72 let v = ffi::path_iter_next(
73 self.inner.pin_mut(),
74 &mut self.p0,
75 &mut self.p1,
76 &mut self.p2,
77 &mut self.p3,
78 );
79 let item = match v {
80 PathVerb::Move => PathVerbItem::Move(self.p0.into()),
81 PathVerb::Line => PathVerbItem::Line(self.p0.into(), self.p1.into()),
82 PathVerb::Quad => PathVerbItem::Quad(self.p1.into(), self.p2.into()),
83 PathVerb::Conic => PathVerbItem::Conic(self.p1.into(), self.p2.into(), 1.0),
84 PathVerb::Cubic => PathVerbItem::Cubic(
85 self.p1.into(),
86 self.p2.into(),
87 self.p3.into(),
88 ),
89 PathVerb::Close => PathVerbItem::Close,
90 PathVerb::Done => return None,
91 _ => return None,
92 };
93 Some(item)
94 }
95}