use egui::Color32;
pub trait HexColor: Sized {
fn from_hex(hex: &str) -> Self;
fn from_hex_premultiplied(hex: &str) -> Self;
}
impl HexColor for Color32 {
#[inline]
fn from_hex(hex: &str) -> Self {
let (r, g, b, a) = parse_hex_to_rgba(hex);
Self::from_rgba_unmultiplied(r, g, b, a)
}
#[inline]
fn from_hex_premultiplied(hex: &str) -> Self {
let (r, g, b, a) = parse_hex_to_rgba(hex);
Self::from_rgba_premultiplied(r, g, b, a)
}
}
fn parse_hex_to_rgba(hex: &str) -> (u8, u8, u8, u8) {
let bytes = hex.as_bytes();
let start = match bytes {
[b'0', b'x', ..] => 2,
[b'#', ..] => 1,
_ => 0,
};
let s = &bytes[start..];
fn hv(b: u8) -> u8 {
match b {
b'0'..=b'9' => b - b'0',
b'a'..=b'f' => b - b'a' + 10,
b'A'..=b'F' => b - b'A' + 10,
_ => 0,
}
}
match s.len() {
3 => (
(hv(s[0]) << 4) | hv(s[0]),
(hv(s[1]) << 4) | hv(s[1]),
(hv(s[2]) << 4) | hv(s[2]),
255,
),
4 => (
(hv(s[0]) << 4) | hv(s[0]),
(hv(s[1]) << 4) | hv(s[1]),
(hv(s[2]) << 4) | hv(s[2]),
(hv(s[3]) << 4) | hv(s[3]),
),
6 => (
(hv(s[0]) << 4) | hv(s[1]),
(hv(s[2]) << 4) | hv(s[3]),
(hv(s[4]) << 4) | hv(s[5]),
255,
),
8 => (
(hv(s[0]) << 4) | hv(s[1]),
(hv(s[2]) << 4) | hv(s[3]),
(hv(s[4]) << 4) | hv(s[5]),
(hv(s[6]) << 4) | hv(s[7]),
),
_ => (0, 0, 0, 255),
}
}