Add more script specific fallbacks
This commit is contained in:
parent
f91cb3ce0f
commit
fec418b3b1
4 changed files with 65 additions and 26 deletions
|
|
@ -30,6 +30,7 @@ pub struct FontFallbackIter<'a> {
|
||||||
script_i: (usize, usize),
|
script_i: (usize, usize),
|
||||||
common_i: usize,
|
common_i: usize,
|
||||||
other_i: usize,
|
other_i: usize,
|
||||||
|
end: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FontFallbackIter<'a> {
|
impl<'a> FontFallbackIter<'a> {
|
||||||
|
|
@ -42,6 +43,36 @@ impl<'a> FontFallbackIter<'a> {
|
||||||
script_i: (0, 0),
|
script_i: (0, 0),
|
||||||
common_i: 0,
|
common_i: 0,
|
||||||
other_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);
|
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;
|
self.script_i.0 += 1;
|
||||||
|
|
@ -82,7 +113,6 @@ impl<'a> Iterator for FontFallbackIter<'a> {
|
||||||
self.common_i += 1;
|
self.common_i += 1;
|
||||||
for font in self.fonts.iter() {
|
for font in self.fonts.iter() {
|
||||||
if font.info.family == common_family {
|
if font.info.family == common_family {
|
||||||
log::debug!("Trying '{}' for scripts {:?} and locale '{}'", font.info.family, self.scripts, self.locale);
|
|
||||||
return Some(font);
|
return Some(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,10 +124,10 @@ impl<'a> Iterator for FontFallbackIter<'a> {
|
||||||
while self.other_i < self.fonts.len() {
|
while self.other_i < self.fonts.len() {
|
||||||
let font = &self.fonts[self.other_i];
|
let font = &self.fonts[self.other_i];
|
||||||
self.other_i += 1;
|
self.other_i += 1;
|
||||||
log::info!("Trying '{}' for scripts {:?} and locale '{}'", font.info.family, self.scripts, self.locale);
|
|
||||||
return Some(font);
|
return Some(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.end = true;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ use unicode_script::Script;
|
||||||
pub fn common_fallback() -> &'static [&'static str] {
|
pub fn common_fallback() -> &'static [&'static str] {
|
||||||
//TODO: abstract style (sans/serif/monospaced)
|
//TODO: abstract style (sans/serif/monospaced)
|
||||||
&[
|
&[
|
||||||
"Fira Sans",
|
|
||||||
"DejaVu Sans",
|
"DejaVu Sans",
|
||||||
//"FreeSans",
|
"FreeSans",
|
||||||
"Noto Sans Symbols",
|
"Noto Sans Symbols",
|
||||||
"Noto Sans Symbols2",
|
"Noto Sans Symbols2",
|
||||||
"Noto Color Emoji",
|
"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] {
|
pub fn script_fallback(script: &Script, locale: &str) -> &'static [&'static str] {
|
||||||
//TODO: abstract style (sans/serif/monospaced)
|
//TODO: abstract style (sans/serif/monospaced)
|
||||||
match script {
|
match script {
|
||||||
Script::Adlam => &["Noto Sans Adlam"],
|
Script::Adlam => &["Noto Sans Adlam", "Noto Sans Adlam Unjoined"],
|
||||||
Script::Arabic => &["Noto Sans Arabic"],
|
Script::Arabic => &["Noto Sans Arabic"],
|
||||||
|
Script::Armenian => &["Noto Sans Armenian"],
|
||||||
Script::Bengali => &["Noto Sans Bengali"],
|
Script::Bengali => &["Noto Sans Bengali"],
|
||||||
Script::Chakma => &["Noto Sans Chakma"],
|
Script::Chakma => &["Noto Sans Chakma"],
|
||||||
Script::Cherokee => &["Noto Sans Cherokee"],
|
Script::Cherokee => &["Noto Sans Cherokee"],
|
||||||
Script::Devanagari => &["Noto Sans Devanagari"],
|
Script::Devanagari => &["Noto Sans Devanagari"],
|
||||||
Script::Ethiopic => &["Noto Sans Ethiopic"],
|
Script::Ethiopic => &["Noto Sans Ethiopic"],
|
||||||
Script::Hangul => &["Noto Sans CJK KR"],
|
Script::Hangul => &["Noto Sans CJK KR"],
|
||||||
|
Script::Georgian => &["Noto Sans Georgian"],
|
||||||
Script::Grantha => &["Noto Sans Grantha"],
|
Script::Grantha => &["Noto Sans Grantha"],
|
||||||
Script::Gujarati => &["Noto Sans Gujarati"],
|
Script::Gujarati => &["Noto Sans Gujarati"],
|
||||||
Script::Gurmukhi => &["Noto Sans Gurmukhi"],
|
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
|
// Simplified Chinese is the default
|
||||||
_ => &["Noto Sans CJK SC"],
|
_ => &["Noto Sans CJK SC"],
|
||||||
},
|
},
|
||||||
|
Script::Hebrew => &["Noto Sans Hebrew"],
|
||||||
Script::Hiragana => &["Noto Sans CJK JP"],
|
Script::Hiragana => &["Noto Sans CJK JP"],
|
||||||
Script::Javanese => &["Noto Sans Javanese"],
|
Script::Javanese => &["Noto Sans Javanese"],
|
||||||
Script::Kannada => &["Noto Sans Kannada"],
|
Script::Kannada => &["Noto Sans Kannada"],
|
||||||
Script::Katakana => &["Noto Sans CJK JP"],
|
Script::Katakana => &["Noto Sans CJK JP"],
|
||||||
Script::Khmer => &["Noto Sans Khmer"],
|
Script::Khmer => &["Noto Sans Khmer"],
|
||||||
|
Script::Lao => &["Noto Sans Lao"],
|
||||||
Script::Malayalam => &["Noto Sans Malayalam"],
|
Script::Malayalam => &["Noto Sans Malayalam"],
|
||||||
Script::Mongolian => &["Noto Sans Mongolian"],
|
Script::Mongolian => &["Noto Sans Mongolian"],
|
||||||
Script::Myanmar => &["Noto Sans Myanmar"],
|
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"],
|
Script::Thai => &["Noto Sans Thai"],
|
||||||
//TODO: no sans script?
|
//TODO: no sans script?
|
||||||
Script::Tibetan => &["Noto Serif Tibetan"],
|
Script::Tibetan => &["Noto Serif Tibetan"],
|
||||||
|
Script::Tifinagh => &["Noto Sans Tifinagh"],
|
||||||
Script::Vai => &["Noto Sans Vai"],
|
Script::Vai => &["Noto Sans Vai"],
|
||||||
Script::Yi => &["Noto Sans Yi", /*TODO: Choose a CJK font*/],
|
Script::Yi => &["Noto Sans Yi", "Noto Sans CJK SC"],
|
||||||
_ => &[],
|
_ => &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,21 +126,12 @@ impl<'a> FontMatches<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scripts.len() > 1 {
|
log::trace!(
|
||||||
log::info!(
|
" Word {:?}{}: '{}'",
|
||||||
" Word {:?}{}: '{}'",
|
scripts,
|
||||||
scripts,
|
if blank { " BLANK" } else { "" },
|
||||||
if blank { " BLANK" } else { "" },
|
&line[start_word..end_word],
|
||||||
&line[start_word..end_word],
|
);
|
||||||
);
|
|
||||||
} else {
|
|
||||||
log::trace!(
|
|
||||||
" Word {:?}{}: '{}'",
|
|
||||||
scripts,
|
|
||||||
if blank { " BLANK" } else { "" },
|
|
||||||
&line[start_word..end_word],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: configure default family
|
//TODO: configure default family
|
||||||
let mut font_iter = FontFallbackIter::new(&self.fonts, Some("Fira Sans"), scripts, &self.locale);
|
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() {
|
for glyph in glyphs.iter() {
|
||||||
log::trace!("'{}': {}, {}, {}, {}", &line[glyph.start..glyph.end], glyph.x_advance, glyph.y_advance, glyph.x_offset, glyph.y_offset);
|
log::trace!("'{}': {}, {}, {}, {}", &line[glyph.start..glyph.end], glyph.x_advance, glyph.y_advance, glyph.x_offset, glyph.y_offset);
|
||||||
|
|
|
||||||
|
|
@ -262,26 +262,36 @@ fn main() {
|
||||||
orbclient::K_PGUP if event.pressed => {
|
orbclient::K_PGUP if event.pressed => {
|
||||||
scroll -= window_lines;
|
scroll -= window_lines;
|
||||||
buffer.redraw = true;
|
buffer.redraw = true;
|
||||||
}
|
},
|
||||||
orbclient::K_PGDN if event.pressed => {
|
orbclient::K_PGDN if event.pressed => {
|
||||||
scroll += window_lines;
|
scroll += window_lines;
|
||||||
buffer.redraw = true;
|
buffer.redraw = true;
|
||||||
}
|
},
|
||||||
orbclient::K_0 if event.pressed && ctrl_pressed => {
|
orbclient::K_0 if event.pressed && ctrl_pressed => {
|
||||||
font_size_i = font_size_default;
|
font_size_i = font_size_default;
|
||||||
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
||||||
}
|
},
|
||||||
orbclient::K_MINUS if event.pressed && ctrl_pressed => {
|
orbclient::K_MINUS if event.pressed && ctrl_pressed => {
|
||||||
if font_size_i > 0 {
|
if font_size_i > 0 {
|
||||||
font_size_i -= 1;
|
font_size_i -= 1;
|
||||||
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
orbclient::K_EQUALS if event.pressed && ctrl_pressed => {
|
orbclient::K_EQUALS if event.pressed && ctrl_pressed => {
|
||||||
if font_size_i + 1 < font_sizes.len() {
|
if font_size_i + 1 < font_sizes.len() {
|
||||||
font_size_i += 1;
|
font_size_i += 1;
|
||||||
buffer.set_font_size(font_sizes[font_size_i].0 * display_scale);
|
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);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue