aboutsummaryrefslogtreecommitdiffstats
path: root/text/shape.c
Commit message (Collapse)AuthorAgeFilesLines
* Set text in a stack of fonts: each grapheme cluster in the first that has iteunhhu2026-09-281-2/+2
| | | | | | | | | | | | | | vega_layout takes fonts in order of preference (VegaFonts). A grapheme cluster goes to the first font that has all its characters (default ignorables aside: shaping hides them); a cluster of Common and Inherited characters stays in the font before it when that one has it, so the spaces between Arabic words stay in the Arabic font; failing that, the first font with its first character, else the first font. Runs split where the font changes too. Positions are in the first font's units, a run's pen scaled as a whole so rounding does not add up. Callers can narrow what a font has (a symbol file holds only the glyphs its codes reach). vega_default_ignorable is shape.c's HarfBuzz 10.2 set, now public.
* Shape Syriac, stretch with stch, and fall back for fonts without Arabic formseunhhu2026-09-281-19/+158
| | | | | | | | | | | | | | | | | | | | | The rest of HarfBuzz 10.2's Arabic shaper. Joining types now come from HarfBuzz's own table (Unicode 16, with Syriac's Alaph and Dalath-Rish groups the state machine's last two columns use), the general category deciding where it has none, so Syriac shapes with fin2, fin3 and med2. What stch multiplies is recorded and, after positioning, stretched under the word before it, repeating pieces copied as often as fit. A font with presentation forms but no Arabic features gets HarfBuzz's fallback lookups, which the build tool writes as OpenType and the runtime applies at their pause like any GSUB lookup. The generator now reads HarfBuzz's generated tables through their lookup functions' ranges and offsets: rows whose range starts mid-row have blank cells in front, which the row comments alone miscounted (Arabic Supplement); the Indic table, read again this way, did not change. Noto Sans Syriac, FreeSans's Syriac, Unifont's Arabic and Noto Sans Arabic shape as HarfBuzz does at 3,000 runs a plan; no installed font is refused any more (213 fonts, 1,822 plans).
* Shape Thai and Lao as HarfBuzz doeseunhhu2026-09-281-1/+118
| | | | | | | | | | | | | | The Thai shaper, from HarfBuzz 10.2's source: SARA AM comes apart into NIKHAHIT and SARA AA, the NIKHAHIT moving back over the above-base marks (and counting as a mark when advances are zeroed). A font with no Thai script of its own (only DFLT or latn in GSUB) gets its marks shifted to its private-use glyphs, Windows' before the Mac's, as the stacking around the base asks; the planner records, as HarfBuzz's does, whether the font had the script under its own tag. Noto Sans Thai and Lao, TLWG Loma, FreeSerif's Thai, DejaVu Sans's Lao and Unifont shape as HarfBuzz does at 3,000 runs a plan, and Loma with its thai script taken out (so the private-use path runs) at 5,000.
* Shape the Universal Shaping Engine's scripts as HarfBuzz doeseunhhu2026-09-281-9/+205
| | | | | | | | | | | | | | | | | | | | | | The USE shaper, from HarfBuzz 10.2's source, for Sinhala, Tibetan, Javanese, Balinese, Mongolian and the rest of its eighty-odd scripts (and Indic fonts with the new dev3-style tags). The syllable machine reads past CGJs and ZWNJs that marks follow; rphf goes on each syllable's first glyphs and records the repha it made, pref records its pre-base glyph, with substitution marks cleared between; a repha moves before the first post-base glyph and pre-base vowels move back. Scripts that join like Arabic take Arabic's forms (Mongolian's free variation selectors their base's), the others join syllable to syllable. Marks lose their advances before GPOS. text/syllabic.py carries HarfBuzz's compressed USE table over as it is, compiles the USE grammar with the others (100,000 random runs against Ragel's machine: no syllable differs), and checks at compile time that the categories syllabic.h names are the machines' own. Noto Sans Sinhala, Javanese, Balinese, Mongolian, Noto Serif Tibetan, FreeSerif's Sinhala and Unifont's five shape as HarfBuzz does at 5,000 runs a plan; all installed fonts (1,748 plans) and 21 Noto fonts too.
* Leave U+180F visible, as HarfBuzz 10.2 doeseunhhu2026-09-281-1/+1
| | | | | | | HarfBuzz's is_default_ignorable takes U+180B..180E from the Mongolian block, not the fourth free variation selector (U+180F, default ignorable since Unicode 14), so it keeps its own glyph rather than the invisible one. Unifont's Mongolian showed it.
* Shape Khmer and Myanmar as HarfBuzz doeseunhhu2026-09-281-19/+175
| | | | | | | | | | | | Two more shapers on the syllabic groundwork, from HarfBuzz 10.2's source. Khmer reorders before any lookup: a coeng and Ro go before the base, masked for pref, what follows them for cfar, a left matra goes first; split matras decompose with U+17C1. Myanmar finds the base after a kinzi, gives each glyph its place around it and sorts by place, and zeroes mark advances before GPOS rather than after. Noto Sans Khmer and Noto Sans Myanmar shape as HarfBuzz does at 20,000 runs a plan, and so do Unifont's Khmer and Myanmar (no GSUB).
* Shape the nine Indic scripts as HarfBuzz doeseunhhu2026-09-281-28/+844
| | | | | | | | | | | | | | | | | | | | | | | | | | The Indic shaper, from HarfBuzz 10.2's source: syllables found by the Indic machine; each syllable's base consonant, its pre-base matras and reph moved around it and masked for the basic features, applied one at a time within the syllable; then matras, reph and pre-base-reordering consonants placed again by what the features made. Vowel constraints, Indic decompositions and compositions, dotted circles for broken syllables, and per-syllable matching come with it. Plans carry GSUB pauses (steps where the shaper does its part) and the stages of the features the shaper asks whether they would substitute; the runtime answers with each subtable's would_apply, as HarfBuzz does. Masks are now the common ones and each shaper's own. text/syllabic.py reads HarfBuzz's Ragel grammars (Indic, Khmer, Myanmar) and compiles each to a minimal DFA with Ragel's scanner semantics; beside the machines Ragel generated from the same grammars, 100,000 random runs each find no syllable that differs. It also reads HarfBuzz's Indic table (Unicode 16) cell for cell. Every installed font shapes as HarfBuzz does (213 fonts, 1,688 plans); the Indic ones at 20,000 runs a plan (FreeSerif's eight scripts, FreeSans, Unifont's nine without GSUB), and nine new-spec Noto Sans fonts at 5,000.
* Give Telugu's length marks classes 4 and 5, as HarfBuzz 10.2 doeseunhhu2026-09-281-2/+4
| | | | | | | HarfBuzz reorders marks by a modified combining class; for U+0C55 and U+0C56 (canonical classes 84 and 91) it is 4 and 5, so they sort before the virama. Vega had 0, which rustybuzz 0.20 uses; HarfBuzz 10.2's hb-unicode.hh says otherwise, and Unifont's Telugu showed it.
* Shape Hangul, kern with kern tables, and place marks without GPOS, as ↵eunhhu2026-09-281-11/+425
| | | | | | | | | | | | | | | | | | | | | | | | HarfBuzz does The planner now picks who positions as HarfBuzz 10.2 does: GPOS, the old kern table when GPOS has no kern feature, and marks placed by combining class and ink boxes when there is no GPOS; the Hangul shaper composes syllables the font has whole, takes apart those it lacks into jamo for ljmo, vjmo and tjmo, and moves tone marks before their syllable. The section grows to an 80-byte header (the kern table, and each glyph's ink box when a plan places marks without GPOS) and 88-byte plans (the kern mask, the jamo masks). Kern tables are applied pair subtable by pair subtable with HarfBuzz's own binary search; state machines, class subtables and cross-stream kerning, which no installed font has, are refused. The check spells Hangul syllables every way text does. Every installed font Vega accepts shapes as HarfBuzz does (209 fonts, 1,520 plans, a thousand runs each), and the fonts refused before at 20,000 runs a plan: Noto Sans CJK KR and Baekmuk for Hangul, IPA Gothic and Noto Mono for marks without GPOS, FreeSans, FreeSerif, Liberation and DejaVu Sans ExtraLight for kern tables, Unifont's Latin, Greek, Cyrillic, Hebrew and Hangul.
* Compose Yiddish yod-yod, not yod, with patah into FB1Feunhhu2026-09-281-1/+1
| | | | | | HarfBuzz's Hebrew presentation forms join U+05F2 and patah into U+FB1F; Vega had U+05D9 there. Only fonts without a GPOS mark feature take the rule, so no font Vega accepted showed it; Unifont's Hebrew did.
* Shape text as HarfBuzz does, from a symbol file, checked against HarfBuzzeunhhu2026-09-281-0/+2156
The build tool compiles a font's shaping plans the way HarfBuzz's planner does (features, stages, masks, lookups per script and direction) and carries them with the font's character map, advances and GDEF, GSUB and GPOS tables in a section of the symbol file (VEGASYM4); glyphs shaping reaches become symbols of their own. A small engine ports HarfBuzz 10's default, Arabic and Hebrew shaping step for step and reads the tables in place, every read bounds-checked. The build refuses a file whose shaping differs from HarfBuzz's on random runs: DejaVu Sans agrees on 600,000 runs in six scripts both ways, and every installed font the tool accepts agrees too, at 1.05-1.18 times HarfBuzz's time.