otl_subtable *caryll_gpos_mark_to_ligature_from_json(json_value *_subtable) { json_value *_marks = json_obj_get_type(_subtable, "marks", json_object); json_value *_bases = json_obj_get_type(_subtable, "bases", json_object); if (!_marks || !_bases) return NULL; otl_subtable *st; NEW(st); classname_hash *h = NULL; parseMarks(_marks, &(st->gpos_mark_to_ligature), &h); st->gpos_mark_to_ligature.classCount = HASH_COUNT(h); parseBases(_bases, &(st->gpos_mark_to_ligature), &h); classname_hash *s, *tmp; HASH_ITER(hh, h, s, tmp) { HASH_DEL(h, s); sdsfree(s->className); free(s); }
otl_Subtable *otl_gsub_parse_reverse(const json_value *_subtable, const otfcc_Options *options) { json_value *_match = json_obj_get_type(_subtable, "match", json_array); json_value *_to = json_obj_get_type(_subtable, "to", json_array); if (!_match || !_to) return NULL; subtable_gsub_reverse *subtable = iSubtable_gsub_reverse.create(); subtable->matchCount = _match->u.array.length; NEW(subtable->match, subtable->matchCount); subtable->inputIndex = json_obj_getnum_fallback(_subtable, "inputIndex", 0); for (tableid_t j = 0; j < subtable->matchCount; j++) { subtable->match[j] = Coverage.parse(_match->u.array.values[j]); } subtable->to = Coverage.parse(_to); return (otl_Subtable *)subtable; }
static void parseMarks(json_value *_marks, subtable_gpos_mark_to_ligature *subtable, classname_hash **h) { NEW(subtable->marks); subtable->marks->numGlyphs = _marks->u.object.length; NEW_N(subtable->marks->glyphs, subtable->marks->numGlyphs); NEW(subtable->markArray); subtable->markArray->markCount = _marks->u.object.length; NEW_N(subtable->markArray->records, subtable->markArray->markCount); for (uint16_t j = 0; j < _marks->u.object.length; j++) { char *gname = _marks->u.object.values[j].name; json_value *anchorRecord = _marks->u.object.values[j].value; subtable->marks->glyphs[j].name = sdsnewlen(gname, _marks->u.object.values[j].name_length); subtable->markArray->records[j].markClass = 0; subtable->markArray->records[j].anchor = otl_anchor_absent(); if (!anchorRecord || anchorRecord->type != json_object) continue; json_value *_className = json_obj_get_type(anchorRecord, "class", json_string); if (!_className) continue; sds className = sdsnewlen(_className->u.string.ptr, _className->u.string.length); classname_hash *s; HASH_FIND_STR(*h, className, s); if (!s) { NEW(s); s->className = className; s->classID = HASH_COUNT(*h); HASH_ADD_STR(*h, className, s); } else { sdsfree(className); } subtable->markArray->records[j].markClass = s->classID; subtable->markArray->records[j].anchor.present = true; subtable->markArray->records[j].anchor.x = json_obj_getnum(anchorRecord, "x"); subtable->markArray->records[j].anchor.y = json_obj_getnum(anchorRecord, "y"); } }