Extend interface language selection with Chinese and Arabic translations
across menus, dialogs, panels, tooltips, and common application controls.
Keep English fallback for untranslated strings, return borrowed translation
text, and validate translation key uniqueness and language switching.
Bundle redistributable Noto CJK and Arabic fonts with OFL license files and
ASSETS.md attribution so native and WASM builds have portable glyph coverage.
Register Arabic regular and semibold families while retaining existing font
fallbacks for proportional and monospace controls.
Render Arabic labels using Unicode bidirectional runs and contextual shaping.
Wrap logical text at grapheme boundaries before ordering each visual line,
mirror neutral punctuation, preserve logical source text for accessibility,
and handle truncation, empty lines, and mixed Latin text and numbers. Keep
ASCII labels on the normal rendering path. Disable selection on shaped RTL
labels because egui's default label cursor mapping assumes LTR text.
Adapt welcome controls, menu ordering, popup alignment, and new-document rows
for RTL layout. Bound popup geometry and avoid unsupported RTL grid behavior;
keep numeric inputs LTR. Isolate user-provided document names from Latin
application and zoom metadata. Interface language changes leave document
binding, paragraph direction, editable text, and engine state unchanged.
Add regressions for contextual Arabic joining, bidirectional punctuation,
mixed document names, logical wrapping, truncation, language switching, and
finite widget geometry. Update the roadmap with localization coverage.
Apply equivalent chunk-iteration and PDF Option/borrow simplifications needed
by the current Rust toolchain's strict Clippy checks.
Validation:
- cargo xtask ci: fmt, Clippy, native tests, assets, and layers passed;
native tests total 517 passed and 2 ignored.
- UI regression suite: 26 passed.
- Headless UI screenshots verified Arabic welcome/new-document creation,
menus, mixed-script document names, and switching back to Chinese/English.
- Default WASM gate is blocked by this host's missing precompiled wasm32
standard library. All 15 WASM crates pass using the installed Rust sources:
RUSTC_BOOTSTRAP=1 CARGO_UNSTABLE_BUILD_STD=std,panic_abort
target/debug/xtask wasm.