1use crate::path::PathCommand;
2use crate::geometry::{Point, Transform, Transformation};
3use crate::internal_iter::{
4 ExtendFromInternalIterator, FromInternalIterator, InternalIterator, IntoInternalIterator,
5};
6use std::iter::Cloned;
7use std::slice::Iter;
8
9#[derive(Clone, Debug, Default, PartialEq)]
12pub struct Path {
13 verbs: Vec<Verb>,
14 points: Vec<Point>,
15 arc_params: Vec<ArcParams>,
16}
17
18#[derive(Clone, Debug, Default, PartialEq)]
19struct ArcParams {
20 pub xr: f64, pub l: bool, pub s: bool, }
24
25impl Path {
26 pub fn new() -> Path {
28 Path::default()
29 }
30
31 pub fn points(&self) -> &[Point] {
33 &self.points
34 }
35
36 pub fn commands(&self) -> Commands {
38 Commands {
39 verbs: self.verbs.iter().cloned(),
40 points: self.points.iter().cloned(),
41 arc_params: self.arc_params.iter().cloned(),
42 }
43 }
44
45 pub fn points_mut(&mut self) -> &mut [Point] {
47 &mut self.points
48 }
49
50 pub fn arc(&mut self, e: Point, r: Point, xr: f64, l: bool, s: bool) {
51 self.verbs.push(Verb::ArcTo);
52 self.points.push(e);
53 self.points.push(r);
54 self.arc_params.push(ArcParams{ xr, l, s });
55 }
56
57 pub fn move_to(&mut self, p: Point) {
59 self.verbs.push(Verb::MoveTo);
60 self.points.push(p);
61 }
62
63 pub fn line_to(&mut self, p: Point) {
65 self.verbs.push(Verb::LineTo);
66 self.points.push(p);
67 }
68
69 pub fn quadratic_to(&mut self, p1: Point, p: Point) {
71 self.verbs.push(Verb::QuadraticTo);
72 self.points.push(p1);
73 self.points.push(p);
74 }
75
76 pub fn cubic_to(&mut self, p1: Point, p2: Point, p: Point) {
78 self.verbs.push(Verb::QuadraticTo);
79 self.points.push(p1);
80 self.points.push(p2);
81 self.points.push(p);
82 }
83
84
85 pub fn close(&mut self) {
87 self.verbs.push(Verb::Close);
88 }
89
90 pub fn clear(&mut self) {
92 self.verbs.clear();
93 self.points.clear();
94 self.arc_params.clear();
95 }
96}
97
98impl ExtendFromInternalIterator<PathCommand> for Path {
99 fn extend_from_internal_iter<I>(&mut self, internal_iter: I)
100 where
101 I: IntoInternalIterator<Item = PathCommand>,
102 {
103 internal_iter.into_internal_iter().for_each(&mut |command| {
104 match command {
105 PathCommand::MoveTo(p) => self.move_to(p),
106 PathCommand::LineTo(p) => self.line_to(p),
107 PathCommand::ArcTo(e, r, xr, l, s) => self.arc(e, r, xr, l, s),
108 PathCommand::QuadraticTo(p1, p) => self.quadratic_to(p1, p),
109 PathCommand::CubicTo(p1, p2, p) => self.cubic_to(p1, p2, p),
110 PathCommand::Close => self.close(),
111 }
112 true
113 });
114 }
115}
116
117impl FromInternalIterator<PathCommand> for Path {
118 fn from_internal_iter<I>(internal_iter: I) -> Self
119 where
120 I: IntoInternalIterator<Item = PathCommand>,
121 {
122 let mut path = Path::new();
123 path.extend_from_internal_iter(internal_iter);
124 path
125 }
126}
127
128impl Transform for Path {
129 fn transform<T>(mut self, t: &T) -> Path
130 where
131 T: Transformation,
132 {
133 self.transform_mut(t);
134 self
135 }
136
137 fn transform_mut<T>(&mut self, t: &T)
138 where
139 T: Transformation,
140 {
141 for point in self.points_mut() {
142 point.transform_mut(t);
143 }
144 }
145}
146
147#[derive(Clone, Debug)]
149pub struct Commands<'a> {
150 verbs: Cloned<Iter<'a, Verb>>,
151 points: Cloned<Iter<'a, Point>>,
152 arc_params: Cloned<Iter<'a, ArcParams>>,
153}
154
155impl<'a> Iterator for Commands<'a> {
156 type Item = PathCommand;
157
158 fn next(&mut self) -> Option<PathCommand> {
159 self.verbs.next().map(|verb| match verb {
160 Verb::MoveTo => PathCommand::MoveTo(self.points.next().unwrap()),
161 Verb::LineTo => PathCommand::LineTo(self.points.next().unwrap()),
162 Verb::ArcTo => {
163 let ArcParams{ xr, l, s } = self.arc_params.next().unwrap();
164 PathCommand::ArcTo(self.points.next().unwrap(), self.points.next().unwrap(), xr, l, s)
165 }
166 Verb::QuadraticTo => {
167 PathCommand::QuadraticTo(self.points.next().unwrap(), self.points.next().unwrap())
168 }
169 Verb::Close => PathCommand::Close,
170 })
171 }
172}
173
174#[derive(Clone, Debug, Eq, Hash, PartialEq)]
175enum Verb {
176 MoveTo,
177 LineTo,
178 ArcTo,
179 QuadraticTo,
180 Close,
181}