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}