os_terminal/
color.rs

1use vte::ansi::Color;
2
3use crate::config::CONFIG;
4use crate::palette::{DEFAULT_PALETTE_INDEX, PALETTE, Palette};
5
6pub type Rgb = (u8, u8, u8);
7
8pub trait ToRgb {
9    fn to_rgb(self) -> Rgb;
10}
11
12impl ToRgb for Color {
13    fn to_rgb(self) -> Rgb {
14        match self {
15            Self::Spec(rgb) => (rgb.r, rgb.g, rgb.b),
16            Self::Named(color) => {
17                let color_scheme = CONFIG.color_scheme.lock();
18                match color as usize {
19                    256 => color_scheme.foreground,
20                    257 => color_scheme.background,
21                    index => color_scheme.ansi_colors[index],
22                }
23            }
24            Self::Indexed(index) => {
25                let color_scheme = CONFIG.color_scheme.lock();
26                color_scheme.ansi_colors[index as usize]
27            }
28        }
29    }
30}
31
32pub struct ColorScheme {
33    pub foreground: Rgb,
34    pub background: Rgb,
35    pub ansi_colors: [Rgb; 256],
36}
37
38impl Default for ColorScheme {
39    fn default() -> Self {
40        Self::new(DEFAULT_PALETTE_INDEX)
41    }
42}
43
44impl ColorScheme {
45    pub fn new(palette_index: usize) -> Self {
46        let palette = PALETTE
47            .get(palette_index)
48            .unwrap_or(&PALETTE[DEFAULT_PALETTE_INDEX]);
49        ColorScheme::from(palette)
50    }
51}
52
53impl From<&Palette> for ColorScheme {
54    fn from(palette: &Palette) -> Self {
55        let mut colors = [(0, 0, 0); 256];
56        colors[..16].copy_from_slice(&palette.ansi_colors);
57
58        for index in 0..216 {
59            let r = index / 36;
60            let g = (index % 36) / 6;
61            let b = index % 6;
62            let scale = |c: usize| if c == 0 { 0 } else { (c * 40 + 55) as u8 };
63            colors[index + 16] = (scale(r), scale(g), scale(b));
64        }
65
66        for gray_level in 0..24 {
67            let index = 16 + 216 + gray_level;
68            let color_value = (gray_level * 10 + 8) as u8;
69            colors[index] = (color_value, color_value, color_value);
70        }
71
72        Self {
73            foreground: palette.foreground,
74            background: palette.background,
75            ansi_colors: colors,
76        }
77    }
78}