diff options
Diffstat (limited to 'Build/source/texk/ttfdump/libttf/cmap.c')
-rw-r--r-- | Build/source/texk/ttfdump/libttf/cmap.c | 1091 |
1 files changed, 702 insertions, 389 deletions
diff --git a/Build/source/texk/ttfdump/libttf/cmap.c b/Build/source/texk/ttfdump/libttf/cmap.c index d876cfb8a96..c3ae65f3b61 100644 --- a/Build/source/texk/ttfdump/libttf/cmap.c +++ b/Build/source/texk/ttfdump/libttf/cmap.c @@ -54,32 +54,56 @@ typedef union _TwoBytes { unsigned char c[2]; } TwoBytes; -static void ttfLoadCMAP(FILE *fp,CMAPPtr cmap,ULONG offset); - -static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfPrintSubTable(FILE* fp,SubTablePtr ptable); -static void ttfFreeSubTable(SubTablePtr ptable); - -static void ttfLoadCMAP0(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfPrintCMAP0(FILE *fp,SubTablePtr subTable); -static USHORT ttfLookUpCMAP0(SubTablePtr subTable,USHORT cc); -static void ttfFreeCMAP0(SubTablePtr subTable); - -static void ttfLoadCMAP2(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfPrintCMAP2(FILE *fp,SubTablePtr subTable); -static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc); -static void ttfFreeCMAP2(SubTablePtr subTable); - -static void ttfLoadCMAP4(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfPrintCMAP4(FILE *fp,SubTablePtr subTable); -static USHORT ttfLookUpCMAP4(SubTablePtr subTable,USHORT cc); -static void ttfFreeCMAP4(SubTablePtr subTable); - -static void ttfLoadCMAP6(FILE *fp,SubTablePtr subTable,ULONG offset); -static void ttfPrintCMAP6(FILE *fp, SubTablePtr sbuTable); -static USHORT ttfLookUpCMAP6(SubTablePtr subTable,USHORT cc); -static void ttfFreeCMAP6(SubTablePtr subTable); +static void ttfLoadCMAP(FILE *fp, CMAPPtr cmap, ULONG offset); + +static void ttfLoadSubTable(FILE *fp, SubTablePtr subTable, ULONG offset); +static void ttfPrintSubTable(FILE* fp, SubTablePtr subTable); +static void ttfFreeSubTable(SubTablePtr subTable); + +static void ttfLoadCMAP0(FILE *fp, MapPtr *map); +static void ttfPrintCMAP0(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP0(MapPtr map, USHORT cc); +static void ttfFreeCMAP0(MapPtr map); + +static void ttfLoadCMAP2(FILE *fp, MapPtr *map); +static void ttfPrintCMAP2(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP2(MapPtr map, USHORT cc); +static void ttfFreeCMAP2(MapPtr map); + +static void ttfLoadCMAP4(FILE *fp, MapPtr *map); +static void ttfPrintCMAP4(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP4(MapPtr map, USHORT cc); +static void ttfFreeCMAP4(MapPtr map); + +static void ttfLoadCMAP6(FILE *fp, MapPtr *map); +static void ttfPrintCMAP6(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP6(MapPtr map, USHORT cc); +static void ttfFreeCMAP6(MapPtr map); + +static void ttfLoadCMAP8(FILE *fp, MapPtr *map); +static void ttfPrintCMAP8(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP8(MapPtr map, ULONG cc); +static void ttfFreeCMAP8(MapPtr map); + +static void ttfLoadCMAP10(FILE *fp, MapPtr *map); +static void ttfPrintCMAP10(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP10(MapPtr map, ULONG cc); +static void ttfFreeCMAP10(MapPtr map); + +static void ttfLoadCMAP12(FILE *fp, MapPtr *map); +static void ttfPrintCMAP12(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP12(MapPtr map, ULONG cc); +static void ttfFreeCMAP12(MapPtr map); + +static void ttfLoadCMAP13(FILE *fp, MapPtr *map); +static void ttfPrintCMAP13(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP13(MapPtr map, ULONG cc); +static void ttfFreeCMAP13(MapPtr map); + +static void ttfLoadCMAP14(FILE *fp, MapPtr *map); +static void ttfPrintCMAP14(FILE *fp, MapPtr map); +static USHORT ttfLookUpCMAP14(MapPtr map, ULONG cc); +static void ttfFreeCMAP14(MapPtr map); void ttfInitCMAP(TTFontPtr font) { @@ -87,34 +111,47 @@ void ttfInitCMAP(TTFontPtr font) TableDirPtr ptd; if ((ptd = ttfLookUpTableDir(tag,font)) != NULL) - { - font->cmap = XCALLOC1 (CMAP); - ttfLoadCMAP(font->fp,font->cmap,ptd->offset); - } + { + font->cmap = XCALLOC1 (CMAP); + ttfLoadCMAP(font->fp,font->cmap,ptd->offset); + } } static void ttfLoadCMAP(FILE *fp,CMAPPtr cmap,ULONG offset) { USHORT i,n; - ULONG posEnc; /* beginning of the Encoding Table */ - ULONG baseSub = offset; /* base of SubTable offset */ + int k = 0; xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP"); cmap->version = ttfGetUSHORT(fp); cmap->numberOfEncodings = n = ttfGetUSHORT(fp); - cmap->subTables = XCALLOC (cmap->numberOfEncodings, SubTable); - - posEnc = baseSub + sizeof(USHORT)*2; /* step over the beginning of encoding - * table */ - - /* for each encoding scheme, load the encoding table (EncodingTable) and - * the real cmap data (SubTable) */ - for (i=0;i<n;i++,posEnc += 8) - { /* 8 == ushort*2 + ulong*1 */ - ttfLoadEncodingTable(fp,cmap->subTables+i,posEnc); - ttfLoadSubTable(fp,cmap->subTables+i,baseSub); - } + cmap->encoding = XCALLOC (cmap->numberOfEncodings, Encoding); + + for (i = 0; i < n; i++) + { + int j; + + cmap->encoding[i].PlatformID = ttfGetUSHORT(fp); + cmap->encoding[i].EncodingID = ttfGetUSHORT(fp); + cmap->encoding[i].offset = ttfGetULONG(fp); + cmap->encoding[i].mapindex = k++; + for (j = 0; j < i; j++) { + if (cmap->encoding[i].offset == cmap->encoding[j].offset) + { + cmap->encoding[i].mapindex = cmap->encoding[j].mapindex; + k--; + break; + + } + } + } + cmap->numberOfMaps = k; + cmap->subTable = XCALLOC (cmap->numberOfMaps, SubTable); + for (i = 0; i < n; i++) + cmap->subTable[cmap->encoding[i].mapindex].offset = cmap->encoding[i].offset; + for (i = 0; i < k; i++) + ttfLoadSubTable(fp, cmap->subTable+i, offset); } void ttfPrintCMAP(FILE *fp,CMAPPtr cmap) { @@ -122,75 +159,79 @@ void ttfPrintCMAP(FILE *fp,CMAPPtr cmap) fprintf(fp,"'cmap' Table - Character to Glyph Index Mapping Table\n"); fprintf(fp,"-----------------------------------------------------\n"); - fprintf(fp,"\t 'cmap' version: %d\n",cmap->version); - fprintf(fp,"\t number of encoding: %d\n\n",cmap->numberOfEncodings); - - for (i=0;i<cmap->numberOfEncodings;i++) - { - fprintf(fp,"Subtable %3d.\t",i); - ttfPrintSubTable(fp,cmap->subTables+i); - fprintf(fp,"\n"); - } + fprintf(fp,"\t 'cmap' version: %d\n", cmap->version); + fprintf(fp,"\t number of encodings: %d\n", cmap->numberOfEncodings); + fprintf(fp,"\t number of subtables: %d\n\n", cmap->numberOfMaps); + + for (i = 0; i < cmap->numberOfEncodings; i++) + { + fprintf(fp, "Encoding %3d.\t PlatformID: %2d\n", i, + cmap->encoding[i].PlatformID); + fprintf(fp, "\t\t EcodingID: %2d\n", + cmap->encoding[i].EncodingID); + fprintf(fp, "\t\t SubTable: %d, Offset: 0x%08x\n\n", + cmap->encoding[i].mapindex, cmap->encoding[i].offset); + } + for (i = 0; i < cmap->numberOfMaps; i++) + { + fprintf(fp,"SubTable %3d.\t",i); + ttfPrintSubTable(fp, cmap->subTable+i); + fprintf(fp,"\n"); + } } -USHORT ttfLookUpCMAP(SubTablePtr subTable,USHORT cc) +USHORT ttfLookUpCMAP(MapPtr map, USHORT cc) { - USHORT idx,format = subTable->format; + USHORT idx,format = *map.format; switch (format) - { - case 0: - idx = ttfLookUpCMAP0(subTable,cc); - break; - case 2: - idx = ttfLookUpCMAP2(subTable,cc); - break; - case 4: - idx = ttfLookUpCMAP4(subTable,cc); - break; - case 6: - idx = ttfLookUpCMAP6(subTable,cc); - break; - default: - ttfError("Unrecognized CMAP format\n"); - return 0; - } + { + case 0: + idx = ttfLookUpCMAP0(map, cc); + break; + case 2: + idx = ttfLookUpCMAP2(map, cc); + break; + case 4: + idx = ttfLookUpCMAP4(map, cc); + break; + case 6: + idx = ttfLookUpCMAP6(map, cc); + break; + case 8: + idx = ttfLookUpCMAP8(map, cc); + break; + case 10: + idx = ttfLookUpCMAP10(map, cc); + break; + case 12: + idx = ttfLookUpCMAP12(map, cc); + break; + case 13: + idx = ttfLookUpCMAP13(map, cc); + break; + case 14: + idx = ttfLookUpCMAP14(map, cc); + break; + default: + ttfError("Unrecognized CMAP format\n"); + return 0; + } return idx; } -SubTablePtr ttfSelectCMAP(CMAPPtr cmap, USHORT PlatformID, USHORT EncodingID) -{ - USHORT i; - - for (i=0;i<cmap->numberOfEncodings;i++) - { - if ((cmap->subTables+i)->PlatformID == PlatformID && - (cmap->subTables+i)->EncodingID == EncodingID) - return cmap->subTables+i; - } - return NULL; -} void ttfFreeCMAP(CMAPPtr cmap) { USHORT i; - for (i=0;i<cmap->numberOfEncodings;i++) - ttfFreeSubTable(cmap->subTables+i); + free(cmap->encoding); - free(cmap->subTables); - free(cmap); -} + for (i = 0; i < cmap->numberOfMaps; i++) + ttfFreeSubTable(cmap->subTable+i); + free(cmap->subTable); -/* actually, EncodingTable is a part of SubTable */ -static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset) -{ - xfseek(fp, offset, SEEK_SET, "ttfLoadEncodingTable"); - - subTable->PlatformID = ttfGetUSHORT(fp); - subTable->EncodingID = ttfGetUSHORT(fp); - subTable->offset = ttfGetULONG(fp); + free(cmap); } -/* should this one be static ? */ -static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG base) +static void ttfLoadSubTable(FILE *fp, SubTablePtr subTable, ULONG offset) { ULONG pos; USHORT format; @@ -198,239 +239,275 @@ static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG base) /* seek to the actuall position for this subtable * base: beginning of cmap * offset: offset field of each encoding table */ - pos = base + subTable->offset; - xfseek(fp, pos, SEEK_SET, "ttfLoadSubTable"); + pos = offset + subTable->offset; + xfseek(fp, pos, SEEK_SET, "ttfLoadEncoding"); - subTable->format = format = ttfGetUSHORT(fp); - subTable->length = ttfGetUSHORT(fp); - subTable->version = ttfGetUSHORT(fp); + format = ttfGetUSHORT(fp); - pos += 6;/* step over format independent data,USHORT*3 */ - switch(format) - { - case 0: - ttfLoadCMAP0(fp,subTable,pos); - break; - case 2: - ttfLoadCMAP2(fp,subTable,pos); - break; - case 4: - ttfLoadCMAP4(fp,subTable,pos); - break; - case 6: - ttfLoadCMAP6(fp,subTable,pos); - break; - default: - ttfError("Unrecognized CMAP format\n"); - } -} -static void ttfPrintSubTable(FILE* fp,SubTablePtr ptable) -{ - USHORT format = ptable->format; - - /* print encoding table */ - fprintf(fp, " PlatformID: %2d\n",ptable->PlatformID); - fprintf(fp,"\t\t EcodingID: %2d\n",ptable->EncodingID); - fprintf(fp,"\t\t 'cmap' Offset: 0x%08x\n",ptable->offset); + { + case 0: + ttfLoadCMAP0(fp, &subTable->map); + break; + case 2: + ttfLoadCMAP2(fp, &subTable->map); + break; + case 4: + ttfLoadCMAP4(fp, &subTable->map); + break; + case 6: + ttfLoadCMAP6(fp, &subTable->map); + break; + case 8: + ttfLoadCMAP8(fp, &subTable->map); + break; + case 10: + ttfLoadCMAP10(fp, &subTable->map); + break; + case 12: + ttfLoadCMAP12(fp, &subTable->map); + break; + case 13: + ttfLoadCMAP13(fp, &subTable->map); + break; + case 14: + ttfLoadCMAP14(fp, &subTable->map); + break; + default: + ttfError("Unrecognized CMAP format\n"); + } + + *subTable->map.format = format; +} +static void ttfPrintSubTable(FILE* fp, SubTablePtr subTable) +{ + USHORT format = *subTable->map.format; - /* print SubTable part */ - fprintf(fp,"\t\t Length: %6d\n",ptable->length); - fprintf(fp,"\t\t Version: %6d\n",ptable->version); - switch(format) - { - case 0: - fprintf(fp,"\t\t Format 0 - Byte encoding table\n"); - ttfPrintCMAP0(fp,ptable); - break; - case 2: - fprintf(fp,"\t\t Format 2 - High-byte mapping through table\n"); - ttfPrintCMAP2(fp,ptable); - break; - case 4: - fprintf(fp,"\t\t Format 4 - Segment mapping to delta values\n"); - ttfPrintCMAP4(fp,ptable); - break; - case 6: - fprintf(fp,"\t\t Format 6 - Trimmed table mapping\n"); - ttfPrintCMAP6(fp,ptable); - break; - default: - ttfError("Unrecognized CMAP format\n"); - } -} -static void ttfFreeSubTable(SubTablePtr ptable) -{ - USHORT format = ptable->format; + { + case 0: + ttfPrintCMAP0(fp, subTable->map); + break; + case 2: + ttfPrintCMAP2(fp, subTable->map); + break; + case 4: + ttfPrintCMAP4(fp, subTable->map); + break; + case 6: + ttfPrintCMAP6(fp, subTable->map); + break; + case 8: + ttfPrintCMAP8(fp, subTable->map); + break; + case 10: + ttfPrintCMAP10(fp, subTable->map); + break; + case 12: + ttfPrintCMAP12(fp, subTable->map); + break; + case 13: + ttfPrintCMAP13(fp, subTable->map); + break; + case 14: + ttfPrintCMAP14(fp, subTable->map); + break; + default: + ttfError("Unrecognized CMAP format\n"); + } +} +static void ttfFreeSubTable(SubTablePtr subTable) +{ + USHORT format = *subTable->map.format; switch(format) - { - case 0: - ttfFreeCMAP0(ptable); - break; - case 2: - ttfFreeCMAP2(ptable); - break; - case 4: - ttfFreeCMAP4(ptable); - break; - case 6: - ttfFreeCMAP6(ptable); - break; - } -} - -static void ttfLoadCMAP0(FILE *fp,SubTablePtr subTable,ULONG offset) + { + case 0: + ttfFreeCMAP0(subTable->map); + break; + case 2: + ttfFreeCMAP2(subTable->map); + break; + case 4: + ttfFreeCMAP4(subTable->map); + break; + case 6: + ttfFreeCMAP6(subTable->map); + break; + case 8: + ttfFreeCMAP8(subTable->map); + break; + case 10: + ttfFreeCMAP10(subTable->map); + break; + case 12: + ttfFreeCMAP12(subTable->map); + break; + case 13: + ttfFreeCMAP13(subTable->map); + break; + case 14: + ttfFreeCMAP14(subTable->map); + break; + } +} + +static void ttfLoadCMAP0(FILE *fp, MapPtr *map) { BYTE * array; - subTable->map.cmap0 = XCALLOC1 (CMAP0); - array = subTable->map.cmap0->glyphIndexArray; - - xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP0"); + map->cmap0 = XCALLOC1 (CMAP0); + map->cmap0->length = ttfGetUSHORT(fp); + map->cmap0->version = ttfGetUSHORT(fp); + array = map->cmap0->glyphIndexArray; /* Attention: we get lots of bytes at once as a work around of the * usual ttfGet*, this cause byte sex trouble as will be seen - * in the fellowing procedures */ + * in the following procedures */ if (fread(array,sizeof(BYTE),256,fp) != 256) - ttfError("Error when getting glyphIndexArray\n"); + ttfError("Error when getting glyphIndexArray\n"); } -static void ttfPrintCMAP0(FILE *fp,SubTablePtr subTable) +static void ttfPrintCMAP0(FILE *fp, MapPtr map) { USHORT index; int i; + fprintf(fp, " Format 0 - Byte encoding table\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap0->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap0->version); for (i=0;i<256;i++) - { - index = ttfLookUpCMAP(subTable,i); - fprintf(fp,"\t\t Char %3d -> Index %4d\n",i,index); - } + { + index = ttfLookUpCMAP(map, i); + fprintf(fp,"\t\t Char %3d -> Index %4d\n",i,index); + } } -static USHORT ttfLookUpCMAP0(SubTablePtr subTable,USHORT cc) +static USHORT ttfLookUpCMAP0(MapPtr map, USHORT cc) { - return subTable->map.cmap0->glyphIndexArray[cc & 0x00ff]; + return map.cmap0->glyphIndexArray[cc & 0x00ff]; } -static void ttfFreeCMAP0(SubTablePtr subTable) +static void ttfFreeCMAP0(MapPtr map) { - free(subTable->map.cmap0); + free(map.cmap0); } -static void ttfLoadCMAP2(FILE *fp,SubTablePtr subTable,ULONG offset) +static void ttfLoadCMAP2(FILE *fp, MapPtr *map) { USHORT * array,i,n = 0; USHORT numGlyphId; SubHeaderPtr header; - xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP2"); - - subTable->map.cmap2 = XCALLOC1 (CMAP2); - array = subTable->map.cmap2->subHeaderKeys; + map->cmap2 = XCALLOC1 (CMAP2); + map->cmap2->length = ttfGetUSHORT(fp); + map->cmap2->version = ttfGetUSHORT(fp); + array = map->cmap2->subHeaderKeys; ttfReadUSHORT (array, 256, fp); for (i=0;i<256;i++) - { - array[i] /= 8; - if (n< array[i]) - n = array[i]; /* find the max of subHeaderKeys */ - } + { + array[i] /= 8; + if (n< array[i]) + n = array[i]; /* find the max of subHeaderKeys */ + } n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */ - subTable->map.cmap2->subHeaders = header = XCALLOC (n, SubHeader); + map->cmap2->subHeaders = header = XCALLOC (n, SubHeader); for (i=0;i<n;i++) - { - (header+i)->firstCode = ttfGetUSHORT(fp); - (header+i)->entryCount = ttfGetUSHORT(fp); - (header+i)->idDelta = ttfGetSHORT(fp); - (header+i)->idRangeOffset = ttfGetUSHORT(fp); - - /* it makes things easier to let the offset starts from - * the beginning of glyphIndexArray */ - if ((header+i)->idRangeOffset != 0) - (header+i)->idRangeOffset -= (sizeof(USHORT) + - (n-i-1) * sizeof(SubHeader)) ; - } + { + (header+i)->firstCode = ttfGetUSHORT(fp); + (header+i)->entryCount = ttfGetUSHORT(fp); + (header+i)->idDelta = ttfGetSHORT(fp); + (header+i)->idRangeOffset = ttfGetUSHORT(fp); + + /* it makes things easier to let the offset starts from + * the beginning of glyphIndexArray */ + if ((header+i)->idRangeOffset != 0) + (header+i)->idRangeOffset -= (sizeof(USHORT) + + (n-i-1) * sizeof(SubHeader)) ; + } /* caculate the length of glyphIndexArray, this is ugly, there should be * a better way to get this information. */ numGlyphId = - subTable->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader); + map->cmap2->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader); numGlyphId /= sizeof(USHORT); - subTable->map.cmap2->glyphIndexArray = XCALLOC (numGlyphId, USHORT); + map->cmap2->glyphIndexArray = XCALLOC (numGlyphId, USHORT); for (i=0;i<numGlyphId;i++) - { - subTable->map.cmap2->glyphIndexArray[i] = ttfGetUSHORT(fp); - } + { + map->cmap2->glyphIndexArray[i] = ttfGetUSHORT(fp); + } } -static void ttfPrintCMAP2(FILE *fp,SubTablePtr subTable) +static void ttfPrintCMAP2(FILE *fp, MapPtr map) { USHORT i,j,numGlyphId; USHORT *array,n=0,index; SubHeaderPtr header; TwoBytes tb; - array = subTable->map.cmap2->subHeaderKeys; - header = subTable->map.cmap2->subHeaders; + fprintf(fp, " Format 2 - High-byte mapping through table\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap2->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap2->version); + array = map.cmap2->subHeaderKeys; + header = map.cmap2->subHeaders; for (i=0;i<256;i++) - { - /* find the number of subHeader */ - if (n< array[i]) - n = array[i]; - fprintf(fp,"\t\t subHeaderKeys[%d] = %d\n",i,array[i]); - } + { + /* find the number of subHeader */ + if (n< array[i]) + n = array[i]; + fprintf(fp,"\t\t subHeaderKeys[%d] = %d\n",i,array[i]); + } n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */ fprintf(fp,"\t\t Number of SubHeaders is %d\n",n); for (i=0;i<=n;i++) - { - fprintf(fp,"\t\t SubHeader[%d]\n",i); - fprintf(fp,"\t\t firstCode \t 0x%04x\n",(header+i)->firstCode); - fprintf(fp,"\t\t entryCount \t %d\n",(header+i)->entryCount); - fprintf(fp,"\t\t idDelta \t %d\n",(header+i)->idDelta); - fprintf(fp,"\t\t idRangeOffset \t 0x%04x\n\n", - (header+i)->idRangeOffset); - } + { + fprintf(fp,"\t\t SubHeader[%d]\n",i); + fprintf(fp,"\t\t firstCode \t 0x%04x\n",(header+i)->firstCode); + fprintf(fp,"\t\t entryCount \t %d\n",(header+i)->entryCount); + fprintf(fp,"\t\t idDelta \t %d\n",(header+i)->idDelta); + fprintf(fp,"\t\t idRangeOffset \t 0x%04x\n\n", + (header+i)->idRangeOffset); + } /* caculate the length of glyphIndexArray, this is ugly, there should be * a better way to get this information. */ numGlyphId = - subTable->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader); + map.cmap2->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader); numGlyphId /= sizeof(USHORT); fprintf(fp,"Number of glyphIndex: %d\n", numGlyphId); for (i=0;i<numGlyphId;i++) - { - fprintf(fp,"\t\t glyphIdArray[%d] = %4d\n",i, - subTable->map.cmap2->glyphIndexArray[i]); - } + { + fprintf(fp,"\t\t glyphIdArray[%d] = %4d\n",i, + map.cmap2->glyphIndexArray[i]); + } i = 0; fprintf(fp,"\t\t First Byte:\t %2x\n",i); tb.c[1] = i; for(j=0;j<=255;j++) - { - tb.c[0] = j; - index = ttfLookUpCMAP2(subTable,tb.u); - fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index); - } + { + tb.c[0] = j; + index = ttfLookUpCMAP2(map, tb.u); + fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index); + } for (i=128;i<=255;i++) - { - fprintf(fp,"\t\t First Byte:\t %2x\n",i); - tb.c[1] = i; - for(j=0;j<=255;j++) - { - tb.c[0] = j; - index = ttfLookUpCMAP2(subTable,tb.u); - fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index); - } - } -} -static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc) + { + fprintf(fp,"\t\t First Byte:\t %2x\n",i); + tb.c[1] = i; + for(j=0;j<=255;j++) + { + tb.c[0] = j; + index = ttfLookUpCMAP2(map, tb.u); + fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index); + } + } +} +static USHORT ttfLookUpCMAP2(MapPtr map, USHORT cc) { USHORT index,idx = 0; - USHORT *array = subTable->map.cmap2->subHeaderKeys; - SubHeaderPtr headers = subTable->map.cmap2->subHeaders; + USHORT *array = map.cmap2->subHeaderKeys; + SubHeaderPtr headers = map.cmap2->subHeaders; SHORT idDelta; USHORT firstCode, entryCount, idRangeOffset; TwoBytes tb; @@ -459,195 +536,431 @@ static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc) idRangeOffset = (headers+idx)->idRangeOffset / sizeof (USHORT); if (second >= firstCode && second < firstCode+entryCount) - { - /* use idRangeOffset to find where in the glyphIndexArray - * the correspinding index is */ - idRangeOffset += (second - firstCode); - index = subTable->map.cmap2->glyphIndexArray[idRangeOffset]; - if (index != 0) - /* if the character is not a missing character then - * add idDelta to it */ - index += idDelta; - } + { + /* use idRangeOffset to find where in the glyphIndexArray + * the correspinding index is */ + idRangeOffset += (second - firstCode); + index = map.cmap2->glyphIndexArray[idRangeOffset]; + if (index != 0) + /* if the character is not a missing character then + * add idDelta to it */ + index += idDelta; + } else - /* The second code is out ranged then return the - * missing glyph character */ - index = 0; - + /* The second code is out ranged then return the + * missing glyph character */ + index = 0; + return index; } -static void ttfFreeCMAP2(SubTablePtr subTable) +static void ttfFreeCMAP2(MapPtr map) { - free(subTable->map.cmap2->subHeaders); - free(subTable->map.cmap2->glyphIndexArray); - free(subTable->map.cmap2); + free(map.cmap2->subHeaders); + free(map.cmap2->glyphIndexArray); + free(map.cmap2); } -static void ttfLoadCMAP4(FILE *fp,SubTablePtr subTable,ULONG offset) +static void ttfLoadCMAP4(FILE *fp, MapPtr *map) { USHORT segCount; USHORT len; - xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP4"); - - subTable->map.cmap4 = XCALLOC1 (CMAP4); + map->cmap4 = XCALLOC1 (CMAP4); + map->cmap4->length = ttfGetUSHORT(fp); + map->cmap4->version = ttfGetUSHORT(fp); - subTable->map.cmap4->segCountX2 = segCount = ttfGetUSHORT(fp); - subTable->map.cmap4->searchRange = ttfGetUSHORT(fp); - subTable->map.cmap4->entrySelector = ttfGetUSHORT(fp); - subTable->map.cmap4->rangeShift = ttfGetUSHORT(fp); + map->cmap4->segCountX2 = segCount = ttfGetUSHORT(fp); + map->cmap4->searchRange = ttfGetUSHORT(fp); + map->cmap4->entrySelector = ttfGetUSHORT(fp); + map->cmap4->rangeShift = ttfGetUSHORT(fp); segCount /= 2; - subTable->map.cmap4->endCount = ttfMakeUSHORT (segCount, fp); + map->cmap4->endCount = ttfMakeUSHORT (segCount, fp); - subTable->map.cmap4->reservedPad = ttfGetUSHORT(fp); + map->cmap4->reservedPad = ttfGetUSHORT(fp); - subTable->map.cmap4->startCount = ttfMakeUSHORT (segCount, fp); + map->cmap4->startCount = ttfMakeUSHORT (segCount, fp); - subTable->map.cmap4->idDelta = ttfMakeUSHORT (segCount, fp); + map->cmap4->idDelta = ttfMakeUSHORT (segCount, fp); - subTable->map.cmap4->idRangeOffset = ttfMakeUSHORT (segCount, fp); + map->cmap4->idRangeOffset = ttfMakeUSHORT (segCount, fp); /* caculate the length of glyphIndexArray, this is ugly, there should be * a better way to get this information. */ - len = subTable->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT); + len = map->cmap4->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT); len /= sizeof(USHORT); - subTable->map.cmap4->glyphIndexArray = ttfMakeUSHORT (len, fp); + map->cmap4->glyphIndexArray = ttfMakeUSHORT (len, fp); } -static void ttfPrintCMAP4(FILE *fp,SubTablePtr subTable) +static void ttfPrintCMAP4(FILE *fp, MapPtr map) { USHORT i; USHORT segCount,len; - segCount = subTable->map.cmap4->segCountX2/2; + fprintf(fp, " Format 4 - Segment mapping to delta values\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap4->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap4->version); + segCount = map.cmap4->segCountX2/2; fprintf(fp, "\t\t segCount:\t %d\n", segCount); - fprintf(fp, "\t\t searchRange:\t %d\n", subTable->map.cmap4->searchRange); - fprintf(fp, "\t\t entrySelector:\t %d\n", subTable->map.cmap4->entrySelector); - fprintf(fp, "\t\t rangeShift:\t %d\n", subTable->map.cmap4->rangeShift); + fprintf(fp, "\t\t searchRange:\t %d\n", map.cmap4->searchRange); + fprintf(fp, "\t\t entrySelector:\t %d\n", map.cmap4->entrySelector); + fprintf(fp, "\t\t rangeShift:\t %d\n", map.cmap4->rangeShift); for (i=0;i<segCount;i++) - { - fprintf(fp, "\t\t Seg %3d :", i); - fprintf(fp, " St = %04x,", subTable->map.cmap4->startCount[i]); - fprintf(fp, " En = %04x,", subTable->map.cmap4->endCount[i]); - /* should this filed be SHORT or USHORT ?? */ - fprintf(fp, " D = %6d," , - (subTable->map.cmap4->idDelta[i])); - fprintf(fp, " RO = %6d," , subTable->map.cmap4->idRangeOffset[i]); - - /* find the glyphIndex correpsonding to this segment */ - if (subTable->map.cmap4->idRangeOffset[i] != 0) - { - USHORT j; - j = subTable->map.cmap4->segCountX2/2 - i; - j = subTable->map.cmap4->idRangeOffset[i] - - j*sizeof(USHORT); - fprintf(fp, " gId# = %d\n", (int) (j/sizeof(USHORT))); - } - else - fprintf(fp, " gId# = N/A\n"); - } + { + fprintf(fp, "\t\t Seg %3d :", i); + fprintf(fp, " St = %04x,", map.cmap4->startCount[i]); + fprintf(fp, " En = %04x,", map.cmap4->endCount[i]); + /* should this filed be SHORT or USHORT ?? */ + fprintf(fp, " D = %6d," , + (map.cmap4->idDelta[i])); + fprintf(fp, " RO = %6d," , map.cmap4->idRangeOffset[i]); + + /* find the glyphIndex correpsonding to this segment */ + if (map.cmap4->idRangeOffset[i] != 0) + { + USHORT j; + j = map.cmap4->segCountX2/2 - i; + j = map.cmap4->idRangeOffset[i] - + j*sizeof(USHORT); + fprintf(fp, " gId# = %d\n", (int) (j/sizeof(USHORT))); + } + else + fprintf(fp, " gId# = N/A\n"); + } /* caculate the length of glyphIndexArray, this is ugly, there should be * a better way to get this information. */ - len = subTable->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT); + len = map.cmap4->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT); len /= sizeof(USHORT); fprintf(fp,"\t\t Number of glyphIndex %d\n",len); for (i=0;i<len;i++) - { - fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i, - subTable->map.cmap4->glyphIndexArray[i]); - } + { + fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i, + map.cmap4->glyphIndexArray[i]); + } for (i=0;i<segCount;i++) - { - int j,index; - fprintf(fp,"Segment %d:\n",i); - for (j=subTable->map.cmap4->startCount[i]; - j<=subTable->map.cmap4->endCount[i];j++) - { - index = ttfLookUpCMAP4(subTable,j); - fprintf(fp,"\t\tChar 0x%04x -> Index %d\n",j,index); - } - } -} -static USHORT ttfLookUpCMAP4(SubTablePtr subTable,USHORT cc) + { + int j,index; + fprintf(fp,"Segment %d:\n",i); + for (j=map.cmap4->startCount[i]; + j<=map.cmap4->endCount[i];j++) + { + index = ttfLookUpCMAP4(map, j); + fprintf(fp,"\t\tChar 0x%04x -> Index %d\n",j,index); + } + } +} +static USHORT ttfLookUpCMAP4(MapPtr map, USHORT cc) { USHORT i; - USHORT index=0, segCount = subTable->map.cmap4->segCountX2/2; + USHORT index=0, segCount = map.cmap4->segCountX2/2; for (i=0;i<segCount;i++) - { - if (cc <= subTable->map.cmap4->endCount[i] && - cc >= subTable->map.cmap4->startCount[i]) - { - USHORT j; - if (subTable->map.cmap4->idRangeOffset[i] != 0) - { - j = subTable->map.cmap4->idRangeOffset[i] - - (segCount - i)*sizeof(USHORT); - j = cc - subTable->map.cmap4->startCount[i] + j/2; - index = subTable->map.cmap4->glyphIndexArray[j]; - if (index != 0) - index += subTable->map.cmap4->idDelta[i]; - } - else - { - index = cc + subTable->map.cmap4->idDelta[i]; - } - break; - } - } + { + if (cc <= map.cmap4->endCount[i] && + cc >= map.cmap4->startCount[i]) + { + USHORT j; + if (map.cmap4->idRangeOffset[i] != 0) + { + j = map.cmap4->idRangeOffset[i] - + (segCount - i)*sizeof(USHORT); + j = cc - map.cmap4->startCount[i] + j/2; + index = map.cmap4->glyphIndexArray[j]; + if (index != 0) + index += map.cmap4->idDelta[i]; + } + else + { + index = cc + map.cmap4->idDelta[i]; + } + break; + } + } return index; } -static void ttfFreeCMAP4(SubTablePtr subTable) +static void ttfFreeCMAP4(MapPtr map) { - free(subTable->map.cmap4->endCount); - free(subTable->map.cmap4->startCount); - free(subTable->map.cmap4->idDelta); - free(subTable->map.cmap4->idRangeOffset); - free(subTable->map.cmap4->glyphIndexArray); - free(subTable->map.cmap4); + free(map.cmap4->endCount); + free(map.cmap4->startCount); + free(map.cmap4->idDelta); + free(map.cmap4->idRangeOffset); + free(map.cmap4->glyphIndexArray); + free(map.cmap4); } -static void ttfLoadCMAP6(FILE *fp,SubTablePtr subTable,ULONG offset) +static void ttfLoadCMAP6(FILE *fp, MapPtr *map) { USHORT len; - xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP6"); - - subTable->map.cmap6 = XCALLOC1 (CMAP6); - subTable->map.cmap6->firstCode = ttfGetUSHORT(fp); - subTable->map.cmap6->entryCount = len = ttfGetUSHORT(fp); - subTable->map.cmap6->glyphIndexArray = ttfMakeUSHORT (len, fp); + map->cmap6 = XCALLOC1 (CMAP6); + map->cmap6->length = ttfGetUSHORT(fp); + map->cmap6->version = ttfGetUSHORT(fp); + map->cmap6->firstCode = ttfGetUSHORT(fp); + map->cmap6->entryCount = len = ttfGetUSHORT(fp); + map->cmap6->glyphIndexArray = ttfMakeUSHORT (len, fp); } -static void ttfPrintCMAP6(FILE *fp, SubTablePtr subTable) +static void ttfPrintCMAP6(FILE *fp, MapPtr map) { USHORT i; - fprintf(fp,"\t\t First Code: 0x%04x\n",subTable->map.cmap6->firstCode); - fprintf(fp,"\t\t Entry Count: %d\n",subTable->map.cmap6->entryCount); + + fprintf(fp, " Format 6 - Trimmed table mapping\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap6->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap6->version); + fprintf(fp,"\t\t First Code: 0x%04x\n", map.cmap6->firstCode); + fprintf(fp,"\t\t Entry Count: %d\n", map.cmap6->entryCount); - for (i=0;i<subTable->map.cmap6->entryCount;i++) - { - fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i, - subTable->map.cmap6->glyphIndexArray[i]); - } + for (i=0;i<map.cmap6->entryCount;i++) + { + fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i, + map.cmap6->glyphIndexArray[i]); + } } -static USHORT ttfLookUpCMAP6(SubTablePtr subTable,USHORT cc) +static USHORT ttfLookUpCMAP6(MapPtr map, USHORT cc) { USHORT index; - index = cc - subTable->map.cmap6->firstCode; - if (index < subTable->map.cmap6->entryCount) - return subTable->map.cmap6->glyphIndexArray[index]; + index = cc - map.cmap6->firstCode; + if (index < map.cmap6->entryCount) + return map.cmap6->glyphIndexArray[index]; + else + /* index out of range, return missing glyph */ + return 0; +} +static void ttfFreeCMAP6(MapPtr map) +{ + free(map.cmap6->glyphIndexArray); + free(map.cmap6); +} + +static void ttfLoadCMAP8(FILE *fp, MapPtr *map) +{ + int i; + + map->cmap8 = XCALLOC1 (CMAP8); + ttfGetUSHORT(fp); + map->cmap8->length = ttfGetULONG(fp); + map->cmap8->version = ttfGetULONG(fp); + if (fread(map->cmap8->is32, sizeof(BYTE), 8192, fp) != 8192) + ttfError("Error when getting is32\n"); + map->cmap8->nGroups = ttfGetULONG(fp); + map->cmap8->charGroup = XCALLOC (map->cmap8->nGroups, CharGroup); + for (i = 0; i < map->cmap8->nGroups; i++) { + map->cmap8->charGroup[i].startCharCode = ttfGetULONG(fp); + map->cmap8->charGroup[i].endCharCode = ttfGetULONG(fp); + map->cmap8->charGroup[i].startGlyphID = ttfGetULONG(fp); + } +} +static void ttfPrintCMAP8(FILE *fp, MapPtr map) +{ + int i; + + fprintf(fp, " Format 8 - Mixed 16-bit and 32-bit coverage\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap8->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap8->version); + fprintf(fp,"\t\t nGroups: %6d\n", map.cmap8->nGroups); + for (i = 0; i < 256; i++) { + int j; + + fprintf(fp, "\t is32 %2x", i); + for (j = 0; j < 32; j++) + fprintf(fp, j % 4 ? "%2x" : " %2x", map.cmap8->is32[i << 5 | j]); + fprintf(fp, "\n"); + } + for (i = 0; i < map.cmap8->nGroups; i++) + fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, startGlyphID = %d\n", i, + map.cmap8->charGroup[i].startCharCode, + map.cmap8->charGroup[i].endCharCode, + map.cmap8->charGroup[i].startGlyphID); +} +static USHORT ttfLookUpCMAP8(MapPtr map, ULONG cc) +{ + int i; + + for (i = 0; i < map.cmap8->nGroups; i++) + if (cc > map.cmap8->charGroup[i].endCharCode) + continue; + else if (cc < map.cmap8->charGroup[i].startCharCode) + break; + else + return map.cmap8->charGroup[i].startGlyphID + + (cc - map.cmap8->charGroup[i].startCharCode); + + /* index out of range, return missing glyph */ + return 0; +} +static void ttfFreeCMAP8(MapPtr map) +{ + free(map.cmap8->charGroup); + free(map.cmap8); +} + +static void ttfLoadCMAP10(FILE *fp, MapPtr *map) +{ + ULONG len; + + map->cmap10 = XCALLOC1 (CMAP10); + ttfGetUSHORT(fp); + map->cmap10->length = ttfGetULONG(fp); + map->cmap10->version = ttfGetULONG(fp); + map->cmap10->startCharCode = ttfGetULONG(fp); + map->cmap10->numChars = len = ttfGetULONG(fp); + map->cmap10->glyphs = ttfMakeUSHORT (len, fp); +} +static void ttfPrintCMAP10(FILE *fp, MapPtr map) +{ + int i; + + fprintf(fp, " Format 10 - Trimmed array\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap10->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap10->version); + fprintf(fp,"\t\t Start Char Code: 0x%04x\n", map.cmap10->startCharCode); + fprintf(fp,"\t\t Num Chars: %d\n", map.cmap10->numChars); + + for (i = 0; i < map.cmap10->numChars; i++) + { + fprintf(fp, "\t\t glyphs[%d] = %d\n", i, map.cmap10->glyphs[i]); + } +} +static USHORT ttfLookUpCMAP10(MapPtr map, ULONG cc) +{ + ULONG index; + + index = cc - map.cmap10->startCharCode; + if (index < map.cmap10->numChars) + return map.cmap10->glyphs[index]; else - /* index out of range, return missing glyph */ - return 0; + /* index out of range, return missing glyph */ + return 0; +} +static void ttfFreeCMAP10(MapPtr map) +{ + free(map.cmap10->glyphs); + free(map.cmap10); +} + +static void ttfLoadCMAP12(FILE *fp, MapPtr *map) +{ + int i; + + map->cmap12 = XCALLOC1 (CMAP12); + ttfGetUSHORT(fp); + map->cmap12->length = ttfGetULONG(fp); + map->cmap12->version = ttfGetULONG(fp); + map->cmap12->nGroups = ttfGetULONG(fp); + map->cmap12->charGroup = XCALLOC (map->cmap12->nGroups, CharGroup); + for (i = 0; i < map->cmap12->nGroups; i++) { + map->cmap12->charGroup[i].startCharCode = ttfGetULONG(fp); + map->cmap12->charGroup[i].endCharCode = ttfGetULONG(fp); + map->cmap12->charGroup[i].startGlyphID = ttfGetULONG(fp); + } +} +static void ttfPrintCMAP12(FILE *fp, MapPtr map) +{ + int i; + + fprintf(fp, " Format 12 - Segmented coverage\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap12->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap12->version); + fprintf(fp,"\t\t nGroups: %6d\n", map.cmap12->nGroups); + for (i = 0; i < map.cmap12->nGroups; i++) + fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, startGlyphID = %d\n", i, + map.cmap12->charGroup[i].startCharCode, + map.cmap12->charGroup[i].endCharCode, + map.cmap12->charGroup[i].startGlyphID); +} +static USHORT ttfLookUpCMAP12(MapPtr map, ULONG cc) +{ + int i; + + for (i = 0; i < map.cmap12->nGroups; i++) + if (cc > map.cmap12->charGroup[i].endCharCode) + continue; + else if (cc < map.cmap12->charGroup[i].startCharCode) + break; + else + return map.cmap12->charGroup[i].startGlyphID + + (cc - map.cmap12->charGroup[i].startCharCode); + + /* index out of range, return missing glyph */ + return 0; +} +static void ttfFreeCMAP12(MapPtr map) +{ + free(map.cmap12->charGroup); + free(map.cmap12); +} + +static void ttfLoadCMAP13(FILE *fp, MapPtr *map) +{ + int i; + + map->cmap13 = XCALLOC1 (CMAP13); + ttfGetUSHORT(fp); + map->cmap13->length = ttfGetULONG(fp); + map->cmap13->version = ttfGetULONG(fp); + map->cmap13->nGroups = ttfGetULONG(fp); + map->cmap13->charGroup = XCALLOC (map->cmap13->nGroups, CharGroup); + for (i = 0; i < map->cmap13->nGroups; i++) { + map->cmap13->charGroup[i].startCharCode = ttfGetULONG(fp); + map->cmap13->charGroup[i].endCharCode = ttfGetULONG(fp); + map->cmap13->charGroup[i].startGlyphID = ttfGetULONG(fp); + } +} +static void ttfPrintCMAP13(FILE *fp, MapPtr map) +{ + int i; + + fprintf(fp, " Format 13 - Many-to-one range mappings\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap13->length); + fprintf(fp,"\t\t Version: %6d\n", map.cmap13->version); + fprintf(fp,"\t\t nGroups: %6d\n", map.cmap13->nGroups); + for (i = 0; i < map.cmap13->nGroups; i++) + fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, glyphID = %d\n", i, + map.cmap13->charGroup[i].startCharCode, + map.cmap13->charGroup[i].endCharCode, + map.cmap13->charGroup[i].startGlyphID); +} +static USHORT ttfLookUpCMAP13(MapPtr map, ULONG cc) +{ + int i; + + for (i = 0; i < map.cmap13->nGroups; i++) + if (cc > map.cmap13->charGroup[i].endCharCode) + continue; + else if (cc < map.cmap13->charGroup[i].startCharCode) + break; + else + return map.cmap12->charGroup[i].startGlyphID; + + /* index out of range, return missing glyph */ + return 0; +} +static void ttfFreeCMAP13(MapPtr map) +{ + free(map.cmap13->charGroup); + free(map.cmap13); +} + +static void ttfLoadCMAP14(FILE *fp, MapPtr *map) +{ + map->cmap14 = XCALLOC1 (CMAP14); + map->cmap14->length = ttfGetULONG(fp); +} +static void ttfPrintCMAP14(FILE *fp, MapPtr map) +{ + fprintf(fp, " Format 14 - Unicode variation sequences\n"); + fprintf(fp,"\t\t Length: %6d\n", map.cmap14->length); + fprintf(fp,"\t\t *** NOT YET IMPLEMENTED ***\n"); +} +static USHORT ttfLookUpCMAP14(MapPtr map, ULONG cc) +{ + return 0; } -static void ttfFreeCMAP6(SubTablePtr subTable) +static void ttfFreeCMAP14(MapPtr map) { - free(subTable->map.cmap6->glyphIndexArray); - free(subTable->map.cmap6); + free(map.cmap14); } |