diff --git a/ROADMAP.md b/ROADMAP.md index a83c2347..bceed27a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -113,7 +113,7 @@ native speakers' reviews of the six language drafts need people. Percentages measured 2026-10-17 over 2,272 entries (strings added since a draft show English). Also shipped: Russian (`ru`, 99%, reviewed by VanTan), Swedish (`sv`, 99.6%, command labels since 2026-10-17; native review welcome), Turkish (`tr`, 99%), Czech (`cs`, 99%, draft) and Georgian (`ka`, 100%, draft). Figma ships English, Japanese, Korean, French, German, Spanish and Portuguese (Brazil); FigCraft has the localization layer, English and Spanish (Spain and Latin America), -French, German, Brazilian Portuguese, Japanese, Korean, Simplified Chinese and Indonesian drafts (Preferences ▸ +French, German, Brazilian Portuguese, Japanese, Korean, Simplified Chinese, Indonesian and Georgian drafts (Preferences ▸ Language; Traditional Chinese has no catalog; CJK UI text uses an installed CJK font, loaded only when needed; adding a language: [`docs/translating.md`](docs/translating.md)). Document text in any script (bidi, Arabic shaping, diff --git a/crates/ui-egui/src/cjk.rs b/crates/ui-egui/src/cjk.rs index fd3ecf8c..d280bca5 100644 --- a/crates/ui-egui/src/cjk.rs +++ b/crates/ui-egui/src/cjk.rs @@ -69,13 +69,22 @@ pub fn language(code: &str) -> u8 { } /// Whether the UI can draw language `code`: always on desktop (a system face is found when it's -/// needed; tofu at worst), on the web only with built-in faces for its scripts. The language -/// picker and the system language skip a language it can't. +/// needed; tofu at worst), on the web only with built-in faces for its scripts (Georgian: craft-fonts' +/// Noto Sans Georgian). The language picker and the system language skip a language it can't. pub fn can_show(code: &str) -> bool { + shows(code, cfg!(target_arch = "wasm32")) +} + +/// [`can_show`] in a desktop or (`web`) a web build. +fn shows(code: &str, web: bool) -> bool { + if !web { + return true; + } + if code.split('-').next() == Some("ka") { + return figcraft_text::face_with_char('ა', &["Noto Sans Georgian"]).is_some(); + } let need = language(code); - need == 0 - || !cfg!(target_arch = "wasm32") - || samples(need, 0).iter().all(|(c, _)| figcraft_text::face_with_char(*c, &["BIZ UDPGothic", "Noto Sans CJK SC"]).is_some()) + need == 0 || samples(need, 0).iter().all(|(c, _)| figcraft_text::face_with_char(*c, &["BIZ UDPGothic", "Noto Sans CJK SC"]).is_some()) } /// A character standing for each script in `need`, with the families to look for it in, the UI @@ -133,6 +142,15 @@ mod tests { assert!(["en", "es", "es-419", "fr", "de", "pt-BR", "tr", "id"].iter().all(|c| can_show(c))); } + #[test] + fn the_web_offers_georgian_only_with_its_face() { + assert!(shows("ka", false), "desktop always lists Georgian"); + let face = figcraft_text::face_with_char('ა', &["Noto Sans Georgian"]).is_some(); + assert_eq!(shows("ka", true), face); + assert_eq!(shows("ka-GE", true), face); + assert!(shows("en", true) && shows("tr", true)); + } + #[test] fn the_ui_language_script_comes_first() { let order = |need, ui| samples(need, ui).into_iter().map(|(c, _)| c).collect::();