diff --git a/examples/text/src/font/fallback/mod.rs b/examples/text/src/font/fallback/mod.rs index 03b4f072..4eca6f19 100644 --- a/examples/text/src/font/fallback/mod.rs +++ b/examples/text/src/font/fallback/mod.rs @@ -30,6 +30,7 @@ pub struct FontFallbackIter<'a> { script_i: (usize, usize), common_i: usize, other_i: usize, + end: bool, } impl<'a> FontFallbackIter<'a> { @@ -42,6 +43,36 @@ impl<'a> FontFallbackIter<'a> { script_i: (0, 0), common_i: 0, other_i: 0, + end: false, + } + } + + pub fn check_missing(&self, word: &str) { + if self.end { + log::warn!( + "Failed to find any fallback for {:?} locale '{}': '{}'", + self.scripts, + self.locale, + word + ); + } else if self.other_i > 0 { + let font = &self.fonts[self.other_i - 1]; + log::warn!( + "Failed to find preset fallback for {:?} locale '{}', used '{}': '{}'", + self.scripts, + self.locale, + font.info.family, + word + ); + } else if ! self.scripts.is_empty() && self.common_i > 0 { + let family = common_fallback()[self.common_i - 1]; + log::debug!( + "Failed to find script fallback for {:?} locale '{}', used '{}': '{}'", + self.scripts, + self.locale, + family, + word + ); } } } @@ -69,7 +100,7 @@ impl<'a> Iterator for FontFallbackIter<'a> { return Some(font); } } - log::warn!("failed to find family '{}' for script {:?} and locale '{}'", script_family, script, self.locale) + log::warn!("failed to find family '{}' for script {:?} and locale '{}'", script_family, script, self.locale); } self.script_i.0 += 1; @@ -82,7 +113,6 @@ impl<'a> Iterator for FontFallbackIter<'a> { self.common_i += 1; for font in self.fonts.iter() { if font.info.family == common_family { - log::debug!("Trying '{}' for scripts {:?} and locale '{}'", font.info.family, self.scripts, self.locale); return Some(font); } } @@ -94,10 +124,10 @@ impl<'a> Iterator for FontFallbackIter<'a> { while self.other_i < self.fonts.len() { let font = &self.fonts[self.other_i]; self.other_i += 1; - log::info!("Trying '{}' for scripts {:?} and locale '{}'", font.info.family, self.scripts, self.locale); return Some(font); } + self.end = true; None } } diff --git a/examples/text/src/font/fallback/unix.rs b/examples/text/src/font/fallback/unix.rs index 25085b71..0d5d1e26 100644 --- a/examples/text/src/font/fallback/unix.rs +++ b/examples/text/src/font/fallback/unix.rs @@ -4,12 +4,12 @@ use unicode_script::Script; pub fn common_fallback() -> &'static [&'static str] { //TODO: abstract style (sans/serif/monospaced) &[ - "Fira Sans", "DejaVu Sans", - //"FreeSans", + "FreeSans", "Noto Sans Symbols", "Noto Sans Symbols2", "Noto Color Emoji", + //TODO: Add CJK script here for doublewides? ] } @@ -17,14 +17,16 @@ pub fn common_fallback() -> &'static [&'static str] { pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] { //TODO: abstract style (sans/serif/monospaced) match script { - Script::Adlam => &["Noto Sans Adlam"], + Script::Adlam => &["Noto Sans Adlam", "Noto Sans Adlam Unjoined"], Script::Arabic => &["Noto Sans Arabic"], + Script::Armenian => &["Noto Sans Armenian"], Script::Bengali => &["Noto Sans Bengali"], Script::Chakma => &["Noto Sans Chakma"], Script::Cherokee => &["Noto Sans Cherokee"], Script::Devanagari => &["Noto Sans Devanagari"], Script::Ethiopic => &["Noto Sans Ethiopic"], Script::Hangul => &["Noto Sans CJK KR"], + Script::Georgian => &["Noto Sans Georgian"], Script::Grantha => &["Noto Sans Grantha"], Script::Gujarati => &["Noto Sans Gujarati"], Script::Gurmukhi => &["Noto Sans Gurmukhi"], @@ -42,11 +44,13 @@ pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] // Simplified Chinese is the default _ => &["Noto Sans CJK SC"], }, + Script::Hebrew => &["Noto Sans Hebrew"], Script::Hiragana => &["Noto Sans CJK JP"], Script::Javanese => &["Noto Sans Javanese"], Script::Kannada => &["Noto Sans Kannada"], Script::Katakana => &["Noto Sans CJK JP"], Script::Khmer => &["Noto Sans Khmer"], + Script::Lao => &["Noto Sans Lao"], Script::Malayalam => &["Noto Sans Malayalam"], Script::Mongolian => &["Noto Sans Mongolian"], Script::Myanmar => &["Noto Sans Myanmar"], @@ -62,8 +66,9 @@ pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] Script::Thai => &["Noto Sans Thai"], //TODO: no sans script? Script::Tibetan => &["Noto Serif Tibetan"], + Script::Tifinagh => &["Noto Sans Tifinagh"], Script::Vai => &["Noto Sans Vai"], - Script::Yi => &["Noto Sans Yi", /*TODO: Choose a CJK font*/], + Script::Yi => &["Noto Sans Yi", "Noto Sans CJK SC"], _ => &[], } } diff --git a/examples/text/src/font/matches.rs b/examples/text/src/font/matches.rs index 3ed2e00c..85354ad7 100644 --- a/examples/text/src/font/matches.rs +++ b/examples/text/src/font/matches.rs @@ -126,21 +126,12 @@ impl<'a> FontMatches<'a> { } } - if scripts.len() > 1 { - log::info!( - " Word {:?}{}: '{}'", - scripts, - if blank { " BLANK" } else { "" }, - &line[start_word..end_word], - ); - } else { - log::trace!( - " Word {:?}{}: '{}'", - scripts, - if blank { " BLANK" } else { "" }, - &line[start_word..end_word], - ); - } + log::trace!( + " Word {:?}{}: '{}'", + scripts, + if blank { " BLANK" } else { "" }, + &line[start_word..end_word], + ); //TODO: configure default family let mut font_iter = FontFallbackIter::new(&self.fonts, Some("Fira Sans"), scripts, &self.locale); @@ -226,6 +217,9 @@ impl<'a> FontMatches<'a> { } } + // Debug missing font fallbacks + font_iter.check_missing(&line[start_word..end_word]); + /* for glyph in glyphs.iter() { log::trace!("'{}': {}, {}, {}, {}", &line[glyph.start..glyph.end], glyph.x_advance, glyph.y_advance, glyph.x_offset, glyph.y_offset); diff --git a/examples/text/src/main.rs b/examples/text/src/main.rs index b59ebbfa..3521b96d 100644 --- a/examples/text/src/main.rs +++ b/examples/text/src/main.rs @@ -262,26 +262,36 @@ fn main() { orbclient::K_PGUP if event.pressed => { scroll -= window_lines; buffer.redraw = true; - } + }, orbclient::K_PGDN if event.pressed => { scroll += window_lines; buffer.redraw = true; - } + }, orbclient::K_0 if event.pressed && ctrl_pressed => { font_size_i = font_size_default; buffer.set_font_size(font_sizes[font_size_i].0 * display_scale); - } + }, orbclient::K_MINUS if event.pressed && ctrl_pressed => { if font_size_i > 0 { font_size_i -= 1; buffer.set_font_size(font_sizes[font_size_i].0 * display_scale); } - } + }, orbclient::K_EQUALS if event.pressed && ctrl_pressed => { if font_size_i + 1 < font_sizes.len() { font_size_i += 1; buffer.set_font_size(font_sizes[font_size_i].0 * display_scale); } + }, + orbclient::K_D if event.pressed && ctrl_pressed => { + // Debug by shaping whole buffer + log::info!("Shaping rest of buffer"); + let instant = Instant::now(); + + buffer.shape_until(i32::max_value()); + + let elapsed = instant.elapsed(); + log::info!("Shaped rest of buffer in {:?}", elapsed); } _ => (), },