diff options
| author | Martin Haug <mhaug@live.de> | 2022-02-08 21:12:09 +0100 |
|---|---|---|
| committer | Martin Haug <mhaug@live.de> | 2022-02-08 21:12:09 +0100 |
| commit | fe70db1f4ce078f7b41c163a1c0ead31fd04850a (patch) | |
| tree | 0f85390a89a05dc763cbc2eb6c611c48877c08cd /src/geom | |
| parent | 62cf2a19d7207118f115c05c8f7c453d6db77a0a (diff) | |
New color stuff
- CMYK function
- More default colors
- Interpret RGB values as sRGB
Diffstat (limited to 'src/geom')
| -rw-r--r-- | src/geom/paint.rs | 108 |
1 files changed, 100 insertions, 8 deletions
diff --git a/src/geom/paint.rs b/src/geom/paint.rs index f8638656..7342024c 100644 --- a/src/geom/paint.rs +++ b/src/geom/paint.rs @@ -26,12 +26,44 @@ where pub enum Color { /// An 8-bit RGBA color. Rgba(RgbaColor), + /// An 8-bit CMYK color. + Cmyk(CmykColor), +} + +impl Color { + pub const BLACK: Self = Self::Rgba(RgbaColor::new(0x00, 0x00, 0x00, 0xFF)); + pub const GRAY: Self = Self::Rgba(RgbaColor::new(0xAA, 0xAA, 0xAA, 0xFF)); + pub const SILVER: Self = Self::Rgba(RgbaColor::new(0xDD, 0xDD, 0xDD, 0xFF)); + pub const WHITE: Self = Self::Rgba(RgbaColor::new(0xFF, 0xFF, 0xFF, 0xFF)); + pub const NAVY: Self = Self::Rgba(RgbaColor::new(0x00, 0x1f, 0x3f, 0xFF)); + pub const BLUE: Self = Self::Rgba(RgbaColor::new(0x00, 0x74, 0xD9, 0xFF)); + pub const AQUA: Self = Self::Rgba(RgbaColor::new(0x7F, 0xDB, 0xFF, 0xFF)); + pub const TEAL: Self = Self::Rgba(RgbaColor::new(0x39, 0xCC, 0xCC, 0xFF)); + pub const EASTERN: Self = Self::Rgba(RgbaColor::new(0x23, 0x9D, 0xAD, 0xFF)); + pub const PURPLE: Self = Self::Rgba(RgbaColor::new(0xB1, 0x0D, 0xC9, 0xFF)); + pub const FUCHSIA: Self = Self::Rgba(RgbaColor::new(0xF0, 0x12, 0xBE, 0xFF)); + pub const MAROON: Self = Self::Rgba(RgbaColor::new(0x85, 0x14, 0x4b, 0xFF)); + pub const RED: Self = Self::Rgba(RgbaColor::new(0xFF, 0x41, 0x36, 0xFF)); + pub const ORANGE: Self = Self::Rgba(RgbaColor::new(0xFF, 0x85, 0x1B, 0xFF)); + pub const YELLOW: Self = Self::Rgba(RgbaColor::new(0xFF, 0xDC, 0x00, 0xFF)); + pub const OLIVE: Self = Self::Rgba(RgbaColor::new(0x3D, 0x99, 0x70, 0xFF)); + pub const GREEN: Self = Self::Rgba(RgbaColor::new(0x2E, 0xCC, 0x40, 0xFF)); + pub const LIME: Self = Self::Rgba(RgbaColor::new(0x01, 0xFF, 0x70, 0xFF)); + + /// Convert this color to RGBA. + pub fn to_rgba(self) -> RgbaColor { + match self { + Self::Rgba(rgba) => rgba, + Self::Cmyk(cmyk) => cmyk.to_rgba(), + } + } } impl Debug for Color { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Rgba(c) => Debug::fmt(c, f), + Self::Cmyk(c) => Debug::fmt(c, f), } } } @@ -59,19 +91,13 @@ pub struct RgbaColor { } impl RgbaColor { - /// Black color. - pub const BLACK: Self = Self { r: 0, g: 0, b: 0, a: 255 }; - - /// White color. - pub const WHITE: Self = Self { r: 255, g: 255, b: 255, a: 255 }; - /// Construct a new RGBA color. - pub fn new(r: u8, g: u8, b: u8, a: u8) -> Self { + pub const fn new(r: u8, g: u8, b: u8, a: u8) -> Self { Self { r, g, b, a } } /// Construct a new, opaque gray color. - pub fn gray(luma: u8) -> Self { + pub const fn gray(luma: u8) -> Self { Self::new(luma, luma, luma, 255) } } @@ -155,6 +181,72 @@ impl Display for RgbaError { impl std::error::Error for RgbaError {} +/// An 8-bit CMYK color. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct CmykColor { + /// The cyan component. + pub c: u8, + /// The magenta component. + pub m: u8, + /// The yellow component. + pub y: u8, + /// The key (black) component. + pub k: u8, +} + +impl CmykColor { + /// Construct a new CMYK color. + pub const fn new(c: u8, m: u8, y: u8, k: u8) -> Self { + Self { c, m, y, k } + } + + /// Construct a new, opaque gray color as a fraction of true black. + pub fn gray(luma: u8) -> Self { + Self::new( + (luma as f64 * 0.75) as u8, + (luma as f64 * 0.68) as u8, + (luma as f64 * 0.67) as u8, + (luma as f64 * 0.90) as u8, + ) + } + + /// Convert this color to RGBA. + pub fn to_rgba(self) -> RgbaColor { + let k = self.k as f32 / 255.0; + let f = |c| { + let c = c as f32 / 255.0; + (255.0 * (1.0 - c) * (1.0 - k)).round() as u8 + }; + + RgbaColor { + r: f(self.c), + g: f(self.m), + b: f(self.y), + a: 255, + } + } +} + +impl Debug for CmykColor { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let g = |c| c as f64 / 255.0; + write!( + f, + "cmyk({:.1}%, {:.1}%, {:.1}%, {:.1}%)", + g(self.c), + g(self.m), + g(self.y), + g(self.k), + ) + } +} + +impl From<CmykColor> for Color { + fn from(cmyk: CmykColor) -> Self { + Self::Cmyk(cmyk) + } +} + #[cfg(test)] mod tests { use super::*; |
