rat_theme2/
scheme.rs

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