mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
fonts: defer best match until we have font_dirs + locator + builtin
A user reported an issue where having just Roboto Thin installed caused the title font to use that one, rather than the desired Roboto Bold. This commit adjusts the font matching code to accumulate candidates from each of the font_dirs, locator and built-in font locations, and then find the best match.
This commit is contained in:
parent
e148cfe8e3
commit
58ece29f00
@ -75,9 +75,6 @@ impl FontDatabase {
|
|||||||
pixel_size: u16,
|
pixel_size: u16,
|
||||||
) {
|
) {
|
||||||
for attr in fonts {
|
for attr in fonts {
|
||||||
if loaded.contains(attr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(handle) = self.resolve(attr, pixel_size) {
|
if let Some(handle) = self.resolve(attr, pixel_size) {
|
||||||
handles.push(handle.clone().synthesize(attr));
|
handles.push(handle.clone().synthesize(attr));
|
||||||
loaded.insert(attr.clone());
|
loaded.insert(attr.clone());
|
||||||
@ -112,6 +109,19 @@ impl FontDatabase {
|
|||||||
Ok(matches)
|
Ok(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn candidates(&self, font_attr: &FontAttributes) -> Vec<&ParsedFont> {
|
||||||
|
self.by_full_name
|
||||||
|
.values()
|
||||||
|
.filter_map(|parsed| {
|
||||||
|
if parsed.matches_name(font_attr) {
|
||||||
|
Some(parsed)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resolve(&self, font_attr: &FontAttributes, pixel_size: u16) -> Option<&ParsedFont> {
|
pub fn resolve(&self, font_attr: &FontAttributes, pixel_size: u16) -> Option<&ParsedFont> {
|
||||||
let candidates: Vec<&ParsedFont> = self
|
let candidates: Vec<&ParsedFont> = self
|
||||||
.by_full_name
|
.by_full_name
|
||||||
|
@ -531,8 +531,6 @@ impl FontConfigInner {
|
|||||||
|
|
||||||
let (sys_font, sys_size) = self.compute_title_font(&config);
|
let (sys_font, sys_size) = self.compute_title_font(&config);
|
||||||
|
|
||||||
let mut handles = vec![];
|
|
||||||
|
|
||||||
let font_size = config.window_frame.font_size.unwrap_or(sys_size);
|
let font_size = config.window_frame.font_size.unwrap_or(sys_size);
|
||||||
|
|
||||||
let text_style = config
|
let text_style = config
|
||||||
@ -545,27 +543,7 @@ impl FontConfigInner {
|
|||||||
let pixel_size = (font_size * dpi as f64 / 72.0) as u16;
|
let pixel_size = (font_size * dpi as f64 / 72.0) as u16;
|
||||||
|
|
||||||
let attributes = text_style.font_with_fallback();
|
let attributes = text_style.font_with_fallback();
|
||||||
let preferred_attributes = attributes
|
let (handles, _loaded) = self.resolve_font_helper_impl(&attributes, pixel_size)?;
|
||||||
.iter()
|
|
||||||
.filter(|a| !a.is_fallback)
|
|
||||||
.map(|a| a.clone())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let fallback_attributes = attributes
|
|
||||||
.iter()
|
|
||||||
.filter(|a| a.is_fallback)
|
|
||||||
.map(|a| a.clone())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let mut loaded = HashSet::new();
|
|
||||||
|
|
||||||
for attrs in &[&preferred_attributes, &fallback_attributes] {
|
|
||||||
self.font_dirs
|
|
||||||
.borrow()
|
|
||||||
.resolve_multiple(attrs, &mut handles, &mut loaded, pixel_size);
|
|
||||||
handles.append(&mut self.locator.load_fonts(attrs, &mut loaded, pixel_size)?);
|
|
||||||
self.built_in
|
|
||||||
.borrow()
|
|
||||||
.resolve_multiple(attrs, &mut handles, &mut loaded, pixel_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
let shaper = new_shaper(&*config, &handles)?;
|
let shaper = new_shaper(&*config, &handles)?;
|
||||||
|
|
||||||
@ -594,13 +572,11 @@ impl FontConfigInner {
|
|||||||
Ok(loaded)
|
Ok(loaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_font_helper(
|
fn resolve_font_helper_impl(
|
||||||
&self,
|
&self,
|
||||||
style: &TextStyle,
|
attributes: &[FontAttributes],
|
||||||
config: &ConfigHandle,
|
|
||||||
pixel_size: u16,
|
pixel_size: u16,
|
||||||
) -> anyhow::Result<(Box<dyn FontShaper>, Vec<ParsedFont>)> {
|
) -> anyhow::Result<(Vec<ParsedFont>, HashSet<FontAttributes>)> {
|
||||||
let attributes = style.font_with_fallback();
|
|
||||||
let preferred_attributes = attributes
|
let preferred_attributes = attributes
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| !a.is_fallback)
|
.filter(|a| !a.is_fallback)
|
||||||
@ -612,18 +588,61 @@ impl FontConfigInner {
|
|||||||
.map(|a| a.clone())
|
.map(|a| a.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let mut loaded = HashSet::new();
|
let mut loaded = HashSet::new();
|
||||||
|
|
||||||
let mut handles = vec![];
|
let mut handles = vec![];
|
||||||
for attrs in &[&preferred_attributes, &fallback_attributes] {
|
|
||||||
self.font_dirs
|
for &attrs in &[&preferred_attributes, &fallback_attributes] {
|
||||||
.borrow()
|
let mut candidates = vec![];
|
||||||
.resolve_multiple(attrs, &mut handles, &mut loaded, pixel_size);
|
|
||||||
handles.append(&mut self.locator.load_fonts(attrs, &mut loaded, pixel_size)?);
|
let font_dirs = self.font_dirs.borrow();
|
||||||
self.built_in
|
for attr in attrs {
|
||||||
.borrow()
|
candidates.append(&mut font_dirs.candidates(attr));
|
||||||
.resolve_multiple(attrs, &mut handles, &mut loaded, pixel_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut loaded_ignored = HashSet::new();
|
||||||
|
let located = self
|
||||||
|
.locator
|
||||||
|
.load_fonts(attrs, &mut loaded_ignored, pixel_size)?;
|
||||||
|
for font in &located {
|
||||||
|
candidates.push(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
let built_in = self.built_in.borrow();
|
||||||
|
for attr in attrs {
|
||||||
|
candidates.append(&mut built_in.candidates(attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
for attr in attrs {
|
||||||
|
if loaded.contains(attr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let named_candidates: Vec<&ParsedFont> = candidates
|
||||||
|
.iter()
|
||||||
|
.filter_map(|&p| if p.matches_name(attr) { Some(p) } else { None })
|
||||||
|
.collect();
|
||||||
|
if let Some(idx) =
|
||||||
|
ParsedFont::best_matching_index(attr, &named_candidates, pixel_size)
|
||||||
|
{
|
||||||
|
named_candidates.get(idx).map(|&p| {
|
||||||
|
loaded.insert(attr.clone());
|
||||||
|
handles.push(p.clone().synthesize(attr))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((handles, loaded))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_font_helper(
|
||||||
|
&self,
|
||||||
|
style: &TextStyle,
|
||||||
|
config: &ConfigHandle,
|
||||||
|
pixel_size: u16,
|
||||||
|
) -> anyhow::Result<(Box<dyn FontShaper>, Vec<ParsedFont>)> {
|
||||||
|
let attributes = style.font_with_fallback();
|
||||||
|
|
||||||
|
let (handles, loaded) = self.resolve_font_helper_impl(&attributes, pixel_size)?;
|
||||||
|
|
||||||
for attr in &attributes {
|
for attr in &attributes {
|
||||||
if !attr.is_synthetic && !attr.is_fallback && !loaded.contains(attr) {
|
if !attr.is_synthetic && !attr.is_fallback && !loaded.contains(attr) {
|
||||||
let styled_extra = if attr.weight != FontWeight::default()
|
let styled_extra = if attr.weight != FontWeight::default()
|
||||||
|
Loading…
Reference in New Issue
Block a user