Example #1
0
static void deleteGSUBLigatureSubtable(otl_subtable *_subtable) {
	if (!_subtable) return;
	subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature);
	if (subtable->from && subtable->to) {
		for (uint16_t j = 0; j < subtable->to->numGlyphs; j++) {
			caryll_delete_coverage(subtable->from[j]);
		}
		free(subtable->from);
	}
	caryll_delete_coverage(subtable->to);
	free(subtable);
}
Example #2
0
otl_subtable *caryll_read_gsub_ligature(font_file_pointer data, uint32_t tableLength,
                                        uint32_t offset) {
	otl_subtable *_subtable;
	NEW(_subtable);
	subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature);
	subtable->from = NULL;
	subtable->to = NULL;
	checkLength(offset + 6);

	otl_coverage *startCoverage =
	    caryll_read_coverage(data, tableLength, offset + read_16u(data + offset + 2));
	if (!startCoverage) goto FAIL;
	uint16_t setCount = read_16u(data + offset + 4);
	if (setCount != startCoverage->numGlyphs) goto FAIL;
	checkLength(offset + 6 + setCount * 2);

	uint32_t ligatureCount = 0;
	for (uint16_t j = 0; j < setCount; j++) {
		uint32_t setOffset = offset + read_16u(data + offset + 6 + j * 2);
		checkLength(setOffset + 2);
		ligatureCount += read_16u(data + setOffset);
		checkLength(setOffset + 2 + read_16u(data + setOffset) * 2);
	}

	NEW(subtable->to);
	subtable->to->numGlyphs = ligatureCount;
	NEW_N(subtable->to->glyphs, ligatureCount);
	NEW_N(subtable->from, ligatureCount);
	for (uint16_t j = 0; j < ligatureCount; j++) { subtable->from[j] = NULL; };
	uint16_t jj = 0;
	for (uint16_t j = 0; j < setCount; j++) {
		uint32_t setOffset = offset + read_16u(data + offset + 6 + j * 2);
		uint16_t lc = read_16u(data + setOffset);
		for (uint16_t k = 0; k < lc; k++) {
			uint32_t ligOffset = setOffset + read_16u(data + setOffset + 2 + k * 2);
			checkLength(ligOffset + 4);
			uint16_t ligComponents = read_16u(data + ligOffset + 2);
			checkLength(ligOffset + 2 + ligComponents * 2);

			subtable->to->glyphs[jj].gid = read_16u(data + ligOffset);
			subtable->to->glyphs[jj].name = NULL;

			NEW(subtable->from[jj]);
			subtable->from[jj]->numGlyphs = ligComponents;
			NEW_N(subtable->from[jj]->glyphs, ligComponents);
			subtable->from[jj]->glyphs[0].gid = startCoverage->glyphs[j].gid;
			subtable->from[jj]->glyphs[0].name = NULL;
			for (uint16_t m = 1; m < ligComponents; m++) {
				subtable->from[jj]->glyphs[m].gid = read_16u(data + ligOffset + 2 + m * 2);
				subtable->from[jj]->glyphs[m].name = NULL;
			}
			jj++;
		}
	}
	caryll_delete_coverage(startCoverage);
	return _subtable;
FAIL:
	deleteGSUBLigatureSubtable(_subtable);
	return NULL;
}
static void delete_mtl_subtable(otl_subtable *_subtable) {
	if (_subtable) {
		subtable_gpos_mark_to_ligature *subtable = &(_subtable->gpos_mark_to_ligature);
		if (subtable->marks) { caryll_delete_coverage(subtable->marks); }
		if (subtable->markArray) { otl_delete_mark_array(subtable->markArray); }
		if (subtable->bases) {
			if (subtable->ligArray) {
				for (uint16_t j = 0; j < subtable->bases->numGlyphs; j++) {
					delete_lig_attachment(subtable->ligArray[j]);
				}
				free(subtable->ligArray);
			}
			caryll_delete_coverage(subtable->bases);
		}
		free(_subtable);
	}
}
Example #4
0
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);
		}
	}
Example #5
0
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;
}