1 use core::ColorInterface;
2 use core::rgb::RGB;
3
4 #[derive(Debug, Copy, Clone, PartialEq)]
5 pub struct HSL {
6 // range 0 ≤ H < 1.0, 0 ≤ S ≤ 1.0 and 0 ≤ L ≤ 1.0:
7 pub h: f32,
8 s: f32,
9 l: f32,
10 }
11
12 impl HSL {
new(h: f32, s: f32, l: f32) -> HSL13 pub fn new(h: f32, s: f32, l: f32) -> HSL {
14 HSL { h: _round(h), s: _round(s), l: _round(l) }
15 }
16
hsl_to_rgb(&self) -> RGB17 pub fn hsl_to_rgb(&self) -> RGB {
18 let red: f32;
19 let green: f32;
20 let blue: f32;
21 let var_1: f32;
22 let var_2: f32;
23 if self.s == 0.0 {
24 let tmp = self.l * 255.0;
25 red = tmp;
26 green = tmp;
27 blue = tmp;
28 } else {
29 if self.l < 0.5 {
30 var_2 = self.l * (1.0 + self.s);
31 } else {
32 var_2 = (self.l + self.s) - (self.s * self.l);
33 }
34 var_1 = 2.0 * self.l - var_2;
35 red = 255.0 * hue_2_rgb(var_1, var_2, &mut (self.h + (1.0 / 3.0)));
36 green = 255.0 * hue_2_rgb(var_1, var_2, &mut self.h.clone());
37 blue = 255.0 * hue_2_rgb(var_1, var_2, &mut (self.h - (1.0 / 3.0)));
38 }
39 RGB::new(red.round() as u8, green.round() as u8, blue.round() as u8)
40 }
41 }
42
43 impl ColorInterface for HSL {
to_color_str(&self) -> String44 fn to_color_str(&self) -> String {
45 self.hsl_to_rgb().to_color_str()
46 }
to_hsl(&self) -> HSL47 fn to_hsl(&self) -> HSL { *self }
48 }
49
hue_2_rgb(v1: f32, v2: f32, vh: &mut f32) -> f3250 fn hue_2_rgb(v1: f32, v2: f32, vh: &mut f32) -> f32 {
51 if *vh < 0.0 {
52 *vh += 1.0;
53 }
54 if *vh > 1.0 {
55 *vh -= 1.0;
56 }
57 if 6.0 * *vh < 1.0 {
58 return v1 + (v2 - v1) * 6.0 * *vh;
59 }
60 if 2.0 * *vh < 1.0 {
61 return v2;
62 }
63 if 3.0 * *vh < 2.0 {
64 return v1 + (v2 - v1) * (2.0 / 3.0 - *vh) * 6.0;
65 }
66 v1
67 }
68
_round(value: f32) -> f3269 fn _round(value: f32) -> f32 {
70 if value < 0.0 {
71 0.0
72 } else if value >= 1.0 {
73 1.0
74 } else {
75 value
76 }
77 }
78
79 #[cfg(test)]
80 mod tests {
81 use super::*;
82
83 #[test]
test_hsl_2_rgb_1()84 fn test_hsl_2_rgb_1() {
85 let hsl = HSL::new(0.7, 0.50, 0.60);
86 let rgb = RGB::new(122, 102, 204);
87
88 assert_eq!(rgb, hsl.hsl_to_rgb());
89 }
90
91 #[test]
test_hsl_2_rgb_2()92 fn test_hsl_2_rgb_2() {
93 let hsl = HSL::new(0.7, 0.0, 0.60);
94 let rgb = RGB::new(153, 153, 153);
95 assert_eq!(rgb, hsl.hsl_to_rgb());
96 }
97
98 #[test]
test_hsl_2_rgb_3()99 fn test_hsl_2_rgb_3() {
100 let hsl = HSL::new(0.7, 0.50, 0.30);
101 let rgb = RGB::new(54, 38, 115);
102
103 assert_eq!(rgb, hsl.hsl_to_rgb());
104 }
105 }