1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 22:42:48 +03:00

fonts: improve categorization, selection of pcf fonts

Match out bold, semicondensed etc. from the full name.

Allow matching a font based on the full path to the font as
an alternative, because pcf fonts tend to have terrible
metadata and many pixel variants.

refs: https://github.com/wez/wezterm/issues/4256
This commit is contained in:
Wez Furlong 2023-09-11 07:37:41 -07:00
parent b902034eac
commit 70931f58f1
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
3 changed files with 80 additions and 0 deletions

View File

@ -20,6 +20,12 @@ impl FontDatabase {
fn load_font_info(&mut self, font_info: Vec<ParsedFont>) { fn load_font_info(&mut self, font_info: Vec<ParsedFont>) {
for parsed in font_info { for parsed in font_info {
if let Some(path) = parsed.handle.path_str() {
self.by_full_name
.entry(path.to_string())
.or_insert_with(Vec::new)
.push(parsed.clone());
}
self.by_full_name self.by_full_name
.entry(parsed.names().full_name.clone()) .entry(parsed.names().full_name.clone())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)

View File

@ -53,6 +53,14 @@ impl FontDataSource {
} }
} }
pub fn path_str(&self) -> Option<Cow<str>> {
match self {
Self::OnDisk(path) => Some(path.to_string_lossy()),
Self::BuiltIn { .. } => None,
Self::Memory { .. } => None,
}
}
pub fn load_data<'a>(&'a self) -> anyhow::Result<Cow<'a, [u8]>> { pub fn load_data<'a>(&'a self) -> anyhow::Result<Cow<'a, [u8]>> {
match self { match self {
Self::OnDisk(path) => { Self::OnDisk(path) => {
@ -161,6 +169,10 @@ impl FontDataHandle {
self.source.name_or_path_str() self.source.name_or_path_str()
} }
pub fn path_str(&self) -> Option<Cow<str>> {
self.source.path_str()
}
pub fn index(&self) -> u32 { pub fn index(&self) -> u32 {
self.index self.index
} }

View File

@ -453,6 +453,63 @@ impl ParsedFont {
FontStyle::Oblique => FontStyle::Oblique, FontStyle::Oblique => FontStyle::Oblique,
}; };
let weight = match weight {
FontWeight::REGULAR => {
let lower = names.full_name.to_lowercase();
let mut weight = weight;
for (label, candidate) in &[
("extrablack", FontWeight::EXTRABLACK),
// must match after other black variants
("black", FontWeight::BLACK),
("extrabold", FontWeight::EXTRABOLD),
("demibold", FontWeight::DEMIBOLD),
// must match after other bold variants
("bold", FontWeight::BOLD),
("medium", FontWeight::MEDIUM),
("book", FontWeight::BOOK),
("demilight", FontWeight::DEMILIGHT),
("extralight", FontWeight::EXTRALIGHT),
// must match after other light variants
("light", FontWeight::LIGHT),
("thin", FontWeight::THIN),
] {
if lower.contains(label) {
weight = *candidate;
break;
}
}
weight
}
weight => weight,
};
let stretch = match stretch {
FontStretch::Normal => {
let lower = names.full_name.to_lowercase();
let mut stretch = stretch;
for (label, value) in &[
("ultracondensed", FontStretch::UltraCondensed),
("extracondensed", FontStretch::ExtraCondensed),
("semicondensed", FontStretch::SemiCondensed),
// must match after other condensed variants
("condensed", FontStretch::Condensed),
("semiexpanded", FontStretch::SemiExpanded),
("extraexpanded", FontStretch::ExtraExpanded),
("ultraexpanded", FontStretch::UltraExpanded),
// must match after other expanded variants
("expanded", FontStretch::Expanded),
] {
if lower.contains(label) {
stretch = *value;
break;
}
}
stretch
}
stretch => stretch,
};
Ok(Self { Ok(Self {
names, names,
weight, weight,
@ -518,6 +575,11 @@ impl ParsedFont {
if attr.family == self.names.family { if attr.family == self.names.family {
return true; return true;
} }
if let Some(path) = self.handle.path_str() {
if attr.family == path {
return true;
}
}
self.matches_full_or_ps_name(attr) || self.matches_alias(attr) self.matches_full_or_ps_name(attr) || self.matches_alias(attr)
} }