From fc5f46ce938b33867f3109ba558ef4139d2294fd Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Wed, 15 Mar 2017 08:27:20 -0700 Subject: [PATCH] Fix issue rendering double, zero width chars This has an issue where many diacritics will not show up at all unless they are baked into a glyph and input as a single codepoint. --- src/term/mod.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/term/mod.rs b/src/term/mod.rs index 4ee685b1..345405ce 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -1036,6 +1036,14 @@ impl ansi::Handler for Term { /// A character to be displayed #[inline] fn input(&mut self, c: char) { + // Number of cells the char will occupy + // + // TODO handle zero width characters (eg unicode variation selectors) + let width = match c.width() { + Some(0) | None => return, + Some(width) => width, + }; + if self.input_needs_wrap { if !self.mode.contains(mode::LINE_WRAP) { return; @@ -1064,9 +1072,6 @@ impl ansi::Handler for Term { } { - // Number of cells the char will occupy - let width = c.width(); - // Sigh, borrowck making us check the width twice. Hopefully the // optimizer can fix it. { @@ -1075,24 +1080,26 @@ impl ansi::Handler for Term { cell.c = self.cursor.charsets[self.active_charset].map(c); // Handle wide chars - if let Some(2) = width { + if width == 2 { cell.flags.insert(cell::WIDE_CHAR); } } // Set spacer cell for wide chars. - if let Some(2) = width { + if width == 2 { + // Only set the wide char spacer when not at EOL if self.cursor.point.col + 1 < self.grid.num_cols() { - self.cursor.point.col += 1; - let spacer = &mut self.grid[&self.cursor.point]; + let mut point = self.cursor.point; + point.col += 1; + let spacer = &mut self.grid[&point]; *spacer = self.cursor.template; spacer.flags.insert(cell::WIDE_CHAR_SPACER); } } } - if (self.cursor.point.col + 1) < self.grid.num_cols() { - self.cursor.point.col += 1; + if (self.cursor.point.col + width) < self.grid.num_cols() { + self.cursor.point.col += width; } else { self.input_needs_wrap = true; }