diff --git a/ui/src/state.rs b/ui/src/state.rs index f480aea3c..896ebb599 100644 --- a/ui/src/state.rs +++ b/ui/src/state.rs @@ -415,14 +415,16 @@ impl State { .unwrap(); for x in x_start..=x_end { let c = self.grid[(x, y)]; - if c.bg() != Color::Default { write!(self.stdout(), "{}", termion::color::Bg(c.bg().as_termion())).unwrap(); } if c.fg() != Color::Default { write!(self.stdout(), "{}", termion::color::Fg(c.fg().as_termion())).unwrap(); } - write!(self.stdout(), "{}", c.ch()).unwrap(); + if !c.empty() { + write!(self.stdout(), "{}", c.ch()).unwrap(); + } + if c.bg() != Color::Default { write!( self.stdout(), diff --git a/ui/src/terminal/cells.rs b/ui/src/terminal/cells.rs index 97a4b5b4a..6208ccef6 100644 --- a/ui/src/terminal/cells.rs +++ b/ui/src/terminal/cells.rs @@ -25,6 +25,7 @@ */ use super::position::*; +use text_processing::wcwidth; use std::convert::From; use std::fmt; @@ -280,6 +281,7 @@ impl fmt::Display for CellBuffer { pub struct Cell { ch: char, + empty: bool, fg: Color, bg: Color, attrs: Attr, @@ -300,7 +302,13 @@ impl Cell { /// assert_eq!(cell.attrs(), Attr::Default); /// ``` pub fn new(ch: char, fg: Color, bg: Color, attrs: Attr) -> Cell { - Cell { ch, fg, bg, attrs } + Cell { + ch, + fg, + bg, + attrs, + empty: false, + } } /// Creates a new `Cell` with the given `char` and default style. @@ -441,6 +449,10 @@ impl Cell { self.attrs = newattrs; self } + + pub fn empty(&self) -> bool { + self.empty + } } impl Default for Cell { @@ -750,6 +762,21 @@ pub fn write_string_to_grid( grid[(x, y)].set_fg(fg_color); grid[(x, y)].set_bg(bg_color); } + + match wcwidth(u32::from(c)) { + Some(0) | None => { + /* Skip drawing zero width characters */ + grid[(x, y)].empty = true; + } + Some(2) => { + /* Grapheme takes more than one column, so the next cell will be + * drawn over. Set it as empty to skip drawing it. */ + x += 1; + inspect_bounds!(grid, area, x, y, line_break); + grid[(x, y)].empty = true; + } + _ => {} + } x += 1; inspect_bounds!(grid, area, x, y, line_break); @@ -769,6 +796,7 @@ pub fn clear_area(grid: &mut CellBuffer, area: Area) { grid[(x, y)].set_ch(' '); grid[(x, y)].set_bg(Color::Default); grid[(x, y)].set_fg(Color::Default); + grid[(x, y)].empty = false; } } }