mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
font-config: fall back to searching by postscript name
Our first pass is to match based on the overall constraints supplied by the user, but if that fails, we fall back to looking up by postscript name.
This commit is contained in:
parent
16e7457049
commit
0694e905e8
@ -310,7 +310,6 @@ impl Pattern {
|
||||
}
|
||||
|
||||
pub fn list(&self) -> anyhow::Result<FontSet> {
|
||||
log::trace!("listing: {:?}", self);
|
||||
unsafe {
|
||||
// This defines the fields that are retrieved
|
||||
let oset = FcObjectSetCreate();
|
||||
|
@ -23,52 +23,89 @@ impl FontLocator for FontConfigFontLocator {
|
||||
) -> anyhow::Result<Vec<ParsedFont>> {
|
||||
let mut fonts = vec![];
|
||||
|
||||
for attr in fonts_selection {
|
||||
for &spacing in &SPACING {
|
||||
let mut pattern = FontPattern::new()?;
|
||||
let start = std::time::Instant::now();
|
||||
pattern.family(&attr.family)?;
|
||||
pattern.add_integer("weight", to_fc_weight(attr.weight))?;
|
||||
pattern.add_integer("width", to_fc_width(attr.width))?;
|
||||
pattern.add_integer(
|
||||
"slant",
|
||||
if attr.italic {
|
||||
fcwrap::FC_SLANT_ITALIC
|
||||
} else {
|
||||
fcwrap::FC_SLANT_ROMAN
|
||||
},
|
||||
)?;
|
||||
pattern.add_integer("spacing", spacing)?;
|
||||
fn by_family(attr: &FontAttributes, spacing: i32) -> anyhow::Result<FontPattern> {
|
||||
let mut pattern = FontPattern::new()?;
|
||||
let start = std::time::Instant::now();
|
||||
pattern.family(&attr.family)?;
|
||||
pattern.add_integer("weight", to_fc_weight(attr.weight))?;
|
||||
pattern.add_integer("width", to_fc_width(attr.width))?;
|
||||
pattern.add_integer(
|
||||
"slant",
|
||||
if attr.italic {
|
||||
fcwrap::FC_SLANT_ITALIC
|
||||
} else {
|
||||
fcwrap::FC_SLANT_ROMAN
|
||||
},
|
||||
)?;
|
||||
pattern.add_integer("spacing", spacing)?;
|
||||
|
||||
log::trace!("fc pattern before config subst: {:?}", pattern);
|
||||
pattern.config_substitute(fcwrap::MatchKind::Pattern)?;
|
||||
pattern.default_substitute();
|
||||
log::trace!("fc pattern before config subst: {:?}", pattern);
|
||||
pattern.config_substitute(fcwrap::MatchKind::Pattern)?;
|
||||
pattern.default_substitute();
|
||||
|
||||
let best = pattern.get_best_match()?;
|
||||
let best = pattern.get_best_match()?;
|
||||
log::trace!(
|
||||
"best match took {:?} to compute and is {:?}",
|
||||
start.elapsed(),
|
||||
best
|
||||
);
|
||||
Ok(best)
|
||||
}
|
||||
|
||||
fn by_postscript(attr: &FontAttributes, _spacing: i32) -> anyhow::Result<FontPattern> {
|
||||
let mut pattern = FontPattern::new()?;
|
||||
let start = std::time::Instant::now();
|
||||
pattern.add_string("postscriptname", &attr.family)?;
|
||||
let matches = pattern.list()?;
|
||||
for best in matches.iter() {
|
||||
log::trace!(
|
||||
"best match took {:?} to compute and is {:?}",
|
||||
"listing by postscriptname took {:?} to compute and is {:?}",
|
||||
start.elapsed(),
|
||||
best
|
||||
);
|
||||
return Ok(best);
|
||||
}
|
||||
|
||||
let file = best.get_file()?;
|
||||
let index = best.get_integer("index")? as u32;
|
||||
let variation = index >> 16;
|
||||
let index = index & 0xffff;
|
||||
let handle = FontDataHandle {
|
||||
source: FontDataSource::OnDisk(file.into()),
|
||||
index,
|
||||
variation,
|
||||
};
|
||||
log::trace!(
|
||||
"listing by postscriptname took {:?} to compute and produced no results",
|
||||
start.elapsed(),
|
||||
);
|
||||
anyhow::bail!("no match for postscript name");
|
||||
}
|
||||
|
||||
// fontconfig will give us a boatload of random fallbacks.
|
||||
// so we need to parse the returned font
|
||||
// here to see if we got what we asked for.
|
||||
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
||||
if parsed.matches_attributes(attr) != FontMatch::NoMatch {
|
||||
log::trace!("found font-config match for {:?}", parsed.names());
|
||||
fonts.push(parsed);
|
||||
loaded.insert(attr.clone());
|
||||
for attr in fonts_selection {
|
||||
for &spacing in &SPACING {
|
||||
if loaded.contains(&attr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// First, we assume that attr.family is the family name.
|
||||
// If that doesn't work, we try by postscript name.
|
||||
for resolver in &[by_family, by_postscript] {
|
||||
match resolver(attr, spacing) {
|
||||
Ok(best) => {
|
||||
let file = best.get_file()?;
|
||||
let index = best.get_integer("index")? as u32;
|
||||
let variation = index >> 16;
|
||||
let index = index & 0xffff;
|
||||
let handle = FontDataHandle {
|
||||
source: FontDataSource::OnDisk(file.into()),
|
||||
index,
|
||||
variation,
|
||||
};
|
||||
|
||||
// fontconfig will give us a boatload of random fallbacks.
|
||||
// so we need to parse the returned font
|
||||
// here to see if we got what we asked for.
|
||||
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
||||
if parsed.matches_attributes(attr) != FontMatch::NoMatch {
|
||||
log::trace!("found font-config match for {:?}", parsed.names());
|
||||
fonts.push(parsed);
|
||||
loaded.insert(attr.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => log::trace!("while searching for {:?}: {:#}", attr, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user