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.

831 lines
27 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFLTTT3.cpp
  8. *
  9. *
  10. * $Header:
  11. */
  12. /* -------------------------------------------------------------------------
  13. Header Includes
  14. --------------------------------------------------------------------------- */
  15. #include "UFOTTT3.h"
  16. #include "UFLPS.h"
  17. #include "UFLMem.h"
  18. #include "UFLErr.h"
  19. #include "UFLPriv.h"
  20. #include "UFLVm.h"
  21. #include "UFLStd.h"
  22. #include "UFLMath.h"
  23. #include "ParseTT.h"
  24. /* ---------------------------------------------------------------------------
  25. Constant
  26. --------------------------------------------------------------------------- */
  27. /* ---------------------------------------------------------------------------
  28. Global variables
  29. --------------------------------------------------------------------------- */
  30. extern const char *buildChar[];
  31. /* ---------------------------------------------------------------------------
  32. Macros
  33. --------------------------------------------------------------------------- */
  34. /* ---------------------------------------------------------------------------
  35. Implementation
  36. --------------------------------------------------------------------------- */
  37. void
  38. TTT3FontCleanUp(
  39. UFOStruct *pUFObj
  40. )
  41. {
  42. /* no special data for T3 */
  43. }
  44. /***************************************************************************
  45. *
  46. * DownloadFontHeader
  47. *
  48. *
  49. * Function: Download the font header. After this action, glyphs
  50. * can be added to the font.
  51. *
  52. ***************************************************************************/
  53. static UFLErrCode
  54. DownloadFontHeader(
  55. UFOStruct *pUFO
  56. )
  57. {
  58. UFLErrCode retVal;
  59. char buf[128];
  60. UFLHANDLE stream;
  61. UFLFontProcs *pFontProcs;
  62. UFLFixedMatrix matrix;
  63. char nilStr[] = "\0\0"; // An empty/nil string.
  64. TTT3FontStruct *pFont;
  65. UFLBool bType3_32_Combo;
  66. bType3_32_Combo = ( pUFO->lDownloadFormat == kTTType332 );
  67. pFont = (TTT3FontStruct *) pUFO->pAFont->hFont;
  68. if ( pUFO->flState != kFontInit )
  69. return kErrInvalidState;
  70. stream = pUFO->pUFL->hOut;
  71. pFontProcs = (UFLFontProcs *)&pUFO->pUFL->fontProcs;
  72. /* Font Name */
  73. UFLsprintf( buf, CCHOF(buf), "/%s", pUFO->pszFontName );
  74. retVal = StrmPutStringEOL( stream, buf );
  75. /* Define Character metric for .notdef. */
  76. if ( kNoErr == retVal )
  77. {
  78. matrix.a = pFont->info.matrix.a;
  79. matrix.b = matrix.c = matrix.d = matrix.e = matrix.f = 0;
  80. retVal = StrmPutMatrix( stream, &matrix, 0 );
  81. }
  82. /* Encoding */
  83. if ( kNoErr == retVal )
  84. retVal = StrmPutStringEOL( stream, nilStr );
  85. if ( kNoErr == retVal )
  86. {
  87. // Always emit Encoding array filled with /.notdef (due to bug fix
  88. // 273021). The encoding array is updated later when each glyph is
  89. // downloaded.
  90. retVal = StrmPutString( stream, gnotdefArray );
  91. }
  92. /* FontBBox */
  93. if ( kNoErr == retVal )
  94. retVal = StrmPutStringEOL( stream, nilStr );
  95. if ( kNoErr == retVal )
  96. {
  97. matrix.a = pFont->info.bbox[0];
  98. matrix.b = pFont->info.bbox[1];
  99. matrix.c = pFont->info.bbox[2];
  100. matrix.d = pFont->info.bbox[3];
  101. matrix.e = 0;
  102. matrix.f = 0;
  103. retVal = StrmPutMatrix( stream, &matrix, 1 );
  104. }
  105. /* FontMatrix */
  106. if ( kNoErr == retVal )
  107. retVal = StrmPutStringEOL( stream, nilStr );
  108. if ( kNoErr == retVal )
  109. {
  110. retVal = StrmPutString( stream, "[1 " );
  111. if ( kNoErr == retVal )
  112. retVal = StrmPutFixed( stream, pFont->info.matrix.a );
  113. if ( kNoErr == retVal )
  114. retVal = StrmPutString( stream, "div 0 0 -1 " );
  115. if ( kNoErr == retVal )
  116. retVal = StrmPutFixed( stream, pFont->info.matrix.d );
  117. if ( kNoErr == retVal )
  118. retVal = StrmPutStringEOL( stream, "div 0 0 ]" );
  119. }
  120. /* Type 32 Font Resource Name */
  121. if ( kNoErr == retVal )
  122. {
  123. UFLsprintf( buf, CCHOF(buf), "/__%s", pUFO->pszFontName );
  124. retVal = StrmPutStringEOL( stream, buf );
  125. }
  126. /* Define the font */
  127. if ( kNoErr == retVal )
  128. {
  129. if (bType3_32_Combo)
  130. retVal = StrmPutStringEOL( stream, "GreNewFont" );
  131. else
  132. retVal = StrmPutStringEOL( stream, "GreNewFontT3" );
  133. }
  134. /* Goodname */
  135. pUFO->dwFlags |= UFO_HasFontInfo;
  136. pUFO->dwFlags |= UFO_HasG2UDict;
  137. return retVal;
  138. }
  139. static UFLErrCode
  140. OutputBitmap(
  141. UFOStruct *pUFO,
  142. UFLGlyphMap *bmp,
  143. long cExtra0s
  144. )
  145. {
  146. UFLErrCode retVal = kNoErr;
  147. short i;
  148. UFLHANDLE stream;
  149. long bitsPerLine;
  150. long bitmapSize;
  151. UFLFontProcs *pFontProcs;
  152. char nilStr[] = "\0\0"; // An empty/nil string.
  153. char *pExtra0 = nil;
  154. TTT3FontStruct *pFont;
  155. pFont = (TTT3FontStruct *) pUFO->pAFont->hFont;
  156. stream = pUFO->pUFL->hOut;
  157. pFontProcs = (UFLFontProcs *)&pUFO->pUFL->fontProcs;
  158. if ( cExtra0s > 0)
  159. pExtra0 = (char *) UFLNewPtr( pUFO->pMem, cExtra0s );
  160. /* universal handling for all types of Type3 character representation:
  161. - < Hex data > % If Level1 ASCII
  162. - ( Binary with \escapes ) % If Binary
  163. - <~ ASCII85 data ~> % If Level2 ASCII
  164. */
  165. bitsPerLine = (bmp->byteWidth + 7) >> 3;
  166. bitmapSize = bitsPerLine * bmp->height;
  167. /********* Output Character bitmap data *************/
  168. if ( StrmCanOutputBinary(stream) )
  169. {
  170. /* If binary mode - output data into the string start string definition */
  171. retVal = StrmPutString( stream, "(" );
  172. if ( kNoErr == retVal )
  173. {
  174. retVal = StrmPutStringBinary( stream, bmp->bits, bitmapSize );
  175. if ( pExtra0 )
  176. retVal = StrmPutStringBinary( stream, pExtra0, cExtra0s );
  177. }
  178. if ( kNoErr == retVal )
  179. StrmPutStringEOL( stream, ")" ); /* End string definition */
  180. }
  181. else if ( pUFO->pUFL->outDev.lPSLevel >= 2 && ( pExtra0 == nil ) ) /* Can't output 2 buffers for ASCII85 */
  182. { /* Level2 - use ASCII85 */
  183. retVal = StrmPutString( stream, "<~" );
  184. if ( kNoErr == retVal )
  185. {
  186. retVal = StrmPutAscii85( stream, bmp->bits, bitmapSize );
  187. }
  188. if ( kNoErr == retVal )
  189. retVal = StrmPutStringEOL( stream, "~>" ); /* End ASCII85 string */
  190. }
  191. else
  192. {
  193. /* Level 1 ASCII - just send out in Hex */
  194. retVal = StrmPutString( stream, "<" ); /* Start AsciiHex */
  195. /* Go line-by-line and output data so we can view the bitmap */
  196. for ( i = 0; kNoErr == retVal && i < bmp->height; i++ )
  197. {
  198. retVal = StrmPutAsciiHex( stream, bmp->bits + (i * bitsPerLine), bitsPerLine );
  199. if ( kNoErr == retVal )
  200. retVal = StrmPutStringEOL( stream, nilStr );
  201. }
  202. if (kNoErr == retVal && pExtra0)
  203. {
  204. for ( i = 0; kNoErr == retVal && i < cExtra0s/bitsPerLine; i++ )
  205. {
  206. retVal = StrmPutAsciiHex( stream, pExtra0, bitsPerLine ); // ALL are 0.
  207. }
  208. if ( kNoErr == retVal )
  209. retVal = StrmPutStringEOL( stream, nilStr );
  210. }
  211. if ( kNoErr == retVal )
  212. retVal = StrmPutStringEOL( stream, ">" ); /* End AsciiHex */
  213. } /* end of Hex encoding */
  214. if ( pExtra0 )
  215. UFLDeletePtr(pUFO->pMem, pExtra0);
  216. return retVal;
  217. }
  218. /***************************************************************************
  219. *
  220. * AddGlyph3
  221. *
  222. *
  223. * Function: Generates the definition of a single character. We currently
  224. * use the imagemask operator to blast the character on the paper
  225. * where the character shape is used as the mask to apply the current
  226. * color through. The format of a character definition is as
  227. * follows (example is for 'A', ASCII 65d, 41h):
  228. * /GlyphName % Character encoding name
  229. * [xInc yInc (0) % X advance and Y advance of origin to
  230. * % next char
  231. * ulx uly lrx lry] % bounding box of character (used by font
  232. * % cache)
  233. * /GlyphName % Character encoding name
  234. * { % begin proc that draws character
  235. * cx cy % width and height of bitmap
  236. * true % image must be inverted (black <=> white)
  237. * [1 0 0 1 tx ty] % 2D transform to convert bitmap
  238. * % coordinates to user coordinates
  239. * {<023F...>} % bitmap data (hexadecimal format)
  240. * imagemask % draw the character
  241. * } % end of character draw proc
  242. * /TT_Arial % Font character should be added
  243. * AddChar % Helper function to define character
  244. *
  245. ***************************************************************************/
  246. static UFLErrCode
  247. AddGlyph3(
  248. UFOStruct *pUFO,
  249. UFLGlyphID glyph,
  250. unsigned short cid,
  251. const char *glyphName,
  252. unsigned long *glyphSize
  253. )
  254. {
  255. UFLErrCode retVal = kNoErr;
  256. UFLGlyphMap* bmp;
  257. UFLFixedMatrix matrix;
  258. UFLFixed bbox[4];
  259. UFLFixed xWidth, yWidth;
  260. char buf[128];
  261. UFLHANDLE stream;
  262. UFLFontProcs *pFontProcs;
  263. char nilStr[] = "\0\0"; // An empty/nil string.
  264. long cExtra0s = 0;
  265. TTT3FontStruct *pFont;
  266. UFLBool bType3_32_Combo;
  267. bType3_32_Combo = ( pUFO->lDownloadFormat == kTTType332 );
  268. pFont = (TTT3FontStruct *) pUFO->pAFont->hFont;
  269. stream = pUFO->pUFL->hOut;
  270. pFontProcs = (UFLFontProcs *)&pUFO->pUFL->fontProcs;
  271. *glyphSize = 0;
  272. /* Whatever is in glyph, pass back to client */
  273. if ( pFontProcs->pfGetGlyphBmp( pUFO->hClientData, glyph, &bmp, &xWidth, &yWidth, (UFLFixed*)bbox ) )
  274. {
  275. if ( kNoErr == retVal )
  276. retVal = StrmPutStringEOL( stream, nilStr );
  277. /* Output the CID */
  278. if ( kNoErr == retVal )
  279. {
  280. UFLsprintf( buf, CCHOF(buf), "%d", cid );
  281. retVal = StrmPutStringEOL( stream, buf );
  282. }
  283. /* Send /GlyphName [type3 character BBox]*/
  284. if ( kNoErr == retVal )
  285. {
  286. UFLsprintf( buf, CCHOF(buf), "/%s ", glyphName );
  287. retVal = StrmPutString( stream, buf );
  288. /* Send type 3 character BBox. We need to truncated the floating point
  289. because of type 32 restriction.
  290. */
  291. matrix.a = xWidth;
  292. matrix.b = yWidth;
  293. matrix.c = UFLTruncFixed(bbox[0]);
  294. matrix.d = UFLTruncFixed(bbox[1]);
  295. matrix.e = UFLTruncFixed(bbox[2]);
  296. matrix.f = UFLTruncFixed(bbox[3]);
  297. retVal = StrmPutMatrix( stream, &matrix, 0 );
  298. cExtra0s = ( (UFLRoundFixedToShort(matrix.e) - UFLRoundFixedToShort(matrix.c) + 7) >> 3 ) *
  299. ( UFLRoundFixedToShort(matrix.f) - UFLRoundFixedToShort(matrix.d) )
  300. - ( ((bmp->byteWidth + 7) >> 3) * bmp->height );
  301. if (cExtra0s < 0 ) cExtra0s = 0;
  302. }
  303. if ( kNoErr == retVal )
  304. {
  305. retVal = StrmPutStringEOL( stream, nilStr );
  306. }
  307. /* Send "/GlyphName [" */
  308. if ( kNoErr == retVal )
  309. {
  310. UFLsprintf( buf, CCHOF(buf), "/%s [", glyphName );
  311. retVal = StrmPutString( stream, buf );
  312. }
  313. /* Don't output non-marking glyphs! */
  314. if ( (kNoErr == retVal) && bmp->byteWidth && bmp->height )
  315. {
  316. /* Send rest of prefix to actual bitmap data : width height polarity matrix datasrc imagemask */
  317. UFLsprintf(buf, CCHOF(buf), "%ld %ld true ", bmp->byteWidth, bmp->height ); /* width, height, polarity */
  318. retVal = StrmPutString( stream, buf );
  319. /* Send [1 0 0 1 tx ty] - 2D transform to convert bitmap coordinate to user coordinate */
  320. if ( kNoErr == retVal )
  321. {
  322. matrix.a = UFLFixedOne;
  323. matrix.b = 0;
  324. matrix.c = 0;
  325. matrix.d = UFLFixedOne;
  326. matrix.e = UFLShortToFixed( bmp->xOrigin );
  327. matrix.f = UFLShortToFixed( bmp->yOrigin );
  328. retVal = StrmPutMatrix( stream, &matrix, 0 );
  329. if ( kNoErr == retVal )
  330. retVal = StrmPutString( stream, nilStr );
  331. }
  332. /* Send out place holder */
  333. if ( kNoErr == retVal )
  334. {
  335. UFLsprintf( buf, CCHOF(buf), " 0 0]" );
  336. retVal = StrmPutStringEOL( stream, buf );
  337. }
  338. /* Send the character bitmap */
  339. if ( kNoErr == retVal )
  340. {
  341. retVal = StrmPutString( stream, "[" );
  342. if ( kNoErr == retVal )
  343. retVal = OutputBitmap( pUFO, bmp, cExtra0s );
  344. if ( kNoErr == retVal )
  345. retVal = StrmPutStringEOL( stream, " ]" );
  346. // Fix bug 246325. 7/13/98 jjia
  347. // glyphsize = hight * bytewidth * safefactor
  348. // *glyphSize = bmp->height * bmp->byteWidth;
  349. *glyphSize = bmp->height * ((bmp->byteWidth + 7) >> 3) * 2;
  350. }
  351. }
  352. else
  353. {
  354. /* Generate nil drawing procedure */
  355. retVal = StrmPutStringEOL( stream, "]" );
  356. if ( kNoErr == retVal )
  357. retVal = StrmPutStringEOL( stream, "[<>]" );
  358. }
  359. /* Send the Add character definition command */
  360. if ( kNoErr == retVal )
  361. {
  362. if (bType3_32_Combo)
  363. UFLsprintf( buf, CCHOF(buf), "/%s AddT3T32Char", pUFO->pszFontName );
  364. else
  365. UFLsprintf( buf, CCHOF(buf), "/%s AddT3Char", pUFO->pszFontName );
  366. retVal = StrmPutStringEOL( stream, buf );
  367. }
  368. /* Delete the bitmap if there is a client function for it */
  369. if ( pFontProcs->pfDeleteGlyphBmp )
  370. pFontProcs->pfDeleteGlyphBmp( pUFO->hClientData );
  371. }
  372. return retVal;
  373. }
  374. #pragma optimize("", off)
  375. UFLErrCode
  376. TTT3VMNeeded(
  377. UFOStruct *pUFO,
  378. const UFLGlyphsInfo *pGlyphs,
  379. unsigned long *pVMNeeded,
  380. unsigned long *pFCNeeded
  381. )
  382. {
  383. UFLErrCode retVal = kNoErr;
  384. short i;
  385. unsigned long totalGlyphs;
  386. TTT3FontStruct *pFont;
  387. DWORD dwTotalGlyphsSize = 0;
  388. unsigned short wIndex;
  389. if (pUFO->flState < kFontInit)
  390. return (kErrInvalidState);
  391. pFont = (TTT3FontStruct *) pUFO->pAFont->hFont;
  392. if (pGlyphs == nil || pGlyphs->pGlyphIndices == nil || pVMNeeded == nil)
  393. return kErrInvalidParam;
  394. totalGlyphs = 0;
  395. /* Scan the list, check what characters that we have downloaded */
  396. if ( pUFO->pUFL->bDLGlyphTracking && pGlyphs->pCharIndex)
  397. {
  398. UFLmemcpy((const UFLMemObj* ) pUFO->pMem,
  399. pUFO->pAFont->pVMGlyphs,
  400. pUFO->pAFont->pDownloadedGlyphs,
  401. (UFLsize_t) (GLYPH_SENT_BUFSIZE( pFont->info.fData.cNumGlyphs) ) );
  402. for ( i = 0; i < pGlyphs->sCount; i++ )
  403. {
  404. /* use glyphIndex to track - fix bug when we do T0/T3 */
  405. wIndex = (unsigned short) pGlyphs->pGlyphIndices[i] & 0x0000FFFF ; /* loWord is the GlyphID */
  406. if (wIndex >= UFO_NUM_GLYPHS(pUFO) )
  407. continue;
  408. if ( !IS_GLYPH_SENT( pUFO->pAFont->pVMGlyphs, wIndex) )
  409. {
  410. totalGlyphs++;
  411. SET_GLYPH_SENT_STATUS( pUFO->pAFont->pVMGlyphs, wIndex );
  412. }
  413. }
  414. }
  415. else
  416. totalGlyphs = pGlyphs->sCount;
  417. if ( pUFO->flState == kFontInit )
  418. *pVMNeeded = kVMTTT3Header;
  419. else
  420. *pVMNeeded = 0;
  421. /* VMNeeded = average size of a glyph * totalGlyphs */
  422. // Fix bug 246325. 7/13/98 jjia
  423. // dwTotalGlyphsSize = totalGlyphs * (pFont->cbMaxGlyphs / pFont->info.fData.maxGlyphs);
  424. dwTotalGlyphsSize = totalGlyphs * (pFont->cbMaxGlyphs * 2 / 3);
  425. if ( GETPSVERSION(pUFO) <= 2015 )
  426. *pVMNeeded += dwTotalGlyphsSize;
  427. *pVMNeeded = VMRESERVED( *pVMNeeded );
  428. /* swong: pFCNeeded for T32 FontCache tracking */
  429. *pFCNeeded = VMRESERVED(dwTotalGlyphsSize);
  430. return kNoErr;
  431. }
  432. #pragma optimize("", on)
  433. /***************************************************************************
  434. *
  435. * DownloadIncrFont
  436. *
  437. *
  438. * Function: Adds all of the characters from pGlyphs that aren't already
  439. * downloaded for the TrueType font.
  440. *
  441. * Note: pCharIndex is used to track which char(in this font) is downloaded or not
  442. * It can be nil if client doesn't wish to track - e.g. Escape(DownloadFace)
  443. * It has no relationship with ppGlyphNames.
  444. * E.g., ppGlyphNames[0]="/A", pCharIndex[0]=6, pGlyphIndices[0]=1000: means
  445. * To download glyphID 1000 as Char-named "/A" and Also, remember the 6th-char is downloaded
  446. *
  447. ***************************************************************************/
  448. UFLErrCode
  449. TTT3FontDownloadIncr(
  450. UFOStruct *pUFO,
  451. const UFLGlyphsInfo *pGlyphs,
  452. unsigned long *pVMUsage,
  453. unsigned long *pFCUsage
  454. )
  455. {
  456. UFLGlyphID *glyphs;
  457. UFLErrCode retVal;
  458. short i;
  459. UFLBool bDownloaded;
  460. unsigned long glyphSize;
  461. char *pGoodName;
  462. unsigned short cid;
  463. UFLBool bType3_32_Combo;
  464. unsigned short wIndex;
  465. UFLBool bGoodName; // GoodName
  466. char pGlyphName[32]; // GoodName
  467. bType3_32_Combo = ( pUFO->lDownloadFormat == kTTType332 );
  468. if ( pUFO->flState < kFontInit )
  469. return kErrInvalidState;
  470. if ( pGlyphs == nil ||
  471. pGlyphs->pGlyphIndices == nil ||
  472. pGlyphs->sCount == -1 )
  473. return kErrInvalidParam;
  474. if ( pUFO->pUFL->outDev.pstream->pfDownloadProcset == 0 )
  475. return kErrDownloadProcset;
  476. if ( !pUFO->pUFL->outDev.pstream->pfDownloadProcset(pUFO->pUFL->outDev.pstream, kT3Header) )
  477. return kErrDownloadProcset;
  478. retVal = kNoErr;
  479. ;
  480. /* Download the font header if this is the first time we download the font */
  481. if ( pUFO->flState == kFontInit )
  482. {
  483. retVal = DownloadFontHeader( pUFO );
  484. if ( pVMUsage )
  485. *pVMUsage = kVMTTT3Header;
  486. }
  487. else if ( pVMUsage )
  488. *pVMUsage = 0;
  489. /* Initial FontCahce Usage */
  490. if ( pFCUsage )
  491. *pFCUsage = 0;
  492. /* Download the new glyphs */
  493. glyphs = pGlyphs->pGlyphIndices;
  494. bDownloaded = 0;
  495. for ( i = 0; retVal == kNoErr && i < pGlyphs->sCount; ++i)
  496. {
  497. /* use glyphIndex to track - fix bug when we do T0/T3 */
  498. wIndex = (unsigned short) glyphs[i] & 0x0000FFFF; /* LOWord is the real GID */
  499. if (wIndex >= UFO_NUM_GLYPHS(pUFO) )
  500. continue;
  501. if ( 0 == pUFO->pUFL->bDLGlyphTracking ||
  502. pGlyphs->pCharIndex == nil || // DownloadFace
  503. pUFO->pEncodeNameList || // DownloadFace
  504. !IS_GLYPH_SENT( pUFO->pAFont->pDownloadedGlyphs, wIndex ) ||
  505. ((pGlyphs->pCharIndex != nil) &&
  506. !IS_GLYPH_SENT( pUFO->pUpdatedEncoding , pGlyphs->pCharIndex[i] )))
  507. {
  508. // GoodName
  509. pGoodName = pGlyphName;
  510. bGoodName = FindGlyphName(pUFO, pGlyphs, i, wIndex, &pGoodName);
  511. // Fix bug 274008 Check Glyph Name only for DownloadFace.
  512. if (pUFO->pEncodeNameList)
  513. {
  514. if ((UFLstrcmp( pGoodName, Hyphen ) == 0) && (i == 45))
  515. {
  516. // Add /minus to CharStrings
  517. if ( kNoErr == retVal )
  518. retVal = AddGlyph3( pUFO, glyphs[i], cid, Minus, &glyphSize );
  519. }
  520. if ((UFLstrcmp( pGoodName, Hyphen ) == 0) && (i == 173))
  521. {
  522. // Add /sfthyphen to CharStrings
  523. if ( kNoErr == retVal )
  524. retVal = AddGlyph3( pUFO, glyphs[i], cid, SftHyphen, &glyphSize );
  525. }
  526. if (!ValidGlyphName(pGlyphs, i, wIndex, pGoodName))
  527. continue;
  528. // Send only one ".notdef"
  529. if ((UFLstrcmp( pGoodName, Notdef ) == 0) &&
  530. (wIndex == (unsigned short) (glyphs[0] & 0x0000FFFF)) &&
  531. IS_GLYPH_SENT( pUFO->pAFont->pDownloadedGlyphs, wIndex ))
  532. continue;
  533. }
  534. if ( 0 == bDownloaded )
  535. {
  536. if (bType3_32_Combo)
  537. StrmPutStringEOL( pUFO->pUFL->hOut, "T32RsrcBegin" );
  538. bDownloaded = 1;
  539. }
  540. if (pGlyphs->pCharIndex)
  541. cid = pGlyphs->pCharIndex[i];
  542. else
  543. cid = i;
  544. if ( kNoErr == retVal )
  545. retVal = AddGlyph3( pUFO, glyphs[i], cid, pGoodName, &glyphSize );
  546. if ( kNoErr == retVal )
  547. {
  548. SET_GLYPH_SENT_STATUS( pUFO->pAFont->pDownloadedGlyphs, wIndex );
  549. if (bGoodName) // GoodName
  550. SET_GLYPH_SENT_STATUS( pUFO->pAFont->pCodeGlyphs, wIndex );
  551. if (pGlyphs->pCharIndex)
  552. SET_GLYPH_SENT_STATUS( pUFO->pUpdatedEncoding, cid );
  553. if ( GETPSVERSION(pUFO) <= 2015 )
  554. {
  555. if ( pVMUsage )
  556. *pVMUsage += glyphSize;
  557. }
  558. else
  559. {
  560. /* if PS >= 2016, assume T32 and update FC tracking */
  561. if ( pFCUsage && bType3_32_Combo )
  562. *pFCUsage += glyphSize;
  563. }
  564. }
  565. }
  566. }
  567. if ( bDownloaded )
  568. {
  569. if (bType3_32_Combo)
  570. retVal = StrmPutStringEOL( pUFO->pUFL->hOut, "T32RsrcEnd" );
  571. /* GoodName */
  572. /* Update the FontInfo with Unicode information. */
  573. if ((kNoErr == retVal) && (pGlyphs->sCount > 0) &&
  574. (pUFO->dwFlags & UFO_HasG2UDict) &&
  575. (pUFO->pUFL->outDev.lPSLevel >= kPSLevel2) && // Don't do this for level1 printers
  576. !(pUFO->lNumNT4SymGlyphs))
  577. {
  578. /* Check pUFObj->pAFont->pCodeGlyphs to see if we really need to update it. */
  579. for ( i = 0; i < pGlyphs->sCount; i++ )
  580. {
  581. wIndex = (unsigned short) glyphs[i] & 0x0000FFFF; /* LOWord is the real GID. */
  582. if (wIndex >= UFO_NUM_GLYPHS(pUFO) )
  583. continue;
  584. if (!IS_GLYPH_SENT( pUFO->pAFont->pCodeGlyphs, wIndex ) )
  585. {
  586. // Found at least one not updated, do it (once) for all.
  587. retVal = UpdateCodeInfo(pUFO, pGlyphs, 1);
  588. break;
  589. }
  590. }
  591. }
  592. if ( kNoErr == retVal )
  593. {
  594. pUFO->flState = kFontHasChars;
  595. }
  596. if ( pVMUsage )
  597. *pVMUsage = VMRESERVED( *pVMUsage );
  598. /* swong: pFCUsage for T32 FontCache tracking */
  599. if ( pFCUsage && bType3_32_Combo )
  600. *pFCUsage = VMRESERVED( *pFCUsage );
  601. }
  602. return retVal;
  603. }
  604. // Send PS code to undefine fonts: /UDF3 should be defined properly by client
  605. // UDF3 should recover the FontCache used by Type32
  606. UFLErrCode
  607. TTT3UndefineFont(
  608. UFOStruct *pUFO
  609. )
  610. {
  611. UFLErrCode retVal = kNoErr;
  612. char buf[128];
  613. UFLHANDLE stream;
  614. UFLBool bType3_32_Combo;
  615. bType3_32_Combo = ( pUFO->lDownloadFormat == kTTType332 );
  616. if (pUFO->flState < kFontHeaderDownloaded) return retVal;
  617. stream = pUFO->pUFL->hOut;
  618. UFLsprintf( buf, CCHOF(buf), "/%s ", pUFO->pszFontName );
  619. retVal = StrmPutString( stream, buf );
  620. if (bType3_32_Combo)
  621. UFLsprintf( buf, CCHOF(buf), "/__%s UDF3", pUFO->pszFontName );
  622. else
  623. UFLsprintf( buf, CCHOF(buf), "UDF");
  624. if ( kNoErr == retVal )
  625. retVal = StrmPutStringEOL( stream, buf );
  626. return retVal;
  627. }
  628. UFOStruct *
  629. TTT3FontInit(
  630. const UFLMemObj *pMem,
  631. const UFLStruct *pUFL,
  632. const UFLRequest *pRequest
  633. )
  634. {
  635. UFOStruct *pUFObj;
  636. TTT3FontStruct *pFont;
  637. UFLTTT3FontInfo *pInfo;
  638. long maxGlyphs;
  639. /* MWCWP1 doesn't like the implicit cast from void* to UFOStruct* --jfu */
  640. pUFObj = (UFOStruct*) UFLNewPtr( pMem, sizeof( UFOStruct ) );
  641. if (pUFObj == 0)
  642. return nil;
  643. /* Initialize data */
  644. UFOInitData(pUFObj, UFO_TYPE3, pMem, pUFL, pRequest,
  645. (pfnUFODownloadIncr) TTT3FontDownloadIncr,
  646. (pfnUFOVMNeeded) TTT3VMNeeded,
  647. (pfnUFOUndefineFont) TTT3UndefineFont,
  648. (pfnUFOCleanUp) TTT3FontCleanUp,
  649. (pfnUFOCopy) CopyFont
  650. );
  651. /* pszFontName should be ready/allocated - if not FontName, cannot continue */
  652. if (pUFObj->pszFontName == nil || pUFObj->pszFontName[0] == '\0')
  653. {
  654. UFLDeletePtr(pMem, pUFObj);
  655. return nil;
  656. }
  657. pInfo = (UFLTTT3FontInfo *)pRequest->hFontInfo;
  658. maxGlyphs = pInfo->fData.cNumGlyphs;
  659. /* a convenience pointer used in GetNumGlyph() - must be set now*/
  660. pUFObj->pFData = &(pInfo->fData); /* Temporary assignment !! */
  661. if (maxGlyphs == 0)
  662. maxGlyphs = GetNumGlyphs( pUFObj );
  663. /*
  664. * On NT4 a non-zero value will be set to pInfo->lNumNT4SymGlyphs for
  665. * symbolic TrueType font with platformID 3/encodingID 0. If it's set, it
  666. * is the real maxGlyphs value.
  667. */
  668. pUFObj->lNumNT4SymGlyphs = pInfo->lNumNT4SymGlyphs;
  669. if (pUFObj->lNumNT4SymGlyphs)
  670. maxGlyphs = pInfo->lNumNT4SymGlyphs;
  671. /*
  672. * We now use Glyph Index to track which glyph is downloaded, so use
  673. * maxGlyphs.
  674. */
  675. if ( NewFont(pUFObj, sizeof(TTT3FontStruct), maxGlyphs) == kNoErr )
  676. {
  677. pFont = (TTT3FontStruct*) pUFObj->pAFont->hFont;
  678. pFont->info = *pInfo;
  679. /* a convenience pointer */
  680. pUFObj->pFData = &(pFont->info.fData);
  681. /*
  682. * Get ready to find out correct glyphNames from "post" table - set
  683. * correct pUFO->pFData->fontIndex and offsetToTableDir.
  684. */
  685. if ( pFont->info.fData.fontIndex == FONTINDEX_UNKNOWN )
  686. pFont->info.fData.fontIndex = GetFontIndexInTTC(pUFObj);
  687. /* Get num of Glyphs in this TT file if not set yet */
  688. if (pFont->info.fData.cNumGlyphs == 0)
  689. pFont->info.fData.cNumGlyphs = maxGlyphs;
  690. pFont->cbMaxGlyphs = pInfo->cbMaxGlyphs;
  691. if ( pUFObj->pUpdatedEncoding == 0 )
  692. {
  693. /* MWCWP1 doesn't like the implicit cast from void* to unsigned char* --jfu */
  694. pUFObj->pUpdatedEncoding = (unsigned char*) UFLNewPtr( pMem, GLYPH_SENT_BUFSIZE(256) );
  695. }
  696. if ( pUFObj->pUpdatedEncoding != 0 ) /* completed initialization */
  697. pUFObj->flState = kFontInit;
  698. }
  699. return pUFObj;
  700. }