diff options
Diffstat (limited to 'src/term/cell.rs')
-rw-r--r-- | src/term/cell.rs | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/term/cell.rs b/src/term/cell.rs index ef8509dc..e6fe980e 100644 --- a/src/term/cell.rs +++ b/src/term/cell.rs @@ -15,9 +15,12 @@ use ansi::{NamedColor, Color}; use grid; use index::Column; +// Maximum number of zerowidth characters which will be stored per cell. +pub const MAX_ZEROWIDTH_CHARS: usize = 5; + bitflags! { #[derive(Serialize, Deserialize)] - pub struct Flags: u32 { + pub struct Flags: u16 { const INVERSE = 0b0_0000_0001; const BOLD = 0b0_0000_0010; const ITALIC = 0b0_0000_0100; @@ -31,12 +34,18 @@ bitflags! { } } +const fn default_extra() -> [char; MAX_ZEROWIDTH_CHARS] { + [' '; MAX_ZEROWIDTH_CHARS] +} + #[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] pub struct Cell { pub c: char, pub fg: Color, pub bg: Color, pub flags: Flags, + #[serde(default="default_extra")] + pub extra: [char; MAX_ZEROWIDTH_CHARS], } impl Default for Cell { @@ -65,7 +74,7 @@ impl LineLength for grid::Row<Cell> { } for (index, cell) in self[..].iter().rev().enumerate() { - if cell.c != ' ' { + if cell.c != ' ' || cell.extra[0] != ' ' { length = Column(self.len() - index); break; } @@ -93,6 +102,7 @@ impl Cell { pub fn new(c: char, fg: Color, bg: Color) -> Cell { Cell { + extra: [' '; MAX_ZEROWIDTH_CHARS], c, bg, fg, @@ -102,9 +112,10 @@ impl Cell { #[inline] pub fn is_empty(&self) -> bool { - self.c == ' ' && - self.bg == Color::Named(NamedColor::Background) && - !self.flags.intersects(Flags::INVERSE | Flags::UNDERLINE) + self.c == ' ' + && self.extra[0] == ' ' + && self.bg == Color::Named(NamedColor::Background) + && !self.flags.intersects(Flags::INVERSE | Flags::UNDERLINE) } #[inline] @@ -112,6 +123,30 @@ impl Cell { // memcpy template to self *self = *template; } + + #[inline] + pub fn chars(&self) -> [char; MAX_ZEROWIDTH_CHARS + 1] { + unsafe { + let mut chars = [std::mem::uninitialized(); MAX_ZEROWIDTH_CHARS + 1]; + std::ptr::write(&mut chars[0], self.c); + std::ptr::copy_nonoverlapping( + self.extra.as_ptr(), + chars.as_mut_ptr().offset(1), + self.extra.len(), + ); + chars + } + } + + #[inline] + pub fn push_extra(&mut self, c: char) { + for elem in self.extra.iter_mut() { + if elem == &' ' { + *elem = c; + break; + } + } + } } #[cfg(test)] |