Fonts: the file search for an uncovered character stops at a budget between scans

This commit is contained in:
Dylan M. Taylor
2026-11-11 20:22:05 +00:00
parent dd6b00c228
commit 3c495a7b61
4 changed files with 27 additions and 0 deletions
+11
View File
@@ -192,6 +192,17 @@ mod alias_tests {
font
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn the_file_search_for_uncovered_characters_stops_at_its_budget() {
let db = FontDb::with_font_dirs(vec![]);
db.sys.lock().unwrap().file_searches = names::MAX_FILE_SEARCHES;
assert!(!db.system_fallback('\u{E000}'));
let sys = db.sys.lock().unwrap();
assert_eq!(sys.file_searches, names::MAX_FILE_SEARCHES);
assert!(!sys.misses.contains(&'\u{E000}'), "an unsearched character is not a remembered miss");
}
#[test]
fn a_collection_lists_at_most_max_faces() {
let mut font = name_font(&[(3, 0x0409, 1, "Fam"), (3, 0x0409, 2, "Regular")]);
+1
View File
@@ -456,6 +456,7 @@ impl FontDb {
let mut sys = self.sys.lock().unwrap_or_else(|e| e.into_inner());
sys.scans = sys.scans.wrapping_add(1);
sys.misses.clear();
sys.file_searches = 0;
}
self.changed();
n
+7
View File
@@ -501,6 +501,13 @@ impl FontDb {
return true;
}
}
{
let mut sys = self.sys.lock().unwrap_or_else(|e| e.into_inner());
if sys.file_searches >= super::names::MAX_FILE_SEARCHES {
return false;
}
sys.file_searches += 1;
}
let mut paths: Vec<PathBuf> = self.read_catalog().values().flat_map(|c| c.faces.iter().map(|cf| cf.path.clone())).collect();
paths.sort();
paths.dedup();
+8
View File
@@ -7,8 +7,16 @@ pub(super) struct SysFallback {
pub(super) misses: std::collections::HashSet<char>,
/// Counts the scans of the font folders: a search that a scan overtook doesn't record its miss.
pub(super) scans: u64,
/// Characters that went on to read every cataloged font file (and found nothing, or a face).
/// Each such search rereads the catalog, so only [`MAX_FILE_SEARCHES`] are made per scan.
pub(super) file_searches: u32,
}
/// The most characters searched for in the font files themselves between two scans of the font
/// folders. Real text has a few uncovered characters; a document of thousands of distinct
/// private-use code points would reread the whole catalog for each.
pub(super) const MAX_FILE_SEARCHES: u32 = 1024;
/// Fonts made for Thai, tried first (when installed) for Thai the font in use lacks: Windows
/// (Leelawadee UI; Tahoma before Windows 8), macOS (Thonburi, Sukhumvit Set) and Linux (Noto,
/// TLWG).