⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmap.c

📁 ttfdump源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -