From a32048db4dc7a995201040ce896f538c62cad96b Mon Sep 17 00:00:00 2001 From: aiongg Date: Fri, 23 Oct 2026 21:31:57 +0000 Subject: [PATCH] Batch fix: fonts: read the CJK locale only for scripts with usual families (#1907) fallback_for read the locale (and the environment) on every call, including the layout hot path; it is computed lazily, only for a character of a script with usual families. --- crates/text/src/fonts.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/text/src/fonts.rs b/crates/text/src/fonts.rs index 688b0bc0..d9c54b1f 100644 --- a/crates/text/src/fonts.rs +++ b/crates/text/src/fonts.rs @@ -924,23 +924,27 @@ fn family_faces_cache() -> &'static RwLock FaceId { - fallback_with_locale(c, prefer, CjkLocale::from_tag(&active_cjk_locale())) + fallback_with_locale(c, prefer, || CjkLocale::from_tag(&active_cjk_locale())) } /// Choose a fallback for an explicit interface language, independent of concurrent global /// language changes. Empty, `c` and `posix` use the OS environment rather than the global request. pub fn fallback_for_locale(c: char, prefer: FaceId, tag: &str) -> FaceId { let tag = tag.trim(); - let locale = if tag.is_empty() || tag.eq_ignore_ascii_case("c") || tag.eq_ignore_ascii_case("posix") { - CjkLocale::from_tag(&environment_cjk_locale()) - } else { - CjkLocale::from_tag(tag) + let locale = || { + if tag.is_empty() || tag.eq_ignore_ascii_case("c") || tag.eq_ignore_ascii_case("posix") { + CjkLocale::from_tag(&environment_cjk_locale()) + } else { + CjkLocale::from_tag(tag) + } }; fallback_with_locale(c, prefer, locale) } -/// Keep a single language snapshot through the family-order lookup and cache insertion. -fn fallback_with_locale(c: char, prefer: FaceId, locale: CjkLocale) -> FaceId { +/// Keep a single language snapshot through the family-order lookup and cache insertion. `locale` +/// is read only for a script with usual families: reading it takes a lock and may consult the +/// environment, and layout asks for a fallback for every character. +fn fallback_with_locale(c: char, prefer: FaceId, locale: impl FnOnce() -> CjkLocale) -> FaceId { let p = face(prefer); if p.has_char(c) || c.is_control() { return prefer; @@ -961,7 +965,7 @@ fn fallback_with_locale(c: char, prefer: FaceId, locale: CjkLocale) -> FaceId { if cfg!(not(target_arch = "wasm32")) && !system_scanned() { scan_system(); } - if let Some(&id) = family_faces(script, &p, locale).iter().find(|&&id| face(id).has_char(c)) { + if let Some(&id) = family_faces(script, &p, locale()).iter().find(|&&id| face(id).has_char(c)) { return id; } }