#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
#[cfg_attr(docsrs, doc(cfg(feature = "color")))]
pub struct Color(
pub palette::Srgba<u8>,
);
impl Color {
#[inline]
pub const fn new(red: u8, green: u8, blue: u8, alpha: u8) -> Color {
Color(palette::Alpha {
color: palette::Srgb {
red,
green,
blue,
standard: core::marker::PhantomData,
},
alpha,
})
}
#[inline]
pub const fn into_inner(self) -> palette::Srgba<u8> {
self.0
}
pub const fn to_hex(&self) -> [char; 8] {
[
half_byte_to_hex(self.0.color.red >> 4 & 0x0F),
half_byte_to_hex(self.0.color.red & 0x0F),
half_byte_to_hex(self.0.color.green >> 4 & 0x0F),
half_byte_to_hex(self.0.color.green & 0x0F),
half_byte_to_hex(self.0.color.blue >> 4 & 0x0F),
half_byte_to_hex(self.0.color.blue & 0x0F),
half_byte_to_hex(self.0.alpha >> 4 & 0x0F),
half_byte_to_hex(self.0.alpha & 0x0F),
]
}
}
const fn half_byte_to_hex(half_byte: u8) -> char {
match half_byte {
0 => '0',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
7 => '7',
8 => '8',
9 => '9',
10 => 'A',
11 => 'B',
12 => 'C',
13 => 'D',
14 => 'E',
15 => 'F',
_ => '?',
}
}
impl Color {
pub const RED: Self = Self::new(0xFF, 0x00, 0x00, 0xFF);
pub const CYAN: Self = Self::new(0x00, 0xFF, 0xFF, 0xFF);
pub const BLUE: Self = Self::new(0x00, 0x00, 0xFF, 0xFF);
pub const DARK_BLUE: Self = Self::new(0x00, 0x00, 0xA0, 0xFF);
pub const LIGHT_BLUE: Self = Self::new(0xAD, 0xD8, 0xE6, 0xFF);
pub const PURPLE: Self = Self::new(0x80, 0x00, 0x80, 0xFF);
pub const YELLOW: Self = Self::new(0xFF, 0xFF, 0x00, 0xFF);
pub const LIME: Self = Self::new(0x00, 0xFF, 0x00, 0xFF);
pub const MAGENTA: Self = Self::new(0xFF, 0x00, 0xFF, 0xFF);
pub const WHITE: Self = Self::new(0xFF, 0xFF, 0xFF, 0xFF);
pub const SLIVER: Self = Self::new(0xC0, 0xC0, 0xC0, 0xFF);
pub const GRAY: Self = Self::new(0x80, 0x80, 0x80, 0xFF);
pub const BLACK: Self = Self::new(0x00, 0x00, 0x00, 0xFF);
pub const ORANGE: Self = Self::new(0xFF, 0xA5, 0x00, 0xFF);
pub const BROWN: Self = Self::new(0xA5, 0x2A, 0x2A, 0xFF);
pub const MAROON: Self = Self::new(0x80, 0x00, 0x00, 0xFF);
pub const GREEN: Self = Self::new(0x00, 0x80, 0x00, 0xFF);
pub const OLIVE: Self = Self::new(0x80, 0x80, 0x00, 0xFF);
}
impl From<u8> for Color {
#[inline]
fn from(gray: u8) -> Self {
Self(palette::Srgba::new(gray, gray, gray, 255))
}
}
impl From<(u8, u8)> for Color {
#[inline]
fn from(color: (u8, u8)) -> Self {
let (gray, alpha) = color;
Self(palette::Srgba::new(gray, gray, gray, alpha))
}
}
impl From<(u8, u8, u8)> for Color {
#[inline]
fn from(color: (u8, u8, u8)) -> Self {
let (red, green, blue) = color;
Self(palette::Srgba::new(red, green, blue, 255))
}
}
impl From<(u8, u8, u8, u8)> for Color {
#[inline]
fn from(color: (u8, u8, u8, u8)) -> Self {
let (red, green, blue, alpha) = color;
Self(palette::Srgba::new(red, green, blue, alpha))
}
}
impl From<f32> for Color {
#[inline]
fn from(gray: f32) -> Self {
Self(palette::Srgba::new(
(gray * 255.0) as u8,
(gray * 255.0) as u8,
(gray * 255.0) as u8,
255,
))
}
}
impl From<(f32, f32)> for Color {
#[inline]
fn from(color: (f32, f32)) -> Self {
let (gray, alpha) = color;
Self(palette::Srgba::new(
(gray * 255.0) as u8,
(gray * 255.0) as u8,
(gray * 255.0) as u8,
(alpha * 255.0) as u8,
))
}
}
impl From<(f32, f32, f32)> for Color {
#[inline]
fn from(color: (f32, f32, f32)) -> Self {
let (red, green, blue) = color;
Self(palette::Srgba::new(
(red * 255.0) as u8,
(green * 255.0) as u8,
(blue * 255.0) as u8,
255,
))
}
}
impl From<(f32, f32, f32, f32)> for Color {
#[inline]
fn from(color: (f32, f32, f32, f32)) -> Self {
let (red, green, blue, alpha) = color;
Self(palette::Srgba::new(
(red * 255.0) as u8,
(green * 255.0) as u8,
(blue * 255.0) as u8,
(alpha * 255.0) as u8,
))
}
}
impl From<u32> for Color {
#[inline]
fn from(hex: u32) -> Self {
Self(palette::Srgba::from(hex))
}
}