os_terminal/
color.rs

1use crate::config::CONFIG;
2use crate::palette::{Palette, DEFAULT_PALETTE_INDEX, PALETTE};
3
4#[repr(u8)]
5#[derive(Debug)]
6#[allow(dead_code)]
7pub enum NamedColor {
8    Black,
9    Red,
10    Green,
11    Yellow,
12    Blue,
13    Magenta,
14    Cyan,
15    White,
16    BrightBlack,
17    BrightRed,
18    BrightGreen,
19    BrightYellow,
20    BrightBlue,
21    BrightMagenta,
22    BrightCyan,
23    BrightWhite,
24}
25
26pub type Rgb = (u8, u8, u8);
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum Color {
30    Indexed(u16),
31    Rgb(Rgb),
32}
33
34impl Color {
35    pub fn to_rgb(self) -> Rgb {
36        match self {
37            Self::Rgb(rgb) => rgb,
38            Self::Indexed(index) => {
39                let color_scheme = CONFIG.color_scheme.lock();
40                match index {
41                    256 => color_scheme.foreground,
42                    257 => color_scheme.background,
43                    index => color_scheme.ansi_colors[index as usize],
44                }
45            }
46        }
47    }
48}
49
50pub struct ColorScheme {
51    pub foreground: Rgb,
52    pub background: Rgb,
53    pub ansi_colors: [Rgb; 256],
54}
55
56impl Default for ColorScheme {
57    fn default() -> Self {
58        Self::new(DEFAULT_PALETTE_INDEX)
59    }
60}
61
62impl ColorScheme {
63    pub fn new(palette_index: usize) -> Self {
64        let palette = PALETTE
65            .get(palette_index)
66            .unwrap_or(&PALETTE[DEFAULT_PALETTE_INDEX]);
67        ColorScheme::from(palette)
68    }
69}
70
71impl From<&Palette> for ColorScheme {
72    fn from(palette: &Palette) -> Self {
73        let mut colors = [(0, 0, 0); 256];
74        colors[..16].copy_from_slice(&palette.ansi_colors);
75
76        for index in 0..216 {
77            let r = index / 36;
78            let g = (index % 36) / 6;
79            let b = index % 6;
80            let scale = |c: usize| if c == 0 { 0 } else { (c * 40 + 55) as u8 };
81            colors[index + 16] = (scale(r), scale(g), scale(b));
82        }
83
84        for gray_level in 0..24 {
85            let index = 16 + 216 + gray_level;
86            let color_value = (gray_level * 10 + 8) as u8;
87            colors[index] = (color_value, color_value, color_value);
88        }
89
90        Self {
91            foreground: palette.foreground,
92            background: palette.background,
93            ansi_colors: colors,
94        }
95    }
96}