From acf6f7973920d3c5cd5272a6bd3bd5eaa9699717 Mon Sep 17 00:00:00 2001 From: aiongg Date: Sun, 25 Oct 2026 19:08:20 +0000 Subject: [PATCH 1/3] craft-text: hyphenation, line-break segmentation, bidi and line breaking --- ATTRIBUTION.md | 4 + Cargo.lock | 49 + Cargo.toml | 1 + NOTICE | 39 + README.md | 3 + crates/text/Cargo.toml | 154 ++ crates/text/README.md | 310 ++++ crates/text/assets/hyphen/en-us.dic | Bin 0 -> 432905 bytes crates/text/assets/hyphen/en-us.pat | 1633 ++++++++++++++++++++++ crates/text/examples/hyphgen.rs | 174 +++ crates/text/src/bidi/mod.rs | 367 +++++ crates/text/src/bidi/tests.rs | 254 ++++ crates/text/src/hyphen/dict.rs | 159 +++ crates/text/src/hyphen/mod.rs | 463 ++++++ crates/text/src/hyphen/patgen.rs | 251 ++++ crates/text/src/hyphen/patterns.rs | 241 ++++ crates/text/src/hyphen/tests.rs | 356 +++++ crates/text/src/lib.rs | 25 + crates/text/src/linebreak/greedy.rs | 108 ++ crates/text/src/linebreak/knuth_plass.rs | 223 +++ crates/text/src/linebreak/mod.rs | 637 +++++++++ crates/text/src/linebreak/tests.rs | 476 +++++++ crates/text/src/segment/complex.rs | 50 + crates/text/src/segment/kinsoku.rs | 119 ++ crates/text/src/segment/mod.rs | 164 +++ crates/text/src/segment/tests.rs | 242 ++++ 26 files changed, 6502 insertions(+) create mode 100644 crates/text/Cargo.toml create mode 100644 crates/text/README.md create mode 100644 crates/text/assets/hyphen/en-us.dic create mode 100644 crates/text/assets/hyphen/en-us.pat create mode 100644 crates/text/examples/hyphgen.rs create mode 100644 crates/text/src/bidi/mod.rs create mode 100644 crates/text/src/bidi/tests.rs create mode 100644 crates/text/src/hyphen/dict.rs create mode 100644 crates/text/src/hyphen/mod.rs create mode 100644 crates/text/src/hyphen/patgen.rs create mode 100644 crates/text/src/hyphen/patterns.rs create mode 100644 crates/text/src/hyphen/tests.rs create mode 100644 crates/text/src/lib.rs create mode 100644 crates/text/src/linebreak/greedy.rs create mode 100644 crates/text/src/linebreak/knuth_plass.rs create mode 100644 crates/text/src/linebreak/mod.rs create mode 100644 crates/text/src/linebreak/tests.rs create mode 100644 crates/text/src/segment/complex.rs create mode 100644 crates/text/src/segment/kinsoku.rs create mode 100644 crates/text/src/segment/mod.rs create mode 100644 crates/text/src/segment/tests.rs diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 20de9c8b..a6493818 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -10,6 +10,10 @@ author, source and license. Library code and original assets are under the repos | `crates/cms/profiles/craft-coated-fogra39.icc` | craft-libs contributors; generated by `crates/cms/tests/fogra39.rs` from the FOGRA39 data below | this repository | CC0-1.0 | | `crates/cms/tests/data/FOGRA39.txt` (unmodified) | Fogra | [Fogra characterisation data](https://fogra.org/en/downloads/work-tools/characterisation-data), `FOGRA39_to_FOGRA60_v2.zip` | Fogra terms: free use and redistribution, unmodified, with Fogra identified as the source; "FOGRA39" identifies the reference data only and implies no certification, approval or endorsement by Fogra (full text in [NOTICE](NOTICE)) | | `crates/i18n/data/collation.postcard` | Unicode, Inc. (ICU 78.1 collation data, CLDR 48.2.1); generated by `crates/i18n/data/generate-collation.sh` | [ICU](https://github.com/unicode-org/icu/releases/tag/release-78.1rc) | Unicode-3.0 | +| `crates/text/assets/hyphen/en-us.dic` | Grady Ward (Moby Hyphenator II), converted by DesignCraft | [Project Gutenberg eBook #3204](https://www.gutenberg.org/ebooks/3204) | Public domain | +| `crates/text/assets/hyphen/en-us.pat` | DesignCraft contributors, trained from the Moby Hyphenator II list | `crates/text/examples/hyphgen.rs` | CC0-1.0 | +| Patterns embedded through `hypher` (optional `craft-text` language features) | hyph-utf8 authors, per language | [tex-hyphen](https://github.com/hyphenation/tex-hyphen), as packaged in [hypher](https://github.com/typst/hypher/tree/main/patterns) | Per file header: LPPL, MIT, BSD-3-Clause, Unlicense or a permit-any-use notice (or a choice including one); Slovak (`hyph-sk.tex`, feature `slovak-gpl` only) is GPL-2.0-or-later; Spanish (`hyph-es.tex` 5.0, Javier Bezos, CervanTeX) is MIT | +| Word-break dictionaries and LSTM models embedded through `icu_segmenter_data` (optional `craft-text` features `thai`, `lao`, `khmer`, `burmese`) | Unicode, Inc. and ICU4X contributors | [ICU4X](https://github.com/unicode-org/icu4x) | Unicode-3.0 | Original assets are covered by the repository licence. diff --git a/Cargo.lock b/Cargo.lock index 70c29ac2..29056e69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -928,6 +928,20 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "craft-text" +version = "0.1.0" +dependencies = [ + "hypher", + "icu_segmenter", + "miniz_oxide 0.8.9", + "unicode-bidi", + "unicode-bidi-mirroring", + "unicode-general-category", + "unicode-linebreak", + "unicode-segmentation", +] + [[package]] name = "craft-ui" version = "0.1.0" @@ -2235,6 +2249,12 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "hypher" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f2b4f6b5da34d400d4c112eadcc14512cc5d04307a8eee182586d9bebd7ce6" + [[package]] name = "iana-time-zone" version = "0.1.65" @@ -2457,6 +2477,29 @@ dependencies = [ "zerovec", ] +[[package]] +name = "icu_segmenter" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d07aafccd67af15d02512a6adf5896fbc5ed00f2e99b471d2efa14016db3db" +dependencies = [ + "core_maths", + "icu_collections", + "icu_locale_fallback", + "icu_provider", + "icu_segmenter_data", + "potential_utf", + "smallvec", + "utf8_iter", + "zerovec", +] + +[[package]] +name = "icu_segmenter_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae293c039020f9ec10710af98d29ce6aa2051486638b49c9a6409f3b4a9e98ad" + [[package]] name = "idna" version = "1.1.0" @@ -5438,6 +5481,12 @@ version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.25" diff --git a/Cargo.toml b/Cargo.toml index 0feef09b..40473a05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ craft-prepress = { path = "crates/prepress" } craft-print = { path = "crates/print" } craft-quit = { path = "crates/quit" } craft-settings = { path = "crates/settings" } +craft-text = { path = "crates/text" } craft-ui = { path = "crates/ui" } craft-update = { path = "crates/update" } craft-window = { path = "crates/window" } diff --git a/NOTICE b/NOTICE index 0af05d8f..699ee37c 100644 --- a/NOTICE +++ b/NOTICE @@ -19,6 +19,38 @@ crates/cms/tests/data/FOGRA39.txt: FOGRA39 characterisation data, distributed un the data are distributed unmodified and Fogra is identified as the source. The designation FOGRAxx may be used solely to identify the respective reference data. Such use does not imply certification, approval or endorsement by Fogra." +crates/text/assets/hyphen/en-us.dic: public domain, derived from the Moby Hyphenator II list by + Grady Ward (Project Gutenberg eBook #3204). +crates/text/assets/hyphen/en-us.pat: CC0-1.0, trained from en-us.dic by DesignCraft's trainer. +Hyphenation patterns for other languages, embedded through the hypher crate only when the + matching craft-text feature is enabled (none are by default). They come from hyph-utf8, + https://github.com/hyphenation/tex-hyphen, as packaged in https://github.com/typst/hypher + (patterns/). Each file is under the license stated in its header: LPPL, MIT, BSD-3-Clause, the + Unlicense, a notice permitting any use, or a choice of licenses that includes one of these. An + application that enables a language ships that file's copyright and license notice. The + exception is Slovak (hyph-sk.tex, Copyright (C) 1992 Jana Chlebíková), under the GNU General + Public License, version 2 or later (SPDX: GPL-2.0-or-later). It is compiled in only with the + feature "slovak-gpl", which "all-languages" does not include; an application that enables it + ships GPL-licensed data. The Spanish patterns (feature "spanish") are hyph-es.tex 5.0. + Copyright (C) 1993, 1997 Javier Bezos, 2001-2019 Javier Bezos, CervanTeX. 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. +- Word-break dictionaries and LSTM models for Thai, Lao, Khmer and Burmese, embedded through the + icu_segmenter_data crate only when craft-text's "thai", "lao", "khmer" or "burmese" feature is + enabled (none are by default). From ICU4X, https://github.com/unicode-org/icu4x. + Copyright (c) 2020-2024 Unicode, Inc. Unicode License v3 (SPDX: Unicode-3.0); portions adapted + from ICU4C, (c) 1995-2016 International Business Machines Corporation and others. An + application that enables one of these features ships the Unicode License v3 copyright and + permission notice, https://www.unicode.org/license.txt. The optional PDF writer bundles four CC0 ICC profiles by Clinton Ingram. See ATTRIBUTION.md for per-file sources and hashes. @@ -53,6 +85,13 @@ The transactional panel model and drop-zone semantics in crates/ui/src/docking d FilmCraft/EffectCraft split, tab and accordion layouts and VectorCraft floating groups listed above. The generic transaction validation, optional renderer and workspace-location helpers are implemented here without dependencies on application engines or native window helpers. +The hyphenation code, data and generator in crates/text (src/hyphen/, assets/hyphen/ and +examples/hyphgen.rs) are adapted from: +- DesignCraft, crates/compose/src/hyphen/, crates/compose/examples/hyphgen.rs and + assets/hyphenation/, revision e161878e4c7744fa06f9a2eede8103cb4c296355 (above). +- WordCraft, crates/proof/src/hyphen.rs, revision e4b7d155f15a7784197ba34eeea0b54490d70eb2. + https://github.com/storytold/wordcraft + Copyright (c) 2026 ArtCraft Team and the WordCraft contributors. All sources listed above are licensed MIT OR Apache-2.0. No icon artwork is copied here. The PDF spooler in crates/print is extracted from: diff --git a/README.md b/README.md index 9ec49a2a..c49e452a 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,9 @@ craft- = { git = "https://github.com/storytold/craft-libs", rev = " Vec { + match Lang::for_language(language) { + Some(lang) => hyphen_points_in(word, &Limits::default(), lang), + None => Vec::new(), // unknown language or feature off: don't hyphenate + } +} +``` + +`Lang::for_language` accepts English language names as InDesign and IDML write them (`Spanish`, +`German: 2006 Reform`, `$ID/Norwegian: Bokmal`) and locale codes (`es`, `es_ES`, `pt-BR`, +`de_DE_2006`). It returns `None` for unknown languages and for languages not compiled in. +`Lang` is `Copy + Eq + Hash`, so it can key a cache of computed points. Its `Patterns` variant +holds an opaque `PatternLang`; build one with `Lang::for_language`. + +### Limits + +`Limits` holds the paragraph's settings: minimum word length, letters before the first and after +the last hyphen, and whether capitalized words are hyphenated. Words in all capitals are never +hyphenated. Limit checks are linear in word length. + +### Regenerating the English data + +`examples/hyphgen.rs` rebuilds `assets/hyphen/en-us.dic` and `assets/hyphen/en-us.pat` from the +Moby list. It needs the `generator` feature, which exposes the dictionary writer (`hyphen::dict`) +and the pattern trainer (`hyphen::patgen`); applications don't need it. + +```sh +curl -LO https://www.gutenberg.org/files/3204/files/mhyph.txt +cargo run --release -p craft-text --features generator --example hyphgen -- mhyph.txt crates/text/assets/hyphen --validate +``` + +## Segmentation + +`craft_text::segment` finds where a line may break. It takes plain text and returns byte offsets; +measuring, choosing breaks and hanging punctuation stay in each application's composer. +Consolidated from vectorcraft, wordcraft, deckcraft and designcraft. + +```rust +use craft_text::segment::{Kinsoku, Options, line_breaks}; + +let options = Options { kinsoku: Kinsoku::Soft, ..Options::default() }; +for b in line_breaks("日本語のテキスト。", &options) { + // A line may end before byte b.offset; it must if b.mandatory. +} +``` + +`line_breaks` starts from UAX #14 (the `unicode-linebreak` crate) and adjusts it: + +- `Options::kinsoku` applies the Japanese and Chinese line-start and line-end rules (JLREQ, + CLREQ) at breaks next to an East Asian character. Text with no East Asian characters gets + UAX #14's breaks unchanged. + - `Hard` (default): UAX #14's breaks, minus those kinsoku forbids. + - `Soft`: as `Hard`, and 々, ー and small kana may start a line. + - `None`: UAX #14's breaks plus a break between any two East Asian characters. +- `Options::korean_words` sets Korean word by word: no break between two Hangul letters or Han + ideographs. Off, Korean breaks between syllables as UAX #14 does. +- Mandatory breaks (newlines and the end of the text) are always kept. + +`Options::for_language(language)` gives the options for a paragraph's BCP 47 language tag, or for +an unknown language (`None`): `korean_words` for Korean, the defaults otherwise. + +When no opportunity leaves a line short enough, `emergency_breaks(text, range)` gives the places +to break the piece `text[range]` anyway: byte offsets into `text` between extended grapheme +clusters (UAX #29, through `unicode-segmentation`). An emoji ZWJ sequence, a flag or a letter with +its marks is never split. + +`kinsoku_allows(before, after, mode)` is the same rule for composers that build their own +opportunity lists. + +### Each app's kinsoku as a `Kinsoku` value + +| App | App setting | `Kinsoku` | Rules the app keeps | +| --- | --- | --- | --- | +| vectorcraft | Kinsoku set None, Hard, Soft | `None`, `Hard`, `Soft` | none | +| wordcraft | `kinsoku` on, off | `Hard`, `None` | `word_wrap` off: Latin words break at any character | +| designcraft | no set (the breaker's own rules); Hard Kinsoku | `Hard` | custom document tables, inseparable pairs, bunri-kinshi, rensuuji, roman word break | +| designcraft | Soft, Simplified Chinese, Traditional Chinese, Korean Kinsoku | `Soft` | as above | +| designcraft | Kinsoku set None | `None` | as above | + +Push-in and push-out priority and hanging punctuation decide how a line fits, not where it may +break, and stay in the composer. deckcraft has no kinsoku of its own (see below). + +### Kinsoku sets for adopters + +The sets are vectorcraft's (`no_line_start`, `soft_line_start`, `no_line_end`), plus these from +the other apps: + +- Can't start a line: 〞 (closing double prime quote), ゛ ゜ ゙ ゚ (spacing sound marks), % ¢ + (postfixed abbreviations, JLREQ cl-13). From wordcraft. +- Can't end a line: $ £ ¥ (prefixed abbreviations, JLREQ cl-12). From wordcraft. + +What changes for each app: + +- vectorcraft: the additions above. Breaks come from UAX #14 rather than "after any CJK + character", so `Hard` and `Soft` also keep every break UAX #14 forbids. Kinsoku no longer + applies between two non-East-Asian characters (a space before an en dash in Latin text may + break). +- wordcraft: its kinsoku on is `Hard`, which also keeps the prolonged sound mark, small kana, + hyphens (‐ – 〜 ゠), ‼ ⁇ ⁈ ⁉ and the Latin closing marks next to East Asian text off the line + start, and « ‘ “ ( [ { off the line end. Its kinsoku off is `None`. Breaking Latin words + anywhere (`word_wrap` off) and the no-break-after-slash rule stay in wordcraft. +- designcraft: its breaker's set is `Hard` without the additions above and without ’ ” 〛 〟 ⦆ + 〜 ~ ゠ ‐ – ‼ ⁇ ⁈ ⁉ », ゕ ゖ, ㇰ–ㇿ and the half-width forms (can't start), « ‘ “ 〚 〝 ⦅ 「 + (can't end). Its Soft set also lets ゝ ゞ ヽ ヾ 〻 start a line; here they stay forbidden, as in + InDesign's Soft set. Document kinsoku tables (`Kinsoku` in `doc/cjk.rs`) stay in designcraft. + `korean_char_breaks: false` is `korean_words: true`. +- deckcraft: `Hard` is its UAX #14 breaks minus those kinsoku forbids. `None` adds breaks between + East Asian characters, so no mode returns plain UAX #14 for East Asian text. + +### Thai, Lao, Khmer and Burmese + +UAX #14 gives these scripts class SA and leaves breaking inside them to a dictionary. Without the +script's language feature, `line_breaks` treats a run of them as one word: it never breaks inside +the run, only at its edges where UAX #14 allows a break (after a space, for example). A long Thai +sentence with no spaces is one unbreakable piece, so the composer needs an emergency break for it. +The features `thai`, `lao`, `khmer` and `burmese` split runs of that +script into words with ICU4X's segmenter (`icu_segmenter`). Any one of them links the data for all +four; the default build has no ICU data. The data is under the Unicode License v3 (see NOTICE). + +The segmenter has two models, chosen by the `lstm` feature: + +| Model | Feature | Added to a wasm32 release build | Gzipped | +| --- | --- | --- | --- | +| Dictionaries (desktop default) | none | 1.86 MB | 0.89 MB | +| LSTM models (for web) | `lstm` | 0.42 MB | 0.33 MB | + +Measured on a minimal `line_breaks` example, against the same example with `segment` alone. The +LSTM models are slower to run and split a few words differently, mostly compounds broken between +syllables (Lao ລາດ|ຊະການ, Burmese မြန်|မာ), which are still valid line breaks. +## Bidi + +`craft_text::bidi` runs the Unicode Bidirectional Algorithm (UAX #9, through +[unicode-bidi](https://crates.io/crates/unicode-bidi)) on document text. It works on plain text and +needs no fonts; shaping, glyph mirroring and caret placement stay in each application. + +The pipeline is the one UAX #9 prescribes: + +1. `Paragraph::new(text, Direction::Rtl)` resolves embedding levels once for the logical + paragraph. `Direction::Auto` takes the direction from the first strong character. + `Paragraph::with_overrides` also forces byte ranges to one direction (as LRO/RLO would), + keeping offsets into the original text. A paragraph separator (`\n`, U+2029) in the text starts + a new paragraph with its own level: `paragraphs()` lists each one's byte range and level, and + `level()` is the first one's. +2. The application shapes and breaks lines in logical order. +3. Each line is reordered on its own: `Paragraph::visual_runs(line)` returns its runs of one level + (byte range and level) left to right as displayed, with rule L1 applied (trailing whitespace, + tabs and separators at the level of the paragraph they are in). Zero-width joiners and tag + characters keep the level of the character before them, so no run splits a grapheme cluster. + A run with an odd level displays its characters from end to start. Lines should not cross a + paragraph separator. + +Lines made of other units (clusters, glyphs, cells) use the free functions on level slices: +`line_levels(chars, levels, para_level)` for rule L1 and `visual_order(levels)` for rule L2. +`mirror(c)` returns the mirrored character for rule L4 (`(` for `)`), or `None` when the font has +to supply a mirrored glyph. + +Offsets are bytes into the paragraph's `&str`: `Paragraph::levels()` holds one level per byte, +as unicode-bidi resolves them, and line ranges and runs are byte ranges. This matches the shaper +cluster offsets and line ranges the apps already keep, so no char-index table is needed; +`char_levels()` gives one level per character for code that works on `char` slices. Levels are +plain `u8` (even left to right, odd right to left), so unicode-bidi's types don't leak into +callers. + +Text with nothing right to left in a left-to-right or `Auto` paragraph skips the algorithm. + +The module started from DeckCraft's `text::bidi` (levels, rule L1 and L2 over chars). The +per-byte levels, the run-level reordering test cases and the hostile-input checks come from +WordCraft's layout; overrides and mirroring follow DesignCraft's composer. +## Line breaking + +`craft_text::linebreak` breaks paragraphs into lines on Knuth and Plass's box/glue/penalty model. +It knows nothing about fonts: the composer turns shaped glyphs into `Item`s, calls a breaker and +places the glyphs of each returned `Line`. Widths are in the caller's units, and `width(k)` gives +the measure of line `k`, so first-line indents and shaped frames work. The core comes from +vectorcraft's every-line composer; tiered justification, emergency breaks, the hyphenation zone, +greedy and balanced lines come from designcraft's breaker. + +- **Items.** Boxes, glue and penalties. Glue has a natural width and stretch and shrink in three + tiers (word space, letter space, glyph scale) that are used in that order, as in InDesign's + justification settings. Boxes may carry letter and glyph tiers too. Penalties have a cost and a + flag (hyphens); ±10 000 forbids or forces the break. `Item::fill()` before the final + `Item::forced()` leaves the last line unjustified. Optional fields, set on top of a constructor + (`Item { hang, ..Item::glue(w, st, sh) }`): `hang` (optical margin), `edge` (an `Edge` of + stretch and shrink gained at a line end or start, such as mojikumi), `hyphenation`, + `emergency`. +- **Breakers.** `knuth_plass` runs one total-fit pass. `break_paragraph` runs passes at rising + tolerances, then falls back to `greedy`; the returned `Breaks` says in `method` which one + produced the lines. `greedy_with` resolves position-dependent widths (tabs). `balanced` evens + the lines (meant for ragged text) and sets `Breaks::balanced` when it did. `overlong` finds + words wider than the measure, where the composer adds `Item::emergency()` breaks. +- **Params.** Demerits, fitness classes, tolerance, hyphen limit, tier costs, `uniform_from`, + and `Rag` for ragged text: rag stretch, short-last-line rating and hyphenation zone. + `uniform_from` is the first line index from which `width(k)` stays the same. The default 0 is + right for a constant measure; a caller with a first-line indent, drop cap or shaped frame sets + it to the first line of the constant tail, or its breaks may not be the best ones. Negative or + NaN demerits count as 0, and a NaN measure as 0. +- **Lines.** Each `Line` gives its item range, natural width, adjustment ratio, the fraction of + each tier used and the width left over, so the composer can distribute the space. + +```rust +use craft_text::linebreak::{Item, Params, Rag, break_paragraph}; + +let space = Item::glue(0.5, 0.0, 0.0); +let items = [Item::boxed(3.0), space, Item::boxed(3.0), space, Item::boxed(5.0), Item::fill(), Item::forced()]; +let ragged = Params { rag: Some(Rag::default()), ..Params::default() }; +let lines = break_paragraph(&items, &|_line| 8.0, &ragged, &[1.0, f64::INFINITY]).lines; +``` + +### Adopting + +- **vectorcraft** `composer::compose`: a box per glyph (`hang` = `start_credit(i)` for `i > 0`), + glue per space (justified: stretch 0.5 and shrink 0.2 of its width; ragged: none), a penalty per + `Breakpoint` (width = its hyphen, flagged when it has one, cost 50 justified or 25 ragged), and + `fill` + `forced` at the end unless Justify All. `Params`: `first_fitness: None`, + `max_badness: 10_000`, `fitness_demerits` 10 000 or 1 000, `fitness` bounds + `[-0.5, 0.5, 1.0]` or `[0.15, 0.4, 0.75]`, `uniform_from` as `layout.rs` computes it (the + first index from which `widths` stay at the last width); ragged adds + `Rag { stretch: 0, width_fraction: 1/6, short_last: 1/3, short_last_unit: 1/3 }`. Its two + `compose` calls become two `knuth_plass` calls (tolerance 1, then 4 or ∞); `None` still falls + back to the single-line composer. +- **designcraft** `breaker::items` builds `linebreak::Item`s: `hang`, `edge` (mojikumi + end/start elasticity), `overflow` (`space_overflow`), `hyphenation` (`auto`), `emergency`. + Ragged text uses plain spaces and `Rag { stretch: ragged_stretch, width_fraction: 0, + hyphenation_zone: hyph_zone }` instead of glue/penalty/glue triples. `Spacing` maps to + `Params { hyphen_limit, overrun: FIT_EPS, uniform_from, .. }` with `uniform_from` the number + of drop-cap lines, else 1 with a first-line indent, else 0. Kinsoku priority 1 or 2 maps + to `stretch_weight` or `shrink_weight` 4; `TIER_COST` is `tier_cost`. `knuth_plass` becomes + `overlong` + emergency items + `break_paragraph(.., &[2.5, 12.0, f64::INFINITY])`; `greedy` + becomes `greedy_with` (tabs through `advance`; `Item::no_break()` where an emergency split is + not allowed); `balanced` becomes `balanced`. Mapping lines back to glyphs + (`breaks_from_positions`) stays in the app. +- **effectcraft** `every_line`: a box per segment between line-break opportunities, glue for its + trailing whitespace, `Rag { width_fraction: 1.0, .. }`, `uniform_from: 1` (the first line's + measure differs when it is indented) and `break_paragraph(.., &[f64::INFINITY])`. + +Differences from the seeds: + +- vectorcraft: a Justify All last line is accepted at any ratio, like every line that ends at a + forced break. +- designcraft: fill glue stretches infinitely instead of by 10 000 units. In ragged text a line + ending at a forced break keeps its neighbour's fitness class. Greedy counts every flagged break + toward the hyphen limit, and splits overlong words at the composer's emergency breaks instead + of scanning for kinsoku. Past 4096 active breaks a pass fails and `break_paragraph` falls back + to greedy, reported as `Method::Greedy`. Lines before `uniform_from` (first-line indent, drop + cap) are kept apart by line number, where designcraft treats every line alike. +- effectcraft: lines are rated by Knuth's cubed ratio, not squared slack. + +## Licenses + +The word list is public domain; the trained patterns are CC0-1.0. hypher's patterns come from +hyph-utf8 under their own permissive licenses (LPPL, MPL, MIT, BSD-3); see the repository's +[NOTICE](../../NOTICE) and [ATTRIBUTION.md](../../ATTRIBUTION.md). + +## Checks + +Some tests depend on language features, so run the suite with them on: + +```sh +cargo test -p craft-text --all-features +``` diff --git a/crates/text/assets/hyphen/en-us.dic b/crates/text/assets/hyphen/en-us.dic new file mode 100644 index 0000000000000000000000000000000000000000..a09009145a91ed230ba7739bd6170cad6a041a45 GIT binary patch literal 432905 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¨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 ZDFvhl4GvE78S%`V!0Z9poR!@7?)R>d_ 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�PgV@1NofK-u6 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 z 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 String { + let high: Vec = MAC_ROMAN_HIGH.chars().collect(); + assert_eq!(high.len(), 128); + bytes.iter().map(|&b| if b < 0x80 { b as char } else { high[b as usize - 0x80] }).collect() +} + +const BREAK: char = '•'; + +fn is_word_char(c: char) -> bool { + c.is_alphabetic() || c == '\'' || c == BREAK +} + +/// `(lowercase word, mask)` of one token like `Aa•ron's`, or None if it isn't a plain word. +fn token(t: &str) -> Option<(String, u64)> { + let t = t.trim_matches('\''); + if t.is_empty() || !t.chars().all(is_word_char) || t.starts_with(BREAK) || t.ends_with(BREAK) { + return None; + } + let mut w = String::new(); + let mut m = 0u64; + let mut n = 0usize; + for c in t.chars() { + if c == BREAK { + if n < 64 { + m |= 1 << n; + } + } else { + w.extend(c.to_lowercase()); + n += 1; + } + } + ((1..64).contains(&n) && w.chars().count() == n).then_some((w, m)) +} + +fn main() { + let args: Vec = std::env::args().skip(1).collect(); + let validate = args.iter().any(|a| a == "--validate"); + let pos: Vec<&String> = args.iter().filter(|a| !a.starts_with("--")).collect(); + let Some(src) = pos.first() else { + eprintln!("usage: hyphgen [out-dir] [--validate]"); + std::process::exit(2); + }; + let out_dir = PathBuf::from(pos.get(1).map_or("crates/text/assets/hyphen", |s| s.as_str())); + let text = mac_roman(&std::fs::read(src).expect("read word list")); + + // key → (lowercase-origin masks, other masks); compound parts only fill gaps. + let mut primary: HashMap, Vec)> = HashMap::new(); + let mut parts: HashMap = HashMap::new(); + let mut entries = 0usize; + for line in text.lines() { + let line = line.trim_end_matches('\r').trim(); + if line.is_empty() { + continue; + } + entries += 1; + if let Some((w, m)) = token(line) { + let lower = !line.chars().any(char::is_uppercase); + let e = primary.entry(w).or_default(); + if lower { e.0.push(m) } else { e.1.push(m) } + } else { + for t in line.split([' ', '-', '/']) { + if let Some((w, m)) = token(t) { + parts.entry(w).or_insert(m); + } + } + } + } + let mut list: Vec<(String, u64)> = primary + .into_iter() + .map(|(w, (lower, other))| { + // Prefer lowercase entries; where spellings disagree (re•cord / rec•ord) keep only the + // breaks they share. + let v = if lower.is_empty() { other } else { lower }; + (w, v.iter().fold(u64::MAX, |a, b| a & b)) + }) + .collect(); + let have: std::collections::HashSet = list.iter().map(|x| x.0.clone()).collect(); + let extra: Vec<(String, u64)> = parts.into_iter().filter(|(w, _)| !have.contains(w)).collect(); + println!("{entries} entries → {} words (+{} from compounds)", list.len(), extra.len()); + list.extend(extra); + let dict = Dictionary::from_entries(list); + let bytes = dict.to_bytes(); + std::fs::create_dir_all(&out_dir).expect("mkdir"); + std::fs::write(out_dir.join("en-us.dic"), &bytes).expect("write en-us.dic"); + let back = Dictionary::from_bytes(&bytes).expect("roundtrip"); + assert_eq!(back.len(), dict.len()); + println!("en-us.dic: {} words, {} bytes", dict.len(), bytes.len()); + + // Training data: plain lowercase ASCII words (+ apostrophes). + let train: Vec<(Vec, Vec)> = dict + .iter() + .filter(|(w, _)| w.chars().all(|c| c.is_ascii_lowercase() || c == '\'')) + .map(|(w, m)| (w.chars().collect(), (1..w.len().min(64)).filter(|&i| m & (1 << i) != 0).collect())) + .collect(); + println!("training on {} words", train.len()); + let mut log = |s: String| println!(" {s}"); + // Optional override for tuning: HYPHGEN_LEVELS="1,4,1,2,20;2,5,2,1,8;…" (min,max,good,bad,threshold). + let custom: Option> = std::env::var("HYPHGEN_LEVELS").ok().map(|s| { + s.split(';') + .map(|l| { + let v: Vec = l.split(',').map(|x| x.trim().parse().expect("number")).collect(); + patgen::Level { min_len: v[0] as usize, max_len: v[1] as usize, good_weight: v[2], bad_weight: v[3], threshold: v[4] } + }) + .collect() + }); + let levels = custom.as_deref().unwrap_or(DEFAULT_LEVELS); + if validate { + let (fit, hold): (Vec<_>, Vec<_>) = train.iter().cloned().enumerate().partition(|(i, _)| i % 10 != 0); + let fit: Vec<_> = fit.into_iter().map(|x| x.1).collect(); + let hold: Vec<_> = hold.into_iter().map(|x| x.1).collect(); + let p = patgen::train(&fit, levels, &mut log); + let s = patgen::score(&p, &hold); + println!( + "held-out: {} words, {} breaks: found {} ({:.1}%), missed {}, wrong {} ({:.2}% of reported)", + s.words, + s.breaks, + s.found, + 100.0 * s.found as f64 / s.breaks.max(1) as f64, + s.missed(), + s.wrong, + 100.0 * s.wrong as f64 / (s.found + s.wrong).max(1) as f64 + ); + } + if std::env::var_os("HYPHGEN_VALIDATE_ONLY").is_some() { + return; + } + let pats = patgen::train(&train, levels, &mut log); + let s = patgen::score(&pats, &train); + println!( + "training set: found {}/{} ({:.1}%), wrong {} — {} patterns", + s.found, + s.breaks, + 100.0 * s.found as f64 / s.breaks.max(1) as f64, + s.wrong, + pats.len() + ); + let mut out = String::new(); + out.push_str("% Craft US English hyphenation patterns (Liang/TeX notation).\n"); + out.push_str("% Generated by crates/text/examples/hyphgen.rs: trained with craft-text's patgen-style trainer\n"); + out.push_str("% from the Moby Hyphenator II word list by Grady Ward (public domain, Project Gutenberg #3204).\n"); + out.push_str("% Released into the public domain (CC0-1.0) by the DesignCraft and craft-libs contributors.\n"); + for line in pats.to_tex().chunks(12) { + out.push_str(&line.join(" ")); + out.push('\n'); + } + std::fs::write(out_dir.join("en-us.pat"), &out).expect("write en-us.pat"); + println!("en-us.pat: {} patterns, {} bytes", pats.len(), out.len()); + for w in ["hyphenation", "typography", "composition", "photographer", "unquestionably", "localization", "blockchain", "smartphone"] { + let c: Vec = w.chars().collect(); + let m = pats.points(&c).unwrap_or_default().iter().fold(0u64, |m, &i| m | 1 << i); + println!(" patterns: {}", hyphenated(w, m)); + } +} diff --git a/crates/text/src/bidi/mod.rs b/crates/text/src/bidi/mod.rs new file mode 100644 index 00000000..39fef7d7 --- /dev/null +++ b/crates/text/src/bidi/mod.rs @@ -0,0 +1,367 @@ +//! Bidirectional text (UAX #9) for document layout, on plain text and independent of fonts. +//! +//! The pipeline is the one the algorithm prescribes: [`Paragraph::new`] resolves embedding levels +//! once for the whole logical paragraph (or for each paragraph, in text with paragraph +//! separators); shaping and line breaking happen in logical order; then each line is reordered on +//! its own. [`Paragraph::line_levels`] applies rule L1 and +//! [`Paragraph::visual_runs`] rule L2 to a byte range of the paragraph. For lines built from other +//! units (clusters, glyphs, cells), [`line_levels`] and [`visual_order`] apply the same rules to +//! slices of levels. [`mirror`] gives the character for rule L4; drawing it, or a font's mirrored +//! glyph, is left to the shaper. +//! +//! Levels are `u8` embedding levels: even runs left to right, odd runs right to left. + +use std::ops::Range; + +use unicode_bidi::BidiClass::{self, AL, AN, B, BN, FSI, LRE, LRI, LRO, PDF, PDI, R, RLE, RLI, RLO, S, WS}; +use unicode_bidi::{BidiInfo, Level, bidi_class}; + +/// A paragraph's base direction (rules P2–P3, or the higher-level protocol HL1 when set). +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub enum Direction { + /// Left to right: paragraph level 0. + Ltr, + /// Right to left: paragraph level 1. + Rtl, + /// From the first strong character, left to right when there is none. + Auto, +} + +/// A directional override (LRO or RLO … PDF) over a byte range of a paragraph: every character in +/// it is treated as strongly left to right or right to left. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Override { + pub range: Range, + pub rtl: bool, +} + +/// A maximal run of one embedding level in a line, as [`Paragraph::visual_runs`] returns it. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub struct Run { + /// Byte range in the paragraph text, in logical order. + pub range: Range, + pub level: u8, +} + +impl Run { + /// Is the run displayed right to left (its characters from the end of `range` to its start)? + pub fn is_rtl(&self) -> bool { + self.level % 2 == 1 + } +} + +/// Resolved embedding levels (rules up to I2) for a paragraph's text, one per byte. +/// +/// A paragraph separator (`\n`, U+2029 and the other class B characters) inside the text ends a +/// paragraph and belongs to it; the next one starts after it with its own paragraph level, which +/// `Direction::Auto` resolves from that paragraph's own first strong character. Rule L1 uses the +/// level of the paragraph each byte is in. +#[derive(Clone, Debug)] +pub struct Paragraph<'t> { + text: &'t str, + levels: Vec, + /// Each paragraph's byte range and level, in order and covering the text; never empty. + paragraphs: Vec<(Range, u8)>, +} + +impl<'t> Paragraph<'t> { + /// Resolve the levels of `text`. Text with nothing right to left in a left-to-right or `Auto` + /// paragraph skips the algorithm. + pub fn new(text: &'t str, base: Direction) -> Self { + if base != Direction::Rtl && !needs_bidi(text) { + let paragraphs = split_paragraphs(text).into_iter().map(|r| (r, 0)).collect(); + return Self { text, levels: vec![0; text.len()], paragraphs }; + } + let (levels, paragraphs) = resolve(text, base); + Self { text, levels, paragraphs } + } + + /// Like [`new`](Self::new), with directional overrides. Overrides that are empty, out of + /// range, off char boundaries or overlapping an earlier one are ignored. An override that + /// spans a paragraph separator continues in the next paragraph; the separator keeps its + /// paragraph's level. + pub fn with_overrides(text: &'t str, base: Direction, overrides: &[Override]) -> Self { + let mut sorted: Vec<&Override> = overrides.iter().filter(|o| o.range.start < o.range.end && text.get(o.range.clone()).is_some()).collect(); + sorted.sort_by_key(|o| o.range.start); + // The text with LRO/RLO … PDF around each override, and where each source char went. + let mut wrapped = String::with_capacity(text.len() + sorted.len() * 6); + let mut at: Vec = Vec::with_capacity(text.len()); + let mut copy = |wrapped: &mut String, piece: Range| { + if let Some(s) = text.get(piece) { + for (_, c) in s.char_indices() { + at.extend(std::iter::repeat_n(wrapped.len(), c.len_utf8())); + wrapped.push(c); + } + } + }; + let mut pos = 0; + for o in sorted { + if o.range.start < pos { + continue; + } + copy(&mut wrapped, pos..o.range.start); + // A paragraph separator ends every embedding (rule X8), so the override is closed + // before each separator and opened again after it. + let mut start = o.range.start; + while start < o.range.end { + let rest = text.get(start..o.range.end).unwrap_or_default(); + let (end, next) = rest + .char_indices() + .find(|&(_, c)| bidi_class(c) == B) + .map_or((o.range.end, o.range.end), |(i, c)| (start + i, start + i + c.len_utf8())); + if start < end { + wrapped.push(if o.rtl { '\u{202E}' } else { '\u{202D}' }); + copy(&mut wrapped, start..end); + wrapped.push('\u{202C}'); + } + copy(&mut wrapped, end..next); + start = next; + } + pos = o.range.end; + } + if pos == 0 { + return Self::new(text, base); + } + copy(&mut wrapped, pos..text.len()); + let (wrapped_levels, wrapped_paragraphs) = resolve(&wrapped, base); + // The inserted controls are not separators, so the paragraphs are the same ones; their + // ranges map back through `at`, which is ascending. + let back = |w: usize| at.partition_point(|&a| a < w); + let paragraphs: Vec<(Range, u8)> = wrapped_paragraphs.iter().map(|(r, l)| (back(r.start)..back(r.end), *l)).collect(); + let levels = at.iter().enumerate().map(|(b, &w)| wrapped_levels.get(w).copied().unwrap_or_else(|| level_in(¶graphs, b))).collect(); + Self { text, levels, paragraphs } + } + + pub fn text(&self) -> &'t str { + self.text + } + + /// The first paragraph's embedding level: 0 or 1. Text with paragraph separators has one + /// level per paragraph: see [`paragraphs`](Self::paragraphs). + pub fn level(&self) -> u8 { + self.paragraphs.first().map_or(0, |p| p.1) + } + + /// Is the first paragraph right to left? + pub fn is_rtl(&self) -> bool { + self.level() % 2 == 1 + } + + /// Each paragraph's byte range (its separator included) and embedding level, in order. There + /// is always at least one; empty text has one empty paragraph. + pub fn paragraphs(&self) -> &[(Range, u8)] { + &self.paragraphs + } + + /// The embedding level of the paragraph containing byte `byte` (the last one's past the end). + pub fn paragraph_level_at(&self, byte: usize) -> u8 { + level_in(&self.paragraphs, byte) + } + + /// Does any line need reordering (is any level above 0)? + pub fn needs_reordering(&self) -> bool { + self.levels.iter().any(|l| *l > 0) + } + + /// The level of each byte of the text. + pub fn levels(&self) -> &[u8] { + &self.levels + } + + pub fn into_levels(self) -> Vec { + self.levels + } + + /// The level of the character at byte `byte` (the last paragraph's level past the end). + pub fn level_at(&self, byte: usize) -> u8 { + self.levels.get(byte).copied().unwrap_or_else(|| self.paragraph_level_at(byte)) + } + + /// The level of each character, in order. + pub fn char_levels(&self) -> Vec { + self.text.char_indices().map(|(b, _)| self.level_at(b)).collect() + } + + /// Rule L1 for the line `line` (a byte range of the text): the level of each of its bytes, + /// with segment and paragraph separators, whitespace before them and whitespace at the end of + /// the line at their paragraph's level; zero-width joiners and tag characters keep the level of + /// the char before them. Empty when `line` is not a char-boundary range of the text. A line + /// should lie within one paragraph; one that crosses a separator takes each byte's own + /// paragraph level here and is reordered as a whole by [`visual_runs`](Self::visual_runs). + pub fn line_levels(&self, line: Range) -> Vec { + let Some(s) = self.text.get(line.clone()) else { return Vec::new() }; + let mut out: Vec = line.clone().map(|b| self.level_at(b)).collect(); + let mut trailing = true; + for (b, c) in s.char_indices().rev() { + if l1_reset(bidi_class(c), &mut trailing) + && let Some(bytes) = out.get_mut(b..b + c.len_utf8()) + { + bytes.fill(self.paragraph_level_at(line.start + b)); + } + } + let mut prev = None; + for (b, c) in s.char_indices() { + if joins_previous(c) + && let Some(l) = prev + && let Some(bytes) = out.get_mut(b..b + c.len_utf8()) + { + bytes.fill(l); + } + prev = out.get(b).copied(); + } + out + } + + /// Rules L1 and L2 for the line `line`: its runs of one level, left to right as displayed. + /// Empty when `line` is not a char-boundary range of the text. + pub fn visual_runs(&self, line: Range) -> Vec { + let levels = self.line_levels(line.clone()); + let Some(s) = self.text.get(line.clone()) else { return Vec::new() }; + let mut runs: Vec = Vec::new(); + for (b, c) in s.char_indices() { + let level = levels.get(b).copied().unwrap_or_else(|| self.paragraph_level_at(line.start + b)); + let end = line.start + b + c.len_utf8(); + match runs.last_mut() { + Some(run) if run.level == level => run.range.end = end, + _ => runs.push(Run { range: line.start + b..end, level }), + } + } + let run_levels: Vec = runs.iter().map(|r| r.level).collect(); + visual_order(&run_levels).into_iter().filter_map(|i| runs.get(i).cloned()).collect() + } +} + +/// Rule L1 over a line's characters `chars` and their resolved `levels`: segment and paragraph +/// separators, any whitespace before them and whitespace at the end of the line take `para_level`; +/// zero-width joiners and tag characters keep the level of the char before them. Missing levels are +/// taken as `para_level`. +pub fn line_levels(chars: &[char], levels: &[u8], para_level: u8) -> Vec { + let mut out = levels.to_vec(); + out.resize(chars.len(), para_level); + let mut trailing = true; + for (i, c) in chars.iter().enumerate().rev() { + if l1_reset(bidi_class(*c), &mut trailing) + && let Some(l) = out.get_mut(i) + { + *l = para_level; + } + } + for i in 1..out.len() { + if chars.get(i).is_some_and(|&c| joins_previous(c)) + && let Some(&l) = out.get(i - 1) + && let Some(cur) = out.get_mut(i) + { + *cur = l; + } + } + out +} + +/// Zero-width joiners and tag characters extend the grapheme cluster of the char before them +/// (UAX #29), so they take its level. Rule L1 counts them as whitespace and would otherwise give a +/// trailing one the paragraph level, splitting its cluster across two runs. +fn joins_previous(c: char) -> bool { + matches!(c, '\u{200C}' | '\u{200D}' | '\u{E0020}'..='\u{E007F}') +} + +/// Rule L2: the display order, left to right, of items with these levels (indices into `levels`). +/// From the highest level down to the lowest odd one, every maximal run at that level or higher is +/// reversed. +pub fn visual_order(levels: &[u8]) -> Vec { + let mut order: Vec = (0..levels.len()).collect(); + let Some(min_odd) = levels.iter().copied().filter(|l| l % 2 == 1).min() else { return order }; + let max = levels.iter().copied().max().unwrap_or(0); + let level_at = |order: &[usize], i: usize| order.get(i).and_then(|&o| levels.get(o)).copied().unwrap_or(0); + for lvl in (min_odd..=max).rev() { + let mut i = 0; + while i < order.len() { + if level_at(&order, i) < lvl { + i += 1; + continue; + } + let mut j = i; + while j < order.len() && level_at(&order, j) >= lvl { + j += 1; + } + if let Some(run) = order.get_mut(i..j) { + run.reverse(); + } + i = j; + } + } + order +} + +/// The mirrored counterpart of `c` (Bidi_Mirroring_Glyph), for a character at an odd level (rule +/// L4): `(` for `)`, `»` for `«`. `None` when it has none; some Bidi_Mirrored characters (`∑`) +/// need a mirrored glyph from the font instead. +pub fn mirror(c: char) -> Option { + unicode_bidi_mirroring::get_mirrored(c) +} + +/// Does anything in the text need the full algorithm (strong right-to-left characters, Arabic +/// numbers or explicit embeddings)? +fn needs_bidi(text: &str) -> bool { + text.chars().any(|c| matches!(bidi_class(c), R | AL | AN | LRE | RLE | LRO | RLO | PDF | LRI | RLI | FSI | PDI)) +} + +/// Levels per byte of `text`, and each paragraph's byte range and level. +fn resolve(text: &str, base: Direction) -> (Vec, Vec<(Range, u8)>) { + let default = match base { + Direction::Ltr => Some(Level::ltr()), + Direction::Rtl => Some(Level::rtl()), + Direction::Auto => None, + }; + let info = BidiInfo::new(text, default); + let mut paragraphs: Vec<(Range, u8)> = info.paragraphs.iter().map(|p| (p.range.clone(), p.level.number())).collect(); + if paragraphs.is_empty() { + paragraphs.push((0..text.len(), u8::from(base == Direction::Rtl))); + } + let levels = (0..text.len()).map(|b| info.levels.get(b).map_or_else(|| level_in(¶graphs, b), |l| l.number())).collect(); + (levels, paragraphs) +} + +/// The byte ranges of the paragraphs in `text` as rule P1 (and unicode-bidi) splits them: each +/// ends after a paragraph separator, and there is always at least one. +fn split_paragraphs(text: &str) -> Vec> { + let mut out = Vec::new(); + let mut start = 0; + for (b, c) in text.char_indices() { + if bidi_class(c) == B { + out.push(start..b + c.len_utf8()); + start = b + c.len_utf8(); + } + } + if start < text.len() || out.is_empty() { + out.push(start..text.len()); + } + out +} + +/// The level of the paragraph containing byte `byte`; the last paragraph's past the end. +fn level_in(paragraphs: &[(Range, u8)], byte: usize) -> u8 { + let i = paragraphs.partition_point(|(r, _)| r.end <= byte); + paragraphs.get(i).or(paragraphs.last()).map_or(0, |p| p.1) +} + +/// Rule L1 walking a line backwards: whether the character of class `class` takes the paragraph +/// level. `trailing` is true while everything after it up to the line end or a separator is +/// whitespace. +fn l1_reset(class: BidiClass, trailing: &mut bool) -> bool { + match class { + S | B => { + *trailing = true; + true + } + WS | FSI | LRI | RLI | PDI | BN | LRE | RLE | LRO | RLO | PDF => *trailing, + _ => { + *trailing = false; + false + } + } +} + +#[cfg(test)] +mod tests; diff --git a/crates/text/src/bidi/tests.rs b/crates/text/src/bidi/tests.rs new file mode 100644 index 00000000..58a450fb --- /dev/null +++ b/crates/text/src/bidi/tests.rs @@ -0,0 +1,254 @@ +use super::*; + +fn rev(s: &str) -> String { + s.chars().rev().collect() +} + +/// Byte offset of char `n` of `s`. +fn at(s: &str, n: usize) -> usize { + s.char_indices().nth(n).map_or(s.len(), |(i, _)| i) +} + +/// The line as displayed, left to right, built from its visual runs. +fn shown(p: &Paragraph<'_>, line: Range) -> String { + p.visual_runs(line).iter().map(|r| if r.is_rtl() { rev(&p.text()[r.range.clone()]) } else { p.text()[r.range.clone()].to_string() }).collect() +} + +fn shown_all(text: &str, base: Direction) -> String { + shown(&Paragraph::new(text, base), 0..text.len()) +} + +#[test] +fn mixed_arabic_latin_numbers_and_brackets() { + let s = "سنة 2024 (Retrait) فقط"; + let p = Paragraph::new(s, Direction::Rtl); + let l = p.char_levels(); + let chars: Vec = s.chars().collect(); + assert_eq!(l.len(), chars.len()); + // Arabic letters at the paragraph level 1; European digits and Latin at 2. + assert_eq!(l[0], 1); + assert_eq!(&l[4..8], &[2, 2, 2, 2]); + assert_eq!(&l[10..17], &[2; 7]); + assert_eq!(l[19], 1); + // Brackets around Latin inside a right-to-left paragraph take the embedding direction (N0). + assert_eq!(l[9] % 2, 1, "( is right to left"); + assert_eq!(l[17] % 2, 1, ") is right to left"); + // The Arabic words reversed, Latin and digits kept, the brackets swapped (the shaper mirrors + // them back, rule L4). Char-level reordering and byte runs agree. + let order = visual_order(&line_levels(&chars, &l, p.level())); + let vis: String = order.iter().map(|&i| chars[i]).collect(); + assert_eq!(vis, "طقف )Retrait( 2024 ةنس"); + assert_eq!(shown(&p, 0..s.len()), vis); +} + +#[test] +fn levels_for_persian_with_latin_and_numbers() { + let p = Paragraph::new("plain English", Direction::Ltr); + assert!(!p.needs_reordering(), "pure left-to-right paragraphs skip the algorithm"); + assert_eq!(p.levels(), &[0; 13]); + let s = "سلام Word ۱۴۰۳"; + let p = Paragraph::new(s, Direction::Rtl); + assert_eq!(p.levels().len(), s.len()); + assert!(p.needs_reordering()); + assert_eq!(p.level_at(0), 1, "Persian letters are right to left"); + assert_eq!(p.level_at(at(s, 5)), 2, "Latin inside a right-to-left paragraph is embedded at level 2"); + assert_eq!(p.level_at(at(s, 10)), 2, "Persian digits are numbers: left to right inside right-to-left text"); + assert_eq!(p.level_at(s.len()), 1, "past the end: the paragraph level"); + // In a left-to-right paragraph Persian is embedded at level 1. + let s = "Hello سلام"; + let p = Paragraph::new(s, Direction::Ltr); + assert_eq!((p.level_at(0), p.level_at(at(s, 6))), (0, 1)); + // A right-to-left paragraph of Latin text keeps it left to right inside it. + assert_eq!(Paragraph::new("ab", Direction::Rtl).char_levels(), vec![2, 2]); +} + +#[test] +fn auto_direction_follows_the_first_strong_character() { + assert!(Paragraph::new("سلام Word", Direction::Auto).is_rtl()); + assert!(!Paragraph::new("Word سلام", Direction::Auto).is_rtl()); + assert!(Paragraph::new("123 سلام", Direction::Auto).is_rtl(), "digits are weak"); + assert_eq!(Paragraph::new("123", Direction::Auto).level(), 0); + assert_eq!(Paragraph::new("", Direction::Auto).level(), 0); + assert_eq!(Paragraph::new("", Direction::Rtl).level(), 1); + assert_eq!(Paragraph::new("Word", Direction::Rtl).level(), 1, "an explicit direction wins"); +} + +#[test] +fn whole_lines_read_in_display_order() { + let s = "سلام دنیا"; + assert_eq!(shown_all(s, Direction::Rtl), rev(s)); + assert_eq!(shown_all("Hello سلام world", Direction::Ltr), "Hello مالس world"); + // "Price 250 toman" in Persian, with a Latin product name, Persian punctuation and digits: + // numbers and Latin keep their order, the words around them read right to left, and the final + // full stop is at the paragraph's end (the far left). + let s = "قیمت 250 تومان برای Word، امسال ۱۴۰۳."; + let want = format!(".۱۴۰۳ {} ،Word {} {} 250 {}", rev("امسال"), rev("برای"), rev("تومان"), rev("قیمت")); + assert_eq!(shown_all(s, Direction::Rtl), want); +} + +#[test] +fn each_line_is_reordered_on_its_own() { + // A right-to-left paragraph of Latin words broken after "ab ": the trailing space takes the + // paragraph level (rule L1), so it sits at the line's end edge, on the left. + let p = Paragraph::new("ab cd", Direction::Rtl); + assert_eq!(p.visual_runs(0..3), vec![Run { range: 2..3, level: 1 }, Run { range: 0..2, level: 2 }]); + assert_eq!(p.visual_runs(3..5), vec![Run { range: 3..5, level: 2 }]); + // Line ranges that aren't char-boundary ranges of the text give nothing. + let p = Paragraph::new("سلام", Direction::Rtl); + assert!(p.visual_runs(1..2).is_empty()); + assert!(p.line_levels(0..99).is_empty()); + #[allow(clippy::reversed_empty_ranges)] + let backwards = 4..2; + assert!(p.visual_runs(backwards).is_empty()); + assert!(p.visual_runs(2..2).is_empty()); +} + +#[test] +fn l1_resets_trailing_whitespace_and_tabs() { + let chars: Vec = "ab\tcd ".chars().collect(); + assert_eq!(line_levels(&chars, &[2; 7], 1), vec![2, 2, 1, 2, 2, 1, 1]); + assert_eq!(Paragraph::new("ab\tcd ", Direction::Rtl).line_levels(0..7), vec![2, 2, 1, 2, 2, 1, 1]); + // Short level slices never panic. + assert_eq!(line_levels(&['a', 'b'], &[], 1), vec![1, 1]); +} + +#[test] +fn visual_order_follows_rule_l2() { + // The example from UAX #9 / unicode-bidi. + assert_eq!(visual_order(&[0, 0, 0, 1, 1, 1, 2, 2]), vec![0, 1, 2, 6, 7, 5, 4, 3]); + assert!(visual_order(&[]).is_empty()); + assert_eq!(visual_order(&[0, 0]), vec![0, 1]); + assert_eq!(visual_order(&[1, 1, 1]), vec![2, 1, 0]); + // Numbers (level 2) inside right-to-left text keep their order. + assert_eq!(visual_order(&[1, 2, 2, 1]), vec![3, 1, 2, 0]); + assert_eq!(visual_order(&[125, 125]), vec![1, 0]); + assert_eq!(visual_order(&[255, 0, 255]), vec![0, 1, 2]); +} + +#[test] +fn overrides_force_a_direction() { + let p = Paragraph::with_overrides("abc def", Direction::Ltr, &[Override { range: 0..3, rtl: true }]); + assert_eq!(p.levels().len(), 7); + assert_eq!(shown(&p, 0..7), "cba def"); + let s = "سلام دنیا"; + let p = Paragraph::with_overrides(s, Direction::Rtl, &[Override { range: 0..at(s, 4), rtl: false }]); + assert_eq!(shown(&p, 0..s.len()), format!("{} سلام", rev("دنیا"))); + // Overrides off char boundaries, empty, out of range or overlapping an earlier one are ignored. + let bad = [Override { range: 1..2, rtl: false }, Override { range: 3..3, rtl: false }, Override { range: 0..99, rtl: false }]; + assert_eq!(Paragraph::with_overrides(s, Direction::Rtl, &bad).levels(), Paragraph::new(s, Direction::Rtl).levels()); + let overlapping = [Override { range: 2..5, rtl: true }, Override { range: 0..3, rtl: true }]; + assert_eq!(shown(&Paragraph::with_overrides("abcdef", Direction::Ltr, &overlapping), 0..6), "cbadef"); +} + +#[test] +fn each_paragraph_has_its_own_level() { + // The second paragraph resolves right to left on its own, so rule L1 puts its trailing space at + // level 1: at the line's end edge, on the left. + let s = "a\nאב "; + let p = Paragraph::new(s, Direction::Auto); + assert_eq!(p.paragraphs(), &[(0..2, 0), (2..7, 1)]); + assert_eq!((p.level(), p.is_rtl()), (0, false), "level() is the first paragraph's"); + assert_eq!((p.paragraph_level_at(1), p.paragraph_level_at(2), p.level_at(s.len())), (0, 1, 1)); + assert_eq!(p.line_levels(2..7), vec![1; 5]); + assert_eq!(p.visual_runs(2..7), vec![Run { range: 2..7, level: 1 }]); + assert_eq!(p.line_levels(0..2), vec![0, 0]); + // Left-to-right text skips the algorithm but still splits paragraphs. + assert_eq!(Paragraph::new("ab\u{2029}c", Direction::Ltr).paragraphs(), &[(0..5, 0), (5..6, 0)]); + assert_eq!(Paragraph::new("", Direction::Auto).paragraphs(), &[(0..0, 0)]); +} + +#[test] +fn overrides_continue_across_paragraph_separators() { + let s = "ab\ncd"; + let p = Paragraph::with_overrides(s, Direction::Ltr, &[Override { range: 0..5, rtl: true }]); + assert_eq!(p.paragraphs(), &[(0..3, 0), (3..5, 0)]); + assert_eq!(p.line_levels(0..3), vec![1, 1, 0], "the separator keeps the paragraph level"); + assert_eq!(shown(&p, 0..3), "ba\n"); + assert_eq!(shown(&p, 3..5), "dc"); + // Each paragraph still resolves its own direction. + let s = "a\nאב "; + let p = Paragraph::with_overrides(s, Direction::Auto, &[Override { range: 0..1, rtl: false }]); + assert_eq!(p.paragraphs(), &[(0..2, 0), (2..7, 1)]); + assert_eq!(p.visual_runs(2..7), vec![Run { range: 2..7, level: 1 }]); +} + +#[test] +fn mirrored_characters() { + assert_eq!(mirror('('), Some(')')); + assert_eq!(mirror(']'), Some('[')); + assert_eq!(mirror('«'), Some('»')); + assert_eq!(mirror('a'), None); + assert_eq!(mirror('∑'), None, "mirrored, but only by glyph"); +} + +#[test] +fn hostile_text_never_panics() { + // Explicit embeddings, isolates, unmatched pops, marks with no base, deep nesting. + let rlo = "\u{202E}".repeat(200); + let junk = [ + "\u{202B}\u{202B}\u{202C}\u{202C}\u{202C}abc\u{2067}سلام\u{2069}\u{2069}", + "\u{064E}\u{064E}\u{200C}\u{200D}", + "\u{200F}\u{200E}\t\u{200F}\n\u{200E}", + "(((((((((سلام]]]]]]]", + "a\u{2029}سلام\u{2029}b", + &rlo, + ]; + for s in junk { + for base in [Direction::Ltr, Direction::Rtl, Direction::Auto] { + let overrides = [Override { range: 0..s.len() / 2, rtl: true }, Override { range: s.len() / 2..s.len(), rtl: false }]; + for p in [Paragraph::new(s, base), Paragraph::with_overrides(s, base, &overrides)] { + assert_eq!(p.levels().len(), s.len()); + let paras = p.paragraphs(); + assert_eq!((paras.first().map(|p| p.0.start), paras.last().map(|p| p.0.end)), (Some(0), Some(s.len())), "{s:?}"); + assert!(paras.windows(2).all(|w| w[0].0.end == w[1].0.start), "{s:?}"); + let bounds: Vec = (0..=s.len()).filter(|&b| s.is_char_boundary(b)).collect(); + for &b in &bounds { + for line in [0..b, b..s.len()] { + let runs = p.visual_runs(line.clone()); + assert_eq!(runs.iter().map(|r| r.range.len()).sum::(), line.len(), "{s:?} {line:?}"); + assert!(runs.iter().all(|r| !r.range.is_empty() && line.start <= r.range.start && r.range.end <= line.end)); + } + } + } + } + } +} + +#[test] +fn runs_never_split_a_grapheme_cluster() { + use unicode_segmentation::UnicodeSegmentation; + let cases = [ + // Arabic with harakat, among Latin and digits. + ("كَتَبَ abc مُحَمَّدٌ 123 بِسْمِ", Direction::Rtl), + ("see كَتَبَ, مُحَمَّدٌ here", Direction::Ltr), + // Hebrew with niqqud (and a dagesh-shin-dot stack). + ("שָׁלוֹם hello עוֹלָם", Direction::Rtl), + ("hello שָׁלוֹם world", Direction::Ltr), + // A Devanagari conjunct (virama, and an explicit half form with ZWJ) in right-to-left text. + ("سلام क्षत्रिय क्\u{200D}ष سلام", Direction::Rtl), + ("سلام क्\u{200D} ", Direction::Rtl), + // A combining mark after a Latin letter in a right-to-left paragraph, and after a Hebrew + // letter in a left-to-right one, each at a run edge. + ("שלום e\u{0301}te\u{0301} עולם", Direction::Rtl), + ("שלום cafe\u{0301}", Direction::Rtl), + ("café ש\u{05B8}\u{05BC} next", Direction::Ltr), + ("abc ש\u{05B8}", Direction::Ltr), + ("a\u{0301}\u{0302}ש", Direction::Auto), + ]; + for (s, base) in cases { + let p = Paragraph::new(s, base); + let bounds: Vec = s.grapheme_indices(true).map(|(i, _)| i).chain([s.len()]).collect(); + for &a in &bounds { + for &b in bounds.iter().filter(|&&b| b > a) { + for r in p.visual_runs(a..b) { + assert!(bounds.contains(&r.range.start) && bounds.contains(&r.range.end), "{s:?} line {a}..{b}: run {r:?}"); + } + } + } + } + // The char-level L1 keeps a trailing joiner with its conjunct too. + let s = "سلام क्\u{200D} "; + let chars: Vec = s.chars().collect(); + let l = line_levels(&chars, &Paragraph::new(s, Direction::Rtl).char_levels(), 1); + assert_eq!((l[6], l[7], l[8]), (2, 2, 1)); +} diff --git a/crates/text/src/hyphen/dict.rs b/crates/text/src/hyphen/dict.rs new file mode 100644 index 00000000..28b71a77 --- /dev/null +++ b/crates/text/src/hyphen/dict.rs @@ -0,0 +1,159 @@ +//! Hyphenation exception dictionary: lowercase words with their break points. +//! +//! On-disk format (`assets/en-us.dic`): raw-deflate of +//! `"DCHYPH1\n"` followed by one line per word, sorted by the plain word's bytes. Each line is +//! front-coded against the previous one: a byte with the shared prefix length (in bytes of the +//! hyphenated form), then the rest of the hyphenated form (`-` at every break), then `\n`. + +/// Sorted word list with a break bitmask per word (bit `i` = hyphen before char `i`). +#[derive(Clone, Debug, Default)] +pub struct Dictionary { + words: String, + offs: Vec, + masks: Vec, +} + +const MAGIC: &[u8] = b"DCHYPH1\n"; + +impl Dictionary { + pub fn len(&self) -> usize { + self.masks.len() + } + + pub fn is_empty(&self) -> bool { + self.masks.is_empty() + } + + fn word(&self, i: usize) -> &str { + &self.words[self.offs[i] as usize..self.offs[i + 1] as usize] + } + + /// Break mask of an exact (already lowercased) word. + pub fn get(&self, word: &str) -> Option { + let (mut lo, mut hi) = (0usize, self.len()); + while lo < hi { + let mid = (lo + hi) / 2; + match self.word(mid).as_bytes().cmp(word.as_bytes()) { + std::cmp::Ordering::Less => lo = mid + 1, + std::cmp::Ordering::Greater => hi = mid, + std::cmp::Ordering::Equal => return Some(self.masks[mid]), + } + } + None + } + + /// Iterate `(word, mask)`. + pub fn iter(&self) -> impl Iterator + '_ { + (0..self.len()).map(|i| (self.word(i), self.masks[i])) + } + + /// Deserialize data written by `Dictionary::to_bytes`. + pub(crate) fn decode(data: &[u8]) -> Result { + let raw = miniz_oxide::inflate::decompress_to_vec(data).map_err(|e| format!("hyphenation dictionary: inflate failed: {e:?}"))?; + let body = raw.strip_prefix(MAGIC).ok_or("hyphenation dictionary: bad header")?; + let mut d = Dictionary { words: String::with_capacity(body.len()), offs: vec![0], masks: Vec::new() }; + let mut cur: Vec = Vec::new(); + let mut i = 0; + while i < body.len() { + let p = body[i] as usize; + let end = body[i + 1..].iter().position(|&b| b == b'\n').map(|e| i + 1 + e).ok_or("hyphenation dictionary: truncated")?; + if p > cur.len() { + return Err("hyphenation dictionary: bad prefix".into()); + } + cur.truncate(p); + cur.extend_from_slice(&body[i + 1..end]); + i = end + 1; + let s = std::str::from_utf8(&cur).map_err(|_| "hyphenation dictionary: bad utf-8")?; + let (w, m) = parse_hyphenated(s); + d.words.push_str(&w); + d.offs.push(d.words.len() as u32); + d.masks.push(m); + } + Ok(d) + } +} + +#[cfg(any(test, feature = "generator"))] +impl Dictionary { + /// Build from `(lowercase word, break mask)` pairs (sorted and de-duplicated here; the first + /// entry of a duplicate wins). + pub fn from_entries(mut entries: Vec<(String, u64)>) -> Dictionary { + entries.sort_by(|a, b| a.0.as_bytes().cmp(b.0.as_bytes())); + entries.dedup_by(|b, a| a.0 == b.0); + let mut d = Dictionary { words: String::new(), offs: vec![0], masks: Vec::with_capacity(entries.len()) }; + for (w, m) in entries { + d.words.push_str(&w); + d.offs.push(d.words.len() as u32); + d.masks.push(m); + } + d + } + + /// Serialize (deflate-compressed). + pub fn to_bytes(&self) -> Vec { + let mut raw = MAGIC.to_vec(); + let mut prev: Vec = Vec::new(); + for (w, m) in self.iter() { + let h = hyphenated(w, m).into_bytes(); + let p = prev.iter().zip(&h).take_while(|(a, b)| a == b).count().min(255); + raw.push(p as u8); + raw.extend_from_slice(&h[p..]); + raw.push(b'\n'); + prev = h; + } + miniz_oxide::deflate::compress_to_vec(&raw, 10) + } + + /// Deserialize data written by [`Dictionary::to_bytes`]. + pub fn from_bytes(data: &[u8]) -> Result { + Dictionary::decode(data) + } +} + +/// `word` with `-` before every char whose bit is set in `mask`. +#[cfg(any(test, feature = "generator"))] +pub fn hyphenated(word: &str, mask: u64) -> String { + let mut s = String::with_capacity(word.len() + 8); + for (i, c) in word.chars().enumerate() { + if i > 0 && i < 64 && mask & (1 << i) != 0 { + s.push('-'); + } + s.push(c); + } + s +} + +/// A word written with `-` at its breaks, as `(word, break mask)`. +pub fn parse_hyphenated(s: &str) -> (String, u64) { + let mut w = String::with_capacity(s.len()); + let mut m = 0u64; + let mut n = 0; + for c in s.chars() { + if c == '-' { + if n > 0 && n < 64 { + m |= 1 << n; + } + } else { + w.push(c); + n += 1; + } + } + (w, m) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn roundtrip() { + let e: Vec<(String, u64)> = ["ty-pog-ra-phy", "cat", "hap-pen", "o'clock", "naïve-té", "naïve"].iter().map(|s| parse_hyphenated(s)).collect(); + let d = Dictionary::from_entries(e); + let back = Dictionary::from_bytes(&d.to_bytes()).unwrap(); + assert_eq!(back.len(), 6); + assert_eq!(back.get("typography").map(|m| hyphenated("typography", m)), Some("ty-pog-ra-phy".to_string())); + assert_eq!(back.get("cat"), Some(0)); + assert_eq!(back.get("naïveté").map(|m| hyphenated("naïveté", m)), Some("naïve-té".to_string())); + assert!(back.get("dog").is_none()); + } +} diff --git a/crates/text/src/hyphen/mod.rs b/crates/text/src/hyphen/mod.rs new file mode 100644 index 00000000..f098bdbb --- /dev/null +++ b/crates/text/src/hyphen/mod.rs @@ -0,0 +1,463 @@ +//! Hyphenation points for text layout. English uses the bundled dictionary and patterns below. +//! Other languages use the Liang patterns compiled into [`hypher`], one cargo feature per +//! language (`spanish`, `german`, …, or `all-languages`); their licenses are listed in NOTICE. +//! +//! English lookup order for each word: +//! 1. the **dictionary** ([`Dictionary::en_us`]) — the public-domain Moby Hyphenator II word list +//! by Grady Ward (~160k words), stored compactly in `assets/hyphen/en-us.dic`; simple +//! inflections (`'s`, `-s`, `-es`, `-ed`, `-d`) inherit the breaks of their stem; +//! 2. **Liang patterns** (`assets/hyphen/en-us.pat`) for words not in the dictionary — our own +//! pattern set, trained from the same list by the patgen-style trainer behind the `generator` +//! feature (`examples/hyphgen.rs` regenerates both files); +//! 3. a small syllable **heuristic** for words outside the pattern alphabet. +//! +//! Then the paragraph's limits ([`Limits`]) are applied. + +#[cfg(feature = "generator")] +pub mod dict; +#[cfg(not(feature = "generator"))] +mod dict; +#[cfg(feature = "generator")] +pub mod patgen; +mod patterns; + +use std::sync::OnceLock; + +pub use dict::Dictionary; +#[cfg(feature = "generator")] +pub use patterns::Patterns; +#[cfg(not(feature = "generator"))] +use patterns::Patterns; + +static EN_US_DIC: &[u8] = include_bytes!("../../assets/hyphen/en-us.dic"); +static EN_US_PAT: &str = include_str!("../../assets/hyphen/en-us.pat"); + +impl Dictionary { + /// The bundled US English dictionary (decoded on first use; empty if the data is corrupt). + pub fn en_us() -> &'static Dictionary { + static D: OnceLock = OnceLock::new(); + D.get_or_init(|| Dictionary::decode(EN_US_DIC).unwrap_or_default()) + } +} + +impl Patterns { + /// The bundled US English patterns (parsed on first use). + pub fn en_us() -> &'static Patterns { + static P: OnceLock = OnceLock::new(); + P.get_or_init(|| Patterns::parse(EN_US_PAT)) + } +} + +/// Hyphenation limits from the paragraph's Hyphenation settings. +#[derive(Clone, Copy, Debug)] +pub struct Limits { + pub min_word: usize, + pub after_first: usize, + pub before_last: usize, + pub capitalized: bool, +} + +impl Default for Limits { + fn default() -> Self { + Limits { min_word: 5, after_first: 2, before_last: 2, capitalized: true } + } +} + +/// The hyphenator for a run of text. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Lang { + /// The bundled dictionary, patterns and heuristic. + English, + /// Patterns compiled into [`hypher`] (one cargo feature per language). + Patterns(PatternLang), +} + +/// A language whose patterns are compiled into [`hypher`]; obtained from [`Lang::for_language`]. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct PatternLang(hypher::Lang); + +/// English names of every language hypher can hyphenate, with their ISO 639-1 codes. Languages +/// whose cargo feature is off are not compiled into hypher, so `from_iso` returns None for them. +const LANGUAGES: &[(&str, [u8; 2])] = &[ + ("afrikaans", *b"af"), + ("albanian", *b"sq"), + ("assamese", *b"as"), + ("belarusian", *b"be"), + ("bengali", *b"bn"), + ("bangla", *b"bn"), + ("bulgarian", *b"bg"), + ("catalan", *b"ca"), + ("croatian", *b"hr"), + ("czech", *b"cs"), + ("danish", *b"da"), + ("dutch", *b"nl"), + ("estonian", *b"et"), + ("finnish", *b"fi"), + ("french", *b"fr"), + ("galician", *b"gl"), + ("georgian", *b"ka"), + ("german", *b"de"), + ("greek", *b"el"), + ("gujarati", *b"gu"), + ("hindi", *b"hi"), + ("hungarian", *b"hu"), + ("icelandic", *b"is"), + ("italian", *b"it"), + ("kannada", *b"kn"), + ("kurmanji", *b"ku"), + ("latin", *b"la"), + ("lithuanian", *b"lt"), + ("malayalam", *b"ml"), + ("marathi", *b"mr"), + ("mongolian", *b"mn"), + ("norwegian", *b"no"), + ("bokmål", *b"nb"), + ("bokmal", *b"nb"), + ("nynorsk", *b"nn"), + ("oriya", *b"or"), + ("odia", *b"or"), + ("panjabi", *b"pa"), + ("punjabi", *b"pa"), + ("polish", *b"pl"), + ("portuguese", *b"pt"), + ("russian", *b"ru"), + ("sanskrit", *b"sa"), + ("serbian", *b"sr"), + ("slovak", *b"sk"), + ("slovenian", *b"sl"), + ("slovene", *b"sl"), + ("spanish", *b"es"), + ("castilian", *b"es"), + ("swedish", *b"sv"), + ("tamil", *b"ta"), + ("telugu", *b"te"), + ("turkish", *b"tr"), + ("turkmen", *b"tk"), + ("ukrainian", *b"uk"), +]; + +impl Lang { + /// The hyphenator for a language name or locale code: an English name as InDesign and IDML + /// write it ("Spanish", "German: 2006 Reform", "$ID/Norwegian: Bokmal"), or a locale code + /// (`es`, `es_ES`, `pt-BR`, `de_DE_2006`). Case and punctuation don't matter. None when the + /// language is unknown or its cargo feature is off. + pub fn for_language(language: &str) -> Option { + if language.starts_with("English") { + return Some(Lang::English); + } + let language = language.trim(); + let language = language.strip_prefix("$ID/").unwrap_or(language); + let l = language.to_lowercase(); + let words: Vec<&str> = l.split(|c: char| !c.is_alphanumeric()).filter(|w| !w.is_empty()).collect(); + let first = *words.first()?; + let code = match locale_language(&words) { + Some("en") => return Some(Lang::English), + Some(code) => <[u8; 2]>::try_from(code.as_bytes()).ok()?, + None if first == "english" => return Some(Lang::English), + None => LANGUAGES.iter().find(|(name, _)| *name == first)?.1, + }; + hypher::Lang::from_iso(code).map(|l| Lang::Patterns(PatternLang(l))) + } +} + +/// The language of a locale code split into lowercase `words`: a language (2 or 3 letters), then +/// optionally a region (2 letters or 3 digits) and a reform year (4 digits). +fn locale_language<'a>(words: &[&'a str]) -> Option<&'a str> { + let letters = |w: &str, n: std::ops::RangeInclusive| n.contains(&w.len()) && w.bytes().all(|b| b.is_ascii_lowercase()); + let digits = |w: &str, n: usize| w.len() == n && w.bytes().all(|b| b.is_ascii_digit()); + match *words { + [lang] if letters(lang, 2..=3) => Some(lang), + [lang, region] if letters(lang, 2..=3) && (letters(region, 2..=2) || digits(region, 3)) => Some(lang), + [lang, region, year] if letters(lang, 2..=3) && (letters(region, 2..=2) || digits(region, 3)) && digits(year, 4) => Some(lang), + _ => None, + } +} + +/// Where a word's break points came from. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Source { + Dictionary, + Patterns, + Heuristic, + None, +} + +fn is_apostrophe(c: char) -> bool { + matches!(c, '\'' | '’' | 'ʼ') +} + +/// Letters, apostrophes, and the combining marks and joiners inside a word: a virama or a +/// decomposed accent doesn't split it. +fn is_word_char(c: char) -> bool { + c.is_alphabetic() || is_apostrophe(c) || is_mark(c) || is_joiner(c) +} + +/// A combining mark (general category M): it belongs to the letter before it. +fn is_mark(c: char) -> bool { + use unicode_general_category::{GeneralCategory, get_general_category}; + matches!(get_general_category(c), GeneralCategory::NonspacingMark | GeneralCategory::SpacingMark | GeneralCategory::EnclosingMark) +} + +/// Zero-width joiner and non-joiner, which shape the letters on both sides. +fn is_joiner(c: char) -> bool { + matches!(c, '\u{200C}' | '\u{200D}') +} + +/// Unrestricted break points of one lowercase core (letters and `'` only, no leading/trailing `'`). +fn core_breaks(core: &[char], lang: Lang) -> (Vec, Source) { + let n = core.len(); + if n < 2 { + return (vec![], Source::None); + } + if let Lang::Patterns(PatternLang(l)) = lang { + // The whole core, apostrophes included: French, Italian and Catalan patterns encode + // elisions (`l'or-ga-ni-sa-tion`, `del-l'am-mi-ni-stra-zio-ne`). + let s: String = core.iter().collect(); + let mut out = Vec::new(); + let mut at = 0; + let syl: Vec<&str> = hypher::hyphenate_bounded(&s, l, 1, 1).collect(); + if let Some((_, init)) = syl.split_last() { + for part in init { + at += part.chars().count(); + out.push(at); + } + } + return (out, Source::Patterns); + } + let dict = Dictionary::en_us(); + let s: String = core.iter().collect(); + let from_mask = |m: u64, len: usize| (1..len.min(64)).filter(|&i| m & (1 << i) != 0).collect::>(); + if let Some(m) = dict.get(&s) { + return (from_mask(m, n), Source::Dictionary); + } + // Inflections inherit the stem's breaks (the suffix adds no break of its own). + for suf in ["'s", "s", "es", "ed", "d"] { + if let Some(stem) = s.strip_suffix(suf) + && stem.chars().count() >= 2 + && let Some(m) = dict.get(stem) + { + return (from_mask(m, stem.chars().count()), Source::Dictionary); + } + } + let pats = Patterns::en_us(); + if !pats.is_empty() + && let Some(p) = pats.points(core) + { + return (p, Source::Patterns); + } + (heuristic_points(core), Source::Heuristic) +} + +/// Unrestricted break points of `word` as byte offsets (a hyphen goes before the char that starts +/// there), handling case, apostrophes (`don't`, `’s`), surrounding punctuation and compounds (each +/// letter run is hyphenated separately). No break is ever placed next to an apostrophe or +/// non-letter, before a combining mark or next to a joiner; marks and joiners don't end a run. +pub fn word_breaks(word: &str) -> (Vec, Source) { + word_breaks_in(word, Lang::English) +} + +/// [`word_breaks`] for a language. +pub fn word_breaks_in(word: &str, lang: Lang) -> (Vec, Source) { + let (pts, src) = char_breaks(word, lang); + (byte_offsets(word, pts), src) +} + +/// Char indices into `word` as byte offsets. +fn byte_offsets(word: &str, pts: Vec) -> Vec { + let starts: Vec = word.char_indices().map(|(b, _)| b).collect(); + pts.into_iter().filter_map(|p| starts.get(p).copied()).collect() +} + +/// [`word_breaks_in`] as char indices. +fn char_breaks(word: &str, lang: Lang) -> (Vec, Source) { + let chars: Vec = word.chars().collect(); + let mut out = Vec::new(); + let mut src = Source::None; + let mut i = 0; + while i < chars.len() { + if !is_word_char(chars[i]) { + i += 1; + continue; + } + let mut j = i; + while j < chars.len() && is_word_char(chars[j]) { + j += 1; + } + let (mut a, mut b) = (i, j); + while a < b && is_apostrophe(chars[a]) { + a += 1; + } + while b > a && is_apostrophe(chars[b - 1]) { + b -= 1; + } + let core: Vec = chars[a..b].iter().map(|&c| if is_apostrophe(c) { '\'' } else { c.to_lowercase().next().unwrap_or(c) }).collect(); + let (pts, s) = core_breaks(&core, lang); + if src == Source::None { + src = s; + } + // Never before a mark or next to a joiner: that would split a shaping cluster. + let allowed = |p: usize| match (core.get(p.wrapping_sub(1)), core.get(p)) { + (Some(&x), Some(&y)) => x != '\'' && y != '\'' && !is_mark(y) && !is_joiner(x) && !is_joiner(y), + _ => false, + }; + out.extend(pts.into_iter().filter(|&p| p > 0 && allowed(p)).map(|p| a + p)); + i = j; + } + (out, src) +} + +/// Allowed hyphenation points in `word` as byte offsets (a hyphen goes before the char that +/// starts there), with the paragraph limits applied to each letter run. +pub fn hyphen_points(word: &str, lim: &Limits) -> Vec { + hyphen_points_in(word, lim, Lang::English) +} + +/// [`hyphen_points`] for a language. +pub fn hyphen_points_in(word: &str, lim: &Limits, lang: Lang) -> Vec { + byte_offsets(word, char_points(word, lim, lang)) +} + +/// [`hyphen_points_in`] as char indices. +fn char_points(word: &str, lim: &Limits, lang: Lang) -> Vec { + let chars: Vec = word.chars().collect(); + let (pts, _) = char_breaks(word, lang); + if pts.is_empty() { + return pts; + } + let min_before = lim.after_first.max(1); + let min_after = lim.before_last.max(1); + // Counted once, so each point's checks take constant time however long the word: letters and + // uppercase letters before each char, and the letter run (trimmed of apostrophes) of each char. + let (mut letters, mut upper) = (Vec::with_capacity(chars.len() + 1), Vec::with_capacity(chars.len() + 1)); + let (mut l, mut u) = (0usize, 0usize); + for c in &chars { + letters.push(l); + upper.push(u); + if c.is_alphabetic() { + l += 1; + u += usize::from(c.is_uppercase()); + } + } + letters.push(l); + upper.push(u); + let mut run_of: Vec<(usize, usize)> = vec![(0, 0); chars.len()]; + let mut i = 0; + while i < chars.len() { + let mut j = i; + while chars.get(j).is_some_and(|c| is_word_char(*c)) { + j += 1; + } + let (mut a, mut b) = (i, j); + while a < b && chars.get(a).is_some_and(|c| is_apostrophe(*c)) { + a += 1; + } + while b > a && chars.get(b - 1).is_some_and(|c| is_apostrophe(*c)) { + b -= 1; + } + for r in run_of.get_mut(i..j).into_iter().flatten() { + *r = (a, b); + } + i = j.max(i + 1); + } + let count = |v: &[usize], a: usize, b: usize| v.get(b).zip(v.get(a)).map_or(0, |(y, x)| y.saturating_sub(*x)); + pts.into_iter() + .filter(|&p| { + // A point lies between two letters of one run; the char after it gives the run. + let Some(&(a, b)) = run_of.get(p) else { return false }; + let n = count(&letters, a, b); + if n < lim.min_word.max(2) { + return false; + } + if n > 1 && count(&upper, a, b) == n { + return false; + } + if !lim.capitalized && chars.get(a).is_some_and(|c| c.is_uppercase()) { + return false; + } + count(&letters, a, p) >= min_before && count(&letters, p, b) >= min_after + }) + .collect() +} + +/// `word` with `-` at every hyphenation point (tests and diagnostics). +pub fn hyphenate_word(word: &str, lim: &Limits) -> String { + let pts = hyphen_points(word, lim); + let mut s = String::with_capacity(word.len() + pts.len()); + for (i, ch) in word.char_indices() { + if pts.contains(&i) { + s.push('-'); + } + s.push(ch); + } + s +} + +// ---------- heuristic fallback (words outside the pattern alphabet) ---------- + +fn is_vowel(c: char) -> bool { + matches!(c.to_ascii_lowercase(), 'a' | 'e' | 'i' | 'o' | 'u' | 'y') || (c.is_alphabetic() && !c.is_ascii()) +} + +fn onset_pair(a: char, b: char) -> bool { + let (a, b) = (a.to_ascii_lowercase(), b.to_ascii_lowercase()); + matches!( + (a, b), + ('c' | 's' | 't' | 'p' | 'w' | 'g', 'h') + | ('b' | 'c' | 'd' | 'f' | 'g' | 'k' | 'p' | 't', 'r') + | ('b' | 'c' | 'f' | 'g' | 'k' | 'p' | 's', 'l') + | ('q', 'u') + | ('s', 't' | 'p' | 'c' | 'k') + ) +} + +/// Syllable heuristic: V-CV ("ty-po"), VC-CV ("hap-pen"), keeping onset clusters ("gra-phy"). +fn heuristic_points(c: &[char]) -> Vec { + let n = c.len(); + if n < 4 || !c.iter().all(|c| c.is_alphabetic()) { + return vec![]; + } + let v: Vec = c.iter().map(|&x| is_vowel(x)).collect(); + // Both parts need a sounded vowel: a trailing silent `e`, `ed` or `es` doesn't count. The part + // after `i` is `c[i..end]`, `end` before that ending; computed once, so each point is O(1). + let end = |i: usize| { + if n - i >= 2 && (c.ends_with(&['e', 'd']) || c.ends_with(&['e', 's'])) { + n - 2 + } else if c.ends_with(&['e']) { + n - 1 + } else { + n + } + }; + // UTF-8 bytes before each char, and the first vowel at or after each char. + let mut bytes = Vec::with_capacity(n + 1); + let mut acc = 0usize; + for ch in c { + bytes.push(acc); + acc += ch.len_utf8(); + } + bytes.push(acc); + let mut next_vowel = vec![n; n + 1]; + for i in (0..n).rev() { + next_vowel[i] = if v[i] { i } else { next_vowel[i + 1] }; + } + let mut out = vec![]; + let mut vowel_before = false; + for i in 1..n { + vowel_before |= v[i - 1]; + let ok = if v[i - 1] && !v[i] { + (i + 1 < n && v[i + 1]) || (i + 2 < n && onset_pair(c[i], c[i + 1]) && v[i + 2]) + } else if !v[i - 1] && !v[i] { + i >= 2 && v[i - 2] && i + 1 < n && v[i + 1] && !onset_pair(c[i - 1], c[i]) && c[i - 1] != c[i] || (c[i - 1] == c[i] && i >= 2 && v[i - 2]) + } else { + false + }; + let e = end(i); + if ok && next_vowel[i] < e && bytes[e] - bytes[i] > 1 && vowel_before { + out.push(i); + } + } + out +} + +#[cfg(test)] +mod tests; diff --git a/crates/text/src/hyphen/patgen.rs b/crates/text/src/hyphen/patgen.rs new file mode 100644 index 00000000..eea88b2a --- /dev/null +++ b/crates/text/src/hyphen/patgen.rs @@ -0,0 +1,251 @@ +//! A small patgen-style trainer (ours): learns Liang hyphenation patterns from a hyphenated word +//! list, level by level. Odd levels add hyphenating patterns, even levels add inhibiting ones. +//! +//! At level `L`, for every pattern length, each inter-letter position whose current value is +//! below `L` is classified as *good* (applying value `L` would fix it) or *bad* (it would break a +//! position that is currently right). A candidate (letters + value position) is selected when +//! `good·good_weight − bad·bad_weight ≥ threshold`; selected patterns are applied to every word +//! before the next length is considered. Used offline by `examples/hyphgen.rs`. + +use super::patterns::{Alphabet, FxMap, MAX_PATTERN_LEN, Patterns, apply, pack}; + +/// Parameters of one level. +#[derive(Clone, Copy, Debug)] +pub struct Level { + pub min_len: usize, + pub max_len: usize, + pub good_weight: u32, + pub bad_weight: u32, + pub threshold: u32, +} + +/// Defaults tuned on the Moby list (see `examples/hyphgen.rs`). +pub const DEFAULT_LEVELS: &[Level] = &[ + Level { min_len: 1, max_len: 4, good_weight: 1, bad_weight: 2, threshold: 20 }, + Level { min_len: 2, max_len: 5, good_weight: 2, bad_weight: 1, threshold: 8 }, + Level { min_len: 3, max_len: 6, good_weight: 1, bad_weight: 4, threshold: 7 }, + Level { min_len: 3, max_len: 7, good_weight: 3, bad_weight: 2, threshold: 2 }, + Level { min_len: 4, max_len: 8, good_weight: 1, bad_weight: 20, threshold: 6 }, + Level { min_len: 4, max_len: 8, good_weight: 3, bad_weight: 1, threshold: 2 }, +]; + +struct Word { + /// Padded codes: boundary, letters…, boundary. + codes: Vec, + /// Correct hyphen before padded char `p`. + hyph: Vec, + vals: Vec, +} + +/// Accuracy of a pattern set over a word list. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct Score { + pub words: usize, + pub breaks: usize, + pub found: usize, + pub wrong: usize, +} + +impl Score { + pub fn missed(&self) -> usize { + self.breaks.saturating_sub(self.found) + } +} + +/// Train patterns from `(lowercase word, break char indices)` pairs. `log` receives progress lines. +pub fn train(words: &[(Vec, Vec)], levels: &[Level], log: &mut dyn FnMut(String)) -> Patterns { + let mut alpha = Alphabet::default(); + let mut data: Vec = Vec::with_capacity(words.len()); + 'w: for (w, br) in words { + let mut codes = Vec::with_capacity(w.len() + 2); + codes.push(1); + for &c in w { + let Some(k) = alpha.intern(c) else { continue 'w }; + codes.push(k); + } + codes.push(1); + let mut hyph = vec![false; codes.len() + 1]; + for &b in br { + if b > 0 && b < w.len() { + hyph[b + 1] = true; + } + } + let vals = vec![0; codes.len() + 1]; + data.push(Word { codes, hyph, vals }); + } + let mut pats: FxMap> = FxMap::default(); + let mut max_len = 0usize; + for (li, lv) in levels.iter().enumerate() { + let level = (li + 1) as u8; + let hyphenating = level % 2 == 1; + for len in lv.min_len..=lv.max_len.min(MAX_PATTERN_LEN) { + // (packed letters | dot) → (good, bad) + let mut counts: FxMap = FxMap::default(); + for w in &data { + let n = w.codes.len(); + // Positions strictly between the word's letters. + for p in 2..n - 1 { + let v = w.vals[p]; + if v >= level { + continue; + } + let (good, bad) = if hyphenating { + (w.hyph[p] && v % 2 == 0, !w.hyph[p] && v % 2 == 0) + } else { + (!w.hyph[p] && v % 2 == 1, w.hyph[p] && v % 2 == 1) + }; + if !good && !bad { + continue; + } + for dot in 0..=len { + if p < dot || p - dot + len > n { + continue; + } + let s = p - dot; + let key = pack(&w.codes[s..s + len]) | ((dot as u64) << 54); + let e = counts.entry(key).or_default(); + if good { + e.0 += 1; + } else { + e.1 += 1; + } + } + } + } + // Select. + let mut new: FxMap> = FxMap::default(); + let mut selected = 0usize; + for (key, (g, b)) in counts { + // Widened first: u32 × u32 fills a u64, and the difference needs a sign. + let score = i128::from(g) * i128::from(lv.good_weight) - i128::from(b) * i128::from(lv.bad_weight); + if g > 0 && score >= i128::from(lv.threshold) { + let dot = ((key >> 54) & 15) as usize; + let letters = key & !(15u64 << 54); + let e = new.entry(letters).or_insert_with(|| vec![0u8; len + 1].into_boxed_slice()); + e[dot] = level; + selected += 1; + } + } + if selected == 0 { + continue; + } + for w in &mut data { + apply(&new, len, &w.codes, &mut w.vals); + } + for (k, v) in new { + let e = pats.entry(k).or_insert_with(|| vec![0u8; len + 1].into_boxed_slice()); + for (a, b) in e.iter_mut().zip(v.iter()) { + *a = (*a).max(*b); + } + } + max_len = max_len.max(len); + let sc = score_vals(&data); + log(format!("level {level} len {len}: +{selected} patterns ({} total); found {}/{} wrong {}", pats.len(), sc.found, sc.breaks, sc.wrong)); + } + } + // Re-express through the public pattern type (TeX strings) so the alphabet matches at runtime. + let tmp = Patterns::from_parts(alpha, pats, max_len); + let mut out = Patterns::default(); + out.add_letters(words.iter().flat_map(|w| w.0.iter().copied())); + for t in tmp.to_tex() { + out.insert(&t); + } + out +} + +fn score_vals(data: &[Word]) -> Score { + let mut s = Score { words: data.len(), ..Default::default() }; + for w in data { + for p in 2..w.codes.len() - 1 { + let on = w.vals[p] % 2 == 1; + if w.hyph[p] { + s.breaks += 1; + if on { + s.found += 1; + } + } else if on { + s.wrong += 1; + } + } + } + s +} + +/// Score `pats` against a word list. +pub fn score(pats: &Patterns, words: &[(Vec, Vec)]) -> Score { + let mut s = Score::default(); + for (w, br) in words { + let Some(pts) = pats.points(w) else { continue }; + s.words += 1; + s.breaks += br.len(); + for p in &pts { + if br.contains(p) { + s.found += 1; + } else { + s.wrong += 1; + } + } + } + s +} + +#[cfg(test)] +mod tests { + use super::*; + + fn w(s: &str) -> (Vec, Vec) { + let mut chars = Vec::new(); + let mut br = Vec::new(); + for c in s.chars() { + if c == '-' { + br.push(chars.len()); + } else { + chars.push(c); + } + } + (chars, br) + } + + /// Weights near `u32::MAX` select the pattern instead of overflowing. + #[test] + fn large_weights_do_not_overflow() { + let words = vec![(vec!['a', 'b'], vec![1]); 2]; + let levels = [Level { min_len: 1, max_len: 1, good_weight: 1 << 31, bad_weight: 1, threshold: 1 }]; + let patterns = train(&words, &levels, &mut |_| {}); + assert_eq!(patterns.points(&['a', 'b']), Some(vec![1])); + } + + #[test] + fn learns_a_tiny_list() { + let list: Vec<_> = [ + "hap-pen", + "hap-pens", + "hap-pened", + "pen-cil", + "pen-cils", + "rab-bit", + "rab-bits", + "kit-ten", + "kit-tens", + "but-ter", + "bet-ter", + "let-ter", + "lit-ter", + "sit-ter", + ] + .iter() + .map(|s| w(s)) + .collect(); + let levels = [ + Level { min_len: 1, max_len: 4, good_weight: 1, bad_weight: 1, threshold: 2 }, + Level { min_len: 1, max_len: 5, good_weight: 1, bad_weight: 1, threshold: 1 }, + ]; + let p = train(&list, &levels, &mut |_| {}); + let sc = score(&p, &list); + assert_eq!(sc.breaks, list.len()); + assert!(sc.found >= sc.breaks - 1, "{sc:?}"); + assert!(sc.wrong <= 1, "{sc:?}"); + // Generalises to an unseen word with the same shape. + assert_eq!(p.points(&"bitter".chars().collect::>()).unwrap(), vec![3]); + } +} diff --git a/crates/text/src/hyphen/patterns.rs b/crates/text/src/hyphen/patterns.rs new file mode 100644 index 00000000..a5dff954 --- /dev/null +++ b/crates/text/src/hyphen/patterns.rs @@ -0,0 +1,241 @@ +//! Liang hyphenation patterns (TeX notation, e.g. `.ab1c`, `4t1ion`): parsing and application. +//! +//! The bundled English set is *ours*: trained from the public-domain Moby Hyphenator word list by +//! the crate's patgen-style trainer (see `examples/hyphgen.rs`). Patterns are stored in a hash map keyed by the +//! packed letter string, so applying them to a word costs `O(len × max_pattern_len)` lookups. + +use std::collections::HashMap; +use std::hash::{BuildHasherDefault, Hasher}; + +/// Word-boundary marker in patterns. +pub(crate) const DOT: char = '.'; +/// Longest pattern the packed key supports. +pub(crate) const MAX_PATTERN_LEN: usize = 9; + +/// Small, fast multiplicative hasher for packed `u64` keys (FxHash-style). +#[derive(Default, Clone, Copy)] +pub(crate) struct FxHasher(u64); + +impl Hasher for FxHasher { + fn finish(&self) -> u64 { + self.0 + } + fn write(&mut self, bytes: &[u8]) { + for &b in bytes { + self.write_u64(b as u64); + } + } + fn write_u64(&mut self, i: u64) { + self.0 = (self.0.rotate_left(5) ^ i).wrapping_mul(0x51_7c_c1_b7_27_22_0a_95); + } +} + +pub(crate) type FxMap = HashMap>; + +/// Maps characters to 6-bit codes (1 = word boundary, 2.. = letters); 0 = not in the alphabet. +#[derive(Clone, Debug)] +pub(crate) struct Alphabet { + ascii: [u8; 128], + other: Vec<(char, u8)>, + next: u8, +} + +impl Default for Alphabet { + fn default() -> Self { + let mut a = Alphabet { ascii: [0; 128], other: Vec::new(), next: 2 }; + a.ascii[DOT as usize] = 1; + a + } +} + +impl Alphabet { + pub(crate) fn code(&self, c: char) -> u8 { + if (c as u32) < 128 { self.ascii[c as usize] } else { self.other.iter().find(|x| x.0 == c).map_or(0, |x| x.1) } + } + /// Code for `c`, adding it if new (None when the 6-bit alphabet is full). + pub(crate) fn intern(&mut self, c: char) -> Option { + let k = self.code(c); + if k != 0 { + return Some(k); + } + if self.next >= 63 { + return None; + } + let k = self.next; + self.next += 1; + if (c as u32) < 128 { + self.ascii[c as usize] = k; + } else { + self.other.push((c, k)); + } + Some(k) + } +} + +/// Packed key of a code string (≤ [`MAX_PATTERN_LEN`] codes). +#[inline] +pub(crate) fn pack(codes: &[u8]) -> u64 { + let mut k = 0u64; + for &c in codes { + k = (k << 6) | c as u64; + } + k | ((codes.len() as u64) << 58) +} + +/// A compiled pattern set. +#[derive(Clone, Debug, Default)] +pub struct Patterns { + alpha: Alphabet, + /// Packed letters → inter-letter values (`len + 1` entries). + map: FxMap>, + max_len: usize, +} + +impl Patterns { + /// Parse TeX-style patterns: whitespace-separated, `%`/`#` start a comment line. + pub fn parse(text: &str) -> Patterns { + let mut p = Patterns::default(); + for line in text.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with('%') || line.starts_with('#') { + continue; + } + for tok in line.split_whitespace() { + p.insert(tok); + } + } + p + } + + /// Add one pattern like `a1b`; returns false if it can't be represented. + pub(crate) fn insert(&mut self, pat: &str) -> bool { + let mut codes = Vec::with_capacity(pat.len()); + let mut vals = vec![0u8]; + for c in pat.chars() { + if let Some(d) = c.to_digit(10) { + *vals.last_mut().unwrap_or(&mut 0) = d as u8; + } else { + let Some(k) = self.alpha.intern(c) else { return false }; + codes.push(k); + vals.push(0); + } + } + if codes.is_empty() || codes.len() > MAX_PATTERN_LEN { + return false; + } + self.max_len = self.max_len.max(codes.len()); + self.map.insert(pack(&codes), vals.into_boxed_slice()); + true + } + + #[cfg(feature = "generator")] + pub(crate) fn from_parts(alpha: Alphabet, map: FxMap>, max_len: usize) -> Patterns { + Patterns { alpha, map, max_len } + } + + /// Make `letters` part of the alphabet even if no pattern mentions them. + #[cfg(feature = "generator")] + pub(crate) fn add_letters(&mut self, letters: impl IntoIterator) { + for c in letters { + let _ = self.alpha.intern(c); + } + } + + #[cfg(any(test, feature = "generator"))] + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Inter-letter values for a lowercase word: `out[i]` is the value *before* char `i` + /// (`out.len() == word.len() + 1`). None if a char is outside the pattern alphabet. + pub(crate) fn values(&self, word: &[char]) -> Option> { + let mut codes = Vec::with_capacity(word.len() + 2); + codes.push(1); + for &c in word { + let k = self.alpha.code(c); + if k == 0 { + return None; + } + codes.push(k); + } + codes.push(1); + let mut vals = vec![0u8; codes.len() + 1]; + apply(&self.map, self.max_len, &codes, &mut vals); + // Padded position p sits before padded char p; word char i is padded char i + 1. + Some(vals[1..codes.len()].to_vec()) + } + + /// Break points (char indices, a hyphen goes before that char) of a lowercase word. + pub fn points(&self, word: &[char]) -> Option> { + let v = self.values(word)?; + Some((1..word.len()).filter(|&i| v[i] % 2 == 1).collect()) + } + + /// The patterns in TeX notation (sorted by letters), e.g. for writing a pattern file. + #[cfg(any(test, feature = "generator"))] + pub fn to_tex(&self) -> Vec { + let mut rev: Vec<(u8, char)> = + (0u8..128).filter(|&c| self.alpha.ascii[c as usize] != 0).map(|c| (self.alpha.ascii[c as usize], c as char)).collect(); + rev.extend(self.alpha.other.iter().map(|&(c, k)| (k, c))); + let ch = |k: u8| rev.iter().find(|x| x.0 == k).map_or('?', |x| x.1); + let mut out: Vec<(String, String)> = self + .map + .iter() + .map(|(&key, vals)| { + let n = (key >> 58) as usize; + let letters: Vec = (0..n).map(|i| ch(((key >> (6 * (n - 1 - i))) & 63) as u8)).collect(); + let mut s = String::new(); + for (i, l) in letters.iter().enumerate() { + if vals[i] > 0 { + s.push(char::from(b'0' + vals[i])); + } + s.push(*l); + } + if vals[n] > 0 { + s.push(char::from(b'0' + vals[n])); + } + (letters.into_iter().collect(), s) + }) + .collect(); + out.sort(); + out.into_iter().map(|x| x.1).collect() + } +} + +/// Apply `map` to padded `codes`, raising `vals` (len = codes.len() + 1). +#[inline] +pub(crate) fn apply(map: &FxMap>, max_len: usize, codes: &[u8], vals: &mut [u8]) { + let n = codes.len(); + for s in 0..n { + let mut k = 0u64; + for len in 1..=max_len.min(n - s) { + k = (k << 6) | codes[s + len - 1] as u64; + if let Some(v) = map.get(&(k | ((len as u64) << 58))) { + for (slot, &x) in vals.iter_mut().skip(s).zip(v.iter()) { + *slot = (*slot).max(x); + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn liang_example() { + // The classic example from Liang's thesis: "hy-phen-ation". + let p = Patterns::parse("hy3ph he2n hena4 hen5at 1na n2at 1tio 2io o2n"); + let w: Vec = "hyphenation".chars().collect(); + assert_eq!(p.points(&w).unwrap(), vec![2, 6]); + let mut tex = p.to_tex(); + tex.sort(); + assert!(tex.contains(&"hen5at".to_string())); + assert!(p.values(&['h', 'é']).is_none()); + } +} diff --git a/crates/text/src/hyphen/tests.rs b/crates/text/src/hyphen/tests.rs new file mode 100644 index 00000000..be36e4de --- /dev/null +++ b/crates/text/src/hyphen/tests.rs @@ -0,0 +1,356 @@ +use super::*; + +fn h(w: &str) -> String { + hyphenate_word(w, &Limits::default()) +} + +#[test] +fn bundled_data_loads() { + assert!(Dictionary::en_us().len() > 150_000, "{}", Dictionary::en_us().len()); + assert!(Patterns::en_us().len() > 1000, "{}", Patterns::en_us().len()); +} + +#[test] +fn dictionary_words() { + assert_eq!(h("happen"), "hap-pen"); + assert_eq!(h("typography"), "ty-pog-ra-phy"); + assert_eq!(h("composition"), "com-po-si-tion"); + assert_eq!(h("hyphenation"), "hy-phen-a-tion"); + assert_eq!(h("international"), "in-ter-na-tion-al"); + assert_eq!(h("cat"), "cat"); + assert!(!h("changed").contains('-')); + assert_eq!(h("NASA"), "NASA"); + assert_eq!(word_breaks("publication").1, Source::Dictionary); +} + +#[test] +fn case_apostrophes_and_punctuation() { + assert_eq!(h("Typography"), "Ty-pog-ra-phy"); + assert_eq!(h("TYPOGRAPHY"), "TYPOGRAPHY"); + assert_eq!(h("typography,"), "ty-pog-ra-phy,"); + assert_eq!(h("“typography”"), "“ty-pog-ra-phy”"); + assert_eq!(h("typography's"), "ty-pog-ra-phy's"); + assert_eq!(h("typography’s"), "ty-pog-ra-phy’s"); + assert_eq!(h("'typography'"), "'ty-pog-ra-phy'"); + // Compounds: each part separately, never next to the hyphen. + assert_eq!(h("typography-composition"), "ty-pog-ra-phy-com-po-si-tion"); + // Points are byte offsets: the opening quote takes three bytes. + assert_eq!(hyphen_points("“typography”", &Limits::default()), vec![5, 8, 10]); +} + +#[test] +fn inflections_inherit_the_stem() { + assert_eq!(h("ripples"), "rip-ples"); + assert_eq!(h("gradients"), "gra-di-ents"); + assert_eq!(h("restrained"), "re-strained"); +} + +#[test] +fn patterns_cover_unknown_words() { + // Not in the word list: the trained patterns decide. + let (pts, src) = word_breaks("hyperlocalization"); + assert_eq!(src, Source::Patterns); + assert!(pts.len() >= 4, "{}", h("hyperlocalization")); + let (_, src) = word_breaks("zzyzx"); + assert_ne!(src, Source::Dictionary); +} + +#[test] +fn limits_are_respected() { + let lim = Limits { min_word: 5, after_first: 3, before_last: 3, capitalized: false }; + for w in ["typography", "hyphenation", "justification", "Paragraph", "beautiful"] { + for p in hyphen_points(w, &lim) { + assert!(p >= 3 && p <= w.chars().count() - 3, "{w} {p}"); + } + } + assert!(hyphen_points("Paragraph", &lim).is_empty()); + let lim = Limits { min_word: 12, ..Limits::default() }; + assert!(hyphen_points("typography", &lim).is_empty()); +} + +#[test] +fn language_names_and_codes() { + for name in ["English", "English: USA", "english", "$ID/English: UK", "en", "en_US", "en-GB", "EN"] { + assert_eq!(Lang::for_language(name), Some(Lang::English), "{name}"); + } + // Each language resolves by name and by code exactly when its feature is on. + for &(name, code) in LANGUAGES { + let want = hypher::Lang::from_iso(code).map(|l| Lang::Patterns(PatternLang(l))); + let code = std::str::from_utf8(&code).unwrap(); + let mut title = name.chars(); + let title: String = title.next().map(|c| c.to_uppercase().chain(title).collect()).unwrap_or_default(); + let upper = code.to_uppercase(); + for spelling in [ + name.to_string(), + format!("{title}: Reform"), + format!("$ID/{title}"), + code.to_string(), + format!("{code}_{upper}"), + format!("{code}-419"), + format!("{code}_{upper}_2006"), + ] { + assert_eq!(Lang::for_language(&spelling), want, "{spelling}"); + } + assert_eq!(Lang::for_language(&format!("{code}_{upper}_x")), None, "{code}: not a locale code"); + } + for unknown in ["", "[No Language]", "Klingon", "zh_CN", "Chinese: Simplified", "tlh"] { + assert_eq!(Lang::for_language(unknown), None, "{unknown}"); + } +} + +#[cfg(feature = "all-languages")] +#[test] +fn every_language_is_available() { + for &(name, code) in LANGUAGES { + if code == *b"sk" && !cfg!(feature = "slovak-gpl") { + continue; + } + assert!(hypher::Lang::from_iso(code).is_some(), "{name}"); + assert!(Lang::for_language(name).is_some(), "{name}"); + } +} + +/// A virama doesn't split a word: the limits count the whole word, and no point falls before a +/// mark or next to a joiner. +#[cfg(feature = "hindi")] +#[test] +fn indic_word_limits_span_viramas() { + let hi = Lang::for_language("hi").unwrap(); + // न म स ् क ा र: unrestricted points before म, स and र; only स has two letters on each side. + assert_eq!(word_breaks_in("नमस्कार", hi).0, vec![3, 6, 18]); + assert_eq!(hyphen_points_in("नमस्कार", &Limits::default(), hi), vec![6]); + for w in ["नमस्कार", "हिन्दुस्तानी", "प्रौद्योगिकी", "विश्वविद्यालय", "क्ष\u{200D}त्रिय"] + { + for p in word_breaks_in(w, hi).0 { + let (before, after) = w.split_at(p); + let (Some(x), Some(y)) = (before.chars().next_back(), after.chars().next()) else { panic!("{w} at {p}") }; + assert!(!is_mark(y) && !is_joiner(x) && !is_joiner(y), "{w} at {p}"); + } + } +} + +/// Slovak's patterns are GPL-2.0-or-later: only their own feature turns them on, never +/// `all-languages`. +#[test] +fn all_languages_leaves_out_the_gpl_slovak_patterns() { + let manifest = include_str!("../../Cargo.toml"); + let all = manifest.split("all-languages = [").nth(1).and_then(|s| s.split(']').next()).unwrap_or_default(); + assert!(all.contains("\"spanish\""), "all-languages list not found"); + assert!(!all.contains("slovak"), "{all}"); + assert!(manifest.contains("\nslovak-gpl = [\"hyphen\", \"hypher/slovak\"]")); +} + +#[cfg(feature = "spanish")] +#[test] +fn spanish_uses_the_bezos_patterns() { + let es = Lang::for_language("Spanish").unwrap(); + assert_eq!(es, Lang::for_language("es_ES").unwrap()); + let h = |w: &str| { + let pts = hyphen_points_in(w, &Limits::default(), es); + assert!(pts.iter().all(|&p| w.is_char_boundary(p)), "{w} {pts:?}"); + w.char_indices().map(|(i, c)| if pts.contains(&i) { format!("-{c}") } else { c.to_string() }).collect::() + }; + // Offsets are bytes: `ú` and `ó` take two each. + assert_eq!(hyphen_points_in("música", &Limits::default(), es), vec![3, 5]); + assert_eq!(hyphen_points_in("ejército", &Limits::default(), es), vec![5, 7]); + assert_eq!(h("transición"), "tran-si-ción"); + assert_eq!(h("pingüino"), "pin-güino"); + assert_eq!(h("Construcción"), "Cons-truc-ción"); + assert_eq!(h("desesperación"), "de-ses-pe-ra-ción"); + assert_eq!(h("teatro"), "tea-tro", "a vowel run stays whole"); + assert_eq!(h("calle"), "ca-lle", "ll stays whole"); + #[cfg(not(feature = "french"))] + assert!(Lang::for_language("French").is_none(), "only languages built in"); +} + +/// An elided article or preposition keeps the breaks of the word after it, and no break falls +/// next to the apostrophe. +#[cfg(feature = "french")] +#[test] +fn french_elisions_keep_their_breaks() { + let fr = Lang::for_language("French").unwrap(); + let h = |w: &str| { + let pts = hyphen_points_in(w, &Limits::default(), fr); + w.char_indices().map(|(i, c)| if pts.contains(&i) { format!("-{c}") } else { c.to_string() }).collect::() + }; + assert_eq!(h("organisation"), "or-ga-ni-sa-tion"); + assert_eq!(h("l'organisation"), "l'or-ga-ni-sa-tion"); + assert_eq!(h("L’organisation"), "L’or-ga-ni-sa-tion"); + assert_eq!(h("d'information"), "d'in-for-ma-tion"); + assert_eq!(h("aujourd'hui"), "au-jour-d'hui"); +} + +/// The fastest of three timings of `f`, after a warm-up. +fn fastest(f: impl Fn()) -> f64 { + f(); + (0..3) + .map(|_| { + let t = std::time::Instant::now(); + f(); + t.elapsed().as_secs_f64() + }) + .fold(f64::INFINITY, f64::min) +} + +/// `hyphen_points`' limit checks as first written (a rescan of the letter run per point): the +/// reference for the linear version. +fn hyphen_points_ref(word: &str, lim: &Limits) -> Vec { + let chars: Vec = word.chars().collect(); + let (pts, _) = char_breaks(word, Lang::English); + let min_before = lim.after_first.max(1); + let min_after = lim.before_last.max(1); + let run_of = |p: usize| { + let mut a = p; + while a > 0 && is_word_char(chars[a - 1]) { + a -= 1; + } + let mut b = p; + while b < chars.len() && is_word_char(chars[b]) { + b += 1; + } + while a < b && is_apostrophe(chars[a]) { + a += 1; + } + while b > a && is_apostrophe(chars[b - 1]) { + b -= 1; + } + (a, b) + }; + pts.into_iter() + .filter(|&p| { + let (a, b) = run_of(p); + let run = &chars[a..b]; + let letters = run.iter().filter(|c| c.is_alphabetic()).count(); + if letters < lim.min_word.max(2) { + return false; + } + if letters > 1 && run.iter().filter(|c| c.is_alphabetic()).all(|c| c.is_uppercase()) { + return false; + } + if !lim.capitalized && run[0].is_uppercase() { + return false; + } + let before = chars[a..p].iter().filter(|c| c.is_alphabetic()).count(); + let after = chars[p..b].iter().filter(|c| c.is_alphabetic()).count(); + before >= min_before && after >= min_after + }) + .collect() +} + +/// `heuristic_points` as first written (the right part rebuilt per point): the reference. +fn heuristic_ref(c: &[char]) -> Vec { + let n = c.len(); + if n < 4 || !c.iter().all(|c| c.is_alphabetic()) { + return vec![]; + } + let v: Vec = c.iter().map(|&x| is_vowel(x)).collect(); + let mut out = vec![]; + for i in 1..n { + let ok = if v[i - 1] && !v[i] { + (i + 1 < n && v[i + 1]) || (i + 2 < n && onset_pair(c[i], c[i + 1]) && v[i + 2]) + } else if !v[i - 1] && !v[i] { + i >= 2 && v[i - 2] && i + 1 < n && v[i + 1] && !onset_pair(c[i - 1], c[i]) && c[i - 1] != c[i] || (c[i - 1] == c[i] && i >= 2 && v[i - 2]) + } else { + false + }; + let right: String = c[i..].iter().collect(); + let core = right.strip_suffix("ed").or_else(|| right.strip_suffix("es")).or_else(|| right.strip_suffix('e')).unwrap_or(&right); + if ok && core.chars().any(is_vowel) && core.len() > 1 && v[..i].iter().any(|x| *x) { + out.push(i); + } + } + out +} + +#[test] +fn linear_limits_and_heuristic_match_the_reference() { + let long = "hyphenation".repeat(40); + let words = [ + "", + "x", + "''", + "a'b'c", + "cat", + "happen", + "hyphenation", + "Typography's", + "TYPOGRAPHY", + "Typography", + "typography’s", + "'typography'", + "“typography”,", + "typography-composition", + "don't", + "rock'n'roll", + "naïveté", + "crème-brûlée", + "Ünïcödé", + "ÉTUDE", + "strengths", + "ee", + "bed", + "hopped", + "rhythmed", + "aeiouy", + "xxyyzz", + "bookkeeper", + "ʼtwas", + "mid-1990s", + "twenty-one", + "école", + "Ålesund", + "smørrebrød", + "cafe\u{301}-cre\u{300}me", + "e\u{301}tude", + "नमस्कार", + "hopes", + "hoped", + "taed", + "teeed", + &long, + ]; + for w in words { + for min_word in [2, 5, 7] { + for (after_first, before_last) in [(1, 1), (2, 2), (3, 2), (2, 4)] { + for capitalized in [true, false] { + let lim = Limits { min_word, after_first, before_last, capitalized }; + assert_eq!(hyphen_points(w, &lim), byte_offsets(w, hyphen_points_ref(w, &lim)), "{w:?} {lim:?}"); + } + } + } + let c: Vec = w.to_lowercase().chars().collect(); + assert_eq!(heuristic_points(&c), heuristic_ref(&c), "{w:?}"); + } +} + +#[test] +#[ignore = "wall-clock timing; run with --ignored"] +fn hyphenating_a_long_word_is_linear() { + // A word of n letters against one of 4n: linear ~4x the time, the old rescans ~16x. One in + // the pattern alphabet, one outside it (the syllable heuristic). + let pattern = |k: usize| "hyphenation".repeat(k); + let heuristic = |k: usize| "smørrebrød".repeat(k); + assert_eq!(word_breaks(&heuristic(2)).1, Source::Heuristic); + // Each timing repeats the call so the shorter one is milliseconds, well above timer noise. + let ratios: Vec<(String, f64)> = [(pattern as fn(usize) -> String, 20), (heuristic, 40)] + .into_iter() + .map(|(word, repeat)| { + let (small, big) = (word(400), word(1600)); + let time = |w: &str| fastest(|| (0..repeat).for_each(|_| drop(hyphen_points(w, &Limits::default())))); + let (t1, t4) = (time(&small), time(&big)); + let ratio = t4 / t1.max(1e-9); + let what = format!("{}…: t(n) {t1:.4} s, t(4n) {t4:.4} s, ratio {ratio:.1}", word(1).chars().take(10).collect::()); + eprintln!("{what}"); + (what, ratio) + }) + .collect(); + for (what, ratio) in ratios { + assert!(ratio < 8.0, "4x the letters, not linear: {what}"); + } +} + +#[test] +fn heuristic_fallback() { + let c: Vec = "happen".chars().collect(); + assert_eq!(heuristic_points(&c), vec![3]); +} diff --git a/crates/text/src/lib.rs b/crates/text/src/lib.rs new file mode 100644 index 00000000..07795c31 --- /dev/null +++ b/crates/text/src/lib.rs @@ -0,0 +1,25 @@ +#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] + +//! Shared text processing for the Craft apps. It sits below the composer: layout code calls it on +//! plain text and a language before it shapes and places glyphs. +//! +//! Modules, each behind the cargo feature of the same name: +//! - [`hyphen`] (default): hyphenation points, with bundled US English data and optional +//! hypher patterns for 47 more languages (Slovak, under the GPL, only with `slovak-gpl`). +//! - [`segment`] (default): line-break opportunities (UAX #14 with kinsoku), and word breaks for +//! Thai, Lao, Khmer and Burmese with their language features. +//! - [`bidi`] (default): bidirectional text (UAX #9): embedding levels, line reordering and +//! mirroring. +//! - [`linebreak`] (default): line breaking on a font-independent box/glue/penalty model. +//! +//! Language features (`spanish`, `german`, …, `all-languages`) add data for that language and +//! turn on the modules that use it. + +#[cfg(feature = "bidi")] +pub mod bidi; +#[cfg(feature = "hyphen")] +pub mod hyphen; +#[cfg(feature = "linebreak")] +pub mod linebreak; +#[cfg(feature = "segment")] +pub mod segment; diff --git a/crates/text/src/linebreak/greedy.rs b/crates/text/src/linebreak/greedy.rs new file mode 100644 index 00000000..b6dcb606 --- /dev/null +++ b/crates/text/src/linebreak/greedy.rs @@ -0,0 +1,108 @@ +//! Greedy first fit: each line takes as much as fits. + +use super::{INFINITE_PENALTY, Item, Kind, Line, Params, Sums, clamp_measure}; + +/// Break `items` first fit: each line ends at the last break where it still fits its measure +/// `width(k)` with its shrink. A line with no such break ends at the last [`Item::emergency`] +/// break that fits, else before the first box that overflows (never after an +/// [`Item::no_break`]). +pub fn greedy(items: &[Item], width: &dyn Fn(usize) -> f64, p: &Params) -> Vec { + greedy_with(items, width, p, &|_, _, k| items.get(k).map_or(0.0, |i| i.width)) +} + +/// [`greedy`] with box widths that depend on position: `advance(line, x, k)` is the width of box +/// `k` when it starts `x` from the start of line `line` (a tab reaching its stop). It returns +/// `items[k].width` for other boxes. +pub fn greedy_with(items: &[Item], width: &dyn Fn(usize) -> f64, p: &Params, advance: &dyn Fn(usize, f64, usize) -> f64) -> Vec { + let p = &p.sanitized(); + let width = |k: usize| clamp_measure(width(k)); + let s = Sums::new(items); + let m = items.len(); + // Japanese "push out first": break where the line fits without shrinking when there is one. + let avoid_shrink = p.shrink_weight > p.stretch_weight; + let zone = p.rag.map_or(0.0, |r| r.hyphenation_zone); + let zoned = |b: usize| zone > 0.0 && items.get(b).is_some_and(|i| i.is_flagged() && i.hyphenation); + let no_break_before = |k: usize| k > 0 && items.get(k - 1).is_some_and(|i| i.kind == Kind::Penalty && i.cost >= INFINITE_PENALTY); + let mut out = Vec::new(); + let mut start = 0; + let mut line = 0; + let mut hyphens = 0; + loop { + let measure = width(line); + // extra[k - start]: width the boxes before item `k` gained from `advance`. + let mut extra = Vec::new(); + let mut ext = 0.0; + let mut last_ok = None; + let mut last_natural = None; + let mut last_emergency = None; + // (break, line width there) + let mut last_space: Option<(usize, f64)> = None; + let mut k = start; + let (end, next) = loop { + extra.push(ext); + let Some(it) = items.get(k) else { break (m, m) }; + if s.is_break(k) { + if it.is_forced() { + break (k, s.next_start(k)); + } + let blocked = it.is_flagged() && p.hyphen_limit > 0 && hyphens >= p.hyphen_limit; + let f = s.fit(start, k, Some(it), false, measure, p, ext); + if !blocked && f.feasible { + if it.emergency { + last_emergency = Some(k); + } else { + last_ok = Some(k); + if f.width <= measure + p.overrun { + last_natural = Some(k); + } + } + } + if it.kind == Kind::Glue { + last_space = Some((k, f.width)); + } + } else if it.kind == Kind::Box { + let x = s.fit(start, k, None, false, measure, p, ext).width; + ext += advance(line, x, k) - it.width; + if k > start { + // Would a line ending right after this box overflow? (The following break's + // hang and edge elasticity apply; a hyphen is checked at its own break.) + let after = items.get(k + 1).filter(|i| i.kind != Kind::Box).map(|i| Item { width: 0.0, emergency: false, ..*i }); + let f = s.fit(start, k + 1, after.as_ref(), false, measure, p, ext); + if avoid_shrink + && f.width > measure + p.overrun + && let Some(b) = last_natural + { + break (b, s.next_start(b)); + } + if !f.feasible { + match (last_ok, last_emergency) { + (Some(b), _) => { + // Hyphenation zone: break before the word if that leaves little space. + if zoned(b) + && let Some((sp, xs)) = last_space + && measure - xs < zone + { + break (sp, s.next_start(sp)); + } + break (b, s.next_start(b)); + } + (None, Some(b)) => break (b, s.next_start(b)), + (None, None) if !no_break_before(k) => break (k, k), + (None, None) => {} + } + } + } + } + k += 1; + }; + hyphens = if items.get(end).is_some_and(Item::is_flagged) { hyphens + 1 } else { 0 }; + let ext_end = extra.get(end.saturating_sub(start)).copied().unwrap_or(ext); + out.push(s.line(start, end, next, measure, p, ext_end)); + if next >= m { + break; + } + start = next; + line += 1; + } + out +} diff --git a/crates/text/src/linebreak/knuth_plass.rs b/crates/text/src/linebreak/knuth_plass.rs new file mode 100644 index 00000000..71f63c2d --- /dev/null +++ b/crates/text/src/linebreak/knuth_plass.rs @@ -0,0 +1,223 @@ +//! Knuth–Plass total fit: the breaks that minimise the paragraph's summed demerits. + +use super::{Item, Kind, Line, Params, Sums, clamp_measure, fitness_class}; + +/// Give up (return `None`) beyond this many active breaks. +const MAX_ACTIVE: usize = 4096; +/// Ratios beyond this are rated as this (an unstretchable line is infinitely loose). +const MAX_RATIO: f64 = 10_000.0; +/// Demerits of an overfull line accepted because nothing else reaches a break. +const OVERFULL_DEMERITS: f64 = 1e8; + +#[derive(Clone, Copy, Debug)] +struct Node { + /// The break this node ends a line at. + pos: usize, + /// First item of the next line. + start: usize, + /// Number of the next line. + line: usize, + fitness: Option, + demerits: f64, + /// Consecutive lines ending at flagged breaks, up to here. + hyphens: usize, + flagged: bool, + prev: Option, +} + +/// The best way found to reach the current break for one (line class, fitness, hyphen state). +/// Line classes are line numbers below [`Params::uniform_from`], then one class for the rest. +struct Candidate { + line: usize, + fitness: u8, + hyphens: usize, + demerits: f64, + from: usize, +} + +/// One total-fit pass over `items`. `width(k)` is the measure of line `k`; set +/// [`Params::uniform_from`] when it varies. Returns `None` when no set of breaks keeps every line +/// within [`Params::tolerance`] (unless [`Params::overfull`]), or past the active-break limit. +pub fn knuth_plass(items: &[Item], width: &dyn Fn(usize) -> f64, p: &Params) -> Option> { + let p = &p.sanitized(); + let width = |k: usize| clamp_measure(width(k)); + let s = Sums::new(items); + let m = items.len(); + let limit = p.hyphen_limit; + // Hyphen states 0..=limit; unlimited still tells a flagged line (1) from others (0). + let max_hyphens = if limit == 0 { 1 } else { limit }; + let zone = p.rag.map_or(0.0, |r| r.hyphenation_zone); + let mut nodes = vec![Node { pos: 0, start: 0, line: 0, fitness: p.first_fitness, demerits: 0.0, hyphens: 0, flagged: false, prev: None }]; + let mut active: Vec = vec![0]; + let mut keep: Vec = Vec::new(); + let mut best: Vec = Vec::new(); + // The last break at a space (glue), for the hyphenation zone. + let mut last_space: Option = None; + for b in 0..=m { + if !s.is_break(b) { + continue; + } + let item = items.get(b); + let forced = s.forced(b); + let flagged = item.is_some_and(Item::is_flagged); + let cost = item.filter(|i| i.kind == Kind::Penalty).map_or(0.0, |i| i.cost); + best.clear(); + keep.clear(); + let mut last_removed = None; + for &a in &active { + let Some(n) = nodes.get(a).copied() else { continue }; + // The node's next line starts after `b` (the penalties between were discarded): no + // line ends here, but one may end at a later break. + if b < n.start { + keep.push(a); + continue; + } + let measure = width(n.line); + let f = s.measure(n.start, b, measure, p); + // An overfull node is dropped even at a penalty with width (a hyphen), as in TeX, + // although a later break without that width might still fit. + if f.feasible && !forced { + keep.push(a); + } else { + last_removed = Some(a); + } + if !f.feasible || (f.ratio > p.tolerance && !forced) { + continue; + } + if flagged { + if limit > 0 && n.hyphens >= limit { + continue; + } + // Hyphenation zone: break at the space before the word instead when that leaves + // less than the zone at the line end. + if zone > 0.0 + && item.is_some_and(|i| i.hyphenation) + && let Some(sp) = last_space.filter(|&sp| sp >= n.start) + && measure - s.measure(n.start, sp, measure, p).width < zone + { + continue; + } + } + let weight = if f.ratio > 0.0 { + p.stretch_weight + } else if f.ratio < 0.0 { + p.shrink_weight + } else { + 1.0 + }; + let badness = (weight * 100.0 * f.ratio.abs().min(MAX_RATIO).powi(3)).min(p.max_badness); + let lp = p.line_penalty + badness; + let mut d = if forced { + lp * lp + } else if cost >= 0.0 { + lp * lp + cost * cost + } else { + lp * lp - cost * cost + }; + if flagged && n.flagged { + d += p.flagged_demerits; + } + // A ragged line ending at a forced break says nothing about the rag: it keeps its + // neighbour's class. + let class = fitness_class(f.ratio, &p.fitness); + let fitness = if forced && p.rag.is_some() { n.fitness.unwrap_or(class) } else { class }; + if n.fitness.is_some_and(|nf| fitness.abs_diff(nf) > 1) { + d += p.fitness_demerits; + } + let hyphens = if flagged { (n.hyphens + 1).min(max_hyphens) } else { 0 }; + let line = (n.line + 1).min(p.uniform_from); + let demerits = n.demerits + d; + match best.iter_mut().find(|c| c.line == line && c.fitness == fitness && c.hyphens == hyphens) { + Some(c) if c.demerits <= demerits => {} + Some(c) => { + c.demerits = demerits; + c.from = a; + } + None => best.push(Candidate { line, fitness, hyphens, demerits, from: a }), + } + } + if p.overfull + && keep.is_empty() + && best.is_empty() + && let Some(a) = last_removed + && let Some(n) = nodes.get(a) + { + // An overfull line ending here would leave the next line empty up to a forced break: + // end it at that forced break instead. Nor may it pass the hyphen limit: it ends at a + // later break. + let empty_next = !forced && s.items.get(s.next_start(b)).is_some_and(Item::is_forced); + let too_many_hyphens = flagged && limit > 0 && n.hyphens >= limit; + if empty_next || too_many_hyphens { + keep.push(a); + } else { + best.push(Candidate { + line: (n.line + 1).min(p.uniform_from), + fitness: 0, + hyphens: 0, + demerits: n.demerits + OVERFULL_DEMERITS, + from: a, + }); + } + } + std::mem::swap(&mut active, &mut keep); + if item.is_some_and(|i| i.kind == Kind::Glue) { + last_space = Some(b); + } else if forced { + last_space = None; + } + if best.is_empty() { + if active.is_empty() { + return None; + } + continue; + } + let start = s.next_start(b); + // Knuth's pruning: within a line class and hyphen state, a node more than the fitness + // demerits behind the best can never win. + for c in &best { + let min = best.iter().filter(|o| o.line == c.line && o.hyphens == c.hyphens).map(|o| o.demerits).fold(f64::INFINITY, f64::min); + if c.demerits > min + p.fitness_demerits { + continue; + } + let Some(prev) = nodes.get(c.from).copied() else { continue }; + nodes.push(Node { + pos: b, + start, + line: prev.line + 1, + fitness: Some(c.fitness), + demerits: c.demerits, + hyphens: if flagged { prev.hyphens + 1 } else { 0 }, + flagged, + prev: Some(c.from), + }); + active.push(nodes.len() - 1); + } + if active.len() > MAX_ACTIVE { + return None; + } + } + let end = if s.ends_forced() { m - 1 } else { m }; + let last = active + .iter() + .copied() + .filter(|&a| nodes.get(a).is_some_and(|n| n.pos == end && n.prev.is_some())) + .min_by(|&a, &b| nodes[a].demerits.total_cmp(&nodes[b].demerits))?; + let mut chain = Vec::new(); + let mut cur = Some(last); + while let Some(i) = cur { + let n = nodes.get(i)?; + if n.prev.is_some() { + chain.push(n.pos); + } + cur = n.prev; + } + chain.reverse(); + let mut start = 0; + let mut lines = Vec::with_capacity(chain.len()); + for (k, &b) in chain.iter().enumerate() { + let next = s.next_start(b); + lines.push(s.line(start, b, next, width(k), p, 0.0)); + start = next; + } + Some(lines) +} diff --git a/crates/text/src/linebreak/mod.rs b/crates/text/src/linebreak/mod.rs new file mode 100644 index 00000000..d34d50b2 --- /dev/null +++ b/crates/text/src/linebreak/mod.rs @@ -0,0 +1,637 @@ +//! Line breaking on Knuth and Plass's box/glue/penalty model, independent of fonts. +//! +//! A composer turns a paragraph's shaped glyphs into [`Item`]s (boxes for glyphs or words, glue +//! for spaces, penalties for other break opportunities), calls a breaker, and places the glyphs of +//! each returned [`Line`]. Widths are in the caller's units. +//! +//! - [`knuth_plass`]: one total-fit pass at [`Params::tolerance`]. +//! - [`break_paragraph`]: Knuth–Plass passes at rising tolerances, the last accepting overfull +//! lines, then [`greedy`] if no pass succeeds. [`Breaks::method`] says which produced the lines. +//! - [`greedy`] / [`greedy_with`]: first fit, each line takes as much as fits. +//! - [`balanced`]: the line count of [`break_paragraph`] with lines as even as possible. +//! - [`overlong`]: runs of boxes wider than the measure, where a composer may add +//! [`Item::emergency`] breaks. +//! +//! Elasticity comes in [`TIERS`] tiers, used in order: tier 0 (word spaces), then tier 1 (letter +//! spacing), then tier 2 (glyph scaling). Each tier is charged [`Params::tier_cost`] per unit of +//! its ratio, so a breaker prefers word-space changes, then letter spacing, then glyph scaling. +//! +//! Breakers take the measure of line `k` from `width(k)`. They clamp each measure to +//! `0.0..=f64::MAX` (NaN counts as 0) and treat lines from [`Params::uniform_from`] on as having +//! the same measure. + +mod greedy; +mod knuth_plass; +#[cfg(test)] +mod tests; + +use std::ops::Range; + +pub use greedy::{greedy, greedy_with}; +pub use knuth_plass::knuth_plass; + +/// Number of elasticity tiers: word space, letter space, glyph scale. +pub const TIERS: usize = 3; + +/// Stretch or shrink per tier. +pub type Tiers = [f64; TIERS]; + +/// A penalty at least this high forbids a break; one at most its negative forces a break. +pub const INFINITE_PENALTY: f64 = 10_000.0; + +/// Cost of an [`Item::emergency`] break: high, so a paragraph takes no more than it must, but legal. +pub const EMERGENCY_PENALTY: f64 = 5_000.0; + +/// What an [`Item`] is. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum Kind { + /// Fixed material (a glyph, a word). Never a break. + Box, + /// Elastic space. A break when it follows a box; discarded at the start of a line. + Glue, + /// A break opportunity with a cost; adds its width when a line ends there. + Penalty, +} + +/// Tier-0 stretch and shrink that a line gains at one of its ends (see [`Item::edge`]). +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct Edge { + pub stretch: f64, + pub shrink: f64, +} + +/// One item of a paragraph. +/// +/// Build items from a constructor ([`Item::boxed`], [`Item::glue`], [`Item::penalty`], …) and +/// override the optional fields with struct update syntax, such as +/// `Item { hang: 2.0, ..Item::glue(3.0, 1.5, 0.6) }`. Fields added later get neutral values in the +/// constructors, so code written this way keeps compiling. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Item { + pub kind: Kind, + /// Natural width (boxes, glue), or the width a line broken here gains (penalties: a hyphen). + pub width: f64, + /// Stretch per tier. Boxes may carry letter-spacing and glyph-scaling stretch. + pub stretch: Tiers, + /// Shrink per tier. + pub shrink: Tiers, + /// Glue: infinite stretch. A line holding fill glue gives it all its leftover space. + pub fill: bool, + /// Glue: the unit in which stretch past every tier is rated. Lines whose glue has none rate it + /// against their total stretch. + pub overflow: f64, + /// Penalty cost: [`INFINITE_PENALTY`] forbids the break, its negative forces it. + pub cost: f64, + /// Penalty: a flagged (hyphen) break. Consecutive flagged lines cost + /// [`Params::flagged_demerits`] and count toward [`Params::hyphen_limit`]. + pub flagged: bool, + /// Breaks: width a line ending here gives back (punctuation hanging into the margin). + /// Boxes: width a line starting with this box gives back. + pub hang: f64, + /// Tier-0 stretch and shrink that a line ending at this break (glue, penalties) or starting + /// with this box gains; negative values remove elasticity. The line's tier-0 totals are + /// clamped at zero. + pub edge: Edge, + /// Penalty: an automatic or discretionary hyphenation point, subject to + /// [`Rag::hyphenation_zone`]. + pub hyphenation: bool, + /// Penalty: a break inside a word wider than the measure. A justified line ending here that + /// must stretch is rated by its leftover space as a fraction of the measure, so the fullest + /// piece wins. + pub emergency: bool, +} + +const BLANK: Item = Item { + kind: Kind::Box, + width: 0.0, + stretch: [0.0; TIERS], + shrink: [0.0; TIERS], + fill: false, + overflow: 0.0, + cost: 0.0, + flagged: false, + hang: 0.0, + edge: Edge { stretch: 0.0, shrink: 0.0 }, + hyphenation: false, + emergency: false, +}; + +impl Item { + /// A box of `width`. + pub const fn boxed(width: f64) -> Item { + Item { width, ..BLANK } + } + /// Glue of natural `width` with tier-0 `stretch` and `shrink`. + pub const fn glue(width: f64, stretch: f64, shrink: f64) -> Item { + Item { kind: Kind::Glue, width, stretch: [stretch, 0.0, 0.0], shrink: [shrink, 0.0, 0.0], ..BLANK } + } + /// Glue of zero width and infinite stretch: ends a paragraph (before [`Item::forced`]) whose + /// last line is not justified. + pub const fn fill() -> Item { + Item { kind: Kind::Glue, fill: true, ..BLANK } + } + /// A break opportunity costing `cost`, adding `width` when taken. + pub const fn penalty(width: f64, cost: f64, flagged: bool) -> Item { + Item { kind: Kind::Penalty, width, cost, flagged, ..BLANK } + } + /// A forced break. + pub const fn forced() -> Item { + Item::penalty(0.0, -INFINITE_PENALTY, false) + } + /// A break that is never taken (keeps [`greedy`] from splitting two boxes). + pub const fn no_break() -> Item { + Item::penalty(0.0, INFINITE_PENALTY, false) + } + /// An emergency break inside an overlong word (see [`overlong`]). + pub const fn emergency() -> Item { + Item { emergency: true, ..Item::penalty(0.0, EMERGENCY_PENALTY, false) } + } + fn is_forced(&self) -> bool { + self.kind == Kind::Penalty && self.cost <= -INFINITE_PENALTY + } + fn is_flagged(&self) -> bool { + self.kind == Kind::Penalty && self.flagged + } +} + +/// Ragged (unjustified) setting. Spaces keep their width; a line is rated by its leftover space +/// against a rag stretch, as if every line ended with glue of that stretch. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Rag { + /// Rag stretch of every line, in width units. + pub stretch: f64, + /// Rag stretch of every line, as a fraction of its measure (added to `stretch`). + pub width_fraction: f64, + /// A line ending at a forced break that is shorter than this fraction of its measure is rated + /// by the shortfall instead of its leftover space (0 = off). Such lines otherwise cost nothing. + pub short_last: f64, + /// The unit of that shortfall, as a fraction of the measure. + pub short_last_unit: f64, + /// Hyphenation zone: a [`Item::hyphenation`] break is not taken when breaking at the space + /// before its word would leave less than this much space at the end of the line (0 = off). + pub hyphenation_zone: f64, +} + +impl Default for Rag { + fn default() -> Self { + Rag { stretch: 0.0, width_fraction: 1.0 / 6.0, short_last: 0.0, short_last_unit: 1.0 / 3.0, hyphenation_zone: 0.0 } + } +} + +/// How lines are rated and chosen. +/// +/// Breakers clamp `flagged_demerits` and `fitness_demerits` to at least 0, with NaN counting as 0 +/// (negative demerits would let pruning drop the best candidate). Other fields are used as given. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Params { + /// Largest adjustment ratio of a line not ending at a forced break ([`knuth_plass`]). + pub tolerance: f64, + /// When no line reaches a break, accept the overfull line from the last node that could + /// ([`knuth_plass`]), so the pass always succeeds. + pub overfull: bool, + /// Added to every line's badness before squaring. + pub line_penalty: f64, + /// Added when two consecutive lines end at flagged breaks. + pub flagged_demerits: f64, + /// Added when neighbouring lines' fitness classes differ by more than one. + pub fitness_demerits: f64, + /// Upper ratio bounds of fitness classes 0 (tight, `r <` bound), 1 and 2 (`r <=` bound); + /// class 3 (very loose) is above. + pub fitness: [f64; 3], + /// Fitness class assumed before the first line; `None`: the first line pays no fitness demerits. + pub first_fitness: Option, + /// Most consecutive lines ending at flagged breaks (0 = unlimited). A hard constraint: a + /// Knuth–Plass pass that cannot meet it fails, and [`greedy`] breaks before the word instead. + pub hyphen_limit: usize, + /// Ratio charged per unit of each tier. + pub tier_cost: Tiers, + /// Badness cap (badness is `100·|r|³`, times the weight below). + pub max_badness: f64, + /// Badness multiplier of stretched lines. + pub stretch_weight: f64, + /// Badness multiplier of shrunk lines. [`greedy`] avoids shrinking when this exceeds + /// `stretch_weight`. + pub shrink_weight: f64, + /// A line longer than its measure by at most this fits exactly (rounded widths). + pub overrun: f64, + /// First line index from which `width(k)` no longer changes. [`knuth_plass`] keeps the ways + /// to reach a break apart by line number only for earlier lines; from here on they compete + /// directly, which keeps the number of active breaks small. + /// + /// The default 0 suits a constant measure. A caller whose measures vary (a first-line indent, + /// a drop cap, a shaped frame) must set it to the first index of the constant tail, such as 1 + /// for a first-line indent; with a smaller value the lines still get their own measures, but + /// the breaks may not be the best ones. Large values make long paragraphs slow and can exceed + /// the active-break limit, so that [`break_paragraph`] falls back to [`greedy`]. + pub uniform_from: usize, + /// Ragged setting; `None` justifies. + pub rag: Option, +} + +impl Default for Params { + fn default() -> Self { + Params { + tolerance: 2.5, + overfull: false, + line_penalty: 10.0, + flagged_demerits: 3000.0, + fitness_demerits: 3000.0, + fitness: [-0.5, 0.5, 1.0], + first_fitness: Some(1), + hyphen_limit: 0, + tier_cost: [1.0, 0.75, 1.0], + max_badness: f64::INFINITY, + stretch_weight: 1.0, + shrink_weight: 1.0, + overrun: 1e-6, + uniform_from: 0, + rag: None, + } + } +} + +impl Params { + /// These parameters with the clamps documented on [`Params`] applied. + fn sanitized(&self) -> Params { + let non_negative = |x: f64| if x.is_nan() { 0.0 } else { x.max(0.0) }; + Params { flagged_demerits: non_negative(self.flagged_demerits), fitness_demerits: non_negative(self.fitness_demerits), ..*self } + } +} + +/// A measure from a caller's `width`, clamped to `0.0..=f64::MAX` (NaN counts as 0). +fn clamp_measure(m: f64) -> f64 { + if m.is_nan() { 0.0 } else { m.clamp(0.0, f64::MAX) } +} + +/// One line chosen by a breaker. +#[derive(Clone, Copy, Debug, PartialEq)] +#[non_exhaustive] +pub struct Line { + /// First item on the line. + pub start: usize, + /// The break: items `start..end` are on the line. `items.len()` for a paragraph that does not + /// end with a forced break; a box's index where [`greedy`] split a word with no break in it. + pub end: usize, + /// First item of the next line (glue and penalties after the break are discarded). + pub next: usize, + /// Natural width: boxes and glue on the line, plus the break's penalty width, minus hangs. + pub width: f64, + /// The line's measure. + pub measure: f64, + /// Adjustment ratio as rated: positive stretches, negative shrinks. Each tier adds + /// [`Params::tier_cost`] per unit used, so a line that fits may shrink below −1; an overfull + /// line has a negative [`excess`](Self::excess) instead. + pub ratio: f64, + /// Fraction of each tier's stretch (positive) or shrink (negative) the line uses. + pub tiers: Tiers, + /// Width the tiers leave: taken by fill glue or the rag, stretch past every tier when + /// justified (spread over the glue's `overflow`, else its stretch), or the overfull amount + /// when negative. + pub excess: f64, + /// Ended at a flagged penalty. + pub flagged: bool, + /// Ended at a forced break or the paragraph end. + pub forced: bool, +} + +/// Runs of boxes, as item ranges, whose width fully shrunk exceeds `measure`: words no line can +/// hold. A composer adds [`Item::emergency`] breaks inside them where its script allows. +pub fn overlong(items: &[Item], measure: f64) -> Vec> { + let mut out = Vec::new(); + // (first box, last box, width) + let mut run: Option<(usize, usize, f64)> = None; + let mut close = |run: &mut Option<(usize, usize, f64)>| { + if let Some((first, last, w)) = run.take() + && w > measure + { + out.push(first..last + 1); + } + }; + for (k, it) in items.iter().enumerate() { + match it.kind { + Kind::Box => { + let w = it.width - it.shrink.iter().sum::(); + run = Some(run.map_or((k, k, w), |(first, _, acc)| (first, k, acc + w))); + } + Kind::Penalty if it.cost >= INFINITE_PENALTY => {} + Kind::Glue | Kind::Penalty => close(&mut run), + } + } + close(&mut run); + out +} + +/// Which breaker produced a paragraph's lines. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum Method { + /// The [`knuth_plass`] pass at `tolerances[pass]`. + KnuthPlass { pass: usize }, + /// [`greedy`], because every Knuth–Plass pass failed or there were none. + Greedy, +} + +/// Lines from [`break_paragraph`] or [`balanced`]. +#[derive(Clone, Debug, PartialEq)] +#[non_exhaustive] +pub struct Breaks { + pub lines: Vec, + /// The breaker that produced `lines`. + pub method: Method, + /// [`balanced`] evened the lines. Always false from [`break_paragraph`]. + pub balanced: bool, +} + +/// [`knuth_plass`] at each of `tolerances` in turn, the last pass also accepting overfull lines; +/// [`greedy`] if every pass fails or `tolerances` is empty. The last pass fails only past the +/// active-break limit (see [`Params::uniform_from`]). +pub fn break_paragraph(items: &[Item], width: &dyn Fn(usize) -> f64, params: &Params, tolerances: &[f64]) -> Breaks { + for (pass, &tolerance) in tolerances.iter().enumerate() { + let overfull = params.overfull || pass + 1 == tolerances.len(); + if let Some(lines) = knuth_plass(items, width, &Params { tolerance, overfull, ..*params }) { + return Breaks { lines, method: Method::KnuthPlass { pass }, balanced: false }; + } + } + Breaks { lines: greedy(items, width, params), method: Method::Greedy, balanced: false } +} + +/// Paragraphs with more items than this are not balanced (each balancing step breaks the whole +/// paragraph again). +pub const MAX_BALANCED_ITEMS: usize = 6000; + +/// Balance lines: keep [`break_paragraph`]'s line count but make the lines as even as possible, +/// by breaking against the narrowest scaled measure that still gives that many lines. The lines +/// are measured against the real `width`. Meant for ragged text; justified text is balanced the +/// same way, so its lines stretch more. +/// +/// Returns [`break_paragraph`]'s lines with [`Breaks::balanced`] false when the paragraph has +/// fewer than two lines, a forced break before its last line, more than [`MAX_BALANCED_ITEMS`] +/// items, or when no narrower measure keeps the line count. +pub fn balanced(items: &[Item], width: &dyn Fn(usize) -> f64, params: &Params, tolerances: &[f64]) -> Breaks { + let base = break_paragraph(items, width, params, tolerances); + let n = base.lines.len(); + if n < 2 || items.len() > MAX_BALANCED_ITEMS || base.lines[..n - 1].iter().any(|l| l.forced) { + return base; + } + let attempt = |f: f64| -> Option { + let w = |j: usize| clamp_measure(width(j)) * f; + let b = break_paragraph(items, &w, params, tolerances); + (b.lines.len() == n && b.lines.iter().enumerate().all(|(j, l)| l.width <= w(j) + params.overrun)).then_some(b) + }; + let (mut lo, mut hi) = (0.3, 1.0); + let mut best = None; + for _ in 0..14 { + let mid = (lo + hi) / 2.0; + match attempt(mid) { + Some(lines) => { + best = Some(lines); + hi = mid; + } + None => lo = mid, + } + } + let Some(best) = best else { return base }; + let sums = Sums::new(items); + let p = params.sanitized(); + let lines = best.lines.iter().enumerate().map(|(j, l)| sums.line(l.start, l.end, l.next, clamp_measure(width(j)), &p, 0.0)).collect(); + Breaks { lines, method: best.method, balanced: true } +} + +/// How a line fits its measure. +#[derive(Clone, Copy, Debug)] +struct Fit { + width: f64, + ratio: f64, + tiers: Tiers, + excess: f64, + /// Fits with the shrink available. + feasible: bool, +} + +/// Prefix sums of a paragraph's items, for measuring any line in constant time. +struct Sums<'a> { + items: &'a [Item], + /// Before item `k`: width of boxes and glue, their stretch and shrink, glue overflow and the + /// number of fill glues. + w: Vec, + y: Vec, + z: Vec, + over: Vec, + fill: Vec, +} + +impl<'a> Sums<'a> { + fn new(items: &'a [Item]) -> Self { + let m = items.len(); + let (mut w, mut y, mut z, mut over, mut fill) = + (Vec::with_capacity(m + 1), Vec::with_capacity(m + 1), Vec::with_capacity(m + 1), Vec::with_capacity(m + 1), Vec::with_capacity(m + 1)); + let (mut sw, mut sy, mut sz, mut so, mut sf) = (0.0, [0.0; TIERS], [0.0; TIERS], 0.0, 0); + for it in items { + w.push(sw); + y.push(sy); + z.push(sz); + over.push(so); + fill.push(sf); + if it.kind != Kind::Penalty { + sw += it.width; + for t in 0..TIERS { + sy[t] += it.stretch[t]; + sz[t] += it.shrink[t]; + } + } + if it.kind == Kind::Glue { + so += it.overflow; + sf += u32::from(it.fill); + } + } + w.push(sw); + y.push(sy); + z.push(sz); + over.push(so); + fill.push(sf); + Sums { items, w, y, z, over, fill } + } + + fn len(&self) -> usize { + self.items.len() + } + + /// The paragraph ends with a forced penalty (else its end is an implicit forced break). + fn ends_forced(&self) -> bool { + self.items.last().is_some_and(Item::is_forced) + } + + /// Is `b` a legal break? `len()` is one unless the items end with a forced penalty. + fn is_break(&self, b: usize) -> bool { + match self.items.get(b) { + None => b == self.len() && !self.ends_forced(), + Some(it) => match it.kind { + Kind::Box => false, + Kind::Penalty => it.cost < INFINITE_PENALTY, + Kind::Glue => b > 0 && self.items.get(b - 1).is_some_and(|p| p.kind == Kind::Box), + }, + } + } + + fn forced(&self, b: usize) -> bool { + self.items.get(b).map_or(b >= self.len(), Item::is_forced) + } + + /// First item of the line after a break at `b`: glue and penalties are discarded up to the next + /// box or forced break. + fn next_start(&self, b: usize) -> usize { + let mut i = b + 1; + while let Some(it) = self.items.get(i) { + if it.kind == Kind::Box || it.is_forced() { + break; + } + i += 1; + } + i.min(self.len()) + } + + fn at(&self, k: usize) -> (f64, Tiers, Tiers, f64, u32) { + let k = k.min(self.len()); + ( + self.w.get(k).copied().unwrap_or(0.0), + self.y.get(k).copied().unwrap_or_default(), + self.z.get(k).copied().unwrap_or_default(), + self.over.get(k).copied().unwrap_or(0.0), + self.fill.get(k).copied().unwrap_or(0), + ) + } + + /// How items `start..end` fit `measure`, ending at `brk` (a glue or penalty whose hang, edge + /// elasticity and penalty width apply; `None` at the paragraph end or a split between boxes). + /// `extra` is added to the natural width (boxes whose width depends on position). + #[allow(clippy::too_many_arguments)] + fn fit(&self, start: usize, end: usize, brk: Option<&Item>, forced: bool, measure: f64, p: &Params, extra: f64) -> Fit { + let (w0, y0, z0, o0, f0) = self.at(start); + let (w1, y1, z1, o1, f1) = self.at(end); + let (start_hang, start_edge) = + self.items.get(start).filter(|i| i.kind == Kind::Box && end > start).map_or((0.0, Edge::default()), |b| (b.hang, b.edge)); + let (pw, end_hang, end_edge, emergency) = brk + .filter(|i| i.kind != Kind::Box) + .map_or((0.0, 0.0, Edge::default(), false), |i| (if i.kind == Kind::Penalty { i.width } else { 0.0 }, i.hang, i.edge, i.emergency)); + let width = w1 - w0 + pw - start_hang - end_hang + extra; + let mut y = [0.0; TIERS]; + let mut z = [0.0; TIERS]; + for t in 0..TIERS { + y[t] = y1[t] - y0[t]; + z[t] = z1[t] - z0[t]; + } + y[0] = (y[0] + start_edge.stretch + end_edge.stretch).max(0.0); + z[0] = (z[0] + start_edge.shrink + end_edge.shrink).max(0.0); + let mut d = measure - width; + if d < 0.0 && d > -p.overrun { + d = 0.0; + } + let free = |ratio: f64| Fit { width, ratio, tiers: [0.0; TIERS], excess: d, feasible: true }; + if d < 0.0 { + let (ratio, tiers, excess, feasible) = tiered(d, &z, 0.0, &p.tier_cost); + return Fit { width, ratio, tiers, excess, feasible }; + } + if let Some(rag) = p.rag { + if forced && rag.short_last > 0.0 { + let short = measure * rag.short_last - width; + let unit = measure * rag.short_last_unit; + return free(if short <= 0.0 { + 0.0 + } else if unit > 0.0 { + short / unit + } else { + f64::INFINITY + }); + } + if f1 > f0 { + return free(0.0); + } + let s = rag.stretch + rag.width_fraction * measure; + return free(if d <= 0.0 { + 0.0 + } else if s > 0.0 { + d / s + } else { + f64::INFINITY + }); + } + if f1 > f0 { + return free(0.0); + } + let (mut ratio, tiers, excess, feasible) = tiered(d, &y, o1 - o0, &p.tier_cost); + if emergency && ratio > 0.0 && measure > 0.0 { + ratio = d / measure; + } + Fit { width, ratio, tiers, excess, feasible } + } + + /// Measure the break at `b` for a line starting at `start` (`b == len()`: the paragraph end). + fn measure(&self, start: usize, b: usize, measure: f64, p: &Params) -> Fit { + self.fit(start, b, self.items.get(b), self.forced(b), measure, p, 0.0) + } + + fn line(&self, start: usize, end: usize, next: usize, measure: f64, p: &Params, extra: f64) -> Line { + let brk = self.items.get(end).filter(|i| i.kind != Kind::Box); + let forced = brk.map_or(end >= self.len(), Item::is_forced); + let f = self.fit(start, end, brk, forced, measure, p, extra); + Line { + start, + end, + next, + width: f.width, + measure, + ratio: f.ratio, + tiers: f.tiers, + excess: f.excess, + flagged: brk.is_some_and(Item::is_flagged), + forced, + } + } +} + +/// Adjustment ratio for `d` units of stretch (`d > 0`) or shrink (`d < 0`) from tier capacities +/// `cap`, used in tier order and charged `cost` per unit of each tier's ratio. Returns the ratio, +/// the fraction of each tier used (negative when shrinking), the width left over and whether the +/// line is feasible: shrinking past every tier is not. Stretch past every tier is rated in units +/// of `over`, or of the total stretch when `over` is zero. +fn tiered(d: f64, cap: &Tiers, over: f64, cost: &Tiers) -> (f64, Tiers, f64, bool) { + const EPS: f64 = 1e-9; + let mut used = [0.0; TIERS]; + if d.abs() < EPS { + return (0.0, used, d, true); + } + let sign = d.signum(); + let mut rem = d.abs(); + let mut r = 0.0; + for t in 0..TIERS { + if cap[t] > EPS && rem > EPS { + let take = rem.min(cap[t]); + r += cost[t] * take / cap[t]; + used[t] = sign * take / cap[t]; + rem -= take; + } + } + let excess = sign * rem; + if d < 0.0 { + return (-r, used, excess, rem <= 1e-6); + } + if rem > 1e-6 { + let unit = if over > EPS { over } else { cap.iter().sum::() }; + r = if unit > EPS { r + rem / unit } else { f64::INFINITY }; + } + (r, used, excess, true) +} + +/// Fitness class 0 (tight) … 3 (very loose) of ratio `r`. +fn fitness_class(r: f64, bounds: &[f64; 3]) -> u8 { + if r < bounds[0] { + 0 + } else if r <= bounds[1] { + 1 + } else if r <= bounds[2] { + 2 + } else { + 3 + } +} diff --git a/crates/text/src/linebreak/tests.rs b/crates/text/src/linebreak/tests.rs new file mode 100644 index 00000000..a9cc150b --- /dev/null +++ b/crates/text/src/linebreak/tests.rs @@ -0,0 +1,476 @@ +//! Breaker tests on a monospaced model: letters are 6 units wide, spaces 3, hyphens 4. Parameter +//! sets mirror vectorcraft's and designcraft's composers. + +use super::*; + +const CHAR: f64 = 6.0; +const SPACE: f64 = 3.0; +const HYPHEN: f64 = 4.0; + +const COPY: &str = "Typography is the craft of arranging type to make written language legible, readable and appealing when displayed. \ +The arrangement of type involves selecting typefaces, point sizes, line lengths, line spacing and letter spacing, and adjusting the space \ +between pairs of letters."; + +/// A paragraph's items and the text each item stands for. +struct Para { + items: Vec, + text: Vec, +} + +impl Para { + /// A box per word and glue per space (elastic unless ragged); with `hyphen_cost`, a + /// hyphenation point every two letters inside words of six letters or more. Ends with fill and + /// a forced break. + fn new(text: &str, p: &Params, hyphen_cost: Option) -> Para { + let mut para = Para { items: Vec::new(), text: Vec::new() }; + for (i, word) in text.split(' ').enumerate() { + if i > 0 { + let glue = if p.rag.is_some() { Item::glue(SPACE, 0.0, 0.0) } else { Item::glue(SPACE, SPACE / 2.0, SPACE / 5.0) }; + para.push(glue, " "); + } + let chars: Vec = word.chars().collect(); + let points: Vec = match hyphen_cost { + Some(_) if chars.len() >= 6 => (2..chars.len() - 2).step_by(2).collect(), + _ => Vec::new(), + }; + let mut from = 0; + for &at in points.iter().chain([chars.len()].iter()) { + let piece: String = chars[from..at].iter().collect(); + para.push(Item::boxed(width_of(&piece)), &piece); + if at < chars.len() { + para.push(Item { hyphenation: true, ..Item::penalty(HYPHEN, hyphen_cost.unwrap_or(0.0), true) }, ""); + } + from = at; + } + } + para.push(Item::fill(), ""); + para.push(Item::forced(), ""); + para + } + + fn push(&mut self, item: Item, text: &str) { + self.items.push(item); + self.text.push(text.to_string()); + } + + fn lines(&self, lines: &[Line]) -> Vec { + lines + .iter() + .map(|l| { + let s: String = self.text[l.start..l.end.min(self.text.len())].concat(); + let s = s.trim_end().to_string(); + if l.flagged { s + "-" } else { s } + }) + .collect() + } +} + +fn width_of(s: &str) -> f64 { + s.chars().map(|c| if c == ' ' { SPACE } else { CHAR }).sum() +} + +fn vectorcraft(ragged: bool) -> Params { + Params { + fitness_demerits: if ragged { 1000.0 } else { 10_000.0 }, + fitness: if ragged { [0.15, 0.4, 0.75] } else { [-0.5, 0.5, 1.0] }, + first_fitness: None, + max_badness: 10_000.0, + rag: ragged.then_some(Rag { + stretch: 0.0, + width_fraction: 1.0 / 6.0, + short_last: 1.0 / 3.0, + short_last_unit: 1.0 / 3.0, + hyphenation_zone: 0.0, + }), + ..Params::default() + } +} + +/// vectorcraft's every-line composer: a strict pass, then a loose one, then single-line. +fn every_line(items: &[Item], width: f64, ragged: bool) -> Vec { + let p = vectorcraft(ragged); + let w = |_| width; + let loose = if ragged { f64::INFINITY } else { 4.0 }; + knuth_plass(items, &w, &Params { tolerance: 1.0, ..p }) + .or_else(|| knuth_plass(items, &w, &Params { tolerance: loose, ..p })) + .unwrap_or_else(|| greedy(items, &w, &p)) +} + +fn designcraft(ragged: bool) -> Params { + Params { + hyphen_limit: 3, + overrun: 0.01, + uniform_from: 0, + rag: ragged.then_some(Rag { stretch: 24.0, width_fraction: 0.0, ..Rag::default() }), + ..Params::default() + } +} + +const PASSES: [f64; 3] = [2.5, 12.0, f64::INFINITY]; + +/// Lines are contiguous and cover every item. +fn assert_covers(items: &[Item], lines: &[Line]) { + assert_eq!(lines.first().map(|l| l.start), Some(0)); + for pair in lines.windows(2) { + assert_eq!(pair[0].next, pair[1].start, "{lines:?}"); + } + assert_eq!(lines.last().map(|l| l.next), Some(items.len())); +} + +#[test] +fn tiers_are_used_in_order() { + let cost = Params::default().tier_cost; + // Word stretch alone. + let (r, used, _, ok) = tiered(5.0, &[10.0, 10.0, 10.0], 10.0, &cost); + assert!(ok && (r - 0.5).abs() < 1e-9 && used == [0.5, 0.0, 0.0]); + // Word saturated, half the letter tier. + let (r, used, _, _) = tiered(15.0, &[10.0, 10.0, 10.0], 10.0, &cost); + assert!((r - (1.0 + 0.5 * cost[1])).abs() < 1e-9 && used == [1.0, 0.5, 0.0]); + // Beyond every tier: unbounded word spacing. + let (r, _, excess, _) = tiered(40.0, &[10.0, 10.0, 10.0], 10.0, &cost); + assert!(r > 2.0 && (excess - 10.0).abs() < 1e-9); + // Shrink beyond the tiers is infeasible. + assert!(!tiered(-25.0, &[10.0, 10.0, 0.0], 0.0, &cost).3); + assert!(tiered(-15.0, &[10.0, 10.0, 0.0], 0.0, &cost).3); +} + +#[test] +fn lines_fit_and_cover_the_paragraph() { + let text = [COPY; 2].join(" "); + for ragged in [false, true] { + for hyphen in [None, Some(50.0)] { + let p = vectorcraft(ragged); + let para = Para::new(&text, &p, hyphen); + for (name, lines) in [("every-line", every_line(¶.items, 180.0, ragged)), ("greedy", greedy(¶.items, &|_| 180.0, &p))] { + assert!(lines.len() > 10, "{name}"); + assert_covers(¶.items, &lines); + for l in &lines { + assert!(l.excess >= -p.overrun, "{name} ragged={ragged} {l:?}"); + if ragged { + assert!(l.width <= 180.0 + 1e-6, "{name} {l:?}"); + } + } + assert!(lines.last().is_some_and(|l| l.forced)); + } + } + } +} + +/// Every-line breaking spreads the spacing more evenly than greedy breaking. +#[test] +fn every_line_is_more_even_than_greedy() { + let text = [COPY; 2].join(" "); + let p = vectorcraft(false); + let para = Para::new(&text, &p, None); + for width in [150.0, 190.0, 240.0] { + let worst = |lines: &[Line]| lines[..lines.len() - 1].iter().map(|l| l.ratio).fold(0.0, f64::max); + let (kp, gr) = (worst(&every_line(¶.items, width, false)), worst(&greedy(¶.items, &|_| width, &p))); + assert!(kp <= gr + 1e-9, "{width}: every-line worst ratio {kp} vs greedy {gr}"); + } +} + +/// Ragged: every-line breaks before a word that would fit, so the last line is not a lone short +/// word; greedy keeps filling the first line. +#[test] +fn every_line_balances_ragged_lines() { + const S: &str = "Destroy all creatures with toughness X or less."; + let width = width_of("Destroy all creatures with toughness X or") + 2.0; + let p = vectorcraft(true); + let para = Para::new(S, &p, None); + assert_eq!(para.lines(&greedy(¶.items, &|_| width, &p)), ["Destroy all creatures with toughness X or", "less."]); + assert_eq!(para.lines(&every_line(¶.items, width, true)), ["Destroy all creatures with toughness X", "or less."]); +} + +/// Every-line evens the rag of a long ragged paragraph: the leftover space is no worse than greedy +/// breaking, with at most one line more. Hyphenated, it trades some rag for fewer hyphens. +#[test] +fn every_line_evens_the_rag() { + let text = [COPY; 2].join(" "); + let p = vectorcraft(true); + for (width, hyphen) in [(150.0, None), (190.0, None), (240.0, Some(25.0)), (310.0, None)] { + let para = Para::new(&text, &p, hyphen); + let rag = |lines: &[Line]| { + for l in lines { + assert!(l.width <= width + 1e-6, "{width}: {l:?}"); + } + let slack = lines[..lines.len() - 1].iter().map(|l| (width - l.width).powi(2)).sum::(); + (slack, lines.len(), lines.iter().filter(|l| l.flagged).count()) + }; + let ((kp, kp_n, kp_hy), (gr, gr_n, gr_hy)) = (rag(&every_line(¶.items, width, true)), rag(&greedy(¶.items, &|_| width, &p))); + if hyphen.is_some() { + assert!(kp_hy < gr_hy, "{width}: {kp_hy} hyphens vs greedy {gr_hy}"); + } else { + assert!(kp <= gr + 1e-6, "{width}: rag {kp} vs greedy {gr}"); + } + assert!(kp_n <= gr_n + 1, "{width}: {kp_n} lines vs {gr_n}"); + } +} + +/// Greedy: each line takes as many words as fit. +#[test] +fn greedy_fills_each_line() { + let width = 190.0; + let p = vectorcraft(true); + let para = Para::new(COPY, &p, None); + let lines = para.lines(&greedy(¶.items, &|_| width, &p)); + for pair in lines.windows(2) { + let next_word = pair[1].split(' ').next().unwrap_or_default(); + assert!(width_of(&format!("{} {next_word}", pair[0])) > width, "{pair:?}"); + } +} + +#[test] +fn hyphen_limit_is_a_hard_constraint() { + let text = [COPY; 4].join(" "); + for limit in [1, 2, 9] { + let p = Params { hyphen_limit: limit, ..designcraft(false) }; + let para = Para::new(&text, &p, Some(0.0)); + for lines in [break_paragraph(¶.items, &|_| 130.0, &p, &PASSES).lines, greedy(¶.items, &|_| 130.0, &p)] { + let mut run = 0; + for l in &lines { + run = if l.flagged { run + 1 } else { 0 }; + assert!(run <= limit, "{run} consecutive hyphens with limit {limit}"); + } + assert!(lines.iter().any(|l| l.flagged)); + } + } +} + +#[test] +fn hyphenation_zone_limits_ragged_hyphens() { + let text = [COPY; 4].join(" "); + let measure = 110.0; + let count = |zone: f64, every_line: bool| { + let base = designcraft(true); + let p = Params { rag: base.rag.map(|r| Rag { hyphenation_zone: zone, ..r }), ..base }; + let para = Para::new(&text, &p, Some(0.0)); + let lines = if every_line { break_paragraph(¶.items, &|_| measure, &p, &PASSES).lines } else { greedy(¶.items, &|_| measure, &p) }; + // A hyphenated line leaves at least the zone after the last space before its last word. + for l in lines.iter().filter(|l| l.flagged) { + if let Some(space) = (l.start..l.end).rfind(|&k| para.items[k].kind == Kind::Glue) { + let before: f64 = para.items[l.start..space].iter().filter(|i| i.kind != Kind::Penalty).map(|i| i.width).sum(); + assert!(measure - before >= zone, "every_line={every_line} zone {zone}: {:?}", para.lines(&[*l])); + } + } + lines.iter().filter(|l| l.flagged).count() + }; + for every_line in [true, false] { + let (free, zoned, huge) = (count(0.0, every_line), count(36.0, every_line), count(1000.0, every_line)); + // A huge zone leaves only words that start a line hyphenable. + assert!(free > 0 && zoned > 0 && huge * 4 <= free, "every_line={every_line}: {free} {zoned} {huge}"); + } +} + +#[test] +fn balanced_lines_even_a_headline() { + let p = Params { rag: Some(Rag { stretch: 24.0, width_fraction: 0.0, ..Rag::default() }), ..designcraft(true) }; + let para = Para::new("Balanced headlines read better than a stub", &p, None); + let w = |_| 150.0; + let plain = break_paragraph(¶.items, &w, &p, &PASSES).lines; + let bal = balanced(¶.items, &w, &p, &PASSES); + assert!(bal.balanced); + let bal = bal.lines; + assert!(plain.len() >= 2 && plain.len() == bal.len(), "{:?} vs {:?}", para.lines(&plain), para.lines(&bal)); + let spread = |lines: &[Line]| lines.iter().map(|l| l.width).fold(f64::MIN, f64::max) - lines.iter().map(|l| l.width).fold(f64::MAX, f64::min); + assert!(spread(&bal) < spread(&plain), "{:?} vs {:?}", para.lines(&bal), para.lines(&plain)); + assert!(bal.iter().all(|l| l.measure == 150.0)); +} + +/// A word wider than the measure breaks at its emergency points, or, for greedy without them, +/// before the box that overflows. +#[test] +fn an_overlong_word_breaks_at_the_measure() { + let build = |emergency: bool, ragged: bool| { + let p = designcraft(ragged); + let glue = if ragged { Item::glue(SPACE, 0.0, 0.0) } else { Item::glue(SPACE, SPACE / 2.0, SPACE / 5.0) }; + let mut items = vec![Item::boxed(4.0 * CHAR), glue]; + for i in 0..60 { + if i > 0 && emergency { + items.push(Item::emergency()); + } + items.push(Item::boxed(CHAR)); + } + items.extend([glue, Item::boxed(3.0 * CHAR), glue, Item::boxed(2.0 * CHAR), Item::fill(), Item::forced()]); + (items, p) + }; + let (plain, _) = build(false, false); + assert_eq!(overlong(&plain, 72.0), vec![2..62]); + for ragged in [false, true] { + let (items, p) = build(true, ragged); + let (no_points, _) = build(false, ragged); + for (name, lines) in [ + ("every-line", break_paragraph(&items, &|_| 72.0, &p, &PASSES).lines), + ("greedy", greedy(&items, &|_| 72.0, &p)), + ("greedy, no emergency points", greedy(&no_points, &|_| 72.0, &p)), + ] { + assert!(lines.len() >= 6, "{name} ragged={ragged}: {lines:?}"); + for l in &lines { + assert!(l.width <= 72.0 + 0.01, "{name} ragged={ragged}: {l:?}"); + } + } + } +} + +#[test] +fn forced_breaks_end_lines_and_the_paragraph_end_is_one() { + let p = designcraft(false); + // No forced penalty at the end: the paragraph end is the last break. + let items = [Item::boxed(30.0), Item::glue(SPACE, 1.5, 0.6), Item::boxed(30.0), Item::fill(), Item::forced(), Item::boxed(30.0)]; + for lines in [break_paragraph(&items, &|_| 100.0, &p, &PASSES).lines, greedy(&items, &|_| 100.0, &p)] { + assert_eq!(lines.iter().map(|l| (l.start, l.end, l.forced)).collect::>(), [(0, 4, true), (5, 6, true)]); + // The last line is justified: it has no fill and nothing to stretch. + assert!(lines[1].ratio.is_infinite()); + } + // Empty paragraph: one empty line. + for lines in [break_paragraph(&[], &|_| 100.0, &p, &PASSES).lines, greedy(&[], &|_| 100.0, &p)] { + assert_eq!(lines.iter().map(|l| (l.start, l.end, l.next)).collect::>(), [(0, 0, 0)]); + } +} + +/// The measure is per line: a first-line indent narrows line 0 only. +#[test] +fn each_line_gets_its_own_measure() { + let p = Params { uniform_from: 1, ..vectorcraft(true) }; + let para = Para::new(COPY, &p, None); + let w = |k: usize| if k == 0 { 120.0 } else { 200.0 }; + for lines in [break_paragraph(¶.items, &w, &p, &[1.0, f64::INFINITY]).lines, greedy(¶.items, &w, &p)] { + for (k, l) in lines.iter().enumerate() { + assert_eq!(l.measure, w(k)); + assert!(l.width <= w(k) + 1e-6, "{k}: {l:?}"); + } + assert!(lines[1].width > 120.0); + } +} + +/// Punctuation hanging into the margin gives its width back: the line fits with the word after it. +#[test] +fn a_hanging_break_gives_its_width_back() { + let p = designcraft(true); + let items = |hang: f64| { + [ + Item::boxed(60.0), + Item::glue(5.0, 0.0, 0.0), + Item::boxed(40.0), + Item { hang, ..Item::glue(5.0, 0.0, 0.0) }, + Item::boxed(30.0), + Item::fill(), + Item::forced(), + ] + }; + for (hang, end) in [(0.0, 1), (5.0, 3)] { + let items = items(hang); + for lines in [break_paragraph(&items, &|_| 100.0, &p, &PASSES).lines, greedy(&items, &|_| 100.0, &p)] { + assert_eq!(lines[0].end, end, "hang {hang}: {lines:?}"); + } + } +} + +/// Justification uses word spacing first, then letter spacing. +#[test] +fn justification_uses_tiers_in_order() { + let p = designcraft(false); + let letters = Item { stretch: [0.0, 10.0, 0.0], ..Item::boxed(40.0) }; + let items = [letters, Item::glue(10.0, 6.0, 0.0), letters, Item::forced()]; + let lines = break_paragraph(&items, &|_| 100.0, &p, &PASSES).lines; + let l = lines[0]; + assert_eq!(l.tiers, [1.0, 0.2, 0.0]); + assert!((l.ratio - (1.0 + 0.2 * p.tier_cost[1])).abs() < 1e-9, "{l:?}"); +} + +/// Letter spacing and glyph scaling absorb what word spacing alone cannot in a narrow column. +#[test] +fn letter_and_glyph_tiers_ease_a_narrow_column() { + let worst = |box_stretch: f64| { + let p = designcraft(false); + let mut para = Para::new(COPY, &p, Some(275.0)); + for it in para.items.iter_mut().filter(|i| i.kind == Kind::Box) { + it.stretch = [0.0, it.width * box_stretch, it.width * box_stretch]; + it.shrink = [0.0, it.width * box_stretch / 2.0, it.width * box_stretch / 2.0]; + } + let lines = break_paragraph(¶.items, &|_| 100.0, &p, &PASSES).lines; + lines[..lines.len() - 1].iter().map(|l| l.ratio).fold(0.0, f64::max) + }; + let (words, all) = (worst(0.0), worst(0.03)); + assert!(all < words, "{all} vs {words}"); +} + +/// A long ragged paragraph with a constant measure breaks by Knuth–Plass under the default +/// parameters and effectcraft's infinitely tolerant rag, without reaching the active-break limit. +#[test] +fn a_long_ragged_paragraph_stays_on_knuth_plass() { + let mut seed = 1u32; + let mut items = Vec::new(); + for i in 0..5000 { + if i > 0 { + items.push(Item::glue(1.0, 0.0, 0.0)); + } + seed = seed.wrapping_mul(1_103_515_245).wrapping_add(12_345); + items.push(Item::boxed(f64::from(3 + (seed >> 16) % 5))); + } + items.extend([Item::fill(), Item::forced()]); + let default = Params { rag: Some(Rag::default()), ..Params::default() }; + let effectcraft = Params { rag: Some(Rag { width_fraction: 1.0, ..Rag::default() }), ..Params::default() }; + for (p, tolerances) in [(default, &[2.5][..]), (effectcraft, &[f64::INFINITY][..])] { + let b = break_paragraph(&items, &|_| 60.0, &p, tolerances); + assert_eq!(b.method, Method::KnuthPlass { pass: 0 }, "{p:?}"); + assert_covers(&items, &b.lines); + } +} + +/// A NaN measure counts as 0 and negative fitness demerits as 0. +#[test] +fn invalid_params_are_clamped() { + let p = designcraft(false); + let para = Para::new(COPY, &p, None); + let lines = break_paragraph(¶.items, &|_| f64::NAN, &p, &PASSES).lines; + assert_eq!(lines, break_paragraph(¶.items, &|_| 0.0, &p, &PASSES).lines); + assert!(lines.iter().all(|l| l.measure == 0.0 && !l.excess.is_nan())); + let negative = Params { fitness_demerits: -5000.0, ..p }; + let zero = Params { fitness_demerits: 0.0, ..p }; + assert_eq!(break_paragraph(¶.items, &|_| 150.0, &negative, &PASSES), break_paragraph(¶.items, &|_| 150.0, &zero, &PASSES)); +} + +/// Two consecutive breaks: the line after the first starts past the second, which must not end a +/// line `4..3` from there. +#[test] +fn lines_never_end_before_they_start() { + let items = [ + Item::boxed(10.0), + Item::glue(1.0, 0.0, 0.0), + Item::penalty(0.0, -1000.0, false), + Item::penalty(0.0, -1000.0, false), + Item::boxed(10.0), + Item::fill(), + Item::forced(), + ]; + let p = Params { rag: Some(Rag { width_fraction: 1.0, ..Rag::default() }), ..Params::default() }; + let lines = break_paragraph(&items, &|_| 11.0, &p, &[2.5, f64::INFINITY]).lines; + assert!(lines.iter().all(|l| l.start <= l.end && l.end <= l.next), "{lines:?}"); + assert_covers(&items, &lines); +} + +fn spans(lines: &[Line]) -> Vec<(usize, usize)> { + lines.iter().map(|l| (l.start, l.end)).collect() +} + +/// A final word wider than the measure is one overfull line: the fill before the forced break +/// doesn't end it and leave an empty line. Consecutive forced breaks still make an empty line. +#[test] +fn an_overlong_last_word_adds_no_empty_line() { + let fill = [Item::boxed(20.0), Item::fill(), Item::forced()]; + assert_eq!(spans(&break_paragraph(&fill, &|_| 11.0, &Params::default(), &[2.5, f64::INFINITY]).lines), [(0, 2)]); + let forced = [Item::boxed(20.0), Item::forced(), Item::forced()]; + assert_eq!(spans(&break_paragraph(&forced, &|_| 11.0, &Params::default(), &[2.5, f64::INFINITY]).lines), [(0, 1), (2, 2)]); +} + +/// Overfull lines keep the hyphen limit too: with a limit of 1, no two consecutive lines end at a +/// hyphen even when every line is overfull. +#[test] +fn overfull_lines_keep_the_hyphen_limit() { + let items = + [Item::boxed(10.0), Item::penalty(1.0, 0.0, true), Item::boxed(10.0), Item::penalty(1.0, 0.0, true), Item::boxed(10.0), Item::forced()]; + let p = Params { hyphen_limit: 1, ..Params::default() }; + let lines = break_paragraph(&items, &|_| 5.0, &p, &[2.5, f64::INFINITY]).lines; + assert!(lines.windows(2).all(|w| !(w[0].flagged && w[1].flagged)), "{lines:?}"); + assert_eq!(spans(&lines), [(0, 1), (2, 5)]); +} diff --git a/crates/text/src/segment/complex.rs b/crates/text/src/segment/complex.rs new file mode 100644 index 00000000..57a625a2 --- /dev/null +++ b/crates/text/src/segment/complex.rs @@ -0,0 +1,50 @@ +//! Word breaks inside Thai, Lao, Khmer and Burmese runs. UAX #14 gives these scripts class SA +//! ("complex context") and leaves breaking inside them to a dictionary; ICU4X's segmenter supplies +//! it, with its dictionaries or, with the `lstm` feature, its LSTM models. Only runs of the scripts +//! whose language feature is on are segmented. + +use icu_segmenter::options::LineBreakOptions; +use icu_segmenter::{LineSegmenter, LineSegmenterBorrowed}; +use unicode_linebreak::{BreakClass, break_property}; + +/// Builds ICU4X's line segmenter with one model for the complex scripts. The models are static +/// data; building the segmenter only looks them up. +pub(super) type Model = fn(LineBreakOptions<'static>) -> LineSegmenterBorrowed<'static>; + +/// The model `line_breaks` uses: the LSTM models with the `lstm` feature, else the dictionaries. +#[cfg(feature = "lstm")] +pub(super) const MODEL: Model = LineSegmenter::new_lstm; +#[cfg(not(feature = "lstm"))] +pub(super) const MODEL: Model = LineSegmenter::new_dictionary; + +/// Byte offsets inside `text` where a run of an enabled script may break between words, in order. +/// Run starts and ends are left to UAX #14. +pub(super) fn word_breaks(text: &str, model: Model) -> Vec { + let mut out = Vec::new(); + let mut segmenter = None; + let mut run_start = None; + let ends = text.char_indices().map(|(i, c)| (i, segmented(c))).chain(std::iter::once((text.len(), false))); + for (i, inside) in ends { + match (run_start, inside) { + (None, true) => run_start = Some(i), + (Some(start), false) => { + run_start = None; + let Some(run) = text.get(start..i) else { continue }; + let seg = *segmenter.get_or_insert_with(|| model(LineBreakOptions::default())); + out.extend(seg.segment_str(run).filter(|&o| o > 0 && o < run.len()).map(|o| start + o)); + } + _ => {} + } + } + out +} + +/// A character of an enabled script that UAX #14 leaves to the word segmenter. +fn segmented(c: char) -> bool { + let u = c as u32; + let enabled = (cfg!(feature = "thai") && matches!(u, 0x0E00..=0x0E7F)) + || (cfg!(feature = "lao") && matches!(u, 0x0E80..=0x0EFF)) + || (cfg!(feature = "khmer") && matches!(u, 0x1780..=0x17FF | 0x19E0..=0x19FF)) + || (cfg!(feature = "burmese") && matches!(u, 0x1000..=0x109F | 0xA9E0..=0xA9FF | 0xAA60..=0xAA7F)); + enabled && break_property(u) == BreakClass::ComplexContext +} diff --git a/crates/text/src/segment/kinsoku.rs b/crates/text/src/segment/kinsoku.rs new file mode 100644 index 00000000..c4d52ba0 --- /dev/null +++ b/crates/text/src/segment/kinsoku.rs @@ -0,0 +1,119 @@ +//! Kinsoku character sets (JLREQ 3.1.7–3.1.8, CLREQ 3.1.7). The sets are VectorCraft's, with the +//! additions listed in the crate README. + +use super::Kinsoku; + +/// Whether kinsoku lets a line break between `before` and `after` (`None`: the end of the +/// paragraph). `Hard` keeps every character of the set off the line start and end; `Soft` lets +/// 々, ー and small kana start a line; `None` allows every break. Breaks with no East Asian +/// character on either side are always allowed, so Latin text keeps its own rules. +pub fn kinsoku_allows(before: char, after: Option, mode: Kinsoku) -> bool { + if mode == Kinsoku::None || (!is_east_asian(before) && !after.is_some_and(is_east_asian)) { + return true; + } + let start_ok = |c: char| !no_line_start(c) || (mode == Kinsoku::Soft && soft_line_start(c)); + !no_line_end(before) && after.is_none_or(start_ok) +} + +/// East Asian text for kinsoku: Han, kana, bopomofo, Hangul syllables and compatibility jamo, CJK +/// punctuation and symbols, full-width and half-width forms. Not the ideographic space, conjoining +/// jamo or the (combining and spacing) kana sound marks, which never take a break before them. +pub(crate) fn is_east_asian(c: char) -> bool { + matches!(c as u32, + 0x2E80..=0x2FFF // radicals, ideographic description + | 0x3001..=0x3096 // CJK symbols and punctuation, hiragana + | 0x309D..=0x30FF // hiragana iteration marks, katakana + | 0x3100..=0x312F // bopomofo + | 0x3131..=0x318F // Hangul compatibility jamo + | 0x3190..=0x33FF // kanbun, strokes, small katakana, enclosed and compatibility forms + | 0x3400..=0x4DBF // CJK extension A + | 0x4E00..=0x9FFF // CJK unified ideographs + | 0xAC00..=0xD7A3 // Hangul syllables + | 0xF900..=0xFAFF // compatibility ideographs + | 0xFE30..=0xFE4F // CJK compatibility forms + | 0xFF01..=0xFF9D // full-width forms, half-width katakana + | 0xFFA0..=0xFFEF // half-width Hangul, full-width signs + | 0x20000..=0x3FFFF) // supplementary ideographs +} + +/// A character that can't start a line: closing brackets and quotes, hyphens, dividing +/// punctuation, middle dots, colons, full stops and commas, iteration marks, the prolonged sound +/// mark, small kana, kana sound marks and postfixed abbreviations (JLREQ cl-02 to cl-07, cl-09 to +/// cl-11, cl-13). +pub(crate) fn no_line_start(c: char) -> bool { + matches!(c, + ')' | ']' | '}' | ',' | '.' | ':' | ';' | '!' | '?' | '»' | '’' | '”' | '‐' | '–' | '‼' | '⁇' | '⁈' | '⁉' + | '、' | '。' | '〉' | '》' | '」' | '』' | '】' | '〕' | '〗' | '〙' | '〛' | '〞' | '〟' | '〜' | '゠' | '・' | '⦆' + | 'ー' | 'ゝ' | 'ゞ' | 'ヽ' | 'ヾ' | '々' | '〻' | '゛' | '゜' + | 'ぁ' | 'ぃ' | 'ぅ' | 'ぇ' | 'ぉ' | 'っ' | 'ゃ' | 'ゅ' | 'ょ' | 'ゎ' | 'ゕ' | 'ゖ' + | 'ァ' | 'ィ' | 'ゥ' | 'ェ' | 'ォ' | 'ッ' | 'ャ' | 'ュ' | 'ョ' | 'ヮ' | 'ヵ' | 'ヶ' | 'ㇰ'..='ㇿ' + | '!' | '%' | ')' | ',' | '.' | ':' | ';' | '?' | ']' | '}' | '~' | '。' | '」' | '、' | '・' | 'ー' | 'ァ'..='ッ' + | '゙' | '゚' | '¢') +} + +/// A character of [`no_line_start`] that may start a line under [`Kinsoku::Soft`]: 々, the +/// prolonged sound mark ー (JLREQ cl-10) and small kana (cl-11), as JLREQ's level 3 rules allow +/// (Appendix C.3, ). Half-width forms aren't in those +/// classes. +pub(crate) fn soft_line_start(c: char) -> bool { + matches!( + c, + '々' | 'ー' + | 'ぁ' + | 'ぃ' + | 'ぅ' + | 'ぇ' + | 'ぉ' + | 'っ' + | 'ゃ' + | 'ゅ' + | 'ょ' + | 'ゎ' + | 'ゕ' + | 'ゖ' + | 'ァ' + | 'ィ' + | 'ゥ' + | 'ェ' + | 'ォ' + | 'ッ' + | 'ャ' + | 'ュ' + | 'ョ' + | 'ヮ' + | 'ヵ' + | 'ヶ' + | 'ㇰ'..='ㇿ' + ) +} + +/// A character that can't end a line: opening brackets and quotes, and prefixed abbreviations +/// (JLREQ cl-01, cl-12). +pub(crate) fn no_line_end(c: char) -> bool { + matches!( + c, + '(' | '[' + | '{' + | '«' + | '‘' + | '“' + | '〈' + | '《' + | '「' + | '『' + | '【' + | '〔' + | '〖' + | '〘' + | '〚' + | '〝' + | '(' + | '[' + | '{' + | '⦅' + | '「' + | '$' + | '£' + | '¥' + ) +} diff --git a/crates/text/src/segment/mod.rs b/crates/text/src/segment/mod.rs new file mode 100644 index 00000000..ebfbd420 --- /dev/null +++ b/crates/text/src/segment/mod.rs @@ -0,0 +1,164 @@ +//! Line-break opportunities for text layout: where a composer may end a line, as byte offsets into +//! the paragraph. Font-independent; measuring and choosing among the breaks stays in the composer. +//! +//! [`line_breaks`] starts from the Unicode line-breaking algorithm (UAX #14, through +//! [`unicode_linebreak`]) and adjusts it: +//! - **Kinsoku** ([`Kinsoku`]): the Japanese and Chinese line-start and line-end rules (JLREQ, +//! CLREQ). Closing brackets, commas, full stops, small kana and the like don't start a line; +//! opening brackets don't end one. The rules apply only next to East Asian characters, so text +//! without them gets UAX #14's breaks unchanged. +//! - **Korean words** ([`Options::korean_words`]): Korean set word by word, breaking at spaces. +//! - **Thai, Lao, Khmer and Burmese**: UAX #14 leaves these scripts (class SA) to a dictionary and +//! never breaks inside a run of them. With the language feature (`thai`, `lao`, `khmer`, +//! `burmese`) the run is split into words by ICU4X's segmenter: its dictionaries by default, its +//! much smaller LSTM models with the `lstm` feature. +//! +//! [`Options::for_language`] picks the options for a paragraph's language. When no opportunity +//! leaves a line short enough, [`emergency_breaks`] gives the places to break a word anyway: +//! between grapheme clusters, never inside one. +//! +//! Composers that build their own opportunity lists can filter them with [`kinsoku_allows`]. + +#[cfg(any(feature = "thai", feature = "lao", feature = "khmer", feature = "burmese"))] +mod complex; +mod kinsoku; +#[cfg(test)] +mod tests; + +use std::ops::Range; + +use unicode_linebreak::{BreakClass, BreakOpportunity, break_property}; + +pub use kinsoku::kinsoku_allows; +use kinsoku::{is_east_asian, soft_line_start}; +use unicode_segmentation::UnicodeSegmentation; + +/// Which kinsoku (line-start and line-end) rules apply. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub enum Kinsoku { + /// No kinsoku: a line may also break between any two East Asian characters, punctuation + /// included. + None, + /// Closing brackets, commas, full stops, iteration marks, the prolonged sound mark, small kana + /// and the like don't start a line; opening brackets don't end one. + #[default] + Hard, + /// As `Hard`, except that 々, the prolonged sound mark ー and small kana may start a line + /// (JLREQ's relaxed rules, Appendix C.3). + Soft, +} + +/// How [`line_breaks`] adjusts UAX #14. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +pub struct Options { + pub kinsoku: Kinsoku, + /// Set Korean word by word (KLREQ): no break between two Hangul letters or Han ideographs + /// (hanja), only at spaces and punctuation. For Korean-language text only, since Han + /// ideographs count as Korean letters. Off, Korean breaks between syllables as UAX #14 does. + pub korean_words: bool, +} + +impl Options { + /// The options for text in `language`, a BCP 47 tag such as `ja` or `ko-KR` (`None`: unknown). + /// Korean is set word by word; every other language, and an unknown one, gets the defaults. + /// Thai, Lao, Khmer and Burmese words are found by script, whatever the language. + pub fn for_language(language: Option<&str>) -> Self { + let primary = language.and_then(|tag| tag.split(['-', '_']).next()).unwrap_or_default(); + Self { korean_words: primary.eq_ignore_ascii_case("ko"), ..Self::default() } + } +} + +/// A place where a line may end: the next line starts at byte `offset`. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub struct Break { + pub offset: usize, + /// The line must end here (after a newline or another hard break, and at the end of the text). + pub mandatory: bool, +} + +/// Line-break opportunities in `text`, in order. The last one is the end of the text (mandatory); +/// empty text has none. +pub fn line_breaks(text: &str, options: &Options) -> Vec { + #[cfg(any(feature = "thai", feature = "lao", feature = "khmer", feature = "burmese"))] + let words = complex::word_breaks(text, complex::MODEL); + #[cfg(not(any(feature = "thai", feature = "lao", feature = "khmer", feature = "burmese")))] + let words = Vec::new(); + breaks_with_words(text, options, words) +} + +/// [`line_breaks`], given the word breaks inside Thai, Lao, Khmer and Burmese runs (sorted). +fn breaks_with_words(text: &str, options: &Options, words: Vec) -> Vec { + if text.is_empty() { + return Vec::new(); + } + let mut uax = unicode_linebreak::linebreaks(text).peekable(); + let mut words = words.into_iter().peekable(); + let mut out = Vec::new(); + // The last character before the boundary that isn't a combining mark: kinsoku looks at the + // character a mark belongs to. + let mut base: Option = None; + let mut after_mark = false; + for (i, c) in text.char_indices() { + if i > 0 { + // Both lists are sorted by offset: take the entry for `i` from each, if it has one. + let uax_here = uax.next_if(|&(o, _)| o == i).map(|(_, op)| op); + let word = words.next_if(|&o| o == i).is_some(); + let allowed = uax_here.is_some() || word; + let brk = if uax_here == Some(BreakOpportunity::Mandatory) { + Some(true) + } else { + adjust(allowed, base, after_mark, c, options).then_some(false) + }; + if let Some(mandatory) = brk { + out.push(Break { offset: i, mandatory }); + } + } + after_mark = is_mark(c); + if !after_mark { + base = Some(c); + } + } + out.push(Break { offset: text.len(), mandatory: true }); + out +} + +/// Emergency breaks for `text[range]`, a piece between two [`line_breaks`] that is too long for a +/// line: byte offsets into `text`, strictly inside `range` and in order, between extended grapheme +/// clusters (UAX #29). An emoji ZWJ sequence, a flag or a letter with its marks stays whole. Empty +/// if `range` isn't on char boundaries of `text`. +pub fn emergency_breaks(text: &str, range: Range) -> Vec { + let Some(piece) = text.get(range.clone()) else { return Vec::new() }; + piece.grapheme_indices(true).skip(1).map(|(o, _)| range.start + o).collect() +} + +/// Whether a line may break between `before` and `after`, given whether UAX #14 (or the word +/// segmenter) allows it. `after_mark`: the character right before the boundary is a combining +/// mark, joiner or variation selector that belongs to `before`. +fn adjust(allowed: bool, before: Option, after_mark: bool, after: char, options: &Options) -> bool { + let Some(before) = before else { return allowed }; + // The East Asian breaks UAX #14 lacks go only between two base characters: never inside a + // cluster, so not after a joiner or before a mark. + let east_asian_pair = !after_mark && is_east_asian(before) && is_east_asian(after) && !is_mark(after); + let allowed = match options.kinsoku { + Kinsoku::None => allowed || east_asian_pair, + // UAX #14 keeps small kana, ー and 々 (classes CJ and NS) off the line start. + Kinsoku::Soft => (allowed || (east_asian_pair && soft_line_start(after))) && kinsoku_allows(before, Some(after), Kinsoku::Soft), + Kinsoku::Hard => allowed && kinsoku_allows(before, Some(after), Kinsoku::Hard), + }; + allowed && !(options.korean_words && is_korean_letter(before) && is_korean_letter(after)) +} + +/// A combining mark, variation selector or joiner (UAX #14 classes CM and ZWJ): it belongs to the +/// character before it. +fn is_mark(c: char) -> bool { + matches!(break_property(c as u32), BreakClass::CombiningMark | BreakClass::ZeroWidthJoiner) +} + +/// Hangul in every form, and Han ideographs (read as hanja). +fn is_korean_letter(c: char) -> bool { + matches!(c as u32, + 0x1100..=0x11FF | 0x3131..=0x318F | 0xA960..=0xA97F | 0xAC00..=0xD7FF | 0xFFA0..=0xFFDC + | 0x3400..=0x4DBF | 0x4E00..=0x9FFF | 0xF900..=0xFAFF | 0x20000..=0x3FFFF) +} diff --git a/crates/text/src/segment/tests.rs b/crates/text/src/segment/tests.rs new file mode 100644 index 00000000..d1d2a0f4 --- /dev/null +++ b/crates/text/src/segment/tests.rs @@ -0,0 +1,242 @@ +use super::kinsoku::{no_line_end, no_line_start}; +use super::*; + +fn opts(kinsoku: Kinsoku) -> Options { + Options { kinsoku, ..Options::default() } +} + +/// Byte offsets of the breaks before the end of the text. +fn offsets(text: &str, options: &Options) -> Vec { + line_breaks(text, options).iter().map(|b| b.offset).filter(|&o| o < text.len()).collect() +} + +/// The text from each break before the end to the next break. +fn pieces(text: &str, options: &Options) -> Vec { + let mut from = 0; + let mut out = Vec::new(); + for b in line_breaks(text, options) { + out.push(text.get(from..b.offset).unwrap_or_default().to_string()); + from = b.offset; + } + out +} + +/// The character each line after the first could start with. +fn starts(text: &str, options: &Options) -> Vec { + offsets(text, options).iter().filter_map(|&o| text.get(o..).and_then(|t| t.chars().next())).collect() +} + +#[test] +fn kinsoku_keeps_closing_marks_off_line_starts_and_opening_ones_off_line_ends() { + for (a, b) in + [('字', '。'), ('弧', '」'), ('」', '、'), ('ャ', 'ー'), ('カ', 'ッ'), ('「', 'か'), ('(', '雅'), ('字', '〞'), ('1', '%'), ('$', '1')] + { + assert!(!kinsoku_allows(a, Some(b), Kinsoku::Hard), "{a}{b}"); + } + for (a, b) in [('。', '雅'), ('」', 'は'), ('字', '「'), ('の', '演')] { + assert!(kinsoku_allows(a, Some(b), Kinsoku::Hard), "{a}{b}"); + } + assert!(kinsoku_allows('。', None, Kinsoku::Hard)); + // No East Asian character on either side: Latin rules apply. + assert!(kinsoku_allows(' ', Some('–'), Kinsoku::Hard)); + assert!(!kinsoku_allows('字', Some(')'), Kinsoku::Hard)); +} + +/// Soft kinsoku lets 々, ー and small kana (JLREQ cl-09's 々, cl-10, cl-11) start a line and keeps +/// the rest of the set (half-width forms aren't in those classes); None allows any break. +#[test] +fn soft_kinsoku_lets_small_kana_and_the_prolonged_sound_mark_start_a_line() { + for (a, b) in [('ャ', 'ー'), ('カ', 'ッ'), ('時', '々'), ('ト', 'ㇰ'), ('か', 'ゃ')] { + assert!(!kinsoku_allows(a, Some(b), Kinsoku::Hard), "{a}{b}"); + assert!(kinsoku_allows(a, Some(b), Kinsoku::Soft), "{a}{b}"); + } + for (a, b) in [('字', '。'), ('弧', '」'), ('「', 'か'), ('カ', 'ッ'), ('カ', 'ー'), ('字', 'ゝ')] { + assert!(!kinsoku_allows(a, Some(b), Kinsoku::Soft), "{a}{b}"); + assert!(kinsoku_allows(a, Some(b), Kinsoku::None), "{a}{b}"); + } +} + +#[test] +fn no_break_puts_a_closing_mark_at_a_line_start_or_an_opening_one_at_a_line_end() { + let text = "あいうえお。かきくけ「こさしすせそ」"; + let breaks = offsets(text, &Options::default()); + assert!(breaks.len() > 10, "{breaks:?}"); + for o in breaks { + let (head, tail) = text.split_at(o); + let (Some(last), Some(first)) = (head.chars().next_back(), tail.chars().next()) else { continue }; + assert!(!no_line_start(first) && !no_line_end(last), "break at {o}: {last}|{first}"); + } +} + +/// あカッ breaks before ッ with Soft and None (a small kana may start a line) and not with Hard; a +/// full stop never starts a line, Soft or not. +#[test] +fn kinsoku_mode_decides_whether_a_small_kana_may_start_a_line() { + assert_eq!(starts("あカッ", &opts(Kinsoku::Hard)), ['カ']); + assert_eq!(starts("あカッ", &opts(Kinsoku::Soft)), ['カ', 'ッ']); + assert_eq!(starts("あカッ", &opts(Kinsoku::None)), ['カ', 'ッ']); + assert_eq!(starts("あカ。", &opts(Kinsoku::Soft)), ['カ']); + assert_eq!(starts("あカ。", &opts(Kinsoku::None)), ['カ', '。']); +} + +#[test] +fn kinsoku_adjusts_uax14_next_to_east_asian_text_only() { + let ja = "日本語、「漢字」。テスト"; + let on = starts(ja, &opts(Kinsoku::Hard)); + for c in ['、', '」', '。', '漢'] { + assert!(!on.contains(&c), "kinsoku: no line starts with {c}: {on:?}"); + } + assert!(on.contains(&'「') && on.contains(&'テ'), "{on:?}"); + let off = starts(ja, &opts(Kinsoku::None)); + for c in ['、', '」', '。', '漢'] { + assert!(off.contains(&c), "no kinsoku: a line may start with {c}: {off:?}"); + } + let en = "Hello wonderful (world), 50%."; + for k in [Kinsoku::None, Kinsoku::Soft] { + assert_eq!(starts(en, &opts(k)), starts(en, &opts(Kinsoku::Hard))); + } + assert_eq!(starts(en, &Options::default()), ['w', '(', '5']); +} + +#[test] +fn breaks_are_byte_offsets_and_newlines_are_mandatory() { + let b = line_breaks("a b\nc", &Options::default()); + let got: Vec<(usize, bool)> = b.iter().map(|b| (b.offset, b.mandatory)).collect(); + assert_eq!(got, [(2, false), (4, true), (5, true)]); + assert!(line_breaks("", &Options::default()).is_empty()); + // A variation selector belongs to its ideograph: no break before it, kinsoku reads the base. + assert_eq!(pieces("字\u{FE00}字\u{FE00}。", &Options::default()), ["字\u{FE00}", "字\u{FE00}。"]); +} + +/// The East Asian breaks that None and Soft add to UAX #14 never split a cluster: not after a +/// joiner, not before a combining mark or variation selector. +#[test] +fn no_kinsoku_mode_breaks_inside_a_cluster() { + for k in [Kinsoku::None, Kinsoku::Soft, Kinsoku::Hard] { + let o = opts(k); + assert_eq!(pieces("日本\u{200D}語", &o), ["日", "本\u{200D}語"], "{k:?}"); + assert_eq!(pieces("あカ\u{200D}ッ", &o), ["あ", "カ\u{200D}ッ"], "{k:?}"); + assert_eq!(pieces("葛\u{E0100}城", &o), ["葛\u{E0100}", "城"], "{k:?}"); + assert_eq!(pieces("字\u{3099}\u{FE00}字", &o), ["字\u{3099}\u{FE00}", "字"], "{k:?}"); + } +} + +#[test] +fn korean_words_break_at_spaces_only() { + let text = "한국어 문장(文章)입니다"; + assert_eq!(pieces(text, &Options::default()), ["한", "국", "어 ", "문", "장", "(文", "章)", "입", "니", "다"]); + let words = Options { korean_words: true, ..Options::default() }; + assert_eq!(pieces(text, &words), ["한국어 ", "문장", "(文章)", "입니다"]); +} + +#[cfg(not(feature = "thai"))] +#[test] +fn thai_without_its_feature_breaks_as_uax14() { + assert_eq!(pieces("ภาษาไทยภาษาไทย ไทย", &Options::default()), ["ภาษาไทยภาษาไทย ", "ไทย"]); +} + +/// Each model available in this build, for the complex-script tests. +#[cfg(any(feature = "thai", feature = "lao", feature = "khmer", feature = "burmese"))] +fn models() -> Vec<(&'static str, complex::Model)> { + use icu_segmenter::LineSegmenter; + #[allow(unused_mut)] + let mut models: Vec<(&str, complex::Model)> = vec![("dictionary", LineSegmenter::new_dictionary)]; + #[cfg(feature = "lstm")] + models.push(("lstm", LineSegmenter::new_lstm)); + models +} + +/// Breaks every model puts in `words.concat()` fall between two of `words`, and there are at least +/// `min` of them. `words` splits compounds where a model may break them. +#[cfg(any(feature = "thai", feature = "lao", feature = "khmer", feature = "burmese"))] +fn assert_word_breaks(words: &[&str], min: usize) { + let text = words.concat(); + let bounds: Vec = words + .iter() + .scan(0, |end, w| { + *end += w.len(); + Some(*end) + }) + .collect(); + for (name, model) in models() { + let breaks = breaks_with_words(&text, &Options::default(), complex::word_breaks(&text, model)); + let inside: Vec = breaks.iter().map(|b| b.offset).filter(|&o| o < text.len()).collect(); + let shown: Vec<&str> = std::iter::once(0) + .chain(inside.iter().copied()) + .zip(inside.iter().copied().chain([text.len()])) + .filter_map(|(a, b)| text.get(a..b)) + .collect(); + assert!(inside.iter().all(|o| bounds.contains(o)), "{name}: {shown:?}"); + assert!(inside.len() >= min, "{name}: {shown:?}"); + } +} + +#[cfg(feature = "thai")] +#[test] +fn thai_breaks_between_words() { + assert_word_breaks(&["Thai: ", "ภาษา", "ไทย", "เป็น", "ภาษา", "ราชการ", "ของ", "ประเทศ", "ไทย."], 6); +} + +#[cfg(feature = "lao")] +#[test] +fn lao_breaks_between_words() { + assert_word_breaks(&["ພາສາ", "ລາວ", "ເປັນ", "ພາສາ", "ລາດ", "ຊະ", "ການ", "ຂອງ", "ປະເທດ", "ລາວ"], 5); +} + +#[cfg(feature = "khmer")] +#[test] +fn khmer_breaks_between_words() { + assert_word_breaks(&["ភាសា", "ខ្មែរ", "ជា", "ភាសា", "ផ្លូវ", "ការ", "នៃ", "ប្រទេស", "កម្ពុជា"], 5); +} + +/// Burmese may break between any two syllables, and the LSTM model splits some words there +/// (မြန်|မာ): the expected breaks are the syllable boundaries. +#[cfg(feature = "burmese")] +#[test] +fn burmese_breaks_between_syllables() { + let syllables = ["မြန်", "မာ", "ဘာ", "သာ", "စ", "ကား", "သည်", "မြန်", "မာ", "နိုင်", "ငံ", "၏", "ရုံး", "သုံး", "ဘာ", "သာ", "စ", "ကား", "ဖြစ်", "သည်"]; + assert_word_breaks(&syllables, 5); +} + +/// Chinese full-width punctuation: no line starts with a closing mark, none ends with an opening +/// one. +#[test] +fn chinese_kinsoku_keeps_punctuation_with_its_text() { + let text = "他说:“《红楼梦》是一部小说,(很长)。”"; + let o = Options::for_language(Some("zh-Hans")); + let breaks = offsets(text, &o); + assert!(breaks.len() > 8, "{:?}", pieces(text, &o)); + for b in breaks { + let (head, tail) = text.split_at(b); + let (Some(last), Some(first)) = (head.chars().next_back(), tail.chars().next()) else { continue }; + assert!(!":”》,)。".contains(first), "line starts with {first}: {:?}", pieces(text, &o)); + assert!(!"“《(".contains(last), "line ends with {last}: {:?}", pieces(text, &o)); + } +} + +#[test] +fn language_picks_korean_words() { + for tag in ["ko", "ko-KR", "KO_kr"] { + assert!(Options::for_language(Some(tag)).korean_words, "{tag}"); + } + for tag in [Some("ja"), Some("kok"), Some("en-KO"), None] { + assert_eq!(Options::for_language(tag), Options::default(), "{tag:?}"); + } +} + +/// Emergency breaks fall between grapheme clusters: never inside an emoji ZWJ sequence, a flag, a +/// skin-tone modifier or a letter with its combining marks. +#[test] +fn emergency_breaks_keep_grapheme_clusters_whole() { + let family = "👨\u{200D}👩\u{200D}👧\u{200D}👦"; + let text = format!("ab{family}e\u{301}🇯🇵👍🏽"); + let breaks = emergency_breaks(&text, 0..text.len()); + let a = family.len() + 2; + let b = a + "e\u{301}".len(); + let c = b + "🇯🇵".len(); + assert_eq!(breaks, [1, 2, a, b, c]); + // Offsets are into `text`; a range off a char boundary has none. + assert_eq!(emergency_breaks(&text, 1..b), [2, a]); + assert!(emergency_breaks(&text, 3..b).is_empty()); + assert!(emergency_breaks("", 0..0).is_empty()); +} From a04bb9da2a00e08fd52c394aec26703800f4415a Mon Sep 17 00:00:00 2001 From: aiongg Date: Sun, 25 Oct 2026 19:37:05 +0000 Subject: [PATCH 2/3] craft-text: locale codes with a script or year subtag; Slovak data through feature unification --- ATTRIBUTION.md | 2 +- NOTICE | 6 ++++-- crates/text/Cargo.toml | 4 +++- crates/text/README.md | 7 +++++-- crates/text/src/hyphen/mod.rs | 30 ++++++++++++++++++++++-------- crates/text/src/hyphen/tests.rs | 6 +++++- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index a6493818..7b32c6f1 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -12,7 +12,7 @@ author, source and license. Library code and original assets are under the repos | `crates/i18n/data/collation.postcard` | Unicode, Inc. (ICU 78.1 collation data, CLDR 48.2.1); generated by `crates/i18n/data/generate-collation.sh` | [ICU](https://github.com/unicode-org/icu/releases/tag/release-78.1rc) | Unicode-3.0 | | `crates/text/assets/hyphen/en-us.dic` | Grady Ward (Moby Hyphenator II), converted by DesignCraft | [Project Gutenberg eBook #3204](https://www.gutenberg.org/ebooks/3204) | Public domain | | `crates/text/assets/hyphen/en-us.pat` | DesignCraft contributors, trained from the Moby Hyphenator II list | `crates/text/examples/hyphgen.rs` | CC0-1.0 | -| Patterns embedded through `hypher` (optional `craft-text` language features) | hyph-utf8 authors, per language | [tex-hyphen](https://github.com/hyphenation/tex-hyphen), as packaged in [hypher](https://github.com/typst/hypher/tree/main/patterns) | Per file header: LPPL, MIT, BSD-3-Clause, Unlicense or a permit-any-use notice (or a choice including one); Slovak (`hyph-sk.tex`, feature `slovak-gpl` only) is GPL-2.0-or-later; Spanish (`hyph-es.tex` 5.0, Javier Bezos, CervanTeX) is MIT | +| Patterns embedded through `hypher` (optional `craft-text` language features) | hyph-utf8 authors, per language | [tex-hyphen](https://github.com/hyphenation/tex-hyphen), as packaged in [hypher](https://github.com/typst/hypher/tree/main/patterns) | Per file header: LPPL, MIT, BSD-3-Clause, Unlicense or a permit-any-use notice (or a choice including one); Slovak (`hyph-sk.tex`, embedded whenever `hypher/slovak` is on: feature `slovak-gpl`, or another dependency through feature unification) is GPL-2.0-or-later; Spanish (`hyph-es.tex` 5.0, Javier Bezos, CervanTeX) is MIT | | Word-break dictionaries and LSTM models embedded through `icu_segmenter_data` (optional `craft-text` features `thai`, `lao`, `khmer`, `burmese`) | Unicode, Inc. and ICU4X contributors | [ICU4X](https://github.com/unicode-org/icu4x) | Unicode-3.0 | Original assets are covered by the repository licence. diff --git a/NOTICE b/NOTICE index 699ee37c..9d0e267a 100644 --- a/NOTICE +++ b/NOTICE @@ -29,9 +29,11 @@ Hyphenation patterns for other languages, embedded through the hypher crate only Unlicense, a notice permitting any use, or a choice of licenses that includes one of these. An application that enables a language ships that file's copyright and license notice. The exception is Slovak (hyph-sk.tex, Copyright (C) 1992 Jana Chlebíková), under the GNU General - Public License, version 2 or later (SPDX: GPL-2.0-or-later). It is compiled in only with the + Public License, version 2 or later (SPDX: GPL-2.0-or-later). craft-text asks for it through the feature "slovak-gpl", which "all-languages" does not include; an application that enables it - ships GPL-licensed data. The Spanish patterns (feature "spanish") are hyph-es.tex 5.0. + ships GPL-licensed data. Cargo unifies features, so another dependency that enables hypher's + "slovak" feature (hypher's default features do) embeds the same data; a build that must exclude + it checks its dependency graph. The Spanish patterns (feature "spanish") are hyph-es.tex 5.0. Copyright (C) 1993, 1997 Javier Bezos, 2001-2019 Javier Bezos, CervanTeX. 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 diff --git a/crates/text/Cargo.toml b/crates/text/Cargo.toml index b9d54a48..ae32a115 100644 --- a/crates/text/Cargo.toml +++ b/crates/text/Cargo.toml @@ -138,7 +138,9 @@ russian = ["hyphen", "hypher/russian"] sanskrit = ["hyphen", "hypher/sanskrit"] serbian = ["hyphen", "hypher/serbian"] # Slovak patterns are under the GPL, version 2 or later (hyph-sk.tex), unlike every other language -# here, so `all-languages` leaves them out. A build that enables this ships GPL-licensed data. +# here, so `all-languages` leaves them out. A build that enables this ships GPL-licensed data. Any +# other dependency that enables `hypher/slovak` (hypher's defaults do) embeds them too, through +# feature unification. slovak-gpl = ["hyphen", "hypher/slovak"] slovenian = ["hyphen", "hypher/slovenian"] spanish = ["hyphen", "hypher/spanish"] diff --git a/crates/text/README.md b/crates/text/README.md index 2694c9b5..585945b7 100644 --- a/crates/text/README.md +++ b/crates/text/README.md @@ -42,8 +42,11 @@ Each has a cargo feature named as in hypher (`spanish`, `german`, `norwegian`, enables 46 of them. Patterns for languages whose feature is off are not compiled in. Slovak's patterns are under the GPL, version 2 or later; the patterns of every other language are -under a permissive license. Their feature is `slovak-gpl`, and `all-languages` leaves it out: a build that -enables it ships GPL-licensed data. +under a permissive license. craft-text asks for Slovak through the feature `slovak-gpl`, which +`all-languages` leaves out; a build that enables it ships GPL-licensed data. Cargo unifies features, +so another dependency that enables hypher's `slovak` feature (hypher's default features do) embeds +the same data. A build that must exclude it checks its dependency graph +(`cargo tree -e features -i hypher`). ```rust use craft_text::hyphen::{Lang, Limits, hyphen_points_in}; diff --git a/crates/text/src/hyphen/mod.rs b/crates/text/src/hyphen/mod.rs index f098bdbb..deac28a2 100644 --- a/crates/text/src/hyphen/mod.rs +++ b/crates/text/src/hyphen/mod.rs @@ -161,16 +161,30 @@ impl Lang { } /// The language of a locale code split into lowercase `words`: a language (2 or 3 letters), then -/// optionally a region (2 letters or 3 digits) and a reform year (4 digits). +/// optionally a script (4 letters), a region (2 letters or 3 digits) and a reform year (4 digits), +/// in that order. fn locale_language<'a>(words: &[&'a str]) -> Option<&'a str> { - let letters = |w: &str, n: std::ops::RangeInclusive| n.contains(&w.len()) && w.bytes().all(|b| b.is_ascii_lowercase()); - let digits = |w: &str, n: usize| w.len() == n && w.bytes().all(|b| b.is_ascii_digit()); - match *words { - [lang] if letters(lang, 2..=3) => Some(lang), - [lang, region] if letters(lang, 2..=3) && (letters(region, 2..=2) || digits(region, 3)) => Some(lang), - [lang, region, year] if letters(lang, 2..=3) && (letters(region, 2..=2) || digits(region, 3)) && digits(year, 4) => Some(lang), - _ => None, + fn letters(w: &str, n: std::ops::RangeInclusive) -> bool { + n.contains(&w.len()) && w.bytes().all(|b| b.is_ascii_lowercase()) } + fn digits(w: &str, n: usize) -> bool { + w.len() == n && w.bytes().all(|b| b.is_ascii_digit()) + } + let (&lang, mut rest) = words.split_first()?; + if !letters(lang, 2..=3) { + return None; + } + let script = |w: &str| letters(w, 4..=4); + let region = |w: &str| letters(w, 2..=2) || digits(w, 3); + let year = |w: &str| digits(w, 4); + for subtag in [script as fn(&str) -> bool, region, year] { + if let Some((&w, tail)) = rest.split_first() + && subtag(w) + { + rest = tail; + } + } + rest.is_empty().then_some(lang) } /// Where a word's break points came from. diff --git a/crates/text/src/hyphen/tests.rs b/crates/text/src/hyphen/tests.rs index be36e4de..8c1f1af8 100644 --- a/crates/text/src/hyphen/tests.rs +++ b/crates/text/src/hyphen/tests.rs @@ -70,7 +70,7 @@ fn limits_are_respected() { #[test] fn language_names_and_codes() { - for name in ["English", "English: USA", "english", "$ID/English: UK", "en", "en_US", "en-GB", "EN"] { + for name in ["English", "English: USA", "english", "$ID/English: UK", "en", "en_US", "en-GB", "EN", "en-Latn-US"] { assert_eq!(Lang::for_language(name), Some(Lang::English), "{name}"); } // Each language resolves by name and by code exactly when its feature is on. @@ -88,6 +88,10 @@ fn language_names_and_codes() { format!("{code}_{upper}"), format!("{code}-419"), format!("{code}_{upper}_2006"), + format!("{code}-Latn"), + format!("{code}-Latn-{upper}"), + format!("{code}-1996"), + format!("{code}-Latn-1996"), ] { assert_eq!(Lang::for_language(&spelling), want, "{spelling}"); } From f4c6718d6875921e69d034d5dac25968279a6260 Mon Sep 17 00:00:00 2001 From: aiongg Date: Mon, 26 Oct 2026 01:54:26 +0000 Subject: [PATCH 3/3] craft-text: a locale's script must match the hyphenation patterns' script --- crates/text/src/hyphen/mod.rs | 50 +++++++++++++++++++++++++++------ crates/text/src/hyphen/tests.rs | 10 +++++-- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/crates/text/src/hyphen/mod.rs b/crates/text/src/hyphen/mod.rs index deac28a2..76d1416f 100644 --- a/crates/text/src/hyphen/mod.rs +++ b/crates/text/src/hyphen/mod.rs @@ -151,8 +151,17 @@ impl Lang { let words: Vec<&str> = l.split(|c: char| !c.is_alphanumeric()).filter(|w| !w.is_empty()).collect(); let first = *words.first()?; let code = match locale_language(&words) { - Some("en") => return Some(Lang::English), - Some(code) => <[u8; 2]>::try_from(code.as_bytes()).ok()?, + Some((code, script)) => { + let code = <[u8; 2]>::try_from(code.as_bytes()).ok()?; + // Patterns for one script find nothing in another: `sr-Latn` has none. + if script.is_some_and(|script| script != pattern_script(code)) { + return None; + } + if code == *b"en" { + return Some(Lang::English); + } + code + } None if first == "english" => return Some(Lang::English), None => LANGUAGES.iter().find(|(name, _)| *name == first)?.1, }; @@ -160,10 +169,30 @@ impl Lang { } } -/// The language of a locale code split into lowercase `words`: a language (2 or 3 letters), then -/// optionally a script (4 letters), a region (2 letters or 3 digits) and a reform year (4 digits), -/// in that order. -fn locale_language<'a>(words: &[&'a str]) -> Option<&'a str> { +/// The script of hypher's patterns for the language `code`, lowercase, as its documentation +/// lists them. +fn pattern_script(code: [u8; 2]) -> &'static str { + match &code { + b"as" | b"bn" => "beng", + b"be" | b"bg" | b"mn" | b"ru" | b"sr" | b"uk" => "cyrl", + b"hi" | b"mr" | b"sa" => "deva", + b"ka" => "geor", + b"el" => "grek", + b"gu" => "gujr", + b"pa" => "guru", + b"kn" => "knda", + b"ml" => "mlym", + b"or" => "orya", + b"ta" => "taml", + b"te" => "telu", + _ => "latn", + } +} + +/// The language and script of a locale code split into lowercase `words`: a language (2 or 3 +/// letters), then optionally a script (4 letters), a region (2 letters or 3 digits) and a reform +/// year (4 digits), in that order. +fn locale_language<'a>(words: &[&'a str]) -> Option<(&'a str, Option<&'a str>)> { fn letters(w: &str, n: std::ops::RangeInclusive) -> bool { n.contains(&w.len()) && w.bytes().all(|b| b.is_ascii_lowercase()) } @@ -174,17 +203,20 @@ fn locale_language<'a>(words: &[&'a str]) -> Option<&'a str> { if !letters(lang, 2..=3) { return None; } - let script = |w: &str| letters(w, 4..=4); + let script = rest.first().copied().filter(|w| letters(w, 4..=4)); + if script.is_some() { + rest = &rest[1..]; + } let region = |w: &str| letters(w, 2..=2) || digits(w, 3); let year = |w: &str| digits(w, 4); - for subtag in [script as fn(&str) -> bool, region, year] { + for subtag in [region as fn(&str) -> bool, year] { if let Some((&w, tail)) = rest.split_first() && subtag(w) { rest = tail; } } - rest.is_empty().then_some(lang) + rest.is_empty().then_some((lang, script)) } /// Where a word's break points came from. diff --git a/crates/text/src/hyphen/tests.rs b/crates/text/src/hyphen/tests.rs index 8c1f1af8..f786a5e3 100644 --- a/crates/text/src/hyphen/tests.rs +++ b/crates/text/src/hyphen/tests.rs @@ -73,6 +73,7 @@ fn language_names_and_codes() { for name in ["English", "English: USA", "english", "$ID/English: UK", "en", "en_US", "en-GB", "EN", "en-Latn-US"] { assert_eq!(Lang::for_language(name), Some(Lang::English), "{name}"); } + assert_eq!(Lang::for_language("en-Cyrl"), None); // Each language resolves by name and by code exactly when its feature is on. for &(name, code) in LANGUAGES { let want = hypher::Lang::from_iso(code).map(|l| Lang::Patterns(PatternLang(l))); @@ -80,6 +81,7 @@ fn language_names_and_codes() { let mut title = name.chars(); let title: String = title.next().map(|c| c.to_uppercase().chain(title).collect()).unwrap_or_default(); let upper = code.to_uppercase(); + let script = pattern_script(code.as_bytes().try_into().unwrap()); for spelling in [ name.to_string(), format!("{title}: Reform"), @@ -88,13 +90,15 @@ fn language_names_and_codes() { format!("{code}_{upper}"), format!("{code}-419"), format!("{code}_{upper}_2006"), - format!("{code}-Latn"), - format!("{code}-Latn-{upper}"), + format!("{code}-{script}"), + format!("{code}-{script}-{upper}"), format!("{code}-1996"), - format!("{code}-Latn-1996"), + format!("{code}-{script}-1996"), ] { assert_eq!(Lang::for_language(&spelling), want, "{spelling}"); } + let other = if script == "latn" { "Cyrl" } else { "Latn" }; + assert_eq!(Lang::for_language(&format!("{code}-{other}-{upper}")), None, "{code}: patterns of another script"); assert_eq!(Lang::for_language(&format!("{code}_{upper}_x")), None, "{code}: not a locale code"); } for unknown in ["", "[No Language]", "Klingon", "zh_CN", "Chinese: Simplified", "tlh"] {