<feed xmlns='http://www.w3.org/2005/Atom'>
<title>vega/text/shape.h, branch master</title>
<subtitle>Surface runtime projecting Pure views across pixel, terminal, CLI, and web.
</subtitle>
<id>http://git.yeowoo.org/vega/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/vega/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/'/>
<updated>2026-09-28T15:13:58Z</updated>
<entry>
<title>Kern with class subtables too (kern formats 2 and 3)</title>
<updated>2026-09-28T15:13:58Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T15:13:58Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=ea6dbcf627e9a440590d0d35ff16ca7ae60d5719'/>
<id>urn:sha1:ea6dbcf627e9a440590d0d35ff16ca7ae60d5719</id>
<content type='text'>
The kern table's class subtables, OpenType's and Apple's, as HarfBuzz
reads them (hb-aat-layout-kerx-table.hh, hb-ot-kern-table.hh): format 2's
class tables give byte offsets into a kerning array, format 3's byte
classes index a value list. Both go through the same pass as pairs
(marks skipped, the kerning split between the pair). Format 2 filters the
glyphs by the class tables' digests, as HarfBuzz's accelerator does, so a
digest's false positive reads class 0 there too; what a subtable reads
must lie within it, the last one's within the table. The build checks the
subtables as HarfBuzz's sanitizer does, and still refuses state machines
(format 1) and cross-stream kerning.

text/test-kern.py makes fonts with format 2 and 3 subtables in every
order, with the edge cases that reading has (value 1, glyphs outside a
table, offsets below the array or odd, values past a subtable's or the
table's end, classes and indexes past their counts): 24 fonts, 96 plans,
the same as HarfBuzz. make check runs it where fontTools is. HarfBuzz's
suite: 5017 of 5199 the same.
</content>
</entry>
<entry>
<title>Carry variation sequences (cmap format 14)</title>
<updated>2026-09-28T15:07:05Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T15:07:05Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=cf6bcf8697589d2a6fc3c6d98bc52bf7eb1ea4ae'/>
<id>urn:sha1:cf6bcf8697589d2a6fc3c6d98bc52bf7eb1ea4ae</id>
<content type='text'>
The section now carries each sequence the font maps, a base and a
selector, with the glyph HarfBuzz gives the pair (a default one's the
base's own). As HarfBuzz's normalizer does, a sequence the font has
becomes that one glyph, the two characters' clusters merged; one it lacks
still passes on as two, the selector hidden. The header grows to 88 bytes
for the table.

The random check now mixes in the font's own sequences and stray
selectors: 30000 runs over Noto Sans CJK's 14787 ideographic variation
sequences are HarfBuzz's, and so are the installed fonts' and Noto's.
HarfBuzz's suite: 5014 of 5199 the same, none different; what is left is
what the build refuses and one run without a plan.
</content>
</entry>
<entry>
<title>Map characters as HarfBuzz maps them, not as it lists them</title>
<updated>2026-09-28T15:04:05Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T15:04:05Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=960fa21762484d3014a6778a7673f15acf2d34bb'/>
<id>urn:sha1:960fa21762484d3014a6778a7673f15acf2d34bb</id>
<content type='text'>
The shaping section's character map came from hb_face_collect_unicodes.
HarfBuzz's own suite showed where that list and its mapping part: it cuts
a format 13 map short (AdobeBlank2's whole Unicode to one glyph), and a
symbol map (3,0) it searches through the private use area, Latin and, in an
old Arabic font, Arabic too. Now every code point is asked with
hb_font_get_nominal_glyph (about 30 ms a font) and the map carried as
groups: codes going to consecutive glyphs, or all to one (12 bytes each,
so a format 13 map stays small).

HarfBuzz's suite: 5011 of 5199 cases the same (1355 before). The installed
fonts (213) and the Noto ones (21) still shape as HarfBuzz does on random
runs.
</content>
</entry>
<entry>
<title>Set text in a stack of fonts: each grapheme cluster in the first that has it</title>
<updated>2026-09-28T14:52:13Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T14:52:13Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=a4ca275ad1b5edc15474407e2852f8fe9abaac4e'/>
<id>urn:sha1:a4ca275ad1b5edc15474407e2852f8fe9abaac4e</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Shape Syriac, stretch with stch, and fall back for fonts without Arabic forms</title>
<updated>2026-09-28T14:20:08Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T14:20:08Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=bafb710f0047751e26b87897eaf2a05609708536'/>
<id>urn:sha1:bafb710f0047751e26b87897eaf2a05609708536</id>
<content type='text'>
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).
</content>
</entry>
<entry>
<title>Shape Thai and Lao as HarfBuzz does</title>
<updated>2026-09-28T14:07:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T14:07:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=218298bb16ef6c147aa6dafc3ea88f62c6fa6ef6'/>
<id>urn:sha1:218298bb16ef6c147aa6dafc3ea88f62c6fa6ef6</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Shape the Universal Shaping Engine's scripts as HarfBuzz does</title>
<updated>2026-09-28T14:03:30Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T14:03:30Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=5788d7e5bd6a26421346d69ae517502527940a0b'/>
<id>urn:sha1:5788d7e5bd6a26421346d69ae517502527940a0b</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Shape Khmer and Myanmar as HarfBuzz does</title>
<updated>2026-09-28T13:53:40Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T13:53:40Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=9bb85cffb10e0d4bc007406d1487a6dede3db975'/>
<id>urn:sha1:9bb85cffb10e0d4bc007406d1487a6dede3db975</id>
<content type='text'>
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).
</content>
</entry>
<entry>
<title>Shape the nine Indic scripts as HarfBuzz does</title>
<updated>2026-09-28T13:49:05Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T13:49:05Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=60a3c0232bbca8d5d8c1107ab8197d272212ef42'/>
<id>urn:sha1:60a3c0232bbca8d5d8c1107ab8197d272212ef42</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Shape Hangul, kern with kern tables, and place marks without GPOS, as HarfBuzz does</title>
<updated>2026-09-28T12:54:31Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T12:54:31Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/vega/commit/?id=88e16d6f971287afd0ab15d1cde73608cde43b1b'/>
<id>urn:sha1:88e16d6f971287afd0ab15d1cde73608cde43b1b</id>
<content type='text'>
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.
</content>
</entry>
</feed>
