diff --git a/crates/fonts/src/fallback.rs b/crates/fonts/src/fallback.rs index 8d54453f8..ad7f64c05 100644 --- a/crates/fonts/src/fallback.rs +++ b/crates/fonts/src/fallback.rs @@ -169,7 +169,7 @@ impl FontDb { if bundled.contains(fam) { continue; } - if self.is_loaded(fam) || self.has_family(fam) { + if self.is_loaded(fam) || (self.system_fallback_enabled() && self.has_family(fam)) { let f = self.face(fam, style); if f.family.eq_ignore_ascii_case(fam) && covers_cluster(&f, cluster) { return f; diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index c1db0b356..a68b4dca9 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -976,6 +976,17 @@ impl FontDb { let _ = on; } + /// Whether automatic system-font lookups (fallback by character, symbol and script families) + /// may touch installed fonts. Lookups of a family the document or host names are not gated. + pub(crate) fn system_fallback_enabled(&self) -> bool { + #[cfg(not(target_arch = "wasm32"))] + { + self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled + } + #[cfg(target_arch = "wasm32")] + false + } + /// Process-wide database: the bundled fonts, then the installed system fonts, cataloged the /// first time a lookup by family name needs them (or ahead of time by /// [`FontDb::scan_in_background`]). @@ -1469,7 +1480,8 @@ impl FontDb { }; #[cfg(not(target_arch = "wasm32"))] { - let cataloged: Vec = self.read_catalog().iter().map(|e| e.family.clone()).collect(); + let cataloged: Vec = + if self.system_fallback_enabled() { self.read_catalog().iter().map(|e| e.family.clone()).collect() } else { Vec::new() }; for fam in SYSTEM_FALLBACKS.iter().filter(|f| f.contains("Symbol")) { if !self.is_loaded(fam) && cataloged.iter().any(|f| f.eq_ignore_ascii_case(fam)) { self.load_cataloged(fam); diff --git a/crates/fonts/src/tests.rs b/crates/fonts/src/tests.rs index 596415d51..e7a3f064d 100644 --- a/crates/fonts/src/tests.rs +++ b/crates/fonts/src/tests.rs @@ -425,3 +425,11 @@ fn the_font_scan_skips_fifos_folders_and_link_loops() { assert!(fifo || n >= 1); let _ = std::fs::remove_dir_all(&dir); } + +#[test] +fn disabling_system_fallback_gates_automatic_family_loads() { + let db = FontDb::with_font_dirs(Vec::new()); + assert!(cfg!(target_arch = "wasm32") || db.system_fallback_enabled()); + db.set_system_fallback(false); + assert!(!db.system_fallback_enabled()); +}