diff --git a/src/attrs.rs b/src/attrs.rs index 1be3c46a6a..a7886d072e 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -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 diff --git a/src/font/fallback/mod.rs b/src/font/fallback/mod.rs index 528cdf816d..9dd1d7f6ff 100644 --- a/src/font/fallback/mod.rs +++ b/src/font/fallback/mod.rs @@ -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, + font_weight_diff: Option, codepoint_non_matches: Option, + 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)); diff --git a/src/font/system.rs b/src/font/system.rs index 82f6fd8a22..be801a60b3 100644 --- a/src/font/system.rs +++ b/src/font/system.rs @@ -11,7 +11,8 @@ pub use rustybuzz; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct FontMatchKey { - pub(crate) weight_offset: Option, + 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::>();