1use crate::term::BufWrite as _;
2
3#[derive(Eq, PartialEq, Debug, Copy, Clone)]
5pub enum Color {
6 Default,
8
9 Idx(u8),
11
12 Rgb(u8, u8, u8),
14}
15
16impl Default for Color {
17 fn default() -> Self {
18 Self::Default
19 }
20}
21
22const TEXT_MODE_BOLD: u8 = 0b0000_0001;
23const TEXT_MODE_ITALIC: u8 = 0b0000_0010;
24const TEXT_MODE_UNDERLINE: u8 = 0b0000_0100;
25const TEXT_MODE_INVERSE: u8 = 0b0000_1000;
26
27#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
28pub struct Attrs {
29 pub fgcolor: Color,
30 pub bgcolor: Color,
31 pub mode: u8,
32}
33
34impl Attrs {
35 pub fn bold(&self) -> bool {
36 self.mode & TEXT_MODE_BOLD != 0
37 }
38
39 pub fn set_bold(&mut self, bold: bool) {
40 if bold {
41 self.mode |= TEXT_MODE_BOLD;
42 } else {
43 self.mode &= !TEXT_MODE_BOLD;
44 }
45 }
46
47 pub fn italic(&self) -> bool {
48 self.mode & TEXT_MODE_ITALIC != 0
49 }
50
51 pub fn set_italic(&mut self, italic: bool) {
52 if italic {
53 self.mode |= TEXT_MODE_ITALIC;
54 } else {
55 self.mode &= !TEXT_MODE_ITALIC;
56 }
57 }
58
59 pub fn underline(&self) -> bool {
60 self.mode & TEXT_MODE_UNDERLINE != 0
61 }
62
63 pub fn set_underline(&mut self, underline: bool) {
64 if underline {
65 self.mode |= TEXT_MODE_UNDERLINE;
66 } else {
67 self.mode &= !TEXT_MODE_UNDERLINE;
68 }
69 }
70
71 pub fn inverse(&self) -> bool {
72 self.mode & TEXT_MODE_INVERSE != 0
73 }
74
75 pub fn set_inverse(&mut self, inverse: bool) {
76 if inverse {
77 self.mode |= TEXT_MODE_INVERSE;
78 } else {
79 self.mode &= !TEXT_MODE_INVERSE;
80 }
81 }
82
83 pub fn write_escape_code_diff(
84 &self,
85 contents: &mut Vec<u8>,
86 other: &Self,
87 ) {
88 if self != other && self == &Self::default() {
89 crate::term::ClearAttrs::default().write_buf(contents);
90 return;
91 }
92
93 let attrs = crate::term::Attrs::default();
94
95 let attrs = if self.fgcolor == other.fgcolor {
96 attrs
97 } else {
98 attrs.fgcolor(self.fgcolor)
99 };
100 let attrs = if self.bgcolor == other.bgcolor {
101 attrs
102 } else {
103 attrs.bgcolor(self.bgcolor)
104 };
105 let attrs = if self.bold() == other.bold() {
106 attrs
107 } else {
108 attrs.bold(self.bold())
109 };
110 let attrs = if self.italic() == other.italic() {
111 attrs
112 } else {
113 attrs.italic(self.italic())
114 };
115 let attrs = if self.underline() == other.underline() {
116 attrs
117 } else {
118 attrs.underline(self.underline())
119 };
120 let attrs = if self.inverse() == other.inverse() {
121 attrs
122 } else {
123 attrs.inverse(self.inverse())
124 };
125
126 attrs.write_buf(contents);
127 }
128}