From d4098ae6af4055044c234a33fc9f42b2e4638999 Mon Sep 17 00:00:00 2001 From: Peter Breitenlohner Date: Tue, 6 Dec 2011 14:44:14 +0000 Subject: ttfdump: Complete the handling of GPOS tables git-svn-id: svn://tug.org/texlive/trunk@24779 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/ttfdump/ChangeLog | 7 +++ Build/source/texk/ttfdump/include/gpos.h | 7 ++- Build/source/texk/ttfdump/libttf/gpos.c | 78 +++++++++++++++++------- Build/source/texk/ttfdump/libttf/otfcommon.c | 90 +++++++++++++++------------- 4 files changed, 116 insertions(+), 66 deletions(-) (limited to 'Build/source/texk/ttfdump') diff --git a/Build/source/texk/ttfdump/ChangeLog b/Build/source/texk/ttfdump/ChangeLog index 9713680022a..b1230a56a66 100644 --- a/Build/source/texk/ttfdump/ChangeLog +++ b/Build/source/texk/ttfdump/ChangeLog @@ -1,3 +1,10 @@ +2011-12-01 Peter Breitenlohner + + * libttf/otfcommon.c: Improved output strings. + + * include/gpos.h, libttf/gpos.c: Support ValueRecords with + device parts (ppem dependent fine tuning). + 2011-12-01 Peter Breitenlohner * include/gpos.h (new): GPOS table format. diff --git a/Build/source/texk/ttfdump/include/gpos.h b/Build/source/texk/ttfdump/include/gpos.h index 23e5bda0846..4f1e72d970a 100644 --- a/Build/source/texk/ttfdump/include/gpos.h +++ b/Build/source/texk/ttfdump/include/gpos.h @@ -32,7 +32,12 @@ typedef struct { SHORT valDesign[4]; - DevicePtr valDevice[4]; + union + { + USHORT offset; + DevicePtr device; + } + valDevice[4]; } ValueRecord, *ValueRecordPtr; diff --git a/Build/source/texk/ttfdump/libttf/gpos.c b/Build/source/texk/ttfdump/libttf/gpos.c index 9d040298099..5ece428e110 100644 --- a/Build/source/texk/ttfdump/libttf/gpos.c +++ b/Build/source/texk/ttfdump/libttf/gpos.c @@ -17,7 +17,7 @@ static USHORT getValueFormat (FILE *fp) } static ValueRecordPtr -gposMakeValueRecord (USHORT valueFormat, FILE *fp, ULONG offset) +gposMakeValueRecord (USHORT valueFormat, FILE *fp) { int i; ValueRecordPtr value; @@ -31,11 +31,23 @@ gposMakeValueRecord (USHORT valueFormat, FILE *fp, ULONG offset) value->valDesign[i] = ttfGetSHORT (fp); for (i = 0; i < 4; i++) if (valueFormat & (ValueFormat_XPlaDevice << i)) - ttfGetUSHORT (fp); + value->valDevice[i].offset = ttfGetUSHORT (fp); return value; } +static void +gposLoadValueRecord (ValueRecordPtr value, FILE *fp, ULONG offset) +{ + int i; + + if (value == NULL) + return; + for (i = 0; i < 4; i++) + if (value->valDevice[i].offset) + value->valDevice[i].device = otfMakeDevice (fp, offset + value->valDevice[i].offset); +} + static const char *txtDesign[4] = { "XPlacement", "YPlacement", @@ -43,6 +55,13 @@ static const char *txtDesign[4] = { "YAdvance" }; +static const char *txtDevice[4] = { + "XPlaDevice", + "YPlaDevice", + "XAdvDevice", + "YAdvDevice" +}; + static void gposPrintValueRecord (FILE *fp, const char *str, USHORT valueFormat, ValueRecordPtr value) { @@ -54,8 +73,12 @@ gposPrintValueRecord (FILE *fp, const char *str, USHORT valueFormat, ValueRecord fprintf (fp, "%s %s = %d\n", s, txtDesign[i], value->valDesign[i]); s = str; } - if (valueFormat & ValueFormat_AllDevice) - fprintf (fp, "\t\t *** Device Table NOT YET IMPLEMENTED ***\n"); + for (i = 0; i < 4; i++) + if (value->valDevice[i].device) { + fprintf (fp, "%s %s:", s, txtDevice[i]); + otfPrintDevice (fp, value->valDevice[i].device); + s = str; + } } static void freeValueRecord (ValueRecordPtr value) @@ -64,8 +87,8 @@ static void freeValueRecord (ValueRecordPtr value) int i; for (i = 0; i < 4; i++) - if (value->valDevice[i]) - free (value->valDevice[i]); + if (value->valDevice[i].device) + free (value->valDevice[i].device); free (value); } } @@ -214,8 +237,9 @@ static Pos11Ptr makeGPOS11 (FILE *fp, ULONG offset) cOffset = ttfGetUSHORT (fp); pos->valueFormat = getValueFormat (fp); - pos->value = gposMakeValueRecord (pos->valueFormat, fp, offset); + pos->value = gposMakeValueRecord (pos->valueFormat, fp); pos->coverage = otfMakeCoverage (fp, offset + cOffset); + gposLoadValueRecord (pos->value, fp, offset); return pos; } @@ -248,8 +272,10 @@ static Pos12Ptr makeGPOS12 (FILE *fp, ULONG offset) pos->valueCount = ttfGetUSHORT (fp); pos->value = XCALLOC (pos->valueCount, ValueRecordPtr); for (i = 0; i < pos->valueCount; i++) - pos->value[i] = gposMakeValueRecord (pos->valueFormat, fp, offset); + pos->value[i] = gposMakeValueRecord (pos->valueFormat, fp); pos->coverage = otfMakeCoverage (fp, offset + cOffset); + for (i = 0; i < pos->valueCount; i++) + gposLoadValueRecord (pos->value[i], fp, offset); return pos; } @@ -277,19 +303,19 @@ static void freeGPOS12 (Pos12Ptr pos) otfFreeCoverage (pos->coverage); } -static void gposLoadPairSet (Pos21Ptr pos, int i, FILE *fp, ULONG offset, USHORT poff) +static void gposLoadPairSet (Pos21Ptr pos, int i, FILE *fp, ULONG offset) { int j; PairSetPtr pairSet = &pos->pairSet[i]; - xfseek (fp, offset + poff, SEEK_SET, "gposLoadPairSet"); + xfseek (fp, offset, SEEK_SET, "gposLoadPairSet"); pairSet->pairValueCount = ttfGetUSHORT (fp); pairSet->pairValue = XCALLOC (pairSet->pairValueCount, PairValueRecord); for (j = 0; j < pairSet->pairValueCount; j++) { pairSet->pairValue[j].secondGlyph = ttfGetUSHORT (fp); - pairSet->pairValue[j].value1 = gposMakeValueRecord (pos->valueFormat1, fp, offset); - pairSet->pairValue[j].value2 = gposMakeValueRecord (pos->valueFormat2, fp, offset); + pairSet->pairValue[j].value1 = gposMakeValueRecord (pos->valueFormat1, fp); + pairSet->pairValue[j].value2 = gposMakeValueRecord (pos->valueFormat2, fp); } } @@ -308,8 +334,16 @@ static Pos21Ptr makeGPOS21 (FILE *fp, ULONG offset) pos->coverage = otfMakeCoverage (fp, offset + cOffset); pos->pairSet = XCALLOC (pos->pairSetCount, PairSet); for (i = 0; i < pos->pairSetCount; i++) - gposLoadPairSet (pos, i, fp, offset, pOffset[i]); + gposLoadPairSet (pos, i, fp, offset + pOffset[i]); free (pOffset); + for (i = 0; i < pos->pairSetCount; i++) { + int j; + + for (j = 0; j < pos->pairSet[i].pairValueCount; j++) { + gposLoadValueRecord (pos->pairSet[i].pairValue[j].value1, fp, offset); + gposLoadValueRecord (pos->pairSet[i].pairValue[j].value2, fp, offset); + } + } return pos; } @@ -324,6 +358,7 @@ static void printGPOS21 (FILE *fp, Pos21Ptr pos) pos->valueFormat1, pos->valueFormat2, pos->pairSetCount); for (i = 0; i < pos->pairSetCount; i++) { int j; + fprintf (fp, "\t %2d. pairValueCount: %d\n", i, pos->pairSet[i].pairValueCount); for (j = 0; j < pos->pairSet[i].pairValueCount; j++) { fprintf (fp, "\t %2d. secondGlyph: %d\n", j, @@ -360,7 +395,7 @@ static void freeGPOS21 (Pos21Ptr pos) static Pos22Ptr makeGPOS22 (FILE *fp, ULONG offset) { - int num = 0, i; + int i; USHORT cOffset, cOffset1, cOffset2; Pos22Ptr pos = XCALLOC1 (Pos22); @@ -372,24 +407,20 @@ static Pos22Ptr makeGPOS22 (FILE *fp, ULONG offset) pos->class1Count = ttfGetUSHORT (fp); pos->class2Count = ttfGetUSHORT (fp); pos->values = XCALLOC (2 * pos->class1Count * pos->class2Count, ValueRecordPtr); - for (i = 0; i < pos->class1Count; i++) { - int j; - - for (j = 0; j < pos->class2Count; j++) { - pos->values[num++] = gposMakeValueRecord (pos->valueFormat1, fp, offset); - pos->values[num++] = gposMakeValueRecord (pos->valueFormat2, fp, offset); - } - } + for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++) + pos->values[i] = gposMakeValueRecord (i & 1 ? pos->valueFormat2 : pos->valueFormat1, fp); pos->coverage = otfMakeCoverage (fp, offset + cOffset); pos->classDef1 = otfMakeClassDef (fp, offset + cOffset1); pos->classDef2 = otfMakeClassDef (fp, offset + cOffset2); + for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++) + gposLoadValueRecord (pos->values[i], fp, offset); return pos; } static void printGPOS22 (FILE *fp, Pos22Ptr pos) { - int num = 0, i; + int i, num = 0; fprintf (fp, " - Pair Adjustment Class\n\t "); otfPrintCoverage (fp, pos->coverage); @@ -461,6 +492,7 @@ static Pos31Ptr makeGPOS31 (FILE *fp, ULONG offset) static void printGPOS31 (FILE *fp, Pos31Ptr pos) { int i, num = 0; + fprintf (fp, " - Cursive Attachment\n\t "); otfPrintCoverage (fp, pos->coverage); fprintf (fp, "\t entryExitCount: %d\n", pos->entryExitCount); diff --git a/Build/source/texk/ttfdump/libttf/otfcommon.c b/Build/source/texk/ttfdump/libttf/otfcommon.c index 8102aae6ab5..4642e73196a 100644 --- a/Build/source/texk/ttfdump/libttf/otfcommon.c +++ b/Build/source/texk/ttfdump/libttf/otfcommon.c @@ -566,33 +566,33 @@ static void loadOtfRule (OtfRulePtr otfRule, FILE *fp, ULONG offset) static void loadOtfRuleSet (OtfRuleSetPtr otfRuleSet, FILE *fp, ULONG offset) { int i; - USHORT *pOffset; + USHORT *rOffset; xfseek (fp, offset, SEEK_SET, "loadOtfRuleSet"); otfRuleSet->otfRuleCount = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otfRuleSet->otfRuleCount, fp); + rOffset = 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); + loadOtfRule (&otfRuleSet->otfRule[i], fp, offset + rOffset[i]); + free (rOffset); } OtfCtx1Ptr makeOTFCtx1 (FILE *fp, ULONG offset) { int i; USHORT cOffset; - USHORT *pOffset; + USHORT *rOffset; OtfCtx1Ptr otf = XCALLOC1 (OtfCtx1); cOffset = ttfGetUSHORT (fp); otf->otfRuleSetCount = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otf->otfRuleSetCount, fp); + rOffset = 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); + loadOtfRuleSet (&otf->otfRuleSet[i], fp, offset + rOffset[i]); + free (rOffset); return otf; } @@ -601,7 +601,8 @@ void printOTFCtx1 (FILE *fp, OtfCtx1Ptr otf) { int i; - fprintf (fp, " - Context Simple\n\t "); + fprintf (fp, " - Context %s Simple\n\t ", + otf->lookupType == 7 ? "Positioning" : "Substitution"); otfPrintCoverage (fp, otf->coverage); fprintf (fp, "\t otfRuleSetCount: %d\n", otf->otfRuleSetCount); for (i = 0; i < otf->otfRuleSetCount; i++) { @@ -611,7 +612,7 @@ void printOTFCtx1 (FILE *fp, OtfCtx1Ptr otf) for (j = 0; j < otf->otfRuleSet[i].otfRuleCount; j++) { int k; - fprintf (fp, "\t %2d. glyphtCount: %d ", j, + fprintf (fp, "\t %2d. glyphCount: %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]); @@ -653,16 +654,16 @@ static void loadOtfClassRule (OtfClassRulePtr otfClassRule, FILE *fp, ULONG offs static void loadOtfClassSet (OtfClassSetPtr otfClassSet, FILE *fp, ULONG offset) { int i; - USHORT *pOffset; + USHORT *sOffset; xfseek (fp, offset, SEEK_SET, "loadOtfClassSet"); otfClassSet->otfClassRuleCnt = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otfClassSet->otfClassRuleCnt, fp); + sOffset = 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); + loadOtfClassRule (&otfClassSet->otfClassRule[i], fp, offset + sOffset[i]); + free (sOffset); } OtfCtx2Ptr makeOTFCtx2 (FILE *fp, ULONG offset) @@ -670,20 +671,20 @@ OtfCtx2Ptr makeOTFCtx2 (FILE *fp, ULONG offset) int i; USHORT cOffset; USHORT clOffset; - USHORT *pOffset; + USHORT *sOffset; OtfCtx2Ptr otf = XCALLOC1 (OtfCtx2); cOffset = ttfGetUSHORT (fp); clOffset = ttfGetUSHORT (fp); otf->otfClassSetCnt = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otf->otfClassSetCnt, fp); + sOffset = 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); + if (sOffset[i]) + loadOtfClassSet (&otf->otfClassSet[i], fp, offset + sOffset[i]); + free (sOffset); return otf; } @@ -692,7 +693,8 @@ void printOTFCtx2 (FILE *fp, OtfCtx2Ptr otf) { int i; - fprintf (fp, " - Context Class-based\n\t "); + fprintf (fp, " - Context %s Class-based\n\t ", + otf->lookupType == 7 ? "Positioning" : "Substitution"); otfPrintCoverage (fp, otf->coverage); fprintf (fp, "\t ClassDef - "); otfPrintClassDef (fp, otf->classDef); @@ -704,7 +706,7 @@ void printOTFCtx2 (FILE *fp, OtfCtx2Ptr otf) for (j = 0; j < otf->otfClassSet[i].otfClassRuleCnt; j++) { int k; - fprintf (fp, "\t %2d. glyphtCount: %d ", j, + fprintf (fp, "\t %2d. glyphCount: %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]); @@ -756,7 +758,8 @@ void printOTFCtx3 (FILE *fp, OtfCtx3Ptr otf) { int i; - fprintf (fp, " - Context Coverage-based\n"); + fprintf (fp, " - Context %s Coverage-based\n", + otf->lookupType == 7 ? "Positioning" : "Substitution"); fprintf (fp, "\t glyphCount: %d\n", otf->glyphCount); for (i = 0; i < otf->glyphCount; i++) { fprintf (fp, "\t %2d. ", i); @@ -794,33 +797,33 @@ static void loadChainOtfRuleSet (ChainOtfRuleSetPtr chainOtfRuleSet, FILE *fp, ULONG offset) { int i; - USHORT *pOffset; + USHORT *rOffset; xfseek (fp, offset, SEEK_SET, "loadChainOtfRuleSet"); chainOtfRuleSet->chainOtfRuleCount = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (chainOtfRuleSet->chainOtfRuleCount, fp); + rOffset = 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); + loadChainOtfRule (&chainOtfRuleSet->chainOtfRule[i], fp, offset + rOffset[i]); + free (rOffset); } OtfChn1Ptr makeOTFChn1 (FILE *fp, ULONG offset) { int i; USHORT cOffset; - USHORT *pOffset; + USHORT *rOffset; OtfChn1Ptr otf = XCALLOC1 (OtfChn1); cOffset = ttfGetUSHORT (fp); otf->chainOtfRuleSetCount = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otf->chainOtfRuleSetCount, fp); + rOffset = 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); + loadChainOtfRuleSet (&otf->chainOtfRuleSet[i], fp, offset + rOffset[i]); + free (rOffset); return otf; } @@ -829,7 +832,8 @@ void printOTFChn1 (FILE *fp, OtfChn1Ptr otf) { int i; - fprintf (fp, " - Chained Context Simple\n\t "); + fprintf (fp, " - Chained Context %s Simple\n\t ", + otf->lookupType == 8 ? "Positioning" : "Substitution"); otfPrintCoverage (fp, otf->coverage); fprintf (fp, "\t chainOtfRuleSetCount: %d\n", otf->chainOtfRuleSetCount); for (i = 0; i < otf->chainOtfRuleSetCount; i++) { @@ -898,16 +902,16 @@ static void loadChainOtfClassSet (ChainOtfClassSetPtr chainOtfClassSet, FILE *fp, ULONG offset) { int i; - USHORT *pOffset; + USHORT *rOffset; xfseek (fp, offset, SEEK_SET, "loadChainOtfClassSet"); chainOtfClassSet->chainOtfClassRuleCnt = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (chainOtfClassSet->chainOtfClassRuleCnt, fp); + rOffset = 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); + loadChainOtfClassRule (&chainOtfClassSet->chainOtfClassRule[i], fp, offset + rOffset[i]); + free (rOffset); } OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset) @@ -915,7 +919,7 @@ OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset) int i; USHORT cOffset; USHORT bOffset, iOffset, lOffset; - USHORT *pOffset; + USHORT *sOffset; OtfChn2Ptr otf = XCALLOC1 (OtfChn2); cOffset = ttfGetUSHORT (fp); @@ -923,16 +927,16 @@ OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset) iOffset = ttfGetUSHORT (fp); lOffset = ttfGetUSHORT (fp); otf->chainOtfClassSetCnt = ttfGetUSHORT (fp); - pOffset = ttfMakeUSHORT (otf->chainOtfClassSetCnt, fp); + sOffset = 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); + if (sOffset[i]) + loadChainOtfClassSet (&otf->chainOtfClassSet[i], fp, offset + sOffset[i]); + free (sOffset); return otf; } @@ -941,7 +945,8 @@ void printOTFChn2 (FILE *fp, OtfChn2Ptr otf) { int i; - fprintf (fp, " - Chained Context Class-based\n\t "); + fprintf (fp, " - Chained Context %s Class-based\n\t ", + otf->lookupType == 8 ? "Positioning" : "Substitution"); otfPrintCoverage (fp, otf->coverage); fprintf (fp, "\t backtrackClassDef - "); otfPrintClassDef (fp, otf->backtrackClassDef); @@ -1037,7 +1042,8 @@ void printOTFChn3 (FILE *fp, OtfChn3Ptr otf) { int i; - fprintf (fp, " - Chained Context Coverage-based\n"); + fprintf (fp, " - Chained Context %s Coverage-based\n", + otf->lookupType == 8 ? "Positioning" : "Substitution"); fprintf (fp, "\t backtrackGlyphCount: %d\n", otf->backtrackGlyphCount); for (i = 0; i < otf->backtrackGlyphCount; i++) { fprintf (fp, "\t %2d. backtrack", i); -- cgit v1.2.3