From 5788d7e5bd6a26421346d69ae517502527940a0b Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 28 Sep 2026 15:03:30 +0100 Subject: Shape the Universal Shaping Engine's scripts as HarfBuzz does 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. --- text/syllabic.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'text/syllabic.h') diff --git a/text/syllabic.h b/text/syllabic.h index 8ab8699..d03116b 100644 --- a/text/syllabic.h +++ b/text/syllabic.h @@ -24,6 +24,20 @@ enum { /* A character's category | position << 8 (hb_indic_get_categories). */ uint16_t vega_indic_categories(uint32_t u); +/* The Universal Shaping Engine's categories (hb-ot-shaper-use-machine.rl). */ +enum { + VEGA_USE_O = 0, VEGA_USE_B = 1, VEGA_USE_N = 4, VEGA_USE_GB = 5, VEGA_USE_CGJ = 6, VEGA_USE_SUB = 11, + VEGA_USE_H = 12, VEGA_USE_HN = 13, VEGA_USE_ZWNJ = 14, VEGA_USE_WJ = 16, VEGA_USE_R = 18, VEGA_USE_VPRE = 22, + VEGA_USE_VMPRE = 23, VEGA_USE_FABV = 24, VEGA_USE_FBLW = 25, VEGA_USE_FPST = 26, VEGA_USE_MABV = 27, + VEGA_USE_MBLW = 28, VEGA_USE_MPST = 29, VEGA_USE_MPRE = 30, VEGA_USE_CMABV = 31, VEGA_USE_CMBLW = 32, + VEGA_USE_VABV = 33, VEGA_USE_VBLW = 34, VEGA_USE_VPST = 35, VEGA_USE_VMABV = 37, VEGA_USE_VMBLW = 38, + VEGA_USE_VMPST = 39, VEGA_USE_SMABV = 41, VEGA_USE_SMBLW = 42, VEGA_USE_CS = 43, VEGA_USE_IS = 44, + VEGA_USE_FMABV = 45, VEGA_USE_FMBLW = 46, VEGA_USE_FMPST = 47, VEGA_USE_SK = 48, VEGA_USE_G = 49, VEGA_USE_J = 50, + VEGA_USE_SB = 51, VEGA_USE_SE = 52, VEGA_USE_HVM = 53, VEGA_USE_HM = 54, VEGA_USE_HR = 55, VEGA_USE_RK = 56 +}; +/* A character's USE category (hb_use_get_category). */ +uint8_t vega_use_category(uint32_t u); + /* A syllable machine: a DFA over classes of symbols (categories, those * past 63 taken as 63). From each position the longest run it accepts is * a syllable, ties to the pattern its grammar lists first (Ragel's @@ -36,5 +50,5 @@ typedef struct { const uint8_t *accept; /* [states]: the syllable type a state ends, plus one; 0 for none */ unsigned broken; /* the broken cluster's type, plus one */ } VegaMachine; -extern const VegaMachine vega_indic_machine, vega_khmer_machine, vega_myanmar_machine; +extern const VegaMachine vega_indic_machine, vega_khmer_machine, vega_myanmar_machine, vega_use_machine; #endif -- cgit v1.2.3