diff options
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/build.c')
-rw-r--r-- | Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/build.c | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/build.c b/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/build.c deleted file mode 100644 index 91739f11589..00000000000 --- a/Build/source/texk/web2c/mfluadir/otfcc/lib/table/otl/build.c +++ /dev/null @@ -1,320 +0,0 @@ -#include "private.h" - -#define LARGE_SUBTABLE_LIMIT 4096 - -static uint32_t featureNameToTag(const sds name) { - uint32_t tag = 0; - if (sdslen(name) > 0) { - tag |= ((uint8_t)name[0]) << 24; - } else { - tag |= ((uint8_t)' ') << 24; - } - if (sdslen(name) > 1) { - tag |= ((uint8_t)name[1]) << 16; - } else { - tag |= ((uint8_t)' ') << 16; - } - if (sdslen(name) > 2) { - tag |= ((uint8_t)name[2]) << 8; - } else { - tag |= ((uint8_t)' ') << 8; - } - if (sdslen(name) > 3) { - tag |= ((uint8_t)name[3]) << 0; - } else { - tag |= ((uint8_t)' ') << 0; - } - return tag; -} - -typedef caryll_Buffer *(*_otl_Builder)(const otl_Subtable *_subtable, - otl_BuildHeuristics heuristics); - -static tableid_t _declare_lookup_writer(otl_LookupType type, _otl_Builder fn, - const otl_Lookup *lookup, caryll_Buffer ***subtables, - size_t *lastOffset, bool *preferExtensionForThisLUT, - otl_BuildHeuristics heuristics) { - if (lookup->type == type) { - NEW(*subtables, lookup->subtables.length); - size_t totalBufSizeShort = 0; - size_t totalBufSizeExt = 0; - for (tableid_t j = 0; j < lookup->subtables.length; j++) { - caryll_Buffer *buf = fn(lookup->subtables.items[j], heuristics); - (*subtables)[j] = buf; - totalBufSizeShort += buf->size; - totalBufSizeExt += 8; - } - if (totalBufSizeShort > LARGE_SUBTABLE_LIMIT) { - *lastOffset += totalBufSizeExt; - *preferExtensionForThisLUT = true; - } else { - *lastOffset += totalBufSizeShort; - *preferExtensionForThisLUT = false; - } - return lookup->subtables.length; - } - return 0; -} - -#define LOOKUP_WRITER(type, fn) \ - if (!written) \ - written = _declare_lookup_writer(type, fn, lookup, subtables, lastOffset, \ - preferExtensionForThisLUT, heuristics); - -static tableid_t _build_lookup(const otl_Lookup *lookup, caryll_Buffer ***subtables, - size_t *lastOffset, bool *preferExtensionForThisLUT, - otl_BuildHeuristics heuristics) { - if (lookup->type == otl_type_gpos_chaining || lookup->type == otl_type_gsub_chaining) { - return otfcc_classifiedBuildChaining(lookup, subtables, lastOffset); - } - - tableid_t written = 0; - LOOKUP_WRITER(otl_type_gsub_single, otfcc_build_gsub_single_subtable); - LOOKUP_WRITER(otl_type_gsub_multiple, otfcc_build_gsub_multi_subtable); - LOOKUP_WRITER(otl_type_gsub_alternate, otfcc_build_gsub_multi_subtable); - LOOKUP_WRITER(otl_type_gsub_ligature, otfcc_build_gsub_ligature_subtable); - LOOKUP_WRITER(otl_type_gsub_reverse, otfcc_build_gsub_reverse); - LOOKUP_WRITER(otl_type_gpos_single, otfcc_build_gpos_single); - LOOKUP_WRITER(otl_type_gpos_pair, otfcc_build_gpos_pair); - LOOKUP_WRITER(otl_type_gpos_cursive, otfcc_build_gpos_cursive); - LOOKUP_WRITER(otl_type_gpos_markToBase, otfcc_build_gpos_markToSingle); - LOOKUP_WRITER(otl_type_gpos_markToMark, otfcc_build_gpos_markToSingle); - LOOKUP_WRITER(otl_type_gpos_markToLigature, otfcc_build_gpos_markToLigature); - return written; -} - -static otl_BuildHeuristics getLookupHeuristics(const table_OTL *table, const otl_Lookup *lut) { - otl_BuildHeuristics heu = OTL_BH_NORMAL; - // GSUB VERT heuristics - // GDI have some restrictions on the internal format of the lookup inisde a VERT feature - if (lut->type == otl_type_gsub_single) { - for (tableid_t j = 0; j < table->features.length; j++) { - const otl_Feature *fea = table->features.items[j]; - if (featureNameToTag(fea->name) != OTFCC_CHR('v','e','r','t')) continue; - for (tableid_t k = 0; k < fea->lookups.length; k++) { - if (fea->lookups.items[k] == lut) heu |= OTL_BH_GSUB_VERT; - } - } - } - return heu; -} - -// When writing lookups, otfcc will try to maintain everything correctly. -// That is, we will use extended layout lookups automatically when the -// offsets are too large. -static bk_Block *writeOTLLookups(const table_OTL *table, const otfcc_Options *options, - const char *tag) { - caryll_Buffer ***subtables; - NEW(subtables, table->lookups.length); - bool *preferExtForThisLut; - tableid_t *subtableQuantity; - NEW(subtableQuantity, table->lookups.length); - NEW(preferExtForThisLut, table->lookups.length); - - size_t lastOffset = 0; - for (tableid_t j = 0; j < table->lookups.length; j++) { - otl_Lookup *lookup = table->lookups.items[j]; - otl_BuildHeuristics heu = getLookupHeuristics(table, lookup); - logProgress("Building lookup %s (%u/%u)\n", lookup->name, j, - (uint32_t)table->lookups.length); - subtableQuantity[j] = - _build_lookup(lookup, &(subtables[j]), &lastOffset, &(preferExtForThisLut[j]), heu); - } - - size_t headerSize = 2 + 2 * table->lookups.length; - for (tableid_t j = 0; j < table->lookups.length; j++) { - if (subtableQuantity[j]) { headerSize += 6 + 2 * subtableQuantity[j]; } - } - bool useExtended = lastOffset >= 0xFF00 - headerSize; - - bk_Block *root = bk_new_Block(b16, table->lookups.length, // LookupCount - bkover); - for (tableid_t j = 0; j < table->lookups.length; j++) { - if (!subtableQuantity[j]) { - logNotice("Lookup %s is empty.\n", table->lookups.items[j]->name); - } - otl_Lookup *lookup = table->lookups.items[j]; - const bool canBeContextual = otfcc_chainingLookupIsContextualLookup(lookup); - const bool useExtendedForIt = useExtended || preferExtForThisLut[j]; - if (useExtendedForIt) { - logNotice("[OTFCC-fea] Using extended OpenType table layout for %s/%s.\n", tag, - lookup->name); - } - uint16_t lookupType = - useExtendedForIt - ? (lookup->type > otl_type_gpos_unknown - ? otl_type_gpos_extend - otl_type_gpos_unknown - : lookup->type > otl_type_gsub_unknown - ? otl_type_gsub_extend - otl_type_gsub_unknown - : 0) - : (lookup->type > otl_type_gpos_unknown - ? lookup->type - otl_type_gpos_unknown - : lookup->type > otl_type_gsub_unknown ? lookup->type - otl_type_gsub_unknown - : 0) - - (canBeContextual ? 1 : 0); - - bk_Block *blk = bk_new_Block(b16, lookupType, // LookupType - b16, lookup->flags, // LookupFlag - b16, subtableQuantity[j], // SubTableCount - bkover); - - for (tableid_t k = 0; k < subtableQuantity[j]; k++) { - if (useExtendedForIt) { - uint16_t extensionLookupType = (lookup->type > otl_type_gpos_unknown - ? lookup->type - otl_type_gpos_unknown - : lookup->type > otl_type_gsub_unknown - ? lookup->type - otl_type_gsub_unknown - : 0) - - (canBeContextual ? 1 : 0); - - bk_Block *stub = - bk_new_Block(b16, 1, // format - b16, extensionLookupType, // ExtensionLookupType - p32, bk_newBlockFromBuffer(subtables[j][k]), // ExtensionOffset - bkover); - bk_push(blk, p16, stub, bkover); - } else { - bk_push(blk, p16, bk_newBlockFromBuffer(subtables[j][k]), bkover); - } - } - bk_push(blk, b16, 0, // MarkFilteringSet - bkover); - bk_push(root, p16, blk, bkover); - FREE(subtables[j]); - } - FREE(subtables); - FREE(subtableQuantity); - FREE(preferExtForThisLut); - return root; -} - -static bk_Block *writeOTLFeatures(const table_OTL *table, const otfcc_Options *options) { - bk_Block *root = bk_new_Block(b16, table->features.length, bkover); - for (tableid_t j = 0; j < table->features.length; j++) { - bk_Block *fea = bk_new_Block(p16, NULL, // FeatureParams - b16, table->features.items[j]->lookups.length, // LookupCount - bkover); - for (tableid_t k = 0; k < table->features.items[j]->lookups.length; k++) { - // reverse lookup - for (tableid_t l = 0; l < table->lookups.length; l++) { - if (table->features.items[j]->lookups.items[k] == table->lookups.items[l]) { - bk_push(fea, b16, l, bkover); - break; - } - } - } - bk_push(root, b32, featureNameToTag(table->features.items[j]->name), // FeatureTag - p16, fea, // Feature - bkover); - } - return root; -} - -// script hash -typedef struct { - sds tag; - uint16_t lc; - otl_LanguageSystem *dl; - otl_LanguageSystem **ll; - UT_hash_handle hh; -} script_stat_hash; - -static tableid_t featureIndex(const otl_Feature *feature, const table_OTL *table) { - for (tableid_t j = 0; j < table->features.length; j++) - if (table->features.items[j] == feature) { return j; } - return 0xFFFF; -} -static bk_Block *writeLanguage(otl_LanguageSystem *lang, const table_OTL *table) { - if (!lang) return NULL; - bk_Block *root = - bk_new_Block(p16, NULL, // LookupOrder - b16, featureIndex(lang->requiredFeature, table), // ReqFeatureIndex - b16, lang->features.length, // FeatureCount - bkover); - for (tableid_t k = 0; k < lang->features.length; k++) { - bk_push(root, b16, featureIndex(lang->features.items[k], table), bkover); - } - return root; -} - -static bk_Block *writeScript(script_stat_hash *script, const table_OTL *table) { - bk_Block *root = bk_new_Block(p16, writeLanguage(script->dl, table), // DefaultLangSys - b16, script->lc, // LangSysCount - bkover); - - for (tableid_t j = 0; j < script->lc; j++) { - sds tag = sdsnewlen(script->ll[j]->name + 5, 4); - - bk_push(root, b32, featureNameToTag(tag), // LangSysTag - p16, writeLanguage(script->ll[j], table), // LangSys - bkover); - sdsfree(tag); - } - return root; -} -static bk_Block *writeOTLScriptAndLanguages(const table_OTL *table, const otfcc_Options *options) { - script_stat_hash *h = NULL; - for (tableid_t j = 0; j < table->languages.length; j++) { - otl_LanguageSystem *language = table->languages.items[j]; - sds scriptTag = sdsnewlen(language->name, 4); - bool isDefault = strncmp(language->name + 5, "DFLT", 4) == 0 || - strncmp(language->name + 5, "dflt", 4) == 0; - - script_stat_hash *s = NULL; - HASH_FIND_STR(h, scriptTag, s); - if (s) { - if (isDefault) { - s->dl = language; - } else { - s->lc += 1; - s->ll[s->lc - 1] = language; - } - sdsfree(scriptTag); - } else { - NEW(s); - s->tag = scriptTag; - s->dl = NULL; - NEW(s->ll, table->languages.length); - if (isDefault) { - s->dl = language; - s->lc = 0; - } else { - s->lc = 1; - s->ll[s->lc - 1] = language; - } - HASH_ADD_STR(h, tag, s); - } - } - - bk_Block *root = bk_new_Block(b16, HASH_COUNT(h), bkover); - - script_stat_hash *s, *tmp; - HASH_ITER(hh, h, s, tmp) { - bk_push(root, b32, featureNameToTag(s->tag), // ScriptTag - p16, writeScript(s, table), // Script - bkover); - HASH_DEL(h, s); - sdsfree(s->tag); - FREE(s->ll); - FREE(s); - } - return root; -} - -caryll_Buffer *otfcc_buildOtl(const table_OTL *table, const otfcc_Options *options, - const char *tag) { - if (!table) return NULL; - caryll_Buffer *buf; - loggedStep("%s", tag) { - bk_Block *lookups = writeOTLLookups(table, options, tag); - bk_Block *features = writeOTLFeatures(table, options); - bk_Block *languages = writeOTLScriptAndLanguages(table, options); - bk_Block *root = bk_new_Block(b32, 0x10000, // Version - p16, languages, // ScriptList - p16, features, // FeatureList - p16, lookups, // LookupList - bkover); - buf = bk_build_Block(root); - } - return buf; -} |