diff --git a/src/buffer.rs b/src/buffer.rs index e51f20e..77756f3 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -141,7 +141,7 @@ impl Buffer { let y = pos.y as u16; for grapheme in content.graphemes(true) { - let width = widthdb.width(grapheme); + let width = widthdb.grapheme_width(grapheme); self.write_grapheme(pos.x, y, width, grapheme, style); pos.x += width as i32; } diff --git a/src/frame.rs b/src/frame.rs index eef783e..762246a 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -39,7 +39,19 @@ impl Frame { self.set_cursor(None); } - pub fn width(&mut self, s: &str) -> u8 { + /// Determine the width of a grapheme. + /// + /// If the width has not been measured yet, it is estimated using the + /// Unicode Standard Annex #11. + pub fn grapheme_width(&mut self, grapheme: &str) -> u8 { + self.widthdb.grapheme_width(grapheme) + } + + /// Determine the width of a string based on its graphemes. + /// + /// If the width of a grapheme has not been measured yet, it is estimated + /// using the Unicode Standard Annex #11. + pub fn width(&mut self, s: &str) -> usize { self.widthdb.width(s) } diff --git a/src/widthdb.rs b/src/widthdb.rs index e3605c3..9c91879 100644 --- a/src/widthdb.rs +++ b/src/widthdb.rs @@ -16,18 +16,32 @@ pub struct WidthDB { } impl WidthDB { + /// Determine the width of a grapheme. + /// + /// If the width has not been measured yet, it is estimated using the + /// Unicode Standard Annex #11. + pub fn grapheme_width(&mut self, grapheme: &str) -> u8 { + assert_eq!(Some(grapheme), grapheme.graphemes(true).next()); + if let Some(width) = self.known.get(grapheme) { + *width + } else { + self.requested.insert(grapheme.to_string()); + grapheme.width() as u8 + } + } + /// Determine the width of a string based on its graphemes. /// /// If the width of a grapheme has not been measured yet, it is estimated /// using the Unicode Standard Annex #11. - pub fn width(&mut self, s: &str) -> u8 { - let mut total = 0; + pub fn width(&mut self, s: &str) -> usize { + let mut total: usize = 0; for grapheme in s.graphemes(true) { total += if let Some(width) = self.known.get(grapheme) { - *width + (*width).into() } else { self.requested.insert(grapheme.to_string()); - grapheme.width() as u8 + grapheme.width() }; } total