diff --git a/contributors/people.toml b/contributors/people.toml index be84b5b01..87b1aaa42 100644 --- a/contributors/people.toml +++ b/contributors/people.toml @@ -68,3 +68,6 @@ sync_github_name = false [people.Shnrqpdr] sync_github_name = true + +[people.allenyllee] +sync_github_name = true diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index 08097ba27..d9eed82b8 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -500,9 +500,23 @@ fn fallback_faces(han: HanOrder) -> Vec<(&'static str, Vec<(String, u32)>)> { /// Linux directories that hold CJK fonts across distributions: Debian/Ubuntu (`opentype/noto`, /// `truetype/wqy`), Fedora (`google-noto-cjk`), Arch (`noto-cjk`, `wenquanyi`), ChromeOS's Linux -/// container (`chromeos/notocjk`, #1762), plus local and flat layouts. +/// container (`chromeos/notocjk`, #1762), plus local and +/// flat layouts. Flatpak exposes the same host layouts through read-only font mounts. #[cfg(not(target_arch = "wasm32"))] -const LINUX_CJK_DIRS: [&str; 11] = [ +const LINUX_CJK_DIRS: [&str; 22] = [ + // Flatpak mounts host fonts here without a broad filesystem permission. Keep the same + // distribution layouts as below; /usr/share/fonts inside the sandbox belongs to the runtime. + "/run/host/fonts/opentype/noto", + "/run/host/fonts/google-noto-cjk", + "/run/host/fonts/noto-cjk", + "/run/host/fonts/truetype/noto", + "/run/host/fonts/noto", + "/run/host/fonts/truetype", + "/run/host/fonts/TTF", + "/run/host/fonts", + "/run/host/local-fonts", + "/run/host/local-fonts/noto-cjk", + "/run/host/user-fonts", "/usr/share/fonts/opentype/noto", "/usr/share/fonts/google-noto-cjk", "/usr/share/fonts/noto-cjk", @@ -842,6 +856,33 @@ mod tests { } } + #[test] + fn cjk_fallback_probes_flatpak_fonts_with_the_correct_locale_faces() { + // Exercise the candidates the fallback loader actually consumes, not just the directory + // constant. This must work on CI without an installed CJK font or a Flatpak runtime. + for (candidates, face) in [(cjk_han_japanese(), 0), (cjk_han_simplified(), 2), (cjk_hangul(), 1)] { + for directory in [ + "/run/host/fonts/opentype/noto", + "/run/host/fonts/google-noto-cjk", + "/run/host/fonts/noto-cjk", + "/run/host/fonts/truetype/noto", + "/run/host/fonts/noto", + "/run/host/fonts/truetype", + "/run/host/fonts/TTF", + "/run/host/fonts", + "/run/host/local-fonts", + "/run/host/local-fonts/noto-cjk", + "/run/host/user-fonts", + ] { + let path = format!("{directory}/NotoSansCJK-Regular.ttc"); + assert!(candidates.contains(&(path.clone(), face)), "missing Flatpak CJK candidate {path}, face {face}"); + } + } + let chinese = cjk_han_simplified(); + assert!(chinese.contains(&("/run/host/fonts/truetype/wqy/wqy-microhei.ttc".into(), 0))); + assert!(chinese.contains(&("/run/host/fonts/wenquanyi/wqy-microhei.ttc".into(), 0))); + } + #[test] fn fallback_faces_load_each_file_once() { // The region-merged Noto Sans CJK .ttc serves Japanese, Chinese and Hangul; it must be loaded @@ -865,7 +906,7 @@ mod tests { // whose face is absent (a minimal machine) and fails if a face is present but not wired in. let cases: [(&str, Vec<(String, u32)>, &str); 7] = [ ("sys-cjk-han-ja", cjk_han_japanese(), "カテゴリ"), - ("sys-cjk-han-zh", cjk_han_simplified(), "页面布局 客户端配置"), + ("sys-cjk-han-zh", cjk_han_simplified(), "页面布局 客户端配置 繁體中文 儲存與重新開啟 中文標點 ,。!?"), ("sys-cjk-hangul", cjk_hangul(), "한글"), ("sys-thai", thai(), "ทดสอบ"), ("sys-hebrew", hebrew(), "עברית"), diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 64876633d..d143d100f 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-19 · **Change:** minor (defined-name length limit counts characters, so long Arabic names are accepted; Table names are limited to 255 characters; right-to-left sheets in `.xls` files open right-to-left; text boxes and shapes keep right-to-left paragraph direction through XLSX save; Save as Web Page and copied HTML keep right-to-left; French and Serbian `context|label` translations no longer show the context) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-19 · **Change:** minor (defined-name length limit counts characters, so long Arabic names are accepted; Table names are limited to 255 characters; right-to-left sheets in `.xls` files open right-to-left; text boxes and shapes keep right-to-left paragraph direction through XLSX save; Save as Web Page and copied HTML keep right-to-left; CJK fallback probes Flatpak host font mounts; French and Serbian `context|label` translations no longer show the context) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 Per-language status against Excel, which ships its UI in dozens of languages (Windows language packs cover 100+), with localized function names, argument separators, number and date formats, @@ -26,7 +26,10 @@ right-to-left sheets and full complex-script support. Part of localized function names and `;` separators (#45). German with localized numbers and formulas is in PR #163 (open). - **Script support.** System-font fallback for CJK, Thai and Hebrew landed in #38 (closes #32; - #142 is still open pending confirmation). There is no complex-text shaping: Arabic and + #142 is still open pending confirmation). Native CJK fallback also probes Flatpak's read-only + `/run/host/fonts`, `/run/host/local-fonts` and `/run/host/user-fonts` layouts, so installed + Noto CJK and WenQuanYi faces can render Chinese without a broad filesystem grant. This does + not change the installed-font catalogue or add bundled fonts. There is no complex-text shaping: Arabic and Devanagari don't join or reorder, and there is no bidirectional layout. **Sheet Right-to-Left** (`view.rightToLeft`, Page Layout › Sheet Options, XLSX `rightToLeft`, `.xls` WINDOW2 fRightToLeft) mirrors the grid (#146): column A and the row headers on the right, the vertical scrollbar on the left; hit-testing, @@ -89,6 +92,7 @@ language (none so far) and of localized function names. | 2026-10-19 | trivial | Text boxes and shapes keep right-to-left paragraph direction (`a:pPr rtl`) on XLSX save, so Excel-authored Arabic and Hebrew text boxes reopen right to left | | 2026-10-19 | minor | Save as Web Page and copied HTML mark right-to-left sheets `dir="rtl"`, let General-aligned Arabic and Hebrew text align by its own direction (`dir="auto"`), and keep numbers on right-to-left sheets left to right and on the left | | 2026-10-19 | minor | French and Serbian kept the context in three `context\|label` translations ("Options\|Général", "Opcije\|Opšte" for `Options\|General`; also `Options\|Save`, `Sheet Options\|View`). `tr` shows a found translation as it is, so File › Options headings and the Sheet Options "View" checkboxes showed the prefix. Fixed; a test checks that no catalog shows a `\|` | +| 2026-10-14 | minor | CJK fallback probes the read-only Flatpak host font mounts with the existing distribution layouts and TTC locale indices; no new sandbox permissions or bundled fonts | | 2026-10-12 | minor | Format Cells looks up its tabs, labels, options and note through `Language::tr` (Fill tab keyed `Format Cells\|Fill`); dialog titles and OK/Cancel too. Labels already in a table (Number, Currency, Fill…) show translated; the rest fall back to English until the tables add them | | 2026-10-12 | minor | Brazilian Portuguese catalog (`i18n/pt.rs`) grows from 377 to 923 entries: every key the other catalogs translate, including the dialog strings #669 starts looking up (~42%) | | 2026-10-11 | minor | German ribbon catalog (`i18n/de.rs`, 266 labels, ~12%); `de` locale tags (de-DE, de-AT, de-CH…) resolve to German. PR #163 (localized German formulas/numbers) still open |