1use ratatui::style::{Color, Style};
22use std::borrow::Cow;
23use std::fmt::{Display, Formatter};
24use std::mem;
25use std::str::FromStr;
26
27#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub struct ColorIdx(pub Colors, pub usize);
31
32#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub enum Colors {
35 TextLight = 0,
37 TextDark,
39 Primary,
41 Secondary,
43 White,
44 Black,
45 Gray,
46 Red,
47 Orange,
48 Yellow,
49 LimeGreen,
50 Green,
51 BlueGreen,
52 Cyan,
53 Blue,
54 DeepBlue,
55 Purple,
56 Magenta,
57 RedPink,
58 #[default]
63 None,
64}
65
66impl Display for ColorIdx {
67 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{}:{}", self.0, self.1)
69 }
70}
71
72impl FromStr for ColorIdx {
73 type Err = ();
74
75 fn from_str(s: &str) -> Result<Self, Self::Err> {
76 let mut ss = s.split(':');
77 let Some(name) = ss.next() else {
78 return Err(());
79 };
80 let Ok(c) = Colors::from_str(name) else {
81 return Err(());
82 };
83 let Some(idx) = ss.next() else { return Err(()) };
84 let Ok(idx) = idx.parse::<usize>() else {
85 return Err(());
86 };
87 Ok(ColorIdx(c, idx))
88 }
89}
90
91impl Display for Colors {
92 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
93 let s = match self {
94 Colors::TextLight => "text-light",
95 Colors::TextDark => "text-dark",
96 Colors::Primary => "primary",
97 Colors::Secondary => "secondary",
98 Colors::White => "white",
99 Colors::Black => "black",
100 Colors::Gray => "gray",
101 Colors::Red => "red",
102 Colors::Orange => "orange",
103 Colors::Yellow => "yellow",
104 Colors::LimeGreen => "lime-green",
105 Colors::Green => "green",
106 Colors::BlueGreen => "blue-green",
107 Colors::Cyan => "cyan",
108 Colors::Blue => "blue",
109 Colors::DeepBlue => "deep-blue",
110 Colors::Purple => "purple",
111 Colors::Magenta => "magenta",
112 Colors::RedPink => "red-pink",
113 Colors::None => "none",
114 };
115 write!(f, "{}", s)
116 }
117}
118
119impl FromStr for Colors {
120 type Err = ();
121
122 fn from_str(s: &str) -> Result<Self, Self::Err> {
123 match s {
124 "text-light" => Ok(Colors::TextLight),
125 "text-dark" => Ok(Colors::TextDark),
126 "primary" => Ok(Colors::Primary),
127 "secondary" => Ok(Colors::Secondary),
128 "white" => Ok(Colors::White),
129 "black" => Ok(Colors::Black),
130 "gray" => Ok(Colors::Gray),
131 "red" => Ok(Colors::Red),
132 "orange" => Ok(Colors::Orange),
133 "yellow" => Ok(Colors::Yellow),
134 "lime-green" => Ok(Colors::LimeGreen),
135 "green" => Ok(Colors::Green),
136 "blue-green" => Ok(Colors::BlueGreen),
137 "cyan" => Ok(Colors::Cyan),
138 "blue" => Ok(Colors::Blue),
139 "deep-blue" => Ok(Colors::DeepBlue),
140 "purple" => Ok(Colors::Purple),
141 "magenta" => Ok(Colors::Magenta),
142 "red-pink" => Ok(Colors::RedPink),
143 "none" => Ok(Colors::None),
144 _ => Err(()),
145 }
146 }
147}
148
149impl Colors {
150 pub const LEN: usize = 19;
151}
152
153#[derive(Debug, Clone)]
157pub struct Palette {
158 pub name: Cow<'static, str>,
160 pub color: [[Color; 8]; Colors::LEN],
162 pub aliased: Cow<'static, [(Cow<'static, str>, ColorIdx)]>,
165}
166
167impl Default for Palette {
168 fn default() -> Self {
169 Self {
170 name: Cow::Borrowed(""),
171 color: [[Color::default(); 8]; Colors::LEN],
172 aliased: Cow::Borrowed(&[]),
173 }
174 }
175}
176
177#[derive(Debug)]
179pub(crate) enum Rating {
180 Light,
182 Dark,
184}
185
186pub const fn define_alias(
188 alias: &'static str,
189 color: Colors,
190 n: usize,
191) -> (Cow<'static, str>, ColorIdx) {
192 (Cow::Borrowed(alias), ColorIdx(color, n))
193}
194
195pub fn define_rt_alias(
198 alias: impl Into<String>,
199 color: Colors,
200 n: usize,
201) -> (Cow<'static, str>, ColorIdx) {
202 let alias = alias.into();
203 (Cow::Owned(alias), ColorIdx(color, n))
204}
205
206impl Palette {
207 pub fn white(&self, n: usize) -> Style {
210 self.style(Colors::White, n)
211 }
212
213 pub fn black(&self, n: usize) -> Style {
216 self.style(Colors::Black, n)
217 }
218
219 pub fn gray(&self, n: usize) -> Style {
222 self.style(Colors::Gray, n)
223 }
224
225 pub fn red(&self, n: usize) -> Style {
228 self.style(Colors::Red, n)
229 }
230
231 pub fn orange(&self, n: usize) -> Style {
234 self.style(Colors::Orange, n)
235 }
236
237 pub fn yellow(&self, n: usize) -> Style {
240 self.style(Colors::Yellow, n)
241 }
242
243 pub fn limegreen(&self, n: usize) -> Style {
246 self.style(Colors::LimeGreen, n)
247 }
248
249 pub fn green(&self, n: usize) -> Style {
252 self.style(Colors::Green, n)
253 }
254
255 pub fn bluegreen(&self, n: usize) -> Style {
258 self.style(Colors::BlueGreen, n)
259 }
260
261 pub fn cyan(&self, n: usize) -> Style {
264 self.style(Colors::Cyan, n)
265 }
266
267 pub fn blue(&self, n: usize) -> Style {
270 self.style(Colors::Blue, n)
271 }
272
273 pub fn deepblue(&self, n: usize) -> Style {
276 self.style(Colors::DeepBlue, n)
277 }
278
279 pub fn purple(&self, n: usize) -> Style {
282 self.style(Colors::Purple, n)
283 }
284
285 pub fn magenta(&self, n: usize) -> Style {
288 self.style(Colors::Magenta, n)
289 }
290
291 pub fn redpink(&self, n: usize) -> Style {
294 self.style(Colors::RedPink, n)
295 }
296
297 pub fn primary(&self, n: usize) -> Style {
300 self.style(Colors::Primary, n)
301 }
302
303 pub fn secondary(&self, n: usize) -> Style {
306 self.style(Colors::Secondary, n)
307 }
308}
309
310impl Palette {
311 pub fn color(&self, id: Colors, n: usize) -> Color {
313 if id == Colors::None {
314 Color::Reset
315 } else {
316 self.color[id as usize][n]
317 }
318 }
319
320 pub fn style(&self, id: Colors, n: usize) -> Style {
324 let color = self.color(id, n);
325 self.normal_contrast(color)
326 }
327
328 pub fn high_style(&self, id: Colors, n: usize) -> Style {
332 let color = self.color(id, n);
333 self.high_contrast(color)
334 }
335
336 pub fn fg_bg_style(&self, fg: Colors, n: usize, bg: Colors, m: usize) -> Style {
338 let color = self.color(fg, n);
339 let color_bg = self.color(bg, m);
340 let mut style = Style::new();
341 if color != Color::Reset {
342 style = style.fg(color);
343 }
344 if color_bg != Color::Reset {
345 style = style.bg(color_bg);
346 }
347 style
348 }
349
350 pub fn fg_style(&self, id: Colors, n: usize) -> Style {
352 let color = self.color(id, n);
353 let mut style = Style::new();
354 if color != Color::Reset {
355 style = style.fg(color);
356 }
357 style
358 }
359
360 pub fn bg_style(&self, id: Colors, n: usize) -> Style {
362 let color = self.color(id, n);
363 let mut style = Style::new();
364 if color != Color::Reset {
365 style = style.bg(color);
366 }
367 style
368 }
369
370 pub fn add_aliased(&mut self, id: &str, color_idx: ColorIdx) {
372 if matches!(self.aliased, Cow::Borrowed(_)) {
373 self.aliased = Cow::Owned(mem::take(&mut self.aliased).into_owned());
374 }
375 match &mut self.aliased {
376 Cow::Borrowed(_) => {
377 unreachable!()
378 }
379 Cow::Owned(aliased) => {
380 aliased.push((Cow::Owned(id.to_string()), color_idx));
381 aliased.sort();
382 }
383 }
384 }
385
386 pub fn try_aliased(&self, id: &str) -> Option<ColorIdx> {
388 match self.aliased.binary_search_by_key(&id, |v| v.0.as_ref()) {
389 Ok(n) => Some(self.aliased[n].1),
390 Err(_) => None,
391 }
392 }
393
394 pub fn aliased(&self, id: &str) -> ColorIdx {
401 match self.try_aliased(id) {
402 Some(c) => c,
403 None => {
404 if cfg!(debug_assertions) {
405 panic!("unknown aliased color {:?}", id);
406 } else {
407 ColorIdx::default()
408 }
409 }
410 }
411 }
412
413 pub fn color_alias(&self, id: &str) -> Color {
415 match self.try_aliased(id) {
416 Some(ColorIdx { 0: c, 1: idx }) => {
417 if c != Colors::None {
418 self.color[c as usize][idx]
419 } else {
420 Color::default()
421 }
422 }
423 None => {
424 if cfg!(debug_assertions) {
425 panic!("unknown aliased color {:?}", id);
426 } else {
427 Color::default()
428 }
429 }
430 }
431 }
432
433 pub fn style_alias(&self, bg: &str) -> Style {
437 let color = self.color_alias(bg);
438 self.normal_contrast(color)
439 }
440
441 pub fn high_style_alias(&self, bg: &str) -> Style {
445 let color = self.color_alias(bg);
446 self.high_contrast(color)
447 }
448
449 pub fn fg_bg_style_alias(&self, fg: &str, bg: &str) -> Style {
452 let color = self.color_alias(fg);
453 let color_bg = self.color_alias(bg);
454 let mut style = Style::new();
455 if color != Color::Reset {
456 style = style.fg(color);
457 }
458 if color_bg != Color::Reset {
459 style = style.bg(color_bg);
460 }
461 style
462 }
463
464 pub fn fg_style_alias(&self, fg: &str) -> Style {
467 let color = self.color_alias(fg);
468 let mut style = Style::new();
469 if color != Color::Reset {
470 style = style.fg(color);
471 }
472 style
473 }
474
475 pub fn bg_style_alias(&self, bg: &str) -> Style {
478 let color = self.color_alias(bg);
479 let mut style = Style::new();
480 if color != Color::Reset {
481 style = style.bg(color);
482 }
483 style
484 }
485}
486
487impl Palette {
488 pub fn high_contrast(&self, color: Color) -> Style {
492 match Self::rate_text_color(color) {
493 None => Style::new(),
494 Some(Rating::Light) => Style::new().bg(color).fg(self.color(Colors::TextLight, 3)),
495 Some(Rating::Dark) => Style::new().bg(color).fg(self.color(Colors::TextDark, 3)),
496 }
497 }
498
499 pub fn normal_contrast(&self, color: Color) -> Style {
503 match Self::rate_text_color(color) {
504 None => Style::new(),
505 Some(Rating::Light) => Style::new().bg(color).fg(self.color(Colors::TextLight, 0)),
506 Some(Rating::Dark) => Style::new().bg(color).fg(self.color(Colors::TextDark, 0)),
507 }
508 }
509
510 pub fn normal_contrast_color(&self, bg: Color, text: &[Color]) -> Style {
513 if bg == Color::Reset {
514 return Style::new();
515 }
516 let mut color0 = text[0];
517 let mut color1 = text[0];
518 let mut contrast1 = Self::contrast_bt_srgb(color1, bg);
519
520 for text_color in text {
521 let test = Self::contrast_bt_srgb(*text_color, bg);
522 if test > contrast1 {
523 color0 = color1;
524 color1 = *text_color;
525 contrast1 = test;
526 }
527 }
528
529 Style::new().bg(bg).fg(color0)
530 }
531
532 pub fn high_contrast_color(&self, bg: Color, text: &[Color]) -> Style {
535 if bg == Color::Reset {
536 return Style::new();
537 }
538 let mut color0 = text[0];
539 let mut color1 = text[0];
540 let mut contrast1 = Self::contrast_bt_srgb(color1, bg);
541
542 for text_color in text {
543 let test = Self::contrast_bt_srgb(*text_color, bg);
544 if test > contrast1 {
545 color0 = color1;
546 color1 = *text_color;
547 contrast1 = test;
548 }
549 }
550 _ = color0;
552
553 Style::new().bg(bg).fg(color1)
554 }
555
556 pub(crate) const fn luminance_bt(color: Color) -> f32 {
581 let (r, g, b) = Self::color_to_rgb(color);
582 0.2126f32 * ((r as f32) / 255f32)
583 + 0.7152f32 * ((g as f32) / 255f32)
584 + 0.0722f32 * ((b as f32) / 255f32)
585 }
586
587 pub(crate) fn luminance_bt_srgb(color: Color) -> f32 {
589 let (r, g, b) = Self::color_to_rgb(color);
590 0.2126f32 * ((r as f32) / 255f32).powf(2.2f32)
591 + 0.7152f32 * ((g as f32) / 255f32).powf(2.2f32)
592 + 0.0722f32 * ((b as f32) / 255f32).powf(2.2f32)
593 }
594
595 pub(crate) fn contrast_bt_srgb(color: Color, color2: Color) -> f32 {
597 let lum1 = Self::luminance_bt_srgb(color);
598 let lum2 = Self::luminance_bt_srgb(color2);
599 (lum1 - lum2).abs()
600 }
604
605 pub(crate) fn rate_text_color(color: Color) -> Option<Rating> {
616 match color {
617 Color::Reset => None,
618 Color::Black => Some(Rating::Light), Color::Red => Some(Rating::Light), Color::Green => Some(Rating::Light), Color::Yellow => Some(Rating::Light), Color::Blue => Some(Rating::Light), Color::Magenta => Some(Rating::Light), Color::Cyan => Some(Rating::Light), Color::Gray => Some(Rating::Dark), Color::DarkGray => Some(Rating::Light), Color::LightRed => Some(Rating::Dark), Color::LightGreen => Some(Rating::Dark), Color::LightYellow => Some(Rating::Dark), Color::LightBlue => Some(Rating::Light), Color::LightMagenta => Some(Rating::Dark), Color::LightCyan => Some(Rating::Dark), Color::White => Some(Rating::Dark), c => {
635 let lum = Self::luminance_bt(c);
636 if lum >= 0.4117f32 {
637 Some(Rating::Dark)
638 } else {
639 Some(Rating::Light)
640 }
641 }
642 }
643 }
644
645 pub const fn grayscale(color: Color) -> Color {
647 let lum = Self::luminance_bt(color);
648 let gray = lum * 255f32;
649 Color::Rgb(gray as u8, gray as u8, gray as u8)
650 }
651
652 pub const fn color_from_u32(c: u32) -> Color {
654 let r0 = (c >> 16) as u8;
655 let g0 = (c >> 8) as u8;
656 let b0 = c as u8;
657 Color::Rgb(r0, g0, b0)
658 }
659
660 pub const fn color_to_u32(color: Color) -> u32 {
662 let (r, g, b) = Self::color_to_rgb(color);
663 ((r as u32) << 16) + ((g as u32) << 8) + (b as u32)
664 }
665
666 pub const fn interpolatec(c0: Color, c3: Color, dark_scale_to: u8) -> [Color; 8] {
670 Self::interpolate(
671 Self::color_to_u32(c0),
672 Self::color_to_u32(c3),
673 dark_scale_to,
674 )
675 }
676
677 pub const fn interpolate(c0: u32, c3: u32, dark_scale_to: u8) -> [Color; 8] {
681 let mut c4 = Self::color_to_rgb(Self::color_from_u32(c0));
683 c4.0 = Self::scale_to(c4.0, dark_scale_to);
684 c4.1 = Self::scale_to(c4.1, dark_scale_to);
685 c4.2 = Self::scale_to(c4.2, dark_scale_to);
686 let c4 = ((c4.0 as u32) << 16) + ((c4.1 as u32) << 8) + (c4.2 as u32);
687
688 let mut c7 = Self::color_to_rgb(Self::color_from_u32(c3));
689 c7.0 = Self::scale_to(c7.0, dark_scale_to);
690 c7.1 = Self::scale_to(c7.1, dark_scale_to);
691 c7.2 = Self::scale_to(c7.2, dark_scale_to);
692 let c7 = ((c7.0 as u32) << 16) + ((c7.1 as u32) << 8) + (c7.2 as u32);
693
694 Self::interpolate2(c0, c3, c4, c7)
695 }
696
697 pub const fn interpolatec2(c0: Color, c3: Color, c4: Color, c7: Color) -> [Color; 8] {
701 Self::interpolate2(
702 Self::color_to_u32(c0),
703 Self::color_to_u32(c3),
704 Self::color_to_u32(c4),
705 Self::color_to_u32(c7),
706 )
707 }
708
709 pub const fn interpolate2(c0: u32, c3: u32, c4: u32, c7: u32) -> [Color; 8] {
713 const fn i1(a: u8, b: u8) -> u8 {
715 if a < b {
716 a + (b - a) / 3
717 } else {
718 a - (a - b) / 3
719 }
720 }
721 const fn i2(a: u8, b: u8) -> u8 {
723 if a < b {
724 b - (b - a) / 3
725 } else {
726 b + (a - b) / 3
727 }
728 }
729
730 let r0 = (c0 >> 16) as u8;
731 let g0 = (c0 >> 8) as u8;
732 let b0 = c0 as u8;
733
734 let r3 = (c3 >> 16) as u8;
735 let g3 = (c3 >> 8) as u8;
736 let b3 = c3 as u8;
737
738 let r1 = i1(r0, r3);
739 let g1 = i1(g0, g3);
740 let b1 = i1(b0, b3);
741
742 let r2 = i2(r0, r3);
743 let g2 = i2(g0, g3);
744 let b2 = i2(b0, b3);
745
746 let r4 = (c4 >> 16) as u8;
748 let g4 = (c4 >> 8) as u8;
749 let b4 = c4 as u8;
750
751 let r7 = (c7 >> 16) as u8;
752 let g7 = (c7 >> 8) as u8;
753 let b7 = c7 as u8;
754
755 let r5 = i1(r4, r7);
756 let g5 = i1(g4, g7);
757 let b5 = i1(b4, b7);
758
759 let r6 = i2(r4, r7);
760 let g6 = i2(g4, g7);
761 let b6 = i2(b4, b7);
762
763 [
764 Color::Rgb(r0, g0, b0),
765 Color::Rgb(r1, g1, b1),
766 Color::Rgb(r2, g2, b2),
767 Color::Rgb(r3, g3, b3),
768 Color::Rgb(r4, g4, b4),
769 Color::Rgb(r5, g5, b5),
770 Color::Rgb(r6, g6, b6),
771 Color::Rgb(r7, g7, b7),
772 ]
773 }
774
775 pub const fn scale_to(v: u8, scale_to: u8) -> u8 {
777 (((v as u16) * scale_to as u16) / 255u16) as u8
778 }
779
780 pub const fn color_to_rgb(color: Color) -> (u8, u8, u8) {
783 match color {
784 Color::Black => (0x00, 0x00, 0x00),
785 Color::Red => (0xaa, 0x00, 0x00),
786 Color::Green => (0x00, 0xaa, 0x00),
787 Color::Yellow => (0xaa, 0x55, 0x00),
788 Color::Blue => (0x00, 0x00, 0xaa),
789 Color::Magenta => (0xaa, 0x00, 0xaa),
790 Color::Cyan => (0x00, 0xaa, 0xaa),
791 Color::Gray => (0xaa, 0xaa, 0xaa),
792 Color::DarkGray => (0x55, 0x55, 0x55),
793 Color::LightRed => (0xff, 0x55, 0x55),
794 Color::LightGreen => (0x55, 0xff, 0x55),
795 Color::LightYellow => (0xff, 0xff, 0x55),
796 Color::LightBlue => (0x55, 0x55, 0xff),
797 Color::LightMagenta => (0xff, 0x55, 0xff),
798 Color::LightCyan => (0x55, 0xff, 0xff),
799 Color::White => (0xff, 0xff, 0xff),
800 Color::Rgb(r, g, b) => (r, g, b),
801 Color::Indexed(i) => {
802 const VGA256: [(u8, u8, u8); 256] = [
803 (0x00, 0x00, 0x00),
804 (0x80, 0x00, 0x00),
805 (0x00, 0x80, 0x00),
806 (0x80, 0x80, 0x00),
807 (0x00, 0x00, 0x80),
808 (0x80, 0x00, 0x80),
809 (0x00, 0x80, 0x80),
810 (0xc0, 0xc0, 0xc0),
811 (0x80, 0x80, 0x80),
812 (0xff, 0x00, 0x00),
813 (0x00, 0xff, 0x00),
814 (0xff, 0xff, 0x00),
815 (0x00, 0x00, 0xff),
816 (0xff, 0x00, 0xff),
817 (0x00, 0xff, 0xff),
818 (0xff, 0xff, 0xff),
819 (0x00, 0x00, 0x00),
820 (0x00, 0x00, 0x5f),
821 (0x00, 0x00, 0x87),
822 (0x00, 0x00, 0xaf),
823 (0x00, 0x00, 0xd7),
824 (0x00, 0x00, 0xff),
825 (0x00, 0x5f, 0x00),
826 (0x00, 0x5f, 0x5f),
827 (0x00, 0x5f, 0x87),
828 (0x00, 0x5f, 0xaf),
829 (0x00, 0x5f, 0xd7),
830 (0x00, 0x5f, 0xff),
831 (0x00, 0x87, 0x00),
832 (0x00, 0x87, 0x5f),
833 (0x00, 0x87, 0x87),
834 (0x00, 0x87, 0xaf),
835 (0x00, 0x87, 0xd7),
836 (0x00, 0x87, 0xff),
837 (0x00, 0xaf, 0x00),
838 (0x00, 0xaf, 0x5f),
839 (0x00, 0xaf, 0x87),
840 (0x00, 0xaf, 0xaf),
841 (0x00, 0xaf, 0xd7),
842 (0x00, 0xaf, 0xff),
843 (0x00, 0xd7, 0x00),
844 (0x00, 0xd7, 0x5f),
845 (0x00, 0xd7, 0x87),
846 (0x00, 0xd7, 0xaf),
847 (0x00, 0xd7, 0xd7),
848 (0x00, 0xd7, 0xff),
849 (0x00, 0xff, 0x00),
850 (0x00, 0xff, 0x5f),
851 (0x00, 0xff, 0x87),
852 (0x00, 0xff, 0xaf),
853 (0x00, 0xff, 0xd7),
854 (0x00, 0xff, 0xff),
855 (0x5f, 0x00, 0x00),
856 (0x5f, 0x00, 0x5f),
857 (0x5f, 0x00, 0x87),
858 (0x5f, 0x00, 0xaf),
859 (0x5f, 0x00, 0xd7),
860 (0x5f, 0x00, 0xff),
861 (0x5f, 0x5f, 0x00),
862 (0x5f, 0x5f, 0x5f),
863 (0x5f, 0x5f, 0x87),
864 (0x5f, 0x5f, 0xaf),
865 (0x5f, 0x5f, 0xd7),
866 (0x5f, 0x5f, 0xff),
867 (0x5f, 0x87, 0x00),
868 (0x5f, 0x87, 0x5f),
869 (0x5f, 0x87, 0x87),
870 (0x5f, 0x87, 0xaf),
871 (0x5f, 0x87, 0xd7),
872 (0x5f, 0x87, 0xff),
873 (0x5f, 0xaf, 0x00),
874 (0x5f, 0xaf, 0x5f),
875 (0x5f, 0xaf, 0x87),
876 (0x5f, 0xaf, 0xaf),
877 (0x5f, 0xaf, 0xd7),
878 (0x5f, 0xaf, 0xff),
879 (0x5f, 0xd7, 0x00),
880 (0x5f, 0xd7, 0x5f),
881 (0x5f, 0xd7, 0x87),
882 (0x5f, 0xd7, 0xaf),
883 (0x5f, 0xd7, 0xd7),
884 (0x5f, 0xd7, 0xff),
885 (0x5f, 0xff, 0x00),
886 (0x5f, 0xff, 0x5f),
887 (0x5f, 0xff, 0x87),
888 (0x5f, 0xff, 0xaf),
889 (0x5f, 0xff, 0xd7),
890 (0x5f, 0xff, 0xff),
891 (0x87, 0x00, 0x00),
892 (0x87, 0x00, 0x5f),
893 (0x87, 0x00, 0x87),
894 (0x87, 0x00, 0xaf),
895 (0x87, 0x00, 0xd7),
896 (0x87, 0x00, 0xff),
897 (0x87, 0x5f, 0x00),
898 (0x87, 0x5f, 0x5f),
899 (0x87, 0x5f, 0x87),
900 (0x87, 0x5f, 0xaf),
901 (0x87, 0x5f, 0xd7),
902 (0x87, 0x5f, 0xff),
903 (0x87, 0x87, 0x00),
904 (0x87, 0x87, 0x5f),
905 (0x87, 0x87, 0x87),
906 (0x87, 0x87, 0xaf),
907 (0x87, 0x87, 0xd7),
908 (0x87, 0x87, 0xff),
909 (0x87, 0xaf, 0x00),
910 (0x87, 0xaf, 0x5f),
911 (0x87, 0xaf, 0x87),
912 (0x87, 0xaf, 0xaf),
913 (0x87, 0xaf, 0xd7),
914 (0x87, 0xaf, 0xff),
915 (0x87, 0xd7, 0x00),
916 (0x87, 0xd7, 0x5f),
917 (0x87, 0xd7, 0x87),
918 (0x87, 0xd7, 0xaf),
919 (0x87, 0xd7, 0xd7),
920 (0x87, 0xd7, 0xff),
921 (0x87, 0xff, 0x00),
922 (0x87, 0xff, 0x5f),
923 (0x87, 0xff, 0x87),
924 (0x87, 0xff, 0xaf),
925 (0x87, 0xff, 0xd7),
926 (0x87, 0xff, 0xff),
927 (0xaf, 0x00, 0x00),
928 (0xaf, 0x00, 0x5f),
929 (0xaf, 0x00, 0x87),
930 (0xaf, 0x00, 0xaf),
931 (0xaf, 0x00, 0xd7),
932 (0xaf, 0x00, 0xff),
933 (0xaf, 0x5f, 0x00),
934 (0xaf, 0x5f, 0x5f),
935 (0xaf, 0x5f, 0x87),
936 (0xaf, 0x5f, 0xaf),
937 (0xaf, 0x5f, 0xd7),
938 (0xaf, 0x5f, 0xff),
939 (0xaf, 0x87, 0x00),
940 (0xaf, 0x87, 0x5f),
941 (0xaf, 0x87, 0x87),
942 (0xaf, 0x87, 0xaf),
943 (0xaf, 0x87, 0xd7),
944 (0xaf, 0x87, 0xff),
945 (0xaf, 0xaf, 0x00),
946 (0xaf, 0xaf, 0x5f),
947 (0xaf, 0xaf, 0x87),
948 (0xaf, 0xaf, 0xaf),
949 (0xaf, 0xaf, 0xd7),
950 (0xaf, 0xaf, 0xff),
951 (0xaf, 0xd7, 0x00),
952 (0xaf, 0xd7, 0x5f),
953 (0xaf, 0xd7, 0x87),
954 (0xaf, 0xd7, 0xaf),
955 (0xaf, 0xd7, 0xd7),
956 (0xaf, 0xd7, 0xff),
957 (0xaf, 0xff, 0x00),
958 (0xaf, 0xff, 0x5f),
959 (0xaf, 0xff, 0x87),
960 (0xaf, 0xff, 0xaf),
961 (0xaf, 0xff, 0xd7),
962 (0xaf, 0xff, 0xff),
963 (0xd7, 0x00, 0x00),
964 (0xd7, 0x00, 0x5f),
965 (0xd7, 0x00, 0x87),
966 (0xd7, 0x00, 0xaf),
967 (0xd7, 0x00, 0xd7),
968 (0xd7, 0x00, 0xff),
969 (0xd7, 0x5f, 0x00),
970 (0xd7, 0x5f, 0x5f),
971 (0xd7, 0x5f, 0x87),
972 (0xd7, 0x5f, 0xaf),
973 (0xd7, 0x5f, 0xd7),
974 (0xd7, 0x5f, 0xff),
975 (0xd7, 0x87, 0x00),
976 (0xd7, 0x87, 0x5f),
977 (0xd7, 0x87, 0x87),
978 (0xd7, 0x87, 0xaf),
979 (0xd7, 0x87, 0xd7),
980 (0xd7, 0x87, 0xff),
981 (0xd7, 0xaf, 0x00),
982 (0xd7, 0xaf, 0x5f),
983 (0xd7, 0xaf, 0x87),
984 (0xd7, 0xaf, 0xaf),
985 (0xd7, 0xaf, 0xd7),
986 (0xd7, 0xaf, 0xff),
987 (0xd7, 0xd7, 0x00),
988 (0xd7, 0xd7, 0x5f),
989 (0xd7, 0xd7, 0x87),
990 (0xd7, 0xd7, 0xaf),
991 (0xd7, 0xd7, 0xd7),
992 (0xd7, 0xd7, 0xff),
993 (0xd7, 0xff, 0x00),
994 (0xd7, 0xff, 0x5f),
995 (0xd7, 0xff, 0x87),
996 (0xd7, 0xff, 0xaf),
997 (0xd7, 0xff, 0xd7),
998 (0xd7, 0xff, 0xff),
999 (0xff, 0x00, 0x00),
1000 (0xff, 0x00, 0x5f),
1001 (0xff, 0x00, 0x87),
1002 (0xff, 0x00, 0xaf),
1003 (0xff, 0x00, 0xd7),
1004 (0xff, 0x00, 0xff),
1005 (0xff, 0x5f, 0x00),
1006 (0xff, 0x5f, 0x5f),
1007 (0xff, 0x5f, 0x87),
1008 (0xff, 0x5f, 0xaf),
1009 (0xff, 0x5f, 0xd7),
1010 (0xff, 0x5f, 0xff),
1011 (0xff, 0x87, 0x00),
1012 (0xff, 0x87, 0x5f),
1013 (0xff, 0x87, 0x87),
1014 (0xff, 0x87, 0xaf),
1015 (0xff, 0x87, 0xd7),
1016 (0xff, 0x87, 0xff),
1017 (0xff, 0xaf, 0x00),
1018 (0xff, 0xaf, 0x5f),
1019 (0xff, 0xaf, 0x87),
1020 (0xff, 0xaf, 0xaf),
1021 (0xff, 0xaf, 0xd7),
1022 (0xff, 0xaf, 0xff),
1023 (0xff, 0xd7, 0x00),
1024 (0xff, 0xd7, 0x5f),
1025 (0xff, 0xd7, 0x87),
1026 (0xff, 0xd7, 0xaf),
1027 (0xff, 0xd7, 0xd7),
1028 (0xff, 0xd7, 0xff),
1029 (0xff, 0xff, 0x00),
1030 (0xff, 0xff, 0x5f),
1031 (0xff, 0xff, 0x87),
1032 (0xff, 0xff, 0xaf),
1033 (0xff, 0xff, 0xd7),
1034 (0xff, 0xff, 0xff),
1035 (0x08, 0x08, 0x08),
1036 (0x12, 0x12, 0x12),
1037 (0x1c, 0x1c, 0x1c),
1038 (0x26, 0x26, 0x26),
1039 (0x30, 0x30, 0x30),
1040 (0x3a, 0x3a, 0x3a),
1041 (0x44, 0x44, 0x44),
1042 (0x4e, 0x4e, 0x4e),
1043 (0x58, 0x58, 0x58),
1044 (0x62, 0x62, 0x62),
1045 (0x6c, 0x6c, 0x6c),
1046 (0x76, 0x76, 0x76),
1047 (0x80, 0x80, 0x80),
1048 (0x8a, 0x8a, 0x8a),
1049 (0x94, 0x94, 0x94),
1050 (0x9e, 0x9e, 0x9e),
1051 (0xa8, 0xa8, 0xa8),
1052 (0xb2, 0xb2, 0xb2),
1053 (0xbc, 0xbc, 0xbc),
1054 (0xc6, 0xc6, 0xc6),
1055 (0xd0, 0xd0, 0xd0),
1056 (0xda, 0xda, 0xda),
1057 (0xe4, 0xe4, 0xe4),
1058 (0xee, 0xee, 0xee),
1059 ];
1060 VGA256[i as usize]
1061 }
1062 Color::Reset => (0, 0, 0),
1063 }
1064 }
1065}