Use weight absolute difference in monospace fallback matching
When matching on weights smaller than normal, "equal or smaller" weight restriction may cause monospace fallback to fail, depending on font support at such weights for the text to be shaped. So remove that restriction, and calculate weight differences instead of offsets. In case of no exact weight match, and with all other factors being equal, smaller weights will be picked before bigger ones. So, this should generally not cause any behavioral changes when matching on normal weight or bigger. Should fix pop-os/cosmic-term#104. Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This commit is contained in:
parent
1a18296a67
commit
0cea55630c
3 changed files with 14 additions and 12 deletions
|
|
@ -176,10 +176,7 @@ impl<'a> Attrs<'a> {
|
|||
pub fn matches(&self, face: &fontdb::FaceInfo) -> bool {
|
||||
//TODO: smarter way of including emoji
|
||||
face.post_script_name.contains("Emoji")
|
||||
|| (face.style == self.style
|
||||
// Relax exact weight matching for the Monospace fallback use-case
|
||||
&& face.weight <= self.weight
|
||||
&& face.stretch == self.stretch)
|
||||
|| (face.style == self.style && face.stretch == self.stretch)
|
||||
}
|
||||
|
||||
/// Check if this set of attributes can be shaped with another
|
||||
|
|
|
|||
|
|
@ -32,13 +32,14 @@ use log::debug as missing_warn;
|
|||
#[cfg(feature = "warn_on_missing_glyphs")]
|
||||
use log::warn as missing_warn;
|
||||
|
||||
// Match on lowest weight_offset, then script_non_matches
|
||||
// Match on lowest font_weight_diff, then script_non_matches, then font_weight
|
||||
// Default font gets None for both `weight_offset` and `script_non_matches`, and thus, it is
|
||||
// always the first to be popped from the set.
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct MonospaceFallbackInfo {
|
||||
weight_offset: Option<u16>,
|
||||
font_weight_diff: Option<u16>,
|
||||
codepoint_non_matches: Option<usize>,
|
||||
font_weight: u16,
|
||||
id: fontdb::ID,
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +145,7 @@ impl<'a> Iterator for FontFallbackIter<'a> {
|
|||
let font_match_keys_iter = |is_mono| {
|
||||
self.font_match_keys
|
||||
.iter()
|
||||
.filter(move |m_key| m_key.weight_offset == Some(0) || is_mono)
|
||||
.filter(move |m_key| m_key.font_weight_diff == 0 || is_mono)
|
||||
};
|
||||
|
||||
while self.default_i < self.default_families.len() {
|
||||
|
|
@ -160,11 +161,12 @@ impl<'a> Iterator for FontFallbackIter<'a> {
|
|||
if let Some(font) = self.font_system.get_font(m_key.id) {
|
||||
if !is_mono {
|
||||
return Some(font);
|
||||
} else if m_key.weight_offset == Some(0) {
|
||||
} else if m_key.font_weight_diff == 0 {
|
||||
// Default font
|
||||
let fallback_info = MonospaceFallbackInfo {
|
||||
weight_offset: None,
|
||||
font_weight_diff: None,
|
||||
codepoint_non_matches: None,
|
||||
font_weight: m_key.font_weight,
|
||||
id: m_key.id,
|
||||
};
|
||||
assert!(self.monospace_fallbacks.insert(fallback_info));
|
||||
|
|
@ -187,8 +189,9 @@ impl<'a> Iterator for FontFallbackIter<'a> {
|
|||
.count();
|
||||
|
||||
let fallback_info = MonospaceFallbackInfo {
|
||||
weight_offset: m_key.weight_offset,
|
||||
font_weight_diff: Some(m_key.font_weight_diff),
|
||||
codepoint_non_matches: Some(codepoint_non_matches),
|
||||
font_weight: m_key.font_weight,
|
||||
id: m_key.id,
|
||||
};
|
||||
assert!(self.monospace_fallbacks.insert(fallback_info));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ pub use rustybuzz;
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct FontMatchKey {
|
||||
pub(crate) weight_offset: Option<u16>,
|
||||
pub(crate) font_weight_diff: u16,
|
||||
pub(crate) font_weight: u16,
|
||||
pub(crate) id: fontdb::ID,
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +152,8 @@ impl FontSystem {
|
|||
.faces()
|
||||
.filter(|face| attrs.matches(face))
|
||||
.map(|face| FontMatchKey {
|
||||
weight_offset: attrs.weight.0.checked_sub(face.weight.0),
|
||||
font_weight_diff: attrs.weight.0.abs_diff(face.weight.0),
|
||||
font_weight: face.weight.0,
|
||||
id: face.id,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue