1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-20 03:09:06 +03:00

fonts: avoid querying macos fallback list multiple times

This commit is contained in:
Wez Furlong 2021-03-22 10:56:45 -07:00
parent ad4b3b4648
commit 1b7c980646
2 changed files with 48 additions and 33 deletions

View File

@ -121,14 +121,14 @@ impl LoadedFont {
}
if extra_handles.is_empty() {
log::error!("No fonts have glyphs for {}", fallback_str.escape_debug());
log::warn!("No fonts have glyphs for {}", fallback_str.escape_debug());
} else {
let loaded = self.insert_fallback_handles(extra_handles)?;
if loaded {
log::trace!("handles is now: {:#?}", self.handles);
return self.shape(text);
} else {
log::error!("No fonts have glyphs for {}", fallback_str.escape_debug())
log::warn!("No fonts have glyphs for {}", fallback_str.escape_debug())
}
}
}

View File

@ -13,6 +13,10 @@ use std::borrow::Cow;
use std::collections::HashSet;
use ttf_parser::fonts_in_collection;
lazy_static::lazy_static! {
static ref FALLBACK: Vec<FontDataHandle> = build_fallback_list();
}
/// A FontLocator implemented using the system font loading
/// functions provided by core text.
pub struct CoreTextFontLocator {}
@ -112,36 +116,47 @@ impl FontLocator for CoreTextFontLocator {
) -> anyhow::Result<Vec<FontDataHandle>> {
// We don't have an API to resolve a font for the codepoints, so instead we
// just get the system fallback list and add the whole thing to the fallback.
let font =
new_from_name("Menlo", 0.0).map_err(|_| anyhow::anyhow!("failed to get Menlo font"))?;
let lang = "en"
.parse::<CFString>()
.map_err(|_| anyhow::anyhow!("failed to parse lang name en as CFString"))?;
let langs = CFArray::from_CFTypes(&[lang]);
let cascade = cascade_list_for_languages(&font, &langs);
let mut fonts = vec![];
for descriptor in &cascade {
if let Some(handle) = handle_from_descriptor(&descriptor) {
fonts.push(handle);
}
}
// Some of the fallback fonts are special fonts that don't exist on
// disk, and that we can't open.
// In particular, `.AppleSymbolsFB` is one such font. Let's try
// a nearby approximation.
let symbols = FontAttributes {
family: "Apple Symbols".to_string(),
bold: false,
italic: false,
is_fallback: true,
};
if let Ok(descriptor) = descriptor_from_attr(&symbols) {
if let Some(handle) = handle_from_descriptor(&descriptor) {
fonts.push(handle);
}
}
Ok(fonts)
Ok(FALLBACK.clone())
}
}
fn build_fallback_list() -> Vec<FontDataHandle> {
build_fallback_list_impl().unwrap_or_else(|err| {
log::error!("Error getting system fallback fonts: {:#}", err);
Vec::new()
})
}
fn build_fallback_list_impl() -> anyhow::Result<Vec<FontDataHandle>> {
let font =
new_from_name("Menlo", 0.0).map_err(|_| anyhow::anyhow!("failed to get Menlo font"))?;
let lang = "en"
.parse::<CFString>()
.map_err(|_| anyhow::anyhow!("failed to parse lang name en as CFString"))?;
let langs = CFArray::from_CFTypes(&[lang]);
let cascade = cascade_list_for_languages(&font, &langs);
let mut fonts = vec![];
for descriptor in &cascade {
if let Some(handle) = handle_from_descriptor(&descriptor) {
fonts.push(handle);
}
}
// Some of the fallback fonts are special fonts that don't exist on
// disk, and that we can't open.
// In particular, `.AppleSymbolsFB` is one such font. Let's try
// a nearby approximation.
let symbols = FontAttributes {
family: "Apple Symbols".to_string(),
bold: false,
italic: false,
is_fallback: true,
};
if let Ok(descriptor) = descriptor_from_attr(&symbols) {
if let Some(handle) = handle_from_descriptor(&descriptor) {
fonts.push(handle);
}
}
Ok(fonts)
}