bool consolidate_gsub_single(caryll_font *font, table_otl *table, otl_subtable *_subtable, sds lookupName) { subtable_gsub_single *subtable = &(_subtable->gsub_single); consolidate_coverage(font, subtable->from, lookupName); consolidate_coverage(font, subtable->to, lookupName); uint16_t len = (subtable->from->numGlyphs < subtable->to->numGlyphs ? subtable->from->numGlyphs : subtable->from->numGlyphs); gsub_single_map_hash *h = NULL; for (uint16_t k = 0; k < len; k++) { if (subtable->from->glyphs[k].name && subtable->to->glyphs[k].name) { gsub_single_map_hash *s; int fromid = subtable->from->glyphs[k].gid; HASH_FIND_INT(h, &fromid, s); if (s) { fprintf(stderr, "[Consolidate] Double-mapping a glyph in a " "single substitution /%s.\n", subtable->from->glyphs[k].name); } else { NEW(s); s->fromid = subtable->from->glyphs[k].gid; s->toid = subtable->to->glyphs[k].gid; s->fromname = subtable->from->glyphs[k].name; s->toname = subtable->to->glyphs[k].name; HASH_ADD_INT(h, fromid, s); } } } HASH_SORT(h, by_from_id); if (HASH_COUNT(h) != subtable->from->numGlyphs || HASH_COUNT(h) != subtable->to->numGlyphs) { fprintf(stderr, "[Consolidate] In single subsitution lookup %s, some " "mappings are ignored.\n", lookupName); } subtable->from->numGlyphs = HASH_COUNT(h); subtable->to->numGlyphs = HASH_COUNT(h); FREE(subtable->from->glyphs); FREE(subtable->to->glyphs); NEW_N(subtable->from->glyphs, subtable->from->numGlyphs); NEW_N(subtable->to->glyphs, subtable->to->numGlyphs); { gsub_single_map_hash *s, *tmp; uint16_t j = 0; HASH_ITER(hh, h, s, tmp) { subtable->from->glyphs[j].gid = s->fromid; subtable->from->glyphs[j].name = s->fromname; subtable->to->glyphs[j].gid = s->toid; subtable->to->glyphs[j].name = s->toname; j++; HASH_DEL(h, s); free(s); } }
bool consolidate_gsub_multi(caryll_font *font, table_otl *table, otl_subtable *_subtable, sds lookupName) { subtable_gsub_multi *subtable = &(_subtable->gsub_multi); consolidate_coverage(font, subtable->from, lookupName); for (uint16_t j = 0; j < subtable->from->numGlyphs; j++) { consolidate_coverage(font, subtable->to[j], lookupName); shrink_coverage(subtable->to[j], false); } gsub_multi_hash *h = NULL; for (uint16_t k = 0; k < subtable->from->numGlyphs; k++) { if (subtable->from->glyphs[k].name) { gsub_multi_hash *s; int fromid = subtable->from->glyphs[k].gid; HASH_FIND_INT(h, &fromid, s); if (!s) { NEW(s); s->fromid = subtable->from->glyphs[k].gid; s->fromname = subtable->from->glyphs[k].name; s->to = subtable->to[k]; HASH_ADD_INT(h, fromid, s); } else { caryll_delete_coverage(subtable->to[k]); } } else { caryll_delete_coverage(subtable->to[k]); } } HASH_SORT(h, by_from_id_multi); subtable->from->numGlyphs = HASH_COUNT(h); { gsub_multi_hash *s, *tmp; uint16_t j = 0; HASH_ITER(hh, h, s, tmp) { subtable->from->glyphs[j].gid = s->fromid; subtable->from->glyphs[j].name = s->fromname; subtable->to[j] = s->to; j++; HASH_DEL(h, s); free(s); } }
bool consolidate_gsub_ligature(caryll_font *font, table_otl *table, otl_subtable *_subtable, sds lookupName) { subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature); consolidate_coverage(font, subtable->to, lookupName); for (uint16_t j = 0; j < subtable->to->numGlyphs; j++) { consolidate_coverage(font, subtable->from[j], lookupName); shrink_coverage(subtable->from[j], false); } uint16_t jj = 0; for (uint16_t k = 0; k < subtable->to->numGlyphs; k++) { if (subtable->to->glyphs[k].name && subtable->from[k]->numGlyphs) { subtable->to->glyphs[jj] = subtable->to->glyphs[k]; subtable->from[jj] = subtable->from[k]; jj++; } else { caryll_delete_coverage(subtable->from[k]); } } subtable->to->numGlyphs = jj; return false; }
bool consolidate_gpos_single(caryll_font *font, table_otl *table, otl_subtable *_subtable, sds lookupName) { subtable_gpos_single *subtable = &(_subtable->gpos_single); consolidate_coverage(font, subtable->coverage, lookupName); gpos_single_hash *h = NULL; for (uint16_t k = 0; k < subtable->coverage->numGlyphs; k++) { if (subtable->coverage->glyphs[k].name) { gpos_single_hash *s; int fromid = subtable->coverage->glyphs[k].gid; HASH_FIND_INT(h, &fromid, s); if (s) { fprintf(stderr, "[Consolidate] Double-mapping a glyph in a " "single substitution /%s.\n", subtable->coverage->glyphs[k].name); } else { NEW(s); s->fromid = subtable->coverage->glyphs[k].gid; s->fromname = subtable->coverage->glyphs[k].name; s->v = subtable->values[k]; HASH_ADD_INT(h, fromid, s); } } } HASH_SORT(h, gpos_by_from_id); subtable->coverage->numGlyphs = HASH_COUNT(h); { gpos_single_hash *s, *tmp; uint16_t j = 0; HASH_ITER(hh, h, s, tmp) { subtable->coverage->glyphs[j].gid = s->fromid; subtable->coverage->glyphs[j].name = s->fromname; subtable->values[j] = s->v; j++; HASH_DEL(h, s); free(s); } }