Leaked source code of windows server 2003
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.

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