use crate::term::BufWrite as _; /// Represents a foreground or background color for cells. #[derive(Eq, PartialEq, Debug, Copy, Clone)] pub enum Color { /// The default terminal color. Default, /// An indexed terminal color. Idx(u8), /// An RGB terminal color. The parameters are (red, green, blue). Rgb(u8, u8, u8), } impl Default for Color { fn default() -> Self { Self::Default } } const TEXT_MODE_BOLD: u8 = 0b0000_0001; const TEXT_MODE_ITALIC: u8 = 0b0000_0010; const TEXT_MODE_UNDERLINE: u8 = 0b0000_0100; const TEXT_MODE_INVERSE: u8 = 0b0000_1000; #[derive(Default, Clone, Copy, PartialEq, Eq, Debug)] pub struct Attrs { pub fgcolor: Color, pub bgcolor: Color, pub mode: u8, } impl Attrs { pub fn bold(&self) -> bool { self.mode & TEXT_MODE_BOLD != 0 } pub fn set_bold(&mut self, bold: bool) { if bold { self.mode |= TEXT_MODE_BOLD; } else { self.mode &= !TEXT_MODE_BOLD; } } pub fn italic(&self) -> bool { self.mode & TEXT_MODE_ITALIC != 0 } pub fn set_italic(&mut self, italic: bool) { if italic { self.mode |= TEXT_MODE_ITALIC; } else { self.mode &= !TEXT_MODE_ITALIC; } } pub fn underline(&self) -> bool { self.mode & TEXT_MODE_UNDERLINE != 0 } pub fn set_underline(&mut self, underline: bool) { if underline { self.mode |= TEXT_MODE_UNDERLINE; } else { self.mode &= !TEXT_MODE_UNDERLINE; } } pub fn inverse(&self) -> bool { self.mode & TEXT_MODE_INVERSE != 0 } pub fn set_inverse(&mut self, inverse: bool) { if inverse { self.mode |= TEXT_MODE_INVERSE; } else { self.mode &= !TEXT_MODE_INVERSE; } } pub fn write_escape_code_diff( &self, contents: &mut Vec, other: &Self, ) { if self != other && self == &Self::default() { crate::term::ClearAttrs.write_buf(contents); return; } let attrs = crate::term::Attrs::default(); let attrs = if self.fgcolor == other.fgcolor { attrs } else { attrs.fgcolor(self.fgcolor) }; let attrs = if self.bgcolor == other.bgcolor { attrs } else { attrs.bgcolor(self.bgcolor) }; let attrs = if self.bold() == other.bold() { attrs } else { attrs.bold(self.bold()) }; let attrs = if self.italic() == other.italic() { attrs } else { attrs.italic(self.italic()) }; let attrs = if self.underline() == other.underline() { attrs } else { attrs.underline(self.underline()) }; let attrs = if self.inverse() == other.inverse() { attrs } else { attrs.inverse(self.inverse()) }; attrs.write_buf(contents); } }