mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
fonts: remember bdfs with multiple sizes found in font_dirs
We were using a simple hashmap of name -> parsed file, but for something like Terminus where there are ~10 files per weight but for different pixel sizes, we'd end up forgetting files beyond the first. This commit tracks the full list in the font db. related to #1820 in the sense that I needed this to confirm that we do handle BDFs, but it is not the issue reported there because that was sourcing fonts via fontconfig on linux.
This commit is contained in:
parent
33e0858f8d
commit
11a19a589a
@ -8,7 +8,7 @@ use rangeset::RangeSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub struct FontDatabase {
|
||||
by_full_name: HashMap<String, ParsedFont>,
|
||||
by_full_name: HashMap<String, Vec<ParsedFont>>,
|
||||
}
|
||||
|
||||
impl FontDatabase {
|
||||
@ -22,7 +22,8 @@ impl FontDatabase {
|
||||
for parsed in font_info {
|
||||
self.by_full_name
|
||||
.entry(parsed.names().full_name.clone())
|
||||
.or_insert(parsed);
|
||||
.or_insert_with(|| vec![])
|
||||
.push(parsed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,10 +54,13 @@ impl FontDatabase {
|
||||
}
|
||||
|
||||
pub fn list_available(&self) -> Vec<ParsedFont> {
|
||||
self.by_full_name
|
||||
.values()
|
||||
.map(|p| p.clone())
|
||||
.collect::<Vec<_>>()
|
||||
let mut fonts = vec![];
|
||||
for parsed_list in self.by_full_name.values() {
|
||||
for parsed in parsed_list {
|
||||
fonts.push(parsed.clone());
|
||||
}
|
||||
}
|
||||
fonts
|
||||
}
|
||||
|
||||
pub fn with_built_in() -> anyhow::Result<Self> {
|
||||
@ -94,15 +98,17 @@ impl FontDatabase {
|
||||
|
||||
let mut matches = vec![];
|
||||
|
||||
for parsed in self.by_full_name.values() {
|
||||
if parsed.names().family == "Last Resort High-Efficiency" {
|
||||
continue;
|
||||
}
|
||||
let covered = parsed
|
||||
.coverage_intersection(&wanted_range)
|
||||
.with_context(|| format!("coverage_interaction for {:?}", parsed))?;
|
||||
if !covered.is_empty() {
|
||||
matches.push(parsed.clone());
|
||||
for parsed_list in self.by_full_name.values() {
|
||||
for parsed in parsed_list {
|
||||
if parsed.names().family == "Last Resort High-Efficiency" {
|
||||
continue;
|
||||
}
|
||||
let covered = parsed
|
||||
.coverage_intersection(&wanted_range)
|
||||
.with_context(|| format!("coverage_interaction for {:?}", parsed))?;
|
||||
if !covered.is_empty() {
|
||||
matches.push(parsed.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,30 +116,26 @@ impl FontDatabase {
|
||||
}
|
||||
|
||||
pub fn candidates(&self, font_attr: &FontAttributes) -> Vec<&ParsedFont> {
|
||||
self.by_full_name
|
||||
.values()
|
||||
.filter_map(|parsed| {
|
||||
let mut fonts = vec![];
|
||||
for parsed_list in self.by_full_name.values() {
|
||||
for parsed in parsed_list {
|
||||
if parsed.matches_name(font_attr) {
|
||||
Some(parsed)
|
||||
} else {
|
||||
None
|
||||
fonts.push(parsed);
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
fonts
|
||||
}
|
||||
|
||||
pub fn resolve(&self, font_attr: &FontAttributes, pixel_size: u16) -> Option<&ParsedFont> {
|
||||
let candidates: Vec<&ParsedFont> = self
|
||||
.by_full_name
|
||||
.values()
|
||||
.filter_map(|parsed| {
|
||||
let mut candidates = vec![];
|
||||
for parsed_list in self.by_full_name.values() {
|
||||
for parsed in parsed_list {
|
||||
if parsed.matches_name(font_attr) {
|
||||
Some(parsed)
|
||||
} else {
|
||||
None
|
||||
candidates.push(parsed);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(idx) = ParsedFont::best_matching_index(font_attr, &candidates, pixel_size) {
|
||||
return candidates.get(idx).map(|&p| p);
|
||||
|
Loading…
Reference in New Issue
Block a user