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.

1516 lines
47 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFOCFF.c - Compact Font Format Object
  8. *
  9. ******************************************************************************
  10. *
  11. * Note about SUBSET_PREFIX and more comment for VRT2_FEATURE_DISABLED
  12. *
  13. * When we donwload a font, its /FontName or /CIDFontName can be any name we
  14. * want. If the name folows the following format:
  15. * SUBSET_PREFIX+RealFontName
  16. * where SUBSET_PREFIX is a string consited of six characters, each of them is
  17. * either 'a' ~ 'p' or 'A' ~ 'P', then Distiller4 takes RealFontName part as
  18. * the font's real name. e.g. abcdef+Helvetica -> Distiller4 realizes that this
  19. * this font's real font name is Helvetica.
  20. * We, Adobe Windows Driver Group, decided to go for it (bug #291934). At the
  21. * same time, we also deciced to remve the code for 'vrt2' feature incapable
  22. * CJK OpenType font, that is, remove #ifdef/#endif with VRT2_FEATURE_DISABLED
  23. * because virtually any CJK OpenType fonts are supposed to have 'vrt2'
  24. * feature. Otherwise vertical version of such CJK OpenType font can't be
  25. * supported (by ATM or CoolType). Thus, there will be no #ifdef/#endif section
  26. * with VRT2_FEATURE_DISABLED keyword in this code and the sentence "But, just
  27. * in case, ....at compile time." in the following note is now obsolite.
  28. * You can retrieve the removed code from the version 16 or below of this file
  29. * in SourceSafe if you want.
  30. *
  31. * --- This note is now obsolete. ---------------------------------------------
  32. *
  33. * Note about 'vrt2' feature and VRT2_FEATURE_DISABLED
  34. *
  35. * OTF-based fonts will only have their "@" capability enabled if they have a
  36. * 'vrt2' feature in their 'GSUB' table; otherwise only horizontal typographic
  37. * rendering is enabled. When the 'vrt2' feature exists in a font, the font
  38. * vendor claims that all of the glyphs for the @ variant of the font should be
  39. * rotated before display / print. Thus, on neither NT4 nor W2K, the PostScript
  40. * driver doesn't even have to call GlyhAttrs to find out which @ glyphs are
  41. * rotated; they all are. But, just in case, the logic for rotating @ glyphs is
  42. * also provided and it will be enabled when VRT2_FEATURE_DISABLED flag is set
  43. * at compile time.
  44. *-----------------------------------------------------------------------------
  45. *
  46. * $Header:
  47. */
  48. #include "UFLMem.h"
  49. #include "UFLErr.h"
  50. #include "UFLPriv.h"
  51. #include "UFLVm.h"
  52. #include "UFLStd.h"
  53. #include "UFLMath.h"
  54. #include "UFLPS.h"
  55. #include "ParseTT.h"
  56. #include "UFOCff.h"
  57. #include "UFOt42.h"
  58. #include "ttformat.h"
  59. #ifdef UNIX
  60. #include <sys/varargs.h>
  61. #include <assert.h>
  62. #else
  63. #ifdef MAC_ENV
  64. #include <assert.h>
  65. #endif
  66. #include <stdarg.h>
  67. #endif
  68. static unsigned char *pSubrNames[4] = {
  69. (unsigned char*) "F0Subr",
  70. (unsigned char*) "F1Subr",
  71. (unsigned char*) "F2Subr",
  72. (unsigned char*) "HSSubr"
  73. };
  74. #define VER_WO_OTHERSUBRS 51
  75. /*
  76. * Maximum known supplement number. This number is used to decide whether
  77. * GlyphName2Unicode table should be downloaded.
  78. */
  79. #define ADOBE_JAPAN1_MAXKNOWN 4
  80. #define ADOBE_KOREA1_MAXKNOWN 1
  81. #define ADOBE_GB1_MAXKNOWN 2
  82. #define ADOBE_CNS1_MAXKNOWN 0
  83. /*
  84. * Macro to check whether they are known ordering and supplement.
  85. */
  86. #define KNOWN_OS(o, on, s, max) (!UFLstrcmp((o), (on)) && ((0 <= (s)) && ((s) < (max))))
  87. /******************************************************************************
  88. *
  89. * Callback Functions
  90. *
  91. ******************************************************************************/
  92. static unsigned long int
  93. AllocateMem(
  94. void PTR_PREFIX *PTR_PREFIX *hndl,
  95. unsigned long int size,
  96. void PTR_PREFIX *clientHook
  97. )
  98. {
  99. UFOStruct *pUFO = (UFOStruct *)clientHook;
  100. if ((size == 0) && (*hndl == nil))
  101. return 1;
  102. if (size == 0)
  103. {
  104. UFLDeletePtr(pUFO->pMem, *hndl);
  105. *hndl = nil;
  106. return 1;
  107. }
  108. if (*hndl == nil)
  109. {
  110. *hndl = UFLNewPtr(pUFO->pMem, size);
  111. return (unsigned long int)(ULONG_PTR)*hndl;
  112. }
  113. else
  114. {
  115. return (unsigned long int)UFLEnlargePtr(pUFO->pMem, (void **)hndl, size, 1);
  116. }
  117. return 1;
  118. }
  119. /* We do not support seeking for this function. */
  120. static int
  121. PutBytesAtPos(
  122. unsigned char PTR_PREFIX *pData,
  123. long int position,
  124. unsigned short int length,
  125. void PTR_PREFIX *clientHook
  126. )
  127. {
  128. if (position >= 0)
  129. {
  130. return 0;
  131. }
  132. if (length > 0)
  133. {
  134. UFOStruct *pUFO = (UFOStruct *)clientHook;
  135. if (kNoErr == StrmPutBytes(pUFO->pUFL->hOut,
  136. (const char *)pData,
  137. (UFLsize_t)length,
  138. (const UFLBool)StrmCanOutputBinary(pUFO->pUFL->hOut)))
  139. {
  140. return 0;
  141. }
  142. }
  143. return 1;
  144. }
  145. static int
  146. GetBytesFromPos(
  147. unsigned char PTR_PREFIX * PTR_PREFIX *ppData,
  148. long int position,
  149. unsigned short int length,
  150. void PTR_PREFIX *clientHook
  151. )
  152. {
  153. UFOStruct *pUFO = (UFOStruct *)clientHook;
  154. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  155. int retVal = 0; /* Set retVal to failure. */
  156. /*
  157. * Check to see if the client passes us a whole cff table.
  158. */
  159. if (pFont->info.ppFontData)
  160. {
  161. /*
  162. * Get the data from the table by ourself.
  163. */
  164. if ((unsigned long int)(position + length) <= pFont->info.fontLength)
  165. {
  166. *ppData = (unsigned char PTR_PREFIX *)*pFont->info.ppFontData + position;
  167. retVal = 1;
  168. }
  169. }
  170. else
  171. {
  172. UFLCFFReadBuf *pReadBuf = pFont->pReadBuf;
  173. if (0 == pReadBuf->cbBuf)
  174. {
  175. pReadBuf->pBuf = (unsigned char PTR_PREFIX *)UFLNewPtr(pUFO->pMem, length);
  176. if (pReadBuf->pBuf)
  177. pReadBuf->cbBuf = length;
  178. else
  179. return 0;
  180. }
  181. else if (pReadBuf->cbBuf < length)
  182. {
  183. UFLEnlargePtr(pUFO->pMem, (void **)&pReadBuf->pBuf, length, 0);
  184. pReadBuf->cbBuf = length;
  185. }
  186. /*
  187. * Fall back to read from callback function.
  188. */
  189. retVal = (int)GETTTFONTDATA(pUFO,
  190. CFF_TABLE,
  191. position,
  192. pReadBuf->pBuf,
  193. length,
  194. pFont->info.fData.fontIndex);
  195. *ppData = (unsigned char PTR_PREFIX *)pReadBuf->pBuf;
  196. }
  197. return retVal;
  198. }
  199. /******************************************************************************
  200. *
  201. * Private Functions
  202. *
  203. ******************************************************************************/
  204. static void *
  205. SetMemory(
  206. void *dest,
  207. int c,
  208. unsigned short int count
  209. )
  210. {
  211. return UFLmemsetShort(dest, c, (size_t) count);
  212. }
  213. static unsigned short int
  214. StringLength(
  215. const char PTR_PREFIX *string
  216. )
  217. {
  218. return (unsigned short int)UFLstrlen(string);
  219. }
  220. static void
  221. MemCpy(
  222. void PTR_PREFIX *dest,
  223. const void PTR_PREFIX *src,
  224. unsigned short int count
  225. )
  226. {
  227. memcpy(dest, (void*)src, (size_t)count);
  228. }
  229. static int
  230. AsciiToInt(
  231. const char* string
  232. )
  233. {
  234. return atoi(string);
  235. }
  236. static long
  237. StringToLong(
  238. const char *nptr,
  239. char **endptr,
  240. int base
  241. )
  242. {
  243. return UFLstrtol(nptr, endptr, base);
  244. }
  245. static int
  246. StrCmp(
  247. const char PTR_PREFIX *string1,
  248. const char PTR_PREFIX *string2
  249. )
  250. {
  251. return UFLstrcmp(string1, string2);
  252. }
  253. static int
  254. GetCharName(
  255. XFhandle handle,
  256. void *client,
  257. XCFGlyphID glyphID,
  258. char PTR_PREFIX *charName,
  259. unsigned short int length
  260. )
  261. {
  262. if (client)
  263. {
  264. /*
  265. * Copy the charname by ourself because the name string returned from
  266. * XCF is not NULL terminated.
  267. */
  268. unsigned short int i;
  269. /* UFLsprintf((char*)client, "%s", charName); */
  270. for (i = 0; i < length; i++)
  271. *((char *)client)++ = *charName++;
  272. *((char *)client) = '\0';
  273. return XCF_Ok;
  274. }
  275. return XCF_InternalError;
  276. }
  277. static int
  278. GIDToCID(
  279. XFhandle handle,
  280. void PTR_PREFIX *client,
  281. XCFGlyphID glyphID,
  282. unsigned short int cid
  283. )
  284. {
  285. if (client)
  286. {
  287. unsigned short int *pCid = (unsigned short int *)client;
  288. *pCid = cid;
  289. return XCF_Ok;
  290. }
  291. return XCF_InternalError;
  292. }
  293. static void
  294. getFSType(
  295. XFhandle h,
  296. long PTR_PREFIX *pfsType,
  297. void PTR_PREFIX *clientHook
  298. )
  299. {
  300. UFOStruct* pUFO;
  301. long fsType;
  302. if (!pfsType)
  303. return;
  304. *pfsType = -1; /* "Don't put FSType" by default. */
  305. if (!(pUFO = (UFOStruct*)clientHook))
  306. return;
  307. fsType = GetOS2FSType(pUFO);
  308. if(0 <= fsType)
  309. *pfsType = fsType;
  310. }
  311. /* GOODNAME */
  312. static void
  313. isKnownROS(XFhandle h,
  314. long PTR_PREFIX *pknownROS,
  315. char PTR_PREFIX *R,
  316. Card16 lenR,
  317. char PTR_PREFIX *O,
  318. Card16 lenO,
  319. long S,
  320. void PTR_PREFIX *clientHook
  321. )
  322. {
  323. UFOStruct *pUFO;
  324. if (!pknownROS)
  325. return;
  326. *pknownROS = 0;
  327. if (!(pUFO = (UFOStruct*)clientHook))
  328. return;
  329. if ((lenR < 32) && (lenO < 32))
  330. {
  331. char Registry[32], Ordering[32];
  332. int i;
  333. for (i = 0; i < (int) lenR; i++)
  334. Registry[i] = (char) R[i];
  335. Registry[lenR] = '\0';
  336. for (i = 0; i < (int)lenO; i++)
  337. Ordering[i] = (char) O[i];
  338. Ordering[lenO] = '\0';
  339. if (!UFLstrcmp(Registry, "Adobe"))
  340. {
  341. if ( KNOWN_OS(Ordering, "Japan1", S, ADOBE_JAPAN1_MAXKNOWN)
  342. || KNOWN_OS(Ordering, "Korea1", S, ADOBE_KOREA1_MAXKNOWN)
  343. || KNOWN_OS(Ordering, "GB1", S, ADOBE_GB1_MAXKNOWN )
  344. || KNOWN_OS(Ordering, "CNS1", S, ADOBE_CNS1_MAXKNOWN ))
  345. {
  346. *pknownROS = 1;
  347. }
  348. }
  349. }
  350. if (*pknownROS)
  351. pUFO->pAFont->knownROS = 1;
  352. else
  353. {
  354. pUFO->pAFont->knownROS = 0;
  355. pUFO->dwFlags |= UFO_HasG2UDict;
  356. }
  357. }
  358. int
  359. printfError(
  360. const char *format, ...
  361. )
  362. {
  363. va_list arglist;
  364. int retval = 0;
  365. char buf[512];
  366. va_start(arglist, format);
  367. if (SUCCEEDED(StringCchVPrintfA(buf, CCHOF(buf), format, arglist)))
  368. {
  369. retval = strlen(buf);
  370. }
  371. va_end(arglist);
  372. return retval;
  373. }
  374. enum XCF_Result
  375. CFFInitFont(
  376. UFOStruct *pUFO,
  377. CFFFontStruct *pFont
  378. )
  379. {
  380. XCF_CallbackStruct callbacks = {0};
  381. XCF_ClientOptions options = {0};
  382. char fontName[256];
  383. /*
  384. * Initialize XCF_CallbackStruct object.
  385. */
  386. /* Stream output functions */
  387. callbacks.putBytes = PutBytesAtPos;
  388. callbacks.putBytesHook = (void PTR_PREFIX *)pUFO;
  389. callbacks.outputPos = (XCF_OutputPosFunc)nil;
  390. callbacks.outputPosHook = (void PTR_PREFIX *)0;
  391. callbacks.getBytes = GetBytesFromPos;
  392. callbacks.getBytesHook = (void PTR_PREFIX *)pUFO;
  393. callbacks.allocate = AllocateMem;
  394. callbacks.allocateHook = (void PTR_PREFIX *)pUFO;
  395. callbacks.pFont = 0;
  396. callbacks.fontLength = 0;
  397. /* C Standard library functions */
  398. callbacks.strlen = (XCF_strlen)StringLength;
  399. callbacks.memcpy = (XCF_memcpy)MemCpy;
  400. callbacks.memset = (XCF_memset)SetMemory;
  401. callbacks.xcfSprintf = (XCF_sprintf)UFLsprintf;
  402. callbacks.printfError = (XCF_printfError)printfError;
  403. callbacks.atoi = (XCF_atoi)AsciiToInt;
  404. callbacks.strtol = (XCF_strtol)StringToLong;
  405. callbacks.atof = (XCF_atof)nil; /* not required */
  406. callbacks.strcmp = (XCF_strcmp)StrCmp;
  407. /* Glyph ID functions */
  408. callbacks.gidToCharName = (XCF_GIDToCharName)GetCharName;
  409. callbacks.gidToCID = (XCF_GIDToCID)GIDToCID;
  410. callbacks.getCharStr = (XCF_GetCharString)nil;
  411. callbacks.getCharStrHook = (void PTR_PREFIX *)nil;
  412. callbacks.getFSType = (XCF_GetFSType)getFSType;
  413. callbacks.getFSTypeHook = (void PTR_PREFIX *)pUFO;
  414. /* GOODNAME */
  415. callbacks.isKnownROS = (XCF_IsKnownROS)isKnownROS;
  416. callbacks.isKnownROSHook = (void PTR_PREFIX *)pUFO;
  417. /*
  418. * Initialize XCF_ClientOptions object.
  419. */
  420. options.fontIndex = 0; /* font index w/i a CFF font set */
  421. options.uniqueIDMethod = pFont->info.uniqueIDMethod; /* UniqueID method */
  422. options.uniqueID = pFont->info.uniqueID;
  423. options.subrFlatten = (pFont->info.subrFlatten == kFlattenSubrs) ? XCF_FLATTEN_SUBRS : XCF_KEEP_SUBRS; /* Flatten subrs */
  424. // lenIV = -1 will fail on some clones bug 354368
  425. // options.lenIV = (pUFO->pUFL->outDev.lPSLevel > kPSLevel1) ? (unsigned int)-1 : 4;
  426. options.lenIV = 0;
  427. options.hexEncoding = StrmCanOutputBinary(pUFO->pUFL->hOut) ? 0 : 1;
  428. options.eexecEncryption = (pUFO->pUFL->outDev.lPSLevel > kPSLevel1) ? 0 : 1;
  429. options.outputCharstrType = 1; /* (pUFO->pUFL->outDev.lPSLevel > kPSLevel2) ? 2 : 1 */
  430. options.maxBlockSize = pFont->info.maxBlockSize;
  431. /*
  432. * XCF_ClientOptions.dlOptions initialization
  433. */
  434. if (pFont->info.usePSName)
  435. options.dlOptions.notdefEncoding = 1;
  436. else
  437. options.dlOptions.notdefEncoding = 0;
  438. options.dlOptions.useSpecialEncoding = (pFont->info.useSpecialEncoding) ? 1 : 0;
  439. options.dlOptions.encodeName = (unsigned char PTR_PREFIX *)pUFO->pszEncodeName;
  440. if (pFont->info.escDownloadFace)
  441. options.dlOptions.fontName = (unsigned char PTR_PREFIX *)pUFO->pszFontName;
  442. else
  443. {
  444. if (pFont->info.type1)
  445. {
  446. if (pUFO->subfontNumber < 0x100)
  447. CREATE_ADCFXX_FONTNAME(UFLsprintf, fontName, CCHOF(fontName),
  448. pUFO->subfontNumber, pFont->info.baseName);
  449. else
  450. CREATE_ADXXXX_FONTNAME(UFLsprintf, fontName, CCHOF(fontName),
  451. pUFO->subfontNumber, pFont->info.baseName);
  452. }
  453. else
  454. {
  455. /* Reuse vifinfo.nPlatformID to fix #507985. */
  456. if (pUFO->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  457. {
  458. if (pUFO->lDownloadFormat == kCFFCID_H)
  459. UFLsprintf(fontName, CCHOF(fontName), "%s%s", CFFPREFIX_H, pFont->info.baseName);
  460. else
  461. UFLsprintf(fontName, CCHOF(fontName), "%s%s", CFFPREFIX_V, pFont->info.baseName);
  462. }
  463. else
  464. UFLsprintf(fontName, CCHOF(fontName), "%s%s", CFFPREFIX, pFont->info.baseName);
  465. }
  466. options.dlOptions.fontName = (unsigned char PTR_PREFIX *)fontName;
  467. }
  468. options.dlOptions.otherSubrNames =
  469. (pUFO->pUFL->outDev.lPSVersion >= VER_WO_OTHERSUBRS)
  470. ? 0 : (unsigned char PTR_PREFIX * PTR_PREFIX *)pSubrNames;
  471. return XCF_Init(&pFont->hFont, &callbacks, &options);
  472. }
  473. /******************************************************************************
  474. *
  475. * Public Functions
  476. *
  477. ******************************************************************************/
  478. void
  479. CFFFontCleanUp(
  480. UFOStruct *pUFObj
  481. )
  482. {
  483. CFFFontStruct *pFont;
  484. UFLCFFReadBuf *pReadBuf;
  485. if (pUFObj->pAFont == nil)
  486. return;
  487. pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  488. if (pFont == nil)
  489. return;
  490. if (pFont->hFont)
  491. {
  492. XCF_CleanUp(&pFont->hFont);
  493. pFont->hFont = nil;
  494. }
  495. pReadBuf = pFont->pReadBuf;
  496. if (pReadBuf->pBuf)
  497. {
  498. UFLDeletePtr(pUFObj->pMem, pReadBuf->pBuf);
  499. pReadBuf->pBuf = nil;
  500. }
  501. }
  502. UFLErrCode
  503. CFFUpdateEncodingVector1(
  504. UFOStruct *pUFO,
  505. const UFLGlyphsInfo *pGlyphs,
  506. const short cGlyphs,
  507. const UFLGlyphID *pGlyphIndices
  508. )
  509. {
  510. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  511. UFLHANDLE stream = pUFO->pUFL->hOut;
  512. UFLErrCode retCode = kNoErr;
  513. char strmbuf[256];
  514. short i;
  515. /* Sanity checks */
  516. if (0 == cGlyphs)
  517. return kNoErr;
  518. if ((0 == pFont) || (0 == pGlyphIndices))
  519. return kErrInvalidParam;
  520. /*
  521. * Do '/FontName findfont /Encoding get'.
  522. */
  523. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s findfont /Encoding get", pUFO->pszFontName);
  524. retCode = StrmPutStringEOL(stream, strmbuf);
  525. for (i = 0; (retCode == kNoErr) && (i < cGlyphs) && *pGlyphIndices; i++, pGlyphIndices++)
  526. {
  527. UFLsprintf(strmbuf, CCHOF(strmbuf), "dup %d /", i);
  528. retCode = StrmPutString(stream, strmbuf);
  529. if (retCode == kNoErr)
  530. {
  531. XCF_GlyphIDsToCharNames(pFont->hFont,
  532. 1,
  533. (XCFGlyphID PTR_PREFIX *)pGlyphIndices, /* list of glyphIDs */
  534. strmbuf,
  535. sizeof(strmbuf));
  536. retCode = StrmPutString(stream, strmbuf);
  537. }
  538. if (retCode == kNoErr)
  539. retCode = StrmPutStringEOL(stream, " put");
  540. }
  541. StrmPutStringEOL(stream, "pop");
  542. return retCode;
  543. }
  544. UFLErrCode
  545. CFFUpdateEncodingVector(
  546. UFOStruct *pUFO,
  547. const short cGlyphs,
  548. const UFLGlyphID *pGlyphIndices,
  549. const unsigned short *pGlyphNameIndex
  550. )
  551. {
  552. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  553. UFLHANDLE stream = pUFO->pUFL->hOut;
  554. UFLErrCode retCode = kNoErr;
  555. const UFLGlyphID *pGlyphIndices2 = pGlyphIndices;
  556. const unsigned short *pGlyphNameIndex2 = pGlyphNameIndex;
  557. char strmbuf[256];
  558. short i;
  559. /* Sanity checks */
  560. if (0 == cGlyphs)
  561. return kNoErr;
  562. if ((0 == pFont) || (0 == pGlyphNameIndex) || (0 == pGlyphIndices))
  563. return kErrInvalidParam;
  564. /*
  565. * Do we really need to update?
  566. */
  567. for (i = 0; i < cGlyphs; i++, pGlyphNameIndex2++, pGlyphIndices2++)
  568. {
  569. if ((*pGlyphNameIndex2 > 0) && (*pGlyphNameIndex2 <= 255))
  570. {
  571. if (!IS_GLYPH_SENT(pUFO->pUpdatedEncoding, *pGlyphNameIndex2))
  572. break;
  573. }
  574. }
  575. if (cGlyphs <= i)
  576. return kNoErr;
  577. /*
  578. * Do '/FontName findfont /Encoding get'.
  579. */
  580. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s findfont /Encoding get", pUFO->pszFontName);
  581. retCode = StrmPutStringEOL(stream, strmbuf);
  582. for (i = 0; (retCode == kNoErr) && (i < cGlyphs); i++, pGlyphNameIndex++, pGlyphIndices++)
  583. {
  584. if ((*pGlyphNameIndex > 0) && (*pGlyphNameIndex <= 255))
  585. {
  586. if (!IS_GLYPH_SENT(pUFO->pUpdatedEncoding, *pGlyphNameIndex))
  587. {
  588. /*
  589. * Do "dup index /Charactername put."
  590. */
  591. UFLsprintf(strmbuf, CCHOF(strmbuf), "dup %d /", *pGlyphNameIndex);
  592. retCode = StrmPutString(stream, strmbuf);
  593. if (kNoErr == retCode)
  594. {
  595. if (XCF_Ok == XCF_GlyphIDsToCharNames(pFont->hFont,
  596. 1,
  597. (XCFGlyphID PTR_PREFIX *)pGlyphIndices, /* list of glyphIDs */
  598. strmbuf,
  599. sizeof(strmbuf)))
  600. {
  601. retCode = StrmPutString(stream, strmbuf);
  602. }
  603. else
  604. retCode = kErrUnknown;
  605. }
  606. if (kNoErr == retCode)
  607. retCode = StrmPutStringEOL(stream, " put");
  608. if (kNoErr == retCode)
  609. SET_GLYPH_SENT_STATUS(pUFO->pUpdatedEncoding, *pGlyphNameIndex);
  610. }
  611. }
  612. }
  613. StrmPutStringEOL(stream, "pop");
  614. return retCode;
  615. }
  616. UFLErrCode
  617. CFFCreateBaseFont(
  618. UFOStruct *pUFObj,
  619. const UFLGlyphsInfo *pGlyphs,
  620. unsigned long *pVMUsage,
  621. char *pHostFontName
  622. )
  623. {
  624. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  625. UFLHANDLE stream = pUFObj->pUFL->hOut;
  626. UFLErrCode retCode = kNoErr;
  627. char strmbuf[512];
  628. /* Sanity checks */
  629. if (pUFObj->flState < kFontInit)
  630. return kErrInvalidState;
  631. if ((pFont == nil) || (pFont->hFont == nil))
  632. return kErrInvalidHandle;
  633. /*
  634. * Download procsets.
  635. */
  636. switch (pUFObj->lDownloadFormat)
  637. {
  638. case kCFF:
  639. if (pUFObj->pUFL->outDev.lPSVersion <= VER_WO_OTHERSUBRS)
  640. {
  641. /*
  642. * Only download the required OtherSubr procset if the printer
  643. * version is less than 51 and we have not download anything.
  644. */
  645. if (pUFObj->pUFL->outDev.pstream->pfDownloadProcset == 0)
  646. return kErrDownloadProcset;
  647. if (!pUFObj->pUFL->outDev.pstream->pfDownloadProcset(pUFObj->pUFL->outDev.pstream, kCFFHeader))
  648. return kErrDownloadProcset;
  649. }
  650. break;
  651. case kCFFCID_H:
  652. case kCFFCID_V:
  653. if (!pUFObj->pUFL->outDev.pstream->pfDownloadProcset(pUFObj->pUFL->outDev.pstream, kCMap_FF))
  654. return kErrDownloadProcset;
  655. if (pUFObj->bPatchQXPCFFCID)
  656. {
  657. if (!pUFObj->pUFL->outDev.pstream->pfDownloadProcset(pUFObj->pUFL->outDev.pstream, kCMap_90msp))
  658. return kErrDownloadProcset;
  659. }
  660. }
  661. /*
  662. * Donwload the font's dictionary and the glyph data.
  663. */
  664. if (!UFO_FONT_INIT2(pUFObj))
  665. {
  666. enum XCF_Result status;
  667. /*
  668. * Fixed bug 366539. hasvmtx is used to determine whether to call the
  669. * CFFUpdateMetrics2 function later.
  670. */
  671. unsigned long tblSize = GETTTFONTDATA(pUFObj,
  672. VMTX_TABLE, 0L,
  673. nil, 0L,
  674. pFont->info.fData.fontIndex);
  675. pUFObj->pAFont->hasvmtx = tblSize ? 1 : 0;
  676. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  677. {
  678. status = XCF_DownloadFontIncr(pFont->hFont,
  679. pGlyphs->sCount,
  680. pGlyphs->pGlyphIndices,
  681. (pGlyphs->pCharIndex == 0)
  682. ? nil
  683. : (unsigned char PTR_PREFIX * PTR_PREFIX *)pGlyphs->ppGlyphNames,
  684. pVMUsage);
  685. if (XCF_Ok != status)
  686. retCode = kErrXCFCall;
  687. }
  688. }
  689. /*
  690. * %hostfont% support
  691. * When this is a %hostfont% emit %%IncludeResource DSC comment prior to
  692. * create the font.
  693. */
  694. if ((kNoErr == retCode) && HOSTFONT_IS_VALID_UFO(pUFObj) && !UFO_FONT_INIT2(pUFObj))
  695. {
  696. UFLsprintf(strmbuf, CCHOF(strmbuf), "\n%%%%IncludeResource: %s %s",
  697. (pUFObj->lDownloadFormat == kCFF) ? "font" : "CIDFont",
  698. pHostFontName);
  699. if (kNoErr == retCode)
  700. retCode = StrmPutStringEOL(stream, strmbuf);
  701. }
  702. if ((kNoErr == retCode) && IS_CFFCID(pUFObj->lDownloadFormat))
  703. {
  704. /*
  705. * Instanciate Identity-H or -V CMap.
  706. *
  707. * When 'vrt2' feature is enabled (and which is default for OTF based
  708. * CJKV fonts), simply compose Identity-V CMap and the CIDFont
  709. * downloaded suffice.
  710. */
  711. if (pUFObj->lDownloadFormat == kCFFCID_H)
  712. {
  713. retCode = StrmPutStringEOL(stream, "CMAP-WinCharSetFFFF-H");
  714. /* Special for Quark */
  715. if ((kNoErr == retCode) && pUFObj->bPatchQXPCFFCID)
  716. retCode = StrmPutStringEOL(stream, "CMAP-90msp-RKSJ-H");
  717. }
  718. else
  719. {
  720. retCode = StrmPutStringEOL(stream, "CMAP-WinCharSetFFFF-V");
  721. /* Special for Quark */
  722. if ((kNoErr == retCode) && pUFObj->bPatchQXPCFFCID)
  723. retCode = StrmPutStringEOL(stream, "CMAP-90msp-RKSJ-H CMAP-90msp-RKSJ-QV");
  724. }
  725. if (kNoErr == retCode)
  726. {
  727. /*
  728. * Create the CID-Keyed font.
  729. */
  730. UFLBool bRequire_vmtx = pUFObj->pAFont->hasvmtx && HOSTFONT_REQUIRE_VMTX;
  731. if (pUFObj->lDownloadFormat == kCFFCID_H)
  732. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s /WinCharSetFFFF-H", pUFObj->pszFontName);
  733. else
  734. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s /WinCharSetFFFF-V", pUFObj->pszFontName);
  735. if (kNoErr == retCode)
  736. retCode = StrmPutStringEOL(stream, strmbuf);
  737. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  738. {
  739. /* Reuse vifinfo.nPlatformID to fix #507985. */
  740. if (pUFObj->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  741. {
  742. if (pUFObj->lDownloadFormat == kCFFCID_H)
  743. UFLsprintf(strmbuf, CCHOF(strmbuf), "[/%s%s] composefont pop", CFFPREFIX_H, pFont->info.baseName);
  744. else
  745. UFLsprintf(strmbuf, CCHOF(strmbuf), "[/%s%s] composefont pop", CFFPREFIX_V, pFont->info.baseName);
  746. }
  747. else
  748. UFLsprintf(strmbuf, CCHOF(strmbuf), "[/%s%s] composefont pop", CFFPREFIX, pFont->info.baseName);
  749. }
  750. else if (!bRequire_vmtx)
  751. UFLsprintf(strmbuf, CCHOF(strmbuf), "[/%s] composefont pop", pHostFontName);
  752. else
  753. {
  754. if (UFL_CIDFONT_SHARED)
  755. {
  756. if (!UFO_FONT_INIT2(pUFObj))
  757. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s %s /%s hfMkCIDFont",
  758. pHostFontName, HFPOSTFIX, HFCIDCDEVPROC, pHostFontName);
  759. else
  760. UFLsprintf(strmbuf, CCHOF(strmbuf), "[/%s%s] composefont pop", pHostFontName, HFPOSTFIX);
  761. }
  762. else
  763. {
  764. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s%s %s /%s hfMkCIDFont",
  765. pHostFontName, HFPOSTFIX,
  766. (pUFObj->lDownloadFormat == kCFFCID_H) ? "h" : "v",
  767. HFCIDCDEVPROC, pHostFontName);
  768. }
  769. }
  770. if (kNoErr == retCode)
  771. retCode = StrmPutStringEOL(stream, strmbuf);
  772. /*
  773. * Special for Quark
  774. */
  775. if ((kNoErr == retCode) && pUFObj->bPatchQXPCFFCID)
  776. {
  777. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%sQ", pUFObj->pszFontName);
  778. retCode = StrmPutString(stream, strmbuf);
  779. if (pUFObj->lDownloadFormat == kCFFCID_H)
  780. {
  781. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  782. {
  783. /* Reuse vifinfo.nPlatformID to fix #507985. */
  784. if (pUFObj->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  785. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-H [/%s%s] composefont pop",
  786. CFFPREFIX_H, pFont->info.baseName);
  787. else
  788. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-H [/%s%s] composefont pop",
  789. CFFPREFIX, pFont->info.baseName);
  790. }
  791. else if (!bRequire_vmtx)
  792. {
  793. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-H [/%s] composefont pop",
  794. pHostFontName);
  795. }
  796. else
  797. {
  798. if (UFL_CIDFONT_SHARED)
  799. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-H [/%s%s] composefont pop",
  800. pHostFontName, HFPOSTFIX);
  801. else
  802. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-H [/%s%s%s] composefont pop",
  803. pHostFontName, HFPOSTFIX, "h");
  804. }
  805. }
  806. else
  807. {
  808. /* Added 'dup dup' for bug 346287. */
  809. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  810. {
  811. /* Reuse vifinfo.nPlatformID to fix #507985. */
  812. if (pUFObj->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  813. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-QV [/%s%s dup dup] composefont pop",
  814. CFFPREFIX_V, pFont->info.baseName);
  815. else
  816. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-QV [/%s%s dup dup] composefont pop",
  817. CFFPREFIX, pFont->info.baseName);
  818. }
  819. else if (!bRequire_vmtx)
  820. {
  821. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-QV [/%s dup dup] composefont pop",
  822. pHostFontName);
  823. }
  824. else
  825. {
  826. if (UFL_CIDFONT_SHARED)
  827. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-QV [/%s%s dup dup] composefont pop",
  828. pHostFontName, HFPOSTFIX);
  829. else
  830. UFLsprintf(strmbuf, CCHOF(strmbuf), " /90msp-RKSJ-QV [/%s%s%s dup dup] composefont pop",
  831. pHostFontName, HFPOSTFIX, "v");
  832. }
  833. }
  834. if (kNoErr == retCode)
  835. retCode = StrmPutStringEOL(stream, strmbuf);
  836. }
  837. }
  838. }
  839. else if ((kNoErr == retCode) && HOSTFONT_IS_VALID_UFO(pUFObj))
  840. {
  841. /*
  842. * Redefine the font using the already existing OpenType host font with
  843. * a unique name so that we can reencode its encoding vector freely. We
  844. * don't want empty CharStrings so that we give false to hfRedefFont.
  845. */
  846. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s false /%s hfRedefFont",
  847. pUFObj->pszFontName, pHostFontName);
  848. if (kNoErr == retCode)
  849. retCode = StrmPutStringEOL(stream, strmbuf);
  850. }
  851. /*
  852. * Change the font state. (skip kFontHeaderDownloaded state.)
  853. */
  854. if (kNoErr == retCode)
  855. pUFObj->flState = kFontHasChars;
  856. return retCode;
  857. }
  858. UFLErrCode
  859. CFFAddChars(
  860. UFOStruct *pUFObj,
  861. const UFLGlyphsInfo *pGlyphs,
  862. unsigned long *pVMUsage
  863. )
  864. {
  865. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  866. UFLErrCode retCode = kNoErr;
  867. /* Sanity checks */
  868. if (pUFObj->flState < kFontHeaderDownloaded)
  869. return kErrInvalidState;
  870. if ((pFont == nil) || (pFont->hFont == nil))
  871. return kErrInvalidHandle;
  872. /*
  873. * Download the glyphs.
  874. */
  875. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  876. {
  877. enum XCF_Result status;
  878. status = XCF_DownloadFontIncr(pFont->hFont,
  879. pGlyphs->sCount,
  880. pGlyphs->pGlyphIndices,
  881. (pGlyphs->pCharIndex == 0)
  882. ? nil
  883. : (unsigned char PTR_PREFIX * PTR_PREFIX *)pGlyphs->ppGlyphNames,
  884. pVMUsage);
  885. if (XCF_Ok != status)
  886. retCode = kErrXCFCall;
  887. }
  888. /*
  889. * Change the font state.
  890. */
  891. if (kNoErr == retCode)
  892. pUFObj->flState = kFontHasChars;
  893. return retCode;
  894. }
  895. UFLErrCode
  896. CFFUpdateMetrics2(
  897. UFOStruct *pUFObj,
  898. const UFLGlyphsInfo *pGlyphs,
  899. char *pHostFontName
  900. )
  901. {
  902. UFLErrCode retVal = kNoErr;
  903. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  904. UFLHANDLE stream = pUFObj->pUFL->hOut;
  905. char strmbuf[256];
  906. unsigned short wIndex;
  907. UFLBool bRequire_vmtx = pUFObj->pAFont->hasvmtx && HOSTFONT_REQUIRE_VMTX;
  908. if ((!HOSTFONT_IS_VALID_UFO(pUFObj) || bRequire_vmtx) && (pGlyphs->sCount > 0))
  909. {
  910. UFLGlyphID *glyphs = pGlyphs->pGlyphIndices;
  911. unsigned short i;
  912. unsigned short *pCIDs = (unsigned short*)UFLNewPtr(pUFObj->pMem, pGlyphs->sCount * sizeof (unsigned short));
  913. if (pCIDs)
  914. retVal = CFFGIDsToCIDs(pFont, pGlyphs->sCount, glyphs, pCIDs);
  915. else
  916. retVal = kErrOutOfMemory;
  917. if (kNoErr != retVal)
  918. {
  919. if (pCIDs)
  920. UFLDeletePtr(pUFObj->pMem, pCIDs);
  921. return retVal;
  922. }
  923. /*
  924. * Check pUFObj->pAFont->pCodeGlyphs to see if we really need to update
  925. * it.
  926. */
  927. for (i = 0; i < (unsigned short) pGlyphs->sCount; i++)
  928. {
  929. unsigned short wIndex = (unsigned short)(glyphs[i] & 0x0000FFFF); /* LOWord is the real GID. */
  930. if (wIndex >= UFO_NUM_GLYPHS(pUFObj))
  931. continue;
  932. if (!IS_GLYPH_SENT(pUFObj->pAFont->pDownloadedGlyphs, wIndex))
  933. {
  934. long em, w1y, vx, vy, tsb, vasc;
  935. UFLBool bUseDef;
  936. GetMetrics2FromTTF(pUFObj, wIndex, &em, &w1y, &vx, &vy, &tsb, &bUseDef, 0, &vasc);
  937. UFLsprintf(strmbuf, CCHOF(strmbuf), "%ld [0 %ld %ld %ld] ", (long)pCIDs[i], -w1y, vx, tsb);
  938. retVal = StrmPutString(stream, strmbuf);
  939. if (!HOSTFONT_IS_VALID_UFO(pUFObj))
  940. {
  941. /* Reuse vifinfo.nPlatformID to fix #507985. */
  942. if (pUFObj->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  943. {
  944. if (pUFObj->lDownloadFormat == kCFFCID_H)
  945. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s T0AddCFFMtx2", CFFPREFIX_H, pFont->info.baseName);
  946. else
  947. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s T0AddCFFMtx2", CFFPREFIX_V, pFont->info.baseName);
  948. }
  949. else
  950. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s%s T0AddCFFMtx2", CFFPREFIX, pFont->info.baseName);
  951. }
  952. else
  953. {
  954. if (UFL_CIDFONT_SHARED)
  955. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s%s T0AddCFFMtx2", pHostFontName, HFPOSTFIX);
  956. else
  957. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s%s%s T0AddCFFMtx2",
  958. pHostFontName, HFPOSTFIX,
  959. (pUFObj->lDownloadFormat == kCFFCID_H) ? "h" : "v");
  960. }
  961. if (kNoErr == retVal)
  962. retVal = StrmPutStringEOL(stream, strmbuf);
  963. if (kNoErr == retVal)
  964. SET_GLYPH_SENT_STATUS(pUFObj->pAFont->pDownloadedGlyphs, wIndex);
  965. }
  966. }
  967. UFLDeletePtr(pUFObj->pMem, pCIDs);
  968. }
  969. return retVal;
  970. }
  971. UFLErrCode
  972. CFFReencode(
  973. UFOStruct *pUFObj,
  974. const UFLGlyphsInfo *pGlyphs,
  975. unsigned long *pVMUsage,
  976. char *pHostFontName
  977. )
  978. {
  979. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  980. UFLErrCode retCode = kNoErr;
  981. /* Sanity checks */
  982. if (pUFObj->flState < kFontHeaderDownloaded)
  983. return kErrInvalidState;
  984. if ((pFont == nil) || (pFont->hFont == nil))
  985. return kErrInvalidHandle;
  986. /*
  987. * Reencode the encoding vector and define good glyph names.
  988. */
  989. if (kNoErr == retCode)
  990. {
  991. if (pFont->info.usePSName)
  992. {
  993. if (pGlyphs->pCharIndex == 0)
  994. retCode = CFFUpdateEncodingVector1(
  995. (UFOStruct *)pUFObj,
  996. pGlyphs,
  997. pGlyphs->sCount,
  998. pGlyphs->pGlyphIndices);
  999. else
  1000. retCode = CFFUpdateEncodingVector(
  1001. (UFOStruct *)pUFObj,
  1002. pGlyphs->sCount,
  1003. pGlyphs->pGlyphIndices,
  1004. pGlyphs->pCharIndex);
  1005. }
  1006. /*
  1007. * Adobe Bug #366539 and #388111: Download Metrics2 for vertical writing
  1008. *
  1009. * Note: to remember the glyphs downloaded for Metrics2 we use
  1010. * pUFObj->pAFont->pDownloadedGlyphs. There is another bitmap data,
  1011. * pUFObj->pAFont->pCodeGlyphs, to remember the glyphs downloaded
  1012. * for GoodGlyphName. They must be used independently. Do not use
  1013. * pDownloadedGlyphs for GoodGlyphName and pCodeGlyphs for Metrics2.
  1014. */
  1015. if ((kNoErr == retCode) && IS_CFFCID(pUFObj->lDownloadFormat))
  1016. {
  1017. retCode = CFFUpdateMetrics2(pUFObj, pGlyphs, pHostFontName);
  1018. }
  1019. /*
  1020. * GOODNAME
  1021. */
  1022. if ((kNoErr == retCode)
  1023. && (pGlyphs->sCount > 0)
  1024. && (pUFObj->dwFlags & UFO_HasG2UDict)
  1025. && (IS_CFFCID(pUFObj->lDownloadFormat))
  1026. && !(pUFObj->pAFont->knownROS))
  1027. {
  1028. UFLGlyphID *glyphs = pGlyphs->pGlyphIndices;
  1029. unsigned short i;
  1030. /*
  1031. * Check pUFObj->pAFont->pCodeGlyphs to see if we really need to
  1032. * update it.
  1033. */
  1034. for (i = 0; i < (unsigned short) pGlyphs->sCount; i++)
  1035. {
  1036. unsigned short wIndex = (unsigned short)(glyphs[i] & 0x0000FFFF); /* LOWord is the real GID. */
  1037. if (wIndex >= UFO_NUM_GLYPHS(pUFObj))
  1038. continue;
  1039. if (!IS_GLYPH_SENT(pUFObj->pAFont->pCodeGlyphs, wIndex))
  1040. {
  1041. /*
  1042. * Found at least one not updated. Do it (once) for all.
  1043. */
  1044. retCode = UpdateCodeInfo(pUFObj, pGlyphs, 0);
  1045. break;
  1046. }
  1047. }
  1048. }
  1049. }
  1050. return retCode;
  1051. }
  1052. UFLErrCode
  1053. CFFFontDownloadIncr(
  1054. UFOStruct *pUFObj,
  1055. const UFLGlyphsInfo *pGlyphs,
  1056. unsigned long *pVMUsage,
  1057. unsigned long *pFCUsage
  1058. )
  1059. {
  1060. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  1061. UFLErrCode retCode = kNoErr;
  1062. char *pHostFontName = nil;
  1063. if (pFCUsage)
  1064. *pFCUsage = 0;
  1065. /*
  1066. * Sanity checks.
  1067. */
  1068. if ((pGlyphs == nil) || (pGlyphs->pGlyphIndices == nil) || (pGlyphs->sCount == 0))
  1069. return kErrInvalidParam;
  1070. /*
  1071. * No need to download if the full font has already been downloaded.
  1072. */
  1073. if (pUFObj->flState == kFontFullDownloaded)
  1074. return kNoErr;
  1075. /*
  1076. * Check %hostfont% status prior to download anything.
  1077. */
  1078. HostFontValidateUFO(pUFObj, &pHostFontName);
  1079. if (pUFObj->flState == kFontInit)
  1080. {
  1081. /*
  1082. * Create a base font (and the glyphs) if it has not been done yet.
  1083. */
  1084. retCode = CFFCreateBaseFont(pUFObj, pGlyphs, pVMUsage, pHostFontName);
  1085. if (kNoErr == retCode)
  1086. retCode = CFFReencode(pUFObj, pGlyphs, pVMUsage, pHostFontName);
  1087. }
  1088. else
  1089. {
  1090. /*
  1091. * Download the glyphs.
  1092. */
  1093. retCode = CFFAddChars(pUFObj, pGlyphs, pVMUsage);
  1094. if (kNoErr == retCode)
  1095. retCode = CFFReencode(pUFObj, pGlyphs, pVMUsage, pHostFontName);
  1096. }
  1097. return retCode;
  1098. }
  1099. UFLErrCode
  1100. CFFVMNeeded(
  1101. const UFOStruct *pUFO,
  1102. const UFLGlyphsInfo *pGlyphs,
  1103. unsigned long *pVMNeeded,
  1104. unsigned long *pFCNeeded
  1105. )
  1106. {
  1107. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  1108. enum XCF_Result status;
  1109. unsigned short cDLGlyphs;
  1110. if (pVMNeeded)
  1111. *pVMNeeded = 0;
  1112. if (pFCNeeded)
  1113. *pFCNeeded = 0;
  1114. if ((pFont == nil) || (pFont->hFont == nil))
  1115. return kErrInvalidHandle;
  1116. status = XCF_CountDownloadGlyphs(pFont->hFont,
  1117. pGlyphs->sCount,
  1118. (XCFGlyphID *)pGlyphs->pGlyphIndices,
  1119. &cDLGlyphs);
  1120. if (XCF_Ok != status)
  1121. return kErrUnknown;
  1122. if (!HOSTFONT_IS_VALID_UFO(pUFO))
  1123. {
  1124. if (pVMNeeded)
  1125. *pVMNeeded = cDLGlyphs * kVMTTT1Char;
  1126. if (pUFO->flState == kFontInit)
  1127. {
  1128. if (pVMNeeded)
  1129. *pVMNeeded += kVMTTT1Header;
  1130. }
  1131. }
  1132. else
  1133. {
  1134. unsigned long tblSize = GETTTFONTDATA(pUFO,
  1135. VMTX_TABLE, 0L,
  1136. nil, 0L,
  1137. pFont->info.fData.fontIndex);
  1138. if (tblSize && HOSTFONT_REQUIRE_VMTX)
  1139. {
  1140. if (pVMNeeded)
  1141. *pVMNeeded = cDLGlyphs * HFVMM2SZ;
  1142. }
  1143. }
  1144. return kNoErr;
  1145. }
  1146. UFLErrCode
  1147. CFFUndefineFont(
  1148. UFOStruct *pUFO
  1149. )
  1150. {
  1151. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  1152. UFLHANDLE stream = pUFO->pUFL->hOut;
  1153. UFLErrCode retVal = kNoErr;
  1154. char strmbuf[256];
  1155. if ((pFont == nil) || (pFont->hFont == nil))
  1156. return kErrInvalidHandle;
  1157. if (pUFO->flState == kFontInit)
  1158. return retVal;
  1159. if ((pUFO->lDownloadFormat == kCFFCID_H) || (pUFO->lDownloadFormat == kCFFCID_V))
  1160. {
  1161. /* Reuse vifinfo.nPlatformID to fix #507985. */
  1162. if (pUFO->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  1163. {
  1164. if (pUFO->lDownloadFormat == kCFFCID_H)
  1165. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s /CIDFont UDR", CFFPREFIX_H, pFont->info.baseName);
  1166. else
  1167. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s /CIDFont UDR", CFFPREFIX_V, pFont->info.baseName);
  1168. }
  1169. else
  1170. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s /CIDFont UDR", CFFPREFIX, pFont->info.baseName);
  1171. retVal = StrmPutStringEOL(stream, strmbuf);
  1172. }
  1173. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s UDF", pUFO->pszFontName);
  1174. if (kNoErr == retVal)
  1175. retVal = StrmPutStringEOL(stream, strmbuf);
  1176. return retVal;
  1177. }
  1178. UFLErrCode
  1179. CFFGIDsToCIDs(
  1180. const CFFFontStruct *pFont,
  1181. const short cGlyphs,
  1182. const UFLGlyphID *pGIDs,
  1183. unsigned short *pCIDs
  1184. )
  1185. {
  1186. unsigned short int *pCurCIDs = (unsigned short int *)pCIDs;
  1187. UFLGlyphID *pCurGIDs = (UFLGlyphID *)pGIDs;
  1188. UFLErrCode retCode = kNoErr;
  1189. enum XCF_Result status;
  1190. short i;
  1191. for (i = 0; i < cGlyphs; i++)
  1192. {
  1193. status = XCF_GlyphIDsToCIDs(pFont->hFont,
  1194. 1,
  1195. (XCFGlyphID PTR_PREFIX *)pCurGIDs++, /* list of glyphIDs */
  1196. pCurCIDs++);
  1197. if (XCF_Ok != status)
  1198. {
  1199. retCode = kErrUnknown;
  1200. break;
  1201. }
  1202. }
  1203. return retCode;
  1204. }
  1205. UFOStruct *
  1206. CFFFontInit(
  1207. const UFLMemObj *pMem,
  1208. const UFLStruct *pUFL,
  1209. const UFLRequest *pRequest,
  1210. UFLBool *pTestRestricted
  1211. )
  1212. {
  1213. enum XCF_Result status = XCF_InternalError;
  1214. CFFFontStruct *pFont = nil;
  1215. UFOStruct *pUFObj = (UFOStruct*)UFLNewPtr(pMem, sizeof (UFOStruct));
  1216. UFLCFFFontInfo *pInfo;
  1217. if (pUFObj == 0)
  1218. return nil;
  1219. /* Initialize data. */
  1220. UFOInitData(pUFObj, UFO_CFF, pMem, pUFL, pRequest,
  1221. (pfnUFODownloadIncr) CFFFontDownloadIncr,
  1222. (pfnUFOVMNeeded) CFFVMNeeded,
  1223. (pfnUFOUndefineFont) CFFUndefineFont,
  1224. (pfnUFOCleanUp) CFFFontCleanUp,
  1225. (pfnUFOCopy) CopyFont);
  1226. /*
  1227. * pszFontName should be ready/allocated. If not, cannot continue.
  1228. */
  1229. if ((pUFObj->pszFontName == nil) || (pUFObj->pszFontName[0] == '\0'))
  1230. {
  1231. UFLDeletePtr(pMem, pUFObj);
  1232. return nil;
  1233. }
  1234. pInfo = (UFLCFFFontInfo *)pRequest->hFontInfo;
  1235. if (NewFont(pUFObj, sizeof(CFFFontStruct), pInfo->fData.maxGlyphs) == kNoErr)
  1236. {
  1237. pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  1238. pFont->info = *pInfo;
  1239. pFont->pReadBuf = &pFont->info.readBuf;
  1240. /* a convenient pointer */
  1241. pUFObj->pFData = &(pFont->info.fData);
  1242. pFont->info.fData.cNumGlyphs = GetNumGlyphs(pUFObj);
  1243. if (pUFObj->pUpdatedEncoding == 0)
  1244. pUFObj->pUpdatedEncoding = (unsigned char *)UFLNewPtr(pMem, GLYPH_SENT_BUFSIZE(256));
  1245. pFont->hFont = 0;
  1246. status = CFFInitFont(pUFObj, pFont);
  1247. }
  1248. if ((XCF_Ok != status) || (pFont == nil) || (pFont->hFont == 0))
  1249. {
  1250. vDeleteFont(pUFObj);
  1251. UFLDeletePtr(pUFObj->pMem, pUFObj);
  1252. return nil;
  1253. }
  1254. else
  1255. {
  1256. if (pTestRestricted)
  1257. {
  1258. unsigned char uc;
  1259. unsigned short int us;
  1260. XCF_SubsetRestrictions(pFont->hFont, &uc, &us);
  1261. *pTestRestricted = (BOOL)uc;
  1262. }
  1263. else
  1264. status = XCF_ProcessCFF(pFont->hFont);
  1265. if (XCF_Ok == status)
  1266. pUFObj->flState = kFontInit;
  1267. else
  1268. {
  1269. vDeleteFont(pUFObj);
  1270. UFLDeletePtr(pUFObj->pMem, pUFObj);
  1271. return nil;
  1272. }
  1273. }
  1274. return pUFObj;
  1275. }