diff --git a/ASSETS.md b/ASSETS.md index 2731f47bf..48d2b6955 100644 --- a/ASSETS.md +++ b/ASSETS.md @@ -8,6 +8,7 @@ Generated-in-code art is original and has no file to list: the UI icon set (`cra | Asset | Author | Source | Licence | Notes | |---|---|---|---|---| +| German hyphenation patterns (embedded by `hypher` 0.1.8, feature `german`) | Deutschsprachige Trennmustermannschaft: Stephan Hennig, Werner Lemberg, Günter Milde, Sander van Geloven, Georg Pfeiffer, Gisbert W. Selke, Tobias Wendorf, Keno Wehr | https://github.com/typst/hypher/blob/d81cc506416bffef2a75ee2dc969d4b41bc36613/patterns/hyph-de-1996.tex | MIT (copyright 2013–2024; full text in NOTICE) | Version 2024-02-28; reformed German spelling (2006), despite the `de-1996` filename; no separate old-spelling or Swiss patterns | | `crates/ui-egui/src/i18n/uk.rs` (332 common phrases) | VectorCraft contributors | https://github.com/storytold/vectorcraft/blob/01f329aa99fa0c9517311c7b6cf7233ffc207742/crates/ui-egui/src/i18n/uk.tsv | MIT OR Apache-2.0 | Adapted for DesignCraft context; remaining Ukrainian phrases are original or credited below | | `crates/ui-egui/src/i18n/uk.rs` (68 common phrases) | PhotoCraft contributors | https://github.com/storytold/photocraft/blob/ed057bdc6fd89a858c5e0ea4eab158a2a7052dde/crates/ui-egui/src/i18n/uk.tsv | MIT OR Apache-2.0 | Adapted interface vocabulary | | `crates/ui-egui/src/i18n/uk.rs` (37 common phrases) | WordCraft contributors | https://github.com/storytold/wordcraft/blob/7fb7b013591e2593fbd038f90bbc535be318e5a3/crates/ui-egui/src/i18n/uk.tsv | MIT OR Apache-2.0 | Adapted interface vocabulary | diff --git a/NOTICE b/NOTICE index f4e3184f6..bf76ecdc3 100644 --- a/NOTICE +++ b/NOTICE @@ -74,6 +74,22 @@ list (author, source, license) is in ASSETS.md. with or without modification, is permitted in any medium without royalty provided the copyright notice and this notice are preserved (additionally distributed under the LaTeX Project Public License in CTAN distributions). +- German hyphenation patterns, embedded through the hypher crate (feature "german"): + hyph-de-1996.tex 2024-02-28, German reformed orthography (2006), from hyph-utf8, + https://github.com/typst/hypher/blob/d81cc506416bffef2a75ee2dc969d4b41bc36613/patterns/hyph-de-1996.tex. + Copyright (c) 2013-2024 Stephan Hennig, Werner Lemberg, Günter Milde, Sander van Geloven, + Georg Pfeiffer, Gisbert W. Selke, Tobias Wendorf, Keno Wehr. MIT License: + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: The above copyright notice + and this permission notice shall be included in all copies or substantial portions of the + Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Japanese fonts (craft-fonts): builds made with craft-fonts (CRAFT_FONTS_DIR; all official releases) embed the fonts listed in https://github.com/storytold/craft-fonts/blob/main/ATTRIBUTION.md (BIZ UDPGothic, BIZ UDMincho, diff --git a/ROADMAP.md b/ROADMAP.md index 9bd0274ef..6652c7def 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -97,7 +97,7 @@ DesignCraft aims at full Adobe InDesign parity — and to be better: faster, ope - Edit ▸ Menus (`window.hideMenuItem`): hide menu items; menus with hidden items end in Show All Menu Items. - View ▸ Separations Preview (`view.separations`): one process plate as ink density, or areas over an ink limit in red (a GCR preview of the rendered view; spot plates and the flattener preview aren't there). - Separations Preview plates now come from each object's own colour (CMYK as authored; RGB and images through the colour settings, images via a cached 17³ table), so pure black shows only on the black plate. -- Language (Character panel ▸ Language, Properties ▸ Character, `type.char {language}`): text in other languages isn't hyphenated or spell-checked with the English dictionaries, typographer's quotes follow the language (German „…“, French and Russian «…», Swiss, Spanish, Dutch, Nordic, Japanese and Traditional Chinese 「…」, Simplified Chinese “…”), the font's localized forms (OpenType `locl`: Turkish i, Bulgarian Cyrillic, Japanese / Chinese / Korean glyph variants) follow it too, and so does the fallback for CJK characters the font lacks (with Draw Missing Glyphs from Fallback Fonts on): Japanese, Simplified Chinese, Traditional Chinese and Korean each try their own installed system fonts (Japanese starts with the craft-fonts Japanese faces, Mincho first, when built with them; Hangul, kana and Bopomofo pick their language's fonts whatever the language). Language names from IDML keep their spelling; locale codes as InDesign writes them for some languages (`de_DE_2006`, `nl_NL_2005`; any `ll`, `ll_CC`, `ll-CC`) are their language and region for all of the above, and Chinese is also recognised in its common spellings ("Simplified Chinese", "Chinese (Traditional)", `zh_CN`, `zh-Hant`). Spanish is hyphenated with Javier Bezos's Liang patterns (`hyph-es.tex` 5.0, MIT) through the `hypher` crate; hyphenation for other languages isn't bundled yet. +- Language (Character panel ▸ Language, Properties ▸ Character, `type.char {language}`): text in other languages isn't hyphenated or spell-checked with the English dictionaries, typographer's quotes follow the language (German „…“, French and Russian «…», Swiss, Spanish, Dutch, Nordic, Japanese and Traditional Chinese 「…」, Simplified Chinese “…”), the font's localized forms (OpenType `locl`: Turkish i, Bulgarian Cyrillic, Japanese / Chinese / Korean glyph variants) follow it too, and so does the fallback for CJK characters the font lacks (with Draw Missing Glyphs from Fallback Fonts on): Japanese, Simplified Chinese, Traditional Chinese and Korean each try their own installed system fonts (Japanese starts with the craft-fonts Japanese faces, Mincho first, when built with them; Hangul, kana and Bopomofo pick their language's fonts whatever the language). Language names from IDML keep their spelling; locale codes as InDesign writes them for some languages (`de_DE_2006`, `nl_NL_2005`; any `ll`, `ll_CC`, `ll-CC`) are their language and region for all of the above, and Chinese is also recognised in its common spellings ("Simplified Chinese", "Chinese (Traditional)", `zh_CN`, `zh-Hant`). English, Spanish, Portuguese, Norwegian, Greek and German (2006 reform) hyphenate. German uses `hyph-de-1996.tex` 2024-02-28 (MIT) through `hypher`; the filename denotes the reformed 2006 rules. Other languages have no bundled patterns. - Books (`book.new/open/add/remove/list/styleSource/paginate/syncStyles/exportPdf`, Book panel): `.dcbook` files, continuous page numbering, style sync from a style source, one merged PDF. - Track Changes (`changes.track/list/acceptAll/rejectAll`, Type ▸ Track Changes): typing is marked added (highlighted on screen), deletions are kept but hidden from layout and exports until accepted or rejected. Per-change accept/reject and authors aren't there yet. - Track Changes: per-change Accept / Reject (`changes.accept`, `changes.reject`) and a Track Changes panel listing every change. @@ -348,6 +348,8 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m Newest first. +- **2026-10-18** · German text hyphenates using the MIT-licensed 2006 reform patterns (`hyph-de-1996.tex`) through `hypher`. Language names and locale codes reach both composers; tests cover umlauts, ß, compounds, reformed ck/st breaks and paragraph limits. Six of InDesign's ~40 hyphenation languages. No readiness percentage change. + - **2026-10-16** · Threading: the loaded text cursor threads into a text frame inside a group (it hit the group and showed it could not thread); a plain click still selects the group (#1075). Gap 27 closed. No readiness percentage change. - **2026-10-16** · Greek text hyphenates. The patterns were never compiled in, so Greek set unhyphenated however narrow the column; `"Greek"`, `"Greek: Greece"`, `el` and `el-GR` all resolve now and ανθρωπος breaks αν-θρω-πος. They are the monotonic patterns (hyph-el-monoton, Dimitrios Filippou, under MIT), which is what polytonic text hyphenates by too. Five of InDesign's ~40 hyphenation languages. No readiness percentage change. - **2026-10-16** · A swatch applied to a placed greyscale or bitmap image colours it, as in InDesign: IDML's `` is read and written, greyscale pixels become a tint of the swatch on opaque white and a bitmap's white lets the frame show through, on screen and in PDF (spot swatches print on their plate). Colour images keep their colours. Applying the swatch from the Swatches panel comes next. No readiness percentage change. diff --git a/crates/compose/Cargo.toml b/crates/compose/Cargo.toml index b7017f80f..2e9334b65 100644 --- a/crates/compose/Cargo.toml +++ b/crates/compose/Cargo.toml @@ -21,7 +21,7 @@ log = { workspace = true } regex = { workspace = true } fancy-regex = { workspace = true } miniz_oxide = "0.8" -hypher = { version = "0.1.8", default-features = false, features = ["alloc", "greek", "portuguese", "spanish", "norwegian"] } +hypher = { version = "0.1.8", default-features = false, features = ["alloc", "german", "greek", "portuguese", "spanish", "norwegian"] } [dev-dependencies] designcraft-fonts = { workspace = true, features = ["testing"] } diff --git a/crates/compose/src/hyphen/mod.rs b/crates/compose/src/hyphen/mod.rs index 57b75d63b..a3b2156cd 100644 --- a/crates/compose/src/hyphen/mod.rs +++ b/crates/compose/src/hyphen/mod.rs @@ -6,6 +6,9 @@ //! Greek is `hyph-el-monoton.tex` 5.0 from hyph-utf8 (Dimitrios Filippou), LPPL or MIT, taken //! under MIT. Those are the **monotonic** patterns, which is what `hypher` maps `el` to, so //! polytonic text hyphenates by them as well. +//! German uses `hyph-de-1996.tex` (2024-02-28, Deutschsprachige Trennmustermannschaft, MIT): +//! despite the filename, these are the reformed 2006 spelling patterns. All German language +//! names and locale codes resolve to this set; no separate old-spelling or Swiss set is bundled. //! //! English lookup order for each word: //! 1. the **dictionary** ([`Dictionary::en_us`]) — the public-domain Moby Hyphenator II word list @@ -379,6 +382,41 @@ mod tests { assert!(hyphen_points("typography", &lim).is_empty()); } + #[test] + fn german_2006_uses_reformed_patterns() { + let de = Lang::for_language("German: 2006 Reform").unwrap(); + assert_eq!(de, Lang::Patterns(hypher::Lang::German)); + for name in ["German", "$ID/German: 2006 Reform", "de", "de-DE", "de_AT", "de_DE_2006", "German: Swiss 2006 Reform", "de_CH_2006"] { + assert_eq!(Lang::for_language(name), Some(de), "{name}"); + } + for (word, expected) in [ + ("Silbentrennung", "Sil-ben-tren-nung"), + ("Zucker", "Zu-cker"), + ("Bäcker", "Bä-cker"), + ("Fenster", "Fens-ter"), + ("Straße", "Stra-ße"), + ("Fußgänger", "Fuß-gän-ger"), + ("Donaudampfschifffahrt", "Do-nau-dampf-schiff-fahrt"), + ("SILBENTRENNUNG", "SIL-BEN-TREN-NUNG"), + ] { + let pts = hyphen_points_in(word, &Limits::default(), de); + let actual: String = word.chars().enumerate().map(|(i, c)| if pts.contains(&i) { format!("-{c}") } else { c.to_string() }).collect(); + assert_eq!(actual, expected, "{word}"); + } + } + + #[test] + fn german_2006_respects_paragraph_limits() { + let de = Lang::for_language("de_DE_2006").unwrap(); + let lim = Limits { after_first: 4, before_last: 5, ..Limits::default() }; + assert_eq!(hyphen_points_in("Silbentrennung", &lim, de), vec![6]); + let lim = Limits { min_word: 15, ..Limits::default() }; + assert!(hyphen_points_in("Silbentrennung", &lim, de).is_empty()); + let lim = Limits { capitalized: false, ..Limits::default() }; + assert!(hyphen_points_in("Silbentrennung", &lim, de).is_empty()); + assert!(!hyphen_points_in("silbentrennung", &lim, de).is_empty()); + } + #[test] fn spanish_uses_the_bezos_patterns() { let es = Lang::for_language("Spanish").unwrap(); diff --git a/crates/compose/src/tests.rs b/crates/compose/src/tests.rs index 9d8f6be70..375768cbe 100644 --- a/crates/compose/src/tests.rs +++ b/crates/compose/src/tests.rs @@ -3833,6 +3833,36 @@ fn empty_paragraph_uses_its_own_mark_not_the_previous_one() { assert!((lines[1].baseline - lines[0].baseline - 8.0).abs() < 1e-6, "{} {}", lines[0].baseline, lines[1].baseline); } +#[test] +fn german_2006_text_gets_german_hyphenation() { + let text = "Silbentrennung Fußgänger Bäcker Fenster Donaudampfschifffahrt Silbentrennung"; + let de = hyphen::Lang::for_language("German: 2006 Reform").unwrap(); + for composer in [Composer::Paragraph, Composer::SingleLine] { + for language in ["German: 2006 Reform", "de_DE_2006"] { + let para = ParaAttrs { composer: Some(composer), ..Default::default() }; + let (mut d, sid, _) = doc_with(text, Rect::new(36.0, 36.0, 96.0, 700.0), para); + d.story_mut(sid).unwrap().format_chars(0..text.len(), |f| f.over.language = Some(language.into())); + let cs = compose_story(&d, sid, &ComposeOptions::default()); + assert!(!cs.is_overset(), "{composer:?}, {language}"); + let lines = all_lines(&cs); + assert!(lines.iter().any(|l| l.hyphenated), "{composer:?}, {language}: German text hyphenates"); + for line in lines.iter().filter(|l| l.hyphenated) { + // Check the actual character offset in the original word, including when the + // word spans more than two lines; UTF-8 byte offsets must not become char counts. + let end = line.range.end; + let start = text[..end].rfind(' ').map_or(0, |at| at + 1); + let word = text[start..].split_whitespace().next().unwrap(); + let point = text[start..end].chars().count(); + assert!(hyphen::hyphen_points_in(word, &hyphen::Limits::default(), de).contains(&point), "{word} at {point}"); + } + // The existing paragraph switch must still disable automatic German hyphenation. + d.story_mut(sid).unwrap().format_paras(0..text.len(), |f| f.para.hyphenate = Some(false)); + let cs = compose_story(&d, sid, &ComposeOptions::default()); + assert!(all_lines(&cs).iter().all(|l| !l.hyphenated)); + } + } +} + #[test] fn spanish_text_gets_spanish_hyphenation() { let text = "La transición democrática fue una construcción colectiva extraordinariamente compleja y desesperadamente necesaria."; diff --git a/docs/gaps.md b/docs/gaps.md index 2e9c57b39..d7e62f6b3 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -1,6 +1,6 @@ # Where DesignCraft falls short of InDesign -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-16 · **Change:** minor (gap 27 closed: the loaded text cursor threads into a frame inside a group (#1075); .indd and .indt open through indd-utils; gap 0 shrunk: text threads by hand; threading gaps added; Optical kerning from outlines (#181); gap 6: macOS lists fonts that font services and managers activate; shared print spooler; image clipping paths from IDML; Tabs panel listed as present (#343); book chapter update safety; gap 16: Based on Parent leftovers; bounded control click/drag input; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-18 · **Change:** minor (German 2006 hyphenation; gap 27 closed: the loaded text cursor threads into a frame inside a group (#1075); .indd and .indt open through indd-utils; gap 0 shrunk: text threads by hand; threading gaps added; Optical kerning from outlines (#181); gap 6: macOS lists fonts that font services and managers activate; shared print spooler; image clipping paths from IDML; Tabs panel listed as present (#343); book chapter update safety; gap 16: Based on Parent leftovers; bounded control click/drag input; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6) Every known shortfall against InDesign 2026, one entry each, ranked by how much it stops an InDesign professional from doing real work. This is the work list: agents pick from the top. @@ -143,7 +143,7 @@ Kind: **F** feature · **U** UI/UX · **T** typography · **FF** file format · - **Estimate:** 25–40 h. ### 13. Hyphenation and spelling languages (T, L) -- **Missing:** hyphenation patterns for every language but English, Spanish, Portuguese, Norwegian and Greek; spelling for +- **Missing:** hyphenation patterns for every language but English, Spanish, Portuguese, Norwegian, Greek and German (2006 reform); spelling for every language but English. InDesign ships dictionaries for ~40 languages. - **Estimate:** 30–60 h (permissively licensed patterns exist for most; spelling word lists need licence review). **Doc:** [typography-parity.md](typography-parity.md) diff --git a/docs/localization-parity.md b/docs/localization-parity.md index fa75a20d8..9fe3b3319 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-14 · **Change:** minor (Polish and Georgian interfaces; catalog counts remain the 2026-10-10 measurement) · **Target:** Adobe InDesign 2026 (21.6) +> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-18 · **Change:** minor (German 2006 hyphenation; Polish and Georgian interfaces; catalog counts remain the 2026-10-10 measurement) · **Target:** Adobe InDesign 2026 (21.6) Per-language status of the DesignCraft interface and of document typesetting in each script. Script-specific typesetting detail: [cjk.md](cjk.md), [cjk-typography.md](cjk-typography.md), @@ -36,7 +36,7 @@ come as Middle East editions with an English or French interface and right-to-le | Portuguese (Brazil) | pt-br | ✓ (pt) | 1,057 (61%) | menus, panels, some dialogs; no help | Latin ✓; Portuguese hyphenation ✓ | no | partial | 8–12 | | Indonesian | id | ✗ | 0 (0%) | none | Latin ✓ | no | none | 12–18 | | Japanese | ja | ✓ | 1,644 (95%) | whole interface (#272), vertical-type commands; no help | vertical text, kinsoku, aki, ruby, warichu ✓ (partial depth, cjk.md); canvas IME ✓, not checked by hand (#322); Japanese UI and Mincho fonts from craft-fonts | no | partial | 6–10 (+ IME checks, shared with zh) | -| German | de | ✓ | 1,438 (83%) | menus, panels, most dialogs; no help | Latin ✓; no German hyphenation (InDesign ships 2006 reform patterns) | no | partial | 6–10 | +| German | de | ✓ | 1,438 (83%) | menus, panels, most dialogs; no help | Latin ✓; German 2006 hyphenation ✓ (hyph-de-1996, MIT) | no | partial | 6–10 | | Korean | ko | ✓ | 0 (0%) | none | Korean line breaking at spaces ✓; canvas IME ✓, not checked by hand (#322) | no | none | 15–25 | | Vietnamese | vi | ✗ | 0 (0%) | none | Latin with stacked diacritics via harfrust, untested | no | none | 12–18 | @@ -64,7 +64,7 @@ eight of the twelve (cs, da, el, en_GB, fi, hu, it, nb, nl, pl, ro, ru, sq, sv, ## Document languages InDesign 2026 hyphenates and spell-checks ~40 languages (Hunspell and Duden dictionaries). -DesignCraft hyphenates **English, Spanish, Portuguese and Norwegian** and spell-checks **English** only. Text language +DesignCraft hyphenates **English, Spanish, Portuguese, Norwegian, Greek and German (2006 reform)** and spell-checks **English** only. Text language can be set per paragraph and character (Properties, Character panel) and drives quotes and locale shaping. See [typography-parity.md](typography-parity.md). diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 4a7e9b99f..4577033cb 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -1,6 +1,6 @@ # DesignCraft parity with Adobe InDesign -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-16 · **Change:** minor (File ▸ Open Recent; .indd and .indt open through indd-utils; text threads by hand; image clipping paths from IDML; anchored objects wrap text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; recovery checkpoint retention; cancelable macOS Dock Quit; Based on Parent; object styles carry effects; colour management on craft-cms, Coated FOGRA39 default CMYK; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6.0.57, macOS) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-18 · **Change:** minor (German 2006 hyphenation; File ▸ Open Recent; .indd and .indt open through indd-utils; text threads by hand; image clipping paths from IDML; anchored objects wrap text; Tabs panel listed as present (#343); spring-loaded Zoom navigation; recovery checkpoint retention; cancelable macOS Dock Quit; Based on Parent; object styles carry effects; colour management on craft-cms, Coated FOGRA39 default CMYK; swatches on placed greyscale and bitmap images) · **Target:** Adobe InDesign 2026 (21.6.0.57, macOS) The authoritative assessment of how close DesignCraft is to Adobe InDesign. [ROADMAP.md](../ROADMAP.md) summarizes it; [gaps.md](gaps.md) lists every known shortfall one at a time; the feature-by-feature @@ -59,7 +59,7 @@ they receive, setting type exactly, and basic editing that never fails. | Dimension | Weight | Ready | Remaining (Opus 5.5 h) | Evidence | Doc | |---|---|---|---|---|---| | Features (depth of each area) | 25% | 55% | 250–400 | 275 catalogue rows exist; many lack options (e.g. Books is 258 lines of engine code, Liquid Layout 329); see the area table | this file | -| Typography and composition fidelity | 15% | 45% | 120–200 | Knuth–Plass composer, keeps, grids, CJK, Arabic all exist; no comparison with InDesign's line breaks; optical kerning falls back to metrics (#181); overset rule differs (#180); hyphenation patterns for English, Spanish, Portuguese, Norwegian and Greek only | [typography-parity.md](typography-parity.md) | +| Typography and composition fidelity | 15% | 45% | 120–200 | Knuth–Plass composer, keeps, grids, CJK, Arabic all exist; no comparison with InDesign's line breaks; optical kerning falls back to metrics (#181); overset rule differs (#180); hyphenation patterns for English, Spanish, Portuguese, Norwegian, Greek and German 2006 only | [typography-parity.md](typography-parity.md) | | File formats | 20% | 40% | 150–250 (+10–30 for an INDD corpus) | INDD and INDT open through indd-utils, measured on synthetic bytes only (#21); IDML both ways and verified in InDesign 2026, but real-file bugs open (#193, #338, #339, #340); PDF export strong; PDF/X-4 only | [file-format-parity.md](file-format-parity.md) | | UI/UX fidelity | 15% | 45% | 120–180 | Measured InDesign 2026 look; but users report object copy/paste (#351, #348, #185, #164), right-click menus (#238, #187, #160), out-port threading (#352, #194, #165) failing | [ui-parity.md](ui-parity.md) | | Stability | 10% | 45% | 60–100 | Never-crash rules and last-resort guards; startup failures on some GPUs and machines (#334, #273, #220, #192, #167, #166); no CI runs the tests on pull requests | [gaps.md](gaps.md) | @@ -355,7 +355,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level - Edit ▸ Menus (`window.hideMenuItem`): hide menu items; menus with hidden items end in Show All Menu Items. - View ▸ Separations Preview (`view.separations`): one process plate as ink density, or areas over an ink limit in red (a GCR preview of the rendered view; spot plates and the flattener preview aren't there). - Separations Preview plates now come from each object's own colour (CMYK as authored; RGB and images through the colour settings, images via a cached 17³ table), so pure black shows only on the black plate. -- Language (Character panel ▸ Language, Properties ▸ Character, `type.char {language}`): text in other languages isn't hyphenated or spell-checked with the English dictionaries, typographer's quotes follow the language (German „…“, French and Russian «…», Swiss, Spanish, Dutch, Nordic, Japanese and Traditional Chinese 「…」, Simplified Chinese “…”), the font's localized forms (OpenType `locl`: Turkish i, Bulgarian Cyrillic, Japanese / Chinese / Korean glyph variants) follow it too, and so does the fallback for CJK characters the font lacks (with Draw Missing Glyphs from Fallback Fonts on): Japanese, Simplified Chinese, Traditional Chinese and Korean each try their own installed system fonts (Japanese starts with the craft-fonts Japanese faces, Mincho first, when built with them; Hangul, kana and Bopomofo pick their language's fonts whatever the language). Language names from IDML keep their spelling; locale codes as InDesign writes them for some languages (`de_DE_2006`, `nl_NL_2005`; any `ll`, `ll_CC`, `ll-CC`) are their language and region for all of the above, and Chinese is also recognised in its common spellings ("Simplified Chinese", "Chinese (Traditional)", `zh_CN`, `zh-Hant`). Spanish is hyphenated with Javier Bezos's Liang patterns (`hyph-es.tex` 5.0, MIT), Portuguese with hyph-utf8's `hyph-pt.tex` 1.4 (BSD-3-Clause) and Norwegian with hyph-utf8's `hyph-no.tex` (permissive), all through the `hypher` crate; hyphenation for other languages isn't bundled yet. +- Language (Character panel ▸ Language, Properties ▸ Character, `type.char {language}`): text in other languages isn't hyphenated or spell-checked with the English dictionaries, typographer's quotes follow the language (German „…“, French and Russian «…», Swiss, Spanish, Dutch, Nordic, Japanese and Traditional Chinese 「…」, Simplified Chinese “…”), the font's localized forms (OpenType `locl`: Turkish i, Bulgarian Cyrillic, Japanese / Chinese / Korean glyph variants) follow it too, and so does the fallback for CJK characters the font lacks (with Draw Missing Glyphs from Fallback Fonts on): Japanese, Simplified Chinese, Traditional Chinese and Korean each try their own installed system fonts (Japanese starts with the craft-fonts Japanese faces, Mincho first, when built with them; Hangul, kana and Bopomofo pick their language's fonts whatever the language). Language names from IDML keep their spelling; locale codes as InDesign writes them for some languages (`de_DE_2006`, `nl_NL_2005`; any `ll`, `ll_CC`, `ll-CC`) are their language and region for all of the above, and Chinese is also recognised in its common spellings ("Simplified Chinese", "Chinese (Traditional)", `zh_CN`, `zh-Hant`). Spanish is hyphenated with Javier Bezos's Liang patterns (`hyph-es.tex` 5.0, MIT), Portuguese with hyph-utf8's `hyph-pt.tex` 1.4 (BSD-3-Clause) and Norwegian with hyph-utf8's `hyph-no.tex` (permissive), all through the `hypher` crate; Greek uses `hyph-el-monoton.tex` (MIT). German uses hyph-utf8's `hyph-de-1996.tex` 2024-02-28 (MIT), which contains the reformed 2006 patterns despite its filename. German names and locale codes (including `German: 2006 Reform` and `de_DE_2006`) use this set; no separate old-spelling or Swiss set is bundled. Hyphenation for other languages isn't bundled yet. - Books (`book.new/open/add/remove/list/styleSource/paginate/syncStyles/exportPdf`, Book panel): `.dcbook` files, continuous page numbering, chapter numbers resolved in book order (Automatic, Start Chapter Numbering at, Same as Previous Document; `layout.chapterNumbering`, with a style for Chapter Number variables and cross-references), style sync from a style source, one merged PDF. Section prefixes follow InDesign's rule (up to 8 characters, no + or comma). - Numbering & Section Options window as in InDesign (Start Section, automatic or explicit page numbering up to 99999, prefix, style, marker, Include Prefix; the document's chapter numbering and its book); OK applies both in one undo step (`layout.numberingOptions`). - Book numbering/style updates validate and serialize all targets before changing the first chapter. They write only closed native chapters, checking canonical paths for open aliases; IDML remains a read-only style source and PDF input. Snapshots are staged on disk with at most 4,096 chapter records in memory. Each replacement is atomic; a later write failure explicitly lists completed chapters rather than claiming whole-book rollback. Import/serialization memory limits and advanced book TOC/index work remain separate. diff --git a/docs/typography-parity.md b/docs/typography-parity.md index b97ec6512..134f97fed 100644 --- a/docs/typography-parity.md +++ b/docs/typography-parity.md @@ -1,6 +1,6 @@ # Typography and composition parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate; Justification dialog for the selected paragraphs; anchored objects wrap text; Tabs panel listed as present (#343); character stroke behind fill) · **Target:** Adobe InDesign 2026 (21.6) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-18 · **Change:** minor (German 2006 hyphenation; Optical kerning from outlines (#181); macOS lists fonts that font services and managers activate; Justification dialog for the selected paragraphs; anchored objects wrap text; Tabs panel listed as present (#343); character stroke behind fill) · **Target:** Adobe InDesign 2026 (21.6) Typesetting is what InDesign is bought for. A feature can exist and still set text differently from InDesign: different line breaks, different page count, overset where InDesign fits. This @@ -36,7 +36,7 @@ Fidelity: **unmeasured** unless stated. | Single-line Composer | greedy | greedy with the same ranges | ✓ | | | World-Ready composers | Paragraph / Single-line World-Ready | RTL, Arabic and bidi in the main composer | ~ | Indic scripts (Devanagari etc.) shape through harfrust but are untested | | Justification | word/letter spacing, glyph scaling min/desired/max, single-word, last line | all of these | ✓ | a justified line with a tab justifies after the tab (#284); set per paragraph in Type › Justification… and the Paragraph panel menu (#531) | -| Hyphenation | per-language dictionaries (~40), zone, limits, capitalized, last word, across columns | Liang patterns: English (trained from the public-domain Moby list), Spanish (Bezos), Portuguese (hyph-pt), Norwegian (hyph-no) and Greek (hyph-el-monoton); zone, limits, exceptions in the user dictionary | ~ | other languages don't hyphenate (#87 reported "doesn't work") | +| Hyphenation | per-language dictionaries (~40), zone, limits, capitalized, last word, across columns | Liang patterns: English (trained from the public-domain Moby list), Spanish (Bezos), Portuguese (hyph-pt), Norwegian (hyph-no), Greek (hyph-el-monoton) and German 2006 (hyph-de-1996); zone, limits, exceptions in the user dictionary | ~ | other languages don't hyphenate (#87 reported "doesn't work") | | Spelling | per-language dictionaries | English (Moby) + document/user dictionary | ~ | | | Kerning | Metrics, Optical, manual, none | Metrics, Optical (outline-based: pairs pulled towards the font's stem gap, `crates/compose/src/optical.rs`), manual, none | ~ | Optical is an approximation of Adobe's algorithm (#181), not a match: imported display text can still break differently | | Tracking, scale, skew, baseline shift | ✓ | ✓ | ✓ | |