1
use std::fmt::Debug;
2

            
3
use figures::{Displayable, Points};
4

            
5
use crate::math::{Pixels, Point, Scale, Scaled};
6
use crate::scene::Target;
7
use crate::shape::circle::Circle;
8
use crate::shape::{Fill, Path, Stroke};
9

            
10
3
#[derive(Clone, Debug)]
11
pub enum ShapeGeometry<S> {
12
    Empty,
13
    Path(Path<S>),
14
    Circle(Circle<S>),
15
}
16

            
17
impl<U> ShapeGeometry<U> {
18
    pub fn cast_unit<V>(self) -> ShapeGeometry<V> {
19
        match self {
20
            Self::Empty => ShapeGeometry::Empty,
21
            Self::Path(path) => ShapeGeometry::Path(path.cast_unit()),
22
            Self::Circle(circle) => ShapeGeometry::Circle(circle.cast_unit()),
23
        }
24
    }
25
}
26

            
27
impl ShapeGeometry<Pixels> {
28
3
    pub fn build(
29
3
        &self,
30
3
        builder: &mut easygpu_lyon::ShapeBuilder,
31
3
        stroke: &Option<Stroke>,
32
3
        fill: &Option<Fill>,
33
3
    ) -> crate::Result<()> {
34
3
        match self {
35
            Self::Empty => Ok(()),
36
            Self::Path(path) => path.build(builder, stroke, fill),
37
3
            Self::Circle(circle) => circle.build(builder, stroke, fill),
38
        }
39
3
    }
40
}
41

            
42
impl ShapeGeometry<Pixels> {
43
3
    pub(crate) fn translate_and_convert_to_device(
44
3
        &self,
45
3
        location: Point<f32, Pixels>,
46
3
        scene: &Target,
47
3
    ) -> Self {
48
3
        match self {
49
            Self::Empty => Self::Empty,
50
            Self::Path(path) => Self::Path(path.translate_and_convert_to_device(location, scene)),
51
3
            Self::Circle(circle) => {
52
3
                Self::Circle(circle.translate_and_convert_to_device(location, scene))
53
            }
54
        }
55
3
    }
56
}
57

            
58
impl<S> Default for ShapeGeometry<S> {
59
    fn default() -> Self {
60
        Self::Empty
61
    }
62
}
63

            
64
impl<Src, Dst> std::ops::Mul<Scale<f32, Src, Dst>> for ShapeGeometry<Src> {
65
    type Output = ShapeGeometry<Dst>;
66

            
67
    fn mul(self, rhs: Scale<f32, Src, Dst>) -> Self::Output {
68
        match self {
69
            Self::Empty => Self::Output::Empty,
70
            Self::Path(path) => Self::Output::Path(path * rhs),
71
            Self::Circle(circle) => Self::Output::Circle(circle * rhs),
72
        }
73
    }
74
}
75

            
76
impl Displayable<f32> for ShapeGeometry<Pixels> {
77
    type Pixels = Self;
78
    type Points = ShapeGeometry<Points>;
79
    type Scaled = ShapeGeometry<Scaled>;
80

            
81
    fn to_pixels(&self, _scale: &figures::DisplayScale<f32>) -> Self::Pixels {
82
        self.clone()
83
    }
84

            
85
    fn to_points(&self, scale: &figures::DisplayScale<f32>) -> Self::Points {
86
        match self {
87
            Self::Empty => ShapeGeometry::Empty,
88
            Self::Path(path) => ShapeGeometry::Path(path.to_points(scale)),
89
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_points(scale)),
90
        }
91
    }
92

            
93
    fn to_scaled(&self, scale: &figures::DisplayScale<f32>) -> Self::Scaled {
94
        match self {
95
            Self::Empty => ShapeGeometry::Empty,
96
            Self::Path(path) => ShapeGeometry::Path(path.to_scaled(scale)),
97
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_scaled(scale)),
98
        }
99
    }
100
}
101

            
102
impl Displayable<f32> for ShapeGeometry<Points> {
103
    type Pixels = ShapeGeometry<Pixels>;
104
    type Points = Self;
105
    type Scaled = ShapeGeometry<Scaled>;
106

            
107
    fn to_pixels(&self, scale: &figures::DisplayScale<f32>) -> Self::Pixels {
108
        match self {
109
            Self::Empty => ShapeGeometry::Empty,
110
            Self::Path(path) => ShapeGeometry::Path(path.to_pixels(scale)),
111
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_pixels(scale)),
112
        }
113
    }
114

            
115
    fn to_points(&self, _scale: &figures::DisplayScale<f32>) -> Self::Points {
116
        self.clone()
117
    }
118

            
119
    fn to_scaled(&self, scale: &figures::DisplayScale<f32>) -> Self::Scaled {
120
        match self {
121
            Self::Empty => ShapeGeometry::Empty,
122
            Self::Path(path) => ShapeGeometry::Path(path.to_scaled(scale)),
123
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_scaled(scale)),
124
        }
125
    }
126
}
127

            
128
impl Displayable<f32> for ShapeGeometry<Scaled> {
129
    type Pixels = ShapeGeometry<Pixels>;
130
    type Points = ShapeGeometry<Points>;
131
    type Scaled = Self;
132

            
133
3
    fn to_pixels(&self, scale: &figures::DisplayScale<f32>) -> Self::Pixels {
134
3
        match self {
135
            Self::Empty => ShapeGeometry::Empty,
136
            Self::Path(path) => ShapeGeometry::Path(path.to_pixels(scale)),
137
3
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_pixels(scale)),
138
        }
139
3
    }
140

            
141
    fn to_points(&self, scale: &figures::DisplayScale<f32>) -> Self::Points {
142
        match self {
143
            Self::Empty => ShapeGeometry::Empty,
144
            Self::Path(path) => ShapeGeometry::Path(path.to_points(scale)),
145
            Self::Circle(circle) => ShapeGeometry::Circle(circle.to_points(scale)),
146
        }
147
    }
148

            
149
    fn to_scaled(&self, _scale: &figures::DisplayScale<f32>) -> Self::Scaled {
150
        self.clone()
151
    }
152
}