mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 22:01:47 +03:00
font-config: failed to resolve clusters like 3065,2686
Root cause is that font-config will try to find a single font that satisfies a query like `fc-list ':charset=2686 3065'`, but if that is impossible, there are no results. The resolution is to split the query up and look for each individual codepoint. refs: #4310
This commit is contained in:
parent
f1be33939b
commit
50cc44a53a
@ -96,6 +96,10 @@ As features stabilize some brief notes about them will accumulate here.
|
|||||||
* Using `CloseCurrentPane` could sometimes leave a stranded pane in a tab. #4030
|
* Using `CloseCurrentPane` could sometimes leave a stranded pane in a tab. #4030
|
||||||
* Wayland: wezterm wouldn't start on Plasma 6 or newer versions of sway. Thanks
|
* Wayland: wezterm wouldn't start on Plasma 6 or newer versions of sway. Thanks
|
||||||
to @hexchain! #3996 #4322.
|
to @hexchain! #3996 #4322.
|
||||||
|
* font-config: when resolving a fallback font for a text cluster like `U+3065,U+2686`
|
||||||
|
where no single font contains both glyphs, wezterm would fail to show a glyph
|
||||||
|
for either codepoint. We now split the fallback query up and query for each
|
||||||
|
individual codepoint separately. #4310
|
||||||
|
|
||||||
#### Updated
|
#### Updated
|
||||||
* Bundled harfbuzz to 8.2.1
|
* Bundled harfbuzz to 8.2.1
|
||||||
|
@ -165,12 +165,42 @@ impl FontLocator for FontConfigFontLocator {
|
|||||||
codepoints: &[char],
|
codepoints: &[char],
|
||||||
) -> anyhow::Result<Vec<ParsedFont>> {
|
) -> anyhow::Result<Vec<ParsedFont>> {
|
||||||
log::trace!("locate_fallback_for_codepoints: {:?}", codepoints);
|
log::trace!("locate_fallback_for_codepoints: {:?}", codepoints);
|
||||||
let mut charset = CharSet::new()?;
|
let mut fonts: Vec<ParsedFont> = vec![];
|
||||||
for &c in codepoints {
|
|
||||||
charset.add(c)?;
|
// In <https://github.com/wez/wezterm/issues/4310> we discover
|
||||||
|
// that a font-config query for a charset containing both
|
||||||
|
// 3065 and 2686 fails because no fonts contain both codepoints,
|
||||||
|
// but querying separately does find the separate fonts.
|
||||||
|
// We therefore need to break up our query so that we resolve
|
||||||
|
// each codepoint individually.
|
||||||
|
// However, if we need to resolve a block of characters that
|
||||||
|
// are found in the same font (eg: someone is printing an
|
||||||
|
// entire unicode block) we don't want to issue N queries
|
||||||
|
// that return the same font.
|
||||||
|
//
|
||||||
|
// So we check the fonts that have been resolved in earlier
|
||||||
|
// iterations to see if any of those cover a given codepoint
|
||||||
|
// and allow that to satisfy the query if they do.
|
||||||
|
|
||||||
|
'next_codepoint: for &c in codepoints {
|
||||||
|
if !fonts.is_empty() {
|
||||||
|
let mut wanted_range = rangeset::RangeSet::new();
|
||||||
|
wanted_range.add(c as u32);
|
||||||
|
for f in &fonts {
|
||||||
|
match f.coverage_intersection(&wanted_range) {
|
||||||
|
Ok(r) if !r.is_empty() => {
|
||||||
|
// already found a font with this one!
|
||||||
|
continue 'next_codepoint;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fonts = vec![];
|
let mut pushed_this_pass = 0;
|
||||||
|
|
||||||
|
let mut charset = CharSet::new()?;
|
||||||
|
charset.add(c)?;
|
||||||
|
|
||||||
// Make two passes to locate a fallback: first try to find any
|
// Make two passes to locate a fallback: first try to find any
|
||||||
// strictly monospace version, then, if we didn't find any matches,
|
// strictly monospace version, then, if we didn't find any matches,
|
||||||
@ -190,9 +220,9 @@ impl FontLocator for FontConfigFontLocator {
|
|||||||
pattern.delete_property("spacing")?;
|
pattern.delete_property("spacing")?;
|
||||||
pattern.add_integer("spacing", spacing)?;
|
pattern.add_integer("spacing", spacing)?;
|
||||||
lists.push(
|
lists.push(
|
||||||
pattern
|
pattern.list().with_context(|| {
|
||||||
.list()
|
format!("pattern.list with spacing={}", spacing)
|
||||||
.with_context(|| format!("pattern.list with spacing={}", spacing))?,
|
})?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,12 +249,13 @@ impl FontLocator for FontConfigFontLocator {
|
|||||||
};
|
};
|
||||||
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
||||||
fonts.push(parsed);
|
fonts.push(parsed);
|
||||||
|
pushed_this_pass += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fonts.is_empty() {
|
if pushed_this_pass == 0 {
|
||||||
// If we get here on the first iteration, then we didn't
|
// If we get here on the first iteration, then we didn't
|
||||||
// find a monospace version of fonts with those codepoints,
|
// find a monospace version of fonts with those codepoints,
|
||||||
// let's continue and try any matching font
|
// let's continue and try any matching font
|
||||||
@ -233,6 +264,7 @@ impl FontLocator for FontConfigFontLocator {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(fonts)
|
Ok(fonts)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user