diff options
author | Christian Duerr <chrisduerr@users.noreply.github.com> | 2018-12-09 15:28:22 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-09 15:28:22 +0000 |
commit | 1cebcd660bf0b6dc514341fe6bc7a392b1572849 (patch) | |
tree | 47a4012107030a73c986e9746aee4bd3a23f1807 /src/term/cell.rs | |
parent | 47f8f1bac6f0b41fe1ad9c4267687db7a42068de (diff) | |
download | r-alacritty-1cebcd660bf0b6dc514341fe6bc7a392b1572849.tar.gz r-alacritty-1cebcd660bf0b6dc514341fe6bc7a392b1572849.tar.bz2 r-alacritty-1cebcd660bf0b6dc514341fe6bc7a392b1572849.zip |
Fix rendering of zero-width characters
Instead of rendering zero-width characters as full characters, they are
now properly rendered without advancing the cursor.
Because of performance limitations, this implementation only supports up
to 5 zero-width characters per cell. However, as a result of this
limitation there should not be any performance impact.
This fixes #1317, fixes #696 and closes #1318.
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)] |