Add hyphenation for eleven Indian languages

Squashed from #5946 onto main.
This commit is contained in:
ruchirguitar
2026-11-07 05:15:17 +07:00
committed by bflatastic
parent 7be6f8731c
commit 5bb21cdddf
28 changed files with 2002 additions and 36 deletions
+16
View File
@@ -1,5 +1,21 @@
# Asset attribution
## Indic hyphenation patterns
| Asset | Author | Source | Licence | Notes |
|---|---|---|---|---|
| `crates/text/patterns/hyph-hi.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-hi.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-mr.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-mr.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-gu.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-gu.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-bn.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-bn.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-pa.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-pa.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-ta.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-ta.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-te.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-te.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-kn.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-kn.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-ml.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-ml.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-or.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-or.tex | MIT (selected option) | Unmodified; full license in file |
| `crates/text/patterns/hyph-as.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-as.tex | MIT (selected option) | Unmodified; full license in file |
Every non-code asset in this repository (icons, images, fonts, example art, colour profiles, presets) is listed here with its author, source and licence. `cargo xtask assets` (part of `cargo xtask ci`) fails if an asset file is missing from this table.
**Policy (mandatory):** VectorCraft contains **no Adobe iconography, images, artwork, presets, swatch/brush/symbol/pattern libraries or ICC profiles**. Every asset is either original work by VectorCraft contributors, or third-party material under an open licence (OSI open source, public domain / CC0, or Creative Commons that allows redistribution), and it is attributed below. Screenshots of Adobe software are never committed. The one exception is the ArtCraft name, wordmark and logos in `docs/brand/`: ArtCraft trademarks, not open source, usable only under [`docs/brand/LICENSE-brand.txt`](docs/brand/LICENSE-brand.txt).
+17
View File
@@ -0,0 +1,17 @@
# Attribution
The complete historical asset manifest is [ASSETS.md](ASSETS.md). These hyphenation assets use the MIT option, with the complete copyright and permission notices preserved in each file.
| Asset | Author | Source | SPDX license | Notes |
|---|---|---|---|---|
| `crates/text/patterns/hyph-hi.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-hi.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-mr.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-mr.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-gu.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-gu.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-bn.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-bn.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-pa.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-pa.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-ta.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-ta.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-te.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-te.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-kn.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-kn.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-ml.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-ml.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-or.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-or.tex | MIT | Unmodified; full license in file |
| `crates/text/patterns/hyph-as.tex` | Santhosh Thottingal | https://github.com/hyphenation/tex-hyphen/blob/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-as.tex | MIT | Unmodified; full license in file |
+5
View File
@@ -136,3 +136,8 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
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.
Indic hyphenation patterns (crates/text/patterns/):
Copyright (C) 2016 Santhosh Thottingal, used under the MIT license option.
Original copyright and full license notices are preserved in each hyph-*.tex file.
Source: hyphenation/tex-hyphen, commit 5684c0f51c0b81133db2efbe60a408b4155a3ff5.
+4
View File
@@ -188,6 +188,8 @@ pub const LANGUAGES: &[(&str, &str, Quotes)] = &[
("Kannada", "kn", Quotes::ENGLISH),
("Malayalam", "ml", Quotes::ENGLISH),
("Odia", "or", Quotes::ENGLISH),
("Assamese", "as", Quotes::ENGLISH),
("Sanskrit", "sa", Quotes::ENGLISH),
("Urdu", "ur", Quotes::ENGLISH),
];
@@ -377,6 +379,8 @@ mod tests {
fn char_languages_are_stored_by_tag() {
assert_eq!(char_language("Turkish"), Ok(Some("tr")));
assert_eq!(char_language("MR"), Ok(Some("mr")));
assert_eq!(char_language("Assamese"), Ok(Some("as")));
assert_eq!(char_language("Sanskrit"), Ok(Some("sa")));
assert_eq!(char_language("english: usa"), Ok(None));
assert_eq!(char_language("en-US"), Ok(None));
assert!(char_language("Klingon").is_err() && char_language("").is_err());
+2
View File
@@ -294,6 +294,8 @@ pub const PREF_SPECS: &[PrefSpec] = &[
("kn", "Kannada"),
("ml", "Malayalam"),
("or", "Odia"),
("as", "Assamese"),
("sa", "Sanskrit"),
("ur", "Urdu")
])
),
+29
View File
@@ -0,0 +1,29 @@
# Indic hyphenation patterns
The eleven `hyph-*.tex` files are unmodified upstream files from
[hyphenation/tex-hyphen](https://github.com/hyphenation/tex-hyphen/tree/5684c0f51c0b81133db2efbe60a408b4155a3ff5/hyph-utf8/tex/generic/hyph-utf8/patterns/tex),
pinned at commit `5684c0f51c0b81133db2efbe60a408b4155a3ff5`.
Hindi, Marathi, Gujarati, Bengali, Punjabi (Gurmukhi), Tamil, Telugu, Kannada,
Malayalam, Odia and Assamese: copyright (C) 2016 Santhosh Thottingal.
VectorCraft uses these under their **MIT** license option; the full copyright
and permission notice is preserved at the top of each file. The alternative
LGPL/GPL licenses are not selected.
Sanskrit remains selectable for shaping, but automatic hyphenation is pending
an allowlisted source (#4947). The hyph-utf8 Sanskrit file's custom grant is
outside the repository's license allowlist, as is the LPPL license of CTAN's
older `sanhyph` package. Neither file is bundled. No language silently falls
back to Hindi or English rules; explicit user exceptions remain available.
The matcher reads only the contents of the TeX `\patterns{…}` block after
removing comments. Odd maximum weights permit breaks and even weights forbid
them (Liang patterns). Paragraph length limits count Unicode scalar values,
as for the existing English implementation. Automatic points and preferences
exceptions are restricted to whole Unicode graphemes and actual shaping
cluster starts. Both composers consume the same points; their existing
Hyphen Limit and Hyphenation Zone behavior applies.
Breaks after viramas are conservatively suppressed, including Tamil pulli
breaks permitted by the upstream patterns and Unicode grapheme segmentation.
This preserves consonant clusters even when the font subdivides them.
+142
View File
@@ -0,0 +1,142 @@
% title: Hyphenation patterns for Assamese
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Assamese
% tag: as
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: assamese
% message: Assamese hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
অ1
আ1
ই1
ঈ1
উ1
ঊ1
ঋ1
ৠ1
ঌ1
ৡ1
এ1
ঐ1
ও1
ঔ1
% Break after any dependent vowel, but not before.
া1
ি1
ী1
ু1
ূ1
ৃ1
ৄ1
ৢ1
ৣ1
ে1
ৈ1
ো1
ৌ1
2়2
ৗ1
% Break before or after any consonant.
1ক
1খ
1গ
1ঘ
1ঙ
1চ
1ছ
1জ
1ঝ
1ঞ
1ট
1ঠ
1ড
1ড়
1ঢ
1ঢ়
1ণ
1ত
1থ
1দ
1ধ
1ন
1প
1ফ
1ব
1ভ
1ম
1য
1য়
1র
1ল
1শ
1ষ
1স
1হ
% Do not break after khanda ta.
ৎ1
% Do not break before chandrabindu, anusvara, visarga, avagraha,
% nukta and au length mark.
2ঃ1
2ং1
2ঁ1
2ঽ1
% Do not break either side of virama (may be within conjunct).
2্2
}
+142
View File
@@ -0,0 +1,142 @@
% title: Hyphenation patterns for Bengali
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Bengali
% tag: bn
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: bengali
% message: Bengali hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
অ1
আ1
ই1
ঈ1
উ1
ঊ1
ঋ1
ৠ1
ঌ1
ৡ1
এ1
ঐ1
ও1
ঔ1
% Break after any dependent vowel, but not before.
া1
ি1
ী1
ু1
ূ1
ৃ1
ৄ1
ৢ1
ৣ1
ে1
ৈ1
ো1
ৌ1
2়2
ৗ1
% Break before or after any consonant.
1ক
1খ
1গ
1ঘ
1ঙ
1চ
1ছ
1জ
1ঝ
1ঞ
1ট
1ঠ
1ড
1ড়
1ঢ
1ঢ়
1ণ
1ত
1থ
1দ
1ধ
1ন
1প
1ফ
1ব
1ভ
1ম
1য
1য়
1র
1ল
1শ
1ষ
1স
1হ
% Do not break after khanda ta.
ৎ1
% Do not break before chandrabindu, anusvara, visarga, avagraha,
% nukta and au length mark.
2ঃ1
2ং1
2ঁ1
2ঽ1
% Do not break either side of virama (may be within conjunct).
2্2
}
+135
View File
@@ -0,0 +1,135 @@
% title: Hyphenation patterns for Gujarati
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Gujarati
% tag: gu
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: gujarati
% message: Gujarati hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
અ1
આ1
ઇ1
ઈ1
ઉ1
ઊ1
ઋ1
ૠ1
એ1
ઐ1
ઓ1
ઔ1
% Break after any dependent vowel but not before.
ા1
િ1
ી1
ુ1
ૂ1
ૃ1
ૄ1
ૢ1
ૣ1
ે1
ૈ1
ો1
ૌ1
% Break before or after any consonant.
1ક
1ખ
1ગ
1ઘ
1ઙ
1ચ
1છ
1જ
1ઝ
1ઞ
1ટ
1ઠ
1ડ
1ઢ
1ણ
1ત
1થ
1દ
1ધ
1ન
1પ
1ફ
1બ
1ભ
1મ
1ય
1ર
1લ
1ળ
1વ
1શ
1ષ
1સ
1હ
% Do not break before chandrabindu, anusvara, visarga, avagraha
% and accents.
2ઁ1
2ઃ1
2ઽ1
% Do not break either side of virama (may be within conjunct).
2્2
2ં2
}
+139
View File
@@ -0,0 +1,139 @@
% title: Hyphenation patterns for Hindi
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Hindi
% tag: hi
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: hindi
% message: Hindi hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
अ1
आ1
इ1
ई1
उ1
ऊ1
ऋ1
ॠ1
ऌ1
ॡ1
ए1
ऐ1
ओ1
औ1
% Break after any dependent vowel but not before.
ा1
ि1
ी1
ु1
ू1
ृ1
ॄ1
ॢ1
ॣ1
े1
ै1
ो1
ौ1
% Break before or after any consonant.
1क
1ख
1ग
1घ
1ङ
1च
1छ
1ज
1झ
1ञ
1ट
1ठ
1ड
1ढ
1ण
1त
1थ
1द
1ध
1न
1प
1फ
1ब
1भ
1म
1य
1र
1ल
1ळ
1व
1श
1ष
1स
1ह
% Do not break before chandrabindu, anusvara, visarga, avagraha
% and accents.
2ँ1
2ं1
2ः1
2ऽ1
2॑1
2॒1
% Do not break either side of virama (may be within conjunct).
2्2
}
+142
View File
@@ -0,0 +1,142 @@
% title: Hyphenation patterns for Kannada
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Kannada
% tag: kn
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: kannada
% message: Kannada hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
ಅ1
ಆ1
ಇ1
ಈ1
ಉ1
ಊ1
ಋ1
ೠ1
ಌ1
ೡ1
ಎ1
ಏ1
ಐ1
ಒ1
ಓ1
ಔ1
% Break after any dependent vowel, but not before.
ಾ1
ಿ1
ೀ1
ು1
ೂ1
ೃ1
ೄ1
ೆ1
ೇ1
ೈ1
ೊ1
ೋ1
ೌ1
% Break before or after any consonant.
1ಕ
1ಖ
1ಗ
1ಘ
1ಙ
1ಚ
1ಛ
1ಜ
1ಝ
1ಞ
1ಟ
1ಠ
1ಡ
1ಢ
1ಣ
1ತ
1ಥ
1ದ
1ಧ
1ನ
1ಪ
1ಫ
1ಬ
1ಭ
1ಮ
1ಯ
1ರ
1ಱ
1ಲ
1ಳ
1ೞ
1ವ
1ಶ
1ಷ
1ಸ
1ಹ
% Do not break before anusvara, visarga, avagraha,
% length mark and ai length mark.
2ಂ1
2ಃ1
2ಽ1
2ೕ1
2ೖ1
% Do not break either side of virama (may be within conjunct).
2್2
}
+157
View File
@@ -0,0 +1,157 @@
% title: Hyphenation patterns for Malayalam
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Malayalam
% tag: ml
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: malayalam
% message: Malayalam hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
1അ1
1ആ1
1ഇ1
1ഈ1
1ഉ1
1ഊ1
1ഋ1
1ൠ1
1ഌ1
1ൡ1
1എ1
1ഏ1
1ഐ1
1ഒ1
1ഓ1
1ഔ1
% Break after any dependent vowel, but not before.
ാ1
ി1
ീ1
ു1
ൂ1
ൃ1
െ1
േ1
ൈ1
ൊ1
ോ1
ൌ1
ൗ1
% Break before or after any consonant.
1ക
1ഖ
1ഗ
1ഘ
1ങ
1ച
1ഛ
1ജ
1ഝ
1ഞ
1ട
1ഠ
1ഡ
1ഢ
1ണ
1ത
1ഥ
1ദ
1ധ
1ന
1പ
1ഫ
1ബ
1ഭ
1മ
1യ
1ര
1റ
1ല
1ള
1ഴ
1വ
1ശ
1ഷ
1സ
1ഹ
% Do not break before anusvara, visarga
2ഃ1
2ം1
% Do not break either side of virama (may be within conjunct).
2്2
% Do not break left side of chillu
ന്2
ര്2
ള്2
ല്2
ക്2
ണ്2
2ന്‍
2ല്‍
2ള്‍
2ണ്‍
2ര്‍
2ക്‍
2ൺ
2ൻ
2ർ
2ൽ
2ൾ
2ൿ
}
+139
View File
@@ -0,0 +1,139 @@
% title: Hyphenation patterns for Marathi
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Marathi
% tag: mr
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences, at your option:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: marathi
% message: Marathi hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
अ1
आ1
इ1
ई1
उ1
ऊ1
ऋ1
ॠ1
ऌ1
ॡ1
ए1
ऐ1
ओ1
औ1
% Break after any dependent vowel but not before.
ा1
ि1
ी1
ु1
ू1
ृ1
ॄ1
ॢ1
ॣ1
े1
ै1
ो1
ौ1
% Break before or after any consonant.
1क
1ख
1ग
1घ
1ङ
1च
1छ
1ज
1झ
1ञ
1ट
1ठ
1ड
1ढ
1ण
1त
1थ
1द
1ध
1न
1प
1फ
1ब
1भ
1म
1य
1र
1ल
1ळ
1व
1श
1ष
1स
1ह
% Do not break before chandrabindu, anusvara, visarga, avagraha
% and accents.
2ँ1
2ं1
2ः1
2ऽ1
2॑1
2॒1
% Do not break either side of virama (may be within conjunct).
2्2
}
+133
View File
@@ -0,0 +1,133 @@
% title: Hyphenation patterns for Oriya
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Odia, Oriya
% tag: or
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: oriya
% message: Oriya hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
ଅ1
ଆ1
ଇ1
ଈ1
ଉ1
ଊ1
ଋ1
ୠ1
ଌ1
ୡ1
ଏ1
ଐ1
ଓ1
ଔ1
% Break after any dependent vowel, but not before.
ା1
ି1
ୀ1
ୁ1
ୂ1
ୃ1
େ1
ୈ1
ୋ1
ୌ1
% Break before or after any consonant.
1କ
1ଖ
1ଗ
1ଘ
1ଙ
1ଚ
1ଛ
1ଜ
1ଝ
1ଞ
1ଟ
1ଠ
1ଡ
1ଢ
1ଣ
1ତ
1ଥ
1ଦ
1ଧ
1ନ
1ପ
1ଫ
1ବ
1ଭ
1ମ
1ଯ
1ର
1ଲ
1ଳ
1ଵ
1ଶ
1ଷ
1ସ
1ହ
% Do not break before anusvara, visarga and length mark.
2ଂ1
2ଃ1
2ୗ1
2ଁ1
% Do not break either side of virama (may be within conjunct).
2୍2
}
+129
View File
@@ -0,0 +1,129 @@
% title: Hyphenation patterns for Panjabi
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Panjabi, Punjabi
% tag: pa
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: panjabi
% message: Panjabi hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
ਅ1
ਆ1
ਇ1
ਈ1
ਉ1
ਊ1
ਏ1
ਐ1
ਓ1
ਔ1
% Break after any dependent vowel but not before.
ਾ1
ਿ1
ੀ1
ੁ1
ੂ1
ੇ1
ੈ1
ੋ1
ੌ1
% Break before or after any consonant.
1ਕ
1ਖ
1ਗ
1ਘ
1ਙ
1ਚ
1ਛ
1ਜ
1ਝ
1ਞ
1ਟ
1ਠ
1ਡ
1ਢ
1ਣ
1ਤ
1ਥ
1ਦ
1ਧ
1ਨ
1ਪ
1ਫ
1ਬ
1ਭ
1ਮ
1ਯ
1ਰ
1ਲ
1ਲ਼
1ਵ
1ਸ਼
1ਸ
1ਹ
% Do not break before chandrabindu, anusvara, visarga, avagraha
% and accents.
2ਁ1
2ਂ1
2ਃ1
% Do not break either side of virama (may be within conjunct).
2੍2
2ੰ2
2ੱ2
}
+140
View File
@@ -0,0 +1,140 @@
% title: Hyphenation patterns for Tamil
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Tamil
% tag: ta
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: tamil
% message: Tamil hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
1அ1
1ஆ1
1இ1
1ஈ1
1உ1
1ஊ1
1எ1
1ஏ1
1ஐ1
1ஒ1
1ஓ1
1ஔ1
% Break after any dependent vowel, but not before.
ா1
ி1
ீ1
ு1
ூ1
ெ1
ே1
ை1
ொ1
ோ1
ௌ1
% Break before or after any consonant.
1க
1ங
1ச
1ஜ
1ஞ
1ட
1ண
1த
1ந
1ப
1ம
1ய
1ர
1ற
1ல
1ள
1ழ
1வ
1ஷ
1ஸ
1ஹ
% Do not break before any consonant + virama.
2க்1
2ங்1
2ச்1
2ஞ்1
2ட்1
2ண்1
2த்1
2ன்1
2ந்1
2ப்1
2ம்1
2ய்1
2ர்1
2ற்1
2ல்1
2ள்1
2ழ்1
2வ்1
2ஷ்1
2ஸ்1
2ஹ்1
% Do not break before anusvara, visarga and length mark.
2ஂ1
2ஃ1
2ௗ1
% Do not break before virama but break after virama.
2்1
}
+141
View File
@@ -0,0 +1,141 @@
% title: Hyphenation patterns for Telugu
% copyright: Copyright (C) 2016 Santhosh Thottingal
% notice: This file is part of the hyph-utf8 package.
% See http://www.hyphenation.org/tex for more information.
% source: https://github.com/santhoshtr/hyphenation/
% language:
% name: Telugu
% tag: te
% version: 0.9.0 2016-01-16
% authors:
% -
% name: Santhosh Thottingal
% contact: santhosh.thottingal (at) gmail.com
% licence:
% - This file is available under any of the following licences:
% -
% name: MIT
% url: https://opensource.org/licenses/MIT
% text: >
% 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.
% -
% name: LGPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/lgpl.html
% -
% name: GPL
% version: 3
% or_later: true
% url: http://www.gnu.org/licenses/gpl.html
% hyphenmins:
% generation:
% left: 1
% right: 1
% texlive:
% babelname: telugu
% message: Telugu hyphenation patterns
% package: indic
%
\patterns{
% GENERAL RULE
% Do not break either side of ZERO-WIDTH JOINER (U+200D)
2‍2
% Break on both sides of ZERO-WIDTH NON JOINER (U+200C)
1‌1
% Break before or after any independent vowel.
అ1
ఆ1
ఇ1
ఈ1
ఉ1
ఊ1
ఋ1
ౠ1
ఌ1
ౡ1
ఎ1
ఏ1
ఐ1
ఒ1
ఓ1
ఔ1
% Break after any dependent vowel, but not before.
ా1
ి1
ీ1
ు1
ూ1
ృ1
ౄ1
ె1
ే1
ై1
ొ1
ో1
ౌ1
% Break before or after any consonant.
1క
1ఖ
1గ
1ఘ
1ఙ
1చ
1ఛ
1జ
1ఝ
1ఞ
1ట
1ఠ
1డ
1ఢ
1ణ
1త
1థ
1ద
1ధ
1న
1ప
1ఫ
1బ
1భ
1మ
1య
1ర
1ఱ
1ల
1ళ
1వ
1శ
1ష
1స
1హ
% Do not break before chandrabindu, anusvara, visarga,
% length mark and ai length mark.
2ఁ1
2ం1
2ః1
2ౕ1
2ౖ1
% Do not break either side of virama (may be within conjunct).
2్2
}
+149 -13
View File
@@ -8,16 +8,44 @@
//! `typography` never breaks, `ty-pog-ra-phy` breaks only where the hyphens mark. See
//! [`set_hyphenation_exceptions`].
//!
//! Each run hyphenates in its own language ([`vectorcraft_doc::CharStyle::language`]). English is
//! the only language with break points so far: text in any other language, or in a language a
//! file names that isn't known, doesn't hyphenate, apart from the words in the Exceptions list
//! ([`language_has_patterns`]).
//! Each run hyphenates in its own language ([`vectorcraft_doc::CharStyle::language`]). English
//! uses the rules above; eleven Indian languages use bundled hyph-utf8 patterns. Other languages
//! only break at user exceptions. Indic breaks always preserve Unicode grapheme boundaries.
use std::collections::HashMap;
use std::sync::{Mutex, MutexGuard, OnceLock};
use vectorcraft_doc::HyphenationOptions;
mod indic;
#[derive(Clone, Copy, Debug)]
pub(crate) enum Language {
None,
English,
Indic(u8),
}
impl Language {
/// Select rules by the primary BCP 47 subtag; absent tags retain the English default.
pub(crate) fn from_tag(tag: Option<&str>) -> Self {
let primary = tag.unwrap_or("en").split('-').next().unwrap_or_default();
if primary.eq_ignore_ascii_case("en") {
Self::English
} else {
indic::TAGS.iter().position(|t| primary.eq_ignore_ascii_case(t)).and_then(|i| u8::try_from(i).ok()).map_or(Self::None, Self::Indic)
}
}
}
/// Keep combining marks and joiners in the same hyphenation word as their letters.
pub(crate) fn is_word_char(ch: char) -> bool {
use unicode_general_category::{GeneralCategory, get_general_category};
ch.is_alphabetic()
|| matches!(ch, '\'' | '’' | '\u{200c}' | '\u{200d}')
|| matches!(get_general_category(ch), GeneralCategory::NonspacingMark | GeneralCategory::SpacingMark | GeneralCategory::EnclosingMark)
}
/// Only words at least this long are hyphenated (Illustrator's default: longer than 5 letters).
pub const MIN_WORD: usize = 6;
pub const MIN_BEFORE: usize = 3;
@@ -152,7 +180,13 @@ fn onset_pair(a: char, b: char) -> bool {
/// Whether text in `language` (a [`vectorcraft_doc::CharStyle::language`]: a BCP 47 tag, `None` for
/// the default, English: USA) has break points of its own.
pub fn language_has_patterns(language: Option<&str>) -> bool {
language.is_none_or(|l| l.get(..2).is_some_and(|p| p.eq_ignore_ascii_case("en")) && matches!(l.as_bytes().get(2), None | Some(b'-')))
!matches!(Language::from_tag(language), Language::None)
}
/// Language-specific break points as character indices. Indic patterns and exceptions are
/// filtered to whole graphemes; the paragraph's length options count Unicode characters.
pub fn hyphen_points_for_language(word: &str, opts: &HyphenationOptions, language: Option<&str>) -> Vec<usize> {
points_for(word, opts, Language::from_tag(language))
}
/// Allowed hyphenation points in `word`, as char indices (a hyphen goes *before* the char), with
@@ -171,22 +205,31 @@ pub fn hyphen_points_with(word: &str, opts: &HyphenationOptions) -> Vec<usize> {
hyphen_points_in(word, opts, true)
}
/// [`hyphen_points_with`] for a word in a language with or without break points of its own
/// ([`language_has_patterns`]): without them, only a word in the Exceptions list breaks.
/// Compatibility helper selecting English rules (`true`) or exceptions only (`false`).
/// Use [`hyphen_points_for_language`] to select Indic patterns by language tag.
pub fn hyphen_points_in(word: &str, opts: &HyphenationOptions, patterns: bool) -> Vec<usize> {
points_for(word, opts, if patterns { Language::English } else { Language::None })
}
/// Apply exceptions first, then language rules and paragraph limits, protecting Indic clusters.
pub(crate) fn points_for(word: &str, opts: &HyphenationOptions, language: Language) -> Vec<usize> {
if let Some(ex) = exception_for(word) {
return match ex {
let mut points = match ex {
Exception::Never => vec![],
Exception::Only(pts) => lowercase_points_to_word(word, &pts),
};
if matches!(language, Language::Indic(_)) {
indic::retain_boundaries(word, &mut points);
}
return points;
}
if !patterns {
if matches!(language, Language::None) {
return vec![];
}
let c: Vec<char> = word.chars().collect();
let n = c.len();
let longer_than = usize::try_from(opts.words_longer_than).unwrap_or(usize::MAX);
if n <= longer_than || !c.iter().all(|c| c.is_alphabetic() || matches!(c, '\'' | '’')) {
if n <= longer_than || !c.iter().all(|&ch| is_word_char(ch)) {
return vec![];
}
// A capitalised run like "NASA" or a proper name stays whole only when all caps.
@@ -198,6 +241,12 @@ pub fn hyphen_points_in(word: &str, opts: &HyphenationOptions, patterns: bool) -
}
let before = usize::try_from(opts.after_first).unwrap_or(usize::MAX).max(1);
let after = usize::try_from(opts.before_last).unwrap_or(usize::MAX).max(1);
if let Language::Indic(index) = language {
let mut points = indic::points(word, usize::from(index));
points.retain(|p| *p >= before && n.saturating_sub(*p) >= after);
indic::retain_boundaries(word, &mut points);
return points;
}
let v: Vec<bool> = c.iter().map(|&x| is_vowel(x)).collect();
let mut out = vec![];
for i in before..=n.saturating_sub(after) {
@@ -255,16 +304,103 @@ mod tests {
with_hyphenation_exceptions_for_test(source, f);
}
/// #394: English in any region has break points; other languages, and a tag from a file that
/// isn't a known language, have none.
/// English and Indic languages accept regional tags; unknown languages have no patterns.
#[test]
fn only_english_has_break_points() {
fn supported_languages_have_break_points() {
for l in [None, Some("en-US"), Some("en-GB"), Some("EN-gb"), Some("en")] {
assert!(language_has_patterns(l), "{l:?}");
}
for l in [Some("de"), Some("fr"), Some("pt"), Some("eng"), Some("x-unknown"), Some(""), Some("é")] {
assert!(!language_has_patterns(l), "{l:?}");
}
for tag in indic::TAGS {
assert!(language_has_patterns(Some(tag)));
assert!(language_has_patterns(Some(&format!("{}-IN", tag.to_uppercase()))));
}
}
/// Every bundled language preserves vowel-sign syllables and applies length/margin limits.
#[test]
fn indic_patterns_preserve_syllables_and_respect_options() {
let opts = HyphenationOptions { words_longer_than: 0, after_first: 1, before_last: 1, ..Default::default() };
for (tag, syllable) in [
("hi", "कि"),
("mr", "कि"),
("gu", "કિ"),
("bn", "কি"),
("pa", "ਕਿ"),
("ta", "கி"),
("te", "కి"),
("kn", "ಕಿ"),
("ml", "കി"),
("or", "କି"),
("as", "কি"),
] {
let word = syllable.repeat(4);
let points = hyphen_points_for_language(&word, &opts, Some(tag));
assert_eq!(points, vec![2, 4, 6], "{tag}: {word}");
assert_eq!(hyphen_points_for_language(&word, &opts, Some(&format!("{}-IN", tag.to_uppercase()))), points);
let longer = HyphenationOptions { words_longer_than: 8, ..opts.clone() };
assert!(hyphen_points_for_language(&word, &longer, Some(tag)).is_empty());
let margins = HyphenationOptions { after_first: 3, before_last: 3, ..opts.clone() };
assert_eq!(hyphen_points_for_language(&word, &margins, Some(tag)), vec![4]);
assert!(hyphen_points_for_language(&word, &opts, Some("zz")).is_empty());
}
}
/// Automatic points and explicit exceptions cannot split a conjunct or attached mark.
#[test]
fn indic_conjuncts_marks_joiners_and_exceptions_stay_whole() {
use unicode_segmentation::UnicodeSegmentation;
let opts = HyphenationOptions { words_longer_than: 0, after_first: 1, before_last: 1, ..Default::default() };
for (tag, conjunct) in [
("hi", "क्षि"),
("mr", "क्षि"),
("gu", "ક્ષિ"),
("bn", "ক্ষি"),
("pa", "ਕ੍ਕਿ"),
("ta", "க்கி"),
("te", "క్షి"),
("kn", "ಕ್ಷಿ"),
("ml", "ക്ഷി"),
("or", "କ୍ଷି"),
("as", "ক্ষি"),
] {
let points = hyphen_points_for_language(&conjunct.repeat(3), &opts, Some(tag));
if tag == "ta" {
// Tamil patterns permit breaks after pulli, and prohibit the other boundaries
// in this synthetic word. The conservative conjunct guard drops those breaks.
assert!(points.is_empty(), "{tag}: {conjunct}: {points:?}");
} else {
assert_eq!(points, vec![4, 8], "{tag}: {conjunct}");
}
}
for word in ["अक्षरअक्षर", "क्\u{200d}षक्\u{200d}ष", "क्\u{200c}षक्\u{200c}ष", "किंकिंकिं", "क़िक़िक़ि", "কিকিকি", "किकि123कि"]
{
let points = hyphen_points_for_language(word, &opts, Some("hi"));
let boundaries: Vec<_> = word.grapheme_indices(true).map(|(b, _)| word[..b].chars().count()).collect();
assert!(points.iter().all(|p| boundaries.contains(p)), "{word}: {points:?}");
}
with_exceptions("क-ि-क्-ष-क-ि", || {
assert_eq!(hyphen_points_for_language("किक्षकि", &opts, Some("hi")), vec![2, 5]);
});
with_exceptions("किकिकिकि", || {
assert!(hyphen_points_for_language("किकिकिकि", &opts, Some("hi")).is_empty());
});
}
/// Sanskrit stays selectable but has no automatic rules until allowlisted patterns exist.
#[test]
fn sanskrit_without_allowlisted_patterns_uses_only_exceptions() {
let opts = HyphenationOptions { words_longer_than: 0, after_first: 1, before_last: 1, ..Default::default() };
for tag in ["sa", "SA-IN", "sa-Deva", "sa-Latn"] {
assert!(!language_has_patterns(Some(tag)), "{tag}");
assert!(hyphen_points_for_language("किकिकिकि", &opts, Some(tag)).is_empty());
assert!(hyphen_points_for_language("typography", &opts, Some(tag)).is_empty(), "no English fallback");
}
with_exceptions("कि-किकिकि", || {
assert_eq!(hyphen_points_for_language("किकिकिकि", &opts, Some("sa")), vec![2]);
});
}
/// #394: a language without break points leaves words whole, but the Exceptions list is the
+123
View File
@@ -0,0 +1,123 @@
//! Liang pattern matching for the bundled hyph-utf8 Indic patterns. Provenance and licenses:
//! `crates/text/patterns/README.md`. Only bundled, trusted pattern data is parsed.
use std::collections::BTreeMap;
use std::sync::OnceLock;
use unicode_segmentation::UnicodeSegmentation;
pub(super) const TAGS: [&str; 11] = ["hi", "mr", "gu", "bn", "pa", "ta", "te", "kn", "ml", "or", "as"];
const SOURCES: [&str; 11] = [
include_str!("../../patterns/hyph-hi.tex"),
include_str!("../../patterns/hyph-mr.tex"),
include_str!("../../patterns/hyph-gu.tex"),
include_str!("../../patterns/hyph-bn.tex"),
include_str!("../../patterns/hyph-pa.tex"),
include_str!("../../patterns/hyph-ta.tex"),
include_str!("../../patterns/hyph-te.tex"),
include_str!("../../patterns/hyph-kn.tex"),
include_str!("../../patterns/hyph-ml.tex"),
include_str!("../../patterns/hyph-or.tex"),
include_str!("../../patterns/hyph-as.tex"),
];
#[derive(Default)]
struct Node {
next: BTreeMap<char, Node>,
weights: Vec<u8>,
}
impl Node {
/// Read only the patterns block of a trusted bundled TeX file, ignoring comments and macros.
fn parse(source: &str) -> Self {
let mut root = Self::default();
let mut active = false;
for line in source.lines() {
let line = line.split('%').next().unwrap_or_default().trim();
if line == "\\patterns{" {
active = true;
continue;
}
if line == "}" {
active = false;
}
if !active || line.is_empty() {
continue;
}
for pattern in line.split_whitespace() {
let mut node = &mut root;
let mut weights = vec![0];
for ch in pattern.chars() {
if let Some(digit) = ch.to_digit(10) {
if let Some(last) = weights.last_mut() {
*last = digit as u8;
}
} else {
node = node.next.entry(ch).or_default();
weights.push(0);
}
}
node.weights = weights;
}
}
root
}
/// Overlay matched Liang weights on a boundary-padded word; odd maxima permit breaks.
fn points(&self, word: &str) -> Vec<usize> {
let chars: Vec<char> = std::iter::once('.').chain(word.chars()).chain(std::iter::once('.')).collect();
let mut weights = vec![0; chars.len() + 1];
for start in 0..chars.len() {
let mut node = self;
for ch in chars.iter().skip(start) {
let Some(next) = node.next.get(ch) else { break };
node = next;
for (slot, weight) in weights.iter_mut().skip(start).zip(&node.weights) {
*slot = (*slot).max(*weight);
}
}
}
(1..word.chars().count()).filter(|p| weights.get(p + 1).is_some_and(|w| w % 2 == 1)).collect()
}
}
/// Lazily initialize the bundled tries and return character-index candidates for one language.
pub(super) fn points(word: &str, index: usize) -> Vec<usize> {
static PATTERNS: OnceLock<Vec<Node>> = OnceLock::new();
PATTERNS.get_or_init(|| SOURCES.iter().map(|s| Node::parse(s)).collect()).get(index).map_or_else(Vec::new, |p| p.points(word))
}
/// Patterns and user exceptions must both preserve a whole Unicode grapheme. This also protects
/// text when a fallback font subdivides a conjunct into several shaping clusters.
pub(super) fn retain_boundaries(word: &str, points: &mut Vec<usize>) {
let mut count = 0;
let mut boundaries = Vec::new();
for cluster in word.graphemes(true) {
boundaries.push(count);
count += cluster.chars().count();
}
let chars: Vec<_> = word.chars().collect();
points.retain(|p| {
*p > 0
&& *p < count
&& boundaries.binary_search(p).is_ok()
&& !chars.get(*p).is_some_and(|c| matches!(c, '\u{200c}' | '\u{200d}'))
&& !p.checked_sub(1).and_then(|i| chars.get(i)).is_some_and(|c| {
// Tamil's pulli is not a Unicode grapheme linker, and its patterns allow
// coda breaks after it. Conservatively keep every virama with what follows,
// even when neither the font nor Unicode groups the consonants together.
matches!(
c,
'\u{200c}'
| '\u{200d}'
| '\u{094d}'
| '\u{09cd}'
| '\u{0a4d}'
| '\u{0acd}'
| '\u{0b4d}'
| '\u{0bcd}'
| '\u{0c4d}'
| '\u{0ccd}'
| '\u{0d4d}'
)
})
});
}
+1 -1
View File
@@ -14,7 +14,7 @@ use vectorcraft_geom::{ArcPath, PathData};
use crate::GlyphBend;
use crate::composer::{Breakpoint, Params, compose};
use crate::fontdb::FontDb;
use crate::hyphen::hyphen_points_in;
use crate::hyphen::points_for;
use crate::justify::{Flex, LineFit, apply_desired, fit_line, is_word_space};
use crate::kashida;
use crate::shape::{
+2 -2
View File
@@ -1,7 +1,7 @@
use super::region::Region;
use super::{
Affine, BezPath, Breakpoint, Burasagari, EPS, FirstBaseline, FontDb, HyphenationOptions, Kinsoku, LeadingModel, SGlyph, hyphen_glyph,
hyphen_points_in, no_line_end, no_line_start, soft_line_start,
no_line_end, no_line_start, points_for, soft_line_start,
};
/// Vertical metrics of a line: (ascent, descent, leading, cap height, x height).
@@ -544,7 +544,7 @@ fn hyphen_breaks(text: &str, g: &[SGlyph], ws: usize, we: usize, opts: &Hyphenat
starts.entry(g[k].byte).or_insert(k);
}
}
hyphen_points_in(word, opts, g[a].hyphenates).into_iter().filter_map(|ci| starts.get(offs.get(ci)?).copied()).collect()
points_for(word, opts, g[a].hyphen_language).into_iter().filter_map(|ci| starts.get(offs.get(ci)?).copied()).collect()
}
/// Break candidates for the every-line composer: hyphenation points under `hyphenate` (the
+42 -1
View File
@@ -39,7 +39,7 @@ fn synthetic_glyphs(specs: &[(usize, usize, f64, char)]) -> Vec<SGlyph> {
no_break: false,
vertical_roman: false,
cursive: false,
hyphenates: true,
hyphen_language: crate::hyphen::Language::English,
})
.collect()
}
@@ -50,6 +50,47 @@ fn source_range(glyphs: &[SGlyph], start: usize, end: usize) -> Range<usize> {
first.byte..last.byte + last.len
}
/// Both composers consume language-specific points even when a font subdivides vowel signs.
#[test]
fn indic_hyphenation_reaches_both_composers_without_splitting_marks() {
let opts = HyphenationOptions { words_longer_than: 0, after_first: 1, before_last: 1, ..Default::default() };
for (tag, syllable) in [
("hi", "कि"),
("mr", "कि"),
("gu", "કિ"),
("bn", "কি"),
("pa", "ਕਿ"),
("ta", "கி"),
("te", "కి"),
("kn", "ಕಿ"),
("ml", "കി"),
("or", "କି"),
("as", "কি"),
] {
let text = syllable.repeat(8);
// Deliberately subdivide each grapheme, as a fallback font may do. Marks are word
// characters but must never become a break, even at a shaping cluster boundary.
let specs: Vec<_> = text.char_indices().map(|(byte, ch)| (byte, ch.len_utf8(), 1.0, ch)).collect();
let mut glyphs = synthetic_glyphs(&specs);
for glyph in &mut glyphs {
glyph.hyphen_language = crate::hyphen::Language::from_tag(Some(tag));
glyph.sx = 0.001;
}
let cands = candidates(&text, &glyphs, Some(&opts), Kinsoku::None);
assert_eq!(cands.iter().filter(|b| b.hyphen > 0.0).map(|b| b.end).collect::<Vec<_>>(), (2..16).step_by(2).collect::<Vec<_>>(), "{tag}");
let (end, hyphen) = break_line(&text, &glyphs, 0, 4.5, &[], 0.0, Some((&opts, 0.0)), Burasagari::None, Kinsoku::None);
assert_eq!((end, hyphen), (4, true), "{tag}");
let params = Params { justify_last: false, ragged: true, tolerance: 1.0, uniform_from: 0, hyphen_limit: 0 };
let lines = compose(&glyphs, &|_| 4.5, &|_| 0.0, &cands, &[], &params).expect("every-line composition");
assert!(lines.iter().any(|(_, hyphen)| *hyphen), "{tag}");
assert!(lines.iter().all(|(end, _)| end % 2 == 0), "{tag}: {lines:?}");
let limited = Params { hyphen_limit: 1, ..params };
if let Some(lines) = compose(&glyphs, &|_| 4.5, &|_| 0.0, &cands, &[], &limited) {
assert!(lines.windows(2).all(|pair| !pair[0].1 || !pair[1].1), "{tag}: {lines:?}");
}
}
}
#[test]
fn composition_trim_stays_along_the_line_when_a_character_rotates() {
let db = FontDb::with_font_dirs(vec![]);
+6 -6
View File
@@ -80,8 +80,8 @@ pub(crate) struct SGlyph {
/// decided for the whole segment it was shaped in ([`joins`]): on a curved path it is bent
/// along the path so its joins meet.
pub cursive: bool,
/// The glyph's language has hyphenation break points ([`crate::hyphen::language_has_patterns`]).
pub hyphenates: bool,
/// Pattern language of this glyph's source run (unknown languages only use user exceptions).
pub hyphen_language: crate::hyphen::Language,
}
/// Does `script` join its letters (a cursive script, whose neighbouring glyphs touch)?
@@ -158,9 +158,9 @@ impl SGlyph {
pub fn is_soft_hyphen(&self) -> bool {
self.ch == SOFT_HYPHEN
}
/// Part of a word that may be hyphenated (letters and apostrophes).
/// Part of a word that may be hyphenated (letters, marks, joiners and apostrophes).
pub fn is_letter(&self) -> bool {
self.ch.is_alphabetic() || matches!(self.ch, '\'' | '’')
crate::hyphen::is_word_char(self.ch)
}
/// Vertical type: a tate-chu-yoko glyph after its block's first, sharing that glyph's cell.
pub fn continues_tcy(&self) -> bool {
@@ -949,7 +949,7 @@ fn inline_glyph(
no_break: st.no_break,
vertical_roman: false,
cursive: false,
hyphenates: false,
hyphen_language: crate::hyphen::Language::None,
}
}
@@ -1333,7 +1333,7 @@ fn shape_segment(text: &str, context: &Range<usize>, seg: &Segment, feats: &OtFe
no_break: gst.no_break,
vertical_roman: gst.standard_vertical_roman,
cursive,
hyphenates: crate::hyphen::language_has_patterns(gst.language.as_deref()),
hyphen_language: crate::hyphen::Language::from_tag(gst.language.as_deref()),
});
}
}
+49
View File
@@ -918,6 +918,55 @@ fn natural_width(s: &str, size: f64) -> f64 {
l.lines[0].x1 - l.lines[0].x0
}
/// Installed fonts exercise run-language routing, source boundaries and hyphen limits end to end.
#[test]
fn indic_language_runs_hyphenate_with_both_composers() {
let db = FontDb::global();
for (tag, syllable) in [
("hi", "कि"),
("mr", "कि"),
("gu", "કિ"),
("bn", "কি"),
("pa", "ਕਿ"),
("ta", "கி"),
("te", "కి"),
("kn", "ಕಿ"),
("ml", "കി"),
("or", "କି"),
("as", "কি"),
] {
let Some(face) = syllable.chars().next().and_then(|ch| db.face_covering(ch)).filter(|f| syllable.chars().all(|ch| f.covers(ch))) else {
eprintln!("SKIPPED: indic hyphenation layout {tag}; no installed font covers {syllable}");
continue;
};
let style = CharStyle {
font_family: face.family.clone(),
font_style: face.style.clone(),
size: 12.0,
language: Some(tag.into()),
..Default::default()
};
let prefix = layout(db, &TextObject::point(Point::ZERO, &format!("{}-", syllable.repeat(3)), style.clone()));
let width = prefix.glyphs.iter().map(|g| g.advance).sum::<f64>() + 0.5;
for composer in [Composer::SingleLine, Composer::EveryLine] {
let text = syllable.repeat(20);
let mut t = area(&text, style.clone(), Rect::new(0.0, 0.0, width, 2000.0), Justify::Left);
t.para.composer = composer;
t.para.hyphenate = true;
let l = layout(db, &t);
assert!(!l.overflow, "{tag} {composer:?}");
assert!(hyphen_run(&l) > 0, "{tag} {composer:?}: no automatic hyphens");
assert!(l.lines.iter().all(|line| line.end % syllable.len() == 0), "{tag} {composer:?}: split syllable");
assert_eq!(l.lines.last().map(|line| line.end), Some(text.len()));
t.para.hyphenation.hyphen_limit = 1;
assert!(hyphen_run(&layout(db, &t)) <= 1, "{tag} {composer:?}: hyphen limit");
t.runs.iter_mut().for_each(|run| run.style.language = Some("zz".into()));
assert_eq!(hyphen_run(&layout(db, &t)), 0, "unknown language must not use Indic patterns");
}
eprintln!("ASSERTIONS RUN: indic hyphenation layout {tag}, {} {}", face.family, face.style);
}
}
/// The text of each line.
fn line_texts(t: &TextObject, l: &TextLayout) -> Vec<String> {
let text = t.plain_text();
+4 -3
View File
@@ -1,6 +1,6 @@
# Gaps
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
## Feature submission evidence
@@ -37,6 +37,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
| 2026-11-05 | minor | G15: long open strokes with an undashed width profile are outlined near the view while keeping profile positions on the full path; a 200,000-segment outline took 59.95 ms before and 8.44 ms after in local median runs. Closed and dashed profile strokes remain whole; estimate unchanged. |
| 2026-11-05 | minor | G15: Direct Selection reuses one document hit result when choosing the cursor over a path; a 200,000-anchor path's segment cursor took 58.15 ms before and 29.33 ms after in local median runs. Cursor behavior is unchanged; estimate unchanged. |
| 2026-11-05 | minor | G15: Selection skips building corner and pie widgets when the pointer is well outside a large selection; empty-canvas hover with 20,000 selected paths took 28.72 ms before and 16.41 ms after in local median runs. Other cursor targets remain active; estimate unchanged. |
@@ -474,8 +475,8 @@ from G14 and the budget run of G15: **~170–270 h** one agent, ~50–80 h wall
afterwards opens in a floating window of its own (G7's Float in Window); documents already open stay where they
are. Estimate unchanged.
- **Done:** Hyphenation › Default Language is the language of new type, unless Document Setup chose one, and each
run hyphenates in its own language (Character panel). Only English has break points so far: text in another
language stays whole, apart from the Exceptions list (#394).
run hyphenates in its own language (Character panel). English and eleven Indian languages have break
points; other languages stay whole apart from the Exceptions list (#394, #4947).
- **Missing:** 2 Preferences options stored but not acted on (#394), each waiting on a subsystem of its own:
Plug-ins & Scratch Disks › Primary and Secondary (documents are kept in memory; nothing pages to
disk), and Clipboard Handling › Legacy vector clipboard with its Preserve Paths / Preserve Appearance and
+5 -4
View File
@@ -1,6 +1,6 @@
# Roadmap: milestones and what's next
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
## Feature submission evidence
@@ -36,6 +36,7 @@ M7 type: Touch Type moves a right-to-left character along its line and up from i
| Date | Change | Summary |
|---|---|---|
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
| 2026-11-05 | minor | Effect dialogs: a colour swatch beside a hex colour field follows typed values, and a double-click opens the Color Picker over the dialog, whose OK fills the field (#5365); scores and estimates unchanged. |
| 2026-11-05 | minor | Selection Tools add-on: Select Linked, Embedded, Missing and Modified select the images and placed documents with that link status (Object › Plug-ins › Selection Tools and the Links panel menu; Shift adds), and Select by Link Status… lists them by name, status and format to pick from, optionally zooming to them; what is hidden, locked, on a template layer or outside the isolated group is left out and the status bar says how many (#5526, a VectorCraft addition); scores and estimates unchanged (estimated). |
| 2026-11-05 | minor | Pencil and Paintbrush: a new stroke with Keep selected off leaves nothing selected, the earlier selection included, while Keep selected on selects only the new path (#5752); scores and estimates unchanged. |
@@ -126,9 +127,9 @@ native wording review, layout checks and a web Devanagari font remain. [Notes](l
| M3 | Paint & appearance (swatches, color, gradient, stroke, appearance, transparency, styles) | ✅ done (M3.7–M3.98): swatches, groups, libraries, tints, Lab spots and Registration; Eyedropper styles highlighted text only (atomic transparency rejection); Eyedropper reads visible locked and outside-isolation sources (#1251); Color Picker, Color panel, Color Guide, Color Themes, Edit Colors and Recolor Artwork (screen-bounded Edit chip list, #3416); gradients that follow every transform, the annotator, linked stops, freeform gradients, focal points, gradients on strokes and Expand; visible strokes when paint is added to inherited None/zero-width art (#1253); stroke geometry, arrowheads, dashes fitted to corners, stroke on type, width profiles and the Width tool (Shift-double-click enables adjoining adjustment in Width Point Edit), Scale Strokes and preview bounds; Appearance targeting, container appearance, target circles, Expand Appearance; knockout, isolation, blend accuracy, CMYK blending, overprint, Attributes, masks and clipping, Flatten Transparency; graphic styles, links and libraries; CSS library export preserves fractional linear and radial gradient stop positions. Left: freeform gradients in SVG/PDF, mixed spot/process gradients in SVG and PDF gradients mixing a spot color with RGB or Lab stops export as stops or process colors; PDF export writes dithered gradient fills with spot stops, and Perceptual spot gradients with RGB or Lab stops other than white or more than 4,096 stops on their curve, as images in process colors; confirm the Scale Strokes & Effects default | 4–8 |
| M5 | Performance | 🟡 background render + caches + MT done; `vectorcraft-cli bench` and `vectorcraft-cli perf` (budget suite); opaque solid-fill knockout paths draw once in hard-edge/supersampled raster export, with analytical-AA compositing unchanged; file format v2 opens 3× faster (50k paths: 722 → 244 ms); raster effects (glows, shadows, blur, feather) no longer force the whole frame single-threaded (filtered offscreen per effect, verified equal to the single-threaded reference); Craquelure/Mosaic Tiles/Stained Glass distance searches optimized with pixel-invariance checks and the `texture_drag_perf` probe (#1257); effect-heavy demos need a clean-machine benchmark; dirty-region rendering, GPU backend spike pending | 15–25 |
| M6 | Path operations (Pathfinder, Shape Builder, offset…) | ✅ mostly done (live compound shapes: Make, Alt-click a Shape Mode, member modes, Release, Expand (#4522); single-result Pathfinder names and SVG IDs retained (#1293); Divide open-cutting-path geometry, appearance and history verified (#1307; existing segment cap remains); Simplify preview/counts and rewritten-path component selection verified (#1272; the slider opens at the Auto-Simplify level; a Direct Selection part of a path simplifies on its own); Compound appearance and member fill-rule edits verified (#1197); Boolean precision on almost-horizontal edges fixed and the property tests made deterministic; Shape Builder gap detection, large-offset bug open); Shape Builder Gap Detection shares Live Paint’s spatial gap finder and temporary merge bridges (#2526); Custom is capped at 72 pt in the existing options dialog | 3–6 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | 🟡 Hanging punctuation keeps its published amounts under Glyph Scaling, and Standard burasagari counts a hung line start as room; Fullwidth `!` / `?` keep an upright fallback in vertical type; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel (including font-defined Stylistic Sets), Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, show recently applied families first (#3515), filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | 🟡 Fullwidth `!` / `?` keep an upright fallback in vertical type; Hyphenation… and Justification… per paragraph (#2310, #2755), Auto Leading also driving the Character panel's Leading, the Alt+↑/↓ leading nudge and Fill with Placeholder Text; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel, Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | 🟡 Fullwidth `!` / `?` keep an upright fallback in vertical type; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel, Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, show recently applied families first (#3515), filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | Indian-language pattern hyphenation preserves syllables in both composers (#4947); 🟡 Hanging punctuation keeps its published amounts under Glyph Scaling, and Standard burasagari counts a hung line start as room; Fullwidth `!` / `?` keep an upright fallback in vertical type; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel (including font-defined Stylistic Sets), Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, show recently applied families first (#3515), filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | Indian-language pattern hyphenation preserves syllables in both composers (#4947); 🟡 Fullwidth `!` / `?` keep an upright fallback in vertical type; Hyphenation… and Justification… per paragraph (#2310, #2755), Auto Leading also driving the Character panel's Leading, the Alt+↑/↓ leading nudge and Fill with Placeholder Text; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel, Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M7 | Type (point/area/path, editing, styles, OpenType, threading, glyphs) | Indian-language pattern hyphenation preserves syllables in both composers (#4947); 🟡 Fullwidth `!` / `?` keep an upright fallback in vertical type; Document-point character controls after object/group scaling (#1034; optional font-size preservation remains separate), Character/Paragraph Styles (explicit Auto-leading resets and local leading overrides), per-paragraph paragraph attributes, mixed paragraph alignment indication (headless regressions, full integration CI and visual review pass), Area Type Options (with Width/Height, Auto Size and Shrink Text to Fit; overflow reported to agents and vertical Align), type areas resized by their handles and reshaped with Direct Selection, threaded text, Fit Headline, Glyphs, OpenType panel, Find Font (Document, Recent and System replacement sources, #5217), installed system fonts in every font menu (fonts registered with Windows outside its font folders, the XDG and Flatpak host font folders on Linux, and fonts installed while the app runs, listed when it comes back to the front; searchable; the Character and Properties menus show each family's sample of the selected text, preview it live under the pointer or ↑/↓, show recently applied families first (#3515), filter by script and kind, list a family's styles, and star favourites; the Glyphs panel and Find Font's Replace With use the same menu without the live preview) and found by name on open/import (full-name aliases and Missing Fonts searches verified, #1258; Windows font-service QA pending), variable fonts' named instances as styles, CJK names in the UI, input methods (marked text in place, candidate window at the caret; Japanese IME), Text Wrap (offset, invert, both sides of an object; follows edits), Type on a Path effects and Options with draggable start/centre/end brackets (slide, flip), tab stops + Tabs panel (Above Text floats it over the selected text, its ruler at the canvas zoom so stops line up with the columns, #729), inline symbols in text (beyond parity), Hebrew/Arabic bidirectional text, Paragraph Direction, Every-line/Single-line Composer per object (ragged text too) done; tab leaders, spell check, vertical type pending | 45–60 |
| M8 | Transform & distort (Puppet Warp, Liquify tools, Envelopes, Blends, Perspective Grid) | ✅ done (M8.1–M8.20 on 2026-10-06, fidelity pass): Liquify Tool Options with one shared brush, pen pressure, hold-to-apply, a safe scope and incremental strokes; tool options that last; Puppet Warp rotation, multi-select, Control bar and a rest-shape session that follows Undo; Width tool on compound paths; Envelope dialogs with preview, Reset with Warp/Mesh, full Envelope Options, type/images/symbols/appearance/gradients/patterns distorted on canvas and in every export, warps that keep their frame, Edit Contents, mesh handles and Control bar; Blend Options, anchor-targeted Blend tool, editable spine, keys picked on the canvas, faithful interpolation and knockout; Anchor Point spine conversion/handle editing and selection priority (#2544), with #2425 Shift reshape preserved; Perspective Grid with Define Grid, presets, lock/snap/rulers, widgets, the 1–4 plane switch, movable planes, Perspective Selection scale/copy/perpendicular/Transform Again, and type and symbols truly projected with Edit Text. Left: Anti-Alias and Preserve Shape output, warp-envelope point editing, brush interpolation in blends, Free Transform/Scale/Reflect along a rotated box | 2–4 |
| M9 | Live effects (+ 3D & Materials) | 🟡 2D effects done incl. Effect → Pathfinder, Color Adjustments and Document Raster Effects Settings; PDF export warns when the pixel cap lowers raster-effect resolution; Artistic › Colored Pencil, Cutout, Dry Brush, Film Grain, Fresco, Neon Glow, Paint Daubs, Palette Knife, Poster Edges, Rough Pastels, Smudge Stick, Sponge, Underpainting and Watercolor and Sketch › Halftone Pattern, Bas Relief, Charcoal, Conté Crayon, Photocopy, Stamp, Torn Edges and Water Paper done (57/57 Photoshop filters); Revolve with automatic smooth vector shading, default-on circular caps and continuous rims, Extrude & Bevel, Inflate and Rotate with one to ten colored directional lights and four original lighting presets; SVG Filters, remaining raster effects and 3D materials and shadows pending | 81–130 |
| M10 | Brushes, symbols, patterns, Repeat | 🟡 pattern swatches (5 tile types, Pattern Options, editing mode, SVG `<pattern>`/PDF export) and live Repeat (radial/grid/mirror) done; interactive selected mirror axis implemented (focused and native checks passed; full CI blocked by an unrelated text test); symbol libraries done (Window › Symbol Libraries, a generated Basic Shapes library, User Defined, Other Library…, Save Symbols); brush libraries done (Window › Brush Libraries, four generated libraries, User Defined, Other Library…, Save Brushes); symbol editing shows draggable 9-slice guides (#5280), with guides outside the artwork still unsupported; brushes/symbols in progress | 23–37 |
+4 -3
View File
@@ -1,6 +1,6 @@
# Parity with Adobe Illustrator
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
## Feature submission evidence
@@ -31,6 +31,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
| 2026-11-06 | minor | Stroke gradients: an arrowhead whose tip sits on the end of a long straight leg is painted by the gradient to the corners of its base. The slices that reach across a head now run to the end of its reach instead of narrowing towards the next corner (#5964). Test: `stroke::tests_gradient::slices_cover_an_arrowhead_on_a_long_straight_leg`. Scores and estimates unchanged. |
| 2026-11-06 | minor | Width profiles: the width between two width points follows a smooth curve instead of a straight line, so a stroke no longer kinks at each width point (#5714). Each side is a monotone cubic through its points: flat at a widest or narrowest point, never past either point of a span; stacked points still step. Straight runs are sampled between width points to the drawing tolerance. Scores and estimates unchanged. |
| 2026-11-05 | minor | A nearby hit on a plain long stroke or outline avoids assembling its whole path. A hit near the middle of a 200,000-anchor path took about 11–13 ms before and 1.0–1.4 ms after in paired runs on a busy Windows machine; a miss inside the path's box fell from 18.7 ms to 1.6 ms, while a distant miss was unchanged. Other stroke styles and fill hits keep their existing checks. Scores and estimates unchanged; idle performance budgets remain unverified. |
@@ -184,7 +185,7 @@ dominate; 3D, graphs and automation are specialist). They sum to 105. Feature de
| Strokes, brushes, width profiles | 5 | 88% | Shift-double-click adjoining adjustment is implemented; brush libraries are done (four generated libraries, User Defined, Other Library…, Save Brushes); remaining: Art brush Overlap, Pattern brush auto corners, pen pressure on macOS, tilt/bearing/rotation | 8–15 | estimated; width-point creation and adjoining adjustment regression-tested; dialog layout reviewed; evidence below; finite-arithmetic follow-up regressions and full CI passed (evidence below) |
| Appearance, transparency, graphic styles, masks | 5 | 97% | raster effect reach in preview bounds | 1–2 | estimated; Transform typing, sliders, preview, and undo are covered in `crates/ui-egui/src/panels/tests_appearance.rs` |
| 3D and Materials (and Turntable) | 4 | ~25% | live Revolve with automatic smooth vector shading and default-on continuous circular caps, Extrude & Bevel (twist, taper, caps, five bevel shapes), Inflate and Rotate with Position presets (colored Inflate uses smooth membrane lighting; white-light Inflate retains its existing shading; Extrude & Bevel and Rotate retain planar shading; one to ten colored lights, shared neutral ambient, painter visibility); materials, light presets, shadows, ray tracing, 3D Classic, Turntable views, 3D export | 30–55 | estimated (Extrude & Bevel, Inflate and Rotate added 2026-10-12) |
| Type core | 9 | 80% | Auto-leading style resets are implemented; Hyphenation… and Justification… options are done (#2310, #2755), and a paragraph's Auto Leading also sets the Character panel's Leading, the Alt+↑/↓ leading nudge and Fill with Placeholder Text; remaining: Optical Margin Alignment, Middle Eastern features beyond bidi layout, optional group font-size preservation; transformed character controls fixed (#1034), see [type-parity.md](type-parity.md) | 14–19 | estimated; recent-font groups in font pickers (#3515); full-name font matches regression-tested (#1258); mixed paragraph alignment indication implemented; headless regressions, full integration CI and visual review pass; localized legacy family-name fallback with loaded/catalog regressions (#2208); Fractional Widths per type object regression-tested; color emoji fonts with bitmap glyphs (`sbix`, `CBDT`) draw and export; threading ports: every selected area type and type on a path shows its in and out ports (empty, arrow, red "+"), and the Selection tool threads from either, the in port into a frame before it, and a double-click on a threaded port breaks the thread there (`threads::tests::break_splits_the_thread_and_the_story_flows_into_the_first_part`, `select::tests::a_double_click_on_a_threaded_port_breaks_the_thread`, `canvas::tests::a_double_click_on_a_threaded_out_port_breaks_the_thread`) (#2572; `select::tests::a_click_on_the_in_port_threads_into_a_frame_before_it`, `text::tests::selected_type_shows_its_ports_in_each_state`, `threads::tests::add_before_threads_the_story_from_the_new_frame_into_the_clicked_one`, live screenshot); the Glyphs panel highlights and scrolls to the character selected with the Type tool (#4908, `panels::glyphs` tests); the OpenType panel lists only `ss01`–`ss20` sets present in the selected font and uses its custom names when supplied; Type-range desktop Copy publishes styled art and keeps font family, size and color on canvas Paste after editing (#5636) |
| Type core | 9 | 80% | Auto-leading style resets are implemented; Hyphenation… and Justification… options are done (#2310, #2755), and a paragraph's Auto Leading also sets the Character panel's Leading, the Alt+↑/↓ leading nudge and Fill with Placeholder Text; remaining: Optical Margin Alignment, Middle Eastern features beyond bidi layout, optional group font-size preservation; transformed character controls fixed (#1034), see [type-parity.md](type-parity.md) | 14–19 | estimated; eleven-language pattern hyphenation in both composers, with grapheme and shaping-cluster protection (#4947, `hyphen::tests` and `layout::wrapping_tests`); Sanskrit patterns pending an allowlisted source; recent-font groups in font pickers (#3515); full-name font matches regression-tested (#1258); mixed paragraph alignment indication implemented; headless regressions, full integration CI and visual review pass; localized legacy family-name fallback with loaded/catalog regressions (#2208); Fractional Widths per type object regression-tested; color emoji fonts with bitmap glyphs (`sbix`, `CBDT`) draw and export; threading ports: every selected area type and type on a path shows its in and out ports (empty, arrow, red "+"), and the Selection tool threads from either, the in port into a frame before it, and a double-click on a threaded port breaks the thread there (`threads::tests::break_splits_the_thread_and_the_story_flows_into_the_first_part`, `select::tests::a_double_click_on_a_threaded_port_breaks_the_thread`, `canvas::tests::a_double_click_on_a_threaded_out_port_breaks_the_thread`) (#2572; `select::tests::a_click_on_the_in_port_threads_into_a_frame_before_it`, `text::tests::selected_type_shows_its_ports_in_each_state`, `threads::tests::add_before_threads_the_story_from_the_new_frame_into_the_clicked_one`, live screenshot); the Glyphs panel highlights and scrolls to the character selected with the Type tool (#4908, `panels::glyphs` tests); the OpenType panel lists only `ss01`–`ss20` sets present in the selected font and uses its custom names when supplied; Type-range desktop Copy publishes styled art and keeps font family, size and color on canvas Paste after editing (#5636) |
| Type advanced (CJK, spelling, Touch Type, Retype) | 4 | 50% | CJK vertical composition (ruby, mojikumi), variable font axes, tab leaders, spell check, Touch Type, Retype | 20–28 | estimated; upright fallback for fullwidth `!` / `?` regression-tested; score and hours unchanged |
| Symbols, blends, envelopes, Repeat, perspective | 5 | 87% | 30.7's Blend panel with ease in/out, on-canvas Direct Selection of parts inside dynamic symbol instances and their `.ai` round trip, more built-in symbol libraries, envelope Anti-Alias/Preserve Shape; Symbol Options › Registration, Export Type (Graphic / Movie Clip) and 9-slice guides (drawn and draggable during symbol editing, #5280) and Symbol Type (dynamic symbols keep per-instance appearance linked, #4938) are done | 4–8 | estimated; Blend panel Type and Ramp control step easing with a separate color Shift (#2539); Blend Options retains spacing and orientation; polynomial curves are original approximations; interactive selected mirror axis implemented; bounding-box handles take priority over the axis line (focused regression and native checks passed; full CI blocked by an unrelated text test); #2544 spine Anchor Point conversion and picking regression-tested; scores and hours unchanged |
| Type advanced (CJK, spelling, Touch Type, Retype) | 4 | 50% | CJK vertical composition (ruby, mojikumi), tab leaders, spell check, Touch Type, Retype | 20–28 | estimated; upright fallback for fullwidth `!` / `?` regression-tested; score and hours unchanged |
@@ -458,7 +459,7 @@ about 1–1.5 agent-hours each, so the other rows (estimated on the older scale)
| Raster effects (Effect Gallery, Document Raster Effects Settings) | 4 | 35% | ~36 Photoshop-style filters (Artistic, Brush Strokes, Sketch, Stylize) and Texturizer's Load Texture (since done, see the area table above, as is the Effect Gallery, #2883); Document Raster Effects Settings, raster effects in PDF, the pixel-filter pipeline, Radial Blur, Smart Blur (Normal, Edge Only and Overlay Edge), Unsharp Mask, Glowing Edges, Distort (Diffuse Glow, Glass, Ocean Ripple), Pixelate (Color Halftone, Crystallize, Mezzotint, Pointillize), Texture (Craquelure, Grain, Mosaic Tiles, Patchwork, Stained Glass, Texturizer) and Video (De-Interlace, NTSC Colors) are done | 8–14 |
| 3D and Materials | 4 | ~25% | Initial Revolve, Extrude & Bevel, Inflate and Rotate, with simple lighting and four original lighting presets; materials, shadows, ray tracing, 3D Classic and more complete visibility remain | 25–45 |
| Type advanced | 4 | 50% | CJK composition for vertical type (mojikumi beyond Line-end Punctuation Half Width — the other sets (and their paragraph-start bracket and indent rules), custom kinsoku sets (beyond Hard, Soft and None) and the Mojikumi Settings dialog —, manual tate-chu-yoko is done, its up/down settings remain; No Break is done), tab leaders, spell check (open dictionary), Touch Type, Retype; vertical point/area/path type and Type Orientation have initial support (beyond parity, not scored: inline symbols in text) | 20–28 |
| Type core | 9 | 80% | Middle Eastern features beyond bidi layout and Paragraph Direction (the Middle Eastern composers, editable bidirectional SVG text, a split caret where directions meet); Every-line Composer fidelity for justified and ragged text (available per object; mixed type sizes in a paragraph still break single-line in non-rectangular area type and with text wrap), Optical Margin Alignment, paragraph spacing limit for vertically justified area type, hidden characters, paragraph attributes in the Type tool's copy and paste (the characters keep their styles, the paragraphs take the destination's), mixed-value display in the Paragraph panel for a selection across differing paragraphs, partial selection of type-area anchors by marquee, optional font-size preservation during group scaling (scaled character controls fixed in #1034). Hyphenation and Justification options, Fractional Widths, System Layout and styled Type-range canvas Paste (#5636) are done | 14–19 |
| Type core | 9 | 80% | Middle Eastern features beyond bidi layout and Paragraph Direction (the Middle Eastern composers, editable bidirectional SVG text, a split caret where directions meet); Every-line Composer fidelity for justified and ragged text (available per object; mixed type sizes in a paragraph still break single-line in non-rectangular area type and with text wrap), Optical Margin Alignment, paragraph spacing limit for vertically justified area type, hidden characters, paragraph attributes in the Type tool's copy and paste (the characters keep their styles, the paragraphs take the destination's), mixed-value display in the Paragraph panel for a selection across differing paragraphs, partial selection of type-area anchors by marquee, optional font-size preservation during group scaling (scaled character controls fixed in #1034). Hyphenation and Justification options, Fractional Widths, System Layout, styled Type-range canvas Paste (#5636), and pattern hyphenation for eleven Indian languages with grapheme/cluster protection (#4947) are done; Sanskrit automatic patterns remain pending an allowlisted source | 14–19 |
| Symbols, blends, envelopes, Repeat, perspective | 5 | 90% | more built-in symbol libraries (original), dynamic symbols, envelope Anti-Alias/Preserve Shape output and warp point editing, brush interpolation in blends (M8 fidelity pass done); Symbol Options › Registration and Export Type are done; symbol editing shows draggable 9-slice guides (#5280), while guides outside the artwork remain unsupported | 4–7 |
| Image Trace, graphs, image tools | 3 | 72% | graph Column designs (Graph Design, Marker designs and series colours set with Group Selection are done), Create Object Mosaic, per-feature stroke/fill choice and varying widths in Image Trace's Create Strokes (Vector Halftone and the Image Trace View modes, Palette and Create Strokes are done) | 6–10 |
| Layers, artboards, document setup | 5 | 82% | Layers panel: a confirmation before deleting layers that hold art, Collect for Export, row context menus, the Layer Options dialog for several rows with mixed values, Paste Remembers Layers for sublayers, drag-scrolling a long panel while dragging rows; artboard preset polish (artboard escape routing and document setup modal handoff done; Move Artwork for artboard X/Y edits, Rearrange All Artboards, Document Setup, New Document and the rest of the Layers panel are done) | 4–7 |
+5 -3
View File
@@ -1,6 +1,6 @@
# Type parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (Bulgarian among the languages, with its quote marks and the fonts' Bulgarian forms, #5945; previously minor: Show Snap to Glyph Options scrolls to the options, with a Snap to Glyph checkbox, #5273; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; Bulgarian among the languages, with its quote marks and the fonts' Bulgarian forms, #5945; previously minor: Show Snap to Glyph Options scrolls to the options, with a Snap to Glyph checkbox, #5273; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
Type is Illustrator's largest single area by use (weight 13 of 105 across "Type core" and "Type advanced" in
[target-app-parity.md](target-app-parity.md)). This checklist lists the features one by one. Status is from the
@@ -42,9 +42,9 @@ against Illustrator's public documentation; **estimated** unless noted.
| System Layout | done | Character panel menu › System Layout, `type.systemLayout`: the whole document, off by default and for documents from before it, saved only when on. On, every text object advances by whole points (at least one when a character takes space). New point, area and path type, threaded frames, placed text, graph and dimension labels and pasted plain text inherit it. Evidence: `tests::system_layout_rounds_positive_advances_to_whole_points`, `typecmd::area_tests::system_layout_sets_the_document_and_every_text_object`, `panels::character::tests::system_layout_menu_item_toggles_the_document` |
| Fractional Widths | done | Character panel menu › Fractional Widths, `type.fractionalWidths`: per type object, and every frame of its threads. On by default and for documents from before it; saved only when off. Off, each character that takes space advances by a whole number of points, at least one, so small type does not run together. Evidence: `tests::fractional_widths_off_rounds_positive_advances_to_whole_points`, `typecmd::area_tests::fractional_widths_is_set_per_object_and_saved_only_when_off`, `panels::character::tests::fractional_widths_menu_item_toggles_the_type_object` |
| Roman Hanging Punctuation | done | Paragraph panel menu › Roman Hanging Punctuation, `text.setFormat {romanHangingPunctuation}` (#2756): per paragraph, Optical Margin Alignment's punctuation and amounts without the letters; paragraph styles carry it. Evidence: `tests::roman_hanging_punctuation_hangs_punctuation_but_not_letters`, `typecmd::area_tests::roman_hanging_punctuation_is_set_per_paragraph_and_saved_only_when_on`. Whole paragraphs hang as published with both composers, ragged, centred and justified, with Line-end Punctuation Half Width and bidirectional lines; Justification's Glyph Scaling leaves the hung marks at their width, and Standard burasagari counts what hangs at a line's start as room before hanging a comma (`tests_hang`) |
| Hyphenation… and Justification… options | done | Hyphenation… (`ui.hyphenation`, `text.setFormat`) sets each paragraph's Words Longer Than, After First, Before Last, Hyphen Limit, Hyphenation Zone (Single-line Composer only) and Hyphenate Capitalized Words, and paragraph styles carry them (#2310). Justification… (`ui.justification`, `text.setFormat`, #2755) sets Word Spacing, Letter Spacing and Glyph Scaling (Minimum, Desired, Maximum), Auto Leading and Single Word Justification; Desired applies to every line, justified lines and the Every-line Composer use the ranges. Vertical type isn't glyph scaled; type on a path doesn't use them. Evidence: `crates/text/src/tests/justify.rs`, `dialogs::justification::tests` |
| Hyphenation… and Justification… options | done | Eleven Indian languages use attributed patterns and preserve syllables in both composers (#4947). Hyphenation… (`ui.hyphenation`, `text.setFormat`) sets each paragraph's Words Longer Than, After First, Before Last, Hyphen Limit, Hyphenation Zone (Single-line Composer only) and Hyphenate Capitalized Words, and paragraph styles carry them (#2310). Justification… (`ui.justification`, `text.setFormat`, #2755) sets Word Spacing, Letter Spacing and Glyph Scaling (Minimum, Desired, Maximum), Auto Leading and Single Word Justification; Desired applies to every line, justified lines and the Every-line Composer use the ranges. Vertical type isn't glyph scaled; type on a path doesn't use them. Evidence: `crates/text/src/tests/justify.rs`, `dialogs::justification::tests` |
| Roman Hanging Punctuation | done | Paragraph panel menu › Roman Hanging Punctuation, `text.setFormat {romanHangingPunctuation}` (#2756): per paragraph, Optical Margin Alignment's punctuation and amounts without the letters; paragraph styles carry it. Evidence: `tests::roman_hanging_punctuation_hangs_punctuation_but_not_letters`, `typecmd::area_tests::roman_hanging_punctuation_is_set_per_paragraph_and_saved_only_when_on` |
| Hyphenation… and Justification… options | done | Hyphenation… (`ui.hyphenation`, `text.setFormat`) sets each paragraph's Words Longer Than, After First, Before Last, Hyphen Limit, Hyphenation Zone (Single-line Composer only) and Hyphenate Capitalized Words, and paragraph styles carry them (#2310). Justification… (`ui.justification`, `text.setFormat`, #2755) sets Word Spacing, Letter Spacing and Glyph Scaling (Minimum, Desired, Maximum), Auto Leading and Single Word Justification; Desired applies to every line, justified lines and the Every-line Composer use the ranges. Vertical type isn't glyph scaled; type on a path doesn't use them. Auto Leading also sets the Leading the Character panel shows for Auto type, the leading Alt+↑/↓ (`type.step`) steps from, per paragraph, and the lines Fill with Placeholder Text counts. Evidence: `crates/text/src/tests/justify.rs`, `dialogs::justification::tests`, `tests_prefs::auto_leading_steps_and_fills_from_the_paragraph_auto_leading`, `panels::character` test `leading_field_shows_the_paragraph_auto_leading` |
| Hyphenation… and Justification… options | done | Eleven Indian languages use attributed patterns and preserve syllables in both composers (#4947). Hyphenation… (`ui.hyphenation`, `text.setFormat`) sets each paragraph's Words Longer Than, After First, Before Last, Hyphen Limit, Hyphenation Zone (Single-line Composer only) and Hyphenate Capitalized Words, and paragraph styles carry them (#2310). Justification… (`ui.justification`, `text.setFormat`, #2755) sets Word Spacing, Letter Spacing and Glyph Scaling (Minimum, Desired, Maximum), Auto Leading and Single Word Justification; Desired applies to every line, justified lines and the Every-line Composer use the ranges. Vertical type isn't glyph scaled; type on a path doesn't use them. Auto Leading also sets the Leading the Character panel shows for Auto type, the leading Alt+↑/↓ (`type.step`) steps from, per paragraph, and the lines Fill with Placeholder Text counts. Evidence: `crates/text/src/tests/justify.rs`, `dialogs::justification::tests`, `tests_prefs::auto_leading_steps_and_fills_from_the_paragraph_auto_leading`, `panels::character` test `leading_field_shows_the_paragraph_auto_leading` |
| Tab stops and leaders; Tabs panel | partial | Tabs panel and stops with leaders in the model (`text.tabs.set`); a stop drags from where the press landed (#1458); leaders fill the tab's gap, repeated on a grid so they line up from line to line (#1877); Ctrl-dragging a stop (Command on macOS) moves all the stops together |
| Hidden characters (Show Hidden Characters) | done | `type.hiddenCharacters` |
| Spell check (Check Spelling, Auto Spell Check, custom dictionary) | missing | menu stubs; needs an openly licensed dictionary |
@@ -66,6 +66,7 @@ against Illustrator's public documentation; **estimated** unless noted.
| CJK: manual tate-chu-yoko | done | Character panel menu › Tate-chu-yoko (`text.setFormat` / `text.setRangeStyle {tateChuYoko}`), with Show East Asian Options: marked characters stand side by side across one em of a vertical column, squeezed to the em when wider; two or three half-width digits still do so without the mark; horizontal type keeps the mark and does not move them. Tate-chu-yoko Settings… (`ui.tateChuYokoSettings`, `{tcyUpDown, tcyLeftRight}` in points) moves a marked block up or down and right or left as one piece. Evidence: `tests_vertical::manual_tate_chu_yoko_sets_marked_characters_across_one_em`, `tests_vertical::tate_chu_yoko_settings_move_a_marked_block_up_down_left_and_right`, `typecmd::tate_chu_yoko_is_a_character_attribute_saved_only_when_on`, `typecmd::tate_chu_yoko_settings_are_character_attributes_saved_only_when_set`, `dialogs::tate_chu_yoko::tests` |
| CJK: Standard Vertical Roman Alignment | done | Character panel menu › Standard Vertical Roman Alignment (`text.setFormat` / `text.setRangeStyle {standardVerticalRoman}`), with Show East Asian Options, off by default: in vertical type the marked half-width characters (Latin letters, digits and other characters that would lie on their side) stand upright one below the other, each in its upright cell; spaces keep their width and tate-chu-yoko blocks stay across the column; horizontal type keeps the mark and does not change. Character Style Options has its own checkbox for it. Evidence: `tests_vertical::standard_vertical_roman_alignment_stands_half_width_characters_upright`, `typecmd::standard_vertical_roman_is_a_character_attribute_saved_only_when_on` |
| CJK: ruby | partial | ruby (ふりがな) for live text (`type.ruby`): a reading over a byte range, above (right of the column in vertical type) or below, start/centre/end alignment, size, overhang or squeeze; saved natively, laid out with its line growing, drawn on the canvas, in SVG and PDF (as outlines where ruby is present), in EPS, EMF/WMF and legacy `.ai` (legacy `.ai` writes type with ruby as outlines), and kept by Create Outlines, Expand Appearance and flattening, each glyph where the layout puts it (`typecmd::ruby_tests::create_outlines_keeps_the_ruby_where_it_is_laid_out`) | #633 |
| Language per character (Character panel › Language, character styles), text shaped in it | done | `text.setFormat` / `text.setRangeStyle {language}` by name or BCP 47 tag, one of Document Setup's languages (Hindi, Marathi, Gujarati, Bengali, Punjabi, Tamil, Telugu, Kannada, Malayalam, Odia and Urdu added, #4943; Assamese and Sanskrit added, #4947; Serbian: Cyrillic, Serbian: Latin and Croatian); the shaper gets the tag, so the font's language forms apply (OpenType `locl`: Turkish keeps `fi` apart and the dot on its i, #4940); new type takes the document's language; saved as the tag only when set, carried by character styles (#4946). English and eleven Indian languages hyphenate by run language; Sanskrit automatic hyphenation awaits allowlisted patterns (#4947). Not yet: spelling by it, `.ai`/PDF import of a text's language, paragraph styles. Evidence: `features::tests::language_picks_the_fonts_forms`, `features::tests::serbian_gets_the_fonts_serbian_forms`, `typecmd::area_tests::language_is_a_character_attribute_saved_only_when_set`, `tests::typo::indic_language_runs_hyphenate_with_both_composers`, `hyphen::tests::sanskrit_without_allowlisted_patterns_uses_only_exceptions` |
| Language per character (Character panel › Language, character styles), text shaped in it | done | `text.setFormat` / `text.setRangeStyle {language}` by name or BCP 47 tag, one of Document Setup's languages (Hindi, Marathi, Gujarati, Bengali, Punjabi, Tamil, Telugu, Kannada, Malayalam, Odia and Urdu added, #4943; Serbian: Cyrillic, Serbian: Latin and Croatian; Bulgarian, #5945); the shaper gets the tag, so the font's language forms apply (OpenType `locl`: Turkish keeps `fi` apart and the dot on its i, #4940); new type takes the document's language; saved as the tag only when set, carried by character styles (#4946). Not yet: hyphenation and spelling by it, `.ai`/PDF import of a text's language, paragraph styles. Evidence: `features::tests::language_picks_the_fonts_forms`, `features::tests::serbian_gets_the_fonts_serbian_forms`, `typecmd::area_tests::language_is_a_character_attribute_saved_only_when_set` |
| No Break | done | Character panel menu (`text.setFormat` / `text.setRangeStyle {noBreak}`): the marked characters stay on one line, including across a space; a run that does not fit after earlier text moves together, and a run longer than the line stays together. Evidence: `layout::wrapping_tests::no_break_keeps_marked_characters_on_one_line`, `tests::no_break_keeps_marked_words_on_one_line`, `typecmd::no_break_is_a_character_attribute_saved_only_when_on` |
| Inline symbols in text | beyond Illustrator | not scored |
@@ -78,6 +79,7 @@ Character Styles menu New/Redefine and footer New capture the first selected cha
| Date | Change | Summary |
|---|---|---|
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
| 2026-11-06 | minor | Alt + numeric-keypad codes (`Alt+0176` → °) type their character at the caret on Windows, and `type.insert` inserts a character by `code` or `unicode` (#5108); scores and estimates unchanged |
| 2026-11-06 | minor | Snap to Glyph › Glyph Bounds: each glyph's box gives four corners a drawn point lands on, also on a curved side (`B`), and its box and edges turn with rotated type (#5112); scores and estimates unchanged |
| 2026-11-05 | minor | Character panel › Show Snap to Glyph Options scrolls the panel down to the Snap to Glyph section, which comes after every character attribute and could sit out of sight, and the section starts with a Snap to Glyph checkbox (View › Snap to Glyph) so its dimmed options can be turned on there (#5273); scores and estimates unchanged |