#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Color {
Rgb(f64, f64, f64),
Gray(f64),
Cmyk(f64, f64, f64, f64),
}
impl Color {
pub const BLACK: Color = Color::Gray(0.0);
pub const WHITE: Color = Color::Gray(1.0);
pub const RED: Color = Color::Rgb(1.0, 0.0, 0.0);
pub const GREEN: Color = Color::Rgb(0.0, 0.8, 0.0);
pub const BLUE: Color = Color::Rgb(0.0, 0.0, 1.0);
pub const DARK_BLUE: Color = Color::Rgb(0.0, 0.2, 0.6);
pub const LIGHT_GRAY: Color = Color::Gray(0.85);
pub const DARK_GRAY: Color = Color::Gray(0.3);
pub fn rgb_u8(r: u8, g: u8, b: u8) -> Self {
Color::Rgb(r as f64 / 255.0, g as f64 / 255.0, b as f64 / 255.0)
}
pub fn from_hex(hex: &str) -> Option<Self> {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 { return None; }
let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
Some(Color::rgb_u8(r, g, b))
}
pub fn fill_op(&self) -> String {
match self {
Color::Rgb(r, g, b) => format!("{:.4} {:.4} {:.4} rg", r, g, b),
Color::Gray(g) => format!("{:.4} g", g),
Color::Cmyk(c, m, y, k) => format!("{:.4} {:.4} {:.4} {:.4} k", c, m, y, k),
}
}
pub fn stroke_op(&self) -> String {
match self {
Color::Rgb(r, g, b) => format!("{:.4} {:.4} {:.4} RG", r, g, b),
Color::Gray(g) => format!("{:.4} G", g),
Color::Cmyk(c, m, y, k) => format!("{:.4} {:.4} {:.4} {:.4} K", c, m, y, k),
}
}
}