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.

1630 lines
47 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFOttt1.c
  8. *
  9. *
  10. * $Header:
  11. */
  12. /* -------------------------------------------------------------------------
  13. Header Includes
  14. --------------------------------------------------------------------------- */
  15. #include "UFOTTT1.h"
  16. #include "UFLMem.h"
  17. #include "UFLErr.h"
  18. #include "UFLPriv.h"
  19. #include "UFLStd.h"
  20. #include "UFLMath.h"
  21. #include "ParseTT.h"
  22. #include "UFLVm.h"
  23. #if UNIX
  24. #include <sys/varargs.h>
  25. #else
  26. #include <stdarg.h>
  27. #endif
  28. /* ---------------------------------------------------------------------------
  29. Constant
  30. --------------------------------------------------------------------------- */
  31. #define kEExecKey 55665
  32. #define kCSKey 4330
  33. /**************************************************************************************
  34. TYPE 1 commands for use with CharString(). The high word contains the
  35. number of operands on the stack, and the loword contains the encoding
  36. of the command. For two byte commands the LSB of the low word contains
  37. 12 decimal and the MSB of the low word contains the second byte of the
  38. code. See Chapter 6 of the Black Book for further details.
  39. ***************************************************************************************/
  40. #define kT1cscStartChar 0xFFFFFFFF /* dummy command to signal start of character definition. */
  41. /*
  42. y dy hstem(1). Declares the vertical range of a horizontal stem zone b/w the y coordinates y and y+dy,
  43. where y is relative to the y coordinate of the left sidebearing point.
  44. */
  45. #define kT1cscHStem 0x00020001
  46. /*
  47. x dx vstem(3). Declares the horizontal range of a vertical stem zone b/w the x coordinates x and x+dx,
  48. where x is relative to the x coordinate of the left sidebearing point.
  49. */
  50. #define kT1cscVStem 0x00020003
  51. /*
  52. dy vmoveto(4). For vertical moveto. This is equivalent to 0 dy rmoveto.
  53. */
  54. #define kT1cscVMoveTo 0x00010004
  55. /*
  56. dx dy rlineto(5). Behaves like rlineto in the PostScript language.
  57. */
  58. #define kT1cscRLineTo 0x00020005
  59. /*
  60. dx hlineto(6). For horizontal lineto. Equivalent to dx 0 rlineto.
  61. */
  62. #define kT1cscHLineTo 0x00010006
  63. /*
  64. dy vlineto(7). For vertical lineto. Equivalent to 0 dy rlineto.
  65. */
  66. #define kT1cscVLineTo 0x00010007
  67. /*
  68. dx1 dy1 dx2 dy2 dx3 dy3 rrcurveto(8). For relative rcuveto.
  69. The arguments to the command are relative to each other.
  70. Equivalent to dx1 dy1 (dx1+ dx2) (dy1 + dy2) (dx1+ dx2 + dx3) (dy1 + dy2 + dy3) rcurveto.
  71. */
  72. #define kT1cscRRCurveTo 0x00060008
  73. /*
  74. closepath(9). Close a subpath.
  75. */
  76. #define kT1cscClosePath 0x00000009
  77. /*
  78. sbx sby wx wy sbw (12 7). Sets the left sidebearing point to (sbx, sby) and sets
  79. the character width vetor to (wx, wy) in character space.
  80. */
  81. #define kT1cscSBW 0x0004070C
  82. /*
  83. sbx wx hsbw (13). Sets the left sidebearing point at (sbx, 0) and sets the
  84. character width vector to (wx, 0) in character space.
  85. */
  86. #define kT1cscHSBW 0x0002000D
  87. /*
  88. endchar(14). Finishes a charstring outline definition and
  89. must be the last command in a character's outline.
  90. */
  91. #define kT1cscEndChar 0x0000000E
  92. /*
  93. dx dy rmoveto(15). Behaves like rmoveto in PostScript.
  94. */
  95. #define kT1cscRMoveTo 0x00020015
  96. /*
  97. dx hmoveto(22). For horizontal moveto. Equivalent to dx 0 rmoveto.
  98. */
  99. #define kT1cscHMoveTo 0x00010016
  100. /*
  101. dy1 dx2 dy2 dx3 vhcurveto(30). For vertical-horizontal curveto.
  102. Equivalent to 0 dy1 dx2 dy2 dx3 0 rrcureveto.
  103. */
  104. #define kT1cscVHCurveTo 0x0004001E
  105. /*
  106. dx1 dx2 dy2 dy3 hvcurveto(31). For horizontal-vertical curveto.
  107. Equivalent to dx1 0 dx2 dy2 0 dy3 rrcurveto.
  108. */
  109. #define kT1cscHVCurveTo 0x0004001F
  110. /***********************************************************************
  111. CS Data buffer size
  112. ************************************************************************/
  113. #define kCSBufInitSize 1024 /* Initial size of TTT1CSBuf */
  114. #define kCSGrow 512 /* Amount to grow CharString buffer */
  115. /* ---------------------------------------------------------------------------
  116. Global variables
  117. --------------------------------------------------------------------------- */
  118. /* The 4 random number that is output at the beginning of a charstring. See blackbook. */
  119. static unsigned char randomBytes[] = { 71, 36, 181, 202 };
  120. /* ---------------------------------------------------------------------------
  121. Macros
  122. --------------------------------------------------------------------------- */
  123. /* ---------------------------------------------------------------------------
  124. Implementation
  125. --------------------------------------------------------------------------- */
  126. UFLErrCode CharString( TTT1FontStruct *pFont, unsigned long cmd, ...);
  127. /************************************** CSBuf Implementation **********************************************/
  128. static CSBufStruct *
  129. CSBufInit(
  130. const UFLMemObj *pMem
  131. )
  132. {
  133. CSBufStruct *p;
  134. p = (CSBufStruct *)UFLNewPtr( pMem, sizeof( *p ) );
  135. if ( p )
  136. {
  137. p->pBuf = (char*) UFLNewPtr( pMem, kCSBufInitSize );
  138. if ( p->pBuf )
  139. {
  140. p->ulSize = kCSBufInitSize;
  141. p->pEnd = p->pBuf + kCSBufInitSize;
  142. p->pPos = p->pBuf;
  143. p->pMemObj = (UFLMemObj *)pMem;
  144. }
  145. else
  146. {
  147. UFLDeletePtr( pMem, p );
  148. p = 0;
  149. }
  150. }
  151. return p;
  152. }
  153. static void
  154. CSBufCleanUp(
  155. CSBufStruct *h
  156. )
  157. {
  158. if ( h )
  159. {
  160. if ( h->pBuf )
  161. {
  162. UFLDeletePtr( h->pMemObj, h->pBuf );
  163. h->pBuf = 0;
  164. }
  165. UFLDeletePtr( h->pMemObj, h );
  166. }
  167. }
  168. /***************************************************************************
  169. *
  170. * CSBufGrowBuffer
  171. *
  172. * Function: Grows the currently allocated CharString buffer by
  173. * kCSGrow bytes.
  174. *
  175. ***************************************************************************/
  176. static UFLBool
  177. CSBufGrowBuffer(
  178. CSBufStruct *h
  179. )
  180. {
  181. UFLBool retVal;
  182. unsigned long len = (unsigned long)CSBufCurrentLen( h );
  183. retVal = UFLEnlargePtr( h->pMemObj, (void**)&h->pBuf, (unsigned long)(CSBufCurrentSize( h ) + kCSGrow), 1 );
  184. if ( retVal )
  185. {
  186. h->ulSize += kCSGrow;
  187. h->pEnd = h->pBuf + h->ulSize;
  188. h->pPos = h->pBuf + len;
  189. }
  190. return retVal;
  191. }
  192. /****************************************************************
  193. *
  194. * CSBufCheckSize
  195. *
  196. * Function: Check to see if the current size of the
  197. * buffer can fit the len bytes data, if not, grow the
  198. * buffer
  199. *
  200. **************************************************************/
  201. static UFLBool
  202. CSBufCheckSize(
  203. CSBufStruct *h,
  204. const unsigned long len
  205. )
  206. {
  207. UFLBool retVal = 1;
  208. while ( retVal && ((unsigned long)CSBufFreeLen( h ) < len) )
  209. {
  210. retVal = CSBufGrowBuffer( h );
  211. }
  212. return retVal;
  213. }
  214. /****************************************************************
  215. *
  216. * CSBufAddNumber
  217. *
  218. * Function: Converts a long int into the Type 1 representation of
  219. * numbers (described in Chapter 6 of the Black Book.)
  220. * The basic idea is they have a few special ranges
  221. * where they can represent the long in < 4 bytes and
  222. * store a long + prefix for everything else.
  223. *
  224. * The if statements show the range of numbers and the
  225. * body of the if statements compute the representation
  226. * for that range. The formulas were derived by reversing
  227. * the formulas given in the book (which tells how to convert
  228. * an encoded number back to a long.) As an example take the
  229. * 108 <= dw <= 1131 range. The derivation is as follows:
  230. *
  231. * dw = ((v - 247) * 256) + w + 108. Find v,w given dw.
  232. * dw - 108 = ((v - 247) * 256) + w
  233. * v - 247 = (dw - 108) / 256
  234. * *** v = 247 + (dw - 108) / 256 ***
  235. * *** w = (dw - 108) % 256 ***
  236. *
  237. * The rest of the derivations are no harder than this one.
  238. *
  239. *
  240. **************************************************************/
  241. static UFLErrCode
  242. CSBufAddNumber(
  243. CSBufStruct *h,
  244. long dw
  245. )
  246. {
  247. dw = UFLTruncFixedToShort( dw ); /* Truncate fraction */
  248. /* Make sure buffer has room */
  249. if (CSBufCheckSize(h, 5) == 0 )
  250. {
  251. return kErrOutOfMemory;
  252. }
  253. /* Encode number based on its value */
  254. if (-107 <= dw && dw <= 107)
  255. CSBufAddChar( h, (char)(dw + 139) );
  256. else if (108 <= dw && dw <= 1131)
  257. {
  258. dw -= 108;
  259. CSBufAddChar( h, (char)((dw >> 8) + 247) );
  260. CSBufAddChar( h, (char)(dw) ); /* Just the low byte */
  261. } /* end else */
  262. else if (-1131 <= dw && dw <= -108)
  263. {
  264. dw += 108;
  265. CSBufAddChar( h, (char)((-dw >> 8) + 251) );
  266. CSBufAddChar( h, (char)(-dw) ); /* Just the low byte */
  267. } /* end else if */
  268. else
  269. {
  270. CSBufAddChar( h, (char)255 );
  271. CSBufAddChar( h, (char)(dw >> 24) );
  272. CSBufAddChar( h, (char)(dw >> 16) );
  273. CSBufAddChar( h, (char)(dw >> 8) );
  274. CSBufAddChar( h, (char)(dw) );
  275. } /* end else */
  276. return kNoErr;
  277. }
  278. static void
  279. Encrypt(
  280. const unsigned char *inBuf,
  281. const unsigned char *outBuf,
  282. long inLen,
  283. long *outLen,
  284. unsigned short *key
  285. )
  286. {
  287. register unsigned char cipher;
  288. register unsigned char *plainSource = (unsigned char *)inBuf;
  289. register unsigned char *cipherDest = (unsigned char *)outBuf;
  290. register unsigned short R = *key;
  291. *outLen = inLen;
  292. while ( --inLen >= 0 )
  293. {
  294. cipher = (*plainSource++ ^ (unsigned char)(R >> 8));
  295. R = (unsigned short)(((unsigned short)cipher + R) * 52845 + 22719);
  296. *cipherDest++ = cipher;
  297. } /* end while */
  298. *key = R;
  299. } /* end Encrypt() */
  300. static UFLErrCode
  301. EExec(
  302. UFLHANDLE stream,
  303. unsigned char *inBuf,
  304. UFLsize_t inLen,
  305. unsigned short *pEExecKey
  306. )
  307. {
  308. unsigned char buff[128]; /* Temporary buffer for output data */
  309. UFLsize_t bytesLeft, bytesEncrypt, maxEncrypt;
  310. long bytesOut;
  311. unsigned char* pb;
  312. UFLErrCode retVal = kNoErr;
  313. pb = inBuf;
  314. bytesLeft = inLen;
  315. maxEncrypt = sizeof(buff);
  316. while ( bytesLeft > 0 )
  317. {
  318. bytesEncrypt = min( bytesLeft, maxEncrypt ) ;
  319. Encrypt( pb, buff, bytesEncrypt, &bytesOut, pEExecKey );
  320. pb += bytesEncrypt;
  321. bytesLeft -= bytesEncrypt;
  322. retVal = StrmPutAsciiHex( stream, (const char*)buff, bytesOut );
  323. if ( retVal != kNoErr )
  324. break;
  325. }
  326. return retVal;
  327. }
  328. /*
  329. * BeginEExec
  330. *
  331. * Function: Signals that we wish to start generating the eexec
  332. * portion of the Type 1 font. The first four bytes of
  333. * a Type 1 font must be randomly generated and satisfy
  334. * two constraints which basically ensure that they do
  335. * not generate whitespace or hexadecimal characters.
  336. * For more details read Chapter 7 of the Black Book.
  337. */
  338. static UFLErrCode
  339. BeginEExec(
  340. UFOStruct *pUFO
  341. )
  342. {
  343. UFLErrCode retVal;
  344. UFLHANDLE stream = pUFO->pUFL->hOut;
  345. char nilStr[] = "\0\0"; // An empty/nil string.
  346. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  347. retVal = StrmPutStringEOL( stream, nilStr );
  348. if ( kNoErr == retVal )
  349. {
  350. if ( pFont->info.bEExec )
  351. {
  352. StrmPutStringEOL( stream, "currentfile eexec" );
  353. if ( kNoErr == retVal )
  354. pFont->eexecKey = (unsigned short)kEExecKey;
  355. if ( kNoErr == retVal )
  356. retVal = EExec( stream, randomBytes, 4, &pFont->eexecKey );
  357. }
  358. else
  359. {
  360. StrmPutStringEOL( stream, "systemdict begin" );
  361. }
  362. }
  363. return retVal;
  364. }
  365. /***************************************************************************
  366. *
  367. * EndEExec
  368. *
  369. * Function: Signals the client is done generating the eexec portion
  370. * of a Type 1 font. The function tells eexec function in printer
  371. * that eexec data are over by sending 512 zeroes at the end.
  372. *
  373. *
  374. ***************************************************************************/
  375. static UFLErrCode
  376. EndEExec(
  377. UFOStruct *pUFO
  378. )
  379. {
  380. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  381. static char *closeStr = "mark currentfile closefile ";
  382. UFLErrCode retVal = kNoErr;
  383. UFLHANDLE stream = pUFO->pUFL->hOut;
  384. short i;
  385. if ( !pFont->info.bEExec )
  386. {
  387. retVal = StrmPutStringEOL( stream, "end" );
  388. }
  389. else
  390. {
  391. retVal = EExec( stream, (unsigned char*)closeStr, UFLstrlen( closeStr ), &pFont->eexecKey );
  392. for ( i = 0; i < 8 && retVal == kNoErr; i++ )
  393. retVal = StrmPutStringEOL( stream, "0000000000000000000000000000000000000000000000000000000000000000" );
  394. if ( kNoErr == retVal )
  395. retVal = StrmPutStringEOL( stream, "cleartomark" );
  396. }
  397. return retVal;
  398. }
  399. static UFLErrCode
  400. PutLine(
  401. UFOStruct *pUFO,
  402. char *line
  403. )
  404. {
  405. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  406. UFLErrCode retVal;
  407. #ifdef WIN_ENV
  408. static char c[2] = { kWinLineEnd, kLineEnd };
  409. #else
  410. static char c[1] = { kLineEnd };
  411. #endif
  412. if ( 0 == pFont->info.bEExec )
  413. retVal = StrmPutStringEOL( pUFO->pUFL->hOut, line );
  414. else
  415. {
  416. /* MWCWP1 doesn't like the implicit cast from char* to unsigned char* --jfu */
  417. retVal = EExec( pUFO->pUFL->hOut, (unsigned char*) line, UFLstrlen( line ), &pFont->eexecKey );
  418. if ( retVal == kNoErr )
  419. #ifdef WIN_ENV
  420. retVal = EExec( pUFO->pUFL->hOut, c, 2, &pFont->eexecKey );
  421. #else
  422. /* MWCWP1 doesn't like the implicit cast from char* to unsigned char* --jfu */
  423. retVal = EExec( pUFO->pUFL->hOut, (unsigned char*) c, 1, &pFont->eexecKey );
  424. #endif
  425. }
  426. return retVal;
  427. }
  428. /***************************************************************************
  429. *
  430. * DownloadFontHeader
  431. *
  432. *
  433. * Function: Download an empty font. After this action, glyphs
  434. * can be added to the font.
  435. *
  436. ***************************************************************************/
  437. static UFLErrCode
  438. DownloadFontHeader(
  439. UFOStruct *pUFO
  440. )
  441. {
  442. UFLErrCode retVal;
  443. char buf[128];
  444. UFLHANDLE stream;
  445. char **pp;
  446. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  447. const static char *lenIV = "/lenIV -1 def";
  448. const static char *type1Hdr[] =
  449. {
  450. "/PaintType 0 def",
  451. "/FontType 1 def",
  452. "/FontBBox { 0 0 0 0 } def", /* Assuming that the font does not use the seac command, see black book page 13 */
  453. "AddFontInfoBegin", /* Goodname */
  454. "AddFontInfo",
  455. "AddFontInfoEnd",
  456. "currentdict",
  457. "end",
  458. ""
  459. };
  460. /* Private dict definition */
  461. const static char *privateDict[] =
  462. {
  463. "dup /Private 7 dict dup begin",
  464. "/BlueValues [] def",
  465. "/MinFeature {16 16} def",
  466. "/password 5839 def",
  467. "/ND {def} def",
  468. "/NP {put} def",
  469. ""
  470. };
  471. const static char *rdDef[] =
  472. {
  473. "/RD {string currentfile exch readstring pop} def\n",
  474. "/RD {string currentfile exch readhexstring pop} def\n"
  475. } ;
  476. if ( pUFO->flState != kFontInit )
  477. return kErrInvalidState;
  478. stream = pUFO->pUFL->hOut;
  479. retVal = StrmPutStringEOL( stream, "11 dict begin" );
  480. if ( kNoErr == retVal )
  481. {
  482. UFLsprintf( buf, CCHOF(buf), "/FontName /%s def", pUFO->pszFontName );
  483. retVal = StrmPutStringEOL( stream, buf );
  484. }
  485. /* Put font matrix */
  486. if ( kNoErr == retVal )
  487. {
  488. retVal = StrmPutString( stream, "/FontMatrix " );
  489. if ( kNoErr == retVal )
  490. retVal = StrmPutString( stream, "[1 " );
  491. if ( kNoErr == retVal )
  492. retVal = StrmPutFixed( stream, pFont->info.matrix.a );
  493. if ( kNoErr == retVal )
  494. retVal = StrmPutString( stream, "div 0 0 1 " );
  495. if ( kNoErr == retVal )
  496. retVal = StrmPutFixed( stream, pFont->info.matrix.d );
  497. if ( kNoErr == retVal )
  498. retVal = StrmPutStringEOL( stream, "div 0 0 ] def" );
  499. }
  500. /* Put font encoding */
  501. if ( kNoErr == retVal )
  502. retVal = StrmPutString( stream, "/Encoding " );
  503. if ( kNoErr == retVal )
  504. {
  505. if ( pUFO->pszEncodeName == 0 )
  506. retVal = StrmPutString( stream, gnotdefArray );
  507. else
  508. retVal = StrmPutString( stream, pUFO->pszEncodeName );
  509. }
  510. if ( retVal == kNoErr )
  511. retVal = StrmPutStringEOL( stream, " def" );
  512. /* Put type1 header */
  513. for ( pp = (char **)type1Hdr; **pp && retVal == kNoErr; pp++ )
  514. retVal = StrmPutStringEOL( stream, *pp );
  515. /* Goodname */
  516. pUFO->dwFlags |= UFO_HasFontInfo;
  517. pUFO->dwFlags |= UFO_HasG2UDict;
  518. /* Put the systemdict on top of the dict stack ( this is what 'eexec' does ).*/
  519. if ( kNoErr == retVal )
  520. {
  521. BeginEExec( pUFO );
  522. }
  523. for ( pp = (char**)privateDict; **pp && retVal == kNoErr; pp++ )
  524. {
  525. retVal = PutLine( pUFO, *pp );
  526. }
  527. /* Define lenIV = -1 which means no extra byte and no encryption. */
  528. if ( 0 == pFont->info.bEExec )
  529. retVal = StrmPutStringEOL( stream, lenIV );
  530. /* Define RD base on the output format */
  531. if ( 0 == pFont->info.bEExec )
  532. PutLine( pUFO, ( StrmCanOutputBinary( stream ) ) ? (char *)rdDef[0] : (char *)rdDef[1] );
  533. else
  534. {
  535. PutLine( pUFO, (char *)rdDef[0] );
  536. }
  537. /* Define the CharString dict */
  538. UFLsprintf( buf, CCHOF(buf), "2 index /CharStrings %d dict dup begin", pFont->info.fData.maxGlyphs );
  539. PutLine( pUFO, buf );
  540. return retVal;
  541. }
  542. static UFLErrCode
  543. DownloadFontFooter(
  544. UFOStruct *pUFO
  545. )
  546. {
  547. UFLErrCode retVal;
  548. UFLHANDLE stream = pUFO->pUFL->hOut;
  549. char **eftr;
  550. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  551. /* Finish up the encrypted portion */
  552. static char *encryptFtr[] =
  553. {
  554. "end",
  555. "end",
  556. "put",
  557. "put",
  558. "dup /FontName get exch definefont pop",
  559. ""
  560. };
  561. retVal = kNoErr;
  562. for ( eftr = encryptFtr; **eftr && retVal == kNoErr; eftr++ )
  563. {
  564. retVal = PutLine( pUFO, *eftr );
  565. }
  566. if ( retVal == kNoErr )
  567. retVal = EndEExec( pUFO );
  568. return retVal;
  569. }
  570. static UFLErrCode
  571. DownloadCharString(
  572. UFOStruct *pUFO,
  573. const char *glyphName
  574. )
  575. {
  576. char buf[128];
  577. UFLErrCode retVal;
  578. UFLHANDLE stream;
  579. unsigned long bufLen;
  580. UFLsize_t len = 0;
  581. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  582. retVal = kNoErr;
  583. stream = pUFO->pUFL->hOut;
  584. bufLen = (unsigned long)CSBufCurrentLen( pFont->pCSBuf );
  585. //
  586. // Note that for user-mode driver, UFLsprintf() returns HRESULT.
  587. //
  588. #ifdef WIN32KERNEL
  589. len = UFLsprintf( buf, CCHOF(buf), "/%s %ld RD ", glyphName, bufLen );
  590. #else // !WIN32KERNEL
  591. if (SUCCEEDED(UFLsprintf( buf, CCHOF(buf), "/%s %ld RD ", glyphName, bufLen )))
  592. {
  593. len = strlen(buf);
  594. }
  595. #endif
  596. if ( pFont->info.bEExec )
  597. retVal = EExec( stream, (unsigned char*)buf, len, &pFont->eexecKey );
  598. else
  599. {
  600. // Fix Adobe Bug #233904: PS error when TBCP
  601. // Do not send 0D 0A after RD.
  602. if (StrmCanOutputBinary( stream ))
  603. {
  604. retVal = StrmPutString( stream, (const char*)buf );
  605. }
  606. else
  607. {
  608. retVal = StrmPutStringEOL( stream, (const char*)buf );
  609. }
  610. }
  611. if ( kNoErr == retVal )
  612. {
  613. if ( pFont->info.bEExec )
  614. {
  615. retVal = EExec( stream, (unsigned char*)pFont->pCSBuf->pBuf, (UFLsize_t) bufLen, &pFont->eexecKey );
  616. if ( kNoErr == retVal )
  617. retVal = EExec( stream, (unsigned char*)" ND ", (UFLsize_t) 4, &pFont->eexecKey );
  618. }
  619. else
  620. {
  621. if ( StrmCanOutputBinary( stream ) )
  622. retVal = StrmPutBytes( stream, (const char*)pFont->pCSBuf->pBuf, (UFLsize_t) bufLen, 0 );
  623. else
  624. retVal = StrmPutAsciiHex( stream, (const char*)pFont->pCSBuf->pBuf, bufLen );
  625. if ( kNoErr == retVal )
  626. retVal = StrmPutStringEOL( stream, (const char*)" ND " );
  627. }
  628. }
  629. return retVal;
  630. }
  631. static UFLErrCode
  632. DefineNotDefCharString(
  633. UFOStruct *pUFO
  634. )
  635. {
  636. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  637. UFLErrCode retVal = kNoErr;
  638. retVal = CharString( pFont, kT1cscStartChar );
  639. if ( kNoErr == retVal )
  640. retVal = CharString( pFont, kT1cscSBW, 0L, 0L, 0L, 0L ); /* make the origin stay the same */
  641. if ( kNoErr == retVal )
  642. retVal = CharString( pFont, kT1cscEndChar );
  643. if ( kNoErr == retVal )
  644. retVal = DownloadCharString( pUFO, ".notdef" );
  645. return retVal;
  646. }
  647. static UFLErrCode
  648. BeginCharString(
  649. TTT1FontStruct *pFont
  650. )
  651. {
  652. if ( pFont->info.bEExec )
  653. {
  654. /* Output 4 random number as defined in the black book */
  655. unsigned char* rb = randomBytes;
  656. short i;
  657. if ( 0 == CSBufCheckSize( pFont->pCSBuf, 4 ) )
  658. {
  659. return kErrOutOfMemory;
  660. }
  661. else
  662. {
  663. for ( i = 0; i < 4; i++, rb++ )
  664. CSBufAddChar( pFont->pCSBuf, *rb );
  665. }
  666. }
  667. return kNoErr;
  668. }
  669. static UFLErrCode
  670. EndCharString(
  671. TTT1FontStruct *pFont
  672. )
  673. {
  674. if ( pFont->info.bEExec )
  675. {
  676. unsigned long len = (unsigned long)CSBufCurrentLen( pFont->pCSBuf );
  677. unsigned short key = kCSKey;
  678. /* MWCWP1 doesn't like the implicit casts from char* to const unsigned char* --jfu */
  679. Encrypt( (const unsigned char*) CSBufBuffer( pFont->pCSBuf ),
  680. (const unsigned char*) CSBufBuffer( pFont->pCSBuf ),
  681. (long)len, (long*)&len, &key );
  682. }
  683. return kNoErr;
  684. }
  685. /***************************************************************************
  686. *
  687. * AddGlyph
  688. *
  689. *
  690. * Function: Adds a single glyph to the font by calling the client
  691. * outline callback routine.
  692. *
  693. ***************************************************************************/
  694. static UFLErrCode
  695. AddGlyph(
  696. UFOStruct *pUFO,
  697. UFLGlyphID glyph,
  698. const char *glyphName
  699. )
  700. {
  701. UFLErrCode retVal = kNoErr;
  702. UFLFixedPoint pt[3], currentPoint;
  703. UFLFixed xWidth, yWidth, xSB, ySB;
  704. UFLFontProcs *pFontProcs;
  705. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  706. UFLBool bYAxisNegative = 1;
  707. //this flag determines whether the char string's Yaxis grows in
  708. //positive(lower left) or negative(upper left) direction from the origin.
  709. //For w95 ufoenc.CreateGlyphOutlineIter(), bYAxisNegative = 0
  710. //Font wNT40/50, ufoenc.CreateGlyphoutlineIter(), bYAxisNegative = 1;
  711. //ang 11/17/97
  712. long lArgs[6];
  713. pFontProcs = (UFLFontProcs *)&pUFO->pUFL->fontProcs;
  714. /* Whatever is in glyph, pass back to client */
  715. if ( pFontProcs->pfCreateGlyphOutlineIter( pUFO->hClientData, glyph, &xWidth, &yWidth, &xSB, &ySB, &bYAxisNegative ) )
  716. {
  717. UFLBool cont = 1;
  718. do{
  719. switch ( pFontProcs->pfNextOutlineSegment( pUFO->hClientData, &pt[0], &pt[1], &pt[2] ) )
  720. {
  721. case kUFLOutlineIterDone:
  722. default:
  723. if ( pFontProcs->pfDeleteGlyphOutlineIter )
  724. pFontProcs->pfDeleteGlyphOutlineIter( pUFO->hClientData );
  725. cont = 0;
  726. break;
  727. case kUFLOutlineIterBeginGlyph:
  728. /* Signal start of character definition */
  729. retVal = CharString( pFont, kT1cscStartChar );
  730. if ( retVal == kNoErr )
  731. {
  732. /* Output the sidebearing and width information. */
  733. retVal = CharString( pFont, kT1cscSBW, UFLTruncFixed(xSB), UFLTruncFixed(ySB),
  734. UFLTruncFixed(xWidth), UFLTruncFixed(yWidth) );
  735. /* Initialize the current point to be the origin */
  736. currentPoint.x = xSB;
  737. currentPoint.y = ySB;
  738. }
  739. break;
  740. case kUFLOutlineIterEndGlyph:
  741. break;
  742. case kUFLOutlineIterMoveTo:
  743. if (bYAxisNegative)
  744. {
  745. retVal = CharString( pFont, kT1cscRMoveTo,
  746. UFLTruncFixed(pt[0].x - currentPoint.x),
  747. UFLTruncFixed(currentPoint.y - pt[0].y));
  748. }
  749. else
  750. {
  751. // In NT, do Truncate AFTER subtract. In Win95, do truncate BEFORE subtract.
  752. retVal = CharString( pFont, kT1cscRMoveTo,
  753. UFLTruncFixed(pt[0].x) - UFLTruncFixed(currentPoint.x),
  754. UFLTruncFixed(pt[0].y) - UFLTruncFixed(currentPoint.y));
  755. }
  756. /* Remember last point so we can generate relative commands */
  757. currentPoint = pt[0];
  758. break;
  759. case kUFLOutlineIterLineTo:
  760. if (bYAxisNegative)
  761. {
  762. retVal = CharString( pFont, kT1cscRLineTo,
  763. UFLTruncFixed(pt[0].x - currentPoint.x),
  764. UFLTruncFixed(currentPoint.y - pt[0].y));
  765. }
  766. else
  767. {
  768. // In NT, do Truncate AFTER subtract. In Win95, do truncate BEFORE subtract.
  769. retVal = CharString( pFont, kT1cscRLineTo,
  770. UFLTruncFixed(pt[0].x) - UFLTruncFixed(currentPoint.x),
  771. UFLTruncFixed(pt[0].y) - UFLTruncFixed(currentPoint.y));
  772. }
  773. currentPoint = pt[0];
  774. break;
  775. case kUFLOutlineIterCurveTo:
  776. /* Convert points so that they match with rrcurveto arguments */
  777. if (bYAxisNegative)
  778. {
  779. retVal = CharString( pFont, kT1cscRRCurveTo,
  780. UFLTruncFixed( pt[0].x - currentPoint.x ),
  781. UFLTruncFixed( currentPoint.y - pt[0].y ),
  782. UFLTruncFixed(pt[1].x - pt[0].x),
  783. UFLTruncFixed(pt[0].y - pt[1].y),
  784. UFLTruncFixed(pt[2].x - pt[1].x),
  785. UFLTruncFixed(pt[1].y - pt[2].y) );
  786. }
  787. else
  788. {
  789. // In NT, do Truncate AFTER subtract. In Win95, do truncate BEFORE subtract.
  790. lArgs[0] = UFLTruncFixed( pt[0].x);
  791. lArgs[0] -= UFLTruncFixed(currentPoint.x );
  792. lArgs[1] = UFLTruncFixed( pt[0].y);
  793. lArgs[1] -= UFLTruncFixed(currentPoint.y);
  794. lArgs[2] = UFLTruncFixed(pt[1].x);
  795. lArgs[2] -= UFLTruncFixed(pt[0].x);
  796. lArgs[3] = UFLTruncFixed(pt[1].y);
  797. lArgs[3] -= UFLTruncFixed(pt[0].y);
  798. lArgs[4] = UFLTruncFixed(pt[2].x);
  799. lArgs[4] -= UFLTruncFixed(pt[1].x);
  800. lArgs[5] = UFLTruncFixed(pt[2].y);
  801. lArgs[5] -= UFLTruncFixed(pt[1].y) ;
  802. retVal = CharString( pFont, kT1cscRRCurveTo,
  803. lArgs[0], lArgs[1], lArgs[2], lArgs[3], lArgs[4], lArgs[5] );
  804. }
  805. currentPoint = pt[2];
  806. break;
  807. case kUFLOutlineIterClose:
  808. {
  809. retVal = CharString( pFont, kT1cscClosePath );
  810. break;
  811. }
  812. } /* switch() */
  813. if ( cont && retVal != kNoErr )
  814. cont = 0;
  815. } while ( cont );
  816. if ( retVal == kNoErr )
  817. retVal = CharString( pFont, kT1cscEndChar );
  818. if ( retVal == kNoErr )
  819. {
  820. retVal = DownloadCharString( pUFO, glyphName );
  821. }
  822. }
  823. else retVal = kErrGetGlyphOutline;
  824. return retVal;
  825. }
  826. static UFLErrCode
  827. DownloadAddGlyphHeader(
  828. UFOStruct *pUFO
  829. )
  830. {
  831. unsigned char buf[256];
  832. UFLErrCode retVal;
  833. UFLHANDLE stream;
  834. char **hdr;
  835. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  836. const static char *encryptHdrU[] =
  837. {
  838. "findfont dup",
  839. "/Private get begin",
  840. "/CharStrings get begin",
  841. ""
  842. };
  843. retVal = kNoErr;
  844. stream = pUFO->pUFL->hOut;
  845. retVal = BeginEExec( pUFO );
  846. if ( kNoErr == retVal )
  847. {
  848. UFLsize_t len = 0;
  849. //
  850. // Note that for user-mode driver, UFLsprintf() returns HRESULT.
  851. //
  852. #ifdef WIN32KERNEL
  853. len = UFLsprintf( (char*)buf, CCHOF(buf), "/%s ", pUFO->pszFontName );
  854. #else // !WIN32KERNEL
  855. if (SUCCEEDED(UFLsprintf( (char*)buf, CCHOF(buf), "/%s ", pUFO->pszFontName )))
  856. {
  857. len = strlen(buf);
  858. }
  859. #endif
  860. if ( pFont->info.bEExec )
  861. retVal = EExec( stream, buf, len, &pFont->eexecKey );
  862. else
  863. retVal = StrmPutStringEOL( stream, (const char*)buf );
  864. }
  865. for ( hdr = (char**)encryptHdrU; retVal == kNoErr && **hdr; hdr++ )
  866. {
  867. if ( pFont->info.bEExec )
  868. retVal = EExec( stream, (unsigned char*)*hdr, UFLstrlen(*hdr), &pFont->eexecKey );
  869. else
  870. retVal = StrmPutStringEOL( stream, (const char*)*hdr );
  871. }
  872. return retVal;
  873. }
  874. static UFLErrCode
  875. DownloadAddGlyphFooter(
  876. UFOStruct *pUFO
  877. )
  878. {
  879. UFLErrCode retVal;
  880. static char *addGlyphFtr = "end end";
  881. retVal = PutLine( pUFO, addGlyphFtr );
  882. if ( kNoErr == retVal )
  883. retVal = EndEExec( pUFO );
  884. return retVal;
  885. }
  886. /***************************************************************************
  887. *
  888. * CharString
  889. *
  890. * Function: Translates symbolic Type 1 character commands into
  891. * their encoded, encrypted equivalent. The list of
  892. * available commands is defined in the constant section.
  893. * They are used by passing the command constant followed
  894. * by the long arguments required by the function.
  895. *
  896. * Example: CharString(lppd, kT1cscRMoveTo, lx, ly);
  897. *
  898. * To make a character definition use kT1cscStartChar, followed
  899. * by all of the Type 1 character commands, and ending with
  900. * kT1cscEndChar. The buffer contains the CharString
  901. * encrypted/encoded representation. Given the length and the
  902. * properly encrypted data, the caller has enough information
  903. * to generate PS code that will add the character to a font
  904. * definition. For more detail see Chapters 2 and 6 in the
  905. * Black Book.
  906. *
  907. ***************************************************************************/
  908. UFLErrCode
  909. CharString(
  910. TTT1FontStruct *pFont,
  911. unsigned long cmd,
  912. ...
  913. )
  914. {
  915. va_list arglist;
  916. long args[10];
  917. unsigned short argCount, i, j;
  918. UFLErrCode retVal = kNoErr;
  919. switch ( cmd )
  920. {
  921. case kT1cscStartChar:
  922. {
  923. /* Allocate the buffer */
  924. CSBufRewind( pFont->pCSBuf );
  925. return BeginCharString( pFont );
  926. }
  927. default:
  928. /* get the variable arguments */
  929. va_start(arglist, cmd);
  930. j = ((unsigned short)(cmd >> 16)) & 0xffff;
  931. for (i=0; i<j; i++)
  932. {
  933. args[i] = va_arg(arglist, long);
  934. }
  935. va_end(arglist);
  936. /* Attempt to optimize the command */
  937. switch ( cmd ) {
  938. case kT1cscSBW:
  939. /* This can be reduced to an HSBW if the Y components are zero */
  940. if ( args[1] || args[3] )
  941. break;
  942. args[1] = args[2];
  943. cmd = kT1cscHSBW;
  944. break;
  945. case kT1cscRMoveTo:
  946. /* This can be reduced to a horizontal or vertical
  947. movement if one of the components is zero.
  948. */
  949. if ( 0 == args[1] )
  950. {
  951. cmd = kT1cscHMoveTo;
  952. }
  953. else if ( 0 == args[0] )
  954. {
  955. args[0] = args[1];
  956. cmd = kT1cscVMoveTo;
  957. }
  958. break;
  959. case kT1cscRLineTo:
  960. /* This can be reduced to a horizontal or vertical
  961. line if one of the components is zero.
  962. */
  963. if ( 0 == args[1] )
  964. {
  965. cmd = kT1cscHLineTo;
  966. }
  967. else if ( 0 == args[0] )
  968. {
  969. args[0] = args[1];
  970. cmd = kT1cscVLineTo;
  971. }
  972. break;
  973. case kT1cscRRCurveTo:
  974. /*
  975. This can be reduced to a simpler curve operator if the tangents
  976. at the endpoints of the Bezier are horizontal or vertical
  977. */
  978. if ( 0 == args[1] && 0 == args[4] )
  979. {
  980. args[1] = args[2];
  981. args[2] = args[3];
  982. args[3] = args[5];
  983. cmd = kT1cscHVCurveTo;
  984. }
  985. else if ( 0 == args[0] && 0 == args[5] )
  986. {
  987. args[0] = args[1];
  988. args[1] = args[2];
  989. args[2] = args[3];
  990. args[3] = args[4];
  991. cmd = kT1cscVHCurveTo;
  992. }
  993. break;
  994. } /* switch (cmd) */
  995. /* arg count stored in HIWORD */
  996. argCount = ((unsigned short) (((long) (cmd) >> 16) & 0x0000FFFF));
  997. /*
  998. If buffer isn't big enough to hold this command expand buffer first.
  999. Exit if we can't grow buffer.
  1000. Note: The formula (wArgCount * 5 + 2) assumes the worst case size
  1001. requirement for the current command (all arguments stored
  1002. as full longs and a two byte command).
  1003. */
  1004. if ( 0 == CSBufCheckSize( pFont->pCSBuf, (unsigned long)( argCount * 5 + 2 ) ) )
  1005. {
  1006. retVal = kErrOutOfMemory;
  1007. }
  1008. else
  1009. {
  1010. /* Push the numbers onto the stack */
  1011. i = 0;
  1012. while ( retVal == kNoErr && argCount-- )
  1013. {
  1014. retVal = CSBufAddNumber( pFont->pCSBuf, args[i++] );
  1015. }
  1016. }
  1017. /* Push the command onto the stack */
  1018. if ( kNoErr == retVal )
  1019. {
  1020. char c = (char) (cmd & 0x000000FF);
  1021. CSBufAddChar( pFont->pCSBuf, c );
  1022. if ( 12 == c )
  1023. { /* two byte command */
  1024. CSBufAddChar( pFont->pCSBuf, (char) ((cmd >> 8) & 0x000000FF) );
  1025. }
  1026. /* If this isn't the end of a character definition return success */
  1027. if ( kT1cscEndChar == cmd )
  1028. {
  1029. /* We have finished the character: encrypt it if necessary */
  1030. retVal = EndCharString( pFont );
  1031. }
  1032. }
  1033. } /* switch (cmd) */
  1034. return retVal;
  1035. }
  1036. /***********************************
  1037. Public Functions
  1038. ***********************************/
  1039. void
  1040. TTT1FontCleanUp(
  1041. UFOStruct *pUFObj
  1042. )
  1043. {
  1044. TTT1FontStruct *pFont;
  1045. if (pUFObj->pAFont == nil)
  1046. return;
  1047. pFont = (TTT1FontStruct *) pUFObj->pAFont->hFont;
  1048. if ( pFont )
  1049. {
  1050. if ( pFont->pCSBuf != nil )
  1051. {
  1052. CSBufCleanUp( pFont->pCSBuf );
  1053. }
  1054. pFont->pCSBuf = nil;
  1055. }
  1056. }
  1057. UFLErrCode
  1058. TTT1VMNeeded(
  1059. UFOStruct *pUFObj,
  1060. const UFLGlyphsInfo *pGlyphs,
  1061. unsigned long *pVMNeeded,
  1062. unsigned long *pFCNeeded
  1063. )
  1064. {
  1065. UFLErrCode retVal = kNoErr;
  1066. short i;
  1067. unsigned long totalGlyphs;
  1068. TTT1FontStruct *pFont;
  1069. unsigned short wIndex;
  1070. if (pUFObj->flState < kFontInit)
  1071. return (kErrInvalidState);
  1072. if ( pFCNeeded )
  1073. *pFCNeeded = 0;
  1074. pFont = (TTT1FontStruct *) pUFObj->pAFont->hFont;
  1075. if (pGlyphs == nil || pGlyphs->pGlyphIndices == nil || pVMNeeded == nil)
  1076. return kErrInvalidParam;
  1077. totalGlyphs = 0;
  1078. /* Scan the list, check what characters that we have downloaded */
  1079. if ( pUFObj->pUFL->bDLGlyphTracking && pGlyphs->pCharIndex)
  1080. {
  1081. UFLmemcpy( (const UFLMemObj* ) pUFObj->pMem,
  1082. pUFObj->pAFont->pVMGlyphs,
  1083. pUFObj->pAFont->pDownloadedGlyphs,
  1084. (UFLsize_t) (GLYPH_SENT_BUFSIZE( pFont->info.fData.cNumGlyphs)));
  1085. for ( i = 0; i < pGlyphs->sCount; i++ )
  1086. {
  1087. /* use glyphIndex to track - fix bug when we do T0/T1 */
  1088. wIndex = (unsigned short) pGlyphs->pGlyphIndices[i] & 0x0000FFFF; /* LOWord is the real GID */
  1089. if (wIndex >= UFO_NUM_GLYPHS(pUFObj) )
  1090. continue;
  1091. if ( !IS_GLYPH_SENT( pUFObj->pAFont->pVMGlyphs, wIndex ) )
  1092. {
  1093. SET_GLYPH_SENT_STATUS( pUFObj->pAFont->pVMGlyphs, wIndex );
  1094. totalGlyphs++;
  1095. }
  1096. }
  1097. }
  1098. else
  1099. totalGlyphs = pGlyphs->sCount;
  1100. if ( pUFObj->flState == kFontInit )
  1101. *pVMNeeded = kVMTTT1Header;
  1102. else
  1103. *pVMNeeded = 0;
  1104. *pVMNeeded += totalGlyphs * kVMTTT1Char;
  1105. *pVMNeeded = VMRESERVED( *pVMNeeded );
  1106. return kNoErr;
  1107. }
  1108. /***************************************************************************
  1109. *
  1110. * DownloadIncrFont
  1111. *
  1112. *
  1113. * Function: Adds all of the characters from pGlyphs that aren't already
  1114. * downloaded for the TrueType font.
  1115. *
  1116. * Note: pCharIndex is used to track which char(in this font) is downloaded or not
  1117. * It can be nil if client doesn't wish to track - e.g. Escape(DownloadFace)
  1118. * It has no relationship with ppGlyphNames.
  1119. * E.g., ppGlyphNames[0]="/A", pCharIndex[0]=6, pGlyphIndices[0]=1000: means
  1120. * To download glyphID 1000 as Char-named "/A" and Also, remember the 6th-char is downloaded
  1121. *
  1122. * ppGlphNames is optional - if not provided, UFL will parse "post" table to find from GlyphID
  1123. * - it it is provided, we may use it as a "hint" for the glyphName - use it if parse failed.
  1124. *
  1125. ***************************************************************************/
  1126. #pragma optimize("", off)
  1127. UFLErrCode
  1128. TTT1FontDownloadIncr(
  1129. UFOStruct *pUFObj,
  1130. const UFLGlyphsInfo *pGlyphs,
  1131. unsigned long *pVMUsage,
  1132. unsigned long *pFCUsage
  1133. )
  1134. {
  1135. UFLGlyphID *glyphs;
  1136. short i, hasCharToAdd;
  1137. short hasCharToEncode;
  1138. UFLErrCode retVal;
  1139. char *pGoodName;
  1140. unsigned short wIndex;
  1141. UFLBool bGoodName; // GoodName
  1142. char pGlyphName[32]; // GoodName
  1143. if (pUFObj->flState < kFontInit)
  1144. return (kErrInvalidState);
  1145. if ( pFCUsage )
  1146. *pFCUsage = 0;
  1147. if ( pGlyphs == nil || pGlyphs->pGlyphIndices == nil)
  1148. return kErrInvalidParam;
  1149. /* We don't support download full font */
  1150. if ( pGlyphs->sCount == -1 )
  1151. return kErrNotImplement;
  1152. retVal = kNoErr;
  1153. glyphs = pGlyphs->pGlyphIndices;
  1154. hasCharToAdd = 1; // Assume has some char to add
  1155. hasCharToEncode = 0;
  1156. /* If AddChar - First check if there is any chars to Add! */
  1157. if (pUFObj->flState == kFontHasChars &&
  1158. pUFObj->pUFL->bDLGlyphTracking != 0 &&
  1159. pGlyphs->pCharIndex != nil)
  1160. {
  1161. hasCharToAdd = 0; /* if asked to AddChar and totrack, check if there is any to add */
  1162. for ( i = 0; i < pGlyphs->sCount; i++ )
  1163. {
  1164. /* use glyphIndex to track - fix bug when we do T0/T1 */
  1165. wIndex = (unsigned short) glyphs[i] & 0x0000FFFF; /* LOWord is the real GID */
  1166. if (wIndex >= UFO_NUM_GLYPHS(pUFObj) )
  1167. continue;
  1168. if (!IS_GLYPH_SENT( pUFObj->pAFont->pDownloadedGlyphs, wIndex ))
  1169. {
  1170. hasCharToAdd = 1;
  1171. break;
  1172. }
  1173. if (!IS_GLYPH_SENT( pUFObj->pUpdatedEncoding, pGlyphs->pCharIndex[i] ))
  1174. hasCharToEncode = 1;
  1175. }
  1176. }
  1177. if (hasCharToAdd==0)
  1178. {
  1179. // This code is to fix bug 288988.
  1180. if (hasCharToEncode)
  1181. UpdateEncodingVector(pUFObj, pGlyphs, 0, pGlyphs->sCount);
  1182. if (pVMUsage) *pVMUsage = 0 ;
  1183. return retVal; /* no error, no VM used */
  1184. }
  1185. /* Download the font header if this is the first time we download the font */
  1186. if ( pUFObj->flState == kFontInit )
  1187. {
  1188. retVal = DownloadFontHeader( pUFObj );
  1189. if ( pVMUsage )
  1190. *pVMUsage = kVMTTT1Header;
  1191. }
  1192. else
  1193. {
  1194. retVal = DownloadAddGlyphHeader( pUFObj );
  1195. if ( pVMUsage )
  1196. *pVMUsage = 0;
  1197. }
  1198. /* Every font must have a .notdef character! */
  1199. if ( kNoErr == retVal && pUFObj->flState == kFontInit )
  1200. {
  1201. retVal = DefineNotDefCharString( pUFObj );
  1202. if ( kNoErr == retVal && pVMUsage )
  1203. *pVMUsage += kVMTTT1Char;
  1204. }
  1205. /* Download the new glyphs */
  1206. if(retVal == kNoErr)
  1207. {
  1208. // Skip the ones don't exist. Don't stop when there's error
  1209. for ( i = 0; i < pGlyphs->sCount; ++i)
  1210. {
  1211. /* use glyphIndex to track - fix bug when we do T0/T1 */
  1212. wIndex = (unsigned short) glyphs[i] & 0x0000FFFF; /* LOWord is the real GID */
  1213. if (wIndex >= UFO_NUM_GLYPHS(pUFObj) )
  1214. continue;
  1215. if ( 0 == pUFObj->pUFL->bDLGlyphTracking ||
  1216. pGlyphs->pCharIndex == nil || // DownloadFace
  1217. pUFObj->pEncodeNameList || // DownloadFace
  1218. !IS_GLYPH_SENT( pUFObj->pAFont->pDownloadedGlyphs, wIndex ) )
  1219. {
  1220. // GoodName
  1221. pGoodName = pGlyphName;
  1222. bGoodName = FindGlyphName(pUFObj, pGlyphs, i, wIndex, &pGoodName);
  1223. // Fix bug 274008 Check Glyph Name only for DownloadFace.
  1224. if (pUFObj->pEncodeNameList)
  1225. {
  1226. if ((UFLstrcmp( pGoodName, Hyphen ) == 0) && (i == 45))
  1227. {
  1228. // Add /minus to CharString
  1229. //if ( kNoErr == retVal )
  1230. retVal = AddGlyph( pUFObj, glyphs[i], Minus);
  1231. }
  1232. if ((UFLstrcmp( pGoodName, Hyphen ) == 0) && (i == 173))
  1233. {
  1234. // Add /sfthyphen to CharString
  1235. //if ( kNoErr == retVal )
  1236. retVal = AddGlyph( pUFObj, glyphs[i], SftHyphen);
  1237. }
  1238. if (!ValidGlyphName(pGlyphs, i, wIndex, pGoodName))
  1239. continue;
  1240. // Send only one ".notdef"
  1241. if ((UFLstrcmp( pGoodName, Notdef ) == 0) &&
  1242. (wIndex == (unsigned short) (glyphs[0] & 0x0000FFFF)) &&
  1243. IS_GLYPH_SENT( pUFObj->pAFont->pDownloadedGlyphs, wIndex ))
  1244. continue;
  1245. }
  1246. //if ( kNoErr == retVal )
  1247. retVal = AddGlyph( pUFObj, glyphs[i], pGoodName);
  1248. if ( kNoErr == retVal )
  1249. {
  1250. SET_GLYPH_SENT_STATUS( pUFObj->pAFont->pDownloadedGlyphs, wIndex );
  1251. if (bGoodName) // GoodName
  1252. SET_GLYPH_SENT_STATUS( pUFObj->pAFont->pCodeGlyphs, wIndex );
  1253. if ( pVMUsage )
  1254. *pVMUsage += kVMTTT1Char;
  1255. }
  1256. }
  1257. }
  1258. }
  1259. /* Always download font footer and update encoding vector regardless of
  1260. retVal. This is because passthrough code may try to use this font */
  1261. retVal = ( pUFObj->flState == kFontInit ) ? DownloadFontFooter( pUFObj ) : DownloadAddGlyphFooter( pUFObj );
  1262. /* update Encoding vector with the good names if necessary*/
  1263. UpdateEncodingVector(pUFObj, pGlyphs, 0, pGlyphs->sCount);
  1264. /* GoodName */
  1265. /* Update the FontInfo with Unicode information. */
  1266. if ((kNoErr == retVal) && (pGlyphs->sCount > 0) &&
  1267. (pUFObj->dwFlags & UFO_HasG2UDict) &&
  1268. (pUFObj->pUFL->outDev.lPSLevel >= kPSLevel2) && // Don't do this for level1 printers
  1269. !(pUFObj->lNumNT4SymGlyphs))
  1270. {
  1271. /* Check pUFObj->pAFont->pCodeGlyphs to see if we really need to update it. */
  1272. for ( i = 0; i < pGlyphs->sCount; i++ )
  1273. {
  1274. wIndex = (unsigned short) glyphs[i] & 0x0000FFFF; /* LOWord is the real GID. */
  1275. if (wIndex >= UFO_NUM_GLYPHS(pUFObj) )
  1276. continue;
  1277. if (!IS_GLYPH_SENT( pUFObj->pAFont->pCodeGlyphs, wIndex ) )
  1278. {
  1279. // Found at least one not updated, do it (once) for all.
  1280. retVal = UpdateCodeInfo(pUFObj, pGlyphs, 0);
  1281. break;
  1282. }
  1283. }
  1284. }
  1285. if ( kNoErr == retVal )
  1286. {
  1287. pUFObj->flState = kFontHasChars;
  1288. }
  1289. if ( pVMUsage )
  1290. *pVMUsage = VMRESERVED( *pVMUsage );
  1291. return retVal;
  1292. }
  1293. #pragma optimize("", on)
  1294. /* Send PS code to undefine fonts: /UDF should be defined properly by client
  1295. * to something like:
  1296. /UDF
  1297. {
  1298. IsLevel2
  1299. {undefinefont}
  1300. { pop }ifelse
  1301. } bind def
  1302. */
  1303. UFLErrCode
  1304. TTT1UndefineFont(
  1305. UFOStruct *pUFObj
  1306. )
  1307. {
  1308. UFLErrCode retVal = kNoErr;
  1309. char buf[128];
  1310. UFLHANDLE stream;
  1311. if (pUFObj->flState < kFontHeaderDownloaded) return retVal;
  1312. stream = pUFObj->pUFL->hOut;
  1313. UFLsprintf( buf, CCHOF(buf), "/%s UDF", pUFObj->pszFontName );
  1314. retVal = StrmPutStringEOL( stream, buf );
  1315. return retVal;
  1316. }
  1317. UFOStruct *
  1318. TTT1FontInit(
  1319. const UFLMemObj *pMem,
  1320. const UFLStruct *pUFL,
  1321. const UFLRequest *pRequest
  1322. )
  1323. {
  1324. TTT1FontStruct *pFont = nil;
  1325. UFLTTT1FontInfo *pInfo;
  1326. UFOStruct *pUFObj;
  1327. long maxGlyphs;
  1328. /* MWCWP1 doesn't like the implicit cast from void* to UFOStruct* --jfu */
  1329. pUFObj = (UFOStruct*) UFLNewPtr( pMem, sizeof( UFOStruct ) );
  1330. if (pUFObj == 0)
  1331. return 0;
  1332. /* Initialize data */
  1333. UFOInitData(pUFObj, UFO_TYPE1, pMem, pUFL, pRequest,
  1334. (pfnUFODownloadIncr) TTT1FontDownloadIncr,
  1335. (pfnUFOVMNeeded) TTT1VMNeeded,
  1336. (pfnUFOUndefineFont) TTT1UndefineFont,
  1337. (pfnUFOCleanUp) TTT1FontCleanUp,
  1338. (pfnUFOCopy) CopyFont );
  1339. /* pszFontName should be ready/allocated - if not FontName, cannot continue */
  1340. if (pUFObj->pszFontName == nil || pUFObj->pszFontName[0] == '\0')
  1341. {
  1342. UFLDeletePtr(pMem, pUFObj);
  1343. return nil;
  1344. }
  1345. pInfo = (UFLTTT1FontInfo *)pRequest->hFontInfo;
  1346. maxGlyphs = pInfo->fData.cNumGlyphs;
  1347. /* a convenience pointer used in GetNumGlyph() - must be set now*/
  1348. pUFObj->pFData = &(pInfo->fData); /* Temporary assignment !! */
  1349. if (maxGlyphs == 0)
  1350. maxGlyphs = GetNumGlyphs( pUFObj );
  1351. /*
  1352. * On NT4 a non-zero value will be set to pInfo->lNumNT4SymGlyphs for
  1353. * symbolic TrueType font with platformID 3/encodingID 0. If it's set, it
  1354. * is the real maxGlyphs value.
  1355. */
  1356. pUFObj->lNumNT4SymGlyphs = pInfo->lNumNT4SymGlyphs;
  1357. if (pUFObj->lNumNT4SymGlyphs)
  1358. maxGlyphs = pInfo->lNumNT4SymGlyphs;
  1359. /*
  1360. * We now use Glyph Index to track which glyph is downloaded, so use
  1361. * maxGlyphs.
  1362. */
  1363. if ( NewFont(pUFObj, sizeof(TTT1FontStruct), maxGlyphs) == kNoErr )
  1364. {
  1365. pFont = (TTT1FontStruct*) pUFObj->pAFont->hFont;
  1366. pFont->info = *pInfo;
  1367. /* a convenience pointer */
  1368. pUFObj->pFData = &(pFont->info.fData);
  1369. /*
  1370. * Get ready to find out correct glyphNames from "post" table - set
  1371. * correct pUFO->pFData->fontIndex and offsetToTableDir.
  1372. */
  1373. if ( pFont->info.fData.fontIndex == FONTINDEX_UNKNOWN )
  1374. pFont->info.fData.fontIndex = GetFontIndexInTTC(pUFObj);
  1375. /* Get num of Glyphs in this TT file if not set yet */
  1376. if (pFont->info.fData.cNumGlyphs == 0)
  1377. pFont->info.fData.cNumGlyphs = maxGlyphs;
  1378. if (pFont->pCSBuf == nil)
  1379. pFont->pCSBuf = CSBufInit( pMem );
  1380. if (pFont->pCSBuf == nil)
  1381. {
  1382. vDeleteFont( pUFObj );
  1383. UFLDeletePtr( pUFObj->pMem, pUFObj );
  1384. return nil;
  1385. }
  1386. if ( pUFObj->pUpdatedEncoding == 0 )
  1387. {
  1388. pUFObj->pUpdatedEncoding = (unsigned char *)UFLNewPtr( pMem, GLYPH_SENT_BUFSIZE(256) );
  1389. }
  1390. if ( pUFObj->pUpdatedEncoding != 0 ) /* completed initialization */
  1391. pUFObj->flState = kFontInit;
  1392. }
  1393. return pUFObj;
  1394. }