示例#1
0
文件: read.c 项目: anthrotype/otfcc
otl_ChainingRule *GeneralReadContextualRule(font_file_pointer data, uint32_t tableLength, uint32_t offset,
                                            uint16_t startGID, bool minusOne, CoverageReaderHandler fn,
                                            void *userdata) {
	otl_ChainingRule *rule;
	NEW(rule);
	rule->match = NULL;
	rule->apply = NULL;

	uint16_t minusOneQ = (minusOne ? 1 : 0);

	checkLength(offset + 4);
	uint16_t nInput = read_16u(data + offset);
	uint16_t nApply = read_16u(data + offset + 2);
	checkLength(offset + 4 + 2 * nInput + 4 * nApply);

	rule->matchCount = nInput;
	rule->inputBegins = 0;
	rule->inputEnds = nInput;

	NEW(rule->match, rule->matchCount);
	uint16_t jj = 0;
	if (minusOne) { rule->match[jj++] = fn(data, tableLength, startGID, offset, 2, userdata); }
	for (uint16_t j = 0; j < nInput - minusOneQ; j++) {
		uint32_t gid = read_16u(data + offset + 4 + j * 2);
		rule->match[jj++] = fn(data, tableLength, gid, offset, 2, userdata);
	}
	rule->applyCount = nApply;
	NEW(rule->apply, rule->applyCount);
	for (tableid_t j = 0; j < nApply; j++) {
		rule->apply[j].index =
		    rule->inputBegins + read_16u(data + offset + 4 + 2 * (rule->matchCount - minusOneQ) + j * 4);
		rule->apply[j].lookup =
		    Handle.fromIndex(read_16u(data + offset + 4 + 2 * (rule->matchCount - minusOneQ) + j * 4 + 2));
	}
	reverseBacktracks(rule);
	return rule;

FAIL:
	DELETE(deleteRule, rule);
	return NULL;
}
示例#2
0
文件: read.c 项目: anthrotype/otfcc
static void parseLanguage(font_file_pointer data, uint32_t tableLength, uint32_t base, otl_LanguageSystem *lang,
                          otl_FeatureList *features) {
	checkLength(base + 6);
	tableid_t rid = read_16u(data + base + 2);
	if (rid < features->length) {
		lang->requiredFeature = features->items[rid];
	} else {
		lang->requiredFeature = NULL;
	}
	tableid_t featureCount = read_16u(data + base + 4);
	for (tableid_t j = 0; j < featureCount; j++) {
		tableid_t featureIndex = read_16u(data + base + 6 + 2 * j);
		if (featureIndex < features->length) {
			otl_iFeatureRefList.push(&lang->features, features->items[featureIndex]);
		}
	}
	return;
FAIL:
	otl_iFeatureRefList.dispose(&lang->features);
	lang->requiredFeature = NULL;
	return;
}
示例#3
0
文件: read.c 项目: anthrotype/otfcc
static subtable_chaining *readContextualFormat2(subtable_chaining *subtable, const font_file_pointer data,
                                                uint32_t tableLength, uint32_t offset) {
	// Contextual Substitution Subtable, Class based.
	checkLength(offset + 8);

	classdefs *cds;
	NEW(cds);
	cds->bc = NULL;
	cds->ic = ClassDef.read(data, tableLength, offset + read_16u(data + offset + 4));
	cds->fc = NULL;

	tableid_t chainSubClassSetCnt = read_16u(data + offset + 6);
	checkLength(offset + 12 + 2 * chainSubClassSetCnt);

	tableid_t totalRules = 0;
	for (tableid_t j = 0; j < chainSubClassSetCnt; j++) {
		uint32_t srcOffset = read_16u(data + offset + 8 + j * 2);
		if (srcOffset) { totalRules += read_16u(data + offset + srcOffset); }
	}
	subtable->rulesCount = totalRules;
	NEW(subtable->rules, totalRules);

	tableid_t jj = 0;
	for (tableid_t j = 0; j < chainSubClassSetCnt; j++) {
		uint32_t srcOffset = read_16u(data + offset + 8 + j * 2);
		if (srcOffset) {
			tableid_t srsCount = read_16u(data + offset + srcOffset);
			for (tableid_t k = 0; k < srsCount; k++) {
				uint32_t srOffset = offset + srcOffset + read_16u(data + offset + srcOffset + 2 + k * 2);
				subtable->rules[jj] =
				    GeneralReadContextualRule(data, tableLength, srOffset, j, true, classCoverage, cds);
				jj += 1;
			}
		}
	}
	if (cds) {
		if (cds->bc) ClassDef.free(cds->bc);
		if (cds->ic) ClassDef.free(cds->ic);
		if (cds->fc) ClassDef.free(cds->fc);
		FREE(cds);
	}
	return subtable;
FAIL:
	iSubtable_chaining.free(subtable);
	return NULL;
}
示例#4
0
文件: read.c 项目: anthrotype/otfcc
static subtable_chaining *readContextualFormat1(subtable_chaining *subtable, const font_file_pointer data,
                                                uint32_t tableLength, uint32_t offset) {
	// Contextual Substitution Subtable, Simple.
	checkLength(offset + 6);

	uint16_t covOffset = offset + read_16u(data + offset + 2);
	otl_Coverage *firstCoverage = Coverage.read(data, tableLength, covOffset);

	tableid_t chainSubRuleSetCount = read_16u(data + offset + 4);
	if (chainSubRuleSetCount != firstCoverage->numGlyphs) goto FAIL;
	checkLength(offset + 6 + 2 * chainSubRuleSetCount);

	tableid_t totalRules = 0;
	for (tableid_t j = 0; j < chainSubRuleSetCount; j++) {
		uint32_t srsOffset = offset + read_16u(data + offset + 6 + j * 2);
		checkLength(srsOffset + 2);
		totalRules += read_16u(data + srsOffset);
		checkLength(srsOffset + 2 + 2 * read_16u(data + srsOffset));
	}
	subtable->rulesCount = totalRules;
	NEW(subtable->rules, totalRules);

	tableid_t jj = 0;
	for (tableid_t j = 0; j < chainSubRuleSetCount; j++) {
		uint32_t srsOffset = offset + read_16u(data + offset + 6 + j * 2);
		tableid_t srsCount = read_16u(data + srsOffset);
		for (tableid_t k = 0; k < srsCount; k++) {
			uint32_t srOffset = srsOffset + read_16u(data + srsOffset + 2 + k * 2);
			subtable->rules[jj] = GeneralReadContextualRule(data, tableLength, srOffset, firstCoverage->glyphs[j].index,
			                                                true, singleCoverage, NULL);
			jj += 1;
		}
	}

	Coverage.free(firstCoverage);
	return subtable;
FAIL:
	iSubtable_chaining.free(subtable);
	return NULL;
}
示例#5
0
otl_Subtable *otl_read_gsub_reverse(const font_file_pointer data, uint32_t tableLength, uint32_t offset,
                                    const otfcc_Options *options) {
	subtable_gsub_reverse *subtable = iSubtable_gsub_reverse.create();
	checkLength(offset + 6);

	tableid_t nBacktrack = read_16u(data + offset + 4);
	checkLength(offset + 6 + nBacktrack * 2);

	tableid_t nForward = read_16u(data + offset + 6 + nBacktrack * 2);
	checkLength(offset + 8 + (nBacktrack + nForward) * 2);

	tableid_t nReplacement = read_16u(data + offset + 8 + (nBacktrack + nForward) * 2);
	checkLength(offset + 10 + (nBacktrack + nForward + nReplacement) * 2);

	subtable->matchCount = nBacktrack + nForward + 1;
	NEW(subtable->match, subtable->matchCount);
	subtable->inputIndex = nBacktrack;

	for (tableid_t j = 0; j < nBacktrack; j++) {
		uint32_t covOffset = offset + read_16u(data + offset + 6 + j * 2);
		subtable->match[j] = Coverage.read(data, tableLength, covOffset);
	}
	{
		uint32_t covOffset = offset + read_16u(data + offset + 2);
		subtable->match[subtable->inputIndex] = Coverage.read(data, tableLength, covOffset);
		if (nReplacement != subtable->match[subtable->inputIndex]->numGlyphs) goto FAIL;
	}
	for (tableid_t j = 0; j < nForward; j++) {
		uint32_t covOffset = offset + read_16u(data + offset + 8 + nBacktrack * 2 + j * 2);
		subtable->match[nBacktrack + 1 + j] = Coverage.read(data, tableLength, covOffset);
	}

	NEW(subtable->to);
	subtable->to->numGlyphs = nReplacement;
	NEW(subtable->to->glyphs, nReplacement);
	for (tableid_t j = 0; j < nReplacement; j++) {
		subtable->to->glyphs[j] = Handle.fromIndex(read_16u(data + offset + 10 + (nBacktrack + nForward + j) * 2));
	}
	reverseBacktracks(subtable->match, subtable->inputIndex);
	return (otl_Subtable *)subtable;

FAIL:
	iSubtable_gsub_reverse.free(subtable);
	return NULL;
}
示例#6
0
文件: read.c 项目: anthrotype/otfcc
otl_Subtable *otl_read_contextual(const font_file_pointer data, uint32_t tableLength, uint32_t offset,
                                  const otfcc_Options *options) {
	uint16_t format = 0;
	subtable_chaining *subtable = iSubtable_chaining.create();
	subtable->type = otl_chaining_poly;

	checkLength(offset + 2);
	format = read_16u(data + offset);
	if (format == 1) {
		return (otl_Subtable *)readContextualFormat1(subtable, data, tableLength, offset);
	} else if (format == 2) {
		return (otl_Subtable *)readContextualFormat2(subtable, data, tableLength, offset);
	} else if (format == 3) {
		// Contextual Substitution Subtable, Coverage based.
		subtable->rulesCount = 1;
		NEW(subtable->rules, 1);
		subtable->rules[0] = GeneralReadContextualRule(data, tableLength, offset + 2, 0, false, format3Coverage, NULL);
		return (otl_Subtable *)subtable;
	}
FAIL:
	logWarning("Unsupported format %d.\n", format);
	iSubtable_chaining.free(subtable);
	return NULL;
}
示例#7
0
文件: read.c 项目: anthrotype/otfcc
static table_OTL *otfcc_readOtl_common(font_file_pointer data, uint32_t tableLength, otl_LookupType lookup_type_base,
                                       const otfcc_Options *options) {
	table_OTL *table = table_iOTL.create();
	if (!table) goto FAIL;
	checkLength(10);
	uint32_t scriptListOffset = read_16u(data + 4);
	checkLength(scriptListOffset + 2);
	uint32_t featureListOffset = read_16u(data + 6);
	checkLength(featureListOffset + 2);
	uint32_t lookupListOffset = read_16u(data + 8);
	checkLength(lookupListOffset + 2);

	// parse lookup list
	{
		tableid_t lookupCount = read_16u(data + lookupListOffset);
		checkLength(lookupListOffset + 2 + lookupCount * 2);
		for (tableid_t j = 0; j < lookupCount; j++) {
			otl_Lookup *lookup;
			otl_iLookupPtr.init(&lookup);
			lookup->_offset = lookupListOffset + read_16u(data + lookupListOffset + 2 + 2 * j);
			checkLength(lookup->_offset + 6);
			lookup->type = read_16u(data + lookup->_offset) + lookup_type_base;
			otl_iLookupList.push(&table->lookups, lookup);
		}
	}

	// parse feature list
	{
		tableid_t featureCount = read_16u(data + featureListOffset);
		checkLength(featureListOffset + 2 + featureCount * 6);
		tableid_t lnk = 0;
		for (tableid_t j = 0; j < featureCount; j++) {
			otl_Feature *feature;
			otl_iFeaturePtr.init(&feature);
			uint32_t tag = read_32u(data + featureListOffset + 2 + j * 6);
			if (options->glyph_name_prefix) {
				feature->name = sdscatprintf(sdsempty(), "%c%c%c%c_%s_%05d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
				                             (tag >> 8) & 0xff, tag & 0xff, options->glyph_name_prefix, j);
			} else {
				feature->name = sdscatprintf(sdsempty(), "%c%c%c%c_%05d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
				                             (tag >> 8) & 0xff, tag & 0xff, j);
			}
			uint32_t featureOffset = featureListOffset + read_16u(data + featureListOffset + 2 + j * 6 + 4);

			checkLength(featureOffset + 4);
			tableid_t lookupCount = read_16u(data + featureOffset + 2);
			checkLength(featureOffset + 4 + lookupCount * 2);
			for (tableid_t k = 0; k < lookupCount; k++) {
				tableid_t lookupid = read_16u(data + featureOffset + 4 + k * 2);
				if (lookupid < table->lookups.length) {
					otl_Lookup *lookup = table->lookups.items[lookupid];
					if (!lookup->name) {
						if (options->glyph_name_prefix) {
							lookup->name = sdscatprintf(sdsempty(), "lookup_%s_%c%c%c%c_%d", options->glyph_name_prefix,
							                            (tag >> 24) & 0xFF, (tag >> 16) & 0xFF, (tag >> 8) & 0xff,
							                            tag & 0xff, lnk++);
						} else {
							lookup->name = sdscatprintf(sdsempty(), "lookup_%c%c%c%c_%d", (tag >> 24) & 0xFF,
							                            (tag >> 16) & 0xFF, (tag >> 8) & 0xff, tag & 0xff, lnk++);
						}
					}
示例#8
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;
}
示例#9
0
文件: LTSH.c 项目: anthrotype/otfcc
#include "LTSH.h"

#include "support/util.h"

static INLINE void disposeLTSH(MOVE table_LTSH *ltsh) {
	if (ltsh) { FREE(ltsh->yPels); }
}
caryll_standardRefType(table_LTSH, table_iLTSH, disposeLTSH);

table_LTSH *otfcc_readLTSH(const otfcc_Packet packet, const otfcc_Options *options) {
	FOR_TABLE('LTSH', table) {
		font_file_pointer data = table.data;

		table_LTSH *LTSH;
		NEW(LTSH);
		LTSH->version = read_16u(data);
		LTSH->numGlyphs = read_16u(data + 2);
		NEW(LTSH->yPels, LTSH->numGlyphs);
		memcpy(LTSH->yPels, data + 4, LTSH->numGlyphs);

		return LTSH;
	}
	return NULL;
}
caryll_Buffer *otfcc_buildLTSH(const table_LTSH *ltsh, const otfcc_Options *options) {
	caryll_Buffer *buf = bufnew();
	if (!ltsh) return buf;
	bufwrite16b(buf, 0);
	bufwrite16b(buf, ltsh->numGlyphs);
	for (uint16_t j = 0; j < ltsh->numGlyphs; j++) {
		bufwrite8(buf, ltsh->yPels[j]);
示例#10
0
文件: PCLT.c 项目: jojoblack/otfcc
#include "PCLT.h"

table_PCLT *caryll_read_PCLT(caryll_packet packet) {
	FOR_TABLE('PCLT', table) {
		font_file_pointer data = table.data;

		table_PCLT *PCLT = (table_PCLT *)malloc(sizeof(table_PCLT) * 1);
		PCLT->version = read_32u(data);
		PCLT->FontNumber = read_32u(data + 4);
		PCLT->Pitch = read_16u(data + 8);
		PCLT->xHeight = read_16u(data + 10);
		PCLT->Style = read_16u(data + 12);
		PCLT->TypeFamily = read_16u(data + 14);
		PCLT->CapHeight = read_16u(data + 16);
		PCLT->SymbolSet = read_16u(data + 18);
		memcpy(PCLT->Typeface, data + 20, 16);
		memcpy(PCLT->CharacterComplement, data + 36, 8);
		memcpy(PCLT->FileName, data + 44, 6);
		PCLT->StrokeWeight = *(data + 50);
		PCLT->WidthType = *(data + 51);
		PCLT->SerifStyle = *(data + 52);
		PCLT->pad = 0;

		return PCLT;
	}
	return NULL;
}