summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c')
-rw-r--r--Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c b/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c
new file mode 100644
index 00000000000..6ec7958addb
--- /dev/null
+++ b/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/subtables/chaining/build.c
@@ -0,0 +1,239 @@
+#include "../chaining.h"
+#include "common.h"
+
+bool otfcc_chainingLookupIsContextualLookup(const otl_Lookup *lookup) {
+ if (!(lookup->type == otl_type_gpos_chaining || lookup->type == otl_type_gsub_chaining))
+ return false;
+ bool isContextual = true;
+ for (tableid_t j = 0; j < lookup->subtables.length; j++) {
+ const subtable_chaining *subtable = &(lookup->subtables.items[j]->chaining);
+ if (subtable->type == otl_chaining_classified) {
+ for (tableid_t k = 0; k < subtable->rulesCount; k++) {
+ otl_ChainingRule *rule = subtable->rules[k];
+ tableid_t nBacktrack = rule->inputBegins;
+ tableid_t nLookahead = rule->matchCount - rule->inputEnds;
+ isContextual = isContextual && !nBacktrack && !nLookahead;
+ }
+ } else {
+ const otl_ChainingRule *rule = (const otl_ChainingRule *)&(subtable->rule);
+ tableid_t nBacktrack = rule->inputBegins;
+ tableid_t nLookahead = rule->matchCount - rule->inputEnds;
+ isContextual = isContextual && !nBacktrack && !nLookahead;
+ }
+ }
+ return isContextual;
+}
+
+////// CHAINING
+
+static caryll_Buffer *otfcc_build_chaining_coverage(const otl_Subtable *_subtable) {
+ const subtable_chaining *subtable = &(_subtable->chaining);
+ const otl_ChainingRule *rule = (const otl_ChainingRule *)&(subtable->rule);
+ tableid_t nBacktrack = rule->inputBegins;
+ tableid_t nInput = rule->inputEnds - rule->inputBegins;
+ tableid_t nLookahead = rule->matchCount - rule->inputEnds;
+ tableid_t nSubst = rule->applyCount;
+ reverseBacktracks(rule);
+
+ bk_Block *root = bk_new_Block(b16, 3, // format
+ bkover);
+
+ bk_push(root, b16, nBacktrack, bkover);
+ for (tableid_t j = 0; j < rule->inputBegins; j++) {
+ bk_push(root, p16, bk_newBlockFromBuffer(Coverage.build(rule->match[j])), bkover);
+ }
+ bk_push(root, b16, nInput, bkover);
+ for (tableid_t j = rule->inputBegins; j < rule->inputEnds; j++) {
+ bk_push(root, p16, bk_newBlockFromBuffer(Coverage.build(rule->match[j])), bkover);
+ }
+ bk_push(root, b16, nLookahead, bkover);
+ for (tableid_t j = rule->inputEnds; j < rule->matchCount; j++) {
+ bk_push(root, p16, bk_newBlockFromBuffer(Coverage.build(rule->match[j])), bkover);
+ }
+ bk_push(root, b16, rule->applyCount, bkover);
+ for (tableid_t j = 0; j < nSubst; j++) {
+ bk_push(root, b16, rule->apply[j].index - nBacktrack, // position
+ b16, rule->apply[j].lookup.index, // lookup
+ bkover);
+ }
+
+ return bk_build_Block(root);
+}
+
+static caryll_Buffer *otfcc_build_chaining_classes(const otl_Subtable *_subtable) {
+ const subtable_chaining *subtable = &(_subtable->chaining);
+
+ otl_Coverage *coverage;
+ NEW(coverage);
+ coverage->numGlyphs = subtable->ic->numGlyphs;
+ coverage->glyphs = subtable->ic->glyphs;
+
+ bk_Block *root =
+ bk_new_Block(b16, 2, // format
+ p16, bk_newBlockFromBuffer(Coverage.build(coverage)), // coverage
+ p16, bk_newBlockFromBuffer(ClassDef.build(subtable->bc)), // BacktrackClassDef
+ p16, bk_newBlockFromBuffer(ClassDef.build(subtable->ic)), // InputClassDef
+ p16, bk_newBlockFromBuffer(ClassDef.build(subtable->fc)), // LookaheadClassDef
+ b16, subtable->ic->maxclass + 1, // ChainSubClassSetCnt
+ bkover);
+
+ glyphclass_t *rcpg;
+ NEW(rcpg, subtable->ic->maxclass + 1);
+ for (glyphclass_t j = 0; j <= subtable->ic->maxclass; j++) {
+ rcpg[j] = 0;
+ }
+ for (tableid_t j = 0; j < subtable->rulesCount; j++) {
+ tableid_t ib = subtable->rules[j]->inputBegins;
+ tableid_t startClass = subtable->rules[j]->match[ib]->glyphs[0].index;
+ if (startClass <= subtable->ic->maxclass) rcpg[startClass] += 1;
+ }
+
+ for (glyphclass_t j = 0; j <= subtable->ic->maxclass; j++) {
+ if (rcpg[j]) {
+ bk_Block *cset = bk_new_Block(b16, rcpg[j], // ChainSubClassRuleCnt
+ bkover);
+ for (tableid_t k = 0; k < subtable->rulesCount; k++) {
+ otl_ChainingRule *rule = subtable->rules[k];
+ glyphclass_t startClass = rule->match[rule->inputBegins]->glyphs[0].index;
+ if (startClass != j) { continue; }
+ reverseBacktracks(rule);
+ tableid_t nBacktrack = rule->inputBegins;
+ tableid_t nInput = rule->inputEnds - rule->inputBegins;
+ tableid_t nLookahead = rule->matchCount - rule->inputEnds;
+ tableid_t nSubst = rule->applyCount;
+ bk_Block *r = bk_new_Block(bkover);
+ bk_push(r, b16, nBacktrack, bkover);
+ for (tableid_t m = 0; m < rule->inputBegins; m++) {
+ bk_push(r, b16, rule->match[m]->glyphs[0].index, bkover);
+ }
+ bk_push(r, b16, nInput, bkover);
+ for (tableid_t m = rule->inputBegins + 1; m < rule->inputEnds; m++) {
+ bk_push(r, b16, rule->match[m]->glyphs[0].index, bkover);
+ }
+ bk_push(r, b16, nLookahead, bkover);
+ for (tableid_t m = rule->inputEnds; m < rule->matchCount; m++) {
+ bk_push(r, b16, rule->match[m]->glyphs[0].index, bkover);
+ }
+ bk_push(r, b16, nSubst, bkover);
+ for (tableid_t m = 0; m < nSubst; m++) {
+ bk_push(r, b16, rule->apply[m].index - nBacktrack, // position
+ b16, rule->apply[m].lookup.index, // lookup index
+ bkover);
+ }
+ bk_push(cset, p16, r, bkover);
+ }
+ bk_push(root, p16, cset, bkover);
+ } else {
+ bk_push(root, p16, NULL, bkover);
+ }
+ }
+
+ FREE(coverage);
+ FREE(rcpg);
+ return bk_build_Block(root);
+}
+
+caryll_Buffer *otfcc_build_chaining(const otl_Subtable *_subtable) {
+ if (_subtable->chaining.type == otl_chaining_classified) {
+ return otfcc_build_chaining_classes(_subtable);
+ } else {
+ return otfcc_build_chaining_coverage(_subtable);
+ }
+}
+
+////// CONTEXTUAL
+
+static caryll_Buffer *otfcc_build_contextual_coverage(const otl_Subtable *_subtable) {
+ const subtable_chaining *subtable = &(_subtable->chaining);
+ const otl_ChainingRule *rule = (const otl_ChainingRule *)&(subtable->rule);
+ tableid_t nInput = rule->inputEnds - rule->inputBegins;
+ tableid_t nSubst = rule->applyCount;
+ reverseBacktracks(rule);
+
+ bk_Block *root = bk_new_Block(b16, 3, // format
+ bkover);
+
+ bk_push(root, b16, nInput, bkover);
+ bk_push(root, b16, nSubst, bkover);
+ for (tableid_t j = rule->inputBegins; j < rule->inputEnds; j++) {
+ bk_push(root, p16, bk_newBlockFromBuffer(Coverage.build(rule->match[j])), bkover);
+ }
+ for (tableid_t j = 0; j < nSubst; j++) {
+ bk_push(root, b16, rule->apply[j].index, // position
+ b16, rule->apply[j].lookup.index, // lookup
+ bkover);
+ }
+
+ return bk_build_Block(root);
+}
+
+static caryll_Buffer *otfcc_build_contextual_classes(const otl_Subtable *_subtable) {
+ const subtable_chaining *subtable = &(_subtable->chaining);
+
+ otl_Coverage *coverage;
+ NEW(coverage);
+ coverage->numGlyphs = subtable->ic->numGlyphs;
+ coverage->glyphs = subtable->ic->glyphs;
+
+ bk_Block *root =
+ bk_new_Block(b16, 2, // format
+ p16, bk_newBlockFromBuffer(Coverage.build(coverage)), // coverage
+ p16, bk_newBlockFromBuffer(ClassDef.build(subtable->ic)), // InputClassDef
+ b16, subtable->ic->maxclass + 1, // ChainSubClassSetCnt
+ bkover);
+
+ glyphclass_t *rcpg;
+ NEW(rcpg, subtable->ic->maxclass + 1);
+ for (glyphclass_t j = 0; j <= subtable->ic->maxclass; j++) {
+ rcpg[j] = 0;
+ }
+ for (tableid_t j = 0; j < subtable->rulesCount; j++) {
+ tableid_t ib = subtable->rules[j]->inputBegins;
+ tableid_t startClass = subtable->rules[j]->match[ib]->glyphs[0].index;
+ if (startClass <= subtable->ic->maxclass) rcpg[startClass] += 1;
+ }
+
+ for (glyphclass_t j = 0; j <= subtable->ic->maxclass; j++) {
+ if (rcpg[j]) {
+ bk_Block *cset = bk_new_Block(b16, rcpg[j], // ChainSubClassRuleCnt
+ bkover);
+ for (tableid_t k = 0; k < subtable->rulesCount; k++) {
+ otl_ChainingRule *rule = subtable->rules[k];
+ glyphclass_t startClass = rule->match[rule->inputBegins]->glyphs[0].index;
+ if (startClass != j) { continue; }
+ reverseBacktracks(rule);
+ tableid_t nInput = rule->inputEnds - rule->inputBegins;
+ tableid_t nSubst = rule->applyCount;
+ bk_Block *r = bk_new_Block(bkover);
+
+ bk_push(r, b16, nInput, bkover);
+ bk_push(r, b16, nSubst, bkover);
+ for (tableid_t m = rule->inputBegins + 1; m < rule->inputEnds; m++) {
+ bk_push(r, b16, rule->match[m]->glyphs[0].index, bkover);
+ }
+
+ for (tableid_t m = 0; m < nSubst; m++) {
+ bk_push(r, b16, rule->apply[m].index, // position
+ b16, rule->apply[m].lookup.index, // lookup index
+ bkover);
+ }
+ bk_push(cset, p16, r, bkover);
+ }
+ bk_push(root, p16, cset, bkover);
+ } else {
+ bk_push(root, p16, NULL, bkover);
+ }
+ }
+
+ FREE(coverage);
+ FREE(rcpg);
+ return bk_build_Block(root);
+}
+
+caryll_Buffer *otfcc_build_contextual(const otl_Subtable *_subtable) {
+ if (_subtable->chaining.type == otl_chaining_classified) {
+ return otfcc_build_contextual_classes(_subtable);
+ } else {
+ return otfcc_build_contextual_coverage(_subtable);
+ }
+}