primitives/foundation/colorspace/
alpha.rs1use super::prelude::*;
2
3use super::*;
4
5pub trait GetAlpha<C> {
7 fn get_alpha(&self) -> Float;
9 fn get_opacity(&self) -> Float;
11 fn get_transparency(&self) -> Float;
13}
14
15pub trait SetAlpha<C> {
17 fn set_alpha(&mut self, alpha: Float) -> &Self;
19 fn set_opacity(&mut self, opacity: Float) -> &Self;
21 fn set_transparency(&mut self, transparency: Float) -> &Self;
23}
24
25pub trait HasAlpha<C>: GetAlpha<C> + SetAlpha<C> {
27 fn get_color(&self) -> C;
29
30 fn set_color(&mut self, color: C) -> &Self;
32
33 fn split(&self) -> (C, Float)
35 where
36 Self: Sized,
37 {
38 (self.get_color(), self.get_alpha())
39 }
40}
41
42pub trait AdjustAlpha<C>: Clone + SetAlpha<C> {
44
45 fn alpha(&self, alpha: Float) -> Self {
47 let mut color = self.clone();
48 color.set_alpha(alpha);
49 color
50 }
51
52 fn opacity(&self, opacity: Float) -> Self {
54 let mut color = self.clone();
55 color.set_opacity(opacity);
56 color
57 }
58
59 fn transparency(&self, transparency: Float) -> Self {
61 let mut color = self.clone();
62 color.set_transparency(transparency);
63 color
64 }
65}
66
67
68#[derive(Clone, Copy, Debug)]
70pub struct Alpha<C: ColorSpace> {
71 color: C,
72 alpha: Float,
73}
74
75impl<C: ColorSpace> Alpha<C> {
76 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}