pathfinder_path_utils/
orientation.rs1use euclid::Point2D;
12use lyon_path::PathEvent;
13
14#[derive(Clone, Copy, Debug, PartialEq)]
15pub enum Orientation {
16 Ccw = -1,
17 Cw = 1,
18}
19
20impl Orientation {
21 pub fn from_path<I>(stream: I) -> Orientation where I: Iterator<Item = PathEvent> {
23 let (mut from, mut subpath_start) = (Point2D::zero(), Point2D::zero());
24 let mut area = 0.0;
25 for event in stream {
26 match event {
27 PathEvent::MoveTo(to) => {
28 from = to;
29 subpath_start = to;
30 }
31 PathEvent::LineTo(to) => {
32 area += det(&from, &to);
33 from = to;
34 }
35 PathEvent::QuadraticTo(ctrl, to) => {
36 area += det(&from, &ctrl) + det(&ctrl, &to);
37 from = to;
38 }
39 PathEvent::CubicTo(ctrl0, ctrl1, to) => {
40 area += det(&from, &ctrl0) + det(&ctrl0, &ctrl1) + det(&ctrl1, &to);
41 from = to;
42 }
43 PathEvent::Arc(..) => {
44 }
46 PathEvent::Close => {
47 area += det(&from, &subpath_start);
48 from = subpath_start;
49 }
50 }
51 }
52 if area <= 0.0 {
53 Orientation::Ccw
54 } else {
55 Orientation::Cw
56 }
57 }
58}
59
60fn det(a: &Point2D<f32>, b: &Point2D<f32>) -> f32 {
61 a.x * b.y - a.y * b.x
62}