summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttfdump/libttf/otfcommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/ttfdump/libttf/otfcommon.c')
-rw-r--r--Build/source/texk/ttfdump/libttf/otfcommon.c1074
1 files changed, 1074 insertions, 0 deletions
diff --git a/Build/source/texk/ttfdump/libttf/otfcommon.c b/Build/source/texk/ttfdump/libttf/otfcommon.c
new file mode 100644
index 00000000000..8102aae6ab5
--- /dev/null
+++ b/Build/source/texk/ttfdump/libttf/otfcommon.c
@@ -0,0 +1,1074 @@
+/* otfcommon.c -- OpenType Common Table Formats
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "ttf.h"
+#include "ttfutil.h"
+
+static LangSysPtr
+otfMakeLangSys (FILE *fp, ULONG offset)
+{
+ LangSysPtr langSys = XCALLOC1 (LangSys);
+ USHORT lookupOrder;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeLangSys");
+
+ if ((lookupOrder = ttfGetUSHORT (fp)) != 0)
+ ttfError ("Non-zero lookupOrder\n");
+ langSys->reqFeatureIndex = ttfGetUSHORT (fp);
+ langSys->featureCount = ttfGetUSHORT (fp);
+ langSys->featureIndex = ttfMakeUSHORT (langSys->featureCount, fp);
+
+ return langSys;
+}
+
+static void
+otfLoadScriptRecord (FILE *fp, ScriptRecordPtr scriptRecord, ULONG offset)
+{
+ int i;
+ USHORT dOffset;
+ USHORT *lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "otfLoadScriptRecord");
+
+ dOffset = ttfGetUSHORT (fp);
+
+ scriptRecord->langSysCount = ttfGetUSHORT (fp);
+ if (scriptRecord->langSysCount) {
+ scriptRecord->langSysRecord = XCALLOC (scriptRecord->langSysCount, LangSysRecord);
+ lOffset = XTALLOC (scriptRecord->langSysCount, USHORT);
+
+ for (i = 0; i < scriptRecord->langSysCount; i++) {
+ scriptRecord->langSysRecord[i].tag = ttfGetULONG (fp);
+ lOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < scriptRecord->langSysCount; i++)
+ scriptRecord->langSysRecord[i].langSys = otfMakeLangSys (fp, offset + lOffset[i]);
+
+ free (lOffset);
+ }
+
+ if (dOffset)
+ scriptRecord->defaultLangSys = otfMakeLangSys (fp, offset + dOffset);
+}
+
+ScriptListPtr
+otfMakeScriptList (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *sOffset;
+ ScriptListPtr scriptList = XCALLOC1 (ScriptList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeScriptList");
+
+ scriptList->scriptCount = ttfGetUSHORT (fp);
+ scriptList->scriptRecord = XCALLOC (scriptList->scriptCount, ScriptRecord);
+ sOffset = XTALLOC (scriptList->scriptCount, USHORT);
+
+ for (i = 0; i < scriptList->scriptCount; i++) {
+ scriptList->scriptRecord[i].tag = ttfGetULONG (fp);
+ sOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < scriptList->scriptCount; i++)
+ otfLoadScriptRecord (fp, &scriptList->scriptRecord[i], offset + sOffset[i]);
+
+ free (sOffset);
+
+ return scriptList;
+}
+
+static void
+otfPrintLangSys (FILE *fp, LangSysPtr langSys)
+{
+ int i;
+
+ fprintf (fp, " lang - featureCount: %d\n", langSys->featureCount);
+ if (langSys->reqFeatureIndex != 0xffff)
+ fprintf (fp, "\t\t reqFeatureIndex: %d\n", langSys->reqFeatureIndex);
+ if (langSys->featureCount) {
+ fprintf (fp, "\t\t featureIndex: %d", langSys->featureIndex[0]);
+ for (i = 1; i < langSys->featureCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t\t%d",
+ langSys->featureIndex[i]);
+ fprintf (fp, "\n");
+ }
+}
+
+static void
+otfPrintScriptRecord (FILE *fp, ScriptRecordPtr scriptRecord)
+{
+ int i;
+
+ fprintf (fp, "'%s' script - langSysCount: %d\n",
+ TagToStr (scriptRecord->tag), scriptRecord->langSysCount);
+ if (scriptRecord->defaultLangSys) {
+ fprintf (fp, "\t default");
+ otfPrintLangSys (fp, scriptRecord->defaultLangSys);
+ }
+ for (i = 0; i < scriptRecord->langSysCount; i++) {
+ fprintf (fp, " %2d. '%s'", i,
+ TagToStr (scriptRecord->langSysRecord[i].tag));
+ otfPrintLangSys (fp, scriptRecord->langSysRecord[i].langSys);
+ }
+}
+
+void
+otfPrintScriptList (FILE *fp, ScriptListPtr scriptList)
+{
+ int i;
+
+ fprintf (fp, " scriptCount: %d\n", scriptList->scriptCount);
+
+ for (i = 0; i < scriptList->scriptCount; i++) {
+ fprintf (fp, " %2d. ", i);
+ otfPrintScriptRecord (fp, &scriptList->scriptRecord[i]);
+ }
+ fprintf (fp, "\n");
+}
+
+static void
+otfFreeLangSys (LangSysPtr langSys)
+{
+ free (langSys->featureIndex);
+ free (langSys);
+}
+
+static void
+otfFreeScriptRecord (ScriptRecordPtr scriptRecord)
+{
+ int i;
+
+ if (scriptRecord->defaultLangSys)
+ otfFreeLangSys (scriptRecord->defaultLangSys);
+ for (i = 0; i < scriptRecord->langSysCount; i++)
+ otfFreeLangSys (scriptRecord->langSysRecord[i].langSys);
+ free (scriptRecord->langSysRecord);
+}
+
+void
+otfFreeScriptList (ScriptListPtr scriptList)
+{
+ int i;
+
+ for (i = 0; i < scriptList->scriptCount; i++)
+ otfFreeScriptRecord (&scriptList->scriptRecord[i]);
+ free (scriptList->scriptRecord);
+ free (scriptList);
+}
+
+static void
+otfLoadFeatureRecord (FILE *fp, FeatureRecordPtr featureRecord, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "otfLoadFeatureRecord");
+
+ featureRecord->featureParams = ttfGetUSHORT (fp);
+ featureRecord->lookupCount = ttfGetUSHORT (fp);
+ featureRecord->lookupListIndex = ttfMakeUSHORT (featureRecord->lookupCount, fp);
+}
+
+FeatureListPtr
+otfMakeFeatureList (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *fOffset;
+ FeatureListPtr featureList = XCALLOC1 (FeatureList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeFeatureList");
+
+ featureList->featureCount = ttfGetUSHORT (fp);
+ if (featureList->featureCount) {
+ featureList->featureRecord = XCALLOC (featureList->featureCount, FeatureRecord);
+ fOffset = XTALLOC (featureList->featureCount, USHORT);
+
+ for (i = 0; i < featureList->featureCount; i++) {
+ featureList->featureRecord[i].tag = ttfGetULONG (fp);
+ fOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < featureList->featureCount; i++)
+ otfLoadFeatureRecord (fp, &featureList->featureRecord[i], offset + fOffset[i]);
+
+ free (fOffset);
+ }
+
+ return featureList;
+}
+
+static void
+otfPrintFeatureRecord (FILE *fp, FeatureRecordPtr featureRecord)
+{
+ int i;
+
+ fprintf (fp, "'%s' feature - lookupCount: %d\n",
+ TagToStr (featureRecord->tag), featureRecord->lookupCount);
+ fprintf (fp, "\t\tlookupListIndex: %d", featureRecord->lookupListIndex[0]);
+ for (i = 1; i < featureRecord->lookupCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ featureRecord->lookupListIndex[i]);
+ fprintf (fp, "\n");
+ if (featureRecord->featureParams)
+ fprintf (fp, "\t\tfeatureParams Offset: 0x%04x\n", featureRecord->featureParams);
+}
+
+void
+otfPrintFeatureList (FILE *fp, FeatureListPtr featureList)
+{
+ int i;
+
+ fprintf (fp, " featureCount: %d\n", featureList->featureCount);
+
+ for (i = 0; i < featureList->featureCount; i++) {
+ fprintf (fp, " %2d. ", i);
+ otfPrintFeatureRecord (fp, &featureList->featureRecord[i]);
+ }
+ fprintf (fp, "\n");
+}
+
+void
+otfFreeFeatureList (FeatureListPtr featureList)
+{
+ int i;
+
+ if (featureList->featureCount) {
+ for (i = 0; i < featureList->featureCount; i++)
+ free (featureList->featureRecord[i].lookupListIndex);
+ free (featureList->featureRecord);
+ }
+ free (featureList);
+}
+
+static void
+otfLoadLookupRecord (FILE *fp, LookupRecordPtr lookupRecord, ULONG offset, MakeLookupFunc makeLookup)
+{
+ int i;
+ USHORT lookupType;
+ USHORT *lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "otfLoadLookupRecord");
+
+ lookupType = ttfGetUSHORT (fp);
+ lookupRecord->lookupFlag = ttfGetUSHORT (fp);
+ lookupRecord->subTableCount = ttfGetUSHORT (fp);
+ lookupRecord->lookup = XCALLOC (lookupRecord->subTableCount, LookupPtr);
+ lOffset = ttfMakeUSHORT (lookupRecord->subTableCount, fp);
+ if (lookupRecord->lookupFlag & lookupFlag_UseMarkFilteringSet)
+ lookupRecord->markFilteringSet = ttfGetUSHORT (fp);
+ for (i = 0; i < lookupRecord->subTableCount; i++)
+ lookupRecord->lookup[i] = (*makeLookup) (fp, lookupType, offset + lOffset[i]);
+ free (lOffset);
+}
+
+LookupListPtr
+otfMakeLookupList (FILE *fp, ULONG offset, MakeLookupFunc makeLookup)
+{
+ int i;
+ USHORT *lOffset;
+ LookupListPtr lookupList = XCALLOC1 (LookupList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeLookupList");
+
+ lookupList->lookupCount = ttfGetUSHORT (fp);
+ if (lookupList->lookupCount) {
+ lookupList->lookupRecord = XCALLOC (lookupList->lookupCount, LookupRecord);
+ lOffset = ttfMakeUSHORT (lookupList->lookupCount, fp);
+
+ for (i = 0; i < lookupList->lookupCount; i++)
+ otfLoadLookupRecord (fp, &lookupList->lookupRecord[i], offset + lOffset[i], makeLookup);
+
+ free (lOffset);
+ }
+
+ return lookupList;
+}
+
+void
+otfPrintLookupList (FILE *fp, LookupListPtr lookupList, PrintLookupFunc printLookup)
+{
+ int i;
+
+ fprintf (fp, " lookupCount: %d\n", lookupList->lookupCount);
+
+ for (i = 0; i < lookupList->lookupCount; i++) {
+ int j;
+
+ fprintf (fp, " %2d. lookupType: %d, lookupFlag: 0x%04x", i,
+ lookupList->lookupRecord[i].lookup[0].otf->lookupType,
+ lookupList->lookupRecord[i].lookupFlag);
+ if (lookupList->lookupRecord[i].lookupFlag & lookupFlag_UseMarkFilteringSet)
+ fprintf (fp, ", markFilteringSet: %d", lookupList->lookupRecord[i].markFilteringSet);
+ fprintf (fp, "\n\tsubTableCount:\t%d\n", lookupList->lookupRecord[i].subTableCount);
+ for (j = 0; j < lookupList->lookupRecord[i].subTableCount; j++) {
+ fprintf (fp, " %2d. lookupFormat: %d", j,
+ lookupList->lookupRecord[i].lookup[j].otf->lookupFormat);
+ (*printLookup) (fp, lookupList->lookupRecord[i].lookup[j]);
+ }
+ }
+ fprintf (fp, "\n");
+}
+
+void
+otfFreeLookupList (LookupListPtr lookupList, FreeLookupFunc freeLookup)
+{
+ int i;
+
+ if (lookupList->lookupCount) {
+ for (i = 0; i < lookupList->lookupCount; i++) {
+ int j;
+
+ for (j = 0; j < lookupList->lookupRecord[i].subTableCount; j++) {
+ (*freeLookup) (lookupList->lookupRecord[i].lookup[j]);
+ free (lookupList->lookupRecord[i].lookup[j].otf);
+ }
+ free (lookupList->lookupRecord[i].lookup);
+ }
+ free (lookupList->lookupRecord);
+ }
+ free (lookupList);
+}
+
+CoveragePtr
+otfMakeCoverage (FILE *fp, ULONG offset)
+{
+ CoveragePtr coverage;
+ int i;
+ USHORT format;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeCoverage");
+
+ format = ttfGetUSHORT (fp);
+ switch (format)
+ {
+ case 1:
+ coverage.coverage1 = XCALLOC1 (Coverage1);
+ coverage.coverage1->glyphCount = ttfGetUSHORT (fp);
+ coverage.coverage1->glyphArray = ttfMakeUSHORT (coverage.coverage1->glyphCount, fp);
+ break;
+ case 2:
+ coverage.coverage2 = XCALLOC1 (Coverage2);
+ coverage.coverage2->rangeCount = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord = XTALLOC (coverage.coverage2->rangeCount, RangeRecord);
+ for (i = 0; i < coverage.coverage2->rangeCount; i++) {
+ coverage.coverage2->rangeRecord[i].start = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord[i].end = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord[i].startCoverageIndex = ttfGetUSHORT (fp);
+ }
+ break;
+ default:
+ ttfError ("Unrecognized coverageFormat\n");
+ }
+
+ *coverage.format = format;
+ return coverage;
+}
+
+void
+otfPrintCoverage (FILE *fp, CoveragePtr coverage)
+{
+ int i;
+
+ fprintf (fp, "Coverage - ");
+ switch (*coverage.format)
+ {
+ case 1:
+ fprintf (fp, "glyphCount: %d\n\t\t glyphArray: %d",
+ coverage.coverage1->glyphCount, coverage.coverage1->glyphArray[0]);
+ for (i = 1; i < coverage.coverage1->glyphCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t %d",
+ coverage.coverage1->glyphArray[i]);
+ fprintf (fp, "\n");
+ break;
+ case 2:
+ fprintf (fp, "rangeCount: %d\n", coverage.coverage2->rangeCount);
+ for (i = 0; i < coverage.coverage2->rangeCount; i++) {
+ fprintf (fp, "\t %2d. start: %d, end: %d, startCoverageIndex: %d\n", i,
+ coverage.coverage2->rangeRecord[i].start,
+ coverage.coverage2->rangeRecord[i].end,
+ coverage.coverage2->rangeRecord[i].startCoverageIndex);
+ }
+ break;
+ default:
+ ttfError ("Internal error: otfPrintCoverage\n");
+ }
+}
+
+void
+otfFreeCoverage (CoveragePtr coverage)
+{
+ switch (*coverage.format)
+ {
+ case 1:
+ free (coverage.coverage1->glyphArray);
+ break;
+ case 2:
+ free (coverage.coverage2->rangeRecord);
+ break;
+ default:
+ ttfError ("Internal error: otfFreeCoverage\n");
+ }
+ free (coverage.format);
+}
+
+ClassDefPtr
+otfMakeClassDef (FILE *fp, ULONG offset)
+{
+ ClassDefPtr classDef;
+ int i;
+ USHORT format;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeClassDef");
+
+ format = ttfGetUSHORT (fp);
+ switch (format)
+ {
+ case 1:
+ classDef.classDef1 = XCALLOC1 (ClassDef1);
+ classDef.classDef1->startGlyph = ttfGetUSHORT (fp);
+ classDef.classDef1->glyphCount = ttfGetUSHORT (fp);
+ classDef.classDef1->classValueArray = ttfMakeUSHORT (classDef.classDef1->glyphCount, fp);
+ break;
+ case 2:
+ classDef.classDef2 = XCALLOC1 (ClassDef2);
+ classDef.classDef2->classRangeCount = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord = XTALLOC (classDef.classDef2->classRangeCount, ClassRangeRecord);
+ for (i = 0; i < classDef.classDef2->classRangeCount; i++) {
+ classDef.classDef2->classRangeRecord[i].start = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord[i].end = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord[i].classValue = ttfGetUSHORT (fp);
+ }
+ break;
+ default:
+ ttfError ("Unrecognized classDefFormat\n");
+ }
+
+ *classDef.format = format;
+ return classDef;
+}
+
+void
+otfPrintClassDef (FILE *fp, ClassDefPtr classDef)
+{
+ int i;
+
+ switch (*classDef.format)
+ {
+ case 1:
+ fprintf (fp, "startGlyph: %d, glyphCount: %d\n\t\tclassValueArray ",
+ classDef.classDef1->startGlyph, classDef.classDef1->glyphCount);
+ for (i = 0; i < classDef.classDef1->glyphCount; i++)
+ fprintf (fp, i == 0 ? "- %d" : i % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ classDef.classDef1->classValueArray[i]);
+ fprintf (fp, "\n");
+ break;
+ case 2:
+ fprintf (fp, "classRangeCount: %d\n", classDef.classDef2->classRangeCount);
+ for (i = 0; i < classDef.classDef2->classRangeCount; i++)
+ fprintf (fp, "\t\t%2d. start: %d, end: %d, classValue: %d\n", i,
+ classDef.classDef2->classRangeRecord[i].start,
+ classDef.classDef2->classRangeRecord[i].end,
+ classDef.classDef2->classRangeRecord[i].classValue);
+ break;
+ default:
+ ttfError ("Internal error: otfPrintClassDef\n");
+ }
+}
+
+void
+otfFreeClassDef (ClassDefPtr classDef)
+{
+ switch (*classDef.format)
+ {
+ case 1:
+ free (classDef.classDef1->classValueArray);
+ break;
+ case 2:
+ free (classDef.classDef2->classRangeRecord);
+ break;
+ default:
+ ttfError ("Internal error: otfFreeClassDef\n");
+ }
+ free (classDef.format);
+}
+
+DevicePtr
+otfMakeDevice (FILE *fp, ULONG offset)
+{
+ size_t num;
+ DevicePtr device;
+ USHORT startSize, endSize, deltaFormat;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeDevice");
+
+ startSize = ttfGetUSHORT (fp);
+ endSize = ttfGetUSHORT (fp);
+ deltaFormat = ttfGetUSHORT (fp);
+ if (deltaFormat < 1 || deltaFormat > 3)
+ ttfError ("Unrecognized deltaFormat\n");
+ num = (endSize - startSize) >> (4 - deltaFormat);
+ device = (DevicePtr) xcalloc (1, sizeof (Device) + num * sizeof (USHORT));
+ device->startSize = startSize;
+ device->endSize = endSize;
+ device->deltaFormat = deltaFormat;
+ ttfReadUSHORT (device->deltaValue, num + 1, fp);
+
+ return device;
+}
+
+void
+otfPrintDevice (FILE *fp, DevicePtr device)
+{
+ int i;
+ size_t num = (device->endSize - device->startSize) >> (4 - device->deltaFormat);
+
+ fprintf (fp, "startSize = %d, endSize = %d, deltaFormat = %d, deltaValue = 0x",
+ device->startSize, device->endSize, device->deltaFormat);
+ for (i = 0; i < num; i++)
+ fprintf (fp, "%04x", device->deltaValue[i]);
+ fprintf (fp, "%04x\n", device->deltaValue[num]);
+}
+
+static OtfLookupRecordPtr
+makeOtfLookupRecord (USHORT otfCount, FILE *fp)
+{
+ int i;
+ OtfLookupRecordPtr otf = XCALLOC (otfCount, OtfLookupRecord);
+
+ for (i = 0; i < otfCount; i++) {
+ otf[i].sequenceIndex = ttfGetUSHORT (fp);
+ otf[i].lookupListIndex = ttfGetUSHORT (fp);
+ }
+ return otf;
+}
+
+static void
+printOtfLookupRecord (FILE * fp, const char *str, USHORT otfCount, OtfLookupRecordPtr otf)
+{
+ int i;
+
+ fprintf (fp, "\t%sotfCount: %d\n", str, otfCount);
+ for (i = 0; i < otfCount; i++)
+ fprintf (fp, "\t%s%2d. sequenceIndex: %d, lookupListIndex: %d\n",
+ str, i, otf[i].sequenceIndex, otf[i].lookupListIndex);
+}
+
+static void loadOtfRule (OtfRulePtr otfRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadOtfRule");
+
+ otfRule->glyphCount = ttfGetUSHORT (fp);
+ otfRule->otfCount = ttfGetUSHORT (fp);
+ otfRule->input = ttfMakeUSHORT (otfRule->glyphCount - 1, fp);
+ otfRule->otf = makeOtfLookupRecord (otfRule->otfCount, fp);
+}
+
+static void loadOtfRuleSet (OtfRuleSetPtr otfRuleSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadOtfRuleSet");
+
+ otfRuleSet->otfRuleCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otfRuleSet->otfRuleCount, fp);
+ otfRuleSet->otfRule = XCALLOC (otfRuleSet->otfRuleCount, OtfRule);
+ for (i = 0; i < otfRuleSet->otfRuleCount; i++)
+ loadOtfRule (&otfRuleSet->otfRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfCtx1Ptr makeOTFCtx1 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *pOffset;
+ OtfCtx1Ptr otf = XCALLOC1 (OtfCtx1);
+
+ cOffset = ttfGetUSHORT (fp);
+ otf->otfRuleSetCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->otfRuleSetCount, fp);
+ otf->otfRuleSet = XCALLOC (otf->otfRuleSetCount, OtfRuleSet);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ for (i = 0; i < otf->otfRuleSetCount; i++)
+ loadOtfRuleSet (&otf->otfRuleSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFCtx1 (FILE *fp, OtfCtx1Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Simple\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t otfRuleSetCount: %d\n", otf->otfRuleSetCount);
+ for (i = 0; i < otf->otfRuleSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. otfRuleCount: %d\n", i, otf->otfRuleSet[i].otfRuleCount);
+ for (j = 0; j < otf->otfRuleSet[i].otfRuleCount; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. glyphtCount: %d ", j,
+ otf->otfRuleSet[i].otfRule[j].glyphCount);
+ for (k = 0; k < otf->otfRuleSet[i].otfRule[j].glyphCount - 1; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->otfRuleSet[i].otfRule[j].input[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->otfRuleSet[i].otfRule[j].otfCount,
+ otf->otfRuleSet[i].otfRule[j].otf);
+ }
+ }
+}
+
+void freeOTFCtx1 (OtfCtx1Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ for (i = 0; i < otf->otfRuleSetCount; i++) {
+ int j;
+
+ for (j = 0; j < otf->otfRuleSet[i].otfRuleCount; j++) {
+ free (otf->otfRuleSet[i].otfRule[j].input);
+ free (otf->otfRuleSet[i].otfRule[j].otf);
+ }
+ free (otf->otfRuleSet[i].otfRule);
+ }
+ free (otf->otfRuleSet);
+}
+
+static void loadOtfClassRule (OtfClassRulePtr otfClassRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadOtfClassRule");
+
+ otfClassRule->glyphCount = ttfGetUSHORT (fp);
+ otfClassRule->otfCount = ttfGetUSHORT (fp);
+ otfClassRule->class = ttfMakeUSHORT (otfClassRule->glyphCount - 1, fp);
+ otfClassRule->otf = makeOtfLookupRecord (otfClassRule->otfCount, fp);
+}
+
+static void loadOtfClassSet (OtfClassSetPtr otfClassSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadOtfClassSet");
+
+ otfClassSet->otfClassRuleCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otfClassSet->otfClassRuleCnt, fp);
+ otfClassSet->otfClassRule = XCALLOC (otfClassSet->otfClassRuleCnt, OtfClassRule);
+ for (i = 0; i < otfClassSet->otfClassRuleCnt; i++)
+ loadOtfClassRule (&otfClassSet->otfClassRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfCtx2Ptr makeOTFCtx2 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT clOffset;
+ USHORT *pOffset;
+ OtfCtx2Ptr otf = XCALLOC1 (OtfCtx2);
+
+ cOffset = ttfGetUSHORT (fp);
+ clOffset = ttfGetUSHORT (fp);
+ otf->otfClassSetCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->otfClassSetCnt, fp);
+ otf->otfClassSet = XCALLOC (otf->otfClassSetCnt, OtfClassSet);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->classDef = otfMakeClassDef (fp, offset + clOffset);
+ for (i = 0; i < otf->otfClassSetCnt; i++)
+ if (pOffset[i])
+ loadOtfClassSet (&otf->otfClassSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFCtx2 (FILE *fp, OtfCtx2Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Class-based\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t ClassDef - ");
+ otfPrintClassDef (fp, otf->classDef);
+ fprintf (fp, "\t otfClassSetCnt: %d\n", otf->otfClassSetCnt);
+ for (i = 0; i < otf->otfClassSetCnt; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. otfClassRuleCnt: %d\n", i, otf->otfClassSet[i].otfClassRuleCnt);
+ for (j = 0; j < otf->otfClassSet[i].otfClassRuleCnt; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. glyphtCount: %d ", j,
+ otf->otfClassSet[i].otfClassRule[j].glyphCount);
+ for (k = 0; k < otf->otfClassSet[i].otfClassRule[j].glyphCount - 1; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->otfClassSet[i].otfClassRule[j].class[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->otfClassSet[i].otfClassRule[j].otfCount,
+ otf->otfClassSet[i].otfClassRule[j].otf);
+ }
+ }
+}
+
+void freeOTFCtx2 (OtfCtx2Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ otfFreeClassDef (otf->classDef);
+ for (i = 0; i < otf->otfClassSetCnt; i++) {
+ int j;
+
+ for (j = 0; j < otf->otfClassSet[i].otfClassRuleCnt; j++) {
+ free (otf->otfClassSet[i].otfClassRule[j].class);
+ free (otf->otfClassSet[i].otfClassRule[j].otf);
+ }
+ free (otf->otfClassSet[i].otfClassRule);
+ }
+ free (otf->otfClassSet);
+}
+
+OtfCtx3Ptr makeOTFCtx3 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *gOffset;
+ OtfCtx3Ptr otf = XCALLOC1 (OtfCtx3);
+
+ otf->glyphCount = ttfGetUSHORT (fp);
+ otf->otfCount = ttfGetUSHORT (fp);
+ gOffset = ttfMakeUSHORT (otf->glyphCount, fp);
+ otf->otf = makeOtfLookupRecord (otf->otfCount, fp);
+ otf->glyphs = XCALLOC (otf->glyphCount, CoveragePtr);
+ for (i = 0; i < otf->glyphCount; i++)
+ otf->glyphs[i] = otfMakeCoverage (fp, offset + gOffset[i]);
+ free (gOffset);
+
+ return otf;
+}
+
+void printOTFCtx3 (FILE *fp, OtfCtx3Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Coverage-based\n");
+ fprintf (fp, "\t glyphCount: %d\n", otf->glyphCount);
+ for (i = 0; i < otf->glyphCount; i++) {
+ fprintf (fp, "\t %2d. ", i);
+ otfPrintCoverage (fp, otf->glyphs[i]);
+ }
+ printOtfLookupRecord (fp, " ", otf->otfCount, otf->otf);
+}
+
+void freeOTFCtx3 (OtfCtx3Ptr otf)
+{
+ int i;
+
+ for (i = 0; i < otf->glyphCount; i++)
+ otfFreeCoverage (otf->glyphs[i]);
+ free (otf->glyphs);
+ free (otf->otf);
+}
+
+static void
+loadChainOtfRule (ChainOtfRulePtr chainOtfRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfRule");
+
+ chainOtfRule->backtrackGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->backtrack = ttfMakeUSHORT (chainOtfRule->backtrackGlyphCount, fp);
+ chainOtfRule->inputGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->input = ttfMakeUSHORT (chainOtfRule->inputGlyphCount - 1, fp);
+ chainOtfRule->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->lookahead = ttfMakeUSHORT (chainOtfRule->lookaheadGlyphCount, fp);
+ chainOtfRule->otfCount = ttfGetUSHORT (fp);
+ chainOtfRule->otf = makeOtfLookupRecord (chainOtfRule->otfCount, fp);
+}
+
+static void
+loadChainOtfRuleSet (ChainOtfRuleSetPtr chainOtfRuleSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfRuleSet");
+
+ chainOtfRuleSet->chainOtfRuleCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (chainOtfRuleSet->chainOtfRuleCount, fp);
+ chainOtfRuleSet->chainOtfRule = XCALLOC (chainOtfRuleSet->chainOtfRuleCount, ChainOtfRule);
+ for (i = 0; i < chainOtfRuleSet->chainOtfRuleCount; i++)
+ loadChainOtfRule (&chainOtfRuleSet->chainOtfRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfChn1Ptr makeOTFChn1 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *pOffset;
+ OtfChn1Ptr otf = XCALLOC1 (OtfChn1);
+
+ cOffset = ttfGetUSHORT (fp);
+ otf->chainOtfRuleSetCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->chainOtfRuleSetCount, fp);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->chainOtfRuleSet = XCALLOC (otf->chainOtfRuleSetCount, ChainOtfRuleSet);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++)
+ loadChainOtfRuleSet (&otf->chainOtfRuleSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFChn1 (FILE *fp, OtfChn1Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Simple\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t chainOtfRuleSetCount: %d\n", otf->chainOtfRuleSetCount);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. chainOtfRuleCount: %d\n", i,
+ otf->chainOtfRuleSet[i].chainOtfRuleCount);
+ for (j = 0; j < otf->chainOtfRuleSet[i].chainOtfRuleCount; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. backtrackGlyphCount: %d ", j,
+ otf->chainOtfRuleSet[i].chainOtfRule[j].backtrackGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].backtrackGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].backtrack[k]);
+ fprintf (fp, "\n\t\tinputGlyphCount: %d ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].inputGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].inputGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].input[k]);
+ fprintf (fp, "\n\t\tlookaheadGlyphCount: %d ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].lookaheadGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].lookaheadGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].lookahead[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].otfCount,
+ otf->chainOtfRuleSet[i].chainOtfRule[j].otf);
+ }
+ }
+}
+
+void freeOTFChn1 (OtfChn1Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++) {
+ int j;
+
+ for (j = 0; j < otf->chainOtfRuleSet[i].chainOtfRuleCount; j++) {
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].backtrack);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].input);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].lookahead);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].otf);
+ }
+ free (otf->chainOtfRuleSet[i].chainOtfRule);
+ }
+ free (otf->chainOtfRuleSet);
+}
+
+static void
+loadChainOtfClassRule (ChainOtfClassRulePtr chainOtfClassRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfClassRule");
+
+ chainOtfClassRule->backtrackGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->backtrack = ttfMakeUSHORT (chainOtfClassRule->backtrackGlyphCount, fp);
+ chainOtfClassRule->inputGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->input = ttfMakeUSHORT (chainOtfClassRule->inputGlyphCount - 1, fp);
+ chainOtfClassRule->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->lookahead = ttfMakeUSHORT (chainOtfClassRule->lookaheadGlyphCount, fp);
+ chainOtfClassRule->otfCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->otf = makeOtfLookupRecord (chainOtfClassRule->otfCount, fp);
+}
+
+static void
+loadChainOtfClassSet (ChainOtfClassSetPtr chainOtfClassSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfClassSet");
+
+ chainOtfClassSet->chainOtfClassRuleCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (chainOtfClassSet->chainOtfClassRuleCnt, fp);
+ chainOtfClassSet->chainOtfClassRule = XCALLOC (chainOtfClassSet->chainOtfClassRuleCnt, ChainOtfClassRule);
+ for (i = 0; i < chainOtfClassSet->chainOtfClassRuleCnt; i++)
+ loadChainOtfClassRule (&chainOtfClassSet->chainOtfClassRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT bOffset, iOffset, lOffset;
+ USHORT *pOffset;
+ OtfChn2Ptr otf = XCALLOC1 (OtfChn2);
+
+ cOffset = ttfGetUSHORT (fp);
+ bOffset = ttfGetUSHORT (fp);
+ iOffset = ttfGetUSHORT (fp);
+ lOffset = ttfGetUSHORT (fp);
+ otf->chainOtfClassSetCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->chainOtfClassSetCnt, fp);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->backtrackClassDef = otfMakeClassDef (fp, offset + bOffset);
+ otf->inputClassDef = otfMakeClassDef (fp, offset + iOffset);
+ otf->lookaheadClassDef = otfMakeClassDef (fp, offset + lOffset);
+ otf->chainOtfClassSet = XCALLOC (otf->chainOtfClassSetCnt, ChainOtfClassSet);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++)
+ if (pOffset[i])
+ loadChainOtfClassSet (&otf->chainOtfClassSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFChn2 (FILE *fp, OtfChn2Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Class-based\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t backtrackClassDef - ");
+ otfPrintClassDef (fp, otf->backtrackClassDef);
+ fprintf (fp, "\t inputClassDef - ");
+ otfPrintClassDef (fp, otf->inputClassDef);
+ fprintf (fp, "\t lookaheadClassDef - ");
+ otfPrintClassDef (fp, otf->lookaheadClassDef);
+ fprintf (fp, "\t chainOtfClassSetCnt: %d\n", otf->chainOtfClassSetCnt);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. chainOtfClassRuleCnt: %d\n", i,
+ otf->chainOtfClassSet[i].chainOtfClassRuleCnt);
+ for (j = 0; j < otf->chainOtfClassSet[i].chainOtfClassRuleCnt; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. backtrackGlyphCount: %2d ", j,
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrackGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrackGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrack[k]);
+ fprintf (fp, "\n\t\tinputGlyphCount: %2d ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].inputGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].inputGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].input[k]);
+ fprintf (fp, "\n\t\tlookaheadGlyphCount: %2d ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].lookaheadGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].lookaheadGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].lookahead[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].otfCount,
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].otf);
+ }
+ }
+}
+
+void freeOTFChn2 (OtfChn2Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ otfFreeClassDef (otf->backtrackClassDef);
+ otfFreeClassDef (otf->inputClassDef);
+ otfFreeClassDef (otf->lookaheadClassDef);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++) {
+ int j;
+
+ for (j = 0; j < otf->chainOtfClassSet[i].chainOtfClassRuleCnt; j++) {
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrack);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].input);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].lookahead);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].otf);
+ }
+ free (otf->chainOtfClassSet[i].chainOtfClassRule);
+ }
+ free (otf->chainOtfClassSet);
+}
+
+OtfChn3Ptr makeOTFChn3 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *bOffset, *iOffset, *lOffset;
+ OtfChn3Ptr otf = XCALLOC1 (OtfChn3);
+
+ otf->backtrackGlyphCount = ttfGetUSHORT (fp);
+ bOffset = ttfMakeUSHORT (otf->backtrackGlyphCount, fp);
+ otf->inputGlyphCount = ttfGetUSHORT (fp);
+ iOffset = ttfMakeUSHORT (otf->inputGlyphCount, fp);
+ otf->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ lOffset = ttfMakeUSHORT (otf->lookaheadGlyphCount, fp);
+ otf->otfCount = ttfGetUSHORT (fp);
+ otf->otf = makeOtfLookupRecord (otf->otfCount, fp);
+ otf->backtrack = XCALLOC (otf->backtrackGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->backtrackGlyphCount; i++)
+ otf->backtrack[i] = otfMakeCoverage (fp, offset + bOffset[i]);
+ free (bOffset);
+ otf->input = XCALLOC (otf->inputGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->inputGlyphCount; i++)
+ otf->input[i] = otfMakeCoverage (fp, offset + iOffset[i]);
+ free (iOffset);
+ otf->lookahead = XCALLOC (otf->lookaheadGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++)
+ otf->lookahead[i] = otfMakeCoverage (fp, offset + lOffset[i]);
+ free (lOffset);
+
+ return otf;
+}
+
+void printOTFChn3 (FILE *fp, OtfChn3Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Coverage-based\n");
+ fprintf (fp, "\t backtrackGlyphCount: %d\n", otf->backtrackGlyphCount);
+ for (i = 0; i < otf->backtrackGlyphCount; i++) {
+ fprintf (fp, "\t %2d. backtrack", i);
+ otfPrintCoverage (fp, otf->backtrack[i]);
+ }
+ fprintf (fp, "\t inputGlyphCount: %d\n", otf->inputGlyphCount);
+ for (i = 0; i < otf->inputGlyphCount; i++) {
+ fprintf (fp, "\t %2d. input", i);
+ otfPrintCoverage (fp, otf->input[i]);
+ }
+ fprintf (fp, "\t lookaheadGlyphCount: %d\n", otf->lookaheadGlyphCount);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++) {
+ fprintf (fp, "\t %2d. lookahead", i);
+ otfPrintCoverage (fp, otf->lookahead[i]);
+ }
+ printOtfLookupRecord (fp, " ", otf->otfCount, otf->otf);
+}
+
+void freeOTFChn3 (OtfChn3Ptr otf)
+{
+ int i;
+
+ for (i = 0; i < otf->backtrackGlyphCount; i++)
+ otfFreeCoverage (otf->backtrack[i]);
+ free (otf->backtrack);
+ for (i = 0; i < otf->inputGlyphCount; i++)
+ otfFreeCoverage (otf->input[i]);
+ free (otf->input);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++)
+ otfFreeCoverage (otf->lookahead[i]);
+ free (otf->lookahead);
+ free (otf->otf);
+}
+