1use crate::geom::Point2;
8
9pub struct Path {
11 path: lyon::path::Path,
12}
13
14pub struct Builder {
16 builder: lyon::path::path::Builder,
17}
18
19impl Path {
20 pub fn builder() -> Builder {
22 Builder::new()
23 }
24
25 pub fn new() -> Self {
27 lyon::path::Path::new().into()
28 }
29
30 pub fn as_slice(&self) -> lyon::path::PathSlice {
32 self.path.as_slice()
33 }
34
35 pub fn attributes(&self, endpoint: lyon::path::EndpointId) -> &[f32] {
37 self.path.attributes(endpoint)
38 }
39
40 pub fn iter(&self) -> lyon::path::path::Iter {
42 self.path.iter()
43 }
44
45 pub fn id_iter(&self) -> lyon::path::path::IdIter {
47 self.path.id_iter()
48 }
49
50 pub fn iter_with_attributes(&self) -> lyon::path::path::IterWithAttributes {
52 self.path.iter_with_attributes()
53 }
54
55 pub fn transformed<T>(self, transform: &T) -> Self
58 where
59 T: lyon::geom::traits::Transformation<f32>,
60 {
61 self.path.transformed(transform).into()
62 }
63
64 pub fn reversed(&self) -> Self {
66 self.path.reversed().into()
67 }
68
69 pub fn merge(&self, other: &Self) -> Self {
71 Self {
72 path: self.path.iter().chain(other.iter()).collect(),
73 }
74 }
75}
76
77impl Builder {
78 pub fn new() -> Self {
80 lyon::path::path::Builder::new().into()
81 }
82
83 pub fn with_capacity(points: usize, edges: usize) -> Self {
85 lyon::path::path::Builder::with_capacity(points, edges).into()
86 }
87
88 pub fn with_svg(self) -> lyon::path::builder::WithSvg<Self> {
90 lyon::path::builder::WithSvg::new(self)
91 }
92
93 pub fn flattened(self, tolerance: f32) -> lyon::path::builder::Flattened<Self> {
95 lyon::path::builder::Flattened::new(self, tolerance)
96 }
97
98 pub fn begin(mut self, to: Point2) -> Self {
102 self.builder.begin(to.to_array().into());
103 self
104 }
105
106 pub fn line_to(mut self, to: Point2) -> Self {
108 self.builder.line_to(to.to_array().into());
109 self
110 }
111
112 pub fn close(mut self) -> Self {
115 self.builder.close();
116 self
117 }
118
119 pub fn quadratic_bezier_to(mut self, ctrl: Point2, to: Point2) -> Self {
121 self.builder
122 .quadratic_bezier_to(ctrl.to_array().into(), to.to_array().into());
123 self
124 }
125
126 pub fn cubic_bezier_to(mut self, ctrl1: Point2, ctrl2: Point2, to: Point2) -> Self {
128 self.builder.cubic_bezier_to(
129 ctrl1.to_array().into(),
130 ctrl2.to_array().into(),
131 to.to_array().into(),
132 );
133 self
134 }
135
136 pub fn build(self) -> Path {
138 self.builder.build().into()
139 }
140
141 pub fn inner(&self) -> &lyon::path::path::Builder {
143 &self.builder
144 }
145
146 pub fn inner_mut(&mut self) -> &mut lyon::path::path::Builder {
148 &mut self.builder
149 }
150}
151
152impl lyon::path::builder::Build for Builder {
155 type PathType = Path;
156
157 fn build(self) -> Self::PathType {
158 self.builder.build().into()
159 }
160}
161
162impl lyon::path::builder::PathBuilder for Builder {
163 fn quadratic_bezier_to(
164 &mut self,
165 ctrl: lyon::math::Point,
166 to: lyon::math::Point,
167 ) -> lyon::path::EndpointId {
168 self.builder.quadratic_bezier_to(ctrl, to)
169 }
170
171 fn cubic_bezier_to(
172 &mut self,
173 ctrl1: lyon::math::Point,
174 ctrl2: lyon::math::Point,
175 to: lyon::math::Point,
176 ) -> lyon::path::EndpointId {
177 self.builder.cubic_bezier_to(ctrl1, ctrl2, to)
178 }
179
180 fn begin(&mut self, at: lyon::math::Point) -> lyon::path::EndpointId {
181 self.builder.begin(at)
182 }
183
184 fn end(&mut self, close: bool) {
185 self.builder.end(close)
186 }
187
188 fn line_to(&mut self, to: lyon::math::Point) -> lyon::path::EndpointId {
189 self.builder.line_to(to)
190 }
191}
192
193impl std::ops::Index<lyon::path::ControlPointId> for Path {
196 type Output = Point2;
197 fn index(&self, id: lyon::path::ControlPointId) -> &Self::Output {
198 point_lyon_to_nannou(self.path.index(id))
199 }
200}
201
202impl std::ops::Index<lyon::path::EndpointId> for Path {
203 type Output = Point2;
204 fn index(&self, id: lyon::path::EndpointId) -> &Self::Output {
205 point_lyon_to_nannou(self.path.index(id))
206 }
207}
208
209impl<'a> IntoIterator for &'a Path {
212 type Item = lyon::path::PathEvent;
213 type IntoIter = lyon::path::path::Iter<'a>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 self.iter()
217 }
218}
219
220impl From<lyon::path::Path> for Path {
223 fn from(path: lyon::path::Path) -> Self {
224 Path { path }
225 }
226}
227
228impl From<lyon::path::path::Builder> for Builder {
229 fn from(builder: lyon::path::path::Builder) -> Self {
230 Builder { builder }
231 }
232}
233
234impl Into<lyon::path::Path> for Path {
235 fn into(self) -> lyon::path::Path {
236 self.path
237 }
238}
239
240impl Into<lyon::path::path::Builder> for Builder {
241 fn into(self) -> lyon::path::path::Builder {
242 self.builder
243 }
244}
245
246impl<'a> Into<lyon::path::PathSlice<'a>> for &'a Path {
247 fn into(self) -> lyon::path::PathSlice<'a> {
248 self.as_slice()
249 }
250}
251
252pub fn path() -> Builder {
256 Builder::new()
257}
258
259pub fn path_with_capacity(points: usize, edges: usize) -> Builder {
261 Builder::with_capacity(points, edges)
262}
263
264fn point_lyon_to_nannou(p: &lyon::math::Point) -> &Point2 {
270 unsafe { std::mem::transmute(p) }
271}