pub type Rgb = u32;
#[rustfmt::skip]
pub const VGA: [Rgb; 16] = [
0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF,
];
pub const ANSI_TO_VGA: [u8; 8] = [0, 4, 2, 6, 1, 5, 3, 7];
pub fn xterm256(i: u8) -> Rgb {
match i {
0..=7 => VGA[ANSI_TO_VGA[i as usize] as usize],
8..=15 => VGA[ANSI_TO_VGA[(i - 8) as usize] as usize + 8],
16..=231 => {
let i = i - 16;
let level = |v: u8| if v == 0 { 0 } else { 55 + 40 * v as u32 };
(level(i / 36) << 16) | (level((i / 6) % 6) << 8) | level(i % 6)
}
232..=255 => {
let v = 8 + 10 * (i - 232) as u32;
(v << 16) | (v << 8) | v
}
}
}
pub const fn rgb(r: u8, g: u8, b: u8) -> Rgb {
((r as u32) << 16) | ((g as u32) << 8) | b as u32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn xterm_cube_corners() {
assert_eq!(xterm256(16), 0x000000);
assert_eq!(xterm256(231), 0xFFFFFF);
assert_eq!(xterm256(196), 0xFF0000);
assert_eq!(xterm256(1), 0xAA0000);
assert_eq!(xterm256(4), 0x0000AA);
}
}