i18n: Russian catalog covers the whole interface

- ru.tsv: all 3,592 strings of the reference catalog (was 355), translated
  from the English sources with ordinary, Premiere-style Russian vocabulary.
  Fixes the known mistranslations (Sequence -> Последовательность, Bin ->
  Корзина, Lumetri Scopes -> Осциллограммы Lumetri, Wipe -> Вытеснение,
  Normalize Mix Track, «мастер-дорожка») and applies one glossary throughout.
- Tests: russian_covers_the_whole_interface requires every Spanish entry and
  no dead ones; a font test covers the Cyrillic alphabet including «ё»;
  System Language maps ru-* to Russian.
- Docs: localization-parity, roadmap, gaps, ROADMAP, the ui-egui README and
  the catalog's attribution sidecar.
This commit is contained in:
grib_job
2026-10-19 20:01:55 +03:00
parent 302f51835a
commit 08432644e5
9 changed files with 3400 additions and 113 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ iconography, images or other Adobe assets; open licences only; every asset attri
| `crates/ui-egui/src/i18n/ko.tsv` | FilmCraft contributors | Original work: clean-room Korean interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/fr.tsv` | FilmCraft contributors | Original work: clean-room French interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/pt-br.tsv` | FilmCraft contributors | Original work: clean-room Brazilian Portuguese interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translation (full catalog) | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/uk.tsv` | FilmCraft contributors | Original work: clean-room Ukrainian interface translations | MIT OR Apache-2.0 |
| `assets/fonts/Inter-Regular.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
| `assets/fonts/Inter-Medium.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
+2 -1
View File
@@ -72,7 +72,7 @@ Evidence for every row: [docs/target-app-parity.md](docs/target-app-parity.md#by
## Languages
Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings):
Premiere ships 10 interface languages. Measured from our catalogs (3,593 strings, last measured 2026-10-19):
| Language | Status | Strings |
|---|---|---|
@@ -86,6 +86,7 @@ Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings
| Indonesian | partial (whole interface; native review welcome) | ~100% |
| Italian | partial (whole interface; native review welcome) | ~100% |
| Korean | partial (whole interface; needs an installed Hangul font; native review welcome) | ~100% |
| Russian | partial (whole interface; native review welcome) | ~100% |
| Japanese | partial (whole interface) | 99.7% |
| German | partial (whole interface; menus native-reviewed, the rest welcome) | ~100% |
| Vietnamese | none | 0% |
+5 -4
View File
@@ -18,8 +18,8 @@ the committed span and undo. Set `FILMCRAFT_UI_SNAPSHOT_DIR` to render screensho
## Localisation
Edit > Language offers English, Japanese, Spanish, Brazilian Portuguese, Ukrainian, Simplified
Chinese, German, Russian, French, Indonesian, Korean and Italian (all but Ukrainian and Russian cover
the whole interface; those two cover the core menus). The language is stored in the engine's `general.interfaceLanguage` preference,
Chinese, German, Russian, French, Indonesian, Korean and Italian (all but Ukrainian cover
the whole interface; Ukrainian covers the core menus). The language is stored in the engine's `general.interfaceLanguage` preference,
restored on startup, and also available in Settings > General.
Its default, System Language (`system`), follows the operating system: the first of the user's
preferred languages that the interface has (the host supplies them through
@@ -33,10 +33,11 @@ fills translated templates, and `i18n::t` translates names from registries. Plac
(including user filenames containing braces) are inserted literally. Catalog translations are
original work using ordinary language, without proprietary localisation resources.
Spanish, Japanese, Simplified Chinese, French, Brazilian Portuguese and German cover menus, panels, dialogs, settings and registry labels. Searches accept both the
Spanish, Japanese, Simplified Chinese, French, Brazilian Portuguese, German and Russian cover
menus, panels, dialogs, settings and registry labels. Searches accept both the
translated label and its English source, including Unicode capitals. Project content, command ids
and preference values retain their original values. Engine errors, CLI and MCP messages remain
English. Ukrainian and Russian currently cover the core menus; they fall back to English elsewhere.
English. Ukrainian currently covers the core menus; it falls back to English elsewhere.
Verification: `cargo test -p filmcraft-ui-egui` checks catalog syntax, duplicate keys, placeholders,
literal/menu/registry coverage and UI behaviour; `cargo xtask ci` runs the workspace gates. Visual
+44 -8
View File
@@ -1196,21 +1196,47 @@ mod tests {
}
}
/// Russian covers the whole interface: every entry of the reference (Spanish) catalog, so the
/// menus, panels, dialogs, settings, effects and status messages are all translated. Every
/// entry must still have a Spanish counterpart, so a renamed or removed source can't leave a
/// dead Russian entry.
#[test]
fn russian_entries_cover_the_original_menu_catalog() {
let app = crate::FilmcraftApp::new(filmcraft_engine::Session::default());
let items = crate::menus::menu_items(&app);
let known = |text: &str| crate::menus::MENUS.contains(&text) || items.iter().any(|it| it.label == text || it.path.iter().any(|p| p == text));
let (entries, _) = catalog::parse_entries(include_str!("ru.tsv"));
for (_, en, _) in entries {
assert!(known(&en) || en == "Settings", "not a menu label: {en}");
fn russian_covers_the_whole_interface() {
let (entries, errors) = catalog::parse_entries(include_str!("ru.tsv"));
assert!(errors.is_empty(), "{errors:?}");
for (ctx, en, _) in &entries {
assert!(ctx.is_empty() && (Language::Es.has(en) || en == "Settings"), "Russian entry without a Spanish one: {ctx:?} {en:?}");
}
let (es, _) = catalog::parse_entries(include_str!("es.tsv"));
let mut missing: Vec<&str> = es.iter().map(|(_, en, _)| en.as_str()).filter(|en| !Language::Ru.has(en)).collect();
missing.sort_unstable();
assert!(missing.is_empty(), "untranslated Russian strings ({}): {:?}", missing.len(), &missing[..missing.len().min(20)]);
for en in core_menu_labels() {
assert!(Language::Ru.has(&en), "missing Russian menu label: {en}");
}
for en in crate::menus::MENUS.into_iter().chain(["Audio", "Settings"]) {
assert_ne!(Language::Ru.tr(en), en, "untranslated Russian menu: {en}");
assert!(Language::Ru.has(en), "untranslated Russian menu: {en}");
}
// beyond the menus: panels, effects and their parameters, settings, status messages
for (en, ru) in [
("Settings", "Настройки"),
("Gaussian Blur", "Размытие по Гауссу"),
("Audio Track Mixer", "Микшер аудиодорожек"),
("Sequence", "Последовательность"),
("Playhead", "Курсор воспроизведения"),
("Lumetri Scopes", "Осциллограммы Lumetri"),
] {
assert_eq!(Language::Ru.tr(en), ru);
}
assert_eq!(Language::Ru.name(), "Русский");
assert_eq!(Language::parse("ru"), Some(Language::Ru));
for tag in ["ru", "ru-RU", "ru_RU.UTF-8"] {
assert_eq!(Language::from_locales(&[tag.to_string()]), Language::Ru, "{tag}");
}
set_current(Language::Ru);
assert!(matches_query("Gaussian Blur", "размытие"));
assert!(matches_query("Gaussian Blur", "gaussian"));
set_current(Language::En);
}
/// Indonesian covers the whole interface (the Spanish catalog's entries and the native macOS
@@ -1315,6 +1341,16 @@ mod tests {
assert_bundled_fonts_cover(alphabet.chars().chain(Language::Uk.name().chars()).chain(entries.iter().flat_map(|(_, _, uk)| uk.chars())));
}
#[test]
fn russian_renders_with_bundled_fonts() {
let (entries, _) = catalog::parse_entries(include_str!("ru.tsv"));
// every Russian letter, including «ё», even ones no entry uses yet, and every letter the
// entries use
let alphabet = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя";
let letters = entries.iter().flat_map(|(_, _, ru)| ru.chars()).filter(|ch| ch.is_alphabetic());
assert_bundled_fonts_cover(alphabet.chars().chain(Language::Ru.name().chars()).chain(letters));
}
#[test]
fn portuguese_renders_with_bundled_fonts() {
let (entries, _) = catalog::parse_entries(include_str!("pt-br.tsv"));
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -5,4 +5,9 @@ source: original work
license: MIT OR Apache-2.0
license-file: LICENSE-MIT and LICENSE-APACHE
added: 2026-10-10 by grib_job
notes: Original English-to-Russian menu translations using clean-room NLE vocabulary.
notes: Original clean-room English-to-Russian translation of the full 3,592-string
reference catalog, using ordinary Russian video-editing vocabulary (Premiere-style
terms: последовательность, корзина, дорожка, визуализация). No proprietary
localisation resource, string table or product interface was consulted. Drafted
with the project's agents and reviewed against the tests; native-speaker review
still welcome.
+7 -2
View File
@@ -234,12 +234,12 @@ platforms** G4, G9, G17; **performance** G16; **ecosystem** G11; **measurement**
## G14. Localization: 3 of the 12 key languages missing (Hindi, Arabic, Vietnamese)
- **Have:** Spanish, Japanese, Simplified Chinese, French (#498) and Portuguese (Brazil) (#859)
catalogs cover ~99.6–100% of the ~3,500 cataloged strings; Ukrainian ~10% (menus).
catalogs cover ~99.6–100% of the ~3,590 cataloged strings; Ukrainian ~10% (menus).
- **Missing:** Hindi, Arabic (no RTL interface layout or catalog; the interface has Arabic and Hebrew
fallback fonts and shows captions in reading order, but other names and fields keep egui's
left-to-right run order; Arabic titles reported broken, #395),
Korean (#508; needs Hangul fonts in craft-fonts),
Vietnamese; Premiere also ships Russian. Engine errors,
Vietnamese. Engine errors,
CLI and MCP stay English. Apart from the German menus (#630), no language has a recorded
native-speaker review.
- **Done:** Indonesian (#867): `id.tsv` has every entry of the Spanish catalog (~100%), in Edit ▸
@@ -251,6 +251,11 @@ platforms** G4, G9, G17; **performance** G16; **ecosystem** G11; **measurement**
- **Done:** German: `de.tsv` has every entry of the Spanish catalog (~100%), beyond the menus of
#630 (panels, dialogs, effects and their parameters, settings, status messages). The menus are
native-reviewed; review of the rest welcome.
- **Done:** Russian: `ru.tsv` has every entry of the Spanish catalog (100% of the reference
catalog), translated from the English sources with Premiere-style Russian vocabulary
(последовательность, корзина, дорожка, визуализация); Edit ▸ Language, Settings ▸ General and
System Language (`ru-*`) reach it, the i18n test requires full coverage and a font test covers
the Russian alphabet including «ё». Native-speaker review welcome.
- **Estimate:** 150–230 h. Doc: [localization-parity.md](localization-parity.md).
## G15. Interchange never validated in Avid / Pro Tools; slow XML import
+15 -11
View File
@@ -1,6 +1,6 @@
# Localization parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (German covers the whole interface) · **Target:** Adobe Premiere Pro 2026 (26.5.2)
> **Last reviewed:** 2026-10-19 · **Last updated:** 2026-10-19 · **Change:** Russian covers the whole interface · **Target:** Adobe Premiere Pro 2026 (26.5.2)
Per-language status of FilmCraft's interface. Premiere 26.5.2 ships 10 interface languages (the
installed bundle's `.lproj` folders): German, English, Spanish, French, Italian, Japanese, Korean,
@@ -19,7 +19,7 @@ displayed labels as well as English sources. Tests fail when a `tl!` literal, a
registry name has no Spanish entry; `zh-cn.tsv` must also cover every `tl!` literal and menu
label; `ja.tsv`, `fr.tsv`, `pt-br.tsv` and `de.tsv` have the same entries but are not yet required by tests
(French and German must cover the core menus, Brazilian Portuguese every menu label, and neither may keep an
entry without a Spanish one). Engine error messages, the
entry without a Spanish one). `ru.tsv` must cover every entry of the Spanish catalog and must not keep an entry without a Spanish one. Engine error messages, the
control channel, the CLI and MCP stay English.
Fonts come from [craft-fonts](https://github.com/storytold/craft-fonts) (`CRAFT_FONTS_DIR`, all
@@ -34,16 +34,16 @@ right to left, but Arabic titles are reported broken (#395).
## Status
Measured 2026-10-10 by counting entries in each catalog. The denominator is the union of all
catalogs' sources (**3,498 strings**); strings not yet wrapped in `tl!` and engine messages are
Measured 2026-10-19 by counting entries in each catalog. The denominator is the union of all
catalogs' sources (**3,593 strings**); strings not yet wrapped in `tl!` and engine messages are
not in it, so real coverage is somewhat lower than shown. Estimates calibrated from #449 (Japanese,
whole interface, one PR) at ~4–8 h per language for the catalog plus tests.
| Language | Code | UI strings | Dialogs / tooltips / help | Script support | Native review | Status | To `full` |
|---|---|---|---|---|---|---|---|
| English | en | 3,498 (100%, source) | yes; no help docs in-app | Latin | n/a | **full** | — |
| English | en | 3,593 (100%, source) | yes; no help docs in-app | Latin | n/a | **full** | — |
| Simplified Chinese | zh-cn | 3,485 (99.6%) | dialogs, Settings, effects, shortcuts, status; engine errors English | CJK font fallback; system IME via winit | not recorded | partial | 6–10 h + review |
| Spanish | es | 3,496 (99.9%) | as above | Latin | not recorded | partial | 4–8 h + review |
| Spanish | es | 3,592 (the reference catalog) | as above | Latin | not recorded | partial | 4–8 h + review |
| Hindi | hi | 0 (0%) | — | **no Devanagari shaping in the interface** | — | none | 30–50 h (shaping in UI + catalog + fonts) |
| Arabic | ar | 0 (0%) | — | **no RTL interface layout**; fallback fonts and shaping in the interface, captions in reading order, other text in egui's left-to-right run order; titles broken (#395) | — | none | 40–70 h |
| French | fr | 3,526 (same entries as Spanish, plus the macOS Settings item) | as Spanish | Latin (bundled fonts) | not recorded; welcome | partial (#498) | review |
@@ -52,27 +52,31 @@ whole interface, one PR) at ~4–8 h per language for the catalog plus tests.
| Japanese | ja | 3,487 (99.7%) | as zh-cn; system-font kanji may pick the Chinese fallback (#547) | CJK fonts, vertical title text | not recorded | partial | 4–8 h + review |
| German | de | 3,590 (same entries as Spanish); must cover the core menus and the macOS app menu, no entry without a Spanish one | as Spanish | Latin (bundled fonts) | menus yes (#630); the rest not recorded, welcome | partial | review |
| Korean | ko | 3,573 (same entries as Spanish, plus the macOS Settings item) | as Spanish | installed system Hangul font (Malgun Gothic, Apple SD Gothic Neo, Noto Sans CJK KR…); refused without one | not recorded; welcome | partial (#508) | review; Hangul in craft-fonts for the web |
| Russian | ru | 3,592 (100%; every Spanish entry) | dialogs, Settings, effects, shortcuts, status; engine errors English | Cyrillic (bundled fonts), «ё» | not recorded; welcome | partial | native review |
| Vietnamese | vi | 0 (0%) | — | Latin with stacked diacritics (font coverage to check) | — | none | 6–12 h + review |
| *Other shipped:* Italian | it | 3,573 (same entries as Spanish, plus the macOS Settings item); must cover the core menus, no entry without a Spanish one | as Spanish | Latin (bundled fonts) | not recorded; welcome | partial | review |
| *Other shipped:* Ukrainian | uk | 351 (10.0%) | menus only | Cyrillic (bundled) | not recorded | menus only | 5–9 h |
UI strings are catalog entries (the non-comment lines of `src/i18n/<code>.tsv`; English counts the
source strings in the code), so the rows were measured at different times: at this change the
Spanish and German catalogs both have 3,590 entries, German every Spanish one. Strings added
later may stay English in German until translated; only the core menus are required.
Spanish catalog has 3,592 entries, German 3,590, and Russian every Spanish one. Strings added
later may stay English in German until translated; Russian is required to cover every source.
Premiere also ships Italian, which we now cover like Spanish, and Russian (6–10 h).
Premiere also ships Italian, which we cover like Spanish, and Russian, which now covers the whole
interface (native review welcome).
**Localization dimension:** 9 of the 12 key languages near-complete (English, Spanish, Japanese,
Simplified Chinese, French, Portuguese (Brazil), Indonesian, Korean, German), 3 none (Hindi, Arabic,
Vietnamese); against Premiere's 10 languages we cover 9 well and Russian partly. **~35%, 150–230 h** for all twelve to `full` plus Italian and Russian, of which the script
work (RTL and complex shaping in the egui interface) is the largest and least parallel part.
Vietnamese); against Premiere's 10 languages we cover 10 at catalog level, Russian pending native
review. **~35%, 150–230 h** for the twelve key languages to `full` plus Russian review, of which the
script work (RTL and complex shaping in the egui interface) is the largest and least parallel part.
Every language needs native-speaker review (human).
## Revision history
| Date | Change | Summary |
|---|---|---|
| 2026-10-19 | major | Russian (ru) covers the whole interface: 3,592 entries (100% of the Spanish catalog), `ru.tsv` translated from the English sources with Premiere-style Russian vocabulary; the i18n test requires every Spanish entry, a font test covers the Russian alphabet including «ё», System Language maps `ru-*`; native review welcome |
| 2026-10-13 | minor | German (de) covers the whole interface: every entry of the Spanish catalog (3,590); the tests require the core menus and the macOS app menu and reject entries without a Spanish one |
| 2026-10-11 | minor | German (de) ships the menus (#630): 371 of 3,498 strings (10.6%), native-reviewed; dimension now 2 menus-only, 5 none |
| 2026-10-10 | major | Created from ROADMAP.md's "Interface localization" section; catalog coverage measured (es 3,496, ja 3,487, zh-cn 3,485, pt-br 348, uk 351 of 3,498); the 12-language table and script-support gaps added |
+1 -1
View File
@@ -74,7 +74,7 @@ Status: ✅ done · 🟡 in progress · ⬜ not started. Estimates are remaining
| M11 | Interchange & project management | ✅ | `.fcproj` schema versions + migrations, atomic saves, Save a Copy/Revert, auto-save ring + crash-recovery journal (Preferences ▸ Auto Save, recovery prompt), FCP7 XML, FCPXML, EDL, OTIO; offline media (own slate) + Link Media (fingerprint-checked relink, folder remap, search, Align Timecode, Make Offline); proxies (ProRes Proxy/LT, H.264 ¼/½ background jobs, attach/detach/reconnect, monitor toggle, export full-res) + ingest (copy/transcode/proxies); Project Manager (collect, consolidate + transcode with handles, size estimate) | Rename media to clip names, image-sequence conversion, Media Browser-driven relink, smart (cross-drive) path tracking | 1–2 |
| M12–M16 | Multicam, web (WASM), platform, long tail | 🟡 | Multicam: audio sync (GCC-PHAT, sub-sample), Merge Clips, multi-camera source sequences, Multi-Camera view with live switching (1–9); L0–L4 crates compile to wasm32 | Web app shell (file access, WebCodecs, audio), scene detection, auto reframe, ~800 remaining commands and dialogs, performance hardening | 35–55 |
| HW | Hardware acceleration (#30) | 🟡 | Blend modes and 34 effect ids on the GPU incl. Lumetri basic / creative / vignette (#32, GPU2–GPU7); GPU export rendering (#421); decode: VideoToolbox (#33, #41), Media Foundation / D3D11 H.264 / HEVC / VP9 / AV1 (HW2, HW3), VA-API H.264 / HEVC (#358), NVDEC H.264 / HEVC (#549); encode: VideoToolbox H.264 / HEVC, NVENC H.264 (Windows, Linux) and HEVC incl. Main 10 HDR (#328, #360) | Zero-copy, remaining GPU effects, VideoToolbox Main 10, Quick Sync / AMF, VA-API VP9 / AV1 and encode | 120–200 |
| L10N | Localization | 🟡 | Spanish, Japanese, Simplified Chinese whole interface; Portuguese (Brazil), Ukrainian menus | Hindi, Arabic (RTL), French, Indonesian, German, Korean, Vietnamese, Italian, Russian; native review | 150–230 |
| L10N | Localization | 🟡 | Whole interface: Spanish, Japanese, Simplified Chinese, French, Portuguese (Brazil), Indonesian, Italian, Korean, German, Russian; Ukrainian the core menus | Hindi, Arabic (RTL), Vietnamese; native review of every language | 150–230 |
## After beta