📄 cmap.c
字号:
for (i=0;i<256;i++) { 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 = (SubHeaderPtr) calloc(n,sizeof(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)) ; } /* 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); numGlyphId /= sizeof(USHORT); subTable->map.cmap2->glyphIndexArray = (USHORT *) calloc(numGlyphId,sizeof(USHORT)); for (i=0;i<numGlyphId;i++) { subTable->map.cmap2->glyphIndexArray[i] = ttfGetUSHORT(fp); } }static void ttfPrintCMAP2(FILE *fp,SubTablePtr subTable){ USHORT i,j,numGlyphId; USHORT *array,n=0,index; SubHeaderPtr header; unsigned short cc; array = subTable->map.cmap2->subHeaderKeys; header = subTable->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]); } 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); } /* 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); 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]); } i = 0; fprintf(fp,"\t\t First Byte:\t %2x\n",i); for(j=0;j<=255;j++) {#ifndef WORDS_BIGENDIAN cc = i + (j << 8);#else cc = j + (i << 8);#endif index = ttfLookUpCMAP2(subTable,cc); 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); for(j=0;j<=255;j++) {#ifndef WORDS_BIGENDIAN cc = i + (j << 8);#else cc = j + (i << 8);#endif index = ttfLookUpCMAP2(subTable,cc); fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index); } }}static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc){ USHORT index,idx = 0; USHORT *array = subTable->map.cmap2->subHeaderKeys; SubHeaderPtr headers = subTable->map.cmap2->subHeaders; SHORT idDelta; USHORT firstCode, entryCount, idRangeOffset; unsigned char first,second; /* On little endian platforms "low byte" is the "first byte". * It determines that if it is necessary to use the second byte to * fully interprete the character code, for expamle, if the first byte * is obivously an ASCII character then it is not necessary to * interpret the second byte, on the other hand, if the first byte is * zero then the second byte is a ASCII char, when the first byte * is not an ASCII char nor zero, those two bytes together determine * the meanning of the character code */#ifndef WORDS_BIGENDIAN first = cc & 0x00ff; second = cc >> 8;#else first = cc >> 8; second = cc & 0x00ff;#endif /* select which subHeader to use */ idx = array[first]; firstCode = (headers+idx)->firstCode; entryCount = (headers+idx)->entryCount; idDelta = (headers+idx)->idDelta; 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; } else /* The second code is out ranged then return the * missing glyph character */ index = 0; return index;}static void ttfFreeCMAP2(SubTablePtr subTable){ free(subTable->map.cmap2->subHeaders); free(subTable->map.cmap2->glyphIndexArray); free(subTable->map.cmap2);}static void ttfLoadCMAP4(FILE *fp,SubTablePtr subTable,ULONG offset){ USHORT segCount; USHORT * array,len; if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadCMAP4 \n"); subTable->map.cmap4 = (CMAP4 *) calloc(1,sizeof(CMAP4)); 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); segCount /= 2; subTable->map.cmap4->endCount = array = (USHORT *) calloc(segCount,sizeof(USHORT)); if (fread(array,sizeof(USHORT),segCount,fp) != segCount) ttfError("Error when getting endCount\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,segCount*sizeof(USHORT));#endif subTable->map.cmap4->reservedPad = ttfGetUSHORT(fp); subTable->map.cmap4->startCount = array = (USHORT *) calloc(segCount,sizeof(USHORT)); if (fread(array,sizeof(USHORT),segCount,fp) != segCount) ttfError("Error when getting startCount\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,segCount*sizeof(USHORT));#endif subTable->map.cmap4->idDelta = array = (USHORT *) calloc(segCount,sizeof(USHORT)); if (fread(array,sizeof(USHORT),segCount,fp) != segCount) ttfError("Error when getting idDelta\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,segCount*sizeof(USHORT));#endif subTable->map.cmap4->idRangeOffset = array = (USHORT *) calloc(segCount,sizeof(USHORT)); if (fread(array,sizeof(USHORT),segCount,fp) != segCount) ttfError("Error when getting idRangeOffset\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,segCount*sizeof(USHORT));#endif /* 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 /= sizeof(USHORT); subTable->map.cmap4->glyphIndexArray = array = (USHORT *) calloc(len,sizeof(USHORT)); if (fread(array,sizeof(USHORT),len,fp) != len) ttfError("Error when getting idRangeOffset\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,len*sizeof(USHORT));#endif}static void ttfPrintCMAP4(FILE *fp,SubTablePtr subTable){ USHORT i; USHORT segCount,len; segCount = subTable->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); 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",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 /= 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]); } 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){ USHORT i; USHORT index=0, segCount = subTable->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; } } return index;}static void ttfFreeCMAP4(SubTablePtr subTable){ 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);}static void ttfLoadCMAP6(FILE *fp,SubTablePtr subTable,ULONG offset){ USHORT * array,len; if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadCMAP6 \n"); subTable->map.cmap6 = (CMAP6 *) calloc(1,sizeof(CMAP6)); subTable->map.cmap6->firstCode = ttfGetUSHORT(fp); subTable->map.cmap6->entryCount = len = ttfGetUSHORT(fp); subTable->map.cmap6->glyphIndexArray = array = (USHORT *) calloc(subTable->map.cmap6->entryCount,sizeof(USHORT)); if (fread(array,sizeof(USHORT),len,fp) != len) ttfError("Error when getting idRangeOffset\n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,len*sizeof(USHORT));#endif}static void ttfPrintCMAP6(FILE *fp, SubTablePtr subTable){ 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); for (i=0;i<subTable->map.cmap6->entryCount;i++) { fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i, subTable->map.cmap6->glyphIndexArray[i]); }}static USHORT ttfLookUpCMAP6(SubTablePtr subTable,USHORT cc){ USHORT index; index = cc - subTable->map.cmap6->firstCode; if (index < subTable->map.cmap6->entryCount) return subTable->map.cmap6->glyphIndexArray[index]; else /* index out of range, return missing glyph */ return 0;}static void ttfFreeCMAP6(SubTablePtr subTable){ free(subTable->map.cmap6->glyphIndexArray); free(subTable->map.cmap6);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -