Store a sorted list of monospace font ids in font system

Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This commit is contained in:
Mohammad AlSaleh 2024-03-10 21:55:24 +03:00 committed by Jeremy Soller
parent 3e02ae1ea6
commit 59ac0b824c
2 changed files with 31 additions and 17 deletions

View file

@ -173,24 +173,21 @@ impl<'a> Iterator for FontFallbackIter<'a> {
}
// Set a monospace fallback if Monospace family is not found
if is_mono {
if let Some(face_info) = self.font_system.db().face(m_key.id) {
// Don't use emoji fonts as Monospace
if face_info.monospaced && !face_info.post_script_name.contains("Emoji") {
let supported_cp_count_opt = self
.font_system
.get_font_supported_codepoints_in_word(m_key.id, self.word);
if let Some(supported_cp_count) = supported_cp_count_opt {
let codepoint_non_matches =
self.word.chars().count() - supported_cp_count;
if self.font_system.is_monospace(m_key.id) {
let supported_cp_count_opt = self
.font_system
.get_font_supported_codepoints_in_word(m_key.id, self.word);
if let Some(supported_cp_count) = supported_cp_count_opt {
let codepoint_non_matches =
self.word.chars().count() - supported_cp_count;
let fallback_info = MonospaceFallbackInfo {
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));
}
let fallback_info = MonospaceFallbackInfo {
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));
}
}
}

View file

@ -86,6 +86,9 @@ pub struct FontSystem {
/// Cache for loaded fonts from the database.
font_cache: HashMap<fontdb::ID, Option<Arc<Font>>>,
/// Sorted unique ID's of all Monospace fonts in DB
monospace_font_ids: Vec<fontdb::ID>,
/// Cache for font codepoint support info
font_codepoint_support_info_cache: HashMap<fontdb::ID, FontCachedCodepointSupportInfo>,
@ -141,9 +144,19 @@ impl FontSystem {
/// Create a new [`FontSystem`] with a pre-specified locale and font database.
pub fn new_with_locale_and_db(locale: String, db: fontdb::Database) -> Self {
let mut monospace_font_ids = db
.faces()
.filter(|face_info| {
face_info.monospaced && !face_info.post_script_name.contains("Emoji")
})
.map(|face_info| face_info.id)
.collect::<Vec<_>>();
monospace_font_ids.sort();
Self {
locale,
db,
monospace_font_ids,
font_cache: Default::default(),
font_matches_cache: Default::default(),
font_codepoint_support_info_cache: Default::default(),
@ -202,6 +215,10 @@ impl FontSystem {
.clone()
}
pub fn is_monospace(&self, id: fontdb::ID) -> bool {
self.monospace_font_ids.binary_search(&id).is_ok()
}
#[inline(always)]
pub fn get_font_supported_codepoints_in_word(
&mut self,