Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2664 lines
60 KiB

  1. //
  2. // Copyright (c) 1997-1999 Microsoft Corporation.
  3. //
  4. #include "stdafx.h"
  5. #include "eudcedit.h"
  6. #include "util.h"
  7. #pragma pack(2)
  8. #include "vdata.h"
  9. #include "ttfstruc.h"
  10. #include "extfunc.h"
  11. /*
  12. * TrueType File I/F
  13. */
  14. #define GLYPHBUFSIZ 0xFFFFL
  15. #define RWBUFSIZ 16384
  16. #define EUDCCODEBASE ((unsigned short)0xE000) /* 0xe000 uni-code */
  17. #define NUMTABLES 15
  18. #define NAMEBUFSIZ 1024
  19. #define NUMOFNAMEREC 8
  20. static void initDirEntry(struct TableEntry *e,int num);
  21. static int setDirEntry(struct TableEntry *e,char *tag);
  22. void smtoi(short *sval);
  23. void lmtoi(long *lval);
  24. void sitom(short *sval);
  25. void litom(long *lval);
  26. static int align32(int siz);
  27. static unsigned long calchksum(char *buf,int siz);
  28. static int copyblk(HDC hDC,char *tag,int ofHdl,long siz,char *buf,int bufsiz,unsigned long *cs);
  29. static int mergeblock(HDC hDC,struct TableEntry *entry,int ofHdl);
  30. static int tableChkSum(int fH,struct TableEntry *te);
  31. static int codeToGID(unsigned short code);
  32. int TTFReadHdr(HANDLE fHdl,struct TTFHeader *hdr);
  33. int TTFWriteHdr(HANDLE fHdl,struct TTFHeader *hdr);
  34. int TTFReadDirEntry(HANDLE fHdl,struct TableEntry *entry,int eCnt);
  35. int TTFWriteDirEntry(HANDLE fHdl,struct TableEntry *entry,int eCnt);
  36. static struct TableEntry *searchEntry(struct TableEntry *entry,int eCnt,char *tag);
  37. int TTFGetTableEntry(HANDLE fH,struct TableEntry *entry,char *tag);
  38. int TTFReadTable(HANDLE fH,struct TableEntry *entry,void *buf,int bufsiz);
  39. int TTFReadFixedTable(HANDLE fH,char *buf,int bufsiz,char *tag);
  40. int TTFReadVarTable(HANDLE fH,char * *buf,unsigned int *bufsiz,char *tag);
  41. int TTFWriteTable(HANDLE fH,struct TableEntry *entry,void *buf,int bufsiz);
  42. int TTFAppendTable(HANDLE fH,struct TableEntry *entry,void *buf,int siz);
  43. static int TTFMergeTable(HDC hDC,HANDLE nfh,char *tag,struct TableEntry *nte);
  44. #ifdef BUILD_ON_WINNT
  45. static int __cdecl compentry(const void *e1,const void *e2);
  46. #else
  47. static int compentry(const void *e1,const void *e2);
  48. #endif // BUILD_ON_WINNT
  49. static void SortEntry(struct TableEntry *ebuf,int num);
  50. static int fileChkSum(HANDLE fh,struct TableEntry *entry,int numEntry,struct TTFHeader *hdr,struct HeadTable *head);
  51. static void makeTTFHeader(struct TTFHeader *hdr,int nTbl);
  52. static int makeGlyphData(int lstH,struct BBX *bbx,char *glyphData,int bufsiz,int *gdatsiz);
  53. static void initsetgbuf(char *b,int lim);
  54. static int setgbuf(char *dat,int siz,char * *np);
  55. static int termbuf(void);
  56. static int strwlen(char *s);
  57. static void strwcat(char *s1,char *s2);
  58. static void setnamebuf(char *buf,int *siz, short EncodingID);
  59. static void modifyOS2(char *buf);
  60. static void modifyhead(struct HeadTable *head);
  61. static void setVhea(struct VheaTable *vhea,struct HheaTable *hhea,struct BBX *bbx);
  62. static int updateMaxp(struct MaxpTbl *maxp,int lstHdl);
  63. static int TTFGetOrgTableEntry(HDC hDC,struct TableEntry *entry,char *tag);
  64. int TTFReadOrgFixedTable(HDC hDC,char *buf,int bufsiz,char *tag);
  65. int TTFReadOrgVarTable(HDC hDC,char * *buf,unsigned int *bufsiz,char *tag);
  66. static void setCountryData(short EncodingID);
  67. static int WIFEOS2(HDC hDC,char * *os2buf,int *os2TblSiz,struct BBX *bbx);
  68. static void WIFEhhea(struct HheaTable *hhea,struct BBX *bbx);
  69. static void WIFEhead(struct HeadTable *head,struct BBX *bbx);
  70. static void WIFEpost(struct postTable *post);
  71. int TTFCreate(HDC hDC,TCHAR *newf,struct BBX *bbx,int lstHdl,int fontType);
  72. int TTFGetBBX(HDC hDC,struct BBX *bbx,short *uPEm);
  73. int TTFTmpPath(TCHAR *path,TCHAR *tmpPath);
  74. static int copyTable(HANDLE iFh,HANDLE oFh,struct TableEntry *te,int nEntry,char *tag);
  75. static int copyfblock(HANDLE iFh,HANDLE oFh,unsigned long siz,unsigned long *cs);
  76. static int mergeGlyph(HANDLE iFh,HANDLE oFh,struct TableEntry *tep,char *locabuf,int glyphID,char *glyphData,int glyphSiz);
  77. static void frebuf(void);
  78. int TTFOpen(TCHAR *path);
  79. int TTFClose(void);
  80. int TTFGetEUDCBBX(TCHAR *path,struct BBX *bbx,short *upem);
  81. static void makeMetrics(int lsthdl,struct HMetrics *hM,struct VMetrics *vM,struct BBX *bbx);
  82. int TTFAppend(unsigned short code,struct BBX *bbx,int lsthdl);
  83. int TTFImpCopy(TCHAR *sPath,TCHAR *dPath);
  84. int TTFImpGlyphCopy(HANDLE sFh,int glyphID);
  85. int TTFImpGlyphWrite(int glyphID, char *buf, int siz);
  86. int TTFLastError();
  87. /**
  88. * static variables
  89. **/
  90. static struct TableEntry *et;
  91. static int entryNum;
  92. static int entryCnt;
  93. static int numOfGlyph=0;
  94. static int lastErr = 0;
  95. /**
  96. * static table data
  97. **/
  98. static char cvtdata[] = {0, 0};
  99. static char fpgmdata[]={ (char)0xb0, (char)0x00, (char)0x2c, (char)0x2d};
  100. static char prepdata[]={(char)0xb8, 0x1, (char)0xff, (char)0x85,
  101. (char)0xb0, (char)0x01, (char)0x8d};
  102. static char maxpdata[]={ /* JPN */
  103. 0x00, 0x01, 0x00, 0x00,
  104. (char)0x07, (char)0x5a, /* 1882 numGlyph of JPN */
  105. 0, 4, 0, 1 , /* maxP, maxC(nullGlyf value)*/
  106. 0, 0, 0, 0, /* maxCom*2*/
  107. 0, 1, 0, 0, /* maxZones, maxTw*/
  108. 0, 0, 0, 1, /* maxStorage, maxFunc*/
  109. 0, 0, 0, 1, /* maxI, maxStack */
  110. 0, 1, 0, 1, 0, 1
  111. };
  112. static char cmapdata[] = {
  113. 0, 0, 0, 1,
  114. 0, 3, 0, 1,
  115. 0, 0, 0, 12,
  116. 0, 4, 0, 32, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0,
  117. (char)0xe7, (char)0x57, (char) 0xff,(char) 0xff, /* last code */
  118. 0, 0,
  119. (char)0xe0, (char)0x00, (char)0xff,(char) 0xff,
  120. 0x20, 0x02, 0x00, 0x01,
  121. 0, 0, 0, 0
  122. };
  123. static char namerecstr[NUMOFNAMEREC][16] ={
  124. { 0, '0', 0, '0', 0, 0},
  125. { 0,'E', 0,'U', 0, 'D',0,'C', 0,0},
  126. { 0,'R', 0, 'e', 0,'g', 0,'u', 0,'l', 0,'a', 0,'r',0,0},
  127. { 0, '0', 0,'0', 0, 0},
  128. { 0,'E', 0,'U', 0, 'D',0,'C', 0,0},
  129. { 0, '0', 0,'0', 0, 0},
  130. { 0, '0', 0,'0',0, 0},
  131. { 0, '0', 0,'0',0, 0}
  132. };
  133. static void
  134. initDirEntry( struct TableEntry *e, int num)
  135. {
  136. et = e;
  137. entryNum = num;
  138. entryCnt = 0;
  139. }
  140. static int
  141. setDirEntry(struct TableEntry *e, char *tag)
  142. {
  143. if ( entryCnt >= entryNum)
  144. return -1;
  145. memcpy( e->tagName, tag, TAGSIZ);
  146. *(et+entryCnt) = *e;
  147. entryCnt++;
  148. return 0;
  149. }
  150. void
  151. smtoi( short *sval)
  152. {
  153. short retval;
  154. unsigned char *cp;
  155. cp = (unsigned char *)sval;
  156. retval = *cp++;
  157. retval <<=8;
  158. retval += *cp;
  159. *sval = retval;
  160. }
  161. void
  162. lmtoi( long *lval)
  163. {
  164. long retval;
  165. unsigned char *cp;
  166. int i;
  167. cp = (unsigned char *)lval;
  168. retval = (long)*cp++;
  169. for(i=0; i<3; i++) {
  170. retval <<=8;
  171. retval |= (long)*cp++;
  172. }
  173. *lval = retval;
  174. }
  175. void
  176. sitom( short *sval)
  177. {
  178. unsigned char *cp;
  179. short setval;
  180. setval = *sval;
  181. cp = (unsigned char *)sval;
  182. *cp++ = (unsigned char)((setval>>8)&0xff);
  183. *cp++ = (unsigned char)(setval&0xff);
  184. }
  185. void
  186. litom( long *lval)
  187. {
  188. long setval;
  189. int i;
  190. unsigned char *cp;
  191. setval = *lval;
  192. cp = (unsigned char *)lval;
  193. cp += 3;
  194. for ( i = 0; i<4; i++) {
  195. *cp--=(char )(setval&0xff);
  196. setval >>=8;
  197. }
  198. }
  199. static int
  200. align32( int siz)
  201. {
  202. siz = (siz + 3)/4 * 4;
  203. return siz;
  204. }
  205. static unsigned long
  206. calchksum( char *buf, int siz)
  207. {
  208. unsigned long *csp;
  209. unsigned long chksum;
  210. unsigned long lval;
  211. unsigned char pad[4];
  212. int i;
  213. int padsiz;
  214. unsigned char *cp;
  215. int csc;
  216. csp = (unsigned long *)buf;
  217. csc = siz/4;
  218. chksum = 0;
  219. while ( csc-->0) {
  220. lval = *csp++;
  221. lmtoi( (long *)&lval);
  222. chksum += lval;
  223. }
  224. padsiz = (siz+3)/4*4 - siz;
  225. if ( padsiz) {
  226. cp = (unsigned char *)csp;
  227. i = 0;
  228. while (padsiz++<4)
  229. pad[i++]=*cp++;
  230. csp = (unsigned long *)pad;
  231. lval = *csp;
  232. lmtoi( (long *)&lval);
  233. chksum += lval;
  234. }
  235. return chksum;
  236. }
  237. static int
  238. copyblk(HDC hDC, char *tag, HANDLE ofHdl, long siz, char *buf, int bufsiz, unsigned long *cs)
  239. {
  240. int rwsiz;
  241. int filsiz;
  242. int aligne;
  243. unsigned long chksum;
  244. long ofs;
  245. DWORD dwTable, nByte;
  246. dwTable = *(DWORD *)tag;
  247. filsiz = (int)(siz % 4);
  248. if ( filsiz) filsiz = 4-filsiz;
  249. ofs = 0L;
  250. aligne =0;
  251. chksum = 0;
  252. while ( siz > 0) {
  253. if ( siz > bufsiz)
  254. rwsiz = bufsiz;
  255. else {
  256. rwsiz = (int)siz;
  257. if ( filsiz)
  258. aligne =1;
  259. }
  260. if ( GetFontData(hDC, dwTable, (DWORD)ofs, buf,(DWORD)rwsiz )
  261. != (DWORD)rwsiz)
  262. goto ERET;
  263. if ( aligne ) {
  264. memset( buf+siz, 0, filsiz);
  265. rwsiz += filsiz;
  266. }
  267. chksum += calchksum( buf, rwsiz);
  268. BOOL res = WriteFile( ofHdl, buf, (unsigned int)rwsiz, &nByte, NULL);
  269. if (!res || nByte !=(unsigned int)rwsiz)
  270. goto ERET;
  271. siz -= rwsiz;
  272. ofs += rwsiz;
  273. }
  274. *cs = chksum;
  275. return 0;
  276. ERET:
  277. return -1;
  278. }
  279. static int
  280. mergeblock( HDC hDC, struct TableEntry *entry, HANDLE ofHdl)
  281. {
  282. long ofs;
  283. char *mem;
  284. unsigned long cs; /* CheckSum value */
  285. mem = (char *)malloc((size_t) RWBUFSIZ);
  286. if ( mem==(char *)0)
  287. return -1;
  288. /* Obtain start offset of Output table */
  289. ofs = SetFilePointer( ofHdl, 0L, NULL, FILE_CURRENT);
  290. if (copyblk( hDC, entry->tagName, ofHdl, entry->siz, mem, RWBUFSIZ, &cs))
  291. goto ERET;
  292. entry->ofs = ofs;
  293. entry->checkSum = cs;
  294. free( mem);
  295. return 0;
  296. ERET:
  297. free( mem);
  298. return -1;
  299. }
  300. static int
  301. tableChkSum( HANDLE fH, struct TableEntry *te)
  302. {
  303. char *rwbuf;
  304. unsigned long cs;
  305. long lsiz;
  306. int rwsiz;
  307. if ( te->siz==0)
  308. return 0;
  309. if ((rwbuf = (char *)malloc( (size_t)RWBUFSIZ))==(char *)0)
  310. return -1;
  311. if ( (long) SetFilePointer( fH, te->ofs, NULL, FILE_BEGIN)!=te->ofs)
  312. goto ERET;
  313. cs = 0;
  314. lsiz = te->siz;
  315. while ( lsiz > 0) {
  316. if (lsiz > RWBUFSIZ)
  317. rwsiz = RWBUFSIZ;
  318. else rwsiz = (int)lsiz;
  319. lsiz -= rwsiz;
  320. cs += calchksum( rwbuf, rwsiz);
  321. }
  322. te->checkSum = cs;
  323. free( rwbuf);
  324. return 0;
  325. ERET:
  326. free( rwbuf);
  327. return -1;
  328. }
  329. static int
  330. codeToGID( unsigned short code)
  331. {
  332. return (int)( code - (unsigned short)EUDCCODEBASE +2);
  333. }
  334. int
  335. TTFReadHdr ( HANDLE fHdl, struct TTFHeader *hdr)
  336. {
  337. DWORD nBytesRead;
  338. SetFilePointer( fHdl, 0L, NULL, FILE_BEGIN);
  339. BOOL res=ReadFile( fHdl, hdr, sizeof(struct TTFHeader),&nBytesRead, NULL);
  340. if (!res || nBytesRead !=sizeof(struct TTFHeader)) {
  341. return -1;
  342. }
  343. smtoi( &hdr->numTables);
  344. smtoi( &hdr->searchRange);
  345. smtoi( &hdr->entrySelector);
  346. smtoi( &hdr->rangeShift);
  347. return 0;
  348. }
  349. int
  350. TTFWriteHdr ( HANDLE fHdl, struct TTFHeader *hdr)
  351. {
  352. struct TTFHeader whdr;
  353. whdr = *hdr;
  354. sitom( &whdr.numTables);
  355. sitom( &whdr.searchRange);
  356. sitom( &whdr.entrySelector);
  357. sitom( &whdr.rangeShift);
  358. if (SetFilePointer( fHdl, 0L, NULL, FILE_BEGIN)!=0L)
  359. return -1;
  360. DWORD nByte;
  361. BOOL res = WriteFile( fHdl, (BYTE *) &whdr, sizeof(struct TTFHeader), &nByte, NULL);
  362. if (!res || nByte !=sizeof(struct TTFHeader))
  363. return -1;
  364. return 0;
  365. }
  366. int
  367. TTFReadDirEntry( HANDLE fHdl, struct TableEntry *entry, int eCnt)
  368. {
  369. long ofs;
  370. DWORD nByte;
  371. BOOL res;
  372. ofs = sizeof (struct TTFHeader);
  373. if ( (long) SetFilePointer( fHdl, ofs, NULL, FILE_BEGIN)!=ofs)
  374. return -1;
  375. res = ReadFile( fHdl, entry, (unsigned int)(sizeof(struct TableEntry)*eCnt), &nByte, NULL);
  376. if (!res || nByte !=(unsigned int)sizeof(struct TableEntry)*eCnt)
  377. return -1;
  378. while ( eCnt-->0) {
  379. lmtoi((long *)&entry->checkSum);
  380. lmtoi(&entry->ofs);
  381. lmtoi(&entry->siz);
  382. entry++;
  383. }
  384. return 0;
  385. }
  386. int
  387. TTFWriteDirEntry( HANDLE fHdl, struct TableEntry *entry, int eCnt)
  388. {
  389. long ofs;
  390. struct TableEntry wentry;
  391. DWORD nByte;
  392. BOOL res;
  393. ofs = sizeof (struct TTFHeader);
  394. if ( (long) SetFilePointer( fHdl, ofs, NULL, FILE_BEGIN)!=ofs)
  395. return -1;
  396. /* Write Entries */
  397. while ( eCnt-->0) {
  398. wentry = *entry++;
  399. litom((long *)&wentry.checkSum);
  400. litom(&wentry.ofs);
  401. litom(&wentry.siz);
  402. res = WriteFile( fHdl,(char *) &wentry, sizeof wentry, &nByte, NULL);
  403. if (!res || nByte !=sizeof wentry) {
  404. return -1;
  405. }
  406. }
  407. return 0;
  408. }
  409. static struct TableEntry *
  410. searchEntry(struct TableEntry *entry, int eCnt, char *tag)
  411. {
  412. while ( eCnt-->0) {
  413. if (memcmp( entry->tagName, tag, TAGSIZ)==0)
  414. return entry;
  415. entry++;
  416. }
  417. return (struct TableEntry *)0;
  418. }
  419. int
  420. TTFGetTableEntry( HANDLE fH, struct TableEntry *entry, char *tag)
  421. {
  422. struct TTFHeader hdr;
  423. struct TableEntry *te, *rte;
  424. int msiz;
  425. te = 0;
  426. /* Read TTF Header to get numTables */
  427. if (TTFReadHdr( fH, &hdr))
  428. goto ERET;
  429. msiz = sizeof(struct TableEntry)*hdr.numTables;
  430. if ( (te = (struct TableEntry *)malloc((size_t)msiz))==(struct TableEntry *)0)
  431. goto ERET;
  432. /* Read entry whole */
  433. if ( TTFReadDirEntry( fH, te, hdr.numTables))
  434. goto ERET;
  435. /* Search for entry with tag */
  436. if ((rte = searchEntry(te, (int)hdr.numTables, tag))==0)
  437. goto ERET;
  438. *entry = *rte;
  439. free(te);
  440. return 0;
  441. ERET:
  442. if (te) free(te);
  443. return -1;
  444. }
  445. /***********************************************************************
  446. * Read Table at once with entry data
  447. */
  448. /* */ int
  449. /* */ TTFReadTable(
  450. /* */ HANDLE fH,
  451. /* */ struct TableEntry *entry,
  452. /* */ void *buf,
  453. /* */ int bufsiz)
  454. /*
  455. * returns : read size
  456. ***********************************************************************/
  457. {
  458. unsigned int rdsiz;
  459. DWORD nByte;
  460. BOOL res;
  461. if ((long) SetFilePointer( fH, entry->ofs, NULL, FILE_BEGIN)!=entry->ofs)
  462. goto ERET;
  463. rdsiz = bufsiz >= (int)entry->siz ? (unsigned int)entry->siz
  464. : (unsigned int)bufsiz;
  465. res = ReadFile( fH, buf, rdsiz, &nByte, NULL);
  466. if (!res || nByte!=rdsiz)
  467. goto ERET;
  468. if ( rdsiz < (unsigned int)bufsiz)
  469. memset((unsigned char *)buf + rdsiz, 0, bufsiz - rdsiz);
  470. return (int)rdsiz;
  471. ERET:
  472. return -1;
  473. }
  474. /***********************************************************************
  475. * Read Fixed Size Table at onece with tag
  476. */
  477. /* */ int
  478. /* */ TTFReadFixedTable(
  479. /* */ HANDLE fH,
  480. /* */ char *buf,
  481. /* */ int bufsiz,
  482. /* */ char *tag)
  483. /*
  484. * returns : 0, -1
  485. ***********************************************************************/
  486. {
  487. struct TableEntry te;
  488. if (TTFGetTableEntry( fH, &te, tag))
  489. goto ERET;
  490. if ( TTFReadTable( fH, &te, buf, bufsiz )!=bufsiz)
  491. goto ERET;
  492. return 0;
  493. ERET:
  494. return -1;
  495. }
  496. /***********************************************************************
  497. * Read Variable Size Table at onece with tag
  498. */
  499. /* */ int
  500. /* */ TTFReadVarTable(
  501. /* */ HANDLE fH,
  502. /* */ char **buf, /* Buffer pointer (be set) */
  503. /* */ unsigned int *bufsiz, /* Buffer Size ( be set) */
  504. /* */ char *tag) /* Tag name */
  505. /*
  506. * returns : 0, -1
  507. * remarks : allocated memory must be free by caller
  508. ***********************************************************************/
  509. {
  510. struct TableEntry te;
  511. char *mem;
  512. if (TTFGetTableEntry( fH, &te, tag))
  513. goto ERET;
  514. if ((mem = (char *)malloc( (size_t)te.siz))==(char *)0)
  515. goto ERET;
  516. if ( TTFReadTable( fH, &te, mem, (int)te.siz )!=(int)te.siz)
  517. goto ERET;
  518. *buf = mem;
  519. *bufsiz = (unsigned int)te.siz;
  520. return 0;
  521. ERET:
  522. return -1;
  523. }
  524. /***********************************************************************
  525. * Write Table
  526. */
  527. /* */ int
  528. /* */ TTFWriteTable(
  529. /* */ HANDLE fH,
  530. /* */ struct TableEntry *entry,
  531. /* */ void *buf,
  532. /* */ int bufsiz)
  533. /*
  534. * returns : written size
  535. * remarks : update checksum
  536. ***********************************************************************/
  537. {
  538. int wsiz;
  539. DWORD nByte;
  540. BOOL res;
  541. if ((long) SetFilePointer( fH, entry->ofs, NULL, FILE_BEGIN)!=entry->ofs)
  542. goto ERET;
  543. wsiz = bufsiz >= (int)entry->siz ? (int)entry->siz : bufsiz;
  544. res = WriteFile( fH, (char *)buf, (unsigned int)wsiz, &nByte, NULL);
  545. if (!res || nByte !=(unsigned int)wsiz)
  546. goto ERET;
  547. entry->checkSum = calchksum( (char *)buf, bufsiz);
  548. return wsiz;
  549. ERET:
  550. return -1;
  551. }
  552. /***********************************************************************
  553. * Write Table
  554. */
  555. /* */ int
  556. /* */ TTFAppendTable(
  557. /* */ HANDLE fH,
  558. /* */ struct TableEntry *entry, /* value be set */
  559. /* */ void *buf,
  560. /* */ int siz)
  561. /*
  562. * returns : 0, -1
  563. * remarks : enttry->siz not aligned 32bit
  564. ***********************************************************************/
  565. {
  566. long ofs;
  567. BYTE pad[4];
  568. int padsiz;
  569. DWORD nByte;
  570. BOOL res;
  571. if ( (ofs=(long) SetFilePointer( fH, 0L, NULL, FILE_CURRENT))<0L)
  572. goto ERET;
  573. res = WriteFile( fH, buf, (unsigned int)siz, &nByte, NULL);
  574. if (!res || nByte !=(unsigned int)siz)
  575. goto ERET;
  576. /* 32 bit Word aligne */
  577. if ( siz % 4) {
  578. padsiz = 4 - siz%4;
  579. memset(pad,0,4);
  580. res = WriteFile(fH,pad, (unsigned int)padsiz, &nByte, NULL);
  581. if (!res || nByte !=(unsigned int)padsiz)
  582. goto ERET;
  583. }
  584. entry->ofs = ofs;
  585. entry->siz = siz;
  586. entry->checkSum = calchksum((char *) buf, siz);
  587. return 0;
  588. ERET:
  589. return -1;
  590. }
  591. /***********************************************************************
  592. * Merge Table
  593. */
  594. /* */ static int
  595. /* */ TTFMergeTable(
  596. /* */ HDC hDC,
  597. /* */ HANDLE nfh,
  598. /* */ char tag[4],
  599. /* */ struct TableEntry *nte)
  600. /*
  601. * returns : 0
  602. ***********************************************************************/
  603. {
  604. if (TTFGetOrgTableEntry( hDC, nte, tag))
  605. return -1;
  606. if (mergeblock( hDC, nte, nfh))
  607. return -1;
  608. return 0;
  609. }
  610. int
  611. #ifdef BUILD_ON_WINNT
  612. __cdecl
  613. #endif // BUILD_ON_WINNT
  614. compentry( const void *e1, const void *e2)
  615. {
  616. struct TableEntry *te1, *te2;
  617. te1 = (struct TableEntry *)e1;
  618. te2 = (struct TableEntry *)e2;
  619. return memcmp(te1->tagName, te2->tagName,4);
  620. }
  621. static void
  622. SortEntry(struct TableEntry *ebuf, int num)
  623. {
  624. if ( num <=0) return;
  625. qsort( ebuf, num, sizeof(struct TableEntry), compentry);
  626. }
  627. static int
  628. fileChkSum(
  629. HANDLE fh,
  630. struct TableEntry *entry,
  631. int numEntry,
  632. struct TTFHeader *hdr,
  633. struct HeadTable *head)
  634. {
  635. unsigned long lval, cs;
  636. unsigned long *lp;
  637. struct TableEntry *e;
  638. int n;
  639. struct TableEntry *headp;
  640. DWORD nByte;
  641. BOOL res;
  642. e = entry;
  643. n = numEntry;
  644. cs = 0;
  645. head->chkSum = 0;
  646. headp = 0;
  647. while ( n-->0) {
  648. lp = (unsigned long *)e->tagName;
  649. if (memcmp( e->tagName,"head", 4)==0)
  650. headp = e;
  651. lval = *lp;
  652. lmtoi( (long *)&lval);
  653. cs += lval;
  654. cs += e->checkSum;
  655. cs += e->checkSum;
  656. cs += e->ofs;
  657. cs += e->siz;
  658. e++;
  659. }
  660. if (headp==0)
  661. return -1;
  662. cs += calchksum( (char *)hdr, sizeof(struct TTFHeader) );
  663. if ((long) SetFilePointer( fh, headp->ofs, NULL, FILE_BEGIN)!=headp->ofs)
  664. goto ERET;
  665. head->chkSum = (unsigned long)0xb1b0afbaL - cs;
  666. litom( (long *)&head->chkSum);
  667. res = WriteFile(fh,(char *)head,sizeof(struct HeadTable), &nByte, NULL);
  668. if (!res || nByte !=sizeof(struct HeadTable))
  669. goto ERET;
  670. return 0;
  671. ERET:
  672. return -1;
  673. }
  674. static void
  675. makeTTFHeader( struct TTFHeader *hdr, int nTbl)
  676. {
  677. int po;
  678. int n;
  679. int ponum;
  680. po = 0;
  681. n = nTbl;
  682. ponum = 1;
  683. while ( n>=2) {
  684. n /= 2;
  685. po++;
  686. ponum*=2;
  687. }
  688. hdr->sfnt_version[0]= hdr->sfnt_version[2]= hdr->sfnt_version[3]= 0;
  689. hdr->sfnt_version[1]= 0x01;
  690. hdr->numTables = (short)nTbl;
  691. hdr->searchRange = (short)ponum*16;
  692. hdr->entrySelector = (short)po;
  693. hdr->rangeShift = (short)( nTbl*16)-hdr->searchRange;
  694. return ;
  695. }
  696. /***********************************************************************
  697. * make GlyphData from lst
  698. */
  699. /* */ static int
  700. /* */ makeGlyphData(
  701. /* */ int lstH,
  702. /* */ struct BBX *bbx, /* Set value to header */
  703. /* */ char *glyphData,
  704. /* */ int bufsiz,
  705. /* */ int *gdatsiz)
  706. /*
  707. * returns : 0, -1
  708. ***********************************************************************/
  709. {
  710. char *flgp, *sflgp;
  711. char flag;
  712. char *dummyp;
  713. struct VHEAD *vhd,
  714. *svhd;
  715. struct glyfHead ghdr;
  716. int nCnt;
  717. struct VDATA *vp;
  718. int nPnt;
  719. int pntSum;
  720. int cnt;
  721. short sval;
  722. short px, py;
  723. short relx, rely;
  724. char cval;
  725. initsetgbuf ( glyphData, bufsiz);
  726. if( ( nCnt = VDGetNCont( lstH))<0)
  727. goto ERET;
  728. else if (nCnt == 0) { /* Space Character */
  729. *gdatsiz = 0;
  730. return 0;
  731. }
  732. ghdr.numberOfContour = (short)nCnt;
  733. sitom( &ghdr.numberOfContour );
  734. ghdr.xMin = (short)bbx->xMin;
  735. sitom( &ghdr.xMin);
  736. ghdr.yMin = (short)bbx->yMin;
  737. sitom( &ghdr.yMin);
  738. ghdr.xMax = (short)bbx->xMax;
  739. sitom( &ghdr.xMax);
  740. ghdr.yMax = (short)bbx->yMax;
  741. sitom( &ghdr.yMax);
  742. if (setgbuf( (char *)&ghdr, sizeof ghdr, &flgp))
  743. goto ERET2;
  744. if (VDGetHead( lstH, &vhd))
  745. goto ERET;
  746. pntSum = 0;
  747. svhd = vhd;
  748. /* Set each Contour Last point number */
  749. for ( cnt = 0; cnt < nCnt; cnt++) {
  750. pntSum += vhd->nPoints;
  751. sval = pntSum-1;
  752. sitom( &sval);
  753. if ( setgbuf((char *)&sval, sizeof( short), &flgp))
  754. goto ERET2;
  755. vhd = vhd->next;
  756. }
  757. /* Toatal number of instructions */
  758. sval = 0;
  759. if ( setgbuf((char *)&sval, sizeof( short), &flgp))
  760. goto ERET2;
  761. /* Set flags */
  762. vhd = svhd;
  763. px = py = 0;
  764. for ( cnt = 0; cnt < nCnt; cnt++) {
  765. vp = vhd->headp;
  766. nPnt = vhd->nPoints;
  767. while ( nPnt-->0) {
  768. flag = (vp->vd.atr&1)==0 ? (char)GLYF_ON_CURVE :(char)0;
  769. relx = vp->vd.x - px;
  770. rely = vp->vd.y - py;
  771. if ( relx == 0)
  772. flag |= GLYF_X_SAME;
  773. else if ( relx > 0 && relx < 256)
  774. flag |= GLYF_X_SHORT_P;
  775. else if ( relx < 0 && relx > -256)
  776. flag |= GLYF_X_SHORT_N;
  777. if ( rely == 0)
  778. flag |= GLYF_Y_SAME;
  779. else if ( rely > 0 && rely < 256)
  780. flag |= GLYF_Y_SHORT_P;
  781. else if ( rely < 0 && rely > -256)
  782. flag |= GLYF_Y_SHORT_N;
  783. if (setgbuf((char *) &flag, 1, &dummyp))
  784. goto ERET2;
  785. px = vp->vd.x;
  786. py = vp->vd.y;
  787. vp = vp->next;
  788. }
  789. vhd = vhd->next;
  790. }
  791. /* set X */
  792. vhd = svhd;
  793. sflgp = flgp;
  794. px = 0;
  795. for ( cnt = 0; cnt < nCnt; cnt++) {
  796. vp = vhd->headp;
  797. nPnt = vhd->nPoints;
  798. while ( nPnt-->0) {
  799. relx = vp->vd.x - px;
  800. if ( *flgp & GLYF_X_SHORT) {
  801. if ( (*flgp & GLYF_X_SAME)==0)
  802. relx = -relx;
  803. cval = (char)relx;
  804. if ( setgbuf( &cval, 1, &dummyp))
  805. goto ERET2;
  806. }
  807. else if ( *flgp & GLYF_X_SAME)
  808. ;
  809. else {
  810. sitom( &relx);
  811. if ( setgbuf( (char *)&relx, 2, &dummyp))
  812. goto ERET2;
  813. }
  814. flgp++;
  815. px = vp->vd.x;
  816. vp = vp->next;
  817. }
  818. vhd = vhd->next;
  819. }
  820. /* set Y */
  821. vhd = svhd;
  822. flgp = sflgp;
  823. py = 0;
  824. for ( cnt = 0; cnt < nCnt; cnt++) {
  825. vp = vhd->headp;
  826. nPnt = vhd->nPoints;
  827. while ( nPnt-->0) {
  828. rely = vp->vd.y - py;
  829. if ( *flgp & GLYF_Y_SHORT) {
  830. if ( (*flgp & GLYF_Y_SAME)==0)
  831. rely = -rely;
  832. cval = (char)rely;
  833. if ( setgbuf( &cval, 1, &dummyp))
  834. goto ERET2;
  835. }
  836. else if ( *flgp & GLYF_Y_SAME)
  837. ;
  838. else {
  839. sitom( &rely);
  840. if ( setgbuf((char *)&rely, 2, &dummyp))
  841. goto ERET2;
  842. }
  843. flgp++;
  844. py = vp->vd.y;
  845. vp = vp->next;
  846. }
  847. vhd = vhd->next;
  848. }
  849. *gdatsiz = termbuf();
  850. return 0;
  851. ERET:
  852. return -1;
  853. ERET2:
  854. return -2;
  855. }
  856. static char *sbuf;
  857. static int limcnt;
  858. static char *setp;
  859. static int bcnt;
  860. static void
  861. initsetgbuf( char *b, int lim)
  862. {
  863. setp = sbuf = b;
  864. limcnt = lim;
  865. bcnt = lim; /* decremental counter */
  866. return;
  867. }
  868. static int
  869. setgbuf( char *dat, int siz, char **np)
  870. {
  871. if ( siz > bcnt) return -1;
  872. memcpy( setp, dat, siz);
  873. setp += siz;
  874. bcnt -= siz;
  875. *np = setp;
  876. return 0;
  877. }
  878. static int
  879. termbuf( )
  880. {
  881. int siz;
  882. siz = limcnt - bcnt;
  883. siz = siz % 4;
  884. if ( siz) {
  885. while ( siz++<4) {
  886. *setp++=0;
  887. bcnt--;
  888. }
  889. }
  890. return limcnt - bcnt;
  891. }
  892. static int
  893. strwlen( char *s)
  894. {
  895. int len;
  896. len = 0;
  897. while (*s || *(s+1)) {
  898. s+=2;
  899. len++;
  900. }
  901. return len*2;
  902. }
  903. static void
  904. strwcat( char *s1, char *s2)
  905. {
  906. while (*s1 || *(s1+1))
  907. s1+=2;
  908. while ( *s2 || *(s2+1)) {
  909. *s1++ = *s2++;
  910. *s1++ = *s2++;
  911. }
  912. *s1++ = 0;
  913. *s1++ = 0;
  914. return;
  915. }
  916. static void
  917. setnamebuf( char *buf, int *siz, short EncodingID)
  918. {
  919. int strsiz;
  920. short strofs;
  921. char *strp;
  922. struct NamingTable *nt;
  923. struct NameRecord *nr;
  924. int rec;
  925. int slen;
  926. strofs = sizeof(struct NamingTable)
  927. + sizeof(struct NameRecord)*NUMOFNAMEREC;
  928. strsiz = 0;
  929. strp = buf +strofs;
  930. *strp=(char)0;
  931. *(strp+1)=(char)0;
  932. nt = (struct NamingTable *)buf;
  933. nt->OfsToStr = strofs;
  934. sitom( &nt->OfsToStr);
  935. nr = (struct NameRecord *)(buf + sizeof(struct NamingTable));
  936. /* Set name record */
  937. strofs = 0;
  938. for ( rec = 0; rec<NUMOFNAMEREC; rec++, nr++) {
  939. nr ->PlatformID = 3;
  940. sitom(&nr ->PlatformID);
  941. nr ->PlatformSpecEncID = EncodingID;
  942. sitom(&nr ->PlatformSpecEncID);
  943. nr ->LanguageID = (short)CountryInfo.LangID;
  944. sitom(&nr ->LanguageID);
  945. nr ->NameID = (short)rec;
  946. sitom(&nr ->NameID);
  947. strwcat( strp,namerecstr[rec]);
  948. slen = strwlen(namerecstr[rec]);
  949. nr -> StringLength = (short)slen;
  950. sitom(&nr -> StringLength );
  951. strsiz += slen;
  952. nr -> StringOfs = strofs;
  953. sitom(&nr -> StringOfs);
  954. strofs += (short)slen;
  955. }
  956. nt->FormSel = 0;
  957. nt->NRecs = NUMOFNAMEREC;
  958. sitom( &nt->NRecs);
  959. *siz = strsiz+ sizeof(struct NamingTable)
  960. + sizeof(struct NameRecord)*NUMOFNAMEREC;
  961. }
  962. static void
  963. modifyOS2( char *buf)
  964. {
  965. /* Allow all license */
  966. *(buf+9) = (char)0x00;
  967. /* Set aulUnicodeRange Privete Use Area bit*/
  968. *(buf+0x31) |= 0x31;
  969. }
  970. static void
  971. modifyhead( struct HeadTable *head)
  972. {
  973. head->chkSum=0L;
  974. memset( head->createdDate, 0, 8);
  975. memset( head->updatedDate, 0, 8);
  976. head->indexToLocFormat = 1;
  977. head->glyphDataFormat = 0;
  978. sitom( &head->indexToLocFormat );
  979. sitom( &head->glyphDataFormat);
  980. }
  981. /*
  982. * Set Vertical Header with Horizontal Header and Bounding Box
  983. */
  984. static void
  985. setVhea( struct VheaTable *vhea, struct HheaTable *hhea, struct BBX *bbx)
  986. {
  987. memcpy( vhea, hhea, sizeof(struct HheaTable));
  988. vhea->minTopSideBearing = 0;
  989. vhea->minBottomSideBearing = 0;
  990. vhea->caretSlopeRise = 0;
  991. vhea->caretSlopeRun = 1;
  992. sitom( &vhea->caretSlopeRun );
  993. vhea->numOfLongVerMetrics = (short)numOfGlyph;
  994. sitom( &vhea->numOfLongVerMetrics );
  995. }
  996. static int
  997. updateMaxp( struct MaxpTbl *maxp, int lstHdl)
  998. {
  999. struct VHEAD *vhd;
  1000. short sval;
  1001. int nCnt;
  1002. int ttlPnt;
  1003. int updflg;
  1004. updflg = 0;
  1005. if ( (nCnt = VDGetNCont( lstHdl))<0)
  1006. goto ERET;
  1007. else if ( nCnt ==0)
  1008. goto RET;
  1009. sval = maxp->maxContours;
  1010. smtoi( &sval);
  1011. if ( sval < nCnt) {
  1012. sval = (short)nCnt;
  1013. sitom(&sval);
  1014. maxp->maxContours = sval;
  1015. updflg = 1;
  1016. }
  1017. if (VDGetHead( lstHdl, &vhd))
  1018. goto ERET;
  1019. ttlPnt = 0;
  1020. while ( nCnt-->0) {
  1021. ttlPnt += vhd->nPoints;
  1022. vhd = vhd->next;
  1023. }
  1024. sval = maxp->maxPoints;
  1025. smtoi( &sval);
  1026. if ( sval < ttlPnt) {
  1027. sval = (short)ttlPnt;
  1028. sitom(&sval);
  1029. maxp->maxPoints = sval;
  1030. updflg = 1;
  1031. }
  1032. RET:
  1033. return updflg;
  1034. ERET:
  1035. return -1;
  1036. }
  1037. /***********************************************************************
  1038. * Obtain Original TTF Table Size
  1039. */
  1040. /* */ static int
  1041. /* */ TTFGetOrgTableEntry(
  1042. /* */ HDC hDC,
  1043. /* */ struct TableEntry *entry,
  1044. /* */ char *tag)
  1045. /*
  1046. * returns : 0, -1
  1047. ***********************************************************************/
  1048. {
  1049. DWORD dwTable; /* Metric Table to request */
  1050. DWORD siz;
  1051. dwTable = *(DWORD *)tag;
  1052. siz = GetFontData(hDC, dwTable, (DWORD)0, (char *)0, (DWORD)0);
  1053. if ( siz == GDI_ERROR) return -1;
  1054. else {
  1055. memcpy( entry->tagName, tag, TAGSIZ);
  1056. entry->siz = (long)siz;
  1057. return 0;
  1058. }
  1059. }
  1060. /***********************************************************************
  1061. * Read Original TTF Table
  1062. */
  1063. /* */ int
  1064. /* */ TTFReadOrgFixedTable (
  1065. /* */ HDC hDC, /* Handle to DC */
  1066. /* */ char *buf, /* Read Buffer */
  1067. /* */ int bufsiz, /* Buffer Siz */
  1068. /* */ char *tag) /* TagName */
  1069. /*
  1070. * returns : 0, -1
  1071. ***********************************************************************/
  1072. {
  1073. DWORD dwTable; /* Metric Table to request */
  1074. DWORD siz;
  1075. dwTable = *(DWORD *)tag;
  1076. siz = GetFontData(hDC, dwTable, (DWORD)0, buf,(DWORD)bufsiz );
  1077. if ( (int)siz != bufsiz)
  1078. return -1;
  1079. else return 0;
  1080. }
  1081. /***********************************************************************
  1082. * Read Variable Size Table at onece with tag
  1083. */
  1084. /* */ int
  1085. /* */ TTFReadOrgVarTable(
  1086. /* */ HDC hDC,
  1087. /* */ char **buf, /* Buffer pointer (be set) */
  1088. /* */ unsigned int *bufsiz, /* Buffer Size ( be set) */
  1089. /* */ char *tag) /* Tag name */
  1090. /*
  1091. * returns : 0, -1
  1092. * remarks : allocated memory must be free by caller
  1093. ***********************************************************************/
  1094. {
  1095. struct TableEntry te;
  1096. char *mem;
  1097. if (TTFGetOrgTableEntry( hDC, &te, tag))
  1098. goto ERET;
  1099. if ((mem = (char *)malloc( (size_t)te.siz))==(char *)0)
  1100. goto ERET;
  1101. if ( TTFReadOrgFixedTable ( hDC, mem,(int)te.siz , tag))
  1102. goto ERET;
  1103. *buf = mem;
  1104. *bufsiz = (unsigned int)te.siz;
  1105. return 0;
  1106. ERET:
  1107. return -1;
  1108. }
  1109. static void
  1110. setCountryData(short EncodingID)
  1111. {
  1112. unsigned short lastCode;
  1113. makeUniCodeTbl();
  1114. lastCode = getMaxUniCode();
  1115. numOfGlyph = lastCode - EUDCCODEBASE +1 + 2; /* +null, +missing */
  1116. cmapdata[6] = (char)((EncodingID>>8)&(unsigned short)0xff);
  1117. cmapdata[7] = (char)(EncodingID&(unsigned short)0xff);
  1118. cmapdata[26] = (char)((lastCode>>8)&(unsigned short)0xff);
  1119. cmapdata[27] = (char)(lastCode&(unsigned short)0xff);
  1120. maxpdata[4] = (char)((numOfGlyph>>8)&(unsigned short)0xff);
  1121. maxpdata[5] = (char)(numOfGlyph&(unsigned short)0xff);
  1122. }
  1123. static int
  1124. WIFEOS2( HDC hDC, char **os2buf, int *os2TblSiz, struct BBX *bbx)
  1125. {
  1126. struct OS2Table *os2tbl;
  1127. int siz;
  1128. TEXTMETRIC tm;
  1129. static PANOSE msminPanose= { (char)2, (char)2, (char)6, (char)9, (char)4,
  1130. (char)2, (char)5, (char)8, (char)3, (char)4};
  1131. if ( GetTextMetrics( hDC, &tm)==0)
  1132. goto ERET;
  1133. siz = sizeof( struct OS2Table);
  1134. if ((os2tbl = (struct OS2Table *)malloc(sizeof(struct OS2Table)))==0)
  1135. goto ERET;
  1136. memset( os2tbl, 0, sizeof(struct OS2Table));
  1137. os2tbl->version = 1;
  1138. sitom( (short *)&os2tbl->version);
  1139. os2tbl->xAvgCharWidth = bbx->xMax+1;
  1140. sitom( &os2tbl->xAvgCharWidth );
  1141. os2tbl->usWeightClass = tm.tmWeight? (unsigned short)tm.tmWeight : 500;
  1142. sitom( (short *)&os2tbl->usWeightClass );
  1143. os2tbl->usWidthClass = 5; /* Medium */
  1144. sitom( (short *)&os2tbl->usWidthClass );
  1145. os2tbl->fsType = 0x0000; /* Allow all liscence */
  1146. sitom( &os2tbl->fsType );
  1147. os2tbl->ySubscriptXSize = (bbx->xMax+1)/2; /* 1/4kaku */
  1148. sitom( &os2tbl->ySubscriptXSize );
  1149. os2tbl->ySubscriptYSize = (bbx->yMax+1)/2; /* 1/4kaku */
  1150. sitom( &os2tbl->ySubscriptYSize );
  1151. os2tbl->ySubscriptXOffset = 0; /* 1/4kaku */
  1152. sitom( &os2tbl->ySubscriptXOffset );
  1153. os2tbl->ySubscriptYOffset = 0; /* 1/4kaku */
  1154. sitom( &os2tbl->ySubscriptYOffset );
  1155. os2tbl->ySuperscriptXSize = (bbx->xMax+1)/2; /* 1/4kaku */
  1156. sitom( &os2tbl->ySuperscriptXSize );
  1157. os2tbl->ySuperscriptYSize = (bbx->yMax+1)/2; /* 1/4kaku */
  1158. sitom( &os2tbl->ySuperscriptYSize );
  1159. os2tbl->ySuperscriptXOffset = (bbx->xMax+1)/2; /* 1/4kaku */
  1160. sitom( &os2tbl->ySuperscriptXOffset );
  1161. os2tbl->ySuperscriptYOffset = (bbx->yMax+1)/2; /* 1/4kaku */
  1162. sitom( &os2tbl->ySuperscriptYOffset );
  1163. os2tbl->yStrikeoutSize = bbx->yMax/20; /* 5% */
  1164. sitom( &os2tbl->yStrikeoutSize );
  1165. os2tbl->yStrikeoutPosition = bbx->yMax/4; /* 25% */
  1166. sitom( &os2tbl->yStrikeoutPosition );
  1167. os2tbl->sFamilyClass = 0; /* no classification */
  1168. sitom( &os2tbl->sFamilyClass );
  1169. os2tbl->panose = msminPanose;
  1170. os2tbl->fsSelection = 0x40;
  1171. sitom( (short *)&os2tbl->fsSelection );
  1172. os2tbl->usFirstCharIndex = 0x20;
  1173. sitom( (short *)&os2tbl->usFirstCharIndex );
  1174. os2tbl->usLastCharIndex = 0xffe5;
  1175. sitom( (short *)&os2tbl->usLastCharIndex );
  1176. os2tbl->sTypoAscender = bbx->yMax+1;
  1177. sitom( &os2tbl->sTypoAscender );
  1178. os2tbl->sTypoDescender = -(bbx->yMax/8);
  1179. sitom( &os2tbl->sTypoDescender );
  1180. os2tbl->sTypoLineGap = 0;
  1181. sitom( &os2tbl->sTypoLineGap );
  1182. os2tbl->usWinAscent = bbx->yMax+1;
  1183. sitom( (short *)&os2tbl->usWinAscent );
  1184. os2tbl->usWinDescent = bbx->yMax/8;
  1185. sitom( (short *)&os2tbl->usWinDescent );
  1186. *os2TblSiz = sizeof( struct OS2Table);
  1187. *os2buf = (char *)os2tbl;
  1188. return 0;
  1189. ERET:
  1190. return -1;
  1191. }
  1192. static void
  1193. WIFEhhea( struct HheaTable *hhea, struct BBX *bbx)
  1194. {
  1195. memset( hhea, 0, sizeof(struct HheaTable));
  1196. hhea->version[1] = (char)1;
  1197. hhea->Ascender = bbx->yMax+1;
  1198. sitom( &hhea->Ascender);
  1199. hhea->Descender = -(bbx->yMax/8);
  1200. sitom( &hhea->Descender);
  1201. hhea->LineGap = 0;
  1202. sitom( &hhea->LineGap);
  1203. hhea->advanceWidthMax = bbx->xMax+1;
  1204. sitom( &hhea->advanceWidthMax);
  1205. hhea->minLeftSideBearing = 0;
  1206. sitom( &hhea->minLeftSideBearing);
  1207. hhea->minRightSideBearing = 0;
  1208. sitom( &hhea->minRightSideBearing);
  1209. hhea->xMaxExtent = bbx->xMax+1;
  1210. sitom( &hhea->xMaxExtent);
  1211. hhea->caretSlopeRise = 1;
  1212. sitom( &hhea->caretSlopeRise);
  1213. hhea->caretSlopeRun = 0;
  1214. sitom( &hhea->caretSlopeRun);
  1215. hhea->numberOfHMetrics = (short)numOfGlyph;
  1216. sitom( &hhea->numberOfHMetrics);
  1217. }
  1218. static void
  1219. WIFEhead( struct HeadTable *head, struct BBX *bbx)
  1220. {
  1221. memset( head, 0, sizeof( struct HeadTable));
  1222. head->version[1] = 0x1;
  1223. head->magicNumber=0x5f0F3CF5L;
  1224. litom((long *)&head->magicNumber);
  1225. head->flags = 0;
  1226. sitom( &head->flags);
  1227. head->unitsPerEm = bbx->xMax - bbx->xMin+1;
  1228. head->unitsPerEm = ((bbx->xMax - bbx->xMin+1)*9+4)/8;
  1229. sitom( &head->unitsPerEm);
  1230. head->xMin = (short)bbx->xMin;
  1231. sitom( &head->xMin);
  1232. head->xMax = (short)bbx->xMax;
  1233. sitom( &head->xMax);
  1234. // head->yMin = (short)bbx->yMin;
  1235. head->yMin = -(bbx->yMax/8);
  1236. sitom( &head->yMin);
  1237. head->yMax = (short)bbx->yMax;
  1238. sitom( &head->yMax);
  1239. head->lowestRecPPEM = 25;
  1240. sitom( &head->lowestRecPPEM);
  1241. head->fontDirectionHint = 1;
  1242. sitom( &head->fontDirectionHint);
  1243. head->indexToLocFormat = 1;
  1244. sitom( &head->indexToLocFormat);
  1245. }
  1246. static void
  1247. WIFEpost( struct postTable *post)
  1248. {
  1249. memset( post, 0, sizeof( struct postTable));
  1250. post->FormatType[1]=0x3;
  1251. post->underlineThickness = 12;
  1252. sitom( &post->underlineThickness);
  1253. post->isFixedPitch = 1;
  1254. litom( (long *)&post->isFixedPitch);
  1255. }
  1256. static short
  1257. getEncID( HDC hDC, int fontType)
  1258. {
  1259. if ( CountryInfo.LangID==EUDC_KRW)
  1260. return (short)1;
  1261. else return (short)1;
  1262. }
  1263. /***********************************************************************
  1264. * Create TTF
  1265. */
  1266. /* */ int
  1267. /* */ TTFCreate(
  1268. /* */ HDC hDC, /* Handle to DC */
  1269. /* */ TCHAR *newf, /* Create TTF Path */
  1270. /* */ struct BBX *bbx, /* the same as original 'head'*/
  1271. /* */ /* but minX should be 0 */
  1272. /* */ int lstHdl, /* missing glyf list */
  1273. /* */ /* bbx, hM, LstHdl is for Missing Glyf*/
  1274. /* */ int fontType) /* 0:TrueType, 1:WIFE */
  1275. /*
  1276. * returns : 0, -1
  1277. ***********************************************************************/
  1278. {
  1279. HANDLE nfh;
  1280. struct TTFHeader hdr;
  1281. struct TableEntry *te, /* Directory Entry */
  1282. nte;
  1283. char *nameBuf;
  1284. int nameBufSiz;
  1285. struct HheaTable hhea;
  1286. struct VheaTable vhea;
  1287. struct HeadTable head;
  1288. struct HMetrics *hmet;
  1289. struct VMetrics *vmet;
  1290. long *loca;
  1291. long ofs;
  1292. char *glyphData;
  1293. int gdatsiz;
  1294. int i;
  1295. char *os2buf;
  1296. int os2siz;
  1297. struct BBX cbbx; /* bounding box for each glyph*/
  1298. struct HMetrics hM; /* horizontal metrics for each glyph */
  1299. struct VMetrics vM; /* Vertical one */
  1300. struct postTable postTbl; /* post table */
  1301. short EncodingID;
  1302. DWORD nByte;
  1303. BOOL res;
  1304. // nfh = -1;
  1305. te = 0;
  1306. nameBuf = 0;
  1307. hmet = 0;
  1308. loca = 0;
  1309. glyphData = 0;
  1310. os2buf = 0;
  1311. /* Determin PlatformSpcificEncodingID */
  1312. if ((EncodingID = getEncID( hDC, fontType))<(short)0)
  1313. goto ERET;
  1314. /* Set cmapdata,maxpdata,numOfGlyph,lastCode */
  1315. setCountryData(EncodingID);
  1316. /* Open files */
  1317. nfh = CreateFile(newf,
  1318. GENERIC_WRITE,
  1319. FILE_SHARE_READ | FILE_SHARE_DELETE,
  1320. NULL,
  1321. CREATE_ALWAYS,
  1322. FILE_ATTRIBUTE_NORMAL,
  1323. NULL);
  1324. if ( nfh == INVALID_HANDLE_VALUE)
  1325. goto ERET;
  1326. /* Write header */
  1327. makeTTFHeader( &hdr, NUMTABLES);
  1328. if ( TTFWriteHdr( nfh, &hdr))
  1329. goto ERET;
  1330. /* Allocate dir entry area */
  1331. if ( (te =(struct TableEntry *)malloc((size_t)sizeof(struct TableEntry)*NUMTABLES))==0)
  1332. goto ERET;
  1333. /*
  1334. * DirEntry Dummy Write
  1335. */
  1336. memset( te, 0, sizeof(struct TableEntry)*NUMTABLES);
  1337. res = WriteFile( nfh, te, sizeof(struct TableEntry)*NUMTABLES, &nByte, NULL);
  1338. if (!res || nByte != sizeof(struct TableEntry)*NUMTABLES)
  1339. goto ERET;
  1340. initDirEntry(te, NUMTABLES );
  1341. /*
  1342. * 'cvt ' Write
  1343. */
  1344. if (TTFAppendTable( nfh, &nte, cvtdata, sizeof cvtdata))
  1345. goto ERET;
  1346. if ( setDirEntry( &nte, "cvt "))
  1347. goto ERET;
  1348. /*
  1349. * 'fpgm' Write
  1350. */
  1351. if (TTFAppendTable( nfh, &nte, fpgmdata, sizeof fpgmdata))
  1352. goto ERET;
  1353. if ( setDirEntry( &nte, "fpgm"))
  1354. goto ERET;
  1355. /*
  1356. * 'prep' write
  1357. */
  1358. if (TTFAppendTable( nfh, &nte, prepdata, sizeof prepdata))
  1359. goto ERET;
  1360. if ( setDirEntry( &nte, "prep"))
  1361. goto ERET;
  1362. /*
  1363. * 'name' write
  1364. */
  1365. if ( (nameBuf = (char *)malloc((size_t)NAMEBUFSIZ))==0)
  1366. goto ERET;
  1367. setnamebuf(nameBuf, &nameBufSiz, EncodingID);
  1368. if (TTFAppendTable( nfh, &nte, nameBuf, nameBufSiz))
  1369. goto ERET;
  1370. free( nameBuf);
  1371. nameBuf = 0;
  1372. if ( setDirEntry( &nte, "name"))
  1373. goto ERET;
  1374. /*
  1375. * 'cmap' Write
  1376. */
  1377. if (TTFAppendTable( nfh, &nte, cmapdata, sizeof cmapdata))
  1378. goto ERET;
  1379. if ( setDirEntry( &nte, "cmap"))
  1380. goto ERET;
  1381. /*
  1382. * 'OS/2' Copy -> modify
  1383. */
  1384. if ( fontType==0) {
  1385. if ( TTFReadOrgVarTable( hDC, &os2buf, (unsigned int *)&os2siz,
  1386. "OS/2"))
  1387. goto ERET;
  1388. modifyOS2( os2buf);
  1389. }
  1390. else {
  1391. if (WIFEOS2( hDC, &os2buf, &os2siz, bbx))
  1392. goto ERET;
  1393. }
  1394. if (TTFAppendTable( nfh, &nte, os2buf, os2siz))
  1395. goto ERET;
  1396. if ( setDirEntry( &nte, "OS/2"))
  1397. goto ERET;
  1398. free( os2buf);
  1399. /*
  1400. * 'post' Copy
  1401. */
  1402. if ( fontType==0) {
  1403. if ( TTFMergeTable( hDC, nfh, "post", &nte))
  1404. goto ERET;
  1405. }
  1406. else {
  1407. WIFEpost( &postTbl);
  1408. if (TTFAppendTable( nfh,&nte, (char *)&postTbl,sizeof(struct postTable)))
  1409. goto ERET;
  1410. }
  1411. if ( setDirEntry( &nte, "post"))
  1412. goto ERET;
  1413. /*
  1414. * 'hhea' Read,modify and write
  1415. */
  1416. if ( fontType==0) {
  1417. if (TTFReadOrgFixedTable( hDC, (char *)&hhea, sizeof hhea,"hhea"))
  1418. goto ERET;
  1419. hhea.metricDataFormat = 0;
  1420. hhea.numberOfHMetrics = (short)numOfGlyph;
  1421. sitom( &hhea.numberOfHMetrics );
  1422. }
  1423. else {
  1424. WIFEhhea( &hhea, bbx);
  1425. }
  1426. if (TTFAppendTable( nfh, &nte, &hhea, sizeof hhea))
  1427. goto ERET;
  1428. if ( setDirEntry( &nte, "hhea"))
  1429. goto ERET;
  1430. /*
  1431. * 'vhea'
  1432. */
  1433. setVhea( &vhea, &hhea, bbx);
  1434. if (TTFAppendTable( nfh, &nte, &vhea, sizeof vhea))
  1435. goto ERET;
  1436. if ( setDirEntry( &nte, "vhea"))
  1437. goto ERET;
  1438. /* Make metrics for missing Glyph */
  1439. cbbx = *bbx;
  1440. makeMetrics( lstHdl, &hM, &vM, &cbbx);
  1441. /*
  1442. * 'vmtx'
  1443. */
  1444. if ((vmet=(struct VMetrics *)malloc( (size_t)sizeof(struct VMetrics)*numOfGlyph))==0)
  1445. goto ERET;
  1446. memset(vmet, 0, sizeof(struct VMetrics)*numOfGlyph);
  1447. /* for missing Glyph */
  1448. *vmet = vM;
  1449. sitom(&vmet->advanceHeight );
  1450. sitom(&vmet->topSideBearing );
  1451. /* for null Glyph */
  1452. (vmet+1)->advanceHeight = 0;
  1453. (vmet+1)->topSideBearing = 0;
  1454. if (TTFAppendTable( nfh,&nte,vmet,sizeof(struct VMetrics)*numOfGlyph))
  1455. goto ERET;
  1456. if ( setDirEntry( &nte, "vmtx"))
  1457. goto ERET;
  1458. free( vmet);
  1459. vmet = 0;
  1460. /*
  1461. * head Read,modify and write
  1462. */
  1463. if ( fontType==0) {
  1464. if (TTFReadOrgFixedTable( hDC,(char *)&head, sizeof head,"head"))
  1465. goto ERET;
  1466. modifyhead( &head);
  1467. }
  1468. else {
  1469. WIFEhead( &head, bbx);
  1470. }
  1471. if (TTFAppendTable( nfh, &nte, &head, sizeof head))
  1472. goto ERET;
  1473. if ( setDirEntry( &nte, "head"))
  1474. goto ERET;
  1475. /*
  1476. * make hmtx
  1477. */
  1478. if ((hmet=(struct HMetrics *)malloc( (size_t)sizeof(struct HMetrics)*numOfGlyph))==0)
  1479. goto ERET;
  1480. memset(hmet, 0, sizeof(struct HMetrics)*numOfGlyph);
  1481. /* for missing Glyph */
  1482. *hmet = hM;
  1483. sitom(&hmet->advanceWidth );
  1484. sitom(&hmet->leftSideBearing);
  1485. /* for null Glyph */
  1486. (hmet+1)->advanceWidth = 0;
  1487. (hmet+1)->leftSideBearing = 0;
  1488. if (TTFAppendTable( nfh,&nte,hmet,sizeof(struct HMetrics)*numOfGlyph))
  1489. goto ERET;
  1490. if ( setDirEntry( &nte, "hmtx"))
  1491. goto ERET;
  1492. free( hmet);
  1493. hmet = 0;
  1494. if ((glyphData = (char *)malloc((size_t)GLYPHBUFSIZ))==0)
  1495. goto ERET;
  1496. if (makeGlyphData( lstHdl, &cbbx, glyphData, GLYPHBUFSIZ, &gdatsiz ))
  1497. goto ERET;
  1498. /*
  1499. * 'loca' make
  1500. */
  1501. if ((loca = (long *)malloc( (size_t)sizeof(unsigned long)*(numOfGlyph+1)))==(long *)0)
  1502. goto ERET;
  1503. *loca = 0;
  1504. ofs = gdatsiz;
  1505. litom(&ofs);
  1506. for ( i = 1; i< numOfGlyph+1; i++)
  1507. *(loca + i)=ofs;
  1508. if (TTFAppendTable( nfh,&nte,loca,sizeof( long)*(numOfGlyph+1)))
  1509. goto ERET;
  1510. if ( setDirEntry( &nte, "loca"))
  1511. goto ERET;
  1512. free( loca);
  1513. loca = 0;
  1514. /*
  1515. * 'maxp' write
  1516. */
  1517. if (TTFAppendTable( nfh,&nte,maxpdata,sizeof(maxpdata)))
  1518. goto ERET;
  1519. if ( setDirEntry( &nte, "maxp"))
  1520. goto ERET;
  1521. /*
  1522. * 'glyf' Write (missing glyph )
  1523. */
  1524. if (TTFAppendTable( nfh, &nte, glyphData, gdatsiz))
  1525. goto ERET;
  1526. if ( setDirEntry( &nte, "glyf"))
  1527. goto ERET;
  1528. free( glyphData);
  1529. glyphData = 0;
  1530. /* Sort dir entry table */
  1531. SortEntry( te, NUMTABLES);
  1532. /* Write dir entry */
  1533. if (TTFWriteDirEntry( nfh, te, NUMTABLES))
  1534. goto ERET;
  1535. /* Set Check sum of file whole to head */
  1536. if (fileChkSum( nfh, te, NUMTABLES, &hdr, &head))
  1537. goto ERET;
  1538. CloseHandle( nfh);
  1539. if ( te) free( te);
  1540. return 0;
  1541. ERET:
  1542. if ( nfh != INVALID_HANDLE_VALUE) CloseHandle( nfh);
  1543. if ( te) free( te);
  1544. if ( nameBuf) free( nameBuf);
  1545. if ( hmet) free( hmet);
  1546. if ( loca) free( loca);
  1547. if ( os2buf) free( os2buf);
  1548. if ( glyphData) free( glyphData);
  1549. return -1;
  1550. }
  1551. /***********************************************************************
  1552. * Obtain BoundingBox ( from 'head' xMin, xMax, yMin, yMax)
  1553. */
  1554. /* */ int
  1555. /* */ TTFGetBBX(
  1556. /* */ HDC hDC,
  1557. /* */ struct BBX *bbx,
  1558. /* */ short *uPEm)
  1559. /*
  1560. * returns : 0, -1
  1561. ***********************************************************************/
  1562. {
  1563. struct HeadTable head;
  1564. DWORD dwTable; /* tagName to request */
  1565. DWORD siz, s;
  1566. memcpy( &dwTable, "head", TAGSIZ);
  1567. siz = (DWORD)sizeof( struct HeadTable);
  1568. if ((s=GetFontData(hDC, dwTable, (DWORD)0, &head,(DWORD)siz))!=siz){
  1569. DWORD err = GetLastError();
  1570. return -1;
  1571. }
  1572. smtoi( &head.xMin);
  1573. smtoi( &head.xMax);
  1574. smtoi( &head.yMin);
  1575. smtoi( &head.yMax);
  1576. smtoi( &head.unitsPerEm);
  1577. bbx->xMin = head.xMin;
  1578. bbx->xMax = head.xMax;
  1579. bbx->yMin = head.yMin;
  1580. bbx->yMax = head.yMax;
  1581. *uPEm = head.unitsPerEm;
  1582. if ( bbx->xMin < 0 )
  1583. bbx->xMin = 0;
  1584. return 0;
  1585. }
  1586. int
  1587. TTFTmpPath( TCHAR *path, TCHAR *tmpPath)
  1588. {
  1589. TCHAR *p1;
  1590. TCHAR dirPath[MAX_PATH];
  1591. lstrcpy( dirPath, path);
  1592. p1 = Mytcsrchr( dirPath, '\\');
  1593. if ( p1==(TCHAR *)0) {
  1594. p1 = Mytcsrchr( dirPath, ':');
  1595. if (p1==(TCHAR *)0)
  1596. *dirPath=(TCHAR)0;
  1597. else
  1598. *(p1+1)=0;
  1599. }
  1600. else
  1601. *p1=0;
  1602. if (GetTempFileName( dirPath, TEXT("TTE"), 0, tmpPath)==0)
  1603. return -1;
  1604. else
  1605. return 0;
  1606. }
  1607. static int
  1608. copyTable( HANDLE iFh,HANDLE oFh, struct TableEntry *te, int nEntry, char *tag)
  1609. {
  1610. struct TableEntry *tep;
  1611. char *buf = NULL;
  1612. if ((tep = searchEntry(te, nEntry, tag))==(struct TableEntry *)0)
  1613. goto ERET;
  1614. if ((buf = (char *)malloc((size_t)tep->siz))==(char *)0)
  1615. goto ERET;
  1616. if ( (TTFReadTable( iFh,tep, buf, (int)tep->siz)!=(int)tep->siz) )
  1617. goto ERET;
  1618. if ( (TTFWriteTable( oFh,tep, buf, (int)tep->siz)!=(int)tep->siz) )
  1619. goto ERET;
  1620. free(buf);
  1621. return 0;
  1622. ERET:
  1623. if (buf) free(buf);
  1624. return -1;
  1625. }
  1626. static int
  1627. copyfblock( HANDLE iFh, HANDLE oFh, unsigned long siz, unsigned long *cs)
  1628. {
  1629. int rwsiz;
  1630. int filsiz;
  1631. int aligne;
  1632. unsigned long chksum;
  1633. char *buf;
  1634. if ((buf = (char *)malloc((size_t) RWBUFSIZ))==(char *)0)
  1635. goto ERET;
  1636. filsiz = (int)(siz % 4);
  1637. if ( filsiz) filsiz = 4-filsiz;
  1638. aligne =0;
  1639. chksum = 0;
  1640. while ( siz > 0) {
  1641. if ( siz > RWBUFSIZ)
  1642. rwsiz = RWBUFSIZ;
  1643. else {
  1644. rwsiz = (int)siz;
  1645. if ( filsiz)
  1646. aligne =1;
  1647. }
  1648. DWORD nByte;
  1649. BOOL res = ReadFile(iFh, buf,(unsigned int)rwsiz, &nByte, NULL );
  1650. if (!res || nByte != (unsigned int)rwsiz)
  1651. goto ERET;
  1652. if ( aligne ) {
  1653. memset( buf+siz, 0, filsiz);
  1654. rwsiz += filsiz;
  1655. }
  1656. chksum += calchksum( buf, rwsiz);
  1657. res = WriteFile ( oFh, buf, (unsigned int)rwsiz, &nByte, NULL);
  1658. if (!res || nByte !=(unsigned int)rwsiz)
  1659. goto ERET;
  1660. siz -= rwsiz;
  1661. }
  1662. *cs = chksum;
  1663. free(buf);
  1664. return 0;
  1665. ERET:
  1666. if(buf) free(buf);
  1667. return -1;
  1668. }
  1669. static int
  1670. mergeGlyph(
  1671. HANDLE iFh,
  1672. HANDLE oFh,
  1673. struct TableEntry *tep,
  1674. char *locabuf,
  1675. int glyphID,
  1676. char *glyphData,
  1677. int glyphSiz)
  1678. {
  1679. long *locp;
  1680. long nloc, cloc;
  1681. long iofs;
  1682. long tail;
  1683. long siz;
  1684. int gid;
  1685. long delta;
  1686. unsigned long cs;
  1687. int filsiz;
  1688. long lval;
  1689. locp = (long *)locabuf;
  1690. cs = 0;
  1691. /* copy leading */
  1692. cloc = *locp;
  1693. lmtoi( &cloc);
  1694. iofs = (unsigned long)tep->ofs+cloc;
  1695. if ((long) SetFilePointer( iFh, iofs, NULL, FILE_BEGIN) != iofs)
  1696. goto ERET;
  1697. if ((long) SetFilePointer( oFh, iofs, NULL, FILE_BEGIN) != iofs)
  1698. goto ERET;
  1699. cloc = *(locp + glyphID);
  1700. lmtoi( &cloc);
  1701. nloc = *(locp + glyphID+1);
  1702. lmtoi( &nloc);
  1703. siz = nloc - cloc;
  1704. if (copyfblock( iFh, oFh, cloc, &cs))
  1705. goto ERET;
  1706. /* write glyphData */
  1707. if ( glyphSiz>0L) {
  1708. filsiz = glyphSiz % 4;
  1709. if ( filsiz) {
  1710. filsiz = 4 - filsiz;
  1711. memset( glyphData+glyphSiz, 0, filsiz);
  1712. glyphSiz += filsiz;
  1713. }
  1714. DWORD nByte;
  1715. BOOL res = WriteFile( oFh, glyphData, (unsigned int)glyphSiz, &nByte, NULL);
  1716. if (!res || nByte !=(unsigned int)glyphSiz)
  1717. goto ERET;
  1718. cs += calchksum( glyphData, glyphSiz);
  1719. }
  1720. iofs = nloc + tep->ofs;
  1721. /* copy trailer */
  1722. if ((long) SetFilePointer( iFh, iofs, NULL, FILE_BEGIN) != iofs)
  1723. goto ERET;
  1724. tail = *(locp+numOfGlyph);
  1725. lmtoi(&tail);
  1726. siz = tail - nloc;
  1727. if (copyfblock( iFh, oFh, siz, &cs))
  1728. goto ERET;
  1729. /* update loca */
  1730. delta = glyphSiz - (nloc - cloc);
  1731. for ( gid = glyphID+1; gid<=numOfGlyph; gid++) {
  1732. lval = *(locp+gid);
  1733. lmtoi(&lval);
  1734. lval += delta;
  1735. litom(&lval);
  1736. *(locp+gid)=lval;
  1737. }
  1738. tep->siz = tail+delta;
  1739. return 0;
  1740. ERET:
  1741. return -1;
  1742. }
  1743. /***********************************************************************
  1744. * Add EUDC Font
  1745. */
  1746. /* */ int
  1747. /* */ TTFAddEUDCChar(
  1748. /* */ TCHAR *path, /* EUDC FontFile path */
  1749. /* */ unsigned short code, /* Charcode */
  1750. /* */ struct BBX *bbx, /* Bounding Box */
  1751. /* */ int lstH) /* List Handle for glyph */
  1752. /*
  1753. * returns :0, -1
  1754. ***********************************************************************/
  1755. {
  1756. struct TTFHeader hdr;
  1757. struct HeadTable head;
  1758. struct MaxpTbl maxp;
  1759. HANDLE fH;
  1760. HANDLE tmpFh = INVALID_HANDLE_VALUE;
  1761. struct TableEntry *te;
  1762. struct TableEntry *tep;
  1763. struct TableEntry *maxpTep;
  1764. struct TableEntry *locaTep;
  1765. int glyphID;
  1766. struct HMetrics hmet;
  1767. struct VMetrics vmet;
  1768. int nEntry;
  1769. char *updbuf;
  1770. char *glyphData;
  1771. int bufsiz;
  1772. int gdatsiz;
  1773. short sval;
  1774. struct BBX cbbx;
  1775. TCHAR tmpPath[MAX_PATH];
  1776. TCHAR savPath[MAX_PATH];
  1777. int sts;
  1778. HINSTANCE hInst = AfxGetInstanceHandle();
  1779. TCHAR szMessage[256];
  1780. lastErr = 0;
  1781. te = ( struct TableEntry *)0;
  1782. updbuf = (char *)0;
  1783. glyphData = (char *)0;
  1784. fH = CreateFile(path,
  1785. GENERIC_READ,
  1786. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1787. NULL,
  1788. OPEN_EXISTING,
  1789. FILE_ATTRIBUTE_NORMAL,
  1790. NULL);
  1791. if ( fH == INVALID_HANDLE_VALUE)
  1792. goto ERET;
  1793. TTFTmpPath( path, tmpPath);
  1794. if ( tmpPath[0] == NULL )
  1795. goto ERET;
  1796. tmpFh = CreateFile(tmpPath,
  1797. GENERIC_WRITE,
  1798. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  1799. NULL,
  1800. CREATE_ALWAYS,
  1801. FILE_ATTRIBUTE_NORMAL,
  1802. NULL);
  1803. if ( tmpFh == INVALID_HANDLE_VALUE)
  1804. goto ERET;
  1805. if ( TTFReadHdr( fH, &hdr))
  1806. goto ERET;
  1807. if ( TTFWriteHdr( tmpFh, &hdr))
  1808. goto ERET;
  1809. nEntry = hdr.numTables;
  1810. glyphID = codeToGID( code);
  1811. /* Read Table entries */
  1812. if ( (te = (struct TableEntry *)malloc((size_t)sizeof(struct TableEntry)*NUMTABLES))==0)
  1813. goto ERET;
  1814. if (TTFReadDirEntry( fH, te, nEntry))
  1815. goto ERET;
  1816. if (TTFWriteDirEntry( tmpFh, te, nEntry))
  1817. goto ERET;
  1818. if (copyTable( fH, tmpFh, te, nEntry, "cvt "))
  1819. goto ERET;
  1820. if (copyTable( fH, tmpFh, te, nEntry, "fpgm"))
  1821. goto ERET;
  1822. if (copyTable( fH, tmpFh, te, nEntry, "prep"))
  1823. goto ERET;
  1824. if (copyTable( fH, tmpFh, te, nEntry, "name"))
  1825. goto ERET;
  1826. if (copyTable( fH, tmpFh, te, nEntry, "cmap"))
  1827. goto ERET;
  1828. if (copyTable( fH, tmpFh, te, nEntry, "OS/2"))
  1829. goto ERET;
  1830. if (copyTable( fH, tmpFh, te, nEntry, "post"))
  1831. goto ERET;
  1832. if (copyTable( fH, tmpFh, te, nEntry, "hhea"))
  1833. goto ERET;
  1834. if (copyTable( fH, tmpFh, te, nEntry, "vhea"))
  1835. goto ERET;
  1836. /* Read maxp Table */
  1837. if ((maxpTep = searchEntry(te, nEntry, "maxp"))==0)
  1838. goto ERET;
  1839. if ( TTFReadTable( fH, maxpTep, &maxp, sizeof maxp)!=(sizeof maxp) )
  1840. goto ERET;
  1841. sval = maxp.numGlyph;
  1842. smtoi( &sval);
  1843. numOfGlyph = sval;
  1844. // Glyph is out of TTE file range, Win9x upgrade
  1845. if (glyphID >= numOfGlyph)
  1846. goto ERET;
  1847. bufsiz = sizeof(struct HMetrics)*(numOfGlyph);
  1848. bufsiz = align32( bufsiz);
  1849. if ( (updbuf = (char *)malloc( (size_t)bufsiz))==0)
  1850. goto ERET;
  1851. /* make metrics for the glyph */
  1852. cbbx = *bbx;
  1853. makeMetrics( lstH, &hmet, &vmet, &cbbx);
  1854. /* make glyph data */
  1855. if ((glyphData = (char *)malloc((size_t)GLYPHBUFSIZ))==0)
  1856. goto ERET;
  1857. if (sts=makeGlyphData(lstH, &cbbx, glyphData, GLYPHBUFSIZ, &gdatsiz)) {
  1858. lastErr = sts;
  1859. goto ERET;
  1860. }
  1861. /* set hmetrics */
  1862. sitom( &hmet.advanceWidth);
  1863. sitom( &hmet.leftSideBearing);
  1864. if ((tep = searchEntry(te, nEntry, "hmtx"))==0)
  1865. goto ERET;
  1866. if ( TTFReadTable( fH, tep, updbuf, bufsiz)<=0)
  1867. goto ERET;
  1868. *((struct HMetrics *)updbuf + glyphID) = hmet;
  1869. if ( TTFWriteTable( tmpFh, tep, updbuf, bufsiz)<=0)
  1870. goto ERET;
  1871. free( updbuf);
  1872. updbuf = 0;
  1873. /* Update 'vmtx' */
  1874. bufsiz = sizeof(struct VMetrics)*(numOfGlyph);
  1875. bufsiz = align32( bufsiz);
  1876. if ( (updbuf = (char *)malloc( (size_t)bufsiz))==0)
  1877. goto ERET;
  1878. /* set vmetrics */
  1879. sitom( &vmet.advanceHeight);
  1880. sitom( &vmet.topSideBearing);
  1881. if ((tep = searchEntry(te, nEntry, "vmtx"))==0)
  1882. goto ERET;
  1883. if ( TTFReadTable( fH, tep, updbuf, bufsiz)<=0)
  1884. goto ERET;
  1885. *((struct VMetrics *)updbuf + glyphID) = vmet;
  1886. if ( TTFWriteTable( tmpFh, tep, updbuf, bufsiz)<=0)
  1887. goto ERET;
  1888. free( updbuf);
  1889. updbuf = 0;
  1890. /* Read loca */
  1891. bufsiz = sizeof(long )*(numOfGlyph+1);
  1892. bufsiz = align32( bufsiz);
  1893. if ( (updbuf = (char *)malloc((size_t)bufsiz)) ==(char *)0)
  1894. goto ERET;
  1895. if ((locaTep = searchEntry(te, nEntry, "loca"))==0)
  1896. goto ERET;
  1897. if ( TTFReadTable( fH, locaTep, updbuf, bufsiz)<=0)
  1898. goto ERET;
  1899. /* move glyf data */
  1900. if ((tep = searchEntry(te, nEntry, "glyf"))==0)
  1901. goto ERET;
  1902. if (mergeGlyph( fH, tmpFh, tep, updbuf, glyphID, glyphData, gdatsiz ))
  1903. goto ERET;
  1904. /* read and cal checkSum of 'glyf' */
  1905. if (tableChkSum( tmpFh, tep))
  1906. goto ERET;
  1907. free( glyphData);
  1908. glyphData =(char *)0;
  1909. /* write loca */
  1910. if ( TTFWriteTable( tmpFh, locaTep, updbuf, bufsiz)<=0)
  1911. goto ERET;
  1912. /* update maxp */
  1913. if ( updateMaxp( &maxp, lstH) < 0)
  1914. goto ERET;
  1915. if (TTFWriteTable(tmpFh, maxpTep, &maxp, sizeof maxp)!=(sizeof maxp))
  1916. goto ERET;
  1917. /* update directory entry */
  1918. if (TTFWriteDirEntry( tmpFh, te, nEntry))
  1919. goto ERET;
  1920. /* Set Check sum of file whole to head */
  1921. if ((tep = searchEntry(te, nEntry, "head"))==0)
  1922. goto ERET;
  1923. if ( TTFReadTable( fH, tep, &head, sizeof head)<=0)
  1924. goto ERET;
  1925. tep->checkSum = 0L;
  1926. if ( TTFWriteTable( tmpFh, tep, &head, sizeof head)<=0)
  1927. goto ERET;
  1928. if (fileChkSum(tmpFh , te, nEntry, &hdr, &head))
  1929. goto ERET;
  1930. if ( TTFWriteTable( tmpFh, tep, &head, sizeof head)<=0)
  1931. goto ERET;
  1932. CloseHandle( fH);
  1933. CloseHandle( tmpFh);
  1934. // fH = tmpFh = -1;
  1935. TTFTmpPath( path, savPath);
  1936. if( DeleteFile( savPath)==0) {
  1937. TCHAR szTitle[256];
  1938. LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR));
  1939. LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR));
  1940. MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK);
  1941. goto ERET2;
  1942. }
  1943. if( MoveFile( path, savPath)==0) {
  1944. TCHAR szTitle[256];
  1945. LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR));
  1946. LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR));
  1947. MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK);
  1948. goto ERET2;
  1949. }
  1950. if( MoveFile( tmpPath, path)==0) {
  1951. TCHAR szTitle[256];
  1952. LoadString(hInst, IDS_MAINFRAMETITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR));
  1953. LoadString(hInst, IDS_NOMEM_MSG, szMessage, sizeof(szMessage) / sizeof(TCHAR));
  1954. MessageBox( AfxGetMainWnd()->GetSafeHwnd(), szMessage, szTitle, MB_OK);
  1955. goto ERET2;
  1956. }
  1957. if ( DeleteFile( savPath) ==0) {
  1958. DeleteFile(path);
  1959. MoveFile(savPath, path);
  1960. if ( te) free(te);
  1961. if ( updbuf) free(updbuf);
  1962. if ( glyphData) free(glyphData);
  1963. return -3; //tte file is being used by another process
  1964. }
  1965. free( te);
  1966. free( updbuf);
  1967. return 0;
  1968. ERET:
  1969. if ( fH != INVALID_HANDLE_VALUE) CloseHandle(fH);
  1970. if ( tmpFh != INVALID_HANDLE_VALUE) CloseHandle(tmpFh);
  1971. if ( te) free(te);
  1972. if ( updbuf) free(updbuf);
  1973. if ( glyphData) free(glyphData);
  1974. return -1;
  1975. ERET2:
  1976. if ( fH != INVALID_HANDLE_VALUE) CloseHandle(fH);
  1977. if ( tmpFh != INVALID_HANDLE_VALUE) CloseHandle(tmpFh);
  1978. if ( te) free(te);
  1979. if ( updbuf) free(updbuf);
  1980. if ( glyphData) free(glyphData);
  1981. if ( tmpPath) DeleteFile( tmpPath);
  1982. return -1;
  1983. }
  1984. /***********************************************************************
  1985. * For Import
  1986. */
  1987. static HANDLE eudcFh;
  1988. static char *locaBuf = 0;
  1989. static char *maxpBuf = 0;
  1990. static char *hmtxBuf = 0;
  1991. static char *vmtxBuf = 0;
  1992. static char *glyphBuf = 0;
  1993. static void
  1994. frebuf()
  1995. {
  1996. if ( locaBuf) {
  1997. free( locaBuf);
  1998. locaBuf = 0;
  1999. }
  2000. if ( maxpBuf) {
  2001. free( maxpBuf);
  2002. maxpBuf = 0;
  2003. }
  2004. if ( vmtxBuf) {
  2005. free( vmtxBuf);
  2006. vmtxBuf = 0;
  2007. }
  2008. if ( hmtxBuf) {
  2009. free( hmtxBuf);
  2010. hmtxBuf = 0;
  2011. }
  2012. if ( glyphBuf) {
  2013. free( glyphBuf);
  2014. glyphBuf = 0;
  2015. }
  2016. if ( et) {
  2017. free( et);
  2018. glyphBuf = 0;
  2019. }
  2020. return;
  2021. }
  2022. int
  2023. TTFOpen( TCHAR *path)
  2024. {
  2025. struct TTFHeader hdr;
  2026. unsigned int bufsiz;
  2027. unsigned short sval;
  2028. et = 0;
  2029. eudcFh = CreateFile(path,
  2030. GENERIC_READ | GENERIC_WRITE,
  2031. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2032. NULL,
  2033. OPEN_EXISTING,
  2034. FILE_ATTRIBUTE_NORMAL,
  2035. NULL);
  2036. if ( eudcFh == INVALID_HANDLE_VALUE)
  2037. goto ERET;
  2038. if (TTFReadHdr(eudcFh,&hdr))
  2039. goto ERET;
  2040. if ((et = (struct TableEntry *)malloc( sizeof (struct TableEntry)*hdr.numTables))
  2041. ==0)
  2042. goto ERET;
  2043. entryNum = hdr.numTables;
  2044. if (TTFReadDirEntry(eudcFh, et, hdr.numTables))
  2045. goto ERET;
  2046. if (TTFReadVarTable( eudcFh, &maxpBuf, &bufsiz, "maxp"))
  2047. goto ERET;
  2048. sval = ((struct MaxpTbl *)maxpBuf) ->numGlyph;
  2049. smtoi( (short *)&sval);
  2050. numOfGlyph = sval;
  2051. if (TTFReadVarTable( eudcFh, &locaBuf, &bufsiz, "loca"))
  2052. goto ERET;
  2053. if (TTFReadVarTable( eudcFh, &hmtxBuf, &bufsiz, "hmtx"))
  2054. goto ERET;
  2055. if (TTFReadVarTable( eudcFh, &vmtxBuf, &bufsiz, "vmtx"))
  2056. goto ERET;
  2057. if ((glyphBuf = (char *)malloc( GLYPHBUFSIZ))==0)
  2058. goto ERET;
  2059. return 0;
  2060. ERET:
  2061. if ( eudcFh != INVALID_HANDLE_VALUE) {
  2062. CloseHandle( eudcFh);
  2063. eudcFh = INVALID_HANDLE_VALUE;
  2064. }
  2065. frebuf();
  2066. return -1;
  2067. }
  2068. int
  2069. TTFClose()
  2070. {
  2071. struct TableEntry *tep;
  2072. struct HeadTable head;
  2073. struct TTFHeader hdr;
  2074. long ofs;
  2075. if ( eudcFh == INVALID_HANDLE_VALUE)
  2076. return -1;
  2077. if (TTFReadHdr( eudcFh, &hdr))
  2078. goto ERET;
  2079. /* obtain glyph table size */
  2080. ofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END);
  2081. /* Update Glyph checkSum */
  2082. if ((tep = searchEntry(et, entryNum, "glyf"))==0)
  2083. goto ERET;
  2084. tep->siz = ofs - tep->ofs;
  2085. /* read and cal checkSum of 'glyf' */
  2086. if (tableChkSum( eudcFh, tep))
  2087. goto ERET;
  2088. if ((tep = searchEntry(et, entryNum, "maxp"))==0)
  2089. goto ERET;
  2090. if (TTFWriteTable( eudcFh, tep, maxpBuf, (int)tep->siz)!=(int)tep->siz)
  2091. goto ERET;
  2092. if ((tep = searchEntry(et, entryNum, "loca"))==0)
  2093. goto ERET;
  2094. if (TTFWriteTable( eudcFh, tep, locaBuf, (int)tep->siz)!=(int)tep->siz)
  2095. goto ERET;
  2096. if ((tep = searchEntry(et, entryNum, "hmtx"))==0)
  2097. goto ERET;
  2098. if (TTFWriteTable( eudcFh, tep, hmtxBuf, (int)tep->siz)!=(int)tep->siz)
  2099. goto ERET;
  2100. if ((tep = searchEntry(et, entryNum, "vmtx"))==0)
  2101. goto ERET;
  2102. if (TTFWriteTable( eudcFh, tep, vmtxBuf, (int)tep->siz)!=(int)tep->siz)
  2103. goto ERET;
  2104. if ((tep = searchEntry(et, entryNum, "head"))==0)
  2105. goto ERET;
  2106. if ( TTFReadTable(eudcFh, tep, &head, sizeof(head))!=sizeof(head))
  2107. goto ERET;
  2108. if ( fileChkSum(eudcFh, et, entryNum, &hdr, &head))
  2109. goto ERET;
  2110. if ( TTFWriteDirEntry( eudcFh, et, entryNum))
  2111. goto ERET;
  2112. CloseHandle( eudcFh);
  2113. frebuf();
  2114. return 0;
  2115. ERET:
  2116. CloseHandle( eudcFh);
  2117. frebuf();
  2118. return -1;
  2119. }
  2120. int
  2121. TTFGetEUDCBBX(TCHAR *path, struct BBX *bbx, short *upem)
  2122. {
  2123. struct HeadTable head;
  2124. HANDLE fH;
  2125. fH = CreateFile(path,
  2126. GENERIC_READ,
  2127. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2128. NULL,
  2129. OPEN_EXISTING,
  2130. FILE_ATTRIBUTE_NORMAL,
  2131. NULL);
  2132. if ( fH == INVALID_HANDLE_VALUE)
  2133. goto ERET;
  2134. if ( TTFReadFixedTable(fH, (char *)&head,sizeof head,"head"))
  2135. goto ERET;
  2136. smtoi( &head.xMin);
  2137. smtoi( &head.xMax);
  2138. smtoi( &head.yMin);
  2139. smtoi( &head.yMax);
  2140. smtoi( &head.unitsPerEm);
  2141. bbx->xMin = head.xMin;
  2142. bbx->xMax = head.xMax;
  2143. bbx->yMin = head.yMin;
  2144. bbx->yMax = head.yMax;
  2145. *upem = head.unitsPerEm;
  2146. if ( bbx->xMin < 0 )
  2147. bbx->xMin = 0;
  2148. CloseHandle( fH);
  2149. return 0;
  2150. ERET:
  2151. if (fH!=INVALID_HANDLE_VALUE)
  2152. CloseHandle( fH);
  2153. return -1;
  2154. }
  2155. static void
  2156. makeMetrics(int lsthdl, struct HMetrics *hM, struct VMetrics *vM, struct BBX *bbx)
  2157. {
  2158. struct VHEAD *vhd;
  2159. struct VDATA *vp;
  2160. int np;
  2161. int sts;
  2162. int xmin, ymin, xmax, ymax;
  2163. if ( (sts = VDGetHead( lsthdl, &vhd))!=0)
  2164. goto RET;
  2165. if ( (sts = VDGetNCont( lsthdl))<=0)
  2166. goto SPACE_CHAR;
  2167. xmin = xmax = vhd->headp->vd.x;
  2168. ymin = ymax = vhd->headp->vd.y;
  2169. while ( vhd->next != NIL) {
  2170. vp = vhd->headp;
  2171. np = vhd->nPoints;
  2172. while ( np-->0) {
  2173. if (vp->vd.x > xmax)
  2174. xmax = vp->vd.x;
  2175. else if(vp->vd.x < xmin)
  2176. xmin = vp->vd.x;
  2177. if (vp->vd.y > ymax)
  2178. ymax = vp->vd.y;
  2179. else if(vp->vd.y < ymin)
  2180. ymin = vp->vd.y;
  2181. vp = vp->next;
  2182. }
  2183. vhd = vhd->next;
  2184. }
  2185. // if ( xmin < 0)
  2186. // xmin = 0;
  2187. hM->leftSideBearing = (short)xmin;
  2188. hM->advanceWidth = bbx->xMax - bbx->xMin;
  2189. {
  2190. int hmw = hM->advanceWidth + 1;
  2191. int ii = 0;
  2192. while (hmw >> 1)
  2193. {
  2194. hmw >>= 1;
  2195. ii++;
  2196. }
  2197. hmw = 1;
  2198. while (ii--) hmw *= 2;
  2199. int gap1 = hM->advanceWidth - hmw;
  2200. int gap2 = hmw*2 - hM->advanceWidth;
  2201. hmw = gap1 > gap2 ? hmw * 2 : hmw;
  2202. hM->advanceWidth = (short)hmw;
  2203. }
  2204. vM->topSideBearing = bbx->yMax - ymax;
  2205. if (vM->topSideBearing < 0)
  2206. vM->topSideBearing = 0;
  2207. vM->advanceHeight = bbx->yMax - bbx->yMin;
  2208. bbx->xMin = xmin;
  2209. bbx->yMin = ymin;
  2210. bbx->xMax = xmax;
  2211. bbx->yMax = ymax;
  2212. return;
  2213. RET:
  2214. SPACE_CHAR:
  2215. hM->leftSideBearing = (short)bbx->xMax;
  2216. hM->advanceWidth = bbx->xMax - bbx->xMin;
  2217. vM->topSideBearing = bbx->yMax - bbx->yMin;
  2218. vM->advanceHeight = bbx->yMax - bbx->yMin;
  2219. bbx->xMin = bbx->xMax;
  2220. bbx->yMax = bbx->yMin;
  2221. return;
  2222. }
  2223. int
  2224. TTFAppend( unsigned short code, struct BBX *bbx, int lsthdl)
  2225. {
  2226. int glyphID;
  2227. struct HMetrics hmet;
  2228. struct VMetrics vmet;
  2229. int updflg;
  2230. int gdatsiz;
  2231. struct BBX cbbx;
  2232. int sts;
  2233. glyphID = codeToGID( code);
  2234. lastErr = 0;
  2235. /* make metrics */
  2236. cbbx = *bbx;
  2237. makeMetrics( lsthdl, &hmet, &vmet, &cbbx);
  2238. /* make glyph data */
  2239. if (sts =makeGlyphData(lsthdl, &cbbx, glyphBuf, GLYPHBUFSIZ, &gdatsiz)) {
  2240. lastErr = sts;
  2241. goto ERET;
  2242. }
  2243. /* set hmetrics */
  2244. sitom( &hmet.advanceWidth);
  2245. sitom( &hmet.leftSideBearing);
  2246. *((struct HMetrics *)hmtxBuf + glyphID) = hmet;
  2247. /* Update 'vmtx' */
  2248. sitom( &vmet.advanceHeight);
  2249. sitom( &vmet.topSideBearing);
  2250. *((struct VMetrics *)vmtxBuf + glyphID) = vmet;
  2251. /* write glyf data */
  2252. if (TTFImpGlyphWrite( glyphID, glyphBuf, gdatsiz))
  2253. goto ERET;
  2254. /* update maxp */
  2255. if ((updflg = updateMaxp( (struct MaxpTbl *)maxpBuf, lsthdl)) < 0)
  2256. goto ERET;
  2257. return 0;
  2258. ERET:
  2259. return -1;
  2260. }
  2261. /*
  2262. * Copy
  2263. */
  2264. int
  2265. TTFImpCopy( TCHAR *sPath, TCHAR *dPath)
  2266. {
  2267. HANDLE sFh, dFh;
  2268. struct TTFHeader hdr;
  2269. struct TableEntry *te;
  2270. int tblSiz;
  2271. int ntbl;
  2272. int tcnt;
  2273. char *buf;
  2274. int bufsiz;
  2275. sFh = dFh = 0;
  2276. te = 0;
  2277. buf = 0;
  2278. /* Open src */
  2279. sFh = CreateFile(sPath,
  2280. GENERIC_READ,
  2281. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2282. NULL,
  2283. OPEN_EXISTING,
  2284. FILE_ATTRIBUTE_NORMAL,
  2285. NULL);
  2286. if (sFh == INVALID_HANDLE_VALUE)
  2287. goto ERET;
  2288. /* create open destination*/
  2289. dFh = CreateFile(dPath,
  2290. GENERIC_WRITE,
  2291. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  2292. NULL,
  2293. CREATE_ALWAYS,
  2294. FILE_ATTRIBUTE_NORMAL,
  2295. NULL);
  2296. if (dFh == INVALID_HANDLE_VALUE)
  2297. goto ERET;
  2298. /* read header */
  2299. if ( TTFReadHdr( sFh, &hdr))
  2300. goto ERET;
  2301. ntbl = (int)hdr.numTables;
  2302. /* write header */
  2303. if ( TTFWriteHdr( dFh, &hdr))
  2304. goto ERET;
  2305. /* read directory entry */
  2306. tblSiz = sizeof( struct TableEntry)*ntbl;
  2307. if ((te = (struct TableEntry *)malloc(tblSiz))==(struct TableEntry *)0)
  2308. goto ERET;
  2309. if ( TTFReadDirEntry(sFh, te, ntbl))
  2310. goto ERET;
  2311. /* write directory entry */
  2312. if ( TTFWriteDirEntry(dFh, te, ntbl))
  2313. goto ERET;
  2314. /* copy each table (except glyph)*/
  2315. for ( tcnt = 0; tcnt < ntbl; tcnt++) {
  2316. if ( memcmp((te+tcnt)->tagName,"glyf", 4)) {
  2317. bufsiz = (int)(te+tcnt)->siz;
  2318. buf = (char *)malloc((int)(te+tcnt)->siz);
  2319. if (TTFReadTable( sFh, te+tcnt, buf, bufsiz)!=bufsiz)
  2320. goto ERET;
  2321. if (TTFWriteTable( dFh, te+tcnt, buf, bufsiz)!=bufsiz)
  2322. goto ERET;
  2323. free( buf);
  2324. buf = 0;
  2325. }
  2326. }
  2327. /* close */
  2328. CloseHandle( sFh);
  2329. CloseHandle( dFh);
  2330. free( te);
  2331. return 0;
  2332. ERET:
  2333. if (sFh != INVALID_HANDLE_VALUE) CloseHandle(sFh);
  2334. if (dFh != INVALID_HANDLE_VALUE) CloseHandle(dFh);
  2335. if (te)
  2336. free( te);
  2337. if ( buf) free( buf);
  2338. return -1;
  2339. }
  2340. int
  2341. TTFImpGlyphCopy(
  2342. HANDLE sFh,
  2343. int glyphID)
  2344. {
  2345. struct TableEntry *tep;
  2346. long *locap;
  2347. long cloc, nloc;
  2348. long siz;
  2349. long ofs;
  2350. long wofs;
  2351. char *buf;
  2352. DWORD nByte;
  2353. buf = 0;
  2354. if ((tep = searchEntry( et, entryNum, "glyf"))==0)
  2355. goto ERET;
  2356. locap = (long *)locaBuf;
  2357. cloc = *(locap+glyphID);
  2358. lmtoi( &cloc);
  2359. nloc = *(locap+glyphID+1);
  2360. lmtoi( &nloc);
  2361. siz = nloc - cloc;
  2362. ofs = tep->ofs + cloc;
  2363. if ( (long) SetFilePointer( sFh, ofs, NULL, FILE_BEGIN) != ofs)
  2364. goto ERET;
  2365. wofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END);
  2366. wofs -= tep->ofs;
  2367. litom( &wofs);
  2368. *(locap+glyphID) = wofs;
  2369. if ( siz) {
  2370. if ( (buf = (char *)malloc((int)siz))==(char *)0)
  2371. goto ERET;
  2372. BOOL res = ReadFile( sFh, buf, (unsigned int)siz, &nByte, NULL);
  2373. if (!res || nByte !=(unsigned int)siz)
  2374. goto ERET;
  2375. res = WriteFile( eudcFh, buf,(unsigned int)siz, &nByte, NULL);
  2376. if (!res || nByte !=(unsigned int)siz)
  2377. goto ERET;
  2378. }
  2379. free( buf);
  2380. return 0;
  2381. ERET:
  2382. if ( buf) free( buf);
  2383. return -1;
  2384. }
  2385. int
  2386. TTFImpGlyphWrite(
  2387. int glyphID, char *glyph, int siz)
  2388. {
  2389. struct TableEntry *tep;
  2390. long ofs;
  2391. long wofs;
  2392. long *locap;
  2393. DWORD nByte;
  2394. if ( glyphID >= numOfGlyph)
  2395. return -1;
  2396. if ((tep = searchEntry( et, entryNum, "glyf"))==0)
  2397. goto ERET;
  2398. wofs = SetFilePointer( eudcFh, 0L, NULL, FILE_END);
  2399. ofs = wofs - tep->ofs;
  2400. litom( &ofs);
  2401. locap = (long *)locaBuf;
  2402. *(locap+glyphID) = ofs;
  2403. if ( siz) {
  2404. BOOL res = WriteFile(eudcFh, glyph, (unsigned int)siz, &nByte, NULL);
  2405. if (!res || nByte !=(unsigned int)siz)
  2406. goto ERET;
  2407. }
  2408. return 0;
  2409. ERET:
  2410. return -1;
  2411. }
  2412. int
  2413. TTFImpTerm(HANDLE orgFh, int glyphID)
  2414. {
  2415. struct TableEntry *tep;
  2416. long ofs;
  2417. long wofs;
  2418. long *locap;
  2419. int gid;
  2420. //
  2421. // copy the rest of the glyph data over.
  2422. //
  2423. for ( gid = glyphID; gid < numOfGlyph; gid++)
  2424. {
  2425. if (TTFImpGlyphCopy(orgFh, gid))
  2426. return -1;
  2427. }
  2428. if ((tep = searchEntry( et, entryNum, "glyf"))==0)
  2429. return -1;
  2430. locap = (long *)locaBuf;
  2431. wofs = SetFilePointer( eudcFh, 0L,NULL, FILE_END);
  2432. ofs = wofs - tep->ofs;
  2433. litom( &ofs);
  2434. *(locap + numOfGlyph) = ofs;
  2435. tep->siz = wofs - tep->ofs;
  2436. return 0;
  2437. }
  2438. int
  2439. TTFLastError()
  2440. {
  2441. return lastErr;
  2442. }
  2443. /* EOF */