color_core/rgb/
convert.rs

1use super::*;
2use crate::HSLA32;
3
4// region: Constructors of 3 channel u8
5
6// endregion
7// region: Constructors of 4 channel u8
8
9// endregion
10// region: Constructors of 4 channel f32
11
12// endregion
13
14impl From<RGBA32> for RGBA8 {
15    fn from(rgba: RGBA32) -> Self {
16        let rgba = rgba.normalized();
17        Self { r: (rgba.r * 255.0) as u8, g: (rgba.g * 255.0) as u8, b: (rgba.b * 255.0) as u8, a: (rgba.a * 255.0) as u8 }
18    }
19}
20
21impl<T> From<[T; 3]> for RGBA8
22where
23    T: Into<u8> + Copy,
24{
25    fn from(rgba: [T; 3]) -> Self {
26        Self { r: rgba[0].into(), g: rgba[1].into(), b: rgba[2].into(), a: 255 }
27    }
28}
29
30// noinspection DuplicatedCode
31impl<T> From<[T; 4]> for RGBA8
32where
33    T: Into<u8> + Copy,
34{
35    fn from(rgba: [T; 4]) -> Self {
36        Self { r: rgba[0].into(), g: rgba[1].into(), b: rgba[2].into(), a: rgba[3].into() }
37    }
38}
39
40impl From<u32> for RGBA8 {
41    #[track_caller]
42    fn from(rgba: u32) -> Self {
43        // if rgba < 0xFFFFFF00 {
44        //     panic!("Invalid color value: #{:02X}", rgba);
45        // }
46        let [r, g, b, a] = rgba.to_be_bytes();
47        Self { r: r, g, b, a: a }
48    }
49}
50
51impl<T> From<&T> for RGBA32
52where
53    Self: From<<T as ToOwned>::Owned>,
54    T: ToOwned,
55{
56    fn from(rgba: &T) -> Self {
57        rgba.to_owned().into()
58    }
59}
60
61impl From<RGB8> for RGBA32 {
62    fn from(rgb: RGB8) -> Self {
63        RGBA32 { r: rgb.r as f32 / 255.0, g: rgb.g as f32 / 255.0, b: rgb.b as f32 / 255.0, a: 1.0 }
64    }
65}
66
67impl From<RGBA8> for RGBA32 {
68    fn from(rgba: RGBA8) -> Self {
69        Self { r: rgba.r as f32 / 255.0, g: rgba.g as f32 / 255.0, b: rgba.b as f32 / 255.0, a: rgba.a as f32 / 255.0 }
70    }
71}
72
73impl From<HSLA32> for RGBA32 {
74    /// <https://www.w3.org/TR/css-color-4/#hsl-to-rgb>
75    fn from(hsla: HSLA32) -> Self {
76        let HSLA32 { h, s, l, a } = hsla.normalized();
77        let ts = |n: f32| {
78            let k = (n + h * 12.0) % 12.0;
79            let c = s * l.min(1.0 - l);
80            l - c * 1f32.min(k - 3.0).min(9.0 - k).max(-1.0)
81        };
82        Self { r: ts(0.0), g: ts(8.0), b: ts(4.0), a: a }
83    }
84}
85
86impl<T> From<[T; 3]> for RGBA32
87where
88    T: Into<f32> + Copy,
89{
90    fn from(rgba: [T; 3]) -> Self {
91        Self { r: rgba[0].into(), g: rgba[1].into(), b: rgba[2].into(), a: 1.0 }
92    }
93}
94
95impl<T> From<[T; 4]> for RGBA32
96where
97    T: Into<f32> + Copy,
98{
99    fn from(rgba: [T; 4]) -> Self {
100        Self { r: rgba[0].into(), g: rgba[1].into(), b: rgba[2].into(), a: rgba[3].into() }
101    }
102}
103
104impl<R, G, B> From<(R, G, B)> for RGBA32
105where
106    R: Into<f32>,
107    G: Into<f32>,
108    B: Into<f32>,
109{
110    fn from(rgba: (R, G, B)) -> Self {
111        Self { r: rgba.0.into(), g: rgba.1.into(), b: rgba.2.into(), a: 1.0 }
112    }
113}
114
115impl<R, G, B, A> From<(R, G, B, A)> for RGBA32
116where
117    R: Into<f32>,
118    G: Into<f32>,
119    B: Into<f32>,
120    A: Into<f32>,
121{
122    fn from(rgba: (R, G, B, A)) -> Self {
123        Self { r: rgba.0.into(), g: rgba.1.into(), b: rgba.2.into(), a: rgba.3.into() }
124    }
125}
126
127impl From<u32> for RGBA32 {
128    fn from(rgba: u32) -> Self {
129        RGBA8::from(rgba).into()
130    }
131}
132
133impl From<RGBA32> for RGB8 {
134    fn from(rgba: RGBA32) -> Self {
135        let rgba = rgba.normalized();
136        Self { r: (rgba.r * 255.0) as u8, g: (rgba.g * 255.0) as u8, b: (rgba.b * 255.0) as u8, a: () }
137    }
138}