makepad_vector/path/
path.rs1use 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}
16
17impl Path {
18 pub fn new() -> Path {
20 Path::default()
21 }
22
23 pub fn points(&self) -> &[Point] {
25 &self.points
26 }
27
28 pub fn commands(&self) -> Commands {
30 Commands {
31 verbs: self.verbs.iter().cloned(),
32 points: self.points.iter().cloned(),
33 }
34 }
35
36 pub fn points_mut(&mut self) -> &mut [Point] {
38 &mut self.points
39 }
40
41 pub fn move_to(&mut self, p: Point) {
43 self.verbs.push(Verb::MoveTo);
44 self.points.push(p);
45 }
46
47 pub fn line_to(&mut self, p: Point) {
49 self.verbs.push(Verb::LineTo);
50 self.points.push(p);
51 }
52
53 pub fn quadratic_to(&mut self, p1: Point, p: Point) {
55 self.verbs.push(Verb::QuadraticTo);
56 self.points.push(p1);
57 self.points.push(p);
58 }
59
60 pub fn cubic_to(&mut self, p1: Point, p2: Point, p: Point) {
62 self.verbs.push(Verb::QuadraticTo);
63 self.points.push(p1);
64 self.points.push(p2);
65 self.points.push(p);
66 }
67
68
69 pub fn close(&mut self) {
71 self.verbs.push(Verb::Close);
72 }
73
74 pub fn clear(&mut self) {
76 self.verbs.clear();
77 self.points.clear();
78 }
79}
80
81impl ExtendFromInternalIterator<PathCommand> for Path {
82 fn extend_from_internal_iter<I>(&mut self, internal_iter: I)
83 where
84 I: IntoInternalIterator<Item = PathCommand>,
85 {
86 internal_iter.into_internal_iter().for_each(&mut |command| {
87 match command {
88 PathCommand::MoveTo(p) => self.move_to(p),
89 PathCommand::LineTo(p) => self.line_to(p),
90 PathCommand::QuadraticTo(p1, p) => self.quadratic_to(p1, p),
91 PathCommand::CubicTo(p1, p2, p) => self.cubic_to(p1, p2, p),
92 PathCommand::Close => self.close(),
93 }
94 true
95 });
96 }
97}
98
99impl FromInternalIterator<PathCommand> for Path {
100 fn from_internal_iter<I>(internal_iter: I) -> Self
101 where
102 I: IntoInternalIterator<Item = PathCommand>,
103 {
104 let mut path = Path::new();
105 path.extend_from_internal_iter(internal_iter);
106 path
107 }
108}
109
110impl Transform for Path {
111 fn transform<T>(mut self, t: &T) -> Path
112 where
113 T: Transformation,
114 {
115 self.transform_mut(t);
116 self
117 }
118
119 fn transform_mut<T>(&mut self, t: &T)
120 where
121 T: Transformation,
122 {
123 for point in self.points_mut() {
124 point.transform_mut(t);
125 }
126 }
127}
128
129#[derive(Clone, Debug)]
131pub struct Commands<'a> {
132 verbs: Cloned<Iter<'a, Verb>>,
133 points: Cloned<Iter<'a, Point>>,
134}
135
136impl<'a> Iterator for Commands<'a> {
137 type Item = PathCommand;
138
139 fn next(&mut self) -> Option<PathCommand> {
140 self.verbs.next().map(|verb| match verb {
141 Verb::MoveTo => PathCommand::MoveTo(self.points.next().unwrap()),
142 Verb::LineTo => PathCommand::LineTo(self.points.next().unwrap()),
143 Verb::QuadraticTo => {
144 PathCommand::QuadraticTo(self.points.next().unwrap(), self.points.next().unwrap())
145 }
146 Verb::Close => PathCommand::Close,
147 })
148 }
149}
150
151#[derive(Clone, Debug, Eq, Hash, PartialEq)]
152enum Verb {
153 MoveTo,
154 LineTo,
155 QuadraticTo,
156 Close,
157}