fix rendering when glyph can't be found and add last resort font

macos-click-through
Keith Simmons 4 years ago
parent 2160520720
commit 5c7deeb8b9

@ -4,7 +4,7 @@ use log::{trace, warn};
use lru::LruCache;
use skia_safe::{TextBlob, TextBlobBuilder};
use swash::shape::ShapeContext;
use swash::text::cluster::{CharCluster, Parser, Status, Token};
use swash::text::cluster::{Char, CharCluster, Parser, Status, Token};
use swash::text::Script;
use swash::Metrics;
use unicode_segmentation::UnicodeSegmentation;
@ -46,7 +46,7 @@ impl CachingShaper {
.unwrap_or(FontKey::Default);
self.font_loader
.get_or_load(font_key)
.get_or_load(&font_key)
.expect("Could not load font")
}
@ -128,6 +128,8 @@ impl CachingShaper {
let mut results = Vec::new();
'cluster: while parser.next(&mut cluster) {
// TODO: Don't redo this work for every cluster. Save it some how
// Create font fallback list
let mut font_fallback_keys = Vec::new();
// Add guifont fallback list
@ -145,9 +147,12 @@ impl CachingShaper {
// Add skia fallback
font_fallback_keys.push(cluster.chars()[0].ch.into());
// Add last resort
font_fallback_keys.push(FontKey::LastResort);
let mut best = None;
// Use the cluster.map function to select a viable font from the fallback list
for fallback_key in font_fallback_keys.into_iter() {
for fallback_key in font_fallback_keys.iter() {
if let Some(font_pair) = self.font_loader.get_or_load(fallback_key) {
let charmap = font_pair.swash_font.as_ref().charmap();
match cluster.map(|ch| charmap.map(ch)) {
@ -161,19 +166,9 @@ impl CachingShaper {
}
}
// If we find a font with partial coverage of the cluster, select it
if let Some(best) = best {
// Last Resort covers all of the unicode space so we will always have a fallback
results.push((cluster.to_owned(), best.clone()));
continue 'cluster;
} else {
warn!("No valid font for {:?}", cluster.chars());
// No good match. Just render with the default font.
let default_font = self
.font_loader
.get_or_load(FontKey::Default)
.expect("Could not load default font");
results.push((cluster.to_owned(), default_font));
}
}
@ -188,7 +183,7 @@ impl CachingShaper {
current_group.push(cluster);
} else {
grouped_results.push((current_group, current_font));
current_group = Vec::new();
current_group = vec![cluster];
current_font_option = Some(font);
}
} else {

@ -10,6 +10,7 @@ use super::swash_font::SwashFont;
pub struct Asset;
const DEFAULT_FONT: &str = "FiraCode-Regular.ttf";
const LAST_RESORT_FONT: &str = "LastResort-Regular.ttf";
pub struct FontPair {
pub skia_font: Font,
@ -46,9 +47,10 @@ pub struct FontLoader {
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
pub enum FontKey {
Default,
Name(String),
Character(char),
Default,
LastResort,
}
impl From<&str> for FontKey {
@ -88,12 +90,6 @@ impl FontLoader {
fn load(&mut self, font_key: FontKey) -> Option<FontPair> {
match font_key {
FontKey::Default => {
let default_font_data = Asset::get(DEFAULT_FONT).unwrap();
let data = Data::new_copy(&default_font_data);
let typeface = Typeface::from_data(data, 0).unwrap();
FontPair::new(Font::from_typeface(typeface, self.font_size))
}
FontKey::Name(name) => {
let font_style = FontStyle::normal();
let typeface = self.font_mgr.match_family_style(name, font_style)?;
@ -109,11 +105,23 @@ impl FontLoader {
)?;
FontPair::new(Font::from_typeface(typeface, self.font_size))
}
FontKey::Default => {
let default_font_data = Asset::get(DEFAULT_FONT).unwrap();
let data = Data::new_copy(&default_font_data);
let typeface = Typeface::from_data(data, 0).unwrap();
FontPair::new(Font::from_typeface(typeface, self.font_size))
}
FontKey::LastResort => {
let default_font_data = Asset::get(LAST_RESORT_FONT).unwrap();
let data = Data::new_copy(&default_font_data);
let typeface = Typeface::from_data(data, 0).unwrap();
FontPair::new(Font::from_typeface(typeface, self.font_size))
}
}
}
pub fn get_or_load(&mut self, font_key: FontKey) -> Option<Arc<FontPair>> {
if let Some(cached) = self.cache.get(&font_key) {
pub fn get_or_load(&mut self, font_key: &FontKey) -> Option<Arc<FontPair>> {
if let Some(cached) = self.cache.get(font_key) {
return Some(cached.clone());
}
@ -121,7 +129,7 @@ impl FontLoader {
let font_arc = Arc::new(loaded_font);
self.cache.put(font_key, font_arc.clone());
self.cache.put(font_key.clone(), font_arc.clone());
Some(font_arc)
}

Loading…
Cancel
Save