// // Copyright (c) 1997-1999 Microsoft Corporation. // #include "stdafx.h" #include "eudcedit.h" #include "util.h" #pragma pack(2) #include "vdata.h" #include "ttfstruc.h" #include "extfunc.h" /* * TrueType File I/F */ #define GLYPHBUFSIZ 0xFFFFL #define RWBUFSIZ 16384 #define EUDCCODEBASE ((unsigned short)0xE000) /* 0xe000 uni-code */ #define NUMTABLES 15 #define NAMEBUFSIZ 1024 #define NUMOFNAMEREC 8 static void initDirEntry(struct TableEntry *e,int num); static int setDirEntry(struct TableEntry *e,char *tag); void smtoi(short *sval); void lmtoi(long *lval); void sitom(short *sval); void litom(long *lval); static int align32(int siz); static unsigned long calchksum(char *buf,int siz); static int copyblk(HDC hDC,char *tag,int ofHdl,long siz,char *buf,int bufsiz,unsigned long *cs); static int mergeblock(HDC hDC,struct TableEntry *entry,int ofHdl); static int tableChkSum(int fH,struct TableEntry *te); static int codeToGID(unsigned short code); int TTFReadHdr(HANDLE fHdl,struct TTFHeader *hdr); int TTFWriteHdr(HANDLE fHdl,struct TTFHeader *hdr); int TTFReadDirEntry(HANDLE fHdl,struct TableEntry *entry,int eCnt); int TTFWriteDirEntry(HANDLE fHdl,struct TableEntry *entry,int eCnt); static struct TableEntry *searchEntry(struct TableEntry *entry,int eCnt,char *tag); int TTFGetTableEntry(HANDLE fH,struct TableEntry *entry,char *tag); int TTFReadTable(HANDLE fH,struct TableEntry *entry,void *buf,int bufsiz); int TTFReadFixedTable(HANDLE fH,char *buf,int bufsiz,char *tag); int TTFReadVarTable(HANDLE fH,char * *buf,unsigned int *bufsiz,char *tag); int TTFWriteTable(HANDLE fH,struct TableEntry *entry,void *buf,int bufsiz); int TTFAppendTable(HANDLE fH,struct TableEntry *entry,void *buf,int siz); static int TTFMergeTable(HDC hDC,HANDLE nfh,char *tag,struct TableEntry *nte); #ifdef BUILD_ON_WINNT static int __cdecl compentry(const void *e1,const void *e2); #else static int compentry(const void *e1,const void *e2); #endif // BUILD_ON_WINNT static void SortEntry(struct TableEntry *ebuf,int num); static int fileChkSum(HANDLE fh,struct TableEntry *entry,int numEntry,struct TTFHeader *hdr,struct HeadTable *head); static void makeTTFHeader(struct TTFHeader *hdr,int nTbl); static int makeGlyphData(int lstH,struct BBX *bbx,char *glyphData,int bufsiz,int *gdatsiz); static void initsetgbuf(char *b,int lim); static int setgbuf(char *dat,int siz,char * *np); static int termbuf(void); static int strwlen(char *s); static void strwcat(char *s1,char *s2); static void setnamebuf(char *buf,int *siz, short EncodingID); static void modifyOS2(char *buf); static void modifyhead(struct HeadTable *head); static void setVhea(struct VheaTable *vhea,struct HheaTable *hhea,struct BBX *bbx); static int updateMaxp(struct MaxpTbl *maxp,int lstHdl); static int TTFGetOrgTableEntry(HDC hDC,struct TableEntry *entry,char *tag); int TTFReadOrgFixedTable(HDC hDC,char *buf,int bufsiz,char *tag); int TTFReadOrgVarTable(HDC hDC,char * *buf,unsigned int *bufsiz,char *tag); static void setCountryData(short EncodingID); static int WIFEOS2(HDC hDC,char * *os2buf,int *os2TblSiz,struct BBX *bbx); static void WIFEhhea(struct HheaTable *hhea,struct BBX *bbx); static void WIFEhead(struct HeadTable *head,struct BBX *bbx); static void WIFEpost(struct postTable *post); int TTFCreate(HDC hDC,TCHAR *newf,struct BBX *bbx,int lstHdl,int fontType); int TTFGetBBX(HDC hDC,struct BBX *bbx,short *uPEm); int TTFTmpPath(TCHAR *path,TCHAR *tmpPath); static int copyTable(HANDLE iFh,HANDLE oFh,struct TableEntry *te,int nEntry,char *tag); static int copyfblock(HANDLE iFh,HANDLE oFh,unsigned long siz,unsigned long *cs); static int mergeGlyph(HANDLE iFh,HANDLE oFh,struct TableEntry *tep,char *locabuf,int glyphID,char *glyphData,int glyphSiz); static void frebuf(void); int TTFOpen(TCHAR *path); int TTFClose(void); int TTFGetEUDCBBX(TCHAR *path,struct BBX *bbx,short *upem); static void makeMetrics(int lsthdl,struct HMetrics *hM,struct VMetrics *vM,struct BBX *bbx); int TTFAppend(unsigned short code,struct BBX *bbx,int lsthdl); int TTFImpCopy(TCHAR *sPath,TCHAR *dPath); int TTFImpGlyphCopy(HANDLE sFh,int glyphID); int TTFImpGlyphWrite(int glyphID, char *buf, int siz); int TTFLastError(); /** * static variables **/ static struct TableEntry *et; static int entryNum; static int entryCnt; static int numOfGlyph=0; static int lastErr = 0; /** * static table data **/ static char cvtdata[] = {0, 0}; static char fpgmdata[]={ (char)0xb0, (char)0x00, (char)0x2c, (char)0x2d}; static char prepdata[]={(char)0xb8, 0x1, (char)0xff, (char)0x85, (char)0xb0, (char)0x01, (char)0x8d}; static char maxpdata[]={ /* JPN */ 0x00, 0x01, 0x00, 0x00, (char)0x07, (char)0x5a, /* 1882 numGlyph of JPN */ 0, 4, 0, 1 , /* maxP, maxC(nullGlyf value)*/ 0, 0, 0, 0, /* maxCom*2*/ 0, 1, 0, 0, /* maxZones, maxTw*/ 0, 0, 0, 1, /* maxStorage, maxFunc*/ 0, 0, 0, 1, /* maxI, maxStack */ 0, 1, 0, 1, 0, 1 }; static char cmapdata[] = { 0, 0, 0, 1, 0, 3, 0, 1, 0, 0, 0, 12, 0, 4, 0, 32, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, (char)0xe7, (char)0x57, (char) 0xff,(char) 0xff, /* last code */ 0, 0, (char)0xe0, (char)0x00, (char)0xff,(char) 0xff, 0x20, 0x02, 0x00, 0x01, 0, 0, 0, 0 }; static char namerecstr[NUMOFNAMEREC][16] ={ { 0, '0', 0, '0', 0, 0}, { 0,'E', 0,'U', 0, 'D',0,'C', 0,0}, { 0,'R', 0, 'e', 0,'g', 0,'u', 0,'l', 0,'a', 0,'r',0,0}, { 0, '0', 0,'0', 0, 0}, { 0,'E', 0,'U', 0, 'D',0,'C', 0,0}, { 0, '0', 0,'0', 0, 0}, { 0, '0', 0,'0',0, 0}, { 0, '0', 0,'0',0, 0} }; static void initDirEntry( struct TableEntry *e, int num) { et = e; entryNum = num; entryCnt = 0; } static int setDirEntry(struct TableEntry *e, char *tag) { if ( entryCnt >= entryNum) return -1; memcpy( e->tagName, tag, TAGSIZ); *(et+entryCnt) = *e; entryCnt++; return 0; } void smtoi( short *sval) { short retval; unsigned char *cp; cp = (unsigned char *)sval; retval = *cp++; retval <<=8; retval += *cp; *sval = retval; } void lmtoi( long *lval) { long retval; unsigned char *cp; int i; cp = (unsigned char *)lval; retval = (long)*cp++; for(i=0; i<3; i++) { retval <<=8; retval |= (long)*cp++; } *lval = retval; } void sitom( short *sval) { unsigned char *cp; short setval; setval = *sval; cp = (unsigned char *)sval; *cp++ = (unsigned char)((setval>>8)&0xff); *cp++ = (unsigned char)(setval&0xff); } void litom( long *lval) { long setval; int i; unsigned char *cp; setval = *lval; cp = (unsigned char *)lval; cp += 3; for ( i = 0; i<4; i++) { *cp--=(char )(setval&0xff); setval >>=8; } } static int align32( int siz) { siz = (siz + 3)/4 * 4; return siz; } static unsigned long calchksum( char *buf, int siz) { unsigned long *csp; unsigned long chksum; unsigned long lval; unsigned char pad[4]; int i; int padsiz; unsigned char *cp; int csc; csp = (unsigned long *)buf; csc = siz/4; chksum = 0; while ( csc-->0) { lval = *csp++; lmtoi( (long *)&lval); chksum += lval; } padsiz = (siz+3)/4*4 - siz; if ( padsiz) { cp = (unsigned char *)csp; i = 0; while (padsiz++<4) pad[i++]=*cp++; csp = (unsigned long *)pad; lval = *csp; lmtoi( (long *)&lval); chksum += lval; } return chksum; } static int copyblk(HDC hDC, char *tag, HANDLE ofHdl, long siz, char *buf, int bufsiz, unsigned long *cs) { int rwsiz; int filsiz; int aligne; unsigned long chksum; long ofs; DWORD dwTable, nByte; dwTable = *(DWORD *)tag; filsiz = (int)(siz % 4); if ( filsiz) filsiz = 4-filsiz; ofs = 0L; aligne =0; chksum = 0; while ( siz > 0) { if ( siz > bufsiz) rwsiz = bufsiz; else { rwsiz = (int)siz; if ( filsiz) aligne =1; } if ( GetFontData(hDC, dwTable, (DWORD)ofs, buf,(DWORD)rwsiz ) != (DWORD)rwsiz) goto ERET; if ( aligne ) { memset( buf+siz, 0, filsiz); rwsiz += filsiz; } chksum += calchksum( buf, rwsiz); BOOL res = WriteFile( ofHdl, buf, (unsigned int)rwsiz, &nByte, NULL); if (!res || nByte !=(unsigned int)rwsiz) goto ERET; siz -= rwsiz; ofs += rwsiz; } *cs = chksum; return 0; ERET: return -1; } static int mergeblock( HDC hDC, struct TableEntry *entry, HANDLE ofHdl) { long ofs; char *mem; unsigned long cs; /* CheckSum value */ mem = (char *)malloc((size_t) RWBUFSIZ); if ( mem==(char *)0) return -1; /* Obtain start offset of Output table */ ofs = SetFilePointer( ofHdl, 0L, NULL, FILE_CURRENT); if (copyblk( hDC, entry->tagName, ofHdl, entry->siz, mem, RWBUFSIZ, &cs)) goto ERET; entry->ofs = ofs; entry->checkSum = cs; free( mem); return 0; ERET: free( mem); return -1; } static int tableChkSum( HANDLE fH, struct TableEntry *te) { char *rwbuf; unsigned long cs; long lsiz; int rwsiz; if ( te->siz==0) return 0; if ((rwbuf = (char *)malloc( (size_t)RWBUFSIZ))==(char *)0) return -1; if ( (long) SetFilePointer( fH, te->ofs, NULL, FILE_BEGIN)!=te->ofs) goto ERET; cs = 0; lsiz = te->siz; while ( lsiz > 0) { if (lsiz > RWBUFSIZ) rwsiz = RWBUFSIZ; else rwsiz = (int)lsiz; lsiz -= rwsiz; cs += calchksum( rwbuf, rwsiz); } te->checkSum = cs; free( rwbuf); return 0; ERET: free( rwbuf); return -1; } static int codeToGID( unsigned short code) { return (int)( code - (unsigned short)EUDCCODEBASE +2); } int TTFReadHdr ( HANDLE fHdl, struct TTFHeader *hdr) { DWORD nBytesRead; SetFilePointer( fHdl, 0L, NULL, FILE_BEGIN); BOOL res=ReadFile( fHdl, hdr, sizeof(struct TTFHeader),&nBytesRead, NULL); if (!res || nBytesRead !=sizeof(struct TTFHeader)) { return -1; } smtoi( &hdr->numTables); smtoi( &hdr->searchRange); smtoi( &hdr->entrySelector); smtoi( &hdr->rangeShift); return 0; } int TTFWriteHdr ( HANDLE fHdl, struct TTFHeader *hdr) { struct TTFHeader whdr; whdr = *hdr; sitom( &whdr.numTables); sitom( &whdr.searchRange); sitom( &whdr.entrySelector); sitom( &whdr.rangeShift); if (SetFilePointer( fHdl, 0L, NULL, FILE_BEGIN)!=0L) return -1; DWORD nByte; BOOL res = WriteFile( fHdl, (BYTE *) &whdr, sizeof(struct TTFHeader), &nByte, NULL); if (!res || nByte !=sizeof(struct TTFHeader)) return -1; return 0; } int TTFReadDirEntry( HANDLE fHdl, struct TableEntry *entry, int eCnt) { long ofs; DWORD nByte; BOOL res; ofs = sizeof (struct TTFHeader); if ( (long) SetFilePointer( fHdl, ofs, NULL, FILE_BEGIN)!=ofs) return -1; res = ReadFile( fHdl, entry, (unsigned int)(sizeof(struct TableEntry)*eCnt), &nByte, NULL); if (!res || nByte !=(unsigned int)sizeof(struct TableEntry)*eCnt) return -1; while ( eCnt-->0) { lmtoi((long *)&entry->checkSum); lmtoi(&entry->ofs); lmtoi(&entry->siz); entry++; } return 0; } int TTFWriteDirEntry( HANDLE fHdl, struct TableEntry *entry, int eCnt) { long ofs; struct TableEntry wentry; DWORD nByte; BOOL res; ofs = sizeof (struct TTFHeader); if ( (long) SetFilePointer( fHdl, ofs, NULL, FILE_BEGIN)!=ofs) return -1; /* Write Entries */ while ( eCnt-->0) { wentry = *entry++; litom((long *)&wentry.checkSum); litom(&wentry.ofs); litom(&wentry.siz); res = WriteFile( fHdl,(char *) &wentry, sizeof wentry, &nByte, NULL); if (!res || nByte !=sizeof wentry) { return -1; } } return 0; } static struct TableEntry * searchEntry(struct TableEntry *entry, int eCnt, char *tag) { while ( eCnt-->0) { if (memcmp( entry->tagName, tag, TAGSIZ)==0) return entry; entry++; } return (struct TableEntry *)0; } int TTFGetTableEntry( HANDLE fH, struct TableEntry *entry, char *tag) { struct TTFHeader hdr; struct TableEntry *te, *rte; int msiz; te = 0; /* Read TTF Header to get numTables */ if (TTFReadHdr( fH, &hdr)) goto ERET; msiz = sizeof(struct TableEntry)*hdr.numTables; if ( (te = (struct TableEntry *)malloc((size_t)msiz))==(struct TableEntry *)0) goto ERET; /* Read entry whole */ if ( TTFReadDirEntry( fH, te, hdr.numTables)) goto ERET; /* Search for entry with tag */ if ((rte = searchEntry(te, (int)hdr.numTables, tag))==0) goto ERET; *entry = *rte; free(te); return 0; ERET: if (te) free(te); return -1; } /*********************************************************************** * Read Table at once with entry data */ /* */ int /* */ TTFReadTable( /* */ HANDLE fH, /* */ struct TableEntry *entry, /* */ void *buf, /* */ int bufsiz) /* * returns : read size ***********************************************************************/ { unsigned int rdsiz; DWORD nByte; BOOL res; if ((long) SetFilePointer( fH, entry->ofs, NULL, FILE_BEGIN)!=entry->ofs) goto ERET; rdsiz = bufsiz >= (int)entry->siz ? (unsigned int)entry->siz : (unsigned int)bufsiz; res = ReadFile( fH, buf, rdsiz, &nByte, NULL); if (!res || nByte!=rdsiz) goto ERET; if ( rdsiz < (unsigned int)bufsiz) memset((unsigned char *)buf + rdsiz, 0, bufsiz - rdsiz); return (int)rdsiz; ERET: return -1; } /*********************************************************************** * Read Fixed Size Table at onece with tag */ /* */ int /* */ TTFReadFixedTable( /* */ HANDLE fH, /* */ char *buf, /* */ int bufsiz, /* */ char *tag) /* * returns : 0, -1 ***********************************************************************/ { struct TableEntry te; if (TTFGetTableEntry( fH, &te, tag)) goto ERET; if ( TTFReadTable( fH, &te, buf, bufsiz )!=bufsiz) goto ERET; return 0; ERET: return -1; } /*********************************************************************** * Read Variable Size Table at onece with tag */ /* */ int /* */ TTFReadVarTable( /* */ HANDLE fH, /* */ char **buf, /* Buffer pointer (be set) */ /* */ unsigned int *bufsiz, /* Buffer Size ( be set) */ /* */ char *tag) /* Tag name */ /* * returns : 0, -1 * remarks : allocated memory must be free by caller ***********************************************************************/ { struct TableEntry te; char *mem; if (TTFGetTableEntry( fH, &te, tag)) goto ERET; if ((mem = (char *)malloc( (size_t)te.siz))==(char *)0) goto ERET; if ( TTFReadTable( fH, &te, mem, (int)te.siz )!=(int)te.siz) goto ERET; *buf = mem; *bufsiz = (unsigned int)te.siz; return 0; ERET: return -1; } /*********************************************************************** * Write Table */ /* */ int /* */ TTFWriteTable( /* */ HANDLE fH, /* */ struct TableEntry *entry, /* */ void *buf, /* */ int bufsiz) /* * returns : written size * remarks : update checksum ***********************************************************************/ { int wsiz; DWORD nByte; BOOL res; if ((long) SetFilePointer( fH, entry->ofs, NULL, FILE_BEGIN)!=entry->ofs) goto ERET; wsiz = bufsiz >= (int)entry->siz ? (int)entry->siz : bufsiz; res = WriteFile( fH, (char *)buf, (unsigned int)wsiz, &nByte, NULL); if (!res || nByte !=(unsigned int)wsiz) goto ERET; entry->checkSum = calchksum( (char *)buf, bufsiz); return wsiz; ERET: return -1; } /*********************************************************************** * Write Table */ /* */ int /* */ TTFAppendTable( /* */ HANDLE fH, /* */ struct TableEntry *entry, /* value be set */ /* */ void *buf, /* */ int siz) /* * returns : 0, -1 * remarks : enttry->siz not aligned 32bit ***********************************************************************/ { long ofs; BYTE pad[4]; int padsiz; DWORD nByte; BOOL res; if ( (ofs=(long) SetFilePointer( fH, 0L, NULL, FILE_CURRENT))<0L) goto ERET; res = WriteFile( fH, buf, (unsigned int)siz, &nByte, NULL); if (!res || nByte !=(unsigned int)siz) goto ERET; /* 32 bit Word aligne */ if ( siz % 4) { padsiz = 4 - siz%4; memset(pad,0,4); res = WriteFile(fH,pad, (unsigned int)padsiz, &nByte, NULL); if (!res || nByte !=(unsigned int)padsiz) goto ERET; } entry->ofs = ofs; entry->siz = siz; entry->checkSum = calchksum((char *) buf, siz); return 0; ERET: return -1; } /*********************************************************************** * Merge Table */ /* */ static int /* */ TTFMergeTable( /* */ HDC hDC, /* */ HANDLE nfh, /* */ char tag[4], /* */ struct TableEntry *nte) /* * returns : 0 ***********************************************************************/ { if (TTFGetOrgTableEntry( hDC, nte, tag)) return -1; if (mergeblock( hDC, nte, nfh)) return -1; return 0; } int #ifdef BUILD_ON_WINNT __cdecl #endif // BUILD_ON_WINNT compentry( const void *e1, const void *e2) { struct TableEntry *te1, *te2; te1 = (struct TableEntry *)e1; te2 = (struct TableEntry *)e2; return memcmp(te1->tagName, te2->tagName,4); } static void SortEntry(struct TableEntry *ebuf, int num) { if ( num <=0) return; qsort( ebuf, num, sizeof(struct TableEntry), compentry); } static int fileChkSum( HANDLE fh, struct TableEntry *entry, int numEntry, struct TTFHeader *hdr, struct HeadTable *head) { unsigned long lval, cs; unsigned long *lp; struct TableEntry *e; int n; struct TableEntry *headp; DWORD nByte; BOOL res; e = entry; n = numEntry; cs = 0; head->chkSum = 0; headp = 0; while ( n-->0) { lp = (unsigned long *)e->tagName; if (memcmp( e->tagName,"head", 4)==0) headp = e; lval = *lp; lmtoi( (long *)&lval); cs += lval; cs += e->checkSum; cs += e->checkSum; cs += e->ofs; cs += e->siz; e++; } if (headp==0) return -1; cs += calchksum( (char *)hdr, sizeof(struct TTFHeader) ); if ((long) SetFilePointer( fh, headp->ofs, NULL, FILE_BEGIN)!=headp->ofs) goto ERET; head->chkSum = (unsigned long)0xb1b0afbaL - cs; litom( (long *)&head->chkSum); res = WriteFile(fh,(char *)head,sizeof(struct HeadTable), &nByte, NULL); if (!res || nByte !=sizeof(struct HeadTable)) goto ERET; return 0; ERET: return -1; } static void makeTTFHeader( struct TTFHeader *hdr, int nTbl) { int po; int n; int ponum; po = 0; n = nTbl; ponum = 1; while ( n>=2) { n /= 2; po++; ponum*=2; } hdr->sfnt_version[0]= hdr->sfnt_version[2]= hdr->sfnt_version[3]= 0; hdr->sfnt_version[1]= 0x01; hdr->numTables = (short)nTbl; hdr->searchRange = (short)ponum*16; hdr->entrySelector = (short)po; hdr->rangeShift = (short)( nTbl*16)-hdr->searchRange; return ; } /*********************************************************************** * make GlyphData from lst */ /* */ static int /* */ makeGlyphData( /* */ int lstH, /* */ struct BBX *bbx, /* Set value to header */ /* */ char *glyphData, /* */ int bufsiz, /* */ int *gdatsiz) /* * returns : 0, -1 ***********************************************************************/ { char *flgp, *sflgp; char flag; char *dummyp; struct VHEAD *vhd, *svhd; struct glyfHead ghdr; int nCnt; struct VDATA *vp; int nPnt; int pntSum; int cnt; short sval; short px, py; short relx, rely; char cval; initsetgbuf ( glyphData, bufsiz); if( ( nCnt = VDGetNCont( lstH))<0) goto ERET; else if (nCnt == 0) { /* Space Character */ *gdatsiz = 0; return 0; } ghdr.numberOfContour = (short)nCnt; sitom( &ghdr.numberOfContour ); ghdr.xMin = (short)bbx->xMin; sitom( &ghdr.xMin); ghdr.yMin = (short)bbx->yMin; sitom( &ghdr.yMin); ghdr.xMax = (short)bbx->xMax; sitom( &ghdr.xMax); ghdr.yMax = (short)bbx->yMax; sitom( &ghdr.yMax); if (setgbuf( (char *)&ghdr, sizeof ghdr, &flgp)) goto ERET2; if (VDGetHead( lstH, &vhd)) goto ERET; pntSum = 0; svhd = vhd; /* Set each Contour Last point number */ for ( cnt = 0; cnt < nCnt; cnt++) { pntSum += vhd->nPoints; sval = pntSum-1; sitom( &sval); if ( setgbuf((char *)&sval, sizeof( short), &flgp)) goto ERET2; vhd = vhd->next; } /* Toatal number of instructions */ sval = 0; if ( setgbuf((char *)&sval, sizeof( short), &flgp)) goto ERET2; /* Set flags */ vhd = svhd; px = py = 0; for ( cnt = 0; cnt < nCnt; cnt++) { vp = vhd->headp; nPnt = vhd->nPoints; while ( nPnt-->0) { flag = (vp->vd.atr&1)==0 ? (char)GLYF_ON_CURVE :(char)0; relx = vp->vd.x - px; rely = vp->vd.y - py; if ( relx == 0) flag |= GLYF_X_SAME; else if ( relx > 0 && relx < 256) flag |= GLYF_X_SHORT_P; else if ( relx < 0 && relx > -256) flag |= GLYF_X_SHORT_N; if ( rely == 0) flag |= GLYF_Y_SAME; else if ( rely > 0 && rely < 256) flag |= GLYF_Y_SHORT_P; else if ( rely < 0 && rely > -256) flag |= GLYF_Y_SHORT_N; if (setgbuf((char *) &flag, 1, &dummyp)) goto ERET2; px = vp->vd.x; py = vp->vd.y; vp = vp->next; } vhd = vhd->next; } /* set X */ vhd = svhd; sflgp = flgp; px = 0; for ( cnt = 0; cnt < nCnt; cnt++) { vp = vhd->headp; nPnt = vhd->nPoints; while ( nPnt-->0) { relx = vp->vd.x - px; if ( *flgp & GLYF_X_SHORT) { if ( (*flgp & GLYF_X_SAME)==0) relx = -relx; cval = (char)relx; if ( setgbuf( &cval, 1, &dummyp)) goto ERET2; } else if ( *flgp & GLYF_X_SAME) ; else { sitom( &relx); if ( setgbuf( (char *)&relx, 2, &dummyp)) goto ERET2; } flgp++; px = vp->vd.x; vp = vp->next; } vhd = vhd->next; } /* set Y */ vhd = svhd; flgp = sflgp; py = 0; for ( cnt = 0; cnt < nCnt; cnt++) { vp = vhd->headp; nPnt = vhd->nPoints; while ( nPnt-->0) { rely = vp->vd.y - py; if ( *flgp & GLYF_Y_SHORT) { if ( (*flgp & GLYF_Y_SAME)==0) rely = -rely; cval = (char)rely; if ( setgbuf( &cval, 1, &dummyp)) goto ERET2; } else if ( *flgp & GLYF_Y_SAME) ; else { sitom( &rely); if ( setgbuf((char *)&rely, 2, &dummyp)) goto ERET2; } flgp++; py = vp->vd.y; vp = vp->next; } vhd = vhd->next; } *gdatsiz = termbuf(); return 0; ERET: return -1; ERET2: return -2; } static char *sbuf; static int limcnt; static char *setp; static int bcnt; static void initsetgbuf( char *b, int lim) { setp = sbuf = b; limcnt = lim; bcnt = lim; /* decremental counter */ return; } static int setgbuf( char *dat, int siz, char **np) { if ( siz > bcnt) return -1; memcpy( setp, dat, siz); setp += siz; bcnt -= siz; *np = setp; return 0; } static int termbuf( ) { int siz; siz = limcnt - bcnt; siz = siz % 4; if ( siz) { while ( siz++<4) { *setp++=0; bcnt--; } } return limcnt - bcnt; } static int strwlen( char *s) { int len; len = 0; while (*s || *(s+1)) { s+=2; len++; } return len*2; } static void strwcat( char *s1, char *s2) { while (*s1 || *(s1+1)) s1+=2; while ( *s2 || *(s2+1)) { *s1++ = *s2++; *s1++ = *s2++; } *s1++ = 0; *s1++ = 0; return; } static void setnamebuf( char *buf, int *siz, short EncodingID) { int strsiz; short strofs; char *strp; struct NamingTable *nt; struct NameRecord *nr; int rec; int slen; strofs = sizeof(struct NamingTable) + sizeof(struct NameRecord)*NUMOFNAMEREC; strsiz = 0; strp = buf +strofs; *strp=(char)0; *(strp+1)=(char)0; nt = (struct NamingTable *)buf; nt->OfsToStr = strofs; sitom( &nt->OfsToStr); nr = (struct NameRecord *)(buf + sizeof(struct NamingTable)); /* Set name record */ strofs = 0; for ( rec = 0; recPlatformID = 3; sitom(&nr ->PlatformID); nr ->PlatformSpecEncID = EncodingID; sitom(&nr ->PlatformSpecEncID); nr ->LanguageID = (short)CountryInfo.LangID; sitom(&nr ->LanguageID); nr ->NameID = (short)rec; sitom(&nr ->NameID); strwcat( strp,namerecstr[rec]); slen = strwlen(namerecstr[rec]); nr -> StringLength = (short)slen; sitom(&nr -> StringLength ); strsiz += slen; nr -> StringOfs = strofs; sitom(&nr -> StringOfs); strofs += (short)slen; } nt->FormSel = 0; nt->NRecs = NUMOFNAMEREC; sitom( &nt->NRecs); *siz = strsiz+ sizeof(struct NamingTable) + sizeof(struct NameRecord)*NUMOFNAMEREC; } static void modifyOS2( char *buf) { /* Allow all license */ *(buf+9) = (char)0x00; /* Set aulUnicodeRange Privete Use Area bit*/ *(buf+0x31) |= 0x31; } static void modifyhead( struct HeadTable *head) { head->chkSum=0L; memset( head->createdDate, 0, 8); memset( head->updatedDate, 0, 8); head->indexToLocFormat = 1; head->glyphDataFormat = 0; sitom( &head->indexToLocFormat ); sitom( &head->glyphDataFormat); } /* * Set Vertical Header with Horizontal Header and Bounding Box */ static void setVhea( struct VheaTable *vhea, struct HheaTable *hhea, struct BBX *bbx) { memcpy( vhea, hhea, sizeof(struct HheaTable)); vhea->minTopSideBearing = 0; vhea->minBottomSideBearing = 0; vhea->caretSlopeRise = 0; vhea->caretSlopeRun = 1; sitom( &vhea->caretSlopeRun ); vhea->numOfLongVerMetrics = (short)numOfGlyph; sitom( &vhea->numOfLongVerMetrics ); } static int updateMaxp( struct MaxpTbl *maxp, int lstHdl) { struct VHEAD *vhd; short sval; int nCnt; int ttlPnt; int updflg; updflg = 0; if ( (nCnt = VDGetNCont( lstHdl))<0) goto ERET; else if ( nCnt ==0) goto RET; sval = maxp->maxContours; smtoi( &sval); if ( sval < nCnt) { sval = (short)nCnt; sitom(&sval); maxp->maxContours = sval; updflg = 1; } if (VDGetHead( lstHdl, &vhd)) goto ERET; ttlPnt = 0; while ( nCnt-->0) { ttlPnt += vhd->nPoints; vhd = vhd->next; } sval = maxp->maxPoints; smtoi( &sval); if ( sval < ttlPnt) { sval = (short)ttlPnt; sitom(&sval); maxp->maxPoints = sval; updflg = 1; } RET: return updflg; ERET: return -1; } /*********************************************************************** * Obtain Original TTF Table Size */ /* */ static int /* */ TTFGetOrgTableEntry( /* */ HDC hDC, /* */ struct TableEntry *entry, /* */ char *tag) /* * returns : 0, -1 ***********************************************************************/ { DWORD dwTable; /* Metric Table to request */ DWORD siz; dwTable = *(DWORD *)tag; siz = GetFontData(hDC, dwTable, (DWORD)0, (char *)0, (DWORD)0); if ( siz == GDI_ERROR) return -1; else { memcpy( entry->tagName, tag, TAGSIZ); entry->siz = (long)siz; return 0; } } /*********************************************************************** * Read Original TTF Table */ /* */ int /* */ TTFReadOrgFixedTable ( /* */ HDC hDC, /* Handle to DC */ /* */ char *buf, /* Read Buffer */ /* */ int bufsiz, /* Buffer Siz */ /* */ char *tag) /* TagName */ /* * returns : 0, -1 ***********************************************************************/ { DWORD dwTable; /* Metric Table to request */ DWORD siz; dwTable = *(DWORD *)tag; siz = GetFontData(hDC, dwTable, (DWORD)0, buf,(DWORD)bufsiz ); if ( (int)siz != bufsiz) return -1; else return 0; } /*********************************************************************** * Read Variable Size Table at onece with tag */ /* */ int /* */ TTFReadOrgVarTable( /* */ HDC hDC, /* */ char **buf, /* Buffer pointer (be set) */ /* */ unsigned int *bufsiz, /* Buffer Size ( be set) */ /* */ char *tag) /* Tag name */ /* * returns : 0, -1 * remarks : allocated memory must be free by caller ***********************************************************************/ { struct TableEntry te; char *mem; if (TTFGetOrgTableEntry( hDC, &te, tag)) goto ERET; if ((mem = (char *)malloc( (size_t)te.siz))==(char *)0) goto ERET; if ( TTFReadOrgFixedTable ( hDC, mem,(int)te.siz , tag)) goto ERET; *buf = mem; *bufsiz = (unsigned int)te.siz; return 0; ERET: return -1; } static void setCountryData(short EncodingID) { unsigned short lastCode; makeUniCodeTbl(); lastCode = getMaxUniCode(); numOfGlyph = lastCode - EUDCCODEBASE +1 + 2; /* +null, +missing */ cmapdata[6] = (char)((EncodingID>>8)&(unsigned short)0xff); cmapdata[7] = (char)(EncodingID&(unsigned short)0xff); cmapdata[26] = (char)((lastCode>>8)&(unsigned short)0xff); cmapdata[27] = (char)(lastCode&(unsigned short)0xff); maxpdata[4] = (char)((numOfGlyph>>8)&(unsigned short)0xff); maxpdata[5] = (char)(numOfGlyph&(unsigned short)0xff); } static int WIFEOS2( HDC hDC, char **os2buf, int *os2TblSiz, struct BBX *bbx) { struct OS2Table *os2tbl; int siz; TEXTMETRIC tm; static PANOSE msminPanose= { (char)2, (char)2, (char)6, (char)9, (char)4, (char)2, (char)5, (char)8, (char)3, (char)4}; if ( GetTextMetrics( hDC, &tm)==0) goto ERET; siz = sizeof( struct OS2Table); if ((os2tbl = (struct OS2Table *)malloc(sizeof(struct OS2Table)))==0) goto ERET; memset( os2tbl, 0, sizeof(struct OS2Table)); os2tbl->version = 1; sitom( (short *)&os2tbl->version); os2tbl->xAvgCharWidth = bbx->xMax+1; sitom( &os2tbl->xAvgCharWidth ); os2tbl->usWeightClass = tm.tmWeight? (unsigned short)tm.tmWeight : 500; sitom( (short *)&os2tbl->usWeightClass ); os2tbl->usWidthClass = 5; /* Medium */ sitom( (short *)&os2tbl->usWidthClass ); os2tbl->fsType = 0x0000; /* Allow all liscence */ sitom( &os2tbl->fsType ); os2tbl->ySubscriptXSize = (bbx->xMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySubscriptXSize ); os2tbl->ySubscriptYSize = (bbx->yMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySubscriptYSize ); os2tbl->ySubscriptXOffset = 0; /* 1/4kaku */ sitom( &os2tbl->ySubscriptXOffset ); os2tbl->ySubscriptYOffset = 0; /* 1/4kaku */ sitom( &os2tbl->ySubscriptYOffset ); os2tbl->ySuperscriptXSize = (bbx->xMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySuperscriptXSize ); os2tbl->ySuperscriptYSize = (bbx->yMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySuperscriptYSize ); os2tbl->ySuperscriptXOffset = (bbx->xMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySuperscriptXOffset ); os2tbl->ySuperscriptYOffset = (bbx->yMax+1)/2; /* 1/4kaku */ sitom( &os2tbl->ySuperscriptYOffset ); os2tbl->yStrikeoutSize = bbx->yMax/20; /* 5% */ sitom( &os2tbl->yStrikeoutSize ); os2tbl->yStrikeoutPosition = bbx->yMax/4; /* 25% */ sitom( &os2tbl->yStrikeoutPosition ); os2tbl->sFamilyClass = 0; /* no classification */ sitom( &os2tbl->sFamilyClass ); os2tbl->panose = msminPanose; os2tbl->fsSelection = 0x40; sitom( (short *)&os2tbl->fsSelection ); os2tbl->usFirstCharIndex = 0x20; sitom( (short *)&os2tbl->usFirstCharIndex ); os2tbl->usLastCharIndex = 0xffe5; sitom( (short *)&os2tbl->usLastCharIndex ); os2tbl->sTypoAscender = bbx->yMax+1; sitom( &os2tbl->sTypoAscender ); os2tbl->sTypoDescender = -(bbx->yMax/8); sitom( &os2tbl->sTypoDescender ); os2tbl->sTypoLineGap = 0; sitom( &os2tbl->sTypoLineGap ); os2tbl->usWinAscent = bbx->yMax+1; sitom( (short *)&os2tbl->usWinAscent ); os2tbl->usWinDescent = bbx->yMax/8; sitom( (short *)&os2tbl->usWinDescent ); *os2TblSiz = sizeof( struct OS2Table); *os2buf = (char *)os2tbl; return 0; ERET: return -1; } static void WIFEhhea( struct HheaTable *hhea, struct BBX *bbx) { memset( hhea, 0, sizeof(struct HheaTable)); hhea->version[1] = (char)1; hhea->Ascender = bbx->yMax+1; sitom( &hhea->Ascender); hhea->Descender = -(bbx->yMax/8); sitom( &hhea->Descender); hhea->LineGap = 0; sitom( &hhea->LineGap); hhea->advanceWidthMax = bbx->xMax+1; sitom( &hhea->advanceWidthMax); hhea->minLeftSideBearing = 0; sitom( &hhea->minLeftSideBearing); hhea->minRightSideBearing = 0; sitom( &hhea->minRightSideBearing); hhea->xMaxExtent = bbx->xMax+1; sitom( &hhea->xMaxExtent); hhea->caretSlopeRise = 1; sitom( &hhea->caretSlopeRise); hhea->caretSlopeRun = 0; sitom( &hhea->caretSlopeRun); hhea->numberOfHMetrics = (short)numOfGlyph; sitom( &hhea->numberOfHMetrics); } static void WIFEhead( struct HeadTable *head, struct BBX *bbx) { memset( head, 0, sizeof( struct HeadTable)); head->version[1] = 0x1; head->magicNumber=0x5f0F3CF5L; litom((long *)&head->magicNumber); head->flags = 0; sitom( &head->flags); head->unitsPerEm = bbx->xMax - bbx->xMin+1; head->unitsPerEm = ((bbx->xMax - bbx->xMin+1)*9+4)/8; sitom( &head->unitsPerEm); head->xMin = (short)bbx->xMin; sitom( &head->xMin); head->xMax = (short)bbx->xMax; sitom( &head->xMax); // head->yMin = (short)bbx->yMin; head->yMin = -(bbx->yMax/8); sitom( &head->yMin); head->yMax = (short)bbx->yMax; sitom( &head->yMax); head->lowestRecPPEM = 25; sitom( &head->lowestRecPPEM); head->fontDirectionHint = 1; sitom( &head->fontDirectionHint); head->indexToLocFormat = 1; sitom( &head->indexToLocFormat); } static void WIFEpost( struct postTable *post) { memset( post, 0, sizeof( struct postTable)); post->FormatType[1]=0x3; post->underlineThickness = 12; sitom( &post->underlineThickness); post->isFixedPitch = 1; litom( (long *)&post->isFixedPitch); } static short getEncID( HDC hDC, int fontType) { if ( CountryInfo.LangID==EUDC_KRW) return (short)1; else return (short)1; } /*********************************************************************** * Create TTF */ /* */ int /* */ TTFCreate( /* */ HDC hDC, /* Handle to DC */ /* */ TCHAR *newf, /* Create TTF Path */ /* */ struct BBX *bbx, /* the same as original 'head'*/ /* */ /* but minX should be 0 */ /* */ int lstHdl, /* missing glyf list */ /* */ /* bbx, hM, LstHdl is for Missing Glyf*/ /* */ int fontType) /* 0:TrueType, 1:WIFE */ /* * returns : 0, -1 ***********************************************************************/ { HANDLE nfh; struct TTFHeader hdr; struct TableEntry *te, /* Directory Entry */ nte; char *nameBuf; int nameBufSiz; struct HheaTable hhea; struct VheaTable vhea; struct HeadTable head; struct HMetrics *hmet; struct VMetrics *vmet; long *loca; long ofs; char *glyphData; int gdatsiz; int i; char *os2buf; int os2siz; struct BBX cbbx; /* bounding box for each glyph*/ struct HMetrics hM; /* horizontal metrics for each glyph */ struct VMetrics vM; /* Vertical one */ struct postTable postTbl; /* post table */ short EncodingID; DWORD nByte; BOOL res; // nfh = -1; te = 0; nameBuf = 0; hmet = 0; loca = 0; glyphData = 0; os2buf = 0; /* Determin PlatformSpcificEncodingID */ if ((EncodingID = getEncID( hDC, fontType))<(short)0) goto ERET; /* Set cmapdata,maxpdata,numOfGlyph,lastCode */ setCountryData(EncodingID); /* Open files */ nfh = CreateFile(newf, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if ( nfh == INVALID_HANDLE_VALUE) goto ERET; /* Write header */ makeTTFHeader( &hdr, NUMTABLES); if ( TTFWriteHdr( nfh, &hdr)) goto ERET; /* Allocate dir entry area */ if ( (te =(struct TableEntry *)malloc((size_t)sizeof(struct TableEntry)*NUMTABLES))==0) goto ERET; /* * DirEntry Dummy Write */ memset( te, 0, sizeof(struct TableEntry)*NUMTABLES); res = WriteFile( nfh, te, sizeof(struct TableEntry)*NUMTABLES, &nByte, NULL); if (!res || nByte != sizeof(struct TableEntry)*NUMTABLES) goto ERET; initDirEntry(te, NUMTABLES ); /* * 'cvt ' Write */ if (TTFAppendTable( nfh, &nte, cvtdata, sizeof cvtdata)) goto ERET; if ( setDirEntry( &nte, "cvt ")) goto ERET; /* * 'fpgm' Write */ if (TTFAppendTable( nfh, &nte, fpgmdata, sizeof fpgmdata)) goto ERET; if ( setDirEntry( &nte, "fpgm")) goto ERET; /* * 'prep' write */ if (TTFAppendTable( nfh, &nte, prepdata, sizeof prepdata)) goto ERET; if ( setDirEntry( &nte, "prep")) goto ERET; /* * 'name' write */ if ( (nameBuf = (char *)malloc((size_t)NAMEBUFSIZ))==0) goto ERET; setnamebuf(nameBuf, &nameBufSiz, EncodingID); if (TTFAppendTable( nfh, &nte, nameBuf, nameBufSiz)) goto ERET; free( nameBuf); nameBuf = 0; if ( setDirEntry( &nte, "name")) goto ERET; /* * 'cmap' Write */ if (TTFAppendTable( nfh, &nte, cmapdata, sizeof cmapdata)) goto ERET; if ( setDirEntry( &nte, "cmap")) goto ERET; /* * 'OS/2' Copy -> modify */ if ( fontType==0) { if ( TTFReadOrgVarTable( hDC, &os2buf, (unsigned int *)&os2siz, "OS/2")) goto ERET; modifyOS2( os2buf); } else { if (WIFEOS2( hDC, &os2buf, &os2siz, bbx)) goto ERET; } if (TTFAppendTable( nfh, &nte, os2buf, os2siz)) goto ERET; if ( setDirEntry( &nte, "OS/2")) goto ERET; free( os2buf); /* * 'post' Copy */ if ( fontType==0) { if ( TTFMergeTable( hDC, nfh, "post", &nte)) goto ERET; } else { WIFEpost( &postTbl); if (TTFAppendTable( nfh,&nte, (char *)&postTbl,sizeof(struct postTable))) goto ERET; } if ( setDirEntry( &nte, "post")) goto ERET; /* * 'hhea' Read,modify and write */ if ( fontType==0) { if (TTFReadOrgFixedTable( hDC, (char *)&hhea, sizeof hhea,"hhea")) goto ERET; hhea.metricDataFormat = 0; hhea.numberOfHMetrics = (short)numOfGlyph; sitom( &hhea.numberOfHMetrics ); } else { WIFEhhea( &hhea, bbx); } if (TTFAppendTable( nfh, &nte, &hhea, sizeof hhea)) goto ERET; if ( setDirEntry( &nte, "hhea")) goto ERET; /* * 'vhea' */ setVhea( &vhea, &hhea, bbx); if (TTFAppendTable( nfh, &nte, &vhea, sizeof vhea)) goto ERET; if ( setDirEntry( &nte, "vhea")) goto ERET; /* Make metrics for missing Glyph */ cbbx = *bbx; makeMetrics( lstHdl, &hM, &vM, &cbbx); /* * 'vmtx' */ if ((vmet=(struct VMetrics *)malloc( (size_t)sizeof(struct VMetrics)*numOfGlyph))==0) goto ERET; memset(vmet, 0, sizeof(struct VMetrics)*numOfGlyph); /* for missing Glyph */ *vmet = vM; sitom(&vmet->advanceHeight ); sitom(&vmet->topSideBearing ); /* for null Glyph */ (vmet+1)->advanceHeight = 0; (vmet+1)->topSideBearing = 0; if (TTFAppendTable( nfh,&nte,vmet,sizeof(struct VMetrics)*numOfGlyph)) goto ERET; if ( setDirEntry( &nte, "vmtx")) goto ERET; free( vmet); vmet = 0; /* * head Read,modify and write */ if ( fontType==0) { if (TTFReadOrgFixedTable( hDC,(char *)&head, sizeof head,"head")) goto ERET; modifyhead( &head); } else { WIFEhead( &head, bbx); } if (TTFAppendTable( nfh, &nte, &head, sizeof head)) goto ERET; if ( setDirEntry( &nte, "head")) goto ERET; /* * make hmtx */ if ((hmet=(struct HMetrics *)malloc( (size_t)sizeof(struct HMetrics)*numOfGlyph))==0) goto ERET; memset(hmet, 0, sizeof(struct HMetrics)*numOfGlyph); /* for missing Glyph */ *hmet = hM; sitom(&hmet->advanceWidth ); sitom(&hmet->leftSideBearing); /* for null Glyph */ (hmet+1)->advanceWidth = 0; (hmet+1)->leftSideBearing = 0; if (TTFAppendTable( nfh,&nte,hmet,sizeof(struct HMetrics)*numOfGlyph)) goto ERET; if ( setDirEntry( &nte, "hmtx")) goto ERET; free( hmet); hmet = 0; if ((glyphData = (char *)malloc((size_t)GLYPHBUFSIZ))==0) goto ERET; if (makeGlyphData( lstHdl, &cbbx, glyphData, GLYPHBUFSIZ, &gdatsiz )) goto ERET; /* * 'loca' make */ if ((loca = (long *)malloc( (size_t)sizeof(unsigned long)*(numOfGlyph+1)))==(long *)0) goto ERET; *loca = 0; ofs = gdatsiz; litom(&ofs); for ( i = 1; i< numOfGlyph+1; i++) *(loca + i)=ofs; if (TTFAppendTable( nfh,&nte,loca,sizeof( long)*(numOfGlyph+1))) goto ERET; if ( setDirEntry( &nte, "loca")) goto ERET; free( loca); loca = 0; /* * 'maxp' write */ if (TTFAppendTable( nfh,&nte,maxpdata,sizeof(maxpdata))) goto ERET; if ( setDirEntry( &nte, "maxp")) goto ERET; /* * 'glyf' Write (missing glyph ) */ if (TTFAppendTable( nfh, &nte, glyphData, gdatsiz)) goto ERET; if ( setDirEntry( &nte, "glyf")) goto ERET; free( glyphData); glyphData = 0; /* Sort dir entry table */ SortEntry( te, NUMTABLES); /* Write dir entry */ if (TTFWriteDirEntry( nfh, te, NUMTABLES)) goto ERET; /* Set Check sum of file whole to head */ if (fileChkSum( nfh, te, NUMTABLES, &hdr, &head)) goto ERET; CloseHandle( nfh); if ( te) free( te); return 0; ERET: if ( nfh != INVALID_HANDLE_VALUE) CloseHandle( nfh); if ( te) free( te); if ( nameBuf) free( nameBuf); if ( hmet) free( hmet); if ( loca) free( loca); if ( os2buf) free( os2buf); if ( glyphData) free( glyphData); return -1; } /*********************************************************************** * Obtain BoundingBox ( from 'head' xMin, xMax, yMin, yMax) */ /* */ int /* */ TTFGetBBX( /* */ HDC hDC, /* */ struct BBX *bbx, /* */ short *uPEm) /* * returns : 0, -1 ***********************************************************************/ { struct HeadTable head; DWORD dwTable; /* tagName to request */ DWORD siz, s; memcpy( &dwTable, "head", TAGSIZ); siz = (DWORD)sizeof( struct HeadTable); if ((s=GetFontData(hDC, dwTable, (DWORD)0, &head,(DWORD)siz))!=siz){ DWORD err = GetLastError(); return -1; } smtoi( &head.xMin); smtoi( &head.xMax); smtoi( &head.yMin); smtoi( &head.yMax); smtoi( &head.unitsPerEm); bbx->xMin = head.xMin; bbx->xMax = head.xMax; bbx->yMin = head.yMin; bbx->yMax = head.yMax; *uPEm = head.unitsPerEm; if ( bbx->xMin < 0 ) bbx->xMin = 0; return 0; } int TTFTmpPath( TCHAR *path, TCHAR *tmpPath) { TCHAR *p1; TCHAR dirPath[MAX_PATH]; lstrcpy( dirPath, path); p1 = Mytcsrchr( dirPath, '\\'); if ( p1==(TCHAR *)0) { p1 = Mytcsrchr( dirPath, ':'); if (p1==(TCHAR *)0) *dirPath=(TCHAR)0; else *(p1+1)=0; } else *p1=0; if (GetTempFileName( dirPath, TEXT("TTE"), 0, tmpPath)==0) return -1; else return 0; } static int copyTable( HANDLE iFh,HANDLE oFh, struct TableEntry *te, int nEntry, char *tag) { struct TableEntry *tep; char *buf = NULL; if ((tep = searchEntry(te, nEntry, tag))==(struct TableEntry *)0) goto ERET; if ((buf = (char *)malloc((size_t)tep->siz))==(char *)0) goto ERET; if ( (TTFReadTable( iFh,tep, buf, (int)tep->siz)!=(int)tep->siz) ) goto ERET; if ( (TTFWriteTable( oFh,tep, buf, (int)tep->siz)!=(int)tep->siz) ) goto ERET; free(buf); return 0; ERET: if (buf) free(buf); return -1; } static int copyfblock( HANDLE iFh, HANDLE oFh, unsigned long siz, unsigned long *cs) { int rwsiz; int filsiz; int aligne; unsigned long chksum; char *buf; if ((buf = (char *)malloc((size_t) RWBUFSIZ))==(char *)0) goto ERET; filsiz = (int)(siz % 4); if ( filsiz) filsiz = 4-filsiz; aligne =0; chksum = 0; while ( siz > 0) { if ( siz > RWBUFSIZ) rwsiz = RWBUFSIZ; else { rwsiz = (int)siz; if ( filsiz) aligne =1; } DWORD nByte; BOOL res = ReadFile(iFh, buf,(unsigned int)rwsiz, &nByte, NULL ); if (!res || nByte != (unsigned int)rwsiz) goto ERET; if ( aligne ) { memset( buf+siz, 0, filsiz); rwsiz += filsiz; } chksum += calchksum( buf, rwsiz); res = WriteFile ( oFh, buf, (unsigned int)rwsiz, &nByte, NULL); if (!res || nByte !=(unsigned int)rwsiz) goto ERET; siz -= rwsiz; } *cs = chksum; free(buf); return 0; ERET: if(buf) free(buf); return -1; } static int mergeGlyph( HANDLE iFh, HANDLE oFh, struct TableEntry *tep, char *locabuf, int glyphID, char *glyphData, int glyphSiz) { long *locp; long nloc, cloc; long iofs; long tail; long siz; int gid; long delta; unsigned long cs; int filsiz; long lval; locp = (long *)locabuf; cs = 0; /* copy leading */ cloc = *locp; lmtoi( &cloc); iofs = (unsigned long)tep->ofs+cloc; if ((long) SetFilePointer( iFh, iofs, NULL, FILE_BEGIN) != iofs) goto ERET; if ((long) SetFilePointer( oFh, iofs, NULL, FILE_BEGIN) != iofs) goto ERET; cloc = *(locp + glyphID); lmtoi( &cloc); nloc = *(locp + glyphID+1); lmtoi( &nloc); siz = nloc - cloc; if (copyfblock( iFh, oFh, cloc, &cs)) goto ERET; /* write glyphData */ if ( glyphSiz>0L) { filsiz = glyphSiz % 4; if ( filsiz) { filsiz = 4 - filsiz; memset( glyphData+glyphSiz, 0, filsiz); glyphSiz += filsiz; } DWORD nByte; BOOL res = WriteFile( oFh, glyphData, (unsigned int)glyphSiz, &nByte, NULL); if (!res || nByte !=(unsigned int)glyphSiz) goto ERET; cs += calchksum( glyphData, glyphSiz); } iofs = nloc + tep->ofs; /* copy trailer */ if ((long) SetFilePointer( iFh, iofs, NULL, FILE_BEGIN) != iofs) goto ERET; tail = *(locp+numOfGlyph); lmtoi(&tail); siz = tail - nloc; if (copyfblock( iFh, oFh, siz, &cs)) goto ERET; /* update loca */ delta = glyphSiz - (nloc - cloc); for ( gid = glyphID+1; gid<=numOfGlyph; gid++) { lval = *(locp+gid); lmtoi(&lval); lval += delta; litom(&lval); *(locp+gid)=lval; } tep->siz = tail+delta; return 0; ERET: return -1; } /*********************************************************************** * Add EUDC Font */ /* */ int /* */ TTFAddEUDCChar( /* */ TCHAR *path, /* EUDC FontFile path */ /* */ unsigned short code, /* Charcode */ /* */ struct BBX *bbx, /* Bounding Box */ /* */ int lstH) /* List Handle for glyph */ /* * returns :0, -1 ***********************************************************************/ { struct TTFHeader hdr; struct HeadTable head; struct MaxpTbl maxp; HANDLE fH; HANDLE tmpFh = INVALID_HANDLE_VALUE; struct TableEntry *te; struct TableEntry *tep; struct TableEntry *maxpTep; struct TableEntry *locaTep; int glyphID; struct HMetrics hmet; struct VMetrics vmet; int nEntry; char *updbuf; char *glyphData; int bufsiz; int gdatsiz; short sval; struct BBX cbbx; TCHAR tmpPath[MAX_PATH]; TCHAR savPath[MAX_PATH]; int sts; HINSTANCE hInst = AfxGetInstanceHandle(); TCHAR szMessage[256]; lastErr = 0; te = ( struct TableEntry *)0; updbuf = (char *)0; glyphData = (char *)0; fH = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( fH == INVALID_HANDLE_VALUE) goto ERET; TTFTmpPath( path, tmpPath); if ( tmpPath[0] == NULL ) goto ERET; tmpFh = CreateFile(tmpPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if ( tmpFh == INVALID_HANDLE_VALUE) goto ERET; if ( TTFReadHdr( fH, &hdr)) goto ERET; if ( TTFWriteHdr( tmpFh, &hdr)) goto ERET; nEntry = hdr.numTables; glyphID = codeToGID( code); /* Read Table entries */ if ( (te = (struct TableEntry *)malloc((size_t)sizeof(struct TableEntry)*NUMTABLES))==0) goto ERET; if (TTFReadDirEntry( fH, te, nEntry)) goto ERET; if (TTFWriteDirEntry( tmpFh, te, nEntry)) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "cvt ")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "fpgm")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "prep")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "name")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "cmap")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "OS/2")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "post")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "hhea")) goto ERET; if (copyTable( fH, tmpFh, te, nEntry, "vhea")) goto ERET; /* Read maxp Table */ if ((maxpTep = searchEntry(te, nEntry, "maxp"))==0) goto ERET; if ( TTFReadTable( fH, maxpTep, &maxp, sizeof maxp)!=(sizeof maxp) ) goto ERET; sval = maxp.numGlyph; smtoi( &sval); numOfGlyph = sval; // Glyph is out of TTE file range, Win9x upgrade if (glyphID >= numOfGlyph) goto ERET; bufsiz = sizeof(struct HMetrics)*(numOfGlyph); bufsiz = align32( bufsiz); if ( (updbuf = (char *)malloc( (size_t)bufsiz))==0) goto ERET; /* make metrics for the glyph */ cbbx = *bbx; makeMetrics( lstH, &hmet, &vmet, &cbbx); /* make glyph data */ if ((glyphData = (char *)malloc((size_t)GLYPHBUFSIZ))==0) goto ERET; if (sts=makeGlyphData(lstH, &cbbx, glyphData, GLYPHBUFSIZ, &gdatsiz)) { lastErr = sts; goto ERET; } /* set hmetrics */ sitom( &hmet.advanceWidth); sitom( &hmet.leftSideBearing); if ((tep = searchEntry(te, nEntry, "hmtx"))==0) goto ERET; if ( TTFReadTable( fH, tep, updbuf, bufsiz)<=0) goto ERET; *((struct HMetrics *)updbuf + glyphID) = hmet; if ( TTFWriteTable( tmpFh, tep, updbuf, bufsiz)<=0) goto ERET; free( updbuf); updbuf = 0; /* Update 'vmtx' */ bufsiz = sizeof(struct VMetrics)*(numOfGlyph); bufsiz = align32( bufsiz); if ( (updbuf = (char *)malloc( (size_t)bufsiz))==0) goto ERET; /* set vmetrics */ sitom( &vmet.advanceHeight); sitom( &vmet.topSideBearing); if ((tep = searchEntry(te, nEntry, "vmtx"))==0) goto ERET; if ( TTFReadTable( fH, tep, updbuf, bufsiz)<=0) goto ERET; *((struct VMetrics *)updbuf + glyphID) = vmet; if ( TTFWriteTable( tmpFh, tep, updbuf, bufsiz)<=0) goto ERET; free( updbuf); updbuf = 0; /* Read loca */ bufsiz = sizeof(long )*(numOfGlyph+1); bufsiz = align32( bufsiz); if ( (updbuf = (char *)malloc((size_t)bufsiz)) ==(char *)0) goto ERET; if ((locaTep = searchEntry(te, nEntry, "loca"))==0) goto ERET; if ( TTFReadTable( fH, locaTep, updbuf, bufsiz)<=0) goto ERET; /* move glyf data */ if ((tep = searchEntry(te, nEntry, "glyf"))==0) goto ERET; if (mergeGlyph( fH, tmpFh, tep, updbuf, glyphID, glyphData, gdatsiz )) goto ERET; /* read and cal checkSum of 'glyf' */ if (tableChkSum( tmpFh, tep)) goto ERET; free( glyphData); glyphData =(char *)0; /* write loca */ if ( TTFWriteTable( tmpFh, locaTep, updbuf, bufsiz)<=0) goto ERET; /* update maxp */ if ( updateMaxp( &maxp, lstH) < 0) goto ERET; if (TTFWriteTable(tmpFh, maxpTep, &maxp, sizeof maxp)!=(sizeof maxp)) goto ERET; /* update directory entry */ if (TTFWriteDirEntry( tmpFh, te, nEntry)) goto ERET; /* Set Check sum of file whole to head */ if ((tep = searchEntry(te, nEntry, "head"))==0) goto ERET; if ( TTFReadTable( fH, tep, &head, sizeof head)<=0) goto ERET; tep->checkSum = 0L; if ( TTFWriteTable( tmpFh, tep, &head, sizeof head)<=0) goto ERET; if (fileChkSum(tmpFh , te, nEntry, &hdr, &head)) goto ERET; if ( TTFWriteTable( tmpFh, tep, &head, sizeof head)<=0) goto ERET; CloseHandle( fH); CloseHandle( tmpFh); // fH = tmpFh = -1; TTFTmpPath( path, savPath); if( DeleteFile( savPath)==0) { TCHAR szTitle[256]; LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR)); LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR)); MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK); goto ERET2; } if( MoveFile( path, savPath)==0) { TCHAR szTitle[256]; LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR)); LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR)); MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK); goto ERET2; } if( MoveFile( tmpPath, path)==0) { TCHAR szTitle[256]; LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR)); LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR)); MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK); goto ERET2; } if ( DeleteFile( savPath) ==0) { DeleteFile(path); MoveFile(savPath, path); if ( te) free(te); if ( updbuf) free(updbuf); if ( glyphData) free(glyphData); return -3; //tte file is being used by another process } free( te); free( updbuf); return 0; ERET: if ( fH != INVALID_HANDLE_VALUE) CloseHandle(fH); if ( tmpFh != INVALID_HANDLE_VALUE) CloseHandle(tmpFh); if ( te) free(te); if ( updbuf) free(updbuf); if ( glyphData) free(glyphData); return -1; ERET2: if ( fH != INVALID_HANDLE_VALUE) CloseHandle(fH); if ( tmpFh != INVALID_HANDLE_VALUE) CloseHandle(tmpFh); if ( te) free(te); if ( updbuf) free(updbuf); if ( glyphData) free(glyphData); if ( tmpPath) DeleteFile( tmpPath); return -1; } /*********************************************************************** * For Import */ static HANDLE eudcFh; static char *locaBuf = 0; static char *maxpBuf = 0; static char *hmtxBuf = 0; static char *vmtxBuf = 0; static char *glyphBuf = 0; static void frebuf() { if ( locaBuf) { free( locaBuf); locaBuf = 0; } if ( maxpBuf) { free( maxpBuf); maxpBuf = 0; } if ( vmtxBuf) { free( vmtxBuf); vmtxBuf = 0; } if ( hmtxBuf) { free( hmtxBuf); hmtxBuf = 0; } if ( glyphBuf) { free( glyphBuf); glyphBuf = 0; } if ( et) { free( et); glyphBuf = 0; } return; } int TTFOpen( TCHAR *path) { struct TTFHeader hdr; unsigned int bufsiz; unsigned short sval; et = 0; eudcFh = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( eudcFh == INVALID_HANDLE_VALUE) goto ERET; if (TTFReadHdr(eudcFh,&hdr)) goto ERET; if ((et = (struct TableEntry *)malloc( sizeof (struct TableEntry)*hdr.numTables)) ==0) goto ERET; entryNum = hdr.numTables; if (TTFReadDirEntry(eudcFh, et, hdr.numTables)) goto ERET; if (TTFReadVarTable( eudcFh, &maxpBuf, &bufsiz, "maxp")) goto ERET; sval = ((struct MaxpTbl *)maxpBuf) ->numGlyph; smtoi( (short *)&sval); numOfGlyph = sval; if (TTFReadVarTable( eudcFh, &locaBuf, &bufsiz, "loca")) goto ERET; if (TTFReadVarTable( eudcFh, &hmtxBuf, &bufsiz, "hmtx")) goto ERET; if (TTFReadVarTable( eudcFh, &vmtxBuf, &bufsiz, "vmtx")) goto ERET; if ((glyphBuf = (char *)malloc( GLYPHBUFSIZ))==0) goto ERET; return 0; ERET: if ( eudcFh != INVALID_HANDLE_VALUE) { CloseHandle( eudcFh); eudcFh = INVALID_HANDLE_VALUE; } frebuf(); return -1; } int TTFClose() { struct TableEntry *tep; struct HeadTable head; struct TTFHeader hdr; long ofs; if ( eudcFh == INVALID_HANDLE_VALUE) return -1; if (TTFReadHdr( eudcFh, &hdr)) goto ERET; /* obtain glyph table size */ ofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END); /* Update Glyph checkSum */ if ((tep = searchEntry(et, entryNum, "glyf"))==0) goto ERET; tep->siz = ofs - tep->ofs; /* read and cal checkSum of 'glyf' */ if (tableChkSum( eudcFh, tep)) goto ERET; if ((tep = searchEntry(et, entryNum, "maxp"))==0) goto ERET; if (TTFWriteTable( eudcFh, tep, maxpBuf, (int)tep->siz)!=(int)tep->siz) goto ERET; if ((tep = searchEntry(et, entryNum, "loca"))==0) goto ERET; if (TTFWriteTable( eudcFh, tep, locaBuf, (int)tep->siz)!=(int)tep->siz) goto ERET; if ((tep = searchEntry(et, entryNum, "hmtx"))==0) goto ERET; if (TTFWriteTable( eudcFh, tep, hmtxBuf, (int)tep->siz)!=(int)tep->siz) goto ERET; if ((tep = searchEntry(et, entryNum, "vmtx"))==0) goto ERET; if (TTFWriteTable( eudcFh, tep, vmtxBuf, (int)tep->siz)!=(int)tep->siz) goto ERET; if ((tep = searchEntry(et, entryNum, "head"))==0) goto ERET; if ( TTFReadTable(eudcFh, tep, &head, sizeof(head))!=sizeof(head)) goto ERET; if ( fileChkSum(eudcFh, et, entryNum, &hdr, &head)) goto ERET; if ( TTFWriteDirEntry( eudcFh, et, entryNum)) goto ERET; CloseHandle( eudcFh); frebuf(); return 0; ERET: CloseHandle( eudcFh); frebuf(); return -1; } int TTFGetEUDCBBX(TCHAR *path, struct BBX *bbx, short *upem) { struct HeadTable head; HANDLE fH; fH = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( fH == INVALID_HANDLE_VALUE) goto ERET; if ( TTFReadFixedTable(fH, (char *)&head,sizeof head,"head")) goto ERET; smtoi( &head.xMin); smtoi( &head.xMax); smtoi( &head.yMin); smtoi( &head.yMax); smtoi( &head.unitsPerEm); bbx->xMin = head.xMin; bbx->xMax = head.xMax; bbx->yMin = head.yMin; bbx->yMax = head.yMax; *upem = head.unitsPerEm; if ( bbx->xMin < 0 ) bbx->xMin = 0; CloseHandle( fH); return 0; ERET: if (fH!=INVALID_HANDLE_VALUE) CloseHandle( fH); return -1; } static void makeMetrics(int lsthdl, struct HMetrics *hM, struct VMetrics *vM, struct BBX *bbx) { struct VHEAD *vhd; struct VDATA *vp; int np; int sts; int xmin, ymin, xmax, ymax; if ( (sts = VDGetHead( lsthdl, &vhd))!=0) goto RET; if ( (sts = VDGetNCont( lsthdl))<=0) goto SPACE_CHAR; xmin = xmax = vhd->headp->vd.x; ymin = ymax = vhd->headp->vd.y; while ( vhd->next != NIL) { vp = vhd->headp; np = vhd->nPoints; while ( np-->0) { if (vp->vd.x > xmax) xmax = vp->vd.x; else if(vp->vd.x < xmin) xmin = vp->vd.x; if (vp->vd.y > ymax) ymax = vp->vd.y; else if(vp->vd.y < ymin) ymin = vp->vd.y; vp = vp->next; } vhd = vhd->next; } // if ( xmin < 0) // xmin = 0; hM->leftSideBearing = (short)xmin; hM->advanceWidth = bbx->xMax - bbx->xMin; { int hmw = hM->advanceWidth + 1; int ii = 0; while (hmw >> 1) { hmw >>= 1; ii++; } hmw = 1; while (ii--) hmw *= 2; int gap1 = hM->advanceWidth - hmw; int gap2 = hmw*2 - hM->advanceWidth; hmw = gap1 > gap2 ? hmw * 2 : hmw; hM->advanceWidth = (short)hmw; } vM->topSideBearing = bbx->yMax - ymax; if (vM->topSideBearing < 0) vM->topSideBearing = 0; vM->advanceHeight = bbx->yMax - bbx->yMin; bbx->xMin = xmin; bbx->yMin = ymin; bbx->xMax = xmax; bbx->yMax = ymax; return; RET: SPACE_CHAR: hM->leftSideBearing = (short)bbx->xMax; hM->advanceWidth = bbx->xMax - bbx->xMin; vM->topSideBearing = bbx->yMax - bbx->yMin; vM->advanceHeight = bbx->yMax - bbx->yMin; bbx->xMin = bbx->xMax; bbx->yMax = bbx->yMin; return; } int TTFAppend( unsigned short code, struct BBX *bbx, int lsthdl) { int glyphID; struct HMetrics hmet; struct VMetrics vmet; int updflg; int gdatsiz; struct BBX cbbx; int sts; glyphID = codeToGID( code); lastErr = 0; /* make metrics */ cbbx = *bbx; makeMetrics( lsthdl, &hmet, &vmet, &cbbx); /* make glyph data */ if (sts =makeGlyphData(lsthdl, &cbbx, glyphBuf, GLYPHBUFSIZ, &gdatsiz)) { lastErr = sts; goto ERET; } /* set hmetrics */ sitom( &hmet.advanceWidth); sitom( &hmet.leftSideBearing); *((struct HMetrics *)hmtxBuf + glyphID) = hmet; /* Update 'vmtx' */ sitom( &vmet.advanceHeight); sitom( &vmet.topSideBearing); *((struct VMetrics *)vmtxBuf + glyphID) = vmet; /* write glyf data */ if (TTFImpGlyphWrite( glyphID, glyphBuf, gdatsiz)) goto ERET; /* update maxp */ if ((updflg = updateMaxp( (struct MaxpTbl *)maxpBuf, lsthdl)) < 0) goto ERET; return 0; ERET: return -1; } /* * Copy */ int TTFImpCopy( TCHAR *sPath, TCHAR *dPath) { HANDLE sFh, dFh; struct TTFHeader hdr; struct TableEntry *te; int tblSiz; int ntbl; int tcnt; char *buf; int bufsiz; sFh = dFh = 0; te = 0; buf = 0; /* Open src */ sFh = CreateFile(sPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (sFh == INVALID_HANDLE_VALUE) goto ERET; /* create open destination*/ dFh = CreateFile(dPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (dFh == INVALID_HANDLE_VALUE) goto ERET; /* read header */ if ( TTFReadHdr( sFh, &hdr)) goto ERET; ntbl = (int)hdr.numTables; /* write header */ if ( TTFWriteHdr( dFh, &hdr)) goto ERET; /* read directory entry */ tblSiz = sizeof( struct TableEntry)*ntbl; if ((te = (struct TableEntry *)malloc(tblSiz))==(struct TableEntry *)0) goto ERET; if ( TTFReadDirEntry(sFh, te, ntbl)) goto ERET; /* write directory entry */ if ( TTFWriteDirEntry(dFh, te, ntbl)) goto ERET; /* copy each table (except glyph)*/ for ( tcnt = 0; tcnt < ntbl; tcnt++) { if ( memcmp((te+tcnt)->tagName,"glyf", 4)) { bufsiz = (int)(te+tcnt)->siz; buf = (char *)malloc((int)(te+tcnt)->siz); if (TTFReadTable( sFh, te+tcnt, buf, bufsiz)!=bufsiz) goto ERET; if (TTFWriteTable( dFh, te+tcnt, buf, bufsiz)!=bufsiz) goto ERET; free( buf); buf = 0; } } /* close */ CloseHandle( sFh); CloseHandle( dFh); free( te); return 0; ERET: if (sFh != INVALID_HANDLE_VALUE) CloseHandle(sFh); if (dFh != INVALID_HANDLE_VALUE) CloseHandle(dFh); if (te) free( te); if ( buf) free( buf); return -1; } int TTFImpGlyphCopy( HANDLE sFh, int glyphID) { struct TableEntry *tep; long *locap; long cloc, nloc; long siz; long ofs; long wofs; char *buf; DWORD nByte; buf = 0; if ((tep = searchEntry( et, entryNum, "glyf"))==0) goto ERET; locap = (long *)locaBuf; cloc = *(locap+glyphID); lmtoi( &cloc); nloc = *(locap+glyphID+1); lmtoi( &nloc); siz = nloc - cloc; ofs = tep->ofs + cloc; if ( (long) SetFilePointer( sFh, ofs, NULL, FILE_BEGIN) != ofs) goto ERET; wofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END); wofs -= tep->ofs; litom( &wofs); *(locap+glyphID) = wofs; if ( siz) { if ( (buf = (char *)malloc((int)siz))==(char *)0) goto ERET; BOOL res = ReadFile( sFh, buf, (unsigned int)siz, &nByte, NULL); if (!res || nByte !=(unsigned int)siz) goto ERET; res = WriteFile( eudcFh, buf,(unsigned int)siz, &nByte, NULL); if (!res || nByte !=(unsigned int)siz) goto ERET; } free( buf); return 0; ERET: if ( buf) free( buf); return -1; } int TTFImpGlyphWrite( int glyphID, char *glyph, int siz) { struct TableEntry *tep; long ofs; long wofs; long *locap; DWORD nByte; if ( glyphID >= numOfGlyph) return -1; if ((tep = searchEntry( et, entryNum, "glyf"))==0) goto ERET; wofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END); ofs = wofs - tep->ofs; litom( &ofs); locap = (long *)locaBuf; *(locap+glyphID) = ofs; if ( siz) { BOOL res = WriteFile(eudcFh, glyph, (unsigned int)siz, &nByte, NULL); if (!res || nByte !=(unsigned int)siz) goto ERET; } return 0; ERET: return -1; } int TTFImpTerm(HANDLE orgFh, int glyphID) { struct TableEntry *tep; long ofs; long wofs; long *locap; int gid; // // copy the rest of the glyph data over. // for ( gid = glyphID; gid < numOfGlyph; gid++) { if (TTFImpGlyphCopy(orgFh, gid)) return -1; } if ((tep = searchEntry( et, entryNum, "glyf"))==0) return -1; locap = (long *)locaBuf; wofs = SetFilePointer( eudcFh, 0L,NULL, FILE_END); ofs = wofs - tep->ofs; litom( &ofs); *(locap + numOfGlyph) = ofs; tep->siz = wofs - tep->ofs; return 0; } int TTFLastError() { return lastErr; } /* EOF */