rat_theme3/
palette.rs

1use ratatui::style::{Color, Style};
2
3/// Color palette.
4///
5/// This provides the palette used for a theme.
6///
7/// The ideas packed in here are
8/// * provide two colors for highlighting and accents.
9/// * I always want some white, black and gray.
10/// * I don't want to miss out anything, so go once
11///   round the hue in HSV. Take steps of 30° then we
12///   hit pretty much anything interesting.
13/// * Just one variant of each color is not enough, make it 4.
14/// * Background colors need extra considerations. Extend to 8.
15#[derive(Debug, Default, Clone)]
16pub struct Palette {
17    pub name: &'static str,
18
19    pub text_light: Color,
20    pub text_bright: Color,
21    pub text_dark: Color,
22    pub text_black: Color,
23
24    pub white: [Color; 8],
25    pub black: [Color; 8],
26    pub gray: [Color; 8],
27
28    pub red: [Color; 8],
29    pub orange: [Color; 8],
30    pub yellow: [Color; 8],
31    pub limegreen: [Color; 8],
32    pub green: [Color; 8],
33    pub bluegreen: [Color; 8],
34    pub cyan: [Color; 8],
35    pub blue: [Color; 8],
36    pub deepblue: [Color; 8],
37    pub purple: [Color; 8],
38    pub magenta: [Color; 8],
39    pub redpink: [Color; 8],
40
41    pub primary: [Color; 8],
42    pub secondary: [Color; 8],
43}
44
45/// Contrast rating for the text-color that should be used.
46#[derive(Debug)]
47pub enum TextColorRating {
48    /// Use light/white text for the given background.
49    Light,
50    /// Use dark/black text for the given background.
51    Dark,
52}
53
54/// Used to create a high contrast or normal contrast style.
55#[derive(Debug)]
56pub enum Contrast {
57    High,
58    Normal,
59}
60
61impl Palette {
62    /// Color index for a bright variant of the base color.
63    /// Brightness increases with the number.
64    pub const BRIGHT_0: usize = 0;
65    /// Color index for a bright variant of the base color.
66    /// Brightness increases with the number.
67    pub const BRIGHT_1: usize = 1;
68    /// Color index for a bright variant of the base color.
69    /// Brightness increases with the number.
70    pub const BRIGHT_2: usize = 2;
71    /// Color index for a bright variant of the base color.
72    /// Brightness increases with the number.
73    pub const BRIGHT_3: usize = 3;
74    /// Color index for a dark variant of the base color.
75    /// Brightness increases with the number.
76    pub const DARK_0: usize = 4;
77    /// Color index for a dark variant of the base color.
78    /// Brightness increases with the number.
79    pub const DARK_1: usize = 5;
80    /// Color index for a dark variant of the base color.
81    /// Brightness increases with the number.
82    pub const DARK_2: usize = 6;
83    /// Color index for a dark variant of the base color.
84    /// Brightness increases with the number.
85    pub const DARK_3: usize = 7;
86
87    /// Create a style from the given white shade.
88    /// n is `0..=3`
89    pub fn white(&self, n: usize, contrast: Contrast) -> Style {
90        self.style(self.white[n], contrast)
91    }
92
93    /// Create a style from the given black shade.
94    /// n is `0..=3`
95    pub fn black(&self, n: usize, contrast: Contrast) -> Style {
96        self.style(self.black[n], contrast)
97    }
98
99    /// Create a style from the given gray shade.
100    /// n is `0..=3`
101    pub fn gray(&self, n: usize, contrast: Contrast) -> Style {
102        self.style(self.gray[n], contrast)
103    }
104
105    /// Create a style from the given red shade.
106    /// n is `0..=3`
107    pub fn red(&self, n: usize, contrast: Contrast) -> Style {
108        self.style(self.red[n], contrast)
109    }
110
111    /// Create a style from the given orange shade.
112    /// n is `0..=3`
113    pub fn orange(&self, n: usize, contrast: Contrast) -> Style {
114        self.style(self.orange[n], contrast)
115    }
116
117    /// Create a style from the given yellow shade.
118    /// n is `0..=3`
119    pub fn yellow(&self, n: usize, contrast: Contrast) -> Style {
120        self.style(self.yellow[n], contrast)
121    }
122
123    /// Create a style from the given limegreen shade.
124    /// n is `0..=3`
125    pub fn limegreen(&self, n: usize, contrast: Contrast) -> Style {
126        self.style(self.limegreen[n], contrast)
127    }
128
129    /// Create a style from the given green shade.
130    /// n is `0..=3`
131    pub fn green(&self, n: usize, contrast: Contrast) -> Style {
132        self.style(self.green[n], contrast)
133    }
134
135    /// Create a style from the given bluegreen shade.
136    /// n is `0..=3`
137    pub fn bluegreen(&self, n: usize, contrast: Contrast) -> Style {
138        self.style(self.bluegreen[n], contrast)
139    }
140
141    /// Create a style from the given cyan shade.
142    /// n is `0..=3`
143    pub fn cyan(&self, n: usize, contrast: Contrast) -> Style {
144        self.style(self.cyan[n], contrast)
145    }
146
147    /// Create a style from the given blue shade.
148    /// n is `0..=3`
149    pub fn blue(&self, n: usize, contrast: Contrast) -> Style {
150        self.style(self.blue[n], contrast)
151    }
152
153    /// Create a style from the given deepblue shade.
154    /// n is `0..=3`
155    pub fn deepblue(&self, n: usize, contrast: Contrast) -> Style {
156        self.style(self.deepblue[n], contrast)
157    }
158
159    /// Create a style from the given purple shade.
160    /// n is `0..=3`
161    pub fn purple(&self, n: usize, contrast: Contrast) -> Style {
162        self.style(self.purple[n], contrast)
163    }
164
165    /// Create a style from the given magenta shade.
166    /// n is `0..=3`
167    pub fn magenta(&self, n: usize, contrast: Contrast) -> Style {
168        self.style(self.magenta[n], contrast)
169    }
170
171    /// Create a style from the given redpink shade.
172    /// n is `0..=3`
173    pub fn redpink(&self, n: usize, contrast: Contrast) -> Style {
174        self.style(self.redpink[n], contrast)
175    }
176
177    /// Create a style from the given primary shade.
178    /// n is `0..=3`
179    pub fn primary(&self, n: usize, contrast: Contrast) -> Style {
180        self.style(self.primary[n], contrast)
181    }
182
183    /// Create a style from the given secondary shade.
184    /// n is `0..=3`
185    pub fn secondary(&self, n: usize, contrast: Contrast) -> Style {
186        self.style(self.secondary[n], contrast)
187    }
188}
189
190impl Palette {
191    /// Create a style with the given background color and
192    /// contrast.
193    pub fn style(&self, color: Color, contrast: Contrast) -> Style {
194        match contrast {
195            Contrast::High => self.high_contrast(color),
196            Contrast::Normal => self.normal_contrast(color),
197        }
198    }
199
200    /// Create a style with the given background color.
201    /// Uses `white[3]` or `black[0]` for the foreground,
202    /// based on `rate_text_color`.
203    pub fn high_contrast(&self, color: Color) -> Style {
204        match Self::rate_text_color(color) {
205            None => Style::reset(),
206            Some(TextColorRating::Light) => Style::new().bg(color).fg(self.text_bright),
207            Some(TextColorRating::Dark) => Style::new().bg(color).fg(self.text_black),
208        }
209    }
210
211    /// Create a style with the given background color.
212    /// Uses `white[0]` or `black[3]` for the foreground,
213    /// based on `rate_text_color`.
214    pub fn normal_contrast(&self, color: Color) -> Style {
215        match Self::rate_text_color(color) {
216            None => Style::reset(),
217            Some(TextColorRating::Light) => Style::new().bg(color).fg(self.text_light),
218            Some(TextColorRating::Dark) => Style::new().bg(color).fg(self.text_dark),
219        }
220    }
221
222    /// Pick a color from the choice with a good contrast to the
223    /// given background.
224    pub fn normal_contrast_color(&self, bg: Color, text: &[Color]) -> Style {
225        let mut color0 = text[0];
226        let mut color1 = text[0];
227        let mut contrast1 = Self::contrast_bt_srgb(color1, bg);
228
229        for i in 0..text.len() {
230            let test = Self::contrast_bt_srgb(text[i], bg);
231            if test > contrast1 {
232                color0 = color1;
233                color1 = text[i];
234                contrast1 = test;
235            }
236        }
237
238        Style::new().bg(bg).fg(color0)
239    }
240
241    /// Pick a color from the choice with the best contrast to the
242    /// given background.
243    pub fn high_contrast_color(&self, bg: Color, text: &[Color]) -> Style {
244        let mut color0 = text[0];
245        let mut color1 = text[0];
246        let mut contrast1 = Self::contrast_bt_srgb(color1, bg);
247
248        for i in 0..text.len() {
249            let test = Self::contrast_bt_srgb(text[i], bg);
250            if test > contrast1 {
251                color0 = color1;
252                color1 = text[i];
253                contrast1 = test;
254            }
255        }
256        // don't use the second brightest.
257        _ = color0;
258
259        Style::new().bg(bg).fg(color1)
260    }
261
262    // /// Gives the luminance according to Rec.ITU-R BT.601-7.
263    // const fn luminance_itu(color: Color) -> f32 {
264    //     let (r, g, b) = Self::color2rgb(color);
265    //     0.2989f32 * (r as f32) / 255f32
266    //         + 0.5870f32 * (g as f32) / 255f32
267    //         + 0.1140f32 * (b as f32) / 255f32
268    // }
269    //
270    // /// Gives the luminance according to Rec.ITU-R BT.601-7.
271    // fn luminance_itu_srgb(color: Color) -> f32 {
272    //     let (r, g, b) = Self::color2rgb(color);
273    //     0.2989f32 * (r as f32) / 255f32
274    //         + 0.5870f32 * (g as f32) / 255f32
275    //         + 0.1140f32 * (b as f32) / 255f32
276    // }
277    //
278    // /// Contrast between two colors.
279    // fn contrast_itu_srgb(color: Color, color2: Color) -> f32 {
280    //     let lum1 = Self::luminance_itu_srgb(color);
281    //     let lum2 = Self::luminance_itu_srgb(color2);
282    //     (lum1 + 0.05f32) / (lum2 + 0.05f32)
283    // }
284
285    /// Gives the luminance according to BT.709.
286    pub(crate) const fn luminance_bt(color: Color) -> f32 {
287        let (r, g, b) = Self::color2rgb(color);
288        0.2126f32 * ((r as f32) / 255f32)
289            + 0.7152f32 * ((g as f32) / 255f32)
290            + 0.0722f32 * ((b as f32) / 255f32)
291    }
292
293    /// Gives the luminance according to BT.709.
294    pub(crate) fn luminance_bt_srgb(color: Color) -> f32 {
295        let (r, g, b) = Self::color2rgb(color);
296        0.2126f32 * ((r as f32) / 255f32).powf(2.2f32)
297            + 0.7152f32 * ((g as f32) / 255f32).powf(2.2f32)
298            + 0.0722f32 * ((b as f32) / 255f32).powf(2.2f32)
299    }
300
301    /// Contrast between two colors.
302    pub(crate) fn contrast_bt_srgb(color: Color, color2: Color) -> f32 {
303        let lum1 = Self::luminance_bt_srgb(color);
304        let lum2 = Self::luminance_bt_srgb(color2);
305        (lum1 - lum2).abs()
306        // Don't use this prescribed method.
307        // The abs diff comes out better.
308        // (lum1 + 0.05f32) / (lum2 + 0.05f32)
309    }
310
311    /// This gives back a [TextColorRating] for the given background.
312    ///
313    /// This converts RGB to grayscale and takes the grayscale value
314    /// of VGA cyan as threshold, which is about 105 out of 255.
315    /// This point is a bit arbitrary, just based on what I
316    /// perceive as acceptable. But it produces a good reading
317    /// contrast in my experience.
318    ///
319    /// For the named colors it takes the VGA equivalent as a base.
320    /// For indexed colors it splits the range in half as an estimate.
321    pub fn rate_text_color(color: Color) -> Option<TextColorRating> {
322        match color {
323            Color::Reset => None,
324            Color::Black => Some(TextColorRating::Light), //0
325            Color::Red => Some(TextColorRating::Light),   //1
326            Color::Green => Some(TextColorRating::Light), //2
327            Color::Yellow => Some(TextColorRating::Light), //3
328            Color::Blue => Some(TextColorRating::Light),  //4
329            Color::Magenta => Some(TextColorRating::Light), //5
330            Color::Cyan => Some(TextColorRating::Light),  //6
331            Color::Gray => Some(TextColorRating::Dark),   //7
332            Color::DarkGray => Some(TextColorRating::Light), //8
333            Color::LightRed => Some(TextColorRating::Dark), //9
334            Color::LightGreen => Some(TextColorRating::Dark), //10
335            Color::LightYellow => Some(TextColorRating::Dark), //11
336            Color::LightBlue => Some(TextColorRating::Light), //12
337            Color::LightMagenta => Some(TextColorRating::Dark), //13
338            Color::LightCyan => Some(TextColorRating::Dark), //14
339            Color::White => Some(TextColorRating::Dark),  //15
340            c => {
341                let lum = Self::luminance_bt(c);
342                if lum >= 0.4117f32 {
343                    Some(TextColorRating::Dark)
344                } else {
345                    Some(TextColorRating::Light)
346                }
347            }
348        }
349    }
350
351    /// Reduces the range of the given color from 0..255
352    /// to 0..scale_to.
353    ///
354    /// This gives a true dark equivalent which can be used
355    /// as a background for a dark theme.
356    pub const fn darken(color: Color, scale_to: u8) -> Color {
357        let (r, g, b) = Self::color2rgb(color);
358        Color::Rgb(
359            Self::scale_to(r, scale_to),
360            Self::scale_to(g, scale_to),
361            Self::scale_to(b, scale_to),
362        )
363    }
364
365    /// Converts the given color to an equivalent grayscale.
366    pub const fn grayscale(color: Color) -> Color {
367        let lum = Self::luminance_bt(color);
368        let gray = lum * 255f32;
369        Color::Rgb(gray as u8, gray as u8, gray as u8)
370    }
371
372    /// Color from u32
373    pub const fn color32(c0: u32) -> Color {
374        let r0 = (c0 >> 16) as u8;
375        let g0 = (c0 >> 8) as u8;
376        let b0 = c0 as u8;
377        Color::Rgb(r0, g0, b0)
378    }
379
380    /// Calculates a linear interpolation for the two colors
381    /// and fills the first 4 colors with it.
382    /// The next 4 colors are scaled down versions using dark_scale_to.
383    pub const fn interpolate(c0: u32, c1: u32, dark_scale_to: u8) -> [Color; 8] {
384        // 1/3
385        const fn i1(a: u8, b: u8) -> u8 {
386            if a < b {
387                a + (b - a) / 3
388            } else {
389                a - (a - b) / 3
390            }
391        }
392        // 2/3
393        const fn i2(a: u8, b: u8) -> u8 {
394            if a < b {
395                b - (b - a) / 3
396            } else {
397                b + (a - b) / 3
398            }
399        }
400
401        let r0 = (c0 >> 16) as u8;
402        let g0 = (c0 >> 8) as u8;
403        let b0 = c0 as u8;
404
405        let r3 = (c1 >> 16) as u8;
406        let g3 = (c1 >> 8) as u8;
407        let b3 = c1 as u8;
408
409        let r1 = i1(r0, r3);
410        let g1 = i1(g0, g3);
411        let b1 = i1(b0, b3);
412
413        let r2 = i2(r0, r3);
414        let g2 = i2(g0, g3);
415        let b2 = i2(b0, b3);
416
417        // dark
418        let r4 = Self::scale_to(r0, dark_scale_to);
419        let g4 = Self::scale_to(g0, dark_scale_to);
420        let b4 = Self::scale_to(b0, dark_scale_to);
421
422        let r5 = Self::scale_to(r1, dark_scale_to);
423        let g5 = Self::scale_to(g1, dark_scale_to);
424        let b5 = Self::scale_to(b1, dark_scale_to);
425
426        let r6 = Self::scale_to(r2, dark_scale_to);
427        let g6 = Self::scale_to(g2, dark_scale_to);
428        let b6 = Self::scale_to(b2, dark_scale_to);
429
430        let r7 = Self::scale_to(r3, dark_scale_to);
431        let g7 = Self::scale_to(g3, dark_scale_to);
432        let b7 = Self::scale_to(b3, dark_scale_to);
433
434        [
435            Color::Rgb(r0, g0, b0),
436            Color::Rgb(r1, g1, b1),
437            Color::Rgb(r2, g2, b2),
438            Color::Rgb(r3, g3, b3),
439            Color::Rgb(r4, g4, b4),
440            Color::Rgb(r5, g5, b5),
441            Color::Rgb(r6, g6, b6),
442            Color::Rgb(r7, g7, b7),
443        ]
444    }
445
446    /// Scale the u8 down to scale_to.
447    pub const fn scale_to(v: u8, scale_to: u8) -> u8 {
448        (((v as u16) * scale_to as u16) / 255u16) as u8
449    }
450
451    /// Gives back the rgb for any ratatui Color.
452    /// Has the indexed and the named colors too.
453    pub const fn color2rgb(color: Color) -> (u8, u8, u8) {
454        match color {
455            Color::Black => (0x00, 0x00, 0x00),
456            Color::Red => (0xaa, 0x00, 0x00),
457            Color::Green => (0x00, 0xaa, 0x00),
458            Color::Yellow => (0xaa, 0x55, 0x00),
459            Color::Blue => (0x00, 0x00, 0xaa),
460            Color::Magenta => (0xaa, 0x00, 0xaa),
461            Color::Cyan => (0x00, 0xaa, 0xaa),
462            Color::Gray => (0xaa, 0xaa, 0xaa),
463            Color::DarkGray => (0x55, 0x55, 0x55),
464            Color::LightRed => (0xff, 0x55, 0x55),
465            Color::LightGreen => (0x55, 0xff, 0x55),
466            Color::LightYellow => (0xff, 0xff, 0x55),
467            Color::LightBlue => (0x55, 0x55, 0xff),
468            Color::LightMagenta => (0xff, 0x55, 0xff),
469            Color::LightCyan => (0x55, 0xff, 0xff),
470            Color::White => (0xff, 0xff, 0xff),
471            Color::Rgb(r, g, b) => (r, g, b),
472            Color::Indexed(i) => {
473                const VGA256: [(u8, u8, u8); 256] = [
474                    (0x00, 0x00, 0x00),
475                    (0x80, 0x00, 0x00),
476                    (0x00, 0x80, 0x00),
477                    (0x80, 0x80, 0x00),
478                    (0x00, 0x00, 0x80),
479                    (0x80, 0x00, 0x80),
480                    (0x00, 0x80, 0x80),
481                    (0xc0, 0xc0, 0xc0),
482                    (0x80, 0x80, 0x80),
483                    (0xff, 0x00, 0x00),
484                    (0x00, 0xff, 0x00),
485                    (0xff, 0xff, 0x00),
486                    (0x00, 0x00, 0xff),
487                    (0xff, 0x00, 0xff),
488                    (0x00, 0xff, 0xff),
489                    (0xff, 0xff, 0xff),
490                    (0x00, 0x00, 0x00),
491                    (0x00, 0x00, 0x5f),
492                    (0x00, 0x00, 0x87),
493                    (0x00, 0x00, 0xaf),
494                    (0x00, 0x00, 0xd7),
495                    (0x00, 0x00, 0xff),
496                    (0x00, 0x5f, 0x00),
497                    (0x00, 0x5f, 0x5f),
498                    (0x00, 0x5f, 0x87),
499                    (0x00, 0x5f, 0xaf),
500                    (0x00, 0x5f, 0xd7),
501                    (0x00, 0x5f, 0xff),
502                    (0x00, 0x87, 0x00),
503                    (0x00, 0x87, 0x5f),
504                    (0x00, 0x87, 0x87),
505                    (0x00, 0x87, 0xaf),
506                    (0x00, 0x87, 0xd7),
507                    (0x00, 0x87, 0xff),
508                    (0x00, 0xaf, 0x00),
509                    (0x00, 0xaf, 0x5f),
510                    (0x00, 0xaf, 0x87),
511                    (0x00, 0xaf, 0xaf),
512                    (0x00, 0xaf, 0xd7),
513                    (0x00, 0xaf, 0xff),
514                    (0x00, 0xd7, 0x00),
515                    (0x00, 0xd7, 0x5f),
516                    (0x00, 0xd7, 0x87),
517                    (0x00, 0xd7, 0xaf),
518                    (0x00, 0xd7, 0xd7),
519                    (0x00, 0xd7, 0xff),
520                    (0x00, 0xff, 0x00),
521                    (0x00, 0xff, 0x5f),
522                    (0x00, 0xff, 0x87),
523                    (0x00, 0xff, 0xaf),
524                    (0x00, 0xff, 0xd7),
525                    (0x00, 0xff, 0xff),
526                    (0x5f, 0x00, 0x00),
527                    (0x5f, 0x00, 0x5f),
528                    (0x5f, 0x00, 0x87),
529                    (0x5f, 0x00, 0xaf),
530                    (0x5f, 0x00, 0xd7),
531                    (0x5f, 0x00, 0xff),
532                    (0x5f, 0x5f, 0x00),
533                    (0x5f, 0x5f, 0x5f),
534                    (0x5f, 0x5f, 0x87),
535                    (0x5f, 0x5f, 0xaf),
536                    (0x5f, 0x5f, 0xd7),
537                    (0x5f, 0x5f, 0xff),
538                    (0x5f, 0x87, 0x00),
539                    (0x5f, 0x87, 0x5f),
540                    (0x5f, 0x87, 0x87),
541                    (0x5f, 0x87, 0xaf),
542                    (0x5f, 0x87, 0xd7),
543                    (0x5f, 0x87, 0xff),
544                    (0x5f, 0xaf, 0x00),
545                    (0x5f, 0xaf, 0x5f),
546                    (0x5f, 0xaf, 0x87),
547                    (0x5f, 0xaf, 0xaf),
548                    (0x5f, 0xaf, 0xd7),
549                    (0x5f, 0xaf, 0xff),
550                    (0x5f, 0xd7, 0x00),
551                    (0x5f, 0xd7, 0x5f),
552                    (0x5f, 0xd7, 0x87),
553                    (0x5f, 0xd7, 0xaf),
554                    (0x5f, 0xd7, 0xd7),
555                    (0x5f, 0xd7, 0xff),
556                    (0x5f, 0xff, 0x00),
557                    (0x5f, 0xff, 0x5f),
558                    (0x5f, 0xff, 0x87),
559                    (0x5f, 0xff, 0xaf),
560                    (0x5f, 0xff, 0xd7),
561                    (0x5f, 0xff, 0xff),
562                    (0x87, 0x00, 0x00),
563                    (0x87, 0x00, 0x5f),
564                    (0x87, 0x00, 0x87),
565                    (0x87, 0x00, 0xaf),
566                    (0x87, 0x00, 0xd7),
567                    (0x87, 0x00, 0xff),
568                    (0x87, 0x5f, 0x00),
569                    (0x87, 0x5f, 0x5f),
570                    (0x87, 0x5f, 0x87),
571                    (0x87, 0x5f, 0xaf),
572                    (0x87, 0x5f, 0xd7),
573                    (0x87, 0x5f, 0xff),
574                    (0x87, 0x87, 0x00),
575                    (0x87, 0x87, 0x5f),
576                    (0x87, 0x87, 0x87),
577                    (0x87, 0x87, 0xaf),
578                    (0x87, 0x87, 0xd7),
579                    (0x87, 0x87, 0xff),
580                    (0x87, 0xaf, 0x00),
581                    (0x87, 0xaf, 0x5f),
582                    (0x87, 0xaf, 0x87),
583                    (0x87, 0xaf, 0xaf),
584                    (0x87, 0xaf, 0xd7),
585                    (0x87, 0xaf, 0xff),
586                    (0x87, 0xd7, 0x00),
587                    (0x87, 0xd7, 0x5f),
588                    (0x87, 0xd7, 0x87),
589                    (0x87, 0xd7, 0xaf),
590                    (0x87, 0xd7, 0xd7),
591                    (0x87, 0xd7, 0xff),
592                    (0x87, 0xff, 0x00),
593                    (0x87, 0xff, 0x5f),
594                    (0x87, 0xff, 0x87),
595                    (0x87, 0xff, 0xaf),
596                    (0x87, 0xff, 0xd7),
597                    (0x87, 0xff, 0xff),
598                    (0xaf, 0x00, 0x00),
599                    (0xaf, 0x00, 0x5f),
600                    (0xaf, 0x00, 0x87),
601                    (0xaf, 0x00, 0xaf),
602                    (0xaf, 0x00, 0xd7),
603                    (0xaf, 0x00, 0xff),
604                    (0xaf, 0x5f, 0x00),
605                    (0xaf, 0x5f, 0x5f),
606                    (0xaf, 0x5f, 0x87),
607                    (0xaf, 0x5f, 0xaf),
608                    (0xaf, 0x5f, 0xd7),
609                    (0xaf, 0x5f, 0xff),
610                    (0xaf, 0x87, 0x00),
611                    (0xaf, 0x87, 0x5f),
612                    (0xaf, 0x87, 0x87),
613                    (0xaf, 0x87, 0xaf),
614                    (0xaf, 0x87, 0xd7),
615                    (0xaf, 0x87, 0xff),
616                    (0xaf, 0xaf, 0x00),
617                    (0xaf, 0xaf, 0x5f),
618                    (0xaf, 0xaf, 0x87),
619                    (0xaf, 0xaf, 0xaf),
620                    (0xaf, 0xaf, 0xd7),
621                    (0xaf, 0xaf, 0xff),
622                    (0xaf, 0xd7, 0x00),
623                    (0xaf, 0xd7, 0x5f),
624                    (0xaf, 0xd7, 0x87),
625                    (0xaf, 0xd7, 0xaf),
626                    (0xaf, 0xd7, 0xd7),
627                    (0xaf, 0xd7, 0xff),
628                    (0xaf, 0xff, 0x00),
629                    (0xaf, 0xff, 0x5f),
630                    (0xaf, 0xff, 0x87),
631                    (0xaf, 0xff, 0xaf),
632                    (0xaf, 0xff, 0xd7),
633                    (0xaf, 0xff, 0xff),
634                    (0xd7, 0x00, 0x00),
635                    (0xd7, 0x00, 0x5f),
636                    (0xd7, 0x00, 0x87),
637                    (0xd7, 0x00, 0xaf),
638                    (0xd7, 0x00, 0xd7),
639                    (0xd7, 0x00, 0xff),
640                    (0xd7, 0x5f, 0x00),
641                    (0xd7, 0x5f, 0x5f),
642                    (0xd7, 0x5f, 0x87),
643                    (0xd7, 0x5f, 0xaf),
644                    (0xd7, 0x5f, 0xd7),
645                    (0xd7, 0x5f, 0xff),
646                    (0xd7, 0x87, 0x00),
647                    (0xd7, 0x87, 0x5f),
648                    (0xd7, 0x87, 0x87),
649                    (0xd7, 0x87, 0xaf),
650                    (0xd7, 0x87, 0xd7),
651                    (0xd7, 0x87, 0xff),
652                    (0xd7, 0xaf, 0x00),
653                    (0xd7, 0xaf, 0x5f),
654                    (0xd7, 0xaf, 0x87),
655                    (0xd7, 0xaf, 0xaf),
656                    (0xd7, 0xaf, 0xd7),
657                    (0xd7, 0xaf, 0xff),
658                    (0xd7, 0xd7, 0x00),
659                    (0xd7, 0xd7, 0x5f),
660                    (0xd7, 0xd7, 0x87),
661                    (0xd7, 0xd7, 0xaf),
662                    (0xd7, 0xd7, 0xd7),
663                    (0xd7, 0xd7, 0xff),
664                    (0xd7, 0xff, 0x00),
665                    (0xd7, 0xff, 0x5f),
666                    (0xd7, 0xff, 0x87),
667                    (0xd7, 0xff, 0xaf),
668                    (0xd7, 0xff, 0xd7),
669                    (0xd7, 0xff, 0xff),
670                    (0xff, 0x00, 0x00),
671                    (0xff, 0x00, 0x5f),
672                    (0xff, 0x00, 0x87),
673                    (0xff, 0x00, 0xaf),
674                    (0xff, 0x00, 0xd7),
675                    (0xff, 0x00, 0xff),
676                    (0xff, 0x5f, 0x00),
677                    (0xff, 0x5f, 0x5f),
678                    (0xff, 0x5f, 0x87),
679                    (0xff, 0x5f, 0xaf),
680                    (0xff, 0x5f, 0xd7),
681                    (0xff, 0x5f, 0xff),
682                    (0xff, 0x87, 0x00),
683                    (0xff, 0x87, 0x5f),
684                    (0xff, 0x87, 0x87),
685                    (0xff, 0x87, 0xaf),
686                    (0xff, 0x87, 0xd7),
687                    (0xff, 0x87, 0xff),
688                    (0xff, 0xaf, 0x00),
689                    (0xff, 0xaf, 0x5f),
690                    (0xff, 0xaf, 0x87),
691                    (0xff, 0xaf, 0xaf),
692                    (0xff, 0xaf, 0xd7),
693                    (0xff, 0xaf, 0xff),
694                    (0xff, 0xd7, 0x00),
695                    (0xff, 0xd7, 0x5f),
696                    (0xff, 0xd7, 0x87),
697                    (0xff, 0xd7, 0xaf),
698                    (0xff, 0xd7, 0xd7),
699                    (0xff, 0xd7, 0xff),
700                    (0xff, 0xff, 0x00),
701                    (0xff, 0xff, 0x5f),
702                    (0xff, 0xff, 0x87),
703                    (0xff, 0xff, 0xaf),
704                    (0xff, 0xff, 0xd7),
705                    (0xff, 0xff, 0xff),
706                    (0x08, 0x08, 0x08),
707                    (0x12, 0x12, 0x12),
708                    (0x1c, 0x1c, 0x1c),
709                    (0x26, 0x26, 0x26),
710                    (0x30, 0x30, 0x30),
711                    (0x3a, 0x3a, 0x3a),
712                    (0x44, 0x44, 0x44),
713                    (0x4e, 0x4e, 0x4e),
714                    (0x58, 0x58, 0x58),
715                    (0x62, 0x62, 0x62),
716                    (0x6c, 0x6c, 0x6c),
717                    (0x76, 0x76, 0x76),
718                    (0x80, 0x80, 0x80),
719                    (0x8a, 0x8a, 0x8a),
720                    (0x94, 0x94, 0x94),
721                    (0x9e, 0x9e, 0x9e),
722                    (0xa8, 0xa8, 0xa8),
723                    (0xb2, 0xb2, 0xb2),
724                    (0xbc, 0xbc, 0xbc),
725                    (0xc6, 0xc6, 0xc6),
726                    (0xd0, 0xd0, 0xd0),
727                    (0xda, 0xda, 0xda),
728                    (0xe4, 0xe4, 0xe4),
729                    (0xee, 0xee, 0xee),
730                ];
731                VGA256[i as usize]
732            }
733            Color::Reset => (0, 0, 0),
734        }
735    }
736}