1use crate::geom::traits::Transformation;
2use crate::math::Point;
3use crate::{ControlPointId, EndpointId, Position};
4
5/// Represents an event or edge of path.
6#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
7#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
8pub enum Event<Endpoint, ControlPoint> {
9 Begin {
10 at: Endpoint,
11 },
12 Line {
13 from: Endpoint,
14 to: Endpoint,
15 },
16 Quadratic {
17 from: Endpoint,
18 ctrl: ControlPoint,
19 to: Endpoint,
20 },
21 Cubic {
22 from: Endpoint,
23 ctrl1: ControlPoint,
24 ctrl2: ControlPoint,
25 to: Endpoint,
26 },
27 End {
28 last: Endpoint,
29 first: Endpoint,
30 close: bool,
31 },
32}
33
34/// A path event representing endpoints and control points as positions.
35pub type PathEvent = Event<Point, Point>;
36
37/// A path event representing endpoints and control points as IDs.
38pub type IdEvent = Event<EndpointId, ControlPointId>;
39
40impl<Ep, Cp> Event<Ep, Cp> {
41 pub fn is_edge(&self) -> bool {
42 match self {
43 &Event::Line { .. }
44 | &Event::Quadratic { .. }
45 | &Event::Cubic { .. }
46 | &Event::End { close: true, .. } => true,
47 _ => false,
48 }
49 }
50
51 pub fn from(&self) -> Ep
52 where
53 Ep: Clone,
54 {
55 match &self {
56 &Event::Line { from, .. }
57 | &Event::Quadratic { from, .. }
58 | &Event::Cubic { from, .. }
59 | &Event::Begin { at: from }
60 | &Event::End { last: from, .. } => from.clone(),
61 }
62 }
63
64 pub fn to(&self) -> Ep
65 where
66 Ep: Clone,
67 {
68 match &self {
69 &Event::Line { to, .. }
70 | &Event::Quadratic { to, .. }
71 | &Event::Cubic { to, .. }
72 | &Event::Begin { at: to }
73 | &Event::End { first: to, .. } => to.clone(),
74 }
75 }
76
77 pub fn with_points(&self) -> PathEvent
78 where
79 Ep: Position,
80 Cp: Position,
81 {
82 match self {
83 Event::Line { from, to } => Event::Line {
84 from: from.position(),
85 to: to.position(),
86 },
87 Event::Quadratic { from, ctrl, to } => Event::Quadratic {
88 from: from.position(),
89 ctrl: ctrl.position(),
90 to: to.position(),
91 },
92 Event::Cubic {
93 from,
94 ctrl1,
95 ctrl2,
96 to,
97 } => Event::Cubic {
98 from: from.position(),
99 ctrl1: ctrl1.position(),
100 ctrl2: ctrl2.position(),
101 to: to.position(),
102 },
103 Event::Begin { at } => Event::Begin { at: at.position() },
104 Event::End { last, first, close } => Event::End {
105 last: last.position(),
106 first: first.position(),
107 close: *close,
108 },
109 }
110 }
111}
112
113impl PathEvent {
114 pub fn transformed<T: Transformation<f32>>(&self, mat: &T) -> Self {
115 match self {
116 Event::Line { from, to } => Event::Line {
117 from: mat.transform_point(*from),
118 to: mat.transform_point(*to),
119 },
120 Event::Quadratic { from, ctrl, to } => Event::Quadratic {
121 from: mat.transform_point(*from),
122 ctrl: mat.transform_point(*ctrl),
123 to: mat.transform_point(*to),
124 },
125 Event::Cubic {
126 from,
127 ctrl1,
128 ctrl2,
129 to,
130 } => Event::Cubic {
131 from: mat.transform_point(*from),
132 ctrl1: mat.transform_point(*ctrl1),
133 ctrl2: mat.transform_point(*ctrl2),
134 to: mat.transform_point(*to),
135 },
136 Event::Begin { at } => Event::Begin {
137 at: mat.transform_point(*at),
138 },
139 Event::End { first, last, close } => Event::End {
140 last: mat.transform_point(*last),
141 first: mat.transform_point(*first),
142 close: *close,
143 },
144 }
145 }
146}
147