/* 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 void ttfLoadLTSH (FILE *fp,LTSHPtr ltsh,ULONG offset) { xfseek(fp, offset, SEEK_SET, "ttfLoadLTSH"); ltsh->version = ttfGetUSHORT(fp); ltsh->numGlyphs = ttfGetUSHORT(fp); ltsh->yPels = ttfMakeBYTE (ltsh->numGlyphs, fp); }
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 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 ttfLoadGASP (FILE *fp,GASPPtr gasp,ULONG offset) { int i; xfseek(fp, offset, SEEK_SET, "ttfLoadGASP"); gasp->version = ttfGetUSHORT(fp); gasp->numRanges = ttfGetUSHORT(fp); gasp->gaspRange = XCALLOC (gasp->numRanges, GASPRANGE); for (i=0;i<gasp->numRanges;i++) { gasp->gaspRange[i].rangeMaxPPEM = ttfGetUSHORT(fp); gasp->gaspRange[i].rangeGaspBehavior = ttfGetUSHORT(fp); } }
USHORT *ttfMakeUSHORT(size_t nelem, FILE *fp) { int i; USHORT *array = XTALLOC (nelem, USHORT); for (i = 0; i < nelem; i++) array[i] = ttfGetUSHORT (fp); return array; }
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 ttfLoadNAME(FILE *fp,NAMEPtr name,ULONG offset) { USHORT i,n; ULONG pos; if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLOADNAME \n"); name->format = ttfGetUSHORT(fp); name->numberOfRecords = n = ttfGetUSHORT(fp); name->offset = ttfGetUSHORT(fp); if ((name->NameRecords = (NameRecordPtr) calloc(n,sizeof(NameRecord))) == NULL) ttfError("Out Of Memory\n"); pos = offset + sizeof(USHORT)*3; for(i=0;i<n;i++,pos+=12 /*sizeof(NameRecord)*/) { ttfLoadNameRecord(fp,name->NameRecords+i,pos); ttfLoadNameRecordData(fp,name->NameRecords+i,offset+name->offset); } }
/* 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 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); } }
/* offset: address of the beginning of the name record */ static void ttfLoadNameRecord(FILE *fp,NameRecordPtr rec,ULONG offset) { if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadNameRecord \n"); rec->PlatformID = ttfGetUSHORT(fp); rec->EncodingID = ttfGetUSHORT(fp); rec->LanguageID = ttfGetUSHORT(fp); rec->NameID = ttfGetUSHORT(fp); rec->length = ttfGetUSHORT(fp); rec->offset = ttfGetUSHORT(fp); }
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 }
uFWord ttfGetuFWord(FILE *fp) { return (uFWord) ttfGetUSHORT(fp); }
F2Dot14 ttfGetF2Dot14(FILE *fp) { return (F2Dot14) ttfGetUSHORT(fp); }
static void ttfLoadMAXP(FILE *fp,MAXPPtr maxp,ULONG offset) { xfseek(fp, offset, SEEK_SET, "ttfLoadMAXP"); maxp->version = ttfGetFixed(fp); maxp->numGlyphs = ttfGetUSHORT(fp); maxp->maxPoints = ttfGetUSHORT(fp); maxp->maxContours = ttfGetUSHORT(fp); maxp->maxCompositePoints = ttfGetUSHORT(fp); maxp->maxCompositeContours = ttfGetUSHORT(fp); maxp->maxZones = ttfGetUSHORT(fp); maxp->maxTwilightPoints = ttfGetUSHORT(fp); maxp->maxStorage = ttfGetUSHORT(fp); maxp->maxFunctionDefs = ttfGetUSHORT(fp); maxp->maxInstructionDefs = ttfGetUSHORT(fp); maxp->maxStackElements = ttfGetUSHORT(fp); maxp->maxSizeOfInstructions = ttfGetUSHORT(fp); maxp->maxComponentElements = ttfGetUSHORT(fp); maxp->maxComponentDepth = ttfGetUSHORT(fp); }
static void ttfLoadKERN (FILE *fp,KERNPtr kern,ULONG offset) { int i; if (fseek(fp,offset,SEEK_SET) !=0) ttfError("Fseek Failed in ttfLoadKERN \n"); kern->version = ttfGetUSHORT(fp); kern->nTables = ttfGetUSHORT(fp); kern->subtable = (KernSubtable *) calloc(kern->nTables, sizeof(KernSubtable)); for (i=0;i<kern->nTables;i++) { struct kernpair *pairs; int j,n; (kern->subtable+i)->version = ttfGetUSHORT(fp); (kern->subtable+i)->length = ttfGetUSHORT(fp); (kern->subtable+i)->coverage = ttfGetUSHORT(fp); switch ((kern->subtable+i)->coverage >> 8) { case 0: (kern->subtable+i)->kern.kern0.nPairs = n = ttfGetUSHORT(fp); (kern->subtable+i)->kern.kern0.searchRange = ttfGetUSHORT(fp); (kern->subtable+i)->kern.kern0.entrySelector = ttfGetUSHORT(fp); (kern->subtable+i)->kern.kern0.rangeShift = ttfGetUSHORT(fp); (kern->subtable+i)->kern.kern0.pairs = pairs = (struct kernpair *) calloc(n,sizeof (struct kernpair)); for (j=0;j<n;j++) { (pairs+j)->left = ttfGetUSHORT(fp); (pairs+j)->right = ttfGetUSHORT(fp); (pairs+j)->value = ttfGetFWord(fp); } break; case 2: /* not implemented yet */ break; default: /* do nothing */ break; } } }
FUnit ttfGetFUnit(FILE *fp) { return (FUnit) ttfGetUSHORT(fp); }
/* Read arrays. */ void ttfReadUSHORT(USHORT *array, size_t nelem, FILE *fp) { int i; for (i = 0; i < nelem; i++) array[i] = ttfGetUSHORT (fp); }