1use palette::{FromColor, LinSrgba, Srgba};
2
3use crate::scene::ColorLinPremul;
4
5impl ColorLinPremul {
7 #[inline]
9 pub fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
10 Self::from_srgba_u8([r, g, b, a])
11 }
12
13 #[inline]
15 pub fn from_srgba_u8(c: [u8; 4]) -> Self {
16 let s = Srgba::new(
17 c[0] as f32 / 255.0,
18 c[1] as f32 / 255.0,
19 c[2] as f32 / 255.0,
20 c[3] as f32 / 255.0,
21 );
22 let lin: LinSrgba = LinSrgba::from_color(s);
23 Self {
24 r: lin.red * lin.alpha,
25 g: lin.green * lin.alpha,
26 b: lin.blue * lin.alpha,
27 a: lin.alpha,
28 }
29 }
30
31 #[inline]
33 pub fn from_srgba(r: u8, g: u8, b: u8, a: f32) -> Self {
34 let s = Srgba::new(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, a);
35 let lin: LinSrgba = LinSrgba::from_color(s);
36 Self {
37 r: lin.red * lin.alpha,
38 g: lin.green * lin.alpha,
39 b: lin.blue * lin.alpha,
40 a: lin.alpha,
41 }
42 }
43
44 #[inline]
46 pub fn from_lin_rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
47 Self {
48 r: r * a,
49 g: g * a,
50 b: b * a,
51 a,
52 }
53 }
54
55 #[inline]
57 pub fn to_srgba_u8(&self) -> [u8; 4] {
58 let (r, g, b) = if self.a > 0.0001 {
60 (self.r / self.a, self.g / self.a, self.b / self.a)
61 } else {
62 (0.0, 0.0, 0.0)
63 };
64
65 let lin = LinSrgba::new(r, g, b, self.a);
67 let srgb: Srgba = Srgba::from_color(lin);
68
69 [
70 (srgb.red * 255.0).round().clamp(0.0, 255.0) as u8,
71 (srgb.green * 255.0).round().clamp(0.0, 255.0) as u8,
72 (srgb.blue * 255.0).round().clamp(0.0, 255.0) as u8,
73 (srgb.alpha * 255.0).round().clamp(0.0, 255.0) as u8,
74 ]
75 }
76}