diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index a37bead6..b12251ce 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -339,8 +339,9 @@ const SCRIPT_PROBES: &[(char, &str)] = &[ /// Japanese-locale machine would be drawn with the Japanese face. The interface language is the /// better signal, so the probe for its script comes first — kana for Japanese, a Han character for /// the Chinese catalogs. Both scripts are registered, so file, layer and template names in the -/// other one still render; then [`SCRIPT_PROBES`]. The web build has no system fonts and installs -/// nothing. +/// other one still render. Hangul comes next, since the Japanese and Chinese faces may lack it +/// (Hiragino Sans on macOS has none); then [`SCRIPT_PROBES`]. The web build has no system fonts +/// and installs nothing. fn install_script_fallbacks(family_fonts: &mut FontDefinitions, language: &str) -> Vec { #[cfg(target_arch = "wasm32")] { @@ -354,10 +355,13 @@ fn install_script_fallbacks(family_fonts: &mut FontDefinitions, language: &str) // language's face draws them. const KANA: (char, &str) = ('あ', "japanese-system"); const HAN: (char, &str) = ('文', "chinese-system"); + // Hangul is probed after kana and Han so their order is unchanged; a face that already covers it + // is skipped as seen. + const HANGUL: (char, &str) = ('한', "korean-system"); // Han text follows the interface language, not the operating system's locale. fonts::set_cjk_locale(cjk_locale(language)); let base = fonts::resolve("Inter", "Regular").face; - let cjk = if is_chinese(language) { [HAN, KANA] } else { [KANA, HAN] }; + let cjk = if is_chinese(language) { [HAN, KANA, HANGUL] } else { [KANA, HAN, HANGUL] }; let mut names = Vec::new(); let mut seen = Vec::new(); for &(probe, name) in cjk.iter().chain(SCRIPT_PROBES) { @@ -597,6 +601,24 @@ mod tests { install_script_fallbacks(&mut english, "en"); } + #[test] + fn hangul_gets_a_face_when_one_is_installed() { + use effectcraft_text::fonts; + let mut fonts_def = FontDefinitions::default(); + install_script_fallbacks(&mut fonts_def, "en"); + let base = fonts::resolve("Inter", "Regular").face; + let id = fonts::fallback_for('한', base); + let face = fonts::face(id); + if !face.has_char('한') { + eprintln!("no Hangul font is installed: nothing to check here"); + return; + } + let Some(font) = face.font() else { return }; + let bytes = font.data().as_bytes(); + let covered = fonts_def.font_data.values().any(|d| d.font.as_ref() == bytes && d.index == face.info.index); + assert!(covered, "a face covering Hangul must be registered with egui"); + } + #[test] fn a_fallback_face_is_registered_at_most_once() { let mut fonts = FontDefinitions::default();