freya_terminal/
colors.rs

1use freya_core::prelude::Color;
2
3/// ANSI 16-color palette (matches WezTerm defaults)
4const ANSI_COLORS: [(u8, u8, u8); 16] = [
5    (0, 0, 0),       // Black
6    (204, 85, 85),   // Red
7    (85, 204, 85),   // Green
8    (215, 215, 0),   // Yellow
9    (84, 85, 203),   // Blue
10    (204, 85, 204),  // Magenta
11    (122, 202, 202), // Cyan
12    (204, 204, 204), // White
13    (85, 85, 85),    // Bright Black
14    (255, 85, 85),   // Bright Red
15    (85, 255, 85),   // Bright Green
16    (255, 255, 0),   // Bright Yellow
17    (85, 85, 255),   // Bright Blue
18    (255, 85, 255),  // Bright Magenta
19    (85, 255, 255),  // Bright Cyan
20    (255, 255, 255), // Bright White
21];
22
23/// 6x6x6 RGB cube levels for 256-color palette
24const RGB_LEVELS: [u8; 6] = [0u8, 95u8, 135u8, 175u8, 215u8, 255u8];
25
26/// Map VT100 color to Skia Color
27///
28/// If `is_bg` is true, Default maps to background color instead of foreground
29pub fn map_vt100_color(
30    c: vt100::Color,
31    is_bg: bool,
32    default_fg: Color,
33    default_bg: Color,
34) -> Color {
35    match c {
36        vt100::Color::Default => {
37            if is_bg {
38                default_bg
39            } else {
40                default_fg
41            }
42        }
43        vt100::Color::Rgb(r, g, b) => Color::from_rgb(r, g, b),
44        vt100::Color::Idx(idx) => {
45            let i = idx as usize;
46
47            // ANSI 16 colors
48            if i < 16 {
49                let (r, g, b) = ANSI_COLORS[i];
50                return Color::from_rgb(r, g, b);
51            }
52
53            // 6x6x6 RGB cube (216 colors, indices 16-231)
54            if (16..=231).contains(&i) {
55                let v = i - 16;
56                let r = v / 36;
57                let g = (v / 6) % 6;
58                let b = v % 6;
59                return Color::from_rgb(RGB_LEVELS[r], RGB_LEVELS[g], RGB_LEVELS[b]);
60            }
61
62            // Grayscale (24 colors, indices 232-255)
63            if (232..=255).contains(&i) {
64                let shade = 8 + ((i - 232) * 10) as u8;
65                return Color::from_rgb(shade, shade, shade);
66            }
67
68            // Fallback
69            if is_bg { default_bg } else { default_fg }
70        }
71    }
72}
73
74/// Map VT100 foreground color to Skia Color
75pub fn map_vt100_fg_color(c: vt100::Color, default_fg: Color, _default_bg: Color) -> Color {
76    map_vt100_color(c, false, default_fg, _default_bg)
77}
78
79/// Map VT100 background color to Skia Color
80pub fn map_vt100_bg_color(c: vt100::Color, _default_fg: Color, default_bg: Color) -> Color {
81    map_vt100_color(c, true, _default_fg, default_bg)
82}