Merge pull request #5845 from devius/ka-language

i18n: Georgian (ka) interface language
This commit is contained in:
David Mann authored and GitHub committed 2026-11-07 19:19:01 +01:00
commit e6ba4aca42
8 files changed
+4831 -6

No files matched your search

+1
View File
@@ -38,6 +38,7 @@ next to them.
| `crates/ui-egui/src/i18n/ro.tsv` | Romanian UI translations | @tronicum with Claude Code, AI-assisted (machine-translated); not yet reviewed by a native speaker | Original translations of PhotoCraft's English labels | MIT OR Apache-2.0, [`LICENSE-translations.txt`](crates/ui-egui/src/i18n/LICENSE-translations.txt) |
| `crates/ui-egui/src/i18n/th.tsv` | Thai UI translations | @Thanawatttt and PhotoCraft contributors, with opencode (DeepSeek) as an AI contributor | Machine-assisted first draft from PhotoCraft's English labels, reviewed for UI terminology | MIT OR Apache-2.0, [`LICENSE-translations.txt`](crates/ui-egui/src/i18n/LICENSE-translations.txt) |
| `crates/ui-egui/src/i18n/ta.tsv` | Tamil UI translations | @newsbaba24x7 and PhotoCraft contributors | Original translations of PhotoCraft's English labels | MIT OR Apache-2.0, [`LICENSE-translations.txt`](crates/ui-egui/src/i18n/LICENSE-translations.txt) |
| `crates/ui-egui/src/i18n/ka.tsv` | Georgian UI translations | @devius with Claude Code, AI-assisted | Original translations of PhotoCraft's English labels | MIT OR Apache-2.0, [`LICENSE-translations.txt`](crates/ui-egui/src/i18n/LICENSE-translations.txt) |
| `epaint_default_fonts::EGUI_ICONS` (build input; deflated into `OUT_DIR/egui_fonts/egui-icons.ttf.deflate`, registered by `crates/ui-egui/src/egui_fonts.rs`) | egui-icons, five-glyph subset of emoji-icon-font | John Slegers | [egui fork at 6d518fc](https://github.com/storytold/egui/tree/6d518fc799681571963842f95b55a6b68431b15a/crates/epaint_default_fonts/fonts), [original](https://github.com/jslegers/emoji-icon-font); egui subset, unmodified here | MIT; Copyright (c) 2014 John Slegers; full upstream notice in [NOTICE](NOTICE) |
| `assets/fonts/Inter-Regular.ttf`, `Inter-Medium.ttf`, `Inter-SemiBold.ttf` | Inter 4.001 (UI font) | The Inter Project Authors (Rasmus Andersson) | <https://github.com/rsms/inter> | SIL OFL 1.1, [`assets/fonts/OFL-Inter.txt`](assets/fonts/OFL-Inter.txt) |
| `assets/fonts/JetBrainsMono-Regular.ttf` | JetBrains Mono 2.305 (numeric font) | The JetBrains Mono Project Authors | <https://github.com/JetBrains/JetBrainsMono> | SIL OFL 1.1, [`assets/fonts/OFL-JetBrainsMono.txt`](assets/fonts/OFL-JetBrainsMono.txt) |
+3 -1
View File
@@ -216,7 +216,7 @@ fn expand(packed: &str, keys: &[&str]) -> Result<String, String> {
}
/// The registry. English first: it is the fallback and the source language.
pub static LANGUAGES: [LangInfo; 34] = [
pub static LANGUAGES: [LangInfo; 35] = [
LangInfo { code: "en", name: "English", source: b"", plural: plural_one_other, complete_menus: false, catalog: OnceLock::new() },
LangInfo { code: "ja", name: "日本語", source: catalog!("ja"), plural: plural_none, complete_menus: true, catalog: OnceLock::new() },
LangInfo { code: "zh-hans", name: "简体中文", source: catalog!("zh-hans"), plural: plural_none, complete_menus: true, catalog: OnceLock::new() },
@@ -284,6 +284,8 @@ pub static LANGUAGES: [LangInfo; 34] = [
LangInfo { code: "ro", name: "Română", source: catalog!("ro"), plural: plural_romanian, complete_menus: true, catalog: OnceLock::new() },
// Tamil; `ta-IN`, `ta-LK` and `ta_IN.UTF-8` resolve here. CLDR plural: one|other.
LangInfo { code: "ta", name: "தமிழ்", source: catalog!("ta"), plural: plural_one_other, complete_menus: true, catalog: OnceLock::new() },
// Georgian: nouns stay singular after a numeral (`შრე: 5`, `5 შრე`), so one form serves every count.
LangInfo { code: "ka", name: "ქართული", source: catalog!("ka"), plural: plural_none, complete_menus: true, catalog: OnceLock::new() },
];
impl LangInfo {
File diff suppressed because it is too large. Load diff
+1
View File
@@ -172,6 +172,7 @@ mod tests {
(vec!["nb-NO", "en-US"], "nb"),
(vec!["nn_NO.UTF-8", "en-US"], "nb"),
(vec!["is-IS", "no-NO"], "nb"),
(vec!["ka-GE", "ru-RU"], "ka"),
(vec![], "en"),
] {
with_system_tags(&tags, || assert_eq!(system_lang().code(), expected));
+15
View File
@@ -7,6 +7,7 @@ const CS: fn() -> Lang = || Lang::from_code("cs").expect("cs registered");
const ID: fn() -> Lang = || Lang::from_code("id").expect("id registered");
const VI: fn() -> Lang = || Lang::from_code("vi").expect("vi registered");
const HI: fn() -> Lang = || Lang::from_code("hi").expect("hi registered");
const KA: fn() -> Lang = || Lang::from_code("ka").expect("ka registered");
#[test]
fn hindi_has_the_reveal_and_camera_raw_rows() {
@@ -28,6 +29,20 @@ fn hindi_tags_resolve() {
assert_eq!(Lang::from_pref("HI"), HI());
}
#[test]
fn georgian_tags_resolve() {
for tag in ["ka", "ka-GE", "ka_GE", "ka_GE.UTF-8"] {
assert_eq!(lang_from_tag(tag), Some(KA()), "{tag}");
}
assert_eq!(KA().name(), "ქართული");
assert_eq!(Lang::from_pref("ka"), KA());
assert_eq!(Lang::from_pref("KA"), KA());
assert_eq!(tr(KA(), "Layer"), "შრე");
assert_eq!(tr(KA(), "File"), "ფაილი");
assert_eq!(trn(KA(), 1, "{n} layer", "{n} layers"), "შრე: 1");
assert_eq!(trn(KA(), 3, "{n} layer", "{n} layers"), "შრე: 3");
}
#[test]
fn indonesian_tags_resolve() {
for tag in ["id", "id-ID", "id_ID", "id_ID.UTF-8"] {
+84
View File
@@ -0,0 +1,84 @@
# Georgian localization and terminology
This note goes with the Georgian catalog (`crates/ui-egui/src/i18n/ka.tsv`). It covers every key
`cargo xtask i18n-coverage` measures and the runtime labels the other complete catalogs carry
(filter and adjustment parameters, Camera Raw, panels, dialogs, status messages). Translations are
written from the meaning of PhotoCraft's English labels; no proprietary translation resources,
fonts, screenshots or user documents are included.
## Choosing Georgian
Open **Edit > Preferences > Interface > Language** (Georgian: **რედაქტირება › პარამეტრები ›
ინტერფეისი › ენა**) and choose **ქართული**. With `interface.language` set to `auto`, the system
locales `ka`, `ka-GE` and `ka_GE.UTF-8` resolve to Georgian.
## Register and style
Commands are verbal nouns (masdar: *შენახვა*, *გახსნა*, *შრის წაშლა*), not imperatives; prompts
and hints address the user politely (*დაწკაპეთ*, *გადაათრიეთ*). Product and technology names
(PhotoCraft, OpenType, CMYK, Lab) stay as they are, and the trailing `…` of dialog commands is kept.
## Georgian script
- Mkhedruli has no letter case, so nothing is capitalised and labels never use Mtavruli.
The text engine's **All Caps** maps Mkhedruli to Mtavruli through Unicode `to_uppercase`, which
is the Unicode-standard behaviour; there is no title-case feature that needs a Georgian guard.
- Nouns stay singular after a numeral, so the catalog uses one plural form and count-neutral
wording: `{n} layers` is `შრე: {n}` (`plural_none` in the registry).
- UI font: PhotoCraft bundles no Georgian face. The fallback list in `crates/text/src/scripts.rs`
uses system fonts: Noto Sans Georgian, Segoe UI, Sylfaen, DejaVu Sans and
FreeSans. The web build has no system fonts, so it needs a Georgian face before Georgian can render
there.
- PhotoCraft has no per-language date or number formatting, so nothing Georgian-specific applies.
## Terminology
Follow this table when adding or changing Georgian strings.
| English source | Georgian | Note |
|---|---|---|
| File / Edit / Select / View / Window | ფაილი / რედაქტირება / მონიშვნა / ხედი / ფანჯარა | menu bar |
| Image | გამოსახულება | the edited picture |
| Canvas / Canvas Size… | ტილო / ტილოს ზომა… | |
| Layer / Layers | შრე / შრეები | |
| Selection | მონიშნული | the selected area; the menu is მონიშვნა |
| Layer Mask / Vector Mask | შრის ნიღაბი / ვექტორული ნიღაბი | |
| Clipping Mask | მომჭრელი ნიღაბი | |
| Smart Object | ჭკვიანი ობიექტი | |
| Rasterize | რასტრირება | |
| Path / Work Path | ტრაექტორია / სამუშაო ტრაექტორია | not კონტური |
| Stroke | კონტური | outline of a shape or text |
| Channel / Alpha | არხი / ალფა | |
| Spot Color / Spot Channel | სპოტ-ფერი / სპოტ-ფერის არხი | |
| Adjustments | კორექცია | |
| Blend Mode / Blending Options | შერევის რეჟიმი / შერევის პარამეტრები | |
| Opacity | გაუმჭვირვალობა | |
| Preset / Presets | პრესეტი / პრესეტები | |
| Pattern | პატერნი | |
| Swatches | ფერის ნიმუშები | |
| Slice | ნაჭერი | |
| Crop | ჩამოჭრა | |
| Feather | კიდეების შერბილება | |
| Hue / Lightness | ფერის ტონი / სიღიავე | |
| Threshold | ზღვარი | |
| Brush / Eraser / Smudge | ფუნჯი / საშლელი / გადღაბნა | |
| Healing Brush | აღმდგენი ფუნჯი | |
| Reset | ჩამოყრა | |
| Paste | ჩასმა | |
| Workspace | სამუშაო სივრცე | |
| Foreground / Background Color | წინა პლანის ფერი / ფონის ფერი | |
## Not covered
Engine error and status messages, user document, layer and preset names, automation command IDs
and the default `Untitled` / `Background` names stay in English, as in every language.
## Maintenance
Add a row to `ka.tsv` for each new English label: `context<TAB>source<TAB>translation`, with
`@plural` rows holding one Georgian form and `@id` rows overriding a command id. Keep `{name}`
placeholders, `\n`, `…` and shortcut text exactly as in the source. Checks:
- `cargo test -p photocraft-ui-egui --lib i18n`: registry, locale tags, placeholders and catalog
consistency.
- `cargo xtask i18n-coverage`: measured key coverage for `ka`.
+7 -5
View File
@@ -1,10 +1,10 @@
# Localization parity
> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-11-06 · **Change:** minor (Azerbaijani UI catalog merged with current languages; native review pending; Bosnian UI catalog; previously minor: Swedish, Finnish, Danish and Norwegian Bokmål UI catalogs; previously minor: Arabic UI catalog) · **Target:** Adobe Photoshop 2026
> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-11-06 · **Change:** minor (Georgian interface catalog; previously minor: Azerbaijani UI catalog merged with current languages; native review pending; Bosnian UI catalog; previously minor: Swedish, Finnish, Danish and Norwegian Bokmål UI catalogs; previously minor: Arabic UI catalog) · **Target:** Adobe Photoshop 2026
Per-language status of PhotoCraft's UI. How catalogs work and how to add one:
[`localization.md`](localization.md). Language notes: [Korean](localization-ko.md), [Spanish](localization-es.md),
[Simplified Chinese](localization-zh-hans.md), [Italian](localization-it.md), [Russian](localization-ru.md).
[Simplified Chinese](localization-zh-hans.md), [Italian](localization-it.md), [Russian](localization-ru.md), [Georgian](localization-ka.md).
**How measured.** `cargo xtask i18n-coverage` (`xtask/src/i18n_coverage.rs`) defines the key
universe: `tl!("…")` literals and `trn(` plurals in `ui-egui` (tests excluded), menu-catalog
@@ -24,7 +24,7 @@ Vietnamese UI; Arabic and Hebrew users get English "Middle East" builds with the
composer, and its text engine handles RTL, Devanagari and Indic scripts.
**Summary.** 7 of the 12 key languages at 100% of measured keys (status `partial` because of the
engine messages), 2 absent (Hindi, Vietnamese), plus 17 other registered languages. Weighted by
engine messages), 2 absent (Hindi, Vietnamese), plus 18 other registered languages. Weighted by
speakers, ~55% ready. Remaining: 80–140 h, plus native-speaker review (recorded only for Italian,
2026-10-12).
@@ -47,13 +47,14 @@ speakers, ~55% ready. Remaining: 80–140 h, plus native-speaker review (recorde
## Other shipped languages
17 registered languages are outside the twelve-language table. The following eight have
18 registered languages are outside the twelve-language table. The following nine have
1,608 / 1,608 measured keys, status `partial` for the same reason: Traditional
Chinese `zh-hant` (2,329 rows), Russian `ru` (4,227 keys; also every dynamic label the
other catalogs translate, [notes](localization-ru.md)), Ukrainian `uk` (3,375), Czech `cs` (3,522),
Polish `pl` (3,366), Greek `el` (3,481), Dutch `nl` (3,568), Italian `it` (4,164; also every dynamic label the
other catalogs translate; reviewed by a native speaker, [notes](localization-it.md)). Hungarian
`hu` (4,347 rows) is also registered. Turkish `tr`
`hu` (4,347 rows) is also registered. Georgian `ka` (4,530 rows; every measured key on 2026-10-31;
Georgian UI fallback font: Noto Sans Georgian, Segoe UI, Sylfaen, SF Georgian, DejaVu Sans; on the web the first served font for `Geor`). Turkish `tr`
(3,731 rows) also covers every measured key. Serbian `sr` (4,022 rows, Latin script, Ekavian, added 2026-10-12) covers every
measured key and the union of the other catalogs' dynamic labels; its one/few/many plurals reuse
the Russian rule. Swedish `sv` (4,552 rows, added 2026-10-28) covers every measured key and the
@@ -113,6 +114,7 @@ engine localization or native review is complete.
| 2026-10-13 | minor | Italian: the `Screen` blend mode read *Schermo* (the display) and is now *Scherma*; the Dodge/Burn/Sponge tool names were already Adobe's (*Scherma*, *Brucia*, *Spugna*) and stay. Pinned by a test |
| 2026-10-18 | minor | Russian: 1,229 dynamic labels added (filter and adjustment parameters, Camera Raw, lighting, History/Layers/paths menus, metadata, System Info, status templates, dialogs) with a terminology note ([localization-ru](localization-ru.md)) |
| 2026-10-22 | minor | Arabic row: paragraph direction has Auto / Left-to-right / Right-to-left buttons in the Paragraph panel and Type options bar (#6793); the visual RTL caret is still missing (TYPE-218-2 partial) |
| 2026-10-22 | minor | Georgian (`ka`) catalog |
| 2026-10-28 | minor | Arabic (`ar`) UI catalog: every measured key, six plural forms; layer names and the title bar no longer reversed on egui 0.37 |
| 2026-10-29 | minor | Swedish (`sv`) UI catalog: every measured key plus the dynamic labels, combined from #5985 and #9536 |
| 2026-10-29 | minor | Finnish (`fi`), Danish (`da`) and Norwegian Bokmål (`nb`) UI catalogs: every measured key plus the dynamic labels, combined from #5666, #6961, #7267, #8072 and #9025 |
+1
View File
@@ -36,6 +36,7 @@ contextual, command-ID and plural translations; missing entries fall back to Eng
| Suomi | `fi` | one / other (partitive after every count but 1) |
| Dansk | `da` | one / other |
| Norsk bokmål | `nb` | one / other |
| ქართული | `ka` | one form (count-neutral: `შრე: {n}`) |
| עברית | `he` | one / other |
| اردو | `ur` | one / other |
| Română | `ro` | one / few (0, 2–19, 101–119 …) / other (20–100, 120 …) |