Get individual grapheme's width

This commit is contained in:
Joscha 2022-05-28 11:15:18 +02:00
parent 833defd1ce
commit 3b2ea37ba5
3 changed files with 32 additions and 6 deletions

View file

@ -141,7 +141,7 @@ impl Buffer {
let y = pos.y as u16; let y = pos.y as u16;
for grapheme in content.graphemes(true) { 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); self.write_grapheme(pos.x, y, width, grapheme, style);
pos.x += width as i32; pos.x += width as i32;
} }

View file

@ -39,7 +39,19 @@ impl Frame {
self.set_cursor(None); 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) self.widthdb.width(s)
} }

View file

@ -16,18 +16,32 @@ pub struct WidthDB {
} }
impl WidthDB { impl WidthDB {
/// Determine the width of a string based on its graphemes. /// Determine the width of a grapheme.
/// ///
/// If the width of a grapheme has not been measured yet, it is estimated /// If the width has not been measured yet, it is estimated using the
/// using the Unicode Standard Annex #11. /// Unicode Standard Annex #11.
pub fn width(&mut self, s: &str) -> u8 { pub fn grapheme_width(&mut self, grapheme: &str) -> u8 {
let mut total = 0; assert_eq!(Some(grapheme), grapheme.graphemes(true).next());
for grapheme in s.graphemes(true) { if let Some(width) = self.known.get(grapheme) {
total += if let Some(width) = self.known.get(grapheme) {
*width *width
} else { } else {
self.requested.insert(grapheme.to_string()); self.requested.insert(grapheme.to_string());
grapheme.width() as u8 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) -> usize {
let mut total: usize = 0;
for grapheme in s.graphemes(true) {
total += if let Some(width) = self.known.get(grapheme) {
(*width).into()
} else {
self.requested.insert(grapheme.to_string());
grapheme.width()
}; };
} }
total total