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}