primitives/foundation/colorspace/
alpha.rs

1use super::prelude::*;
2
3use super::*;
4
5/// Defines get alpha getters functionality
6pub trait GetAlpha<C> {
7    /// Retrieve the alpha component
8    fn get_alpha(&self) -> Float;
9    /// Retrieve the alpha component as opacity
10    fn get_opacity(&self) -> Float;
11    /// Retrieve the alpha component as transparency
12    fn get_transparency(&self) -> Float;
13}
14
15/// Defines alpha setters functionality
16pub trait SetAlpha<C> {
17    /// Set the alpha component
18    fn set_alpha(&mut self, alpha: Float) -> &Self;
19    /// Set the alpha component as opacity
20    fn set_opacity(&mut self, opacity: Float) -> &Self;
21    /// Set the alpha component as transparency
22    fn set_transparency(&mut self, transparency: Float) -> &Self;
23}
24
25/// Defines alpha functionality
26pub trait HasAlpha<C>: GetAlpha<C> + SetAlpha<C> {
27    /// Retrieve the color component
28    fn get_color(&self) -> C;
29
30    /// Set the color component
31    fn set_color(&mut self, color: C) -> &Self;
32    
33    /// Retrieve the color and aplha components
34    fn split(&self) -> (C, Float)
35    where
36        Self: Sized,
37    {
38        (self.get_color(), self.get_alpha())
39    }
40}
41
42/// Defines alpha adjustment functionality
43pub trait AdjustAlpha<C>: Clone + SetAlpha<C> {
44    
45    /// Set the alpha component
46    fn alpha(&self, alpha: Float) -> Self {
47        let mut color = self.clone();
48        color.set_alpha(alpha);
49        color
50    }
51
52    /// Set the opacity
53    fn opacity(&self, opacity: Float) -> Self {
54        let mut color = self.clone();
55        color.set_opacity(opacity);
56        color
57    }
58
59    /// Set the transparency
60    fn transparency(&self, transparency: Float) -> Self {
61        let mut color = self.clone();
62        color.set_transparency(transparency);
63        color
64    }
65}
66
67
68/// Represents the color with aplha component
69#[derive(Clone, Copy, Debug)]
70pub struct Alpha<C: ColorSpace> {
71    color: C,
72    alpha: Float,
73}
74
75impl<C: ColorSpace> Alpha<C> {
76    /// Create color with alpha
77    pub fn new(color: C, alpha: Float) -> Self {
78        Self { color, alpha }
79    }
80}
81
82impl<C: ColorSpace> GetAlpha<C> for Alpha<C> {
83    fn get_alpha(&self) -> Float {
84        self.alpha
85    }
86    fn get_opacity(&self) -> Float {
87        self.alpha * 100.
88    }
89    fn get_transparency(&self) -> Float {
90        (1. - self.alpha) * 100.
91    }
92}
93
94impl<C: ColorSpace> SetAlpha<C> for Alpha<C> {
95    fn set_alpha(&mut self, alpha: Float) -> &Self {
96        self.alpha = alpha;
97        self
98    }
99    fn set_opacity(&mut self, opacity: Float) -> &Self {
100        self.alpha = utils::clamp(opacity, 0., 100.) / 100.;
101        self
102    }
103    fn set_transparency(&mut self, transparency: Float) -> &Self {
104        self.alpha = 1. - utils::clamp(transparency, 0., 100.) / 100.;
105        self
106    }
107}
108
109impl<C: ColorSpace> HasAlpha<C> for Alpha<C> {
110    fn get_color(&self) -> C {
111        self.color
112    }
113    fn set_color(&mut self, color: C) -> &Self {
114        self.color = color;
115        self
116    }
117    fn split(&self) -> (C, Float) {
118        (self.color, self.alpha)
119    }
120}
121
122impl GetAlpha<Self> for Color {
123    fn get_alpha(&self) -> Float {
124        self.alpha
125    }
126    fn get_opacity(&self) -> Float {
127        self.alpha * 100.
128    }
129    fn get_transparency(&self) -> Float {
130        (1. - self.alpha) * 100.
131    }
132}
133
134impl SetAlpha<Self> for Color {
135    fn set_alpha(&mut self, alpha: Float) -> &Self {
136        self.alpha = alpha;
137        self
138    }
139    fn set_opacity(&mut self, opacity: Float) -> &Self {
140        self.alpha = opacity / 100.;
141        self
142    }
143    fn set_transparency(&mut self, transparency: Float) -> &Self {
144        self.alpha = 1. - transparency / 100.;
145        self
146    }
147}
148
149impl HasAlpha<Self> for Color {
150    fn get_color(&self) -> Self {
151        *self
152    }
153    fn set_color(&mut self, color: Self) -> &Self {
154        self.red = color.red;
155        self.green = color.green;
156        self.blue = color.blue;
157        self
158    }
159    fn split(&self) -> (Self, Float) {
160        (self.get_color(), self.get_alpha())
161    }
162}
163
164impl GetAlpha<RgbColor> for RgbaColor {
165    fn get_alpha(&self) -> Float {
166        (self.alpha as Float) / 255.0
167    }
168    fn get_opacity(&self) -> Float {
169        self.alpha as Float / 255. * 100.
170    }
171    fn get_transparency(&self) -> Float {
172        (1. - self.alpha as Float / 255.) * 100.
173    }
174}
175
176impl SetAlpha<RgbColor> for RgbaColor {
177    fn set_alpha(&mut self, alpha: Float) -> &Self {
178        self.alpha = (alpha * 255.).round() as u8;
179        self
180    }
181    fn set_opacity(&mut self, opacity: Float) -> &Self {
182        self.alpha = (opacity / 100.).round() as u8;
183        self
184    }
185    fn set_transparency(&mut self, transparency: Float) -> &Self {
186        self.alpha = (1. - transparency / 100.).round() as u8;
187        self
188    }
189}
190
191impl HasAlpha<RgbColor> for RgbaColor {
192    fn get_color(&self) -> RgbColor {
193        (*self).into()
194    }
195    fn set_color(&mut self, color: RgbColor) -> &Self {
196        self.red = color.red;
197        self.green = color.green;
198        self.blue = color.blue;
199        self
200    }
201    fn split(&self) -> (RgbColor, Float) {
202        (self.get_color(), self.get_alpha())
203    }
204}
205
206impl From<Alpha<RgbColor>> for Color {
207    fn from(from_color_with_alpha: Alpha<RgbColor>) -> Self {
208        let mut color: Self = from_color_with_alpha.get_color().into_color();
209        *color.set_alpha(from_color_with_alpha.get_alpha())
210    }
211}
212
213impl From<Alpha<RgbColor>> for RgbaColor {
214    fn from(from_color_with_alpha: Alpha<RgbColor>) -> Self {
215        let mut color: Self = from_color_with_alpha.get_color().into_color();
216        *color.set_alpha(from_color_with_alpha.get_alpha())
217    }
218}
219
220#[cfg(test)]
221mod test {
222    use super::super::prelude::*;
223    
224    use super::super::*;
225
226    #[test]
227    fn new_rgba_from_rgb_with_alpha() {
228        let RgbaColor {
229            red,
230            green,
231            blue,
232            alpha,
233        } = prelude::Alpha::new(RgbColor::new(200, 200, 200), 0.50).into_color();
234        assert_eq!(red, 200);
235        assert_eq!(green, 200);
236        assert_eq!(blue, 200);
237        assert_eq!(alpha, 128);
238    }
239
240    #[test]
241    fn rgb_color_with_alpha() {
242        let prelude::Alpha {
243            color: RgbColor { red, green, blue },
244            alpha,
245        } = prelude::Alpha::new(RgbColor::new(200, 200, 200), 0.5);
246        assert_eq!(red, 200);
247        assert_eq!(green, 200);
248        assert_eq!(blue, 200);
249        assert_eq!(alpha, 0.5);
250    }
251}