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