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