?? cmap.c
字號:
/* cmap.c -- Load and Print the content of cmap table * Copyright (C) 1996 Li-Da Lho, All right reserved * * The structure of a cmap is really complex, it depends on which format the * cmap is and loading a cmap is a kind of confusing thing. * The structure of CMAP: * A cmap begins with a general description of the table * USHORT version indicates the version of this cmap. * USHORT numEncodings is the number of encodings in the cmap table. * Then follow 'numEncodings' of encoding tables, each of which contains * the following informations for each subtable. The subtable contains the * true data to map character code to glyph index * USHORT PlatformID shows which platform the subtable is to be used * (e.g. Mac, PC) * USHORT Platfrom specofic EncodingID shows what kind of encoding scheme * this table uses (e.g. Big5, iso8859, Unicode etc.) * ULONG offset is the offset from the beginning of the whole cmap table * to the beginning of the corresponding subtable * ----------------------- --- --- * | USHORT version | ^ ^ * ----------------------- | | * | USHORT numEncodings | | | * ----------------------- | | * | Encoding Table 1 | | | * | USHORT PlatformID | | | * | USHORT EncodingID | | | * | ULONG offset 1 |------ | | * ----------------------- | | offset 1 | offset 2 * | Encoding Table 2 | | | | * | USHORT PlatformID | | | | * | USHORT EncodingID | | | | * | ULONG offset 2 |--- | v | * ----------------------- | | --- | * | Subtable 1 |<----- | * | with format 0 | | v * ----------------------- | --- * | Subtable 2 |<-- * | with format 2 | * ----------------------| * * Problem with Character Code vs. Byte Endianess. * */#include <stdio.h>#include <stdlib.h>#include "config.h"#include "ttf.h"#include "ttfutil.h"#ifdef MEMCHECK#include <dmalloc.h>#endif/* $Id: cmap.c,v 1.1.1.1 1998/06/05 07:47:52 robert Exp $ */#ifndef lintstatic char vcid[] = "$Id: cmap.c,v 1.1.1.1 1998/06/05 07:47:52 robert Exp $";#endif /* lint */static CMAPPtr ttfAllocCMAP(TTFontPtr font);static void ttfLoadCMAP(FILE *fp,CMAPPtr cmap,ULONG offset);static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset);static SubTablePtr ttfAllocSubTable(CMAPPtr cmap);static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG offset);static void ttfPrintSubTable(FILE* fp,SubTablePtr ptable);static void ttfFreeSubTable(SubTablePtr ptable);static CMAP0 * ttfAllocCMAP0(SubTablePtr subTable);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);void ttfInitCMAP(TTFontPtr font){ ULONG tag = 'c' | 'm' << 8 | 'a' << 16 | 'p' << 24; TableDirPtr ptd; if ((ptd = ttfLookUpTableDir(tag,font)) != NULL) { font->cmap = ttfAllocCMAP(font); ttfLoadCMAP(font->fp,font->cmap,ptd->offset); }}static CMAPPtr ttfAllocCMAP(TTFontPtr font){ CMAPPtr cmap; if ((cmap = (CMAPPtr) calloc(1,sizeof(CMAP))) == NULL) { ttfError("Out Of Memory in __FILE_ : __LINE__ \n"); return NULL; } return cmap;}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 */ if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLOADCMAP \n"); cmap->version = ttfGetUSHORT(fp); cmap->numberOfEncodings = n = ttfGetUSHORT(fp); cmap->subTables = ttfAllocSubTable(cmap); 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); }}void ttfPrintCMAP(FILE *fp,CMAPPtr cmap){ USHORT i; 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"); }}USHORT ttfLookUpCMAP(SubTablePtr subTable,USHORT cc){ USHORT idx,format = subTable->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; } 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->subTables); free(cmap);}/* actually, EncodingTable is a part of SubTable */static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset){ if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadEncodingTable \n"); subTable->PlatformID = ttfGetUSHORT(fp); subTable->EncodingID = ttfGetUSHORT(fp); subTable->offset = ttfGetULONG(fp);}static SubTablePtr ttfAllocSubTable(CMAPPtr cmap){ SubTablePtr subTable; if ((subTable = (SubTablePtr) calloc(cmap->numberOfEncodings,sizeof(SubTable))) == NULL) { ttfError("Out Of Memory in __FILE__ : __LINE__ \n"); return NULL; } return subTable;}/* should this one be static ? */static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG base){ ULONG pos; USHORT format; /* seek to the actuall position for this subtable * base: beginning of cmap * offset: offset field of each encoding table */ pos = base + subTable->offset; if (fseek(fp,pos,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadSubTable\n"); subTable->format = format = ttfGetUSHORT(fp); subTable->length = ttfGetUSHORT(fp); subTable->version = 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); /* 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; switch(format) { case 0: ttfFreeCMAP0(ptable); break; case 2: ttfFreeCMAP2(ptable); break; case 4: ttfFreeCMAP4(ptable); break; case 6: ttfFreeCMAP6(ptable); break; }}static CMAP0 * ttfAllocCMAP0(SubTablePtr subTable){ CMAP0 * cmap0; if ((cmap0 = (CMAP0 *) calloc(1,sizeof(CMAP0))) == NULL) { ttfError("Out Of Memory in __FILE__ : __LINE__ \n"); return NULL; } return cmap0;}static void ttfLoadCMAP0(FILE *fp,SubTablePtr subTable,ULONG offset){ BYTE * array; subTable->map.cmap0 = ttfAllocCMAP0(subTable); array = subTable->map.cmap0->glyphIndexArray; if (fseek(fp,offset,SEEK_SET) != 0) ttfError("Fseek Failed in ttfLoadCMAP0 \n"); /* 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 */ if (fread(array,sizeof(BYTE),256,fp) != 256) ttfError("Error when getting glyphIndexArray \n");}static void ttfPrintCMAP0(FILE *fp,SubTablePtr subTable){ USHORT index; int i; for (i=0;i<256;i++) { index = ttfLookUpCMAP(subTable,i); fprintf(fp,"\t\t Char %3d -> Index %4d \n",i,index); }}static USHORT ttfLookUpCMAP0(SubTablePtr subTable,USHORT cc){ return subTable->map.cmap0->glyphIndexArray[cc & 0x00ff];}static void ttfFreeCMAP0(SubTablePtr subTable){ free(subTable->map.cmap0);}static void ttfLoadCMAP2(FILE *fp,SubTablePtr subTable,ULONG offset){ USHORT * array,i,n = 0; USHORT numGlyphId; SubHeaderPtr header; if (fseek(fp,offset,SEEK_SET) != 0) ttfError("Fseek Failed in ttfLoadCMAP2 \n"); subTable->map.cmap2 = (CMAP2 *) calloc(1,sizeof(CMAP2)); array = subTable->map.cmap2->subHeaderKeys; if (fread(array,sizeof(USHORT),256,fp) != 256) ttfError("Error when getting subHeaderKeys \n");#ifndef WORDS_BIGENDIAN TwoByteSwap((unsigned char *) array,256*sizeof(USHORT));#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -