1pub trait ToAlpha: Sized {
3 fn to_alpha(&self) -> f32;
5
6 fn fully_opaque(&self) -> bool {
8 self.to_alpha() == 100.0
9 }
10
11 fn fully_transparent(&self) -> bool {
13 self.to_alpha() == 0.0
14 }
15}
16
17pub type Channel = Option<f64>;
22
23pub trait PolarLayout {
25 const HUE_INDEX: Option<usize> = None;
27}
28
29use crate::{
30 A98Rgb, DisplayP3, Hsl, Hwb, Lab, Lch, LinearRgb, Oklab, Oklch, ProphotoRgb, Rec2020, Srgb, XyzD50, XyzD65,
31};
32
33macro_rules! impl_channels {
34 (@cast $v:expr, u8) => { $v.round() as u8 };
35 (@cast $v:expr, f64) => { $v };
36 (@cast $v:expr, f32) => { $v as f32 };
37 ($ty:ident { $f1:ident: $t1:tt, $f2:ident: $t2:tt, $f3:ident: $t3:tt $(,)? }) => {
38 impl_channels!($ty { $f1: $t1, $f2: $t2, $f3: $t3 }, polar = None);
39 };
40 ($ty:ident { $f1:ident: $t1:tt, $f2:ident: $t2:tt, $f3:ident: $t3:tt $(,)? }, polar = $hue:expr) => {
41 impl From<$ty> for [Channel; 4] {
42 fn from(c: $ty) -> Self {
43 [
44 Some(c.$f1 as f64),
45 Some(c.$f2 as f64),
46 Some(c.$f3 as f64),
47 Some(c.alpha as f64),
48 ]
49 }
50 }
51
52 impl From<[Channel; 4]> for $ty {
53 fn from(c: [Channel; 4]) -> Self {
54 $ty::new(
55 impl_channels!(@cast c[0].unwrap_or(0.0), $t1),
56 impl_channels!(@cast c[1].unwrap_or(0.0), $t2),
57 impl_channels!(@cast c[2].unwrap_or(0.0), $t3),
58 c[3].unwrap_or(0.0) as f32,
59 )
60 }
61 }
62
63 impl PolarLayout for $ty {
64 const HUE_INDEX: Option<usize> = $hue;
65 }
66 };
67}
68
69impl_channels!(Srgb { red: u8, green: u8, blue: u8 });
70impl_channels!(LinearRgb { red: f64, green: f64, blue: f64 });
71impl_channels!(A98Rgb { red: f64, green: f64, blue: f64 });
72impl_channels!(DisplayP3 { red: f64, green: f64, blue: f64 });
73impl_channels!(ProphotoRgb { red: f64, green: f64, blue: f64 });
74impl_channels!(Rec2020 { red: f64, green: f64, blue: f64 });
75impl_channels!(Lab { lightness: f64, a: f64, b: f64 });
76impl_channels!(Oklab { lightness: f64, a: f64, b: f64 });
77impl_channels!(XyzD50 { x: f64, y: f64, z: f64 });
78impl_channels!(XyzD65 { x: f64, y: f64, z: f64 });
79impl_channels!(Hsl { hue: f32, saturation: f32, lightness: f32 }, polar = Some(0));
80impl_channels!(Hwb { hue: f32, whiteness: f32, blackness: f32 }, polar = Some(0));
81impl_channels!(Lch { lightness: f64, chroma: f64, hue: f64 }, polar = Some(2));
82impl_channels!(Oklch { lightness: f64, chroma: f64, hue: f64 }, polar = Some(2));