aboutsummaryrefslogtreecommitdiffstats
path: root/text
diff options
context:
space:
mode:
Diffstat (limited to 'text')
-rw-r--r--text/shape-build.c55
-rw-r--r--text/shape.c214
-rw-r--r--text/shape.h10
-rw-r--r--text/syllabic-data.c501
-rw-r--r--text/syllabic.h16
-rw-r--r--text/syllabic.py40
6 files changed, 815 insertions, 21 deletions
diff --git a/text/shape-build.c b/text/shape-build.c
index 166ad22..a3b924e 100644
--- a/text/shape-build.c
+++ b/text/shape-build.c
@@ -334,8 +334,9 @@ static int categorize(uint32_t script, hb_tag_t gsub_script) {
if (script == TAG("Khmr")) return VEGA_SHAPER_KHMER;
if (script == TAG("Syrc") || script == TAG("Thai") || script == TAG("Laoo") || script == TAG("Qaag")) return -1;
if (listed(indic_scripts, sizeof(indic_scripts) / sizeof(*indic_scripts), script))
- return dflt ? VEGA_SHAPER_DEFAULT : (gsub_script & 0xFF) == '3' ? -1 : VEGA_SHAPER_INDIC;
- if (listed(use_scripts, sizeof(use_scripts) / sizeof(*use_scripts), script)) return dflt ? VEGA_SHAPER_DEFAULT : -1;
+ return dflt ? VEGA_SHAPER_DEFAULT : (gsub_script & 0xFF) == '3' ? VEGA_SHAPER_USE : VEGA_SHAPER_INDIC;
+ if (listed(use_scripts, sizeof(use_scripts) / sizeof(*use_scripts), script))
+ return dflt ? VEGA_SHAPER_DEFAULT : VEGA_SHAPER_USE;
if (script == TAG("Mymr")) return dflt || gsub_script == TAG("mymr") ? VEGA_SHAPER_DEFAULT : VEGA_SHAPER_MYANMAR;
return VEGA_SHAPER_DEFAULT;
}
@@ -545,6 +546,32 @@ static bool plan_for(hb_face_t *face, uint32_t script_tag, int direction, Plan *
add_gsub_pause(m, VEGA_PAUSE_CLEAR_SYLLABLES);
for (int i = 0; i < 4; ++i) enable_feature(m, TAG(myanmar_other[i]), F_MANUAL_ZWJ, 1);
}
+ /* hb-ot-shaper-use.cc: syllables; the default glyph pre-processing;
+ * rphf and pref, each recording what it substituted; the basic
+ * features; the reordering; the topographical forms; the rest. */
+ static const char *const use_basic[] = {"rkrf", "abvf", "blwf", "half", "pstf", "vatu", "cjct"};
+ static const char *const use_topographical[] = {"isol", "init", "medi", "fina"};
+ static const char *const use_other[] = {"abvs", "blws", "haln", "pres", "psts"};
+ if (shaper == VEGA_SHAPER_USE) {
+ m->is_simple = false;
+ add_gsub_pause(m, VEGA_PAUSE_SYLLABLES);
+ enable_feature(m, TAG("locl"), F_PER_SYLLABLE, 1);
+ enable_feature(m, TAG("ccmp"), F_PER_SYLLABLE, 1);
+ enable_feature(m, TAG("nukt"), F_PER_SYLLABLE, 1);
+ enable_feature(m, TAG("akhn"), F_MANUAL_ZWJ | F_PER_SYLLABLE, 1);
+ add_gsub_pause(m, VEGA_PAUSE_CLEAR_SUBSTITUTED);
+ add_feature(m, TAG("rphf"), F_MANUAL_ZWJ | F_PER_SYLLABLE, 1);
+ add_gsub_pause(m, VEGA_PAUSE_RECORD_RPHF);
+ add_gsub_pause(m, VEGA_PAUSE_CLEAR_SUBSTITUTED);
+ enable_feature(m, TAG("pref"), F_MANUAL_ZWJ | F_PER_SYLLABLE, 1);
+ add_gsub_pause(m, VEGA_PAUSE_RECORD_PREF);
+ for (int i = 0; i < 7; ++i) enable_feature(m, TAG(use_basic[i]), F_MANUAL_ZWJ | F_PER_SYLLABLE, 1);
+ add_gsub_pause(m, VEGA_PAUSE_INITIAL_REORDERING);
+ add_gsub_pause(m, VEGA_PAUSE_CLEAR_SYLLABLES);
+ for (int i = 0; i < 4; ++i) add_feature(m, TAG(use_topographical[i]), F_NONE, 1);
+ add_gsub_pause(m, 0);
+ for (int i = 0; i < 5; ++i) enable_feature(m, TAG(use_other[i]), F_MANUAL_ZWJ, 1);
+ }
if (shaper == VEGA_SHAPER_HANGUL) {
m->is_simple = false;
add_feature(m, TAG("ljmo"), F_NONE, 1);
@@ -583,7 +610,7 @@ static bool plan_for(hb_face_t *face, uint32_t script_tag, int direction, Plan *
/* Hangul's, Indic's and Khmer's shapers zero no marks (Myanmar's does,
* before GPOS); none of these places marks without GPOS. */
bool zeroes = shaper != VEGA_SHAPER_HANGUL && shaper != VEGA_SHAPER_INDIC && shaper != VEGA_SHAPER_KHMER;
- bool script_marks = zeroes && shaper != VEGA_SHAPER_MYANMAR;
+ bool script_marks = zeroes && shaper != VEGA_SHAPER_MYANMAR && shaper != VEGA_SHAPER_USE;
bool adjust = !apply_gpos && (!apply_kern || !kern_table.cross), fallback_marks = adjust && script_marks;
if (shaper == VEGA_SHAPER_ARABIC) {
if (one_mask(m, "stch")) FAIL("%s: the font stretches (stch)", name);
@@ -610,8 +637,9 @@ static bool plan_for(hb_face_t *face, uint32_t script_tag, int direction, Plan *
plan->masks[VEGA_MASK_FRAC] = frac;
plan->masks[VEGA_MASK_NUMR] = numr;
plan->masks[VEGA_MASK_DNOM] = dnom;
- if (shaper == VEGA_SHAPER_ARABIC)
+ if (shaper == VEGA_SHAPER_ARABIC || shaper == VEGA_SHAPER_USE)
for (int i = 0; i < 7; ++i) plan->masks[VEGA_MASK_ISOL + i] = one_mask(m, arabic_features[i]);
+ if (shaper == VEGA_SHAPER_USE) plan->masks[VEGA_MASK_USE_RPHF] = one_mask(m, "rphf");
if (shaper == VEGA_SHAPER_HANGUL) {
plan->masks[VEGA_MASK_LJMO] = one_mask(m, "ljmo");
plan->masks[VEGA_MASK_VJMO] = one_mask(m, "vjmo");
@@ -975,8 +1003,9 @@ void vega_shaping_check(hb_font_t *font, const VegaShaping *s, uint32_t script,
* punctuation), and those whose glyphs some substitution starts from. */
Pool letters = {0}, marks = {0}, others = {0}, hot = {0}, jamo_pools[3] = {{0}}, indic[INDIC_POOLS] = {{0}};
bool hangul = script == HB_TAG('H', 'a', 'n', 'g');
+ bool use = listed(use_scripts, sizeof(use_scripts) / sizeof(*use_scripts), script);
bool syllabic = listed(indic_scripts, sizeof(indic_scripts) / sizeof(*indic_scripts), script) ||
- script == HB_TAG('K', 'h', 'm', 'r') || script == HB_TAG('M', 'y', 'm', 'r');
+ script == HB_TAG('K', 'h', 'm', 'r') || script == HB_TAG('M', 'y', 'm', 'r') || use;
hb_set_t *inputs = hb_set_create();
uint32_t common = HB_TAG('Z', 'y', 'y', 'y'), inherited = HB_TAG('Z', 'i', 'n', 'h');
for (unsigned t = 0; t < s->lookup_count[0]; ++t)
@@ -990,7 +1019,21 @@ void vega_shaping_check(hb_font_t *font, const VegaShaping *s, uint32_t script,
if (hangul && ((code >= 0x1100 && code <= 0x115F) || (code >= 0xA960 && code <= 0xA97C))) pool_add(&jamo_pools[0], code);
if (hangul && ((code >= 0x1160 && code <= 0x11A7) || (code >= 0xD7B0 && code <= 0xD7C6))) pool_add(&jamo_pools[1], code);
if (hangul && ((code >= 0x11A8 && code <= 0x11FF) || (code >= 0xD7CB && code <= 0xD7FB))) pool_add(&jamo_pools[2], code);
- if (syllabic && (of == script || of == inherited)) {
+ if (use && (of == script || of == inherited)) {
+ int pool = -1;
+ switch (vega_use_category(code)) {
+ case VEGA_USE_B: case VEGA_USE_GB: case VEGA_USE_CS: pool = INDIC_CONSONANTS; break;
+ case VEGA_USE_R: pool = INDIC_RA; break;
+ case VEGA_USE_H: case VEGA_USE_IS: case VEGA_USE_HVM: case VEGA_USE_SK: pool = INDIC_HALANTS; break;
+ case VEGA_USE_SUB: case VEGA_USE_CMABV: case VEGA_USE_CMBLW: case VEGA_USE_MABV: case VEGA_USE_MBLW:
+ case VEGA_USE_MPST: case VEGA_USE_MPRE: pool = INDIC_NUKTAS; break;
+ case VEGA_USE_VABV: case VEGA_USE_VBLW: case VEGA_USE_VPST: case VEGA_USE_VPRE: pool = INDIC_MATRAS; break;
+ case VEGA_USE_VMABV: case VEGA_USE_VMBLW: case VEGA_USE_VMPST: case VEGA_USE_VMPRE: case VEGA_USE_SMABV:
+ case VEGA_USE_SMBLW: case VEGA_USE_FABV: case VEGA_USE_FBLW: case VEGA_USE_FPST: case VEGA_USE_FMABV:
+ case VEGA_USE_FMBLW: case VEGA_USE_FMPST: pool = INDIC_MODIFIERS; break;
+ }
+ if (pool >= 0) pool_add(&indic[pool], code);
+ } else if (syllabic && (of == script || of == inherited)) {
int pool = -1;
switch (vega_indic_categories(code) & 0xFF) {
case VEGA_OT_C: case VEGA_OT_CS: pool = INDIC_CONSONANTS; break;
diff --git a/text/shape.c b/text/shape.c
index 4dd92da..76d5409 100644
--- a/text/shape.c
+++ b/text/shape.c
@@ -227,7 +227,7 @@ bool vega_shaping_open(VegaShaping *s, const unsigned char *bytes, size_t size,
for (uint32_t i = 0; i < s->plan_count; ++i) {
const unsigned char *p = s->plans + (size_t)i * VEGA_PLAN_BYTES;
uint32_t ranges[2][2] = {{le32(p + 80), le32(p + 84)}, {le32(p + 88), le32(p + 92)}};
- if ((p[4] != VEGA_SHAPE_LTR && p[4] != VEGA_SHAPE_RTL) || p[5] > VEGA_SHAPE_RTL || p[6] > VEGA_SHAPER_MYANMAR)
+ if ((p[4] != VEGA_SHAPE_LTR && p[4] != VEGA_SHAPE_RTL) || p[5] > VEGA_SHAPE_RTL || p[6] > VEGA_SHAPER_USE)
REFUSE("plan %u", i);
if ((p[7] & VEGA_PLAN_FALLBACK_MARKS) && !s->extents) REFUSE("plan %u: marks placed without extents", i);
for (int table = 0; table < 2; ++table) {
@@ -236,7 +236,7 @@ bool vega_shaping_open(VegaShaping *s, const unsigned char *bytes, size_t size,
for (uint32_t k = 0; k < ranges[table][1]; ++k) {
const unsigned char *step = s->steps + (size_t)(ranges[table][0] + k) * VEGA_STEP_BYTES;
bool pause = le16(step) == VEGA_STEP_PAUSE;
- if (pause ? table || !step[2] || step[2] > VEGA_PAUSE_CLEAR_SYLLABLES : le16(step) >= s->lookup_count[table])
+ if (pause ? table || !step[2] || step[2] > VEGA_PAUSE_RECORD_PREF : le16(step) >= s->lookup_count[table])
REFUSE("plan %u: a lookup the font lacks", i);
}
}
@@ -315,6 +315,7 @@ typedef struct {
struct VegaShaper {
Info *info, *out;
Position *pos;
+ uint32_t *kept; /* the glyphs a syllable machine reads (USE's) */
size_t len, out_len, idx, allocated, max_len;
bool have_output, successful;
int direction;
@@ -334,6 +335,7 @@ void vega_shaper_free(VegaShaper *b) {
free(b->info);
free(b->out);
free(b->pos);
+ free(b->kept);
free(b->glyphs);
free(b);
}
@@ -352,11 +354,13 @@ static bool ensure(VegaShaper *b, size_t size) {
Info *out = info ? realloc(b->out, n * sizeof(*out)) : NULL;
if (out) b->out = out;
Position *pos = out ? realloc(b->pos, n * sizeof(*pos)) : NULL;
- if (!pos) {
+ if (pos) b->pos = pos;
+ uint32_t *kept = pos ? realloc(b->kept, n * sizeof(*kept)) : NULL;
+ if (!kept) {
b->successful = false;
return false;
}
- b->pos = pos;
+ b->kept = kept;
b->allocated = n;
return true;
}
@@ -823,7 +827,7 @@ static bool compose(const Normalizer *c, uint32_t a, uint32_t b, uint32_t *ab) {
switch (c->plan->shaper) {
case VEGA_SHAPER_HEBREW: return compose_hebrew(c, a, b, ab);
case VEGA_SHAPER_INDIC: return compose_indic(a, b, ab);
- case VEGA_SHAPER_KHMER: return !is_mark_category(vega_category(a)) && compose_unicode(a, b, ab);
+ case VEGA_SHAPER_KHMER: case VEGA_SHAPER_USE: return !is_mark_category(vega_category(a)) && compose_unicode(a, b, ab);
default: return compose_unicode(a, b, ab);
}
}
@@ -1035,7 +1039,7 @@ static void normalize(const VegaShaping *s, const Plan *plan, VegaShaper *b) {
* Indic's decomposes what decomposes even when the font has it whole. */
const bool none = plan->shaper == VEGA_SHAPER_HANGUL;
const bool syllabic = plan->shaper == VEGA_SHAPER_INDIC || plan->shaper == VEGA_SHAPER_KHMER ||
- plan->shaper == VEGA_SHAPER_MYANMAR;
+ plan->shaper == VEGA_SHAPER_MYANMAR || plan->shaper == VEGA_SHAPER_USE;
const bool always_short_circuit = none, might_short_circuit = none || !syllabic;
bool all_simple = true;
clear_output(b);
@@ -1169,6 +1173,10 @@ static void setup_masks_arabic(VegaShaper *b, const Plan *plan) {
prev = i;
state = entry[2];
}
+ if (plan->script == TAG4('M', 'o', 'n', 'g'))
+ for (size_t i = 1; i < b->len; ++i)
+ if ((b->info[i].codepoint >= 0x180B && b->info[i].codepoint <= 0x180D) || b->info[i].codepoint == 0x180F)
+ b->info[i].action = b->info[i - 1].action;
for (size_t i = 0; i < b->len; ++i)
if (b->info[i].action < NONE) b->info[i].mask |= plan->masks[VEGA_MASK_ISOL + b->info[i].action];
}
@@ -3325,6 +3333,183 @@ static bool myanmar_reorder(const VegaShaping *s, VegaShaper *b) {
return changed;
}
+/* ---- The Universal Shaping Engine (hb-ot-shaper-use.cc): syllables by
+ * USE categories; rphf and pref, each recording what it made (a repha, a
+ * pre-base glyph); then a repha moved before the first post-base glyph and
+ * pre-base glyphs moved to the start (or past a halant). Scripts that join
+ * like Arabic take Arabic's forms; others join syllable to syllable. */
+
+enum { USE_VIRAMA_TERMINATED, USE_SAKOT_TERMINATED, USE_STANDARD, USE_NUMBER_JOINER_TERMINATED, USE_NUMERAL,
+ USE_SYMBOL, USE_HIEROGLYPH, USE_BROKEN, USE_NON_CLUSTER };
+
+/* The scripts with Arabic's joining data (hb-ot-shaper-arabic-joining-list.hh). */
+static bool arabic_joining_script(uint32_t script) {
+ switch (script) {
+ case TAG4('A', 'd', 'l', 'm'): case TAG4('A', 'r', 'a', 'b'): case TAG4('C', 'h', 'r', 's'):
+ case TAG4('R', 'o', 'h', 'g'): case TAG4('M', 'a', 'n', 'd'): case TAG4('M', 'a', 'n', 'i'):
+ case TAG4('M', 'o', 'n', 'g'): case TAG4('N', 'k', 'o', 'o'): case TAG4('O', 'u', 'g', 'r'):
+ case TAG4('P', 'h', 'a', 'g'): case TAG4('P', 'h', 'l', 'p'): case TAG4('S', 'o', 'g', 'd'):
+ case TAG4('S', 'y', 'r', 'c'):
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void setup_masks_use(VegaShaper *b, const Plan *plan) {
+ if (arabic_joining_script(plan->script)) setup_masks_arabic(b, plan);
+ for (size_t i = 0; i < b->len; ++i) b->info[i].category = vega_use_category(b->info[i].codepoint);
+}
+
+/* The machine reads the glyphs but CGJs, and a ZWNJ only when no mark
+ * follows it (past CGJs); a syllable holds what it skipped after it. */
+static void find_syllables_use(VegaShaper *b) {
+ size_t n = 0;
+ for (size_t i = 0; i < b->len; ++i) {
+ if (b->info[i].category == VEGA_USE_CGJ) continue;
+ if (b->info[i].category == VEGA_USE_ZWNJ) {
+ size_t k = i + 1;
+ while (k < b->len && b->info[k].category == VEGA_USE_CGJ) k++;
+ if (k < b->len && is_unicode_mark(&b->info[k])) continue;
+ }
+ b->kept[n++] = (uint32_t)i;
+ }
+ const VegaMachine *m = &vega_use_machine;
+ unsigned serial = 1;
+ for (size_t p = 0; p < n;) {
+ unsigned state = 0, type = 0;
+ size_t end = p + 1;
+ for (size_t q = p; q < n; ++q) {
+ unsigned category = b->info[b->kept[q]].category;
+ size_t cell = (size_t)state * m->classes + m->class_of[category < 63 ? category : 63];
+ state = m->width == 1 ? ((const uint8_t *)m->next)[cell] : ((const uint16_t *)m->next)[cell];
+ if (state >= m->states) break;
+ if (m->accept[state]) type = m->accept[state], end = q + 1;
+ }
+ if (type == m->broken) b->scratch |= HAS_BROKEN_SYLLABLE;
+ size_t first = b->kept[p], last = end < n ? b->kept[end] : b->len;
+ for (size_t i = first; i < last; ++i) b->info[i].syllable = (uint8_t)(serial << 4 | (type ? type - 1 : 0));
+ if (++serial == 16) serial = 1;
+ p = end;
+ }
+}
+
+static void use_setup_syllables(const Plan *plan, VegaShaper *b) {
+ find_syllables_use(b);
+ Info *info = b->info;
+ /* rphf on what may be a repha: an encoded one, or the first three */
+ uint32_t rphf = plan->masks[VEGA_MASK_USE_RPHF];
+ if (rphf)
+ for (size_t start = 0, end; start < b->len; start = end) {
+ end = next_syllable(b, start);
+ size_t limit = info[start].category == VEGA_USE_R ? 1 : end - start < 3 ? end - start : 3;
+ for (size_t i = start; i < start + limit; ++i) info[i].mask |= rphf;
+ }
+ /* Joining forms, syllable to syllable, where Arabic's did not come. */
+ if (arabic_joining_script(plan->script)) return;
+ enum { FORM_ISOL, FORM_INIT, FORM_MEDI, FORM_FINA, FORM_NONE };
+ uint32_t masks[4] = {plan->masks[VEGA_MASK_ISOL], plan->masks[VEGA_MASK_INIT], plan->masks[VEGA_MASK_MEDI],
+ plan->masks[VEGA_MASK_FINA]},
+ all = 0;
+ for (int i = 0; i < 4; ++i) {
+ if (masks[i] == plan->global_mask) masks[i] = 0;
+ all |= masks[i];
+ }
+ if (!all) return;
+ uint32_t other = ~all;
+ size_t last_start = 0;
+ int last_form = FORM_NONE;
+ for (size_t start = 0, end; start < b->len; start = end) {
+ end = next_syllable(b, start);
+ unsigned type = info[start].syllable & 0x0F;
+ if (type == USE_HIEROGLYPH || type == USE_NON_CLUSTER)
+ last_form = FORM_NONE;
+ else {
+ bool join = last_form == FORM_FINA || last_form == FORM_ISOL;
+ if (join) {
+ last_form = last_form == FORM_FINA ? FORM_MEDI : FORM_INIT;
+ for (size_t i = last_start; i < start; ++i) info[i].mask = (info[i].mask & other) | masks[last_form];
+ }
+ last_form = join ? FORM_FINA : FORM_ISOL;
+ for (size_t i = start; i < end; ++i) info[i].mask = (info[i].mask & other) | masks[last_form];
+ }
+ last_start = start;
+ }
+}
+
+/* A repha rphf made (the first substituted glyph under its mask) is a
+ * repha; a glyph pref made is a pre-base vowel. */
+static void use_record(const Plan *plan, VegaShaper *b, unsigned pause) {
+ uint32_t rphf = plan->masks[VEGA_MASK_USE_RPHF];
+ if (pause == VEGA_PAUSE_RECORD_RPHF && !rphf) return;
+ for (size_t start = 0, end; start < b->len; start = end) {
+ end = next_syllable(b, start);
+ for (size_t i = start; i < end && (pause != VEGA_PAUSE_RECORD_RPHF || (b->info[i].mask & rphf)); ++i)
+ if (b->info[i].gprops & SUBSTITUTED) {
+ b->info[i].category = pause == VEGA_PAUSE_RECORD_RPHF ? VEGA_USE_R : VEGA_USE_VPRE;
+ break;
+ }
+ }
+}
+
+static bool is_halant_use(const Info *i) {
+ return (i->category == VEGA_USE_H || i->category == VEGA_USE_HVM || i->category == VEGA_USE_IS) &&
+ !(i->gprops & LIGATED);
+}
+
+#define FLAG64_UNSAFE(x) ((x) < 64 ? (uint64_t)1 << (x) : 0)
+#define USE_POST_BASE \
+ (FLAG64_UNSAFE(VEGA_USE_FABV) | FLAG64_UNSAFE(VEGA_USE_FBLW) | FLAG64_UNSAFE(VEGA_USE_FPST) | \
+ FLAG64_UNSAFE(VEGA_USE_FMABV) | FLAG64_UNSAFE(VEGA_USE_FMBLW) | FLAG64_UNSAFE(VEGA_USE_FMPST) | \
+ FLAG64_UNSAFE(VEGA_USE_MABV) | FLAG64_UNSAFE(VEGA_USE_MBLW) | FLAG64_UNSAFE(VEGA_USE_MPST) | \
+ FLAG64_UNSAFE(VEGA_USE_MPRE) | FLAG64_UNSAFE(VEGA_USE_VABV) | FLAG64_UNSAFE(VEGA_USE_VBLW) | \
+ FLAG64_UNSAFE(VEGA_USE_VPST) | FLAG64_UNSAFE(VEGA_USE_VPRE) | FLAG64_UNSAFE(VEGA_USE_VMABV) | \
+ FLAG64_UNSAFE(VEGA_USE_VMBLW) | FLAG64_UNSAFE(VEGA_USE_VMPST) | FLAG64_UNSAFE(VEGA_USE_VMPRE))
+
+static void use_reorder_syllable(VegaShaper *b, size_t start, size_t end) {
+ unsigned type = b->info[start].syllable & 0x0F;
+ if (!(FLAG_UNSAFE(type) & (FLAG(USE_VIRAMA_TERMINATED) | FLAG(USE_SAKOT_TERMINATED) | FLAG(USE_STANDARD) |
+ FLAG(USE_SYMBOL) | FLAG(USE_BROKEN))))
+ return;
+ Info *info = b->info;
+ /* A repha forward, before the first post-base glyph (or to the end). */
+ if (info[start].category == VEGA_USE_R && end - start > 1)
+ for (size_t i = start + 1; i < end; ++i) {
+ bool post_base = (FLAG64_UNSAFE(info[i].category) & USE_POST_BASE) || is_halant_use(&info[i]);
+ if (post_base || i == end - 1) {
+ if (post_base) i--;
+ merge_clusters(b, start, i + 1);
+ Info t = info[start];
+ memmove(&info[start], &info[start + 1], (i - start) * sizeof(Info));
+ info[i] = t;
+ break;
+ }
+ }
+ /* Pre-base vowels back, to the start or past the last halant (only a
+ * multiple substitution's first component). */
+ size_t j = start;
+ for (size_t i = start; i < end; ++i) {
+ uint32_t flag = FLAG_UNSAFE(info[i].category);
+ if (is_halant_use(&info[i]))
+ j = i + 1;
+ else if ((flag & (FLAG(VEGA_USE_VPRE) | FLAG(VEGA_USE_VMPRE))) && !lig_comp(&info[i]) && j < i) {
+ merge_clusters(b, j, i + 1);
+ Info t = info[i];
+ memmove(&info[j + 1], &info[j], (i - j) * sizeof(Info));
+ info[j] = t;
+ }
+ }
+}
+
+static bool use_reorder(const VegaShaping *s, VegaShaper *b) {
+ bool changed = insert_dotted_circles(s, b, USE_BROKEN, VEGA_USE_B, VEGA_USE_R, -1);
+ for (size_t start = 0, end; start < b->len; start = end) {
+ end = next_syllable(b, start);
+ use_reorder_syllable(b, start, end);
+ }
+ return changed;
+}
+
/* The shaper's part of the work at a pause in GSUB; whether it changed the
* buffer. */
static bool shaper_pause(const VegaShaping *s, const Plan *plan, VegaShaper *b, unsigned pause) {
@@ -3344,6 +3529,16 @@ static bool shaper_pause(const VegaShaping *s, const Plan *plan, VegaShaper *b,
case VEGA_SHAPER_MYANMAR:
if (pause == VEGA_PAUSE_SYLLABLES) find_syllables(b, &vega_myanmar_machine);
return pause == VEGA_PAUSE_INITIAL_REORDERING && myanmar_reorder(s, b);
+ case VEGA_SHAPER_USE:
+ switch (pause) {
+ case VEGA_PAUSE_SYLLABLES: use_setup_syllables(plan, b); return false;
+ case VEGA_PAUSE_CLEAR_SUBSTITUTED:
+ for (size_t i = 0; i < b->len; ++i) b->info[i].gprops &= (uint16_t)~SUBSTITUTED;
+ return false;
+ case VEGA_PAUSE_RECORD_RPHF: case VEGA_PAUSE_RECORD_PREF: use_record(plan, b, pause); return false;
+ case VEGA_PAUSE_INITIAL_REORDERING: return use_reorder(s, b);
+ default: return false;
+ }
default: return false;
}
}
@@ -3423,8 +3618,8 @@ static void position(const VegaShaping *s, const Plan *plan, VegaShaper *b) {
for (size_t i = 0; i < b->len; ++i) b->pos[i].x_advance = advance_of(s, b->info[i].codepoint);
if (b->scratch & HAS_SPACE_FALLBACK) fallback_spaces(s, b);
bool adjust = (plan->flags & VEGA_PLAN_ADJUST_ZEROING) && b->direction == VEGA_SHAPE_LTR;
- /* Marks' advances go by GDEF: before GPOS (Myanmar's shaper) or after. */
- bool early = plan->shaper == VEGA_SHAPER_MYANMAR;
+ /* Marks' advances go by GDEF: before GPOS (Myanmar's shaper and USE) or after. */
+ bool early = plan->shaper == VEGA_SHAPER_MYANMAR || plan->shaper == VEGA_SHAPER_USE;
if ((plan->flags & VEGA_PLAN_ZERO_MARKS) && early) zero_mark_widths(b, adjust);
if (plan->flags & VEGA_PLAN_GPOS) apply_table(s, plan, b, 1);
if (plan->flags & VEGA_PLAN_KERN) kern_table(s, b, plan);
@@ -3460,7 +3655,7 @@ long vega_shape(VegaShaper *b, const VegaShaping *s, const uint32_t *codes, size
form_clusters(b);
ensure_native_direction(b, &plan);
if (plan.shaper == VEGA_SHAPER_HANGUL) preprocess_hangul(s, b);
- if (plan.shaper == VEGA_SHAPER_INDIC) preprocess_vowel_constraints(&plan, b);
+ if (plan.shaper == VEGA_SHAPER_INDIC || plan.shaper == VEGA_SHAPER_USE) preprocess_vowel_constraints(&plan, b);
/* Mirror what the font mirrors; mark the rest for rtlm. */
if (direction == VEGA_SHAPE_RTL)
@@ -3474,6 +3669,7 @@ long vega_shape(VegaShaper *b, const VegaShaping *s, const uint32_t *codes, size
if (plan.shaper == VEGA_SHAPER_ARABIC) setup_masks_arabic(b, &plan);
if (plan.shaper == VEGA_SHAPER_INDIC) setup_masks_indic(b);
if (plan.shaper == VEGA_SHAPER_KHMER || plan.shaper == VEGA_SHAPER_MYANMAR) setup_masks_category(b);
+ if (plan.shaper == VEGA_SHAPER_USE) setup_masks_use(b, &plan);
if (plan.shaper == VEGA_SHAPER_HANGUL)
for (size_t i = 0; i < b->len; ++i)
if (b->info[i].action >= LJMO && b->info[i].action <= TJMO)
diff --git a/text/shape.h b/text/shape.h
index 7f02729..bd38d96 100644
--- a/text/shape.h
+++ b/text/shape.h
@@ -6,8 +6,8 @@
/* Shaping (docs/design/004-text.md): a run of characters (one script, one
* direction) to glyphs and their positions, as HarfBuzz 10 shapes it with
- * its default, Arabic, Hebrew, Hangul, Indic, Khmer and Myanmar shapers,
- * glyph for glyph and unit for unit.
+ * its default, Arabic, Hebrew, Hangul, Indic, Khmer, Myanmar and Universal
+ * (USE) shapers, glyph for glyph and unit for unit.
*
* What a font's shaping needs travels in a symbol file (its shaping
* section), written by the build tool:
@@ -48,7 +48,7 @@ enum { VEGA_SHAPING_HEADER = 80, VEGA_PLAN_BYTES = 144, VEGA_STEP_BYTES = 8, VEG
VEGA_PLAN_STAGES = 5 };
enum { VEGA_SHAPE_LTR = 1, VEGA_SHAPE_RTL = 2 };
enum { VEGA_SHAPER_DEFAULT, VEGA_SHAPER_ARABIC, VEGA_SHAPER_HEBREW, VEGA_SHAPER_HANGUL, VEGA_SHAPER_INDIC,
- VEGA_SHAPER_KHMER, VEGA_SHAPER_MYANMAR };
+ VEGA_SHAPER_KHMER, VEGA_SHAPER_MYANMAR, VEGA_SHAPER_USE };
/* Plan flags: GPOS runs; mark advances are zeroed after it (by GDEF); glyph
* classes come from Unicode (the font has none); the font positions marks
* (a 'mark' feature); automatic fractions; the kern table kerns; marks are
@@ -66,6 +66,7 @@ enum { VEGA_MASK_RPHF = VEGA_MASK_SHAPER, VEGA_MASK_PREF, VEGA_MASK_BLWF, VEGA_M
VEGA_MASK_PSTF, VEGA_MASK_INDIC_INIT }; /* Indic */
enum { VEGA_MASK_KHMER_PREF = VEGA_MASK_SHAPER, VEGA_MASK_KHMER_BLWF, VEGA_MASK_KHMER_ABVF, VEGA_MASK_KHMER_PSTF,
VEGA_MASK_KHMER_CFAR }; /* Khmer */
+enum { VEGA_MASK_USE_RPHF = VEGA_MASK_INIT + 1 }; /* USE: that, and Arabic's for its joining forms */
/* The stages a plan names: Indic's, whose features decide a consonant's
* position by whether they would substitute it. */
enum { VEGA_STAGE_RPHF, VEGA_STAGE_PREF, VEGA_STAGE_BLWF, VEGA_STAGE_PSTF, VEGA_STAGE_VATU };
@@ -75,7 +76,8 @@ enum { VEGA_INDIC_OLD_SPEC = 1 };
/* Step flags; pauses, which the shaper tells apart. */
enum { VEGA_STEP_AUTO_ZWNJ = 1, VEGA_STEP_AUTO_ZWJ = 2, VEGA_STEP_RANDOM = 4, VEGA_STEP_PER_SYLLABLE = 8 };
enum { VEGA_STEP_PAUSE = 0xFFFF };
-enum { VEGA_PAUSE_SYLLABLES = 1, VEGA_PAUSE_INITIAL_REORDERING, VEGA_PAUSE_FINAL_REORDERING, VEGA_PAUSE_CLEAR_SYLLABLES };
+enum { VEGA_PAUSE_SYLLABLES = 1, VEGA_PAUSE_INITIAL_REORDERING, VEGA_PAUSE_FINAL_REORDERING, VEGA_PAUSE_CLEAR_SYLLABLES,
+ VEGA_PAUSE_CLEAR_SUBSTITUTED, VEGA_PAUSE_RECORD_RPHF, VEGA_PAUSE_RECORD_PREF };
typedef struct { const unsigned char *p; uint32_t size; } VegaTable;
/* Which glyphs may be in a set, as three 64-bit patterns of glyph bits
diff --git a/text/syllabic-data.c b/text/syllabic-data.c
index 3b3e6ff..cfff1b5 100644
--- a/text/syllabic-data.c
+++ b/text/syllabic-data.c
@@ -179,6 +179,383 @@ uint16_t vega_indic_categories(uint32_t u) {
return 0x0E00;
}
+/* Each character's USE category (hb-ot-shaper-use-table.hh, Unicode 16): HarfBuzz's arrays and
+ * lookup. */
+static const uint8_t use_u8[3345] = {
+ 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 15, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2,
+ 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17,
+ 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2,
+ 2, 34, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 2, 2,
+ 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, 2, 39, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 40, 41, 42, 43, 44, 45, 2, 46, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 48, 2,
+ 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2,
+ 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73,
+ 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84,
+ 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92,
+ 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2,
+ 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2,
+ 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+ 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+ 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4,
+ 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11,
+ 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0,
+ 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17,
+ 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2,
+ 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
+ 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17,
+ 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2,
+ 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0,
+ 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39,
+ 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2,
+ 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2,
+ 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17,
+ 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41,
+ 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17,
+ 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9,
+ 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0,
+ 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0,
+ 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39,
+ 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9,
+ 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0,
+ 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9,
+ 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34,
+ 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2,
+ 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30,
+ 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48,
+ 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0,
+ 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9,
+ 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60,
+ 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70,
+ 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2,
+ 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2,
+ 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45,
+ 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0,
+ 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9,
+ 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20,
+ 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88,
+ 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0,
+ 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0,
+ 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0,
+ 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0,
+ 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80,
+ 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2,
+ 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9,
+ 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0,
+ 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61,
+ 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0,
+ 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116,
+ 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0,
+ 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119,
+ 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120,
+ 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0,
+ 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0,
+ 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0,
+ 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2,
+ 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0,
+ 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23,
+ 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116,
+ 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0,
+ 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132,
+ 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2,
+ 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0,
+ 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15,
+ 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0,
+ 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81,
+ 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0,
+ 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2,
+ 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145,
+ 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0,
+ 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0,
+ 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116,
+ 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0,
+ 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0,
+ 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20,
+ 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0,
+ 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0,
+ 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2,
+ 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0,
+ 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31,
+ 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23,
+ 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2,
+ 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0,
+ 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17,
+ 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0,
+ 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20,
+ 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0,
+ 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20,
+ 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
+ 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25,
+ 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
+ 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82,
+ 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170,
+ 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43,
+ 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0,
+ 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2,
+ 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23,
+ 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2,
+ 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0,
+ 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178,
+ 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11,
+ 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0,
+ 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22,
+ 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2,
+ 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0,
+ 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2,
+ 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184,
+ 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190,
+ 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193,
+ 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0,
+ 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0,
+ 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11,
+ 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2,
+ 20, 2, 2, 44, 44, 44, 92, 0, 0, 0, 0, 0, 5, 1, 1, 0,
+ 51, 0, 52, 5, 0, 0, 16, 47, 47, 0, 6, 1, 0, 1, 37, 37,
+ 37, 0, 37, 1, 32, 32, 32, 37, 39, 33, 35, 32, 1, 35, 22, 35,
+ 34, 34, 34, 34, 33, 33, 33, 35, 35, 35, 12, 22, 35, 38, 0, 0,
+ 33, 5, 37, 39, 39, 0, 1, 34, 0, 0, 22, 22, 0, 22, 12, 0,
+ 35, 45, 0, 32, 0, 33, 0, 33, 12, 0, 38, 37, 31, 5, 5, 0,
+ 28, 31, 31, 35, 33, 37, 0, 35, 0, 22, 22, 37, 1, 0, 43, 43,
+ 39, 1, 33, 33, 1, 18, 0, 53, 0, 0, 46, 0, 31, 0, 32, 33,
+ 34, 1, 11, 11, 11, 0, 11, 11, 0, 46, 0, 1, 35, 34, 22, 37,
+ 38, 39, 44, 33, 29, 30, 28, 28, 1, 28, 28, 35, 39, 39, 1, 28,
+ 35, 22, 33, 33, 39, 39, 38, 1, 39, 34, 35, 6, 6, 35, 37, 37,
+ 45, 24, 31, 45, 37, 45, 33, 44, 45, 1, 45, 1, 6, 16, 6, 5,
+ 31, 31, 1, 5, 1, 33, 11, 26, 26, 38, 26, 26, 25, 37, 46, 33,
+ 22, 1, 30, 28, 11, 24, 24, 27, 11, 48, 35, 33, 37, 37, 24, 31,
+ 35, 12, 1, 0, 41, 41, 41, 35, 44, 56, 56, 34, 24, 23, 23, 45,
+ 32, 38, 38, 37, 43, 0, 45, 14, 6, 16, 16, 16, 0, 47, 0, 51,
+ 52, 0, 12, 29, 35, 12, 37, 33, 38, 1, 34, 26, 35, 24, 39, 1,
+ 31, 33, 28, 29, 28, 12, 0, 34, 29, 30, 27, 28, 0, 1, 24, 24,
+ 26, 34, 1, 1, 22, 0, 39, 44, 0, 39, 34, 35, 38, 38, 37, 0,
+ 44, 38, 1, 39, 37, 39, 43, 43, 1, 4, 4, 0, 13, 22, 34, 33,
+ 44, 31, 0, 35, 1, 18, 18, 32, 33, 22, 37, 37, 12, 33, 32, 39,
+ 0, 37, 32, 44, 18, 45, 1, 43, 43, 12, 32, 39, 12, 39, 33, 37,
+ 35, 29, 18, 29, 32, 1, 46, 34, 37, 43, 11, 11, 5, 25, 25, 31,
+ 44, 34, 44, 18, 28, 5, 33, 18, 39, 49, 49, 50, 50, 50, 51, 52,
+ 50, 55, 49, 49, 54, 54, 54, 49, 0, 30, 30, 29, 37, 28, 34, 0,
+ 34,
+};
+static const uint16_t use_u16[856] = {
+ 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12,
+ 0, 0, 0, 0, 10, 13, 0, 0, 14, 10, 10, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32,
+ 33, 34, 22, 35, 36, 0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41,
+ 42, 43, 44, 45, 46, 47, 31, 0, 48, 49, 22, 50, 51, 52, 18, 0,
+ 53, 49, 22, 54, 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 18, 0,
+ 61, 62, 10, 63, 64, 65, 31, 66, 67, 68, 10, 69, 70, 10, 71, 72,
+ 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83,
+ 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90,
+ 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95,
+ 96, 10, 97, 0, 0, 0, 0, 0, 98, 99, 100, 101, 31, 10, 102, 103,
+ 10, 10, 104, 10, 105, 106, 0, 0, 10, 107, 10, 10, 10, 108, 109, 110,
+ 2, 2, 0, 0, 0, 0, 0, 0, 111, 10, 10, 112, 113, 2, 114, 115,
+ 116, 10, 117, 10, 10, 10, 118, 119, 10, 10, 120, 121, 122, 0, 0, 0,
+ 0, 0, 0, 0, 0, 123, 124, 125, 0, 0, 0, 0, 0, 0, 0, 126,
+ 127, 128, 129, 0, 0, 0, 130, 131, 132, 0, 0, 0, 0, 0, 0, 133,
+ 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0,
+ 0, 0, 0, 10, 10, 10, 136, 137, 0, 0, 138, 0, 0, 0, 0, 0,
+ 139, 10, 140, 0, 10, 10, 10, 141, 142, 10, 10, 143, 144, 2, 145, 146,
+ 10, 10, 147, 10, 148, 149, 0, 0, 150, 10, 10, 151, 152, 2, 153, 99,
+ 10, 10, 154, 155, 156, 2, 10, 157, 10, 10, 10, 158, 159, 0, 160, 161,
+ 0, 0, 0, 0, 10, 10, 162, 2, 163, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 165,
+ 0, 0, 0, 0, 0, 0, 0, 166, 166, 167, 34, 168, 0, 0, 0, 0,
+ 169, 170, 10, 171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10, 172, 0,
+ 10, 173, 174, 0, 0, 0, 0, 0, 10, 10, 175, 2, 9, 10, 176, 10,
+ 177, 0, 0, 0, 0, 0, 0, 0, 10, 10, 178, 173, 0, 0, 0, 0,
+ 0, 0, 0, 10, 179, 180, 0, 10, 181, 0, 0, 182, 183, 0, 0, 0,
+ 184, 10, 10, 185, 186, 187, 188, 189, 190, 10, 10, 191, 192, 0, 0, 0,
+ 193, 10, 194, 195, 196, 10, 10, 197, 190, 10, 10, 198, 199, 106, 200, 103,
+ 10, 34, 201, 202, 203, 0, 0, 0, 204, 205, 95, 10, 10, 206, 207, 2,
+ 208, 21, 22, 209, 210, 211, 212, 213, 214, 10, 10, 215, 216, 217, 218, 0,
+ 10, 10, 10, 219, 220, 221, 222, 0, 200, 10, 10, 223, 224, 2, 0, 0,
+ 10, 10, 225, 226, 227, 228, 0, 0, 10, 10, 10, 229, 230, 2, 0, 0,
+ 10, 10, 231, 232, 2, 10, 141, 0, 10, 233, 234, 104, 235, 0, 0, 0,
+ 10, 10, 236, 237, 0, 0, 0, 0, 238, 239, 10, 240, 241, 2, 0, 0,
+ 0, 0, 242, 10, 10, 243, 244, 0, 245, 10, 10, 246, 247, 248, 10, 10,
+ 249, 250, 0, 0, 0, 0, 0, 0, 22, 10, 225, 251, 8, 10, 71, 19,
+ 10, 252, 74, 253, 0, 0, 0, 0, 254, 10, 10, 255, 256, 2, 257, 10,
+ 258, 259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 260,
+ 261, 49, 10, 262, 263, 264, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265,
+ 265, 265, 265, 266, 267, 268, 265, 265, 265, 265, 265, 265, 265, 265, 265, 269,
+ 10, 270, 271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 10, 10, 10, 272, 0, 0, 0, 0, 0, 0, 0, 0, 273, 10, 274, 2,
+ 10, 10, 10, 10, 275, 276, 277, 277, 278, 279, 0, 0, 0, 0, 280, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 177, 0, 281,
+ 10, 10, 10, 10, 10, 10, 106, 71, 95, 282, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 283, 10, 10, 71, 284, 285, 0, 0, 0,
+ 0, 10, 286, 0, 10, 10, 287, 2, 0, 0, 0, 0, 0, 10, 288, 2,
+ 0, 0, 0, 0, 0, 10, 289, 106, 10, 10, 10, 10, 290, 2, 0, 0,
+ 130, 130, 130, 130, 130, 130, 130, 130, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 130,
+};
+static unsigned use_b4(const uint8_t *a, unsigned i) { return (a[i >> 1] >> ((i & 1u) << 2)) & 15u; }
+uint8_t vega_use_category(uint32_t u) { return (uint8_t)(u<921600u?use_u8[2953+(((use_u8[625+(((use_u16[((use_u8[113+(((use_b4(use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:0); }
+
+/* The categories syllabic.h names are the machines' own. */
+_Static_assert(VEGA_OT_A == 9, "indic A");
+_Static_assert(VEGA_OT_C == 1, "indic C");
+_Static_assert(VEGA_OT_CM == 16, "indic CM");
+_Static_assert(VEGA_OT_CS == 18, "indic CS");
+_Static_assert(VEGA_OT_DOTTEDCIRCLE == 11, "indic DOTTEDCIRCLE");
+_Static_assert(VEGA_OT_H == 4, "indic H");
+_Static_assert(VEGA_OT_M == 7, "indic M");
+_Static_assert(VEGA_OT_MPST == 13, "indic MPst");
+_Static_assert(VEGA_OT_N == 3, "indic N");
+_Static_assert(VEGA_OT_PLACEHOLDER == 10, "indic PLACEHOLDER");
+_Static_assert(VEGA_OT_RS == 12, "indic RS");
+_Static_assert(VEGA_OT_RA == 15, "indic Ra");
+_Static_assert(VEGA_OT_REPHA == 14, "indic Repha");
+_Static_assert(VEGA_OT_SM == 8, "indic SM");
+_Static_assert(VEGA_OT_SMPST == 57, "indic SMPst");
+_Static_assert(VEGA_OT_SYMBOL == 17, "indic Symbol");
+_Static_assert(VEGA_OT_V == 2, "indic V");
+_Static_assert(VEGA_OT_VD == 9, "indic VD");
+_Static_assert(VEGA_OT_X == 0, "indic X");
+_Static_assert(VEGA_OT_ZWJ == 6, "indic ZWJ");
+_Static_assert(VEGA_OT_ZWNJ == 5, "indic ZWNJ");
+_Static_assert(VEGA_OT_C == 1, "khmer C");
+_Static_assert(VEGA_OT_DOTTEDCIRCLE == 11, "khmer DOTTEDCIRCLE");
+_Static_assert(VEGA_OT_H == 4, "khmer H");
+_Static_assert(VEGA_OT_PLACEHOLDER == 10, "khmer PLACEHOLDER");
+_Static_assert(VEGA_OT_RA == 15, "khmer Ra");
+_Static_assert(VEGA_OT_ROBATIC == 25, "khmer Robatic");
+_Static_assert(VEGA_OT_V == 2, "khmer V");
+_Static_assert(VEGA_OT_VABV == 20, "khmer VAbv");
+_Static_assert(VEGA_OT_VBLW == 21, "khmer VBlw");
+_Static_assert(VEGA_OT_VPRE == 22, "khmer VPre");
+_Static_assert(VEGA_OT_VPST == 23, "khmer VPst");
+_Static_assert(VEGA_OT_XGROUP == 26, "khmer Xgroup");
+_Static_assert(VEGA_OT_YGROUP == 27, "khmer Ygroup");
+_Static_assert(VEGA_OT_ZWJ == 6, "khmer ZWJ");
+_Static_assert(VEGA_OT_ZWNJ == 5, "khmer ZWNJ");
+_Static_assert(VEGA_OT_A == 9, "myanmar A");
+_Static_assert(VEGA_OT_AS == 32, "myanmar As");
+_Static_assert(VEGA_OT_C == 1, "myanmar C");
+_Static_assert(VEGA_OT_CS == 18, "myanmar CS");
+_Static_assert(VEGA_OT_DOTTEDCIRCLE == 11, "myanmar DOTTEDCIRCLE");
+_Static_assert(VEGA_OT_H == 4, "myanmar H");
+_Static_assert(VEGA_OT_MH == 35, "myanmar MH");
+_Static_assert(VEGA_OT_ML == 41, "myanmar ML");
+_Static_assert(VEGA_OT_MR == 36, "myanmar MR");
+_Static_assert(VEGA_OT_MW == 37, "myanmar MW");
+_Static_assert(VEGA_OT_MY == 38, "myanmar MY");
+_Static_assert(VEGA_OT_PT == 39, "myanmar PT");
+_Static_assert(VEGA_OT_RA == 15, "myanmar Ra");
+_Static_assert(VEGA_OT_SM == 8, "myanmar SM");
+_Static_assert(VEGA_OT_SMPST == 57, "myanmar SMPst");
+_Static_assert(VEGA_OT_VABV == 20, "myanmar VAbv");
+_Static_assert(VEGA_OT_VBLW == 21, "myanmar VBlw");
+_Static_assert(VEGA_OT_VPRE == 22, "myanmar VPre");
+_Static_assert(VEGA_OT_VPST == 23, "myanmar VPst");
+_Static_assert(VEGA_OT_VS == 40, "myanmar VS");
+_Static_assert(VEGA_OT_ZWJ == 6, "myanmar ZWJ");
+_Static_assert(VEGA_OT_ZWNJ == 5, "myanmar ZWNJ");
+_Static_assert(VEGA_USE_B == 1, "use B");
+_Static_assert(VEGA_USE_CGJ == 6, "use CGJ");
+_Static_assert(VEGA_USE_CMABV == 31, "use CMAbv");
+_Static_assert(VEGA_USE_CMBLW == 32, "use CMBlw");
+_Static_assert(VEGA_USE_CS == 43, "use CS");
+_Static_assert(VEGA_USE_FABV == 24, "use FAbv");
+_Static_assert(VEGA_USE_FBLW == 25, "use FBlw");
+_Static_assert(VEGA_USE_FMABV == 45, "use FMAbv");
+_Static_assert(VEGA_USE_FMBLW == 46, "use FMBlw");
+_Static_assert(VEGA_USE_FMPST == 47, "use FMPst");
+_Static_assert(VEGA_USE_FPST == 26, "use FPst");
+_Static_assert(VEGA_USE_G == 49, "use G");
+_Static_assert(VEGA_USE_GB == 5, "use GB");
+_Static_assert(VEGA_USE_H == 12, "use H");
+_Static_assert(VEGA_USE_HM == 54, "use HM");
+_Static_assert(VEGA_USE_HN == 13, "use HN");
+_Static_assert(VEGA_USE_HR == 55, "use HR");
+_Static_assert(VEGA_USE_HVM == 53, "use HVM");
+_Static_assert(VEGA_USE_IS == 44, "use IS");
+_Static_assert(VEGA_USE_J == 50, "use J");
+_Static_assert(VEGA_USE_MABV == 27, "use MAbv");
+_Static_assert(VEGA_USE_MBLW == 28, "use MBlw");
+_Static_assert(VEGA_USE_MPRE == 30, "use MPre");
+_Static_assert(VEGA_USE_MPST == 29, "use MPst");
+_Static_assert(VEGA_USE_N == 4, "use N");
+_Static_assert(VEGA_USE_O == 0, "use O");
+_Static_assert(VEGA_USE_R == 18, "use R");
+_Static_assert(VEGA_USE_RK == 56, "use RK");
+_Static_assert(VEGA_USE_SB == 51, "use SB");
+_Static_assert(VEGA_USE_SE == 52, "use SE");
+_Static_assert(VEGA_USE_SMABV == 41, "use SMAbv");
+_Static_assert(VEGA_USE_SMBLW == 42, "use SMBlw");
+_Static_assert(VEGA_USE_SUB == 11, "use SUB");
+_Static_assert(VEGA_USE_SK == 48, "use Sk");
+_Static_assert(VEGA_USE_VABV == 33, "use VAbv");
+_Static_assert(VEGA_USE_VBLW == 34, "use VBlw");
+_Static_assert(VEGA_USE_VMABV == 37, "use VMAbv");
+_Static_assert(VEGA_USE_VMBLW == 38, "use VMBlw");
+_Static_assert(VEGA_USE_VMPRE == 23, "use VMPre");
+_Static_assert(VEGA_USE_VMPST == 39, "use VMPst");
+_Static_assert(VEGA_USE_VPRE == 22, "use VPre");
+_Static_assert(VEGA_USE_VPST == 35, "use VPst");
+_Static_assert(VEGA_USE_WJ == 16, "use WJ");
+_Static_assert(VEGA_USE_ZWNJ == 14, "use ZWNJ");
+
/* The syllable machines: a DFA over classes of symbol; a state's accept is
* the syllable type it ends, plus one. */
/* indic (hb-ot-shaper-indic-machine.rl): 137 states, 20 classes of symbol; types indic_consonant_syllable, indic_vowel_syllable, indic_standalone_cluster, indic_symbol_cluster, indic_broken_cluster, indic_non_indic_cluster. */
@@ -461,3 +838,127 @@ static const uint8_t myanmar_accept[57] = {
};
const VegaMachine vega_myanmar_machine = {myanmar_class, 23, 57, myanmar_next[0], sizeof(myanmar_next[0][0]), myanmar_accept, 2};
+/* use (hb-ot-shaper-use-machine.rl): 109 states, 43 classes of symbol; types use_virama_terminated_cluster, use_sakot_terminated_cluster, use_standard_cluster, use_number_joiner_terminated_cluster, use_numeral_cluster, use_symbol_cluster, use_hieroglyph_cluster, use_broken_cluster, use_non_cluster. */
+static const uint8_t use_class[64] = {
+ 0, 1, 2, 2, 3, 4, 2, 2, 2, 2, 2, 5, 6, 7, 8, 2, 2, 2, 9, 2, 2, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 2, 24, 25, 26, 2, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 2, 2, 2, 2, 2, 2, 2,
+};
+static const uint8_t use_next[109][43] = {
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 6, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 30, 34, 3, 35, 3, 36, 3, 3, 37},
+ {109, 109, 109, 109, 109, 38, 39, 109, 40, 109, 41, 42, 43, 44, 45, 46, 47, 48, 49, 38, 50, 51, 52, 53, 54, 55, 56, 57, 58, 109, 59, 60, 61, 62, 59, 109, 109, 109, 109, 63, 109, 109, 62},
+ {109, 109, 109, 109, 109, 2, 64, 109, 65, 109, 66, 67, 68, 69, 70, 71, 72, 73, 74, 2, 75, 76, 77, 78, 79, 80, 81, 109, 109, 109, 82, 83, 84, 85, 86, 109, 109, 109, 109, 87, 109, 109, 88},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 89, 90, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 2, 64, 109, 65, 109, 66, 67, 68, 69, 70, 71, 72, 73, 74, 2, 75, 76, 77, 78, 79, 80, 81, 57, 58, 109, 82, 83, 84, 85, 86, 109, 109, 109, 109, 87, 109, 109, 88},
+ {109, 109, 109, 109, 109, 6, 7, 109, 9, 109, 11, 12, 13, 14, 15, 16, 17, 18, 19, 6, 20, 21, 22, 23, 24, 25, 26, 109, 109, 109, 30, 31, 32, 37, 30, 109, 109, 109, 109, 36, 109, 109, 37},
+ {109, 6, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 92, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 2, 6, 7, 8, 9, 109, 11, 12, 13, 14, 15, 16, 17, 18, 19, 6, 20, 21, 22, 23, 24, 25, 26, 27, 28, 109, 30, 31, 32, 37, 30, 109, 109, 109, 109, 36, 109, 109, 37},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 11, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 31, 32, 37, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 31, 32, 37, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 31, 32, 37, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 93, 109, 9, 109, 11, 12, 13, 14, 15, 109, 17, 18, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 93, 109, 9, 109, 11, 12, 13, 14, 15, 109, 109, 18, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 93, 109, 9, 109, 11, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 93, 109, 9, 109, 11, 12, 13, 14, 15, 16, 17, 18, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 6, 7, 109, 9, 109, 11, 12, 13, 14, 15, 16, 17, 18, 19, 109, 20, 21, 22, 23, 24, 25, 26, 109, 109, 109, 30, 31, 32, 37, 30, 109, 109, 109, 109, 36, 109, 109, 37},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 21, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 22, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 23, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 27, 28, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 28, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 2, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 6, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 31, 32, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 32, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 94, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 95, 109, 96, 109, 96, 97, 109},
+ {109, 109, 109, 109, 109, 38, 39, 109, 40, 109, 41, 42, 43, 44, 45, 46, 47, 48, 49, 38, 50, 51, 52, 53, 54, 55, 56, 57, 58, 109, 59, 60, 61, 62, 59, 34, 109, 98, 109, 63, 109, 109, 62},
+ {109, 6, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 38, 39, 109, 40, 109, 41, 42, 43, 44, 45, 46, 47, 48, 49, 38, 50, 51, 52, 53, 54, 55, 56, 109, 109, 109, 59, 60, 61, 62, 59, 109, 109, 109, 109, 63, 109, 109, 62},
+ {109, 38, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 41, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 60, 61, 62, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 60, 61, 62, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 60, 61, 62, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 100, 109, 40, 109, 41, 42, 43, 44, 45, 109, 47, 48, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 100, 109, 40, 109, 41, 42, 43, 44, 45, 109, 109, 48, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 100, 109, 40, 109, 41, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 100, 109, 40, 109, 41, 42, 43, 44, 45, 46, 47, 48, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 38, 39, 109, 40, 109, 41, 42, 43, 44, 45, 46, 47, 48, 49, 109, 50, 51, 52, 53, 54, 55, 56, 109, 109, 109, 59, 60, 61, 62, 59, 109, 109, 109, 109, 63, 109, 109, 62},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 51, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 52, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 53, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 57, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 38, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 60, 61, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 61, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 38, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 66, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 83, 84, 85, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 109, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 83, 84, 85, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 109, 109, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 83, 84, 85, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 102, 109, 65, 109, 66, 67, 68, 69, 70, 109, 72, 73, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 102, 109, 65, 109, 66, 67, 68, 69, 70, 109, 109, 73, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 102, 109, 65, 109, 66, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 102, 109, 65, 109, 66, 67, 68, 69, 70, 71, 72, 73, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 2, 64, 109, 65, 109, 66, 67, 68, 69, 70, 71, 72, 73, 74, 109, 75, 76, 77, 78, 79, 80, 81, 109, 109, 109, 82, 83, 84, 85, 86, 109, 109, 109, 109, 87, 109, 109, 88},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 76, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 77, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 78, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 109, 109, 109, 109, 103, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 83, 84, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 84, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 109, 109, 109, 109, 104, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 2, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 103, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 4, 109, 109, 109, 109, 105, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 106, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 8, 9, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 12, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 24, 25, 26, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 12, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 94, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 34, 95, 95, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 94, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 95, 109, 96, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 94, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 95, 109, 96, 109, 96, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 34, 109, 98, 109, 109, 109, 109, 109},
+ {109, 107, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 42, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 54, 55, 56, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 42, 109, 109, 109},
+ {109, 108, 109, 109, 109, 109, 109, 109, 104, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 67, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 79, 80, 81, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 67, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 9, 109, 109, 109, 13, 14, 15, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 31, 32, 37, 91, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 43, 44, 45, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 60, 61, 62, 99, 109, 109, 109, 109, 109, 109, 109, 109},
+ {109, 109, 109, 109, 109, 109, 109, 109, 65, 109, 109, 109, 68, 69, 70, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 83, 84, 85, 101, 109, 109, 109, 109, 109, 109, 109, 109},
+};
+static const uint8_t use_accept[109] = {
+ 8, 6, 3, 9, 5, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8,
+ 8, 9, 7, 6, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 2, 3, 1, 4, 5, 8, 8, 8, 7, 7,
+ 7, 7, 0, 6, 6, 2, 3, 1, 2, 4, 8, 6, 3,
+};
+const VegaMachine vega_use_machine = {use_class, 43, 109, use_next[0], sizeof(use_next[0][0]), use_accept, 8};
+
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
diff --git a/text/syllabic.py b/text/syllabic.py
index 6eb7c93..4a79869 100644
--- a/text/syllabic.py
+++ b/text/syllabic.py
@@ -12,6 +12,10 @@ HARFBUZZ_SRC is HarfBuzz 10.2.0's src/ directory; what is read from it:
read cell for cell (Unicode here is 15.1: the table is taken as HarfBuzz
has it). Khmer and Myanmar read the same table.
+- Each character's category for the Universal Shaping Engine: hb-ot-
+ shaper-use-table.hh, whose arrays and lookup (gen-use-table.py's) are
+ carried over as they are, the categories named in them resolved.
+
- The syllable machines: hb-ot-shaper-*-machine.rl, the Ragel grammars.
This compiles each to a DFA with Ragel's scanner semantics (the longest
match from each position, ties to the pattern listed first), its symbols
@@ -27,7 +31,7 @@ import sys
from pathlib import Path
HB = Path(sys.argv[1] if len(sys.argv) > 1 else '.')
-MACHINES = ['indic', 'khmer', 'myanmar']
+MACHINES = ['indic', 'khmer', 'myanmar', 'use']
ALPHABET = 64 # categories past 63 are folded into 63, which only `any` takes
@@ -277,6 +281,22 @@ def runs_of(cells):
return runs
+def use_table(grammar):
+ """HarfBuzz's USE lookup: its arrays (categories resolved to numbers)
+ and its expression, as C."""
+ text = (HB / 'hb-ot-shaper-use-table.hh').read_text()
+ part = text[text.index('#ifndef HB_OPTIMIZE_SIZE'):text.index('#else')]
+ arrays = []
+ for kind, name, n, body in re.findall(r'static const (uint8_t|uint16_t)\s+(hb_use_\w+)\[(\d+)\] =\s*\{(.*?)\};',
+ part, re.S):
+ values = [int(t) if t.isdigit() else grammar.symbols[t] for t in re.findall(r'[A-Za-z_]\w*|\d+', body)]
+ assert len(values) == int(n), name
+ arrays.append((kind, name.replace('hb_use_', 'use_'), values))
+ expression = re.search(r'return (u<.*?);\n', part).group(1).replace('hb_use_', 'use_')
+ assert expression.endswith(':O')
+ return arrays, expression[:-1] + str(grammar.symbols['O'])
+
+
# ---- Checking against Ragel's machines (hb-ot-shaper-*-machine.hh)
def ragel(name):
@@ -445,6 +465,24 @@ def main():
out.append(f' return 0x{default[0] | default[1] << 8:04X};')
out.append('}')
out.append('')
+ arrays, expression = use_table(grammars['use'])
+ out.append('/* Each character\'s USE category (hb-ot-shaper-use-table.hh, Unicode 16): HarfBuzz\'s arrays and')
+ out.append(' * lookup. */')
+ for kind, name, values in arrays:
+ out.append(f'static const {kind} {name}[{len(values)}] = {{')
+ for k in range(0, len(values), 16):
+ out.append(' ' + ', '.join(str(v) for v in values[k:k + 16]) + ',')
+ out.append('};')
+ out.append('static unsigned use_b4(const uint8_t *a, unsigned i) { return (a[i >> 1] >> ((i & 1u) << 2)) & 15u; }')
+ out.append(f'uint8_t vega_use_category(uint32_t u) {{ return (uint8_t)({expression}); }}')
+ out.append('')
+ out.append('/* The categories syllabic.h names are the machines\' own. */')
+ for name, prefix in (('indic', 'VEGA_OT_'), ('khmer', 'VEGA_OT_'), ('myanmar', 'VEGA_OT_'), ('use', 'VEGA_USE_')):
+ for symbol, value in sorted(grammars[name].symbols.items()):
+ if name == 'myanmar' and symbol in ('IV', 'DB', 'GB'):
+ continue # Myanmar's names for V, N and PLACEHOLDER
+ out.append(f'_Static_assert({prefix}{symbol.upper()} == {value}, "{name} {symbol}");')
+ out.append('')
out.append('/* The syllable machines: a DFA over classes of symbol; a state\'s accept is')
out.append(' * the syllable type it ends, plus one. */')
for name in MACHINES: