1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
use unicode_normalization::UnicodeNormalization as _;
use unicode_width::UnicodeWidthChar as _;
/// Represents a single terminal cell.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Cell {
contents: String,
attrs: crate::attrs::Attrs,
}
impl Cell {
pub(crate) fn set(&mut self, c: char, a: crate::attrs::Attrs) {
let mut buf = vec![0; 4];
c.encode_utf8(&mut buf);
self.contents = unsafe { String::from_utf8_unchecked(buf) };
self.attrs = a;
}
pub(crate) fn append(&mut self, c: char) {
self.contents.push(c);
// some fonts have combined characters but can't render combining
// characters correctly, so try to prefer precombined characters when
// possible
if !unicode_normalization::is_nfc(&self.contents) {
self.contents = self.contents.nfc().collect();
}
}
pub(crate) fn clear(&mut self, bgcolor: crate::attrs::Color) {
self.contents.clear();
self.attrs.clear();
self.attrs.bgcolor = bgcolor;
}
/// Returns the text contents of the cell.
///
/// Can include multiple unicode characters if combining characters are
/// used, but will contain at most one character with a non-zero character
/// width.
pub fn contents(&self) -> &str {
&self.contents
}
/// Returns whether the cell contains any text data.
pub fn has_contents(&self) -> bool {
self.contents != ""
}
/// Returns whether the text data in the cell represents a wide character.
pub fn is_wide(&self) -> bool {
// strings in this context should always be an arbitrary character
// followed by zero or more zero-width characters, so we should only
// have to look at the first character
let width = self
.contents
.chars()
.next()
.map_or(0, |c| c.width().unwrap_or(0));
width > 1
}
pub(crate) fn attrs(&self) -> &crate::attrs::Attrs {
&self.attrs
}
/// Returns the foreground color of the cell.
pub fn fgcolor(&self) -> crate::attrs::Color {
self.attrs.fgcolor
}
/// Returns the background color of the cell.
pub fn bgcolor(&self) -> crate::attrs::Color {
self.attrs.bgcolor
}
/// Returns whether the cell should be rendered with the bold text
/// attribute.
pub fn bold(&self) -> bool {
self.attrs.bold()
}
/// Returns whether the cell should be rendered with the italic text
/// attribute.
pub fn italic(&self) -> bool {
self.attrs.italic()
}
/// Returns whether the cell should be rendered with the underlined text
/// attribute.
pub fn underline(&self) -> bool {
self.attrs.underline()
}
/// Returns whether the cell should be rendered with the inverse text
/// attribute.
pub fn inverse(&self) -> bool {
self.attrs.inverse()
}
}
|