Files
photocraft/docs/localization.md
T
e79dcb6f7f i18n: add German (de) UI translation (#309) (#663)
* i18n: add German (de) UI translation (#309)

A complete German catalog plus the registry row:

- de.tsv: the full key set (menus, tl! literals, blend-mode names, Camera
  Raw labels, generated preference labels), plural rule one|other, header
  documenting the format and the clean-room policy like ja.tsv.
- Registered with complete_menus: true; the locale resolver and the
  language-list tests gain de (de-DE/de-AT/de-CH resolve to it).
- ATTRIBUTION.md row and the docs/localization.md language table entry.

Translations are original work from the plain meaning of the English
labels in ordinary German image-editing vocabulary (Ebene, Maske,
Auswahl, Weichzeichnen, Tonwertkorrektur, Smart-Objekt ...); no other
product's localisation resources were consulted. Product and technology
names (PhotoCraft, ArtCraft, OpenType, CMYK, Lab, Camera Raw) stay in
Latin letters; the Camera Raw curve bands are distinct (Schwarz, Tiefen,
Dunkle, Helle, Lichter, Weiss).

Verified: catalog tests and preference-label tests green,
cargo xtask i18n-coverage reports de 1404/1404 (100%), the full
ui-egui suite passes (except the known machine-local wgpu driver
failure that also fails on clean main), clippy and wasm32 clean, and
an offscreen snapshot sequence switches de -> en -> de in one process
and ends fully German.

* de: translate Metadata (Export As gains the label in the #647 fix)

* Revert "de: translate Metadata (Export As gains the label in the #647 fix)"

This reverts commit 948a8d01dd83579a899d938611101daa50a9e1e1.

* de: apply the native-speaker review (#663)

All meaning errors from the review: Auto Tone is the tonal range
(Automatische Tonwertkorrektur), the Divide blend mode is arithmetic
(Dividieren), Note Paper is Notizpapier, Legal is the US paper format,
Fuzziness widens the colour tolerance (Toleranz:), Perspective Warp
planes are Flaechen (not Ebenen, which reads as layers), Revert is
Zuruecksetzen (matching its confirm text), Fade is Verblassen.
Typos: Tonwerthistogramm, Magischer-Radiergummi-Werkzeug,
Einfrier-Lasso. Consistency: Kanalmixer everywhere, Zoom In/Out as
Vergrössern/Verkleinern, a space before % in the scale labels.

* xtask i18n-coverage: gate the German catalog too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 15:48:02 -04:00

4.5 KiB

UI localisation and live language switching

PhotoCraft uses the same Rust catalog implementation in the native egui shell and the WebAssembly build. English source strings are lookup keys. UTF-8 TSV catalogs supply plain, contextual, command-ID and plural translations; missing entries fall back to English.

Supported languages

Language Preference code Integer plural forms
English en one / other
简体中文 zh-hans one form
日本語 ja one form
한국어 ko one form
Русский ru one / few / many
Français fr singular for 0 and 1 / plural for 2+
繁體中文 zh-hant one form
Español es one / other
Čeština cs one / few / other
Deutsch de one / other
Bahasa Indonesia id one form

Every non-English catalog covers the current menu labels, tl! literals, blend mode names, and generated preference labels. Tests enforce that coverage. This does not include every engine error or status message: those remain English, as do automation command IDs and user-provided document, layer and preset names.

Switch without restarting

Open Edit > Preferences > Interface > Language and choose a language. The Preferences dialog previews its title, controls and buttons in the chosen language. Cancel discards the preview, Apply commits it without closing the dialog, and OK commits and closes. The rest of the interface follows the committed preference on its next draw. Existing documents, undo history and tools remain available throughout a language change.

The existing preference store saves the selection for future launches. auto follows the native system locale; an unsupported code follows the same fallback. Regional tags such as fr-CA, ko-KR and zh-CN resolve to the corresponding registered catalog. Traditional and Simplified Chinese remain distinct.

Agents use the existing prefs.set command through CLI, MCP or the desktop control channel:

{"method":"engine.execute","params":{"command":"prefs.set","params":{"path":"interface.language","value":"ko"}}}

Control requests are processed before synchronising the drawing language, so a request updates the labels in the same rendered frame. Drawing language is local to the UI thread; a scoped preview restores the previous language even if drawing unwinds. Menu and dialog identity continues to use command IDs, independent of translated labels.

This is hot switching among the bundled catalogs. Catalog files are embedded with include_str!; editing a TSV file requires a rebuild. External catalog watching and file-resource hot reload are not implemented.

Fonts

The native lazy CJK font loader prioritises the selected Japanese, Korean or Chinese script. Switching languages rebuilds the font definitions and resets the existing loader, so fonts removed from the definitions can be registered again. Idle frames keep their font cache. Other languages retain the system's CJK fallback preference for document names and text.

Font files are not added to this repository. Native rendering uses installed system fonts and the optional craft-fonts build input; see Fonts. The web build can select every catalog, but CJK glyph delivery and automatic browser-locale detection remain separate outstanding work. Switching catalogs does not supply missing fonts.

Add or maintain a catalog

  1. Add <code>.tsv under crates/ui-egui/src/i18n, following the header in ja.tsv.
  2. Register its code, native name and plural rule in i18n::LANGUAGES.
  3. Translate the meaning of the English source keys. Preserve {name} placeholders, escaped characters and the trailing … on dialog commands. Use @id to disambiguate a command label and @plural for count-sensitive text. Keep product names such as PhotoCraft.
  4. Set complete_menus when the catalog covers all enforced keys. Add source and license attribution for translation assets, then run the catalog and shell tests.
cargo test -p photocraft-ui-egui --locked
cargo clippy -p photocraft-ui-egui --all-targets --locked -- -D warnings
cargo xtask i18n-coverage
cargo xtask layers
cargo xtask wasm

Render representative dialogs with the offscreen snapshot example, including a sequence of language changes in one process. Inspect the PNGs for missing glyphs and truncated labels. Translations are original work or reuse the open PhotoCraft contributions credited in ATTRIBUTION.md; no proprietary localisation resources are used.