rat_theme/
lib.rs

1#![doc = include_str!("../readme.md")]
2
3use crate::dark_theme::DarkTheme;
4use crate::scheme::*;
5use map_range_int::MapRange;
6use ratatui_core::style::Color;
7use ratatui_core::style::Style;
8
9mod base16;
10mod base16r;
11pub mod dark_theme;
12mod imperial;
13mod monekai;
14mod monochrome;
15mod ocean;
16mod oxocarbon;
17mod radium;
18mod tundra;
19mod vscode_dark;
20
21/// Color palettes
22pub mod scheme {
23    pub use crate::base16::BASE16;
24    pub use crate::base16r::BASE16_RELAXED;
25    pub use crate::imperial::IMPERIAL;
26    pub use crate::monekai::MONEKAI;
27    pub use crate::monochrome::MONOCHROME;
28    pub use crate::ocean::OCEAN;
29    pub use crate::oxocarbon::OXOCARBON;
30    pub use crate::radium::RADIUM;
31    pub use crate::tundra::TUNDRA;
32    pub use crate::vscode_dark::VSCODE_DARK;
33}
34
35/// Color scheme.
36///
37/// This provides the palette used for a theme.
38///
39/// The ideas packed in here are
40/// * provide two colors for highlighting and accents.
41/// * I always want some white, black and gray.
42/// * I don't want to miss out anything, so go once
43///   round the hue in HSV. Take steps of 30° then we
44///   hit pretty much anything interesting.
45/// * Just one variant of each color is not enough, make it 4.
46///
47#[derive(Debug, Default, Clone)]
48pub struct Scheme {
49    pub white: [Color; 4],
50    pub black: [Color; 4],
51    pub gray: [Color; 4],
52
53    pub red: [Color; 4],
54    pub orange: [Color; 4],
55    pub yellow: [Color; 4],
56    pub limegreen: [Color; 4],
57    pub green: [Color; 4],
58    pub bluegreen: [Color; 4],
59    pub cyan: [Color; 4],
60    pub blue: [Color; 4],
61    pub deepblue: [Color; 4],
62    pub purple: [Color; 4],
63    pub magenta: [Color; 4],
64    pub redpink: [Color; 4],
65
66    pub primary: [Color; 4],
67    pub secondary: [Color; 4],
68}
69
70impl Scheme {
71    /// Create a style from the given white shade.
72    /// n is `0..=3`
73    pub fn white(&self, n: usize) -> Style {
74        self.style(self.white[n])
75    }
76
77    /// Create a style from the given black shade.
78    /// n is `0..=3`
79    pub fn black(&self, n: usize) -> Style {
80        self.style(self.black[n])
81    }
82
83    /// Create a style from the given gray shade.
84    /// n is `0..=3`
85    pub fn gray(&self, n: usize) -> Style {
86        self.style(self.gray[n])
87    }
88
89    /// Create a style from the given red shade.
90    /// n is `0..=3`
91    pub fn red(&self, n: usize) -> Style {
92        self.style(self.red[n])
93    }
94
95    /// Create a style from the given orange shade.
96    /// n is `0..=3`
97    pub fn orange(&self, n: usize) -> Style {
98        self.style(self.orange[n])
99    }
100
101    /// Create a style from the given yellow shade.
102    /// n is `0..=3`
103    pub fn yellow(&self, n: usize) -> Style {
104        self.style(self.yellow[n])
105    }
106
107    /// Create a style from the given limegreen shade.
108    /// n is `0..=3`
109    pub fn limegreen(&self, n: usize) -> Style {
110        self.style(self.limegreen[n])
111    }
112
113    /// Create a style from the given green shade.
114    /// n is `0..=3`
115    pub fn green(&self, n: usize) -> Style {
116        self.style(self.green[n])
117    }
118
119    /// Create a style from the given bluegreen shade.
120    /// n is `0..=3`
121    pub fn bluegreen(&self, n: usize) -> Style {
122        self.style(self.bluegreen[n])
123    }
124
125    /// Create a style from the given cyan shade.
126    /// n is `0..=3`
127    pub fn cyan(&self, n: usize) -> Style {
128        self.style(self.cyan[n])
129    }
130
131    /// Create a style from the given blue shade.
132    /// n is `0..=3`
133    pub fn blue(&self, n: usize) -> Style {
134        self.style(self.blue[n])
135    }
136
137    /// Create a style from the given deepblue shade.
138    /// n is `0..=3`
139    pub fn deepblue(&self, n: usize) -> Style {
140        self.style(self.deepblue[n])
141    }
142
143    /// Create a style from the given purple shade.
144    /// n is `0..=3`
145    pub fn purple(&self, n: usize) -> Style {
146        self.style(self.purple[n])
147    }
148
149    /// Create a style from the given magenta shade.
150    /// n is `0..=3`
151    pub fn magenta(&self, n: usize) -> Style {
152        self.style(self.magenta[n])
153    }
154
155    /// Create a style from the given redpink shade.
156    /// n is `0..=3`
157    pub fn redpink(&self, n: usize) -> Style {
158        self.style(self.redpink[n])
159    }
160
161    /// Create a style from the given primary shade.
162    /// n is `0..=3`
163    pub fn primary(&self, n: usize) -> Style {
164        self.style(self.primary[n])
165    }
166
167    /// Create a style from the given secondary shade.
168    /// n is `0..=3`
169    pub fn secondary(&self, n: usize) -> Style {
170        self.style(self.secondary[n])
171    }
172}
173
174impl Scheme {
175    /// Create a style from the given white shade.
176    /// n is `0..=3`
177    pub fn true_dark_white(&self, n: usize) -> Style {
178        self.true_dark_style(self.white[n])
179    }
180
181    /// Create a style from the given black shade.
182    /// n is `0..=3`
183    pub fn true_dark_black(&self, n: usize) -> Style {
184        self.true_dark_style(self.black[n])
185    }
186
187    /// Create a style from the given gray shade.
188    /// n is `0..=3`
189    pub fn true_dark_gray(&self, n: usize) -> Style {
190        self.true_dark_style(self.gray[n])
191    }
192
193    /// Create a style from the given red shade.
194    /// n is `0..=3`
195    pub fn true_dark_red(&self, n: usize) -> Style {
196        self.true_dark_style(self.red[n])
197    }
198
199    /// Create a style from the given orange shade.
200    /// n is `0..=3`
201    pub fn true_dark_orange(&self, n: usize) -> Style {
202        self.true_dark_style(self.orange[n])
203    }
204
205    /// Create a style from the given yellow shade.
206    /// n is `0..=3`
207    pub fn true_dark_yellow(&self, n: usize) -> Style {
208        self.true_dark_style(self.yellow[n])
209    }
210
211    /// Create a style from the given limegreen shade.
212    /// n is `0..=3`
213    pub fn true_dark_limegreen(&self, n: usize) -> Style {
214        self.true_dark_style(self.limegreen[n])
215    }
216
217    /// Create a style from the given green shade.
218    /// n is `0..=3`
219    pub fn true_dark_green(&self, n: usize) -> Style {
220        self.true_dark_style(self.green[n])
221    }
222
223    /// Create a style from the given bluegreen shade.
224    /// n is `0..=3`
225    pub fn true_dark_bluegreen(&self, n: usize) -> Style {
226        self.true_dark_style(self.bluegreen[n])
227    }
228
229    /// Create a style from the given cyan shade.
230    /// n is `0..=3`
231    pub fn true_dark_cyan(&self, n: usize) -> Style {
232        self.true_dark_style(self.cyan[n])
233    }
234
235    /// Create a style from the given blue shade.
236    /// n is `0..=3`
237    pub fn true_dark_blue(&self, n: usize) -> Style {
238        self.true_dark_style(self.blue[n])
239    }
240
241    /// Create a style from the given deepblue shade.
242    /// n is `0..=3`
243    pub fn true_dark_deepblue(&self, n: usize) -> Style {
244        self.true_dark_style(self.deepblue[n])
245    }
246
247    /// Create a style from the given purple shade.
248    /// n is `0..=3`
249    pub fn true_dark_purple(&self, n: usize) -> Style {
250        self.true_dark_style(self.purple[n])
251    }
252
253    /// Create a style from the given magenta shade.
254    /// n is `0..=3`
255    pub fn true_dark_magenta(&self, n: usize) -> Style {
256        self.true_dark_style(self.magenta[n])
257    }
258
259    /// Create a style from the given redpink shade.
260    /// n is `0..=3`
261    pub fn true_dark_redpink(&self, n: usize) -> Style {
262        self.true_dark_style(self.redpink[n])
263    }
264
265    /// Create a style from the given primary shade.
266    /// n is `0..=3`
267    pub fn true_dark_primary(&self, n: usize) -> Style {
268        self.true_dark_style(self.primary[n])
269    }
270
271    /// Create a style from the given secondary shade.
272    /// n is `0..=3`
273    pub fn true_dark_secondary(&self, n: usize) -> Style {
274        self.true_dark_style(self.secondary[n])
275    }
276}
277
278impl Scheme {
279    /// Create a style from the given white shade.
280    /// n is `0..=3`
281    pub fn reduced_white(&self, n: usize) -> Style {
282        self.reduced_style(self.white[n])
283    }
284
285    /// Create a style from the given black shade.
286    /// n is `0..=3`
287    pub fn reduced_black(&self, n: usize) -> Style {
288        self.reduced_style(self.black[n])
289    }
290
291    /// Create a style from the given gray shade.
292    /// n is `0..=3`
293    pub fn reduced_gray(&self, n: usize) -> Style {
294        self.reduced_style(self.gray[n])
295    }
296
297    /// Create a style from the given red shade.
298    /// n is `0..=3`
299    pub fn reduced_red(&self, n: usize) -> Style {
300        self.reduced_style(self.red[n])
301    }
302
303    /// Create a style from the given orange shade.
304    /// n is `0..=3`
305    pub fn reduced_orange(&self, n: usize) -> Style {
306        self.reduced_style(self.orange[n])
307    }
308
309    /// Create a style from the given yellow shade.
310    /// n is `0..=3`
311    pub fn reduced_yellow(&self, n: usize) -> Style {
312        self.reduced_style(self.yellow[n])
313    }
314
315    /// Create a style from the given limegreen shade.
316    /// n is `0..=3`
317    pub fn reduced_limegreen(&self, n: usize) -> Style {
318        self.reduced_style(self.limegreen[n])
319    }
320
321    /// Create a style from the given green shade.
322    /// n is `0..=3`
323    pub fn reduced_green(&self, n: usize) -> Style {
324        self.reduced_style(self.green[n])
325    }
326
327    /// Create a style from the given bluegreen shade.
328    /// n is `0..=3`
329    pub fn reduced_bluegreen(&self, n: usize) -> Style {
330        self.reduced_style(self.bluegreen[n])
331    }
332
333    /// Create a style from the given cyan shade.
334    /// n is `0..=3`
335    pub fn reduced_cyan(&self, n: usize) -> Style {
336        self.reduced_style(self.cyan[n])
337    }
338
339    /// Create a style from the given blue shade.
340    /// n is `0..=3`
341    pub fn reduced_blue(&self, n: usize) -> Style {
342        self.reduced_style(self.blue[n])
343    }
344
345    /// Create a style from the given deepblue shade.
346    /// n is `0..=3`
347    pub fn reduced_deepblue(&self, n: usize) -> Style {
348        self.reduced_style(self.deepblue[n])
349    }
350
351    /// Create a style from the given purple shade.
352    /// n is `0..=3`
353    pub fn reduced_purple(&self, n: usize) -> Style {
354        self.reduced_style(self.purple[n])
355    }
356
357    /// Create a style from the given magenta shade.
358    /// n is `0..=3`
359    pub fn reduced_magenta(&self, n: usize) -> Style {
360        self.reduced_style(self.magenta[n])
361    }
362
363    /// Create a style from the given redpink shade.
364    /// n is `0..=3`
365    pub fn reduced_redpink(&self, n: usize) -> Style {
366        self.reduced_style(self.redpink[n])
367    }
368
369    /// Create a style from the given primary shade.
370    /// n is `0..=3`
371    pub fn reduced_primary(&self, n: usize) -> Style {
372        self.reduced_style(self.primary[n])
373    }
374
375    /// Create a style from the given secondary shade.
376    /// n is `0..=3`
377    pub fn reduced_secondary(&self, n: usize) -> Style {
378        self.reduced_style(self.secondary[n])
379    }
380}
381
382impl Scheme {
383    /// Create a style with the given background color.
384    /// Foreground is calculated with `text_color`.
385    pub fn style(&self, color: Color) -> Style {
386        Style::new().bg(color).fg(self.text_color(color))
387    }
388
389    /// Create a style with the given background color.
390    /// Foreground is calculated with `reduced_text_color`.
391    pub fn reduced_style(&self, color: Color) -> Style {
392        Style::new().bg(color).fg(self.reduced_text_color(color))
393    }
394
395    /// Create a style with the given background color
396    /// converted with true_dark_color().
397    /// Foreground is calculated with `text_color`.
398    pub fn true_dark_style(&self, color: Color) -> Style {
399        let dark = self.true_dark_color(color);
400        Style::new().bg(dark).fg(self.text_color(dark))
401    }
402
403    /// Create a style with the given background color.
404    /// converted with true_dark_color().
405    /// Foreground is calculated with `reduced_text_color`.
406    pub fn reduced_dark_style(&self, color: Color) -> Style {
407        let dark = self.true_dark_color(color);
408        Style::new().bg(dark).fg(self.reduced_text_color(dark))
409    }
410
411    /// Linear interpolation between the two colors.
412    pub const fn linear4(c0: u32, c1: u32) -> [Color; 4] {
413        // 1/3
414        const fn i1(a: u8, b: u8) -> u8 {
415            if a < b {
416                a + (b - a) / 3
417            } else {
418                a - (a - b) / 3
419            }
420        }
421        // 2/3
422        const fn i2(a: u8, b: u8) -> u8 {
423            if a < b {
424                b - (b - a) / 3
425            } else {
426                b + (a - b) / 3
427            }
428        }
429
430        let r0 = (c0 >> 16) as u8;
431        let g0 = (c0 >> 8) as u8;
432        let b0 = c0 as u8;
433
434        let r3 = (c1 >> 16) as u8;
435        let g3 = (c1 >> 8) as u8;
436        let b3 = c1 as u8;
437
438        let r1 = i1(r0, r3);
439        let g1 = i1(g0, g3);
440        let b1 = i1(b0, b3);
441
442        let r2 = i2(r0, r3);
443        let g2 = i2(g0, g3);
444        let b2 = i2(b0, b3);
445
446        [
447            Color::Rgb(r0, g0, b0),
448            Color::Rgb(r1, g1, b1),
449            Color::Rgb(r2, g2, b2),
450            Color::Rgb(r3, g3, b3),
451        ]
452    }
453
454    /// Reduces the range of the given color from 0..255 to 0..63.
455    ///
456    /// This gives a true dark equivalent which can be used
457    /// as a background for a dark theme.
458    pub fn true_dark_color(&self, color: Color) -> Color {
459        let (r, g, b) = as_rgb(color);
460        Color::Rgb(
461            r.map_range_unchecked((0, 255), (0, 63)),
462            g.map_range_unchecked((0, 255), (0, 63)),
463            b.map_range_unchecked((0, 255), (0, 63)),
464        )
465    }
466
467    /// Converts the given color to an equivalent grayscale.
468    pub fn grey_color(&self, color: Color) -> Color {
469        let (r, g, b) = as_rgb(color);
470        // The formula used in the GIMP is Y = 0.3R + 0.59G + 0.11B;
471        let grey = r as f32 * 0.3f32 + g as f32 * 0.59f32 + b as f32 * 0.11f32;
472        Color::Rgb(grey as u8, grey as u8, grey as u8)
473    }
474
475    /// This gives back `white[3]` or `black[0]` for text foreground
476    /// providing good contrast to the given background.
477    ///
478    /// This converts RGB to grayscale and takes the grayscale value
479    /// of VGA cyan as threshold, which is about 105 out of 255.
480    /// This point is a bit arbitrary, just based on what I
481    /// perceive as acceptable. But it produces a good reading
482    /// contrast in my experience.
483    ///
484    /// For the named colors it takes the VGA equivalent as a base.
485    /// For indexed colors it splits the range in half as an estimate.
486    pub fn text_color(&self, color: Color) -> Color {
487        match self.rate_text_color(color) {
488            None => Color::Reset,
489            Some(true) => self.white[3],
490            Some(false) => self.black[0],
491        }
492    }
493
494    /// This gives back `white[3]` or `black[0]` for text foreground
495    /// providing good contrast to the given background.
496    ///
497    /// This converts RGB to grayscale and takes the grayscale value
498    /// of VGA cyan as threshold, which is about 105 out of 255.
499    /// This point is a bit arbitrary, just based on what I
500    /// perceive as acceptable. But it produces a good reading
501    /// contrast in my experience.
502    ///
503    /// For the named colors it takes the VGA equivalent as a base.
504    /// For indexed colors it splits the range in half as an estimate.
505    pub fn reduced_text_color(&self, color: Color) -> Color {
506        match self.rate_text_color(color) {
507            None => Color::Reset,
508            Some(true) => self.white[0],
509            Some(false) => self.black[3],
510        }
511    }
512
513    /// This gives back `true` or `false` for text foreground
514    /// where true means light and false means a dark text-color
515    /// providing good contrast to the given background.
516    ///
517    /// This converts RGB to grayscale and takes the grayscale value
518    /// of VGA cyan as threshold, which is about 105 out of 255.
519    /// This point is a bit arbitrary, just based on what I
520    /// perceive as acceptable. But it produces a good reading
521    /// contrast in my experience.
522    ///
523    /// For the named colors it takes the VGA equivalent as a base.
524    /// For indexed colors it splits the range in half as an estimate.
525    pub fn rate_text_color(&self, color: Color) -> Option<bool> {
526        match color {
527            Color::Reset => None,
528            Color::Black => Some(true),         //0
529            Color::Red => Some(true),           //1
530            Color::Green => Some(true),         //2
531            Color::Yellow => Some(true),        //3
532            Color::Blue => Some(true),          //4
533            Color::Magenta => Some(true),       //5
534            Color::Cyan => Some(true),          //6
535            Color::Gray => Some(false),         //7
536            Color::DarkGray => Some(true),      //8
537            Color::LightRed => Some(false),     //9
538            Color::LightGreen => Some(false),   //10
539            Color::LightYellow => Some(false),  //11
540            Color::LightBlue => Some(true),     //12
541            Color::LightMagenta => Some(false), //13
542            Color::LightCyan => Some(false),    //14
543            Color::White => Some(false),        //15
544            Color::Rgb(r, g, b) => {
545                // The formula used in the GIMP is Y = 0.3R + 0.59G + 0.11B;
546                let grey = r as f32 * 0.3f32 + g as f32 * 0.59f32 + b as f32 * 0.11f32;
547                if grey >= 105f32 {
548                    Some(false)
549                } else {
550                    Some(true)
551                }
552            }
553            Color::Indexed(n) => match n {
554                0..=6 => Some(true),
555                7 => Some(false),
556                8 => Some(true),
557                9..=11 => Some(false),
558                12 => Some(true),
559                13..=15 => Some(false),
560                v @ 16..=231 => {
561                    if (v - 16) % 36 < 18 {
562                        Some(true)
563                    } else {
564                        Some(false)
565                    }
566                }
567                v @ 232..=255 => {
568                    if (v - 232) % 24 < 12 {
569                        Some(true)
570                    } else {
571                        Some(false)
572                    }
573                }
574            },
575        }
576    }
577}
578
579/// All currently existing color palettes.
580pub fn color_schemes() -> Vec<(String, Scheme)> {
581    vec![
582        ("Imperial".to_string(), IMPERIAL),
583        ("Radium".to_string(), RADIUM),
584        ("Tundra".to_string(), TUNDRA),
585        ("Monochrome".to_string(), MONOCHROME),
586        ("Monekai".to_string(), MONEKAI),
587        ("OxoCarbon".to_string(), OXOCARBON),
588        ("VSCodeDark".to_string(), VSCODE_DARK),
589        ("Ocean".to_string(), OCEAN),
590        ("Base16".to_string(), BASE16),
591        ("Base16Relaxed".to_string(), BASE16_RELAXED),
592    ]
593}
594
595/// A list of DarkTheme for all color palettes.
596pub fn dark_themes() -> Vec<DarkTheme> {
597    vec![
598        DarkTheme::new("Imperial".to_string(), IMPERIAL),
599        DarkTheme::new("Radium".to_string(), RADIUM),
600        DarkTheme::new("Tundra".to_string(), TUNDRA),
601        DarkTheme::new("Monochrome".to_string(), MONOCHROME),
602        DarkTheme::new("Monekai".to_string(), MONEKAI),
603        DarkTheme::new("Oxocarbon".to_string(), OXOCARBON),
604        DarkTheme::new("VSCodeDark".to_string(), VSCODE_DARK),
605        DarkTheme::new("Ocean".to_string(), OCEAN),
606        DarkTheme::new("Base16".to_string(), BASE16),
607        DarkTheme::new("Base16Relaxed".to_string(), BASE16_RELAXED),
608    ]
609}
610
611const fn as_rgb(color: Color) -> (u8, u8, u8) {
612    match color {
613        Color::Black => (0x00, 0x00, 0x00),
614        Color::Red => (0xaa, 0x00, 0x00),
615        Color::Green => (0x00, 0xaa, 0x00),
616        Color::Yellow => (0xaa, 0x55, 0x00),
617        Color::Blue => (0x00, 0x00, 0xaa),
618        Color::Magenta => (0xaa, 0x00, 0xaa),
619        Color::Cyan => (0x00, 0xaa, 0xaa),
620        Color::Gray => (0xaa, 0xaa, 0xaa),
621        Color::DarkGray => (0x55, 0x55, 0x55),
622        Color::LightRed => (0xff, 0x55, 0x55),
623        Color::LightGreen => (0x55, 0xff, 0x55),
624        Color::LightYellow => (0xff, 0xff, 0x55),
625        Color::LightBlue => (0x55, 0x55, 0xff),
626        Color::LightMagenta => (0xff, 0x55, 0xff),
627        Color::LightCyan => (0x55, 0xff, 0xff),
628        Color::White => (0xff, 0xff, 0xff),
629        Color::Rgb(r, g, b) => (r, g, b),
630        Color::Indexed(i) => {
631            const VGA256: [(u8, u8, u8); 256] = [
632                (0x00, 0x00, 0x00),
633                (0x80, 0x00, 0x00),
634                (0x00, 0x80, 0x00),
635                (0x80, 0x80, 0x00),
636                (0x00, 0x00, 0x80),
637                (0x80, 0x00, 0x80),
638                (0x00, 0x80, 0x80),
639                (0xc0, 0xc0, 0xc0),
640                (0x80, 0x80, 0x80),
641                (0xff, 0x00, 0x00),
642                (0x00, 0xff, 0x00),
643                (0xff, 0xff, 0x00),
644                (0x00, 0x00, 0xff),
645                (0xff, 0x00, 0xff),
646                (0x00, 0xff, 0xff),
647                (0xff, 0xff, 0xff),
648                (0x00, 0x00, 0x00),
649                (0x00, 0x00, 0x5f),
650                (0x00, 0x00, 0x87),
651                (0x00, 0x00, 0xaf),
652                (0x00, 0x00, 0xd7),
653                (0x00, 0x00, 0xff),
654                (0x00, 0x5f, 0x00),
655                (0x00, 0x5f, 0x5f),
656                (0x00, 0x5f, 0x87),
657                (0x00, 0x5f, 0xaf),
658                (0x00, 0x5f, 0xd7),
659                (0x00, 0x5f, 0xff),
660                (0x00, 0x87, 0x00),
661                (0x00, 0x87, 0x5f),
662                (0x00, 0x87, 0x87),
663                (0x00, 0x87, 0xaf),
664                (0x00, 0x87, 0xd7),
665                (0x00, 0x87, 0xff),
666                (0x00, 0xaf, 0x00),
667                (0x00, 0xaf, 0x5f),
668                (0x00, 0xaf, 0x87),
669                (0x00, 0xaf, 0xaf),
670                (0x00, 0xaf, 0xd7),
671                (0x00, 0xaf, 0xff),
672                (0x00, 0xd7, 0x00),
673                (0x00, 0xd7, 0x5f),
674                (0x00, 0xd7, 0x87),
675                (0x00, 0xd7, 0xaf),
676                (0x00, 0xd7, 0xd7),
677                (0x00, 0xd7, 0xff),
678                (0x00, 0xff, 0x00),
679                (0x00, 0xff, 0x5f),
680                (0x00, 0xff, 0x87),
681                (0x00, 0xff, 0xaf),
682                (0x00, 0xff, 0xd7),
683                (0x00, 0xff, 0xff),
684                (0x5f, 0x00, 0x00),
685                (0x5f, 0x00, 0x5f),
686                (0x5f, 0x00, 0x87),
687                (0x5f, 0x00, 0xaf),
688                (0x5f, 0x00, 0xd7),
689                (0x5f, 0x00, 0xff),
690                (0x5f, 0x5f, 0x00),
691                (0x5f, 0x5f, 0x5f),
692                (0x5f, 0x5f, 0x87),
693                (0x5f, 0x5f, 0xaf),
694                (0x5f, 0x5f, 0xd7),
695                (0x5f, 0x5f, 0xff),
696                (0x5f, 0x87, 0x00),
697                (0x5f, 0x87, 0x5f),
698                (0x5f, 0x87, 0x87),
699                (0x5f, 0x87, 0xaf),
700                (0x5f, 0x87, 0xd7),
701                (0x5f, 0x87, 0xff),
702                (0x5f, 0xaf, 0x00),
703                (0x5f, 0xaf, 0x5f),
704                (0x5f, 0xaf, 0x87),
705                (0x5f, 0xaf, 0xaf),
706                (0x5f, 0xaf, 0xd7),
707                (0x5f, 0xaf, 0xff),
708                (0x5f, 0xd7, 0x00),
709                (0x5f, 0xd7, 0x5f),
710                (0x5f, 0xd7, 0x87),
711                (0x5f, 0xd7, 0xaf),
712                (0x5f, 0xd7, 0xd7),
713                (0x5f, 0xd7, 0xff),
714                (0x5f, 0xff, 0x00),
715                (0x5f, 0xff, 0x5f),
716                (0x5f, 0xff, 0x87),
717                (0x5f, 0xff, 0xaf),
718                (0x5f, 0xff, 0xd7),
719                (0x5f, 0xff, 0xff),
720                (0x87, 0x00, 0x00),
721                (0x87, 0x00, 0x5f),
722                (0x87, 0x00, 0x87),
723                (0x87, 0x00, 0xaf),
724                (0x87, 0x00, 0xd7),
725                (0x87, 0x00, 0xff),
726                (0x87, 0x5f, 0x00),
727                (0x87, 0x5f, 0x5f),
728                (0x87, 0x5f, 0x87),
729                (0x87, 0x5f, 0xaf),
730                (0x87, 0x5f, 0xd7),
731                (0x87, 0x5f, 0xff),
732                (0x87, 0x87, 0x00),
733                (0x87, 0x87, 0x5f),
734                (0x87, 0x87, 0x87),
735                (0x87, 0x87, 0xaf),
736                (0x87, 0x87, 0xd7),
737                (0x87, 0x87, 0xff),
738                (0x87, 0xaf, 0x00),
739                (0x87, 0xaf, 0x5f),
740                (0x87, 0xaf, 0x87),
741                (0x87, 0xaf, 0xaf),
742                (0x87, 0xaf, 0xd7),
743                (0x87, 0xaf, 0xff),
744                (0x87, 0xd7, 0x00),
745                (0x87, 0xd7, 0x5f),
746                (0x87, 0xd7, 0x87),
747                (0x87, 0xd7, 0xaf),
748                (0x87, 0xd7, 0xd7),
749                (0x87, 0xd7, 0xff),
750                (0x87, 0xff, 0x00),
751                (0x87, 0xff, 0x5f),
752                (0x87, 0xff, 0x87),
753                (0x87, 0xff, 0xaf),
754                (0x87, 0xff, 0xd7),
755                (0x87, 0xff, 0xff),
756                (0xaf, 0x00, 0x00),
757                (0xaf, 0x00, 0x5f),
758                (0xaf, 0x00, 0x87),
759                (0xaf, 0x00, 0xaf),
760                (0xaf, 0x00, 0xd7),
761                (0xaf, 0x00, 0xff),
762                (0xaf, 0x5f, 0x00),
763                (0xaf, 0x5f, 0x5f),
764                (0xaf, 0x5f, 0x87),
765                (0xaf, 0x5f, 0xaf),
766                (0xaf, 0x5f, 0xd7),
767                (0xaf, 0x5f, 0xff),
768                (0xaf, 0x87, 0x00),
769                (0xaf, 0x87, 0x5f),
770                (0xaf, 0x87, 0x87),
771                (0xaf, 0x87, 0xaf),
772                (0xaf, 0x87, 0xd7),
773                (0xaf, 0x87, 0xff),
774                (0xaf, 0xaf, 0x00),
775                (0xaf, 0xaf, 0x5f),
776                (0xaf, 0xaf, 0x87),
777                (0xaf, 0xaf, 0xaf),
778                (0xaf, 0xaf, 0xd7),
779                (0xaf, 0xaf, 0xff),
780                (0xaf, 0xd7, 0x00),
781                (0xaf, 0xd7, 0x5f),
782                (0xaf, 0xd7, 0x87),
783                (0xaf, 0xd7, 0xaf),
784                (0xaf, 0xd7, 0xd7),
785                (0xaf, 0xd7, 0xff),
786                (0xaf, 0xff, 0x00),
787                (0xaf, 0xff, 0x5f),
788                (0xaf, 0xff, 0x87),
789                (0xaf, 0xff, 0xaf),
790                (0xaf, 0xff, 0xd7),
791                (0xaf, 0xff, 0xff),
792                (0xd7, 0x00, 0x00),
793                (0xd7, 0x00, 0x5f),
794                (0xd7, 0x00, 0x87),
795                (0xd7, 0x00, 0xaf),
796                (0xd7, 0x00, 0xd7),
797                (0xd7, 0x00, 0xff),
798                (0xd7, 0x5f, 0x00),
799                (0xd7, 0x5f, 0x5f),
800                (0xd7, 0x5f, 0x87),
801                (0xd7, 0x5f, 0xaf),
802                (0xd7, 0x5f, 0xd7),
803                (0xd7, 0x5f, 0xff),
804                (0xd7, 0x87, 0x00),
805                (0xd7, 0x87, 0x5f),
806                (0xd7, 0x87, 0x87),
807                (0xd7, 0x87, 0xaf),
808                (0xd7, 0x87, 0xd7),
809                (0xd7, 0x87, 0xff),
810                (0xd7, 0xaf, 0x00),
811                (0xd7, 0xaf, 0x5f),
812                (0xd7, 0xaf, 0x87),
813                (0xd7, 0xaf, 0xaf),
814                (0xd7, 0xaf, 0xd7),
815                (0xd7, 0xaf, 0xff),
816                (0xd7, 0xd7, 0x00),
817                (0xd7, 0xd7, 0x5f),
818                (0xd7, 0xd7, 0x87),
819                (0xd7, 0xd7, 0xaf),
820                (0xd7, 0xd7, 0xd7),
821                (0xd7, 0xd7, 0xff),
822                (0xd7, 0xff, 0x00),
823                (0xd7, 0xff, 0x5f),
824                (0xd7, 0xff, 0x87),
825                (0xd7, 0xff, 0xaf),
826                (0xd7, 0xff, 0xd7),
827                (0xd7, 0xff, 0xff),
828                (0xff, 0x00, 0x00),
829                (0xff, 0x00, 0x5f),
830                (0xff, 0x00, 0x87),
831                (0xff, 0x00, 0xaf),
832                (0xff, 0x00, 0xd7),
833                (0xff, 0x00, 0xff),
834                (0xff, 0x5f, 0x00),
835                (0xff, 0x5f, 0x5f),
836                (0xff, 0x5f, 0x87),
837                (0xff, 0x5f, 0xaf),
838                (0xff, 0x5f, 0xd7),
839                (0xff, 0x5f, 0xff),
840                (0xff, 0x87, 0x00),
841                (0xff, 0x87, 0x5f),
842                (0xff, 0x87, 0x87),
843                (0xff, 0x87, 0xaf),
844                (0xff, 0x87, 0xd7),
845                (0xff, 0x87, 0xff),
846                (0xff, 0xaf, 0x00),
847                (0xff, 0xaf, 0x5f),
848                (0xff, 0xaf, 0x87),
849                (0xff, 0xaf, 0xaf),
850                (0xff, 0xaf, 0xd7),
851                (0xff, 0xaf, 0xff),
852                (0xff, 0xd7, 0x00),
853                (0xff, 0xd7, 0x5f),
854                (0xff, 0xd7, 0x87),
855                (0xff, 0xd7, 0xaf),
856                (0xff, 0xd7, 0xd7),
857                (0xff, 0xd7, 0xff),
858                (0xff, 0xff, 0x00),
859                (0xff, 0xff, 0x5f),
860                (0xff, 0xff, 0x87),
861                (0xff, 0xff, 0xaf),
862                (0xff, 0xff, 0xd7),
863                (0xff, 0xff, 0xff),
864                (0x08, 0x08, 0x08),
865                (0x12, 0x12, 0x12),
866                (0x1c, 0x1c, 0x1c),
867                (0x26, 0x26, 0x26),
868                (0x30, 0x30, 0x30),
869                (0x3a, 0x3a, 0x3a),
870                (0x44, 0x44, 0x44),
871                (0x4e, 0x4e, 0x4e),
872                (0x58, 0x58, 0x58),
873                (0x62, 0x62, 0x62),
874                (0x6c, 0x6c, 0x6c),
875                (0x76, 0x76, 0x76),
876                (0x80, 0x80, 0x80),
877                (0x8a, 0x8a, 0x8a),
878                (0x94, 0x94, 0x94),
879                (0x9e, 0x9e, 0x9e),
880                (0xa8, 0xa8, 0xa8),
881                (0xb2, 0xb2, 0xb2),
882                (0xbc, 0xbc, 0xbc),
883                (0xc6, 0xc6, 0xc6),
884                (0xd0, 0xd0, 0xd0),
885                (0xda, 0xda, 0xda),
886                (0xe4, 0xe4, 0xe4),
887                (0xee, 0xee, 0xee),
888            ];
889            VGA256[i as usize]
890        }
891        Color::Reset => (0, 0, 0),
892    }
893}