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.

1228 lines
35 KiB

  1. /*
  2. * Adobe Universal Font Library
  3. *
  4. * Copyright (c) 1996 Adobe Systems Inc.
  5. * All Rights Reserved
  6. *
  7. * UFO.c - Universal Font Object
  8. *
  9. *
  10. * $Header:
  11. */
  12. #include "UFO.h"
  13. #include "UFLMem.h"
  14. #include "UFLErr.h"
  15. #include "UFLStd.h"
  16. #include "UFOCff.h"
  17. #include "UFOTTT1.h"
  18. #include "UFOTTT3.h"
  19. #include "UFOT42.h"
  20. #include "ParseTT.h"
  21. /*
  22. * Private default methods used by UFO base class
  23. */
  24. UFLErrCode
  25. UFODefaultVMNeeded(
  26. const UFOStruct *pUFObj,
  27. const UFLGlyphsInfo *pGlyphs,
  28. unsigned long *pVMNeeded,
  29. unsigned long *pFCNeeded
  30. )
  31. {
  32. return kErrInvalidFontType;
  33. }
  34. UFLErrCode
  35. UFODefaultUndefineFont(
  36. const UFOStruct *pUFObj
  37. )
  38. {
  39. return kErrInvalidFontType;
  40. }
  41. void
  42. UFODefaultCleanUp(
  43. UFOStruct *pUFObj
  44. )
  45. {
  46. }
  47. UFLErrCode
  48. UFODefaultDownloadIncr(
  49. const UFOStruct *pUFObj,
  50. const UFLGlyphsInfo *pGlyphs,
  51. unsigned long *pVMUsage,
  52. unsigned long *pFCUsage
  53. )
  54. {
  55. return kErrInvalidFontType;
  56. }
  57. UFOStruct *
  58. UFODefaultCopy(
  59. UFOStruct *pUFObj
  60. )
  61. {
  62. return nil;
  63. }
  64. /*
  65. * Public methods
  66. */
  67. void
  68. UFOInitData(
  69. UFOStruct *pUFObj,
  70. int ufoType,
  71. const UFLMemObj *pMem,
  72. const UFLStruct *pSession,
  73. const UFLRequest *pRequest,
  74. pfnUFODownloadIncr pfnDownloadIncr,
  75. pfnUFOVMNeeded pfnVMNeeded,
  76. pfnUFOUndefineFont pfnUndefineFont,
  77. pfnUFOCleanUp pfnCleanUp,
  78. pfnUFOCopy pfnCopy
  79. )
  80. {
  81. short sNameLen = 0;
  82. short sEncodeLen = 0;
  83. /*
  84. * Initialize basic fields
  85. */
  86. pUFObj->ufoType = ufoType;
  87. pUFObj->flState = kFontCreated;
  88. pUFObj->lProcsetResID = 0; /* resource ID of the required procset */
  89. pUFObj->dwFlags = 0;
  90. pUFObj->pMem = pMem;
  91. pUFObj->pUFL = pSession; /* the session handle returned by FTLInit */
  92. pUFObj->pAFont = nil;
  93. pUFObj->pUpdatedEncoding = nil;
  94. pUFObj->pFData = nil;
  95. pUFObj->lNumNT4SymGlyphs = 0;
  96. /*
  97. * Handle request data.
  98. */
  99. pUFObj->lDownloadFormat = pRequest->lDownloadFormat;
  100. pUFObj->hClientData = pRequest->hData;
  101. pUFObj->subfontNumber = pRequest->subfontNumber;
  102. /*
  103. * Allocate a buffer to hold both FontName and EncodeName. This will be
  104. * freed in UFOCleanUpData().
  105. */
  106. pUFObj->pszFontName = nil;
  107. pUFObj->pszEncodeName = nil;
  108. if ((pRequest->pszFontName == nil) || (pRequest->pszFontName[0] == '\0'))
  109. return;
  110. sNameLen = UFLstrlen(pRequest->pszFontName) + 1; /* Add extra 1 for NULL. */
  111. if (pRequest->pszEncodeName)
  112. sEncodeLen = UFLstrlen(pRequest->pszEncodeName) + 1; /* Add extra 1 for NULL. */
  113. pUFObj->pszFontName = (char *)UFLNewPtr(pUFObj->pMem, sNameLen + sEncodeLen);
  114. if (pUFObj->pszFontName != nil)
  115. {
  116. StringCchCopyA(pUFObj->pszFontName, sNameLen / sizeof(char), pRequest->pszFontName);
  117. if (pRequest->pszEncodeName)
  118. {
  119. pUFObj->pszEncodeName = pUFObj->pszFontName + sNameLen;
  120. StringCchCopyA(pUFObj->pszEncodeName, sEncodeLen / sizeof(char), pRequest->pszEncodeName);
  121. }
  122. }
  123. /*
  124. * If this flag is set to 1, then UFL will use the name passed in without
  125. * parsing 'post' table.
  126. */
  127. pUFObj->useMyGlyphName = pRequest->useMyGlyphName;
  128. /*
  129. * The buffer that contains MacGlyphNameList are locked all the time.
  130. * The containt in that buffer will not be changed. So, we do'nt need to
  131. * copy the data to the private UFL buffer.
  132. */
  133. if (pRequest->pMacGlyphNameList)
  134. pUFObj->pMacGlyphNameList = pRequest->pMacGlyphNameList;
  135. else
  136. pUFObj->pMacGlyphNameList = nil;
  137. /* Fix bug 274008 */
  138. if (pRequest->pEncodeNameList
  139. && pRequest->pwCommonEncode
  140. && pRequest->pwExtendEncode)
  141. {
  142. /*
  143. * The glyph handles are in ANSI codepage order or other standard
  144. * codepage order (1250, 1251, ... 1257). The buffer that contains
  145. * EncodeNameList and CommonEncode are locked all the time.
  146. * The containt in that buffer will not be changed. So, we do'nt need
  147. * to copy the data to the private UFL buffer.
  148. */
  149. pUFObj->pEncodeNameList = pRequest->pEncodeNameList;
  150. pUFObj->pwCommonEncode = pRequest->pwCommonEncode;
  151. pUFObj->pwExtendEncode = pRequest->pwExtendEncode;
  152. }
  153. else
  154. {
  155. pUFObj->pEncodeNameList = nil;
  156. pUFObj->pwCommonEncode = nil;
  157. pUFObj->pwExtendEncode = nil;
  158. }
  159. /* Fix #387084, #309104, and #309482. */
  160. pUFObj->vpfinfo = pRequest->vpfinfo;
  161. /* %hostfont% support */
  162. pUFObj->hHostFontData = pRequest->hHostFontData;
  163. if (HOSTFONT_IS_VALID_UFO_HFDH(pUFObj))
  164. HOSTFONT_VALIDATE_UFO(pUFObj);
  165. /* Fix #341904 */
  166. pUFObj->bPatchQXPCFFCID = pRequest->bPatchQXPCFFCID;
  167. /*
  168. * Initialize method pointers.
  169. */
  170. if (pfnDownloadIncr == nil)
  171. pUFObj->pfnDownloadIncr = (pfnUFODownloadIncr)UFODefaultDownloadIncr;
  172. else
  173. pUFObj->pfnDownloadIncr = pfnDownloadIncr;
  174. if (pfnVMNeeded == nil)
  175. pUFObj->pfnVMNeeded = (pfnUFOVMNeeded)UFODefaultVMNeeded;
  176. else
  177. pUFObj->pfnVMNeeded = pfnVMNeeded;
  178. if (pfnUndefineFont == nil)
  179. pUFObj->pfnUndefineFont = (pfnUFOUndefineFont)UFODefaultUndefineFont;
  180. else
  181. pUFObj->pfnUndefineFont = pfnUndefineFont;
  182. if (pfnCleanUp == nil)
  183. pUFObj->pfnCleanUp = (pfnUFOCleanUp)UFODefaultCleanUp;
  184. else
  185. pUFObj->pfnCleanUp = pfnCleanUp;
  186. if (pfnCopy == nil)
  187. pUFObj->pfnCopy = (pfnUFOCopy)UFODefaultCopy;
  188. else
  189. pUFObj->pfnCopy = pfnCopy;
  190. }
  191. void UFOCleanUpData(
  192. UFOStruct *pUFObj
  193. )
  194. {
  195. /* Free data that is NOT shared */
  196. if (pUFObj->pszFontName)
  197. {
  198. UFLDeletePtr(pUFObj->pMem, pUFObj->pszFontName);
  199. pUFObj->pszFontName = nil;
  200. }
  201. if (pUFObj->pUpdatedEncoding)
  202. {
  203. UFLDeletePtr(pUFObj->pMem, pUFObj->pUpdatedEncoding);
  204. pUFObj->pUpdatedEncoding = nil;
  205. }
  206. }
  207. UFLBool
  208. bUFOTestRestricted(
  209. const UFLMemObj *pMem,
  210. const UFLStruct *pSession,
  211. const UFLRequest *pRequest
  212. )
  213. {
  214. UFLBool bRetVal = 0;
  215. UFOStruct *pUFObj = CFFFontInit(pMem, pSession, pRequest, &bRetVal);
  216. if (pUFObj)
  217. UFOCleanUp(pUFObj);
  218. return bRetVal;
  219. }
  220. UFOStruct *
  221. UFOInit(
  222. const UFLMemObj *pMem,
  223. const UFLStruct *pSession,
  224. const UFLRequest *pRequest
  225. )
  226. {
  227. UFOStruct *pUFObj = nil;
  228. switch (pRequest->lDownloadFormat)
  229. {
  230. case kCFF:
  231. case kCFFCID_H:
  232. case kCFFCID_V:
  233. if (!bUFOTestRestricted(pMem, pSession, pRequest))
  234. pUFObj = CFFFontInit(pMem, pSession, pRequest, nil);
  235. break;
  236. case kTTType1: /* TT Font in Type 1 format */
  237. pUFObj = TTT1FontInit(pMem, pSession, pRequest);
  238. break;
  239. case kTTType3: /* TT Font in Type 3 format */
  240. case kTTType332: /* TT Font in Type 3/32 combo */
  241. pUFObj = TTT3FontInit(pMem, pSession, pRequest);
  242. break;
  243. case kTTType42: /* TT Font in Type 42 format */
  244. case kTTType42CID_H: /* TT Font in CID Type 42 format H */
  245. case kTTType42CID_V: /* TT Font in CID Type 42 format V */
  246. case kTTType42CID_Resource_H: /* TT Font: create CIDFont Resource only, no composefont */
  247. case kTTType42CID_Resource_V: /* TT Font: create CIDFont Resource only, no composefont */
  248. pUFObj = T42FontInit(pMem, pSession, pRequest);
  249. break;
  250. default:
  251. pUFObj = nil;
  252. }
  253. return pUFObj;
  254. }
  255. void
  256. UFOCleanUp(
  257. UFOStruct *pUFObj
  258. )
  259. {
  260. /* Free data that is NOT shared. */
  261. UFOCleanUpData(pUFObj);
  262. /* Free data that is Shared: decrease refCount or really free buffers. */
  263. vDeleteFont(pUFObj);
  264. /* Finally Free the UFOStruct itself. */
  265. UFLDeletePtr(pUFObj->pMem, pUFObj);
  266. }
  267. UFLErrCode
  268. UFODownloadIncr(
  269. const UFOStruct *pUFObj,
  270. const UFLGlyphsInfo *pGlyphs,
  271. unsigned long *pVMUsage,
  272. unsigned long *pFCUsage
  273. )
  274. {
  275. return pUFObj->pfnDownloadIncr(pUFObj, pGlyphs, pVMUsage, pFCUsage);
  276. }
  277. UFLErrCode
  278. UFOVMNeeded(
  279. const UFOStruct *pUFObj,
  280. const UFLGlyphsInfo *pGlyphs,
  281. unsigned long *pVMNeeded,
  282. unsigned long *pFCNeeded
  283. )
  284. {
  285. return pUFObj->pfnVMNeeded(pUFObj, pGlyphs, pVMNeeded, pFCNeeded);
  286. }
  287. UFLErrCode
  288. UFOUndefineFont(
  289. const UFOStruct *pUFObj
  290. )
  291. {
  292. return pUFObj->pfnUndefineFont(pUFObj);
  293. }
  294. UFOStruct *
  295. UFOCopyFont(
  296. const UFOStruct *pUFObj,
  297. const UFLRequest* pRequest
  298. )
  299. {
  300. return pUFObj->pfnCopy(pUFObj, pRequest);
  301. }
  302. UFLErrCode
  303. UFOGIDsToCIDs(
  304. const UFOStruct *pUFO,
  305. const short cGlyphs,
  306. const UFLGlyphID *pGIDs,
  307. unsigned short *pCIDs
  308. )
  309. {
  310. CFFFontStruct *pFont = (CFFFontStruct *)pUFO->pAFont->hFont;
  311. UFLErrCode retVal = kErrInvalidFontType;
  312. if ((pUFO->lDownloadFormat == kCFFCID_H) || (pUFO->lDownloadFormat == kCFFCID_V))
  313. retVal = CFFGIDsToCIDs(pFont, cGlyphs, pGIDs, pCIDs);
  314. return retVal;
  315. }
  316. UFLBool
  317. FindGlyphName(
  318. UFOStruct *pUFObj,
  319. const UFLGlyphsInfo *pGlyphs,
  320. short i, /* ANSI index */
  321. unsigned short wIndex, /* Glyph Index */
  322. char **pGoodName
  323. )
  324. /*++
  325. return value: 0 -- Can not find a good glyph name, using /Gxxxx.
  326. xxxx is a glyph id or predefined number(00-FF).
  327. 1 -- Find a good glyph name
  328. --*/
  329. {
  330. char *pHintName = nil;
  331. UFLBool bGoodName = 0; /* GoodName */
  332. if (pUFObj->useMyGlyphName && pGlyphs->ppGlyphNames)
  333. pHintName = (char *)pGlyphs->ppGlyphNames[i];
  334. if (pUFObj->useMyGlyphName && pHintName != nil)
  335. *pGoodName = pHintName;
  336. /*
  337. * Fix bug 274008 Get CharName from pre-defined table. This is only for
  338. * DownloadFace.
  339. */
  340. else if (pUFObj->pEncodeNameList && (i < 256))
  341. {
  342. /* Fix bug 274008 */
  343. char **pIndexTable = (char **)(pUFObj->pEncodeNameList);
  344. if (i < 128)
  345. *pGoodName = pIndexTable[pUFObj->pwCommonEncode[i]];
  346. else
  347. *pGoodName = pIndexTable[pUFObj->pwExtendEncode[i - 128]];
  348. bGoodName = 1; /* GoodName */
  349. }
  350. else
  351. {
  352. /* GoodName */
  353. *pGoodName = GetGlyphName(pUFObj, wIndex, pHintName, &bGoodName);
  354. if (!bGoodName && !(pGlyphs->pCode && pGlyphs->pCode[i]))
  355. {
  356. unsigned short unicode;
  357. /*
  358. * If GDI passes UV to the driver, we will use /gDDDDD as name and
  359. * add a hint to G2Udict. Otherwise, Parse CMAP table for unicode.
  360. */
  361. if (ParseTTTablesForUnicode(pUFObj, wIndex, &unicode, 1, DTT_parseCmapOnly))
  362. {
  363. // Fixed bug #516516. Now the buffer size is MAX_GLYPHNAME_LEN (256)
  364. char *gGlyphName = pUFObj->pAFont->gGlyphName;
  365. UFLsprintf(gGlyphName, CCHOF(pUFObj->pAFont->gGlyphName), "uni%04X", unicode);
  366. *pGoodName = gGlyphName;
  367. bGoodName = 1;
  368. }
  369. }
  370. }
  371. return bGoodName; /* GoodName */
  372. }
  373. /*
  374. * this function actually generates some PostScript that updates endocing
  375. * vector for entries from sStart to sEnd - 1.
  376. */
  377. UFLErrCode
  378. UpdateEncodingVector(
  379. UFOStruct *pUFObj,
  380. const UFLGlyphsInfo *pGlyphs,
  381. short int sStart,
  382. short int sEnd
  383. )
  384. {
  385. const static char encodingBegin[] = " findfont /Encoding get";
  386. const static char encodingEnd[] = "pop";
  387. UFLHANDLE stream = pUFObj->pUFL->hOut;
  388. UFLErrCode retVal = kNoErr;
  389. short i;
  390. /*
  391. * both start and end must be in the range of 0 to sCount.
  392. */
  393. if ((sStart < 0) || (sEnd > pGlyphs->sCount) || (sStart >= sEnd))
  394. return kErrInvalidArg;
  395. retVal = StrmPutString(stream, "/");
  396. if (kNoErr == retVal)
  397. retVal = StrmPutString(stream, pUFObj->pszFontName);
  398. if (kNoErr == retVal)
  399. retVal = StrmPutStringEOL(stream, encodingBegin);
  400. for (i = sStart; (retVal == kNoErr) && (i < sEnd); ++i)
  401. {
  402. if ((0 == pUFObj->pUFL->bDLGlyphTracking)
  403. || (pGlyphs->pCharIndex == nil)
  404. || !IS_GLYPH_SENT(pUFObj->pUpdatedEncoding, pGlyphs->pCharIndex[i]))
  405. {
  406. char *pGoodName;
  407. char buf[16];
  408. unsigned short wIndex = (unsigned short)(pGlyphs->pGlyphIndices[i] & 0x0000FFFF); /* LOWord is the GID. */
  409. FindGlyphName(pUFObj, pGlyphs, i, wIndex, &pGoodName);
  410. if (pGlyphs->pCharIndex)
  411. UFLsprintf(buf, CCHOF(buf), "dup %d /", pGlyphs->pCharIndex[i]);
  412. else
  413. UFLsprintf(buf, CCHOF(buf), "dup %d /", i);
  414. retVal = StrmPutString(stream, buf);
  415. if (retVal == kNoErr)
  416. retVal = StrmPutString(stream, pGoodName);
  417. if (retVal == kNoErr)
  418. retVal = StrmPutStringEOL(stream, " put");
  419. if ((retVal == kNoErr) && pGlyphs->pCharIndex)
  420. SET_GLYPH_SENT_STATUS(pUFObj->pUpdatedEncoding, pGlyphs->pCharIndex[i]);
  421. }
  422. }
  423. if (kNoErr == retVal)
  424. retVal = StrmPutStringEOL(stream, encodingEnd);
  425. return retVal;
  426. }
  427. UFLErrCode
  428. UpdateCodeInfo(
  429. UFOStruct *pUFObj,
  430. const UFLGlyphsInfo *pGlyphs,
  431. UFLBool bT3T32Font
  432. )
  433. {
  434. UFLHANDLE stream = pUFObj->pUFL->hOut;
  435. UFLGlyphID *glyphs = pGlyphs->pGlyphIndices;
  436. UFLErrCode retVal = kNoErr;
  437. UFLBool bHeaderSent = 0; /* GoodName */
  438. UFLBool bUniCodeCmap = 0;
  439. UFLBool bCheckCmap = 0;
  440. char glyphNameID[64], strmbuf[256];
  441. short i;
  442. if (GetTablesFromTTFont(pUFObj))
  443. bUniCodeCmap = TTcmap_IS_UNICODE(pUFObj->pAFont->cmapFormat);
  444. if ((pGlyphs->pCode && bUniCodeCmap) || (pGlyphs->pCode == NULL))
  445. bCheckCmap = 1;
  446. if (pGlyphs->pCode)
  447. bUniCodeCmap = 1;
  448. for (i = 0; (retVal == kNoErr) && (i < pGlyphs->sCount); ++i)
  449. {
  450. unsigned short unicode = 0; /* GoodName */
  451. unsigned short wIndex = (unsigned short)(glyphs[i] & 0x0000FFFF); /* LOWord is the GlyphID. */
  452. if (wIndex >= UFO_NUM_GLYPHS(pUFObj))
  453. continue;
  454. if (IS_GLYPH_SENT( pUFObj->pAFont->pCodeGlyphs, wIndex))
  455. continue;
  456. if (IS_TYPE42CID(pUFObj->lDownloadFormat) || IS_CFFCID(pUFObj->lDownloadFormat))
  457. {
  458. UFLsprintf(glyphNameID, CCHOF(glyphNameID), "%d ", wIndex);
  459. if (pGlyphs->pCode && pGlyphs->pCode[i])
  460. unicode = pGlyphs->pCode[i];
  461. else if (bCheckCmap)
  462. ParseTTTablesForUnicode(pUFObj,
  463. wIndex, &unicode,
  464. 1, DTT_parseAllTables);
  465. }
  466. else
  467. {
  468. char *pGoodName;
  469. FindGlyphName(pUFObj, pGlyphs, i, wIndex, &pGoodName);
  470. UFLsprintf(glyphNameID, CCHOF(glyphNameID), "/%s ", pGoodName);
  471. if (pGlyphs->pCode && pGlyphs->pCode[i])
  472. unicode = pGlyphs->pCode[i];
  473. else if (bCheckCmap)
  474. {
  475. if (bUniCodeCmap)
  476. ParseTTTablesForUnicode(pUFObj,
  477. wIndex, &unicode,
  478. 1, DTT_parseMoreGSUBOnly);
  479. else
  480. ParseTTTablesForUnicode(pUFObj,
  481. wIndex, &unicode,
  482. 1, DTT_parseAllTables);
  483. }
  484. }
  485. if (unicode && !bHeaderSent)
  486. {
  487. bHeaderSent = 1;
  488. /*
  489. * Output "/FontName /Font" or "/CIDFontResource /CIDFont"
  490. */
  491. if (IS_TYPE42CID(pUFObj->lDownloadFormat))
  492. {
  493. /*
  494. * If CID-keyed font, then append "CID" to the CIDFont name.
  495. */
  496. if (IS_TYPE42CID_KEYEDFONT(pUFObj->lDownloadFormat))
  497. {
  498. T42FontStruct *pFont = (T42FontStruct *)pUFObj->pAFont->hFont;
  499. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s%s", pFont->info.CIDFontName, gcidSuffix[0]);
  500. }
  501. else
  502. {
  503. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s", pUFObj->pszFontName);
  504. }
  505. if (kNoErr == retVal)
  506. retVal = StrmPutString(stream, strmbuf);
  507. if (kNoErr == retVal)
  508. retVal = StrmPutString(stream, " /CIDFont");
  509. }
  510. else if (IS_CFFCID(pUFObj->lDownloadFormat))
  511. {
  512. CFFFontStruct *pFont = (CFFFontStruct *)pUFObj->pAFont->hFont;
  513. if (pFont->info.type1)
  514. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s", pFont->info.baseName);
  515. else
  516. {
  517. /* Reuse vifinfo.nPlatformID to fix #507985. */
  518. if (pUFObj->vpfinfo.nPlatformID == kUFLVPFPlatformID9x)
  519. {
  520. if (pUFObj->lDownloadFormat == kCFFCID_H)
  521. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s", CFFPREFIX_H, pFont->info.baseName);
  522. else
  523. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s", CFFPREFIX_V, pFont->info.baseName);
  524. }
  525. else
  526. UFLsprintf(strmbuf, CCHOF(strmbuf), "/%s%s", CFFPREFIX, pFont->info.baseName);
  527. }
  528. if (kNoErr == retVal)
  529. retVal = StrmPutString(stream, strmbuf);
  530. if (kNoErr == retVal)
  531. retVal = StrmPutString(stream, " /CIDFont");
  532. }
  533. else
  534. {
  535. if (bT3T32Font) /* GoodName */
  536. StrmPutStringEOL(stream, "Is2016andT32? not {");
  537. UFLsprintf(strmbuf, CCHOF(strmbuf), " /%s", pUFObj->pszFontName);
  538. if (kNoErr == retVal)
  539. retVal = StrmPutString(stream, strmbuf);
  540. if (kNoErr == retVal)
  541. retVal = StrmPutString(stream, " /Font");
  542. }
  543. if (kNoErr == retVal)
  544. {
  545. if (bUniCodeCmap)
  546. retVal = StrmPutStringEOL(stream, " G2UBegin");
  547. else
  548. {
  549. retVal = StrmPutStringEOL(stream, " G2CCBegin");
  550. if (pUFObj && pUFObj->pAFont)
  551. {
  552. if (TTcmap_IS_J_CMAP(pUFObj->pAFont->cmapFormat))
  553. retVal = StrmPutStringEOL(stream, "/WinCharSet 128 def");
  554. else if (TTcmap_IS_CS_CMAP(pUFObj->pAFont->cmapFormat))
  555. retVal = StrmPutStringEOL(stream, "/WinCharSet 134 def");
  556. else if (TTcmap_IS_CT_CMAP(pUFObj->pAFont->cmapFormat))
  557. retVal = StrmPutStringEOL(stream, "/WinCharSet 136 def");
  558. else if (TTcmap_IS_K_CMAP(pUFObj->pAFont->cmapFormat))
  559. retVal = StrmPutStringEOL(stream, "/WinCharSet 129 def");
  560. }
  561. }
  562. }
  563. }
  564. if (unicode)
  565. {
  566. if (retVal == kNoErr)
  567. retVal = StrmPutString(stream, glyphNameID);
  568. /*
  569. * support only one CodePoint per glyph.
  570. */
  571. UFLsprintf(strmbuf, CCHOF(strmbuf), "<%04X> def", unicode);
  572. if (kNoErr == retVal)
  573. retVal = StrmPutStringEOL(stream, strmbuf);
  574. SET_GLYPH_SENT_STATUS(pUFObj->pAFont->pCodeGlyphs, wIndex);
  575. }
  576. }
  577. if ((kNoErr == retVal) && bHeaderSent)
  578. {
  579. retVal = StrmPutStringEOL(stream, "G2UEnd"); /* end for UV or CC */
  580. if (bT3T32Font) /* GoodName */
  581. StrmPutStringEOL(stream, "} if");
  582. }
  583. return retVal;
  584. }
  585. UFLErrCode
  586. ReEncodePSFont(
  587. const UFOStruct *pUFObj,
  588. const char *pszNewFontName,
  589. const char *pszNewEncodingName
  590. )
  591. {
  592. const static char copyFontBegin[] = " findfont dup maxlength dict begin "
  593. "{1 index /FID ne {def} {pop pop} ifelse} forall";
  594. const static char copyFontEnd[] = " currentdict end definefont pop";
  595. UFLHANDLE stream = pUFObj->pUFL->hOut;
  596. UFLErrCode retVal = kNoErr;
  597. retVal = StrmPutString(stream, "/");
  598. if (kNoErr == retVal)
  599. retVal = StrmPutString(stream, pszNewFontName);
  600. if (kNoErr == retVal)
  601. retVal = StrmPutString(stream, "/");
  602. if (kNoErr == retVal)
  603. retVal = StrmPutString(stream, pUFObj->pszFontName);
  604. if (kNoErr == retVal)
  605. retVal = StrmPutStringEOL(stream, copyFontBegin);
  606. /*
  607. * Put a new encoding vectory here.
  608. */
  609. if (kNoErr == retVal)
  610. retVal = StrmPutString(stream, "/Encoding ");
  611. if (kNoErr == retVal)
  612. {
  613. if (pszNewEncodingName == nil)
  614. retVal = StrmPutString(stream, gnotdefArray);
  615. else
  616. retVal = StrmPutString(stream, pszNewEncodingName);
  617. }
  618. if (retVal == kNoErr)
  619. retVal = StrmPutStringEOL(stream, " def");
  620. if (kNoErr == retVal)
  621. retVal = StrmPutStringEOL(stream, copyFontEnd);
  622. return retVal;
  623. }
  624. UFLErrCode
  625. RecomposefontCIDFont(
  626. const UFOStruct *pUFOSrc,
  627. UFOStruct *pUFObj
  628. )
  629. {
  630. char *pHostFontName;
  631. UFLErrCode retVal;
  632. HostFontValidateUFO(pUFObj, &pHostFontName);
  633. if (IS_TYPE42CID_KEYEDFONT(pUFObj->lDownloadFormat))
  634. retVal = T42CreateBaseFont(pUFObj, nil, nil, 0, pHostFontName);
  635. else
  636. retVal = CFFCreateBaseFont(pUFObj, nil, nil, pHostFontName);
  637. return retVal;
  638. }
  639. UFLErrCode
  640. NewFont(
  641. UFOStruct *pUFObj,
  642. unsigned long dwSize,
  643. const long cGlyphs
  644. )
  645. {
  646. UFLErrCode retVal = kNoErr;
  647. if (pUFObj->pAFont == nil)
  648. {
  649. retVal = kErrOutOfMemory;
  650. pUFObj->pAFont = (AFontStruct*)(UFOHandle)UFLNewPtr(pUFObj->pMem, sizeof (AFontStruct));
  651. if (pUFObj->pAFont)
  652. {
  653. pUFObj->pAFont->hFont = (UFOHandle)UFLNewPtr(pUFObj->pMem, dwSize);
  654. if (pUFObj->pAFont->hFont)
  655. {
  656. /*
  657. * Allocate the space for both pDownloadedGlyphs, pVMGlyphs and
  658. * pCodeGlyphs at the same time.
  659. */
  660. pUFObj->pAFont->pDownloadedGlyphs =
  661. (unsigned char*)UFLNewPtr(pUFObj->pMem, GLYPH_SENT_BUFSIZE(cGlyphs) * 3);
  662. if (pUFObj->pAFont->pDownloadedGlyphs != nil)
  663. {
  664. retVal = kNoErr;
  665. /*
  666. * Initialize this array - currently nothing is downloaded.
  667. */
  668. pUFObj->pAFont->pVMGlyphs =
  669. (unsigned char*)pUFObj->pAFont->pDownloadedGlyphs + GLYPH_SENT_BUFSIZE(cGlyphs);
  670. pUFObj->pAFont->pCodeGlyphs =
  671. (unsigned char*)(unsigned char*)pUFObj->pAFont->pVMGlyphs + GLYPH_SENT_BUFSIZE(cGlyphs);
  672. }
  673. else
  674. {
  675. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->hFont);
  676. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont);
  677. pUFObj->pAFont = nil;
  678. }
  679. }
  680. else
  681. {
  682. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont);
  683. pUFObj->pAFont = nil;
  684. }
  685. }
  686. }
  687. if (pUFObj->pAFont != nil)
  688. AFONT_AddRef(pUFObj->pAFont);
  689. return retVal;
  690. }
  691. void
  692. vDeleteFont(
  693. UFOStruct *pUFObj
  694. )
  695. {
  696. if (pUFObj->pAFont != nil)
  697. {
  698. /*
  699. * Decrease RefCount.
  700. */
  701. AFONT_Release(pUFObj->pAFont);
  702. if (AFONT_RefCount(pUFObj->pAFont) == 0)
  703. {
  704. /*
  705. * Free format (Type1/3/42/cff) dependent shared data.
  706. */
  707. pUFObj->pfnCleanUp(pUFObj);
  708. /*
  709. * Free Common shared data.
  710. */
  711. if (pUFObj->pAFont->hFont)
  712. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->hFont);
  713. if (pUFObj->pAFont->Xuid.pXUID)
  714. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->Xuid.pXUID);
  715. if (pUFObj->pAFont->pDownloadedGlyphs)
  716. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->pDownloadedGlyphs);
  717. if (pUFObj->pAFont->pTTpost)
  718. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->pTTpost);
  719. /* GOODNAME */
  720. if (pUFObj->pAFont->pTTcmap && pUFObj->pAFont->hascmap)
  721. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->pTTcmap);
  722. if (pUFObj->pAFont->pTTmort && pUFObj->pAFont->hasmort)
  723. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->pTTmort);
  724. if (pUFObj->pAFont->pTTGSUB && pUFObj->pAFont->hasGSUB)
  725. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont->pTTGSUB);
  726. /* GOODNAME */
  727. UFLDeletePtr(pUFObj->pMem, pUFObj->pAFont);
  728. pUFObj->pAFont = nil;
  729. }
  730. }
  731. }
  732. UFOStruct *
  733. CopyFont(
  734. const UFOStruct *pUFObjFrom,
  735. const UFLRequest* pRequest
  736. )
  737. {
  738. UFLErrCode retVal = kNoErr;
  739. short sNameLen = 0;
  740. short sEncodeLen = 0;
  741. const char *pszNewFontName = pRequest->pszFontName;
  742. const char *pszNewEncodingName = pRequest->pszEncodeName;
  743. long fontStructSize, maxGlyphs;
  744. UFOStruct *pUFObjTo;
  745. /*
  746. * cannot/shouldnot copy a font if it is not created yet - prevent
  747. * "courier" in the way.
  748. */
  749. if (pUFObjFrom->flState < kFontHeaderDownloaded)
  750. return nil;
  751. if ((pszNewFontName == nil) || (pszNewFontName[0] == '\0'))
  752. return nil;
  753. /*
  754. * Determine downloaded font type.
  755. */
  756. switch (pUFObjFrom->ufoType)
  757. {
  758. case UFO_CFF:
  759. fontStructSize = sizeof (CFFFontStruct);
  760. maxGlyphs = ((CFFFontStruct *)pUFObjFrom->pAFont->hFont)->info.fData.maxGlyphs;
  761. break;
  762. case UFO_TYPE1:
  763. fontStructSize = sizeof (TTT1FontStruct);
  764. maxGlyphs = ((TTT1FontStruct *)pUFObjFrom->pAFont->hFont)->info.fData.maxGlyphs;
  765. break;
  766. case UFO_TYPE42:
  767. fontStructSize = sizeof (T42FontStruct);
  768. maxGlyphs = ((T42FontStruct *)pUFObjFrom->pAFont->hFont)->info.fData.maxGlyphs;
  769. break;
  770. case UFO_TYPE3:
  771. fontStructSize = sizeof (TTT3FontStruct);
  772. maxGlyphs = ((TTT3FontStruct *)pUFObjFrom->pAFont->hFont)->info.fData.maxGlyphs;
  773. break;
  774. default:
  775. return nil;
  776. }
  777. /*
  778. * Allocate memory for the UFOStruct, and...
  779. */
  780. pUFObjTo = (UFOStruct *)UFLNewPtr(pUFObjFrom->pMem, sizeof (UFOStruct));
  781. if (pUFObjTo == 0)
  782. return nil;
  783. /*
  784. * ...do a shallow copy on UFOStruct level.
  785. */
  786. memcpy(pUFObjTo, pUFObjFrom, sizeof (UFOStruct));
  787. /*
  788. * This NewFont does AddRef only.
  789. */
  790. if (NewFont(pUFObjTo, fontStructSize, maxGlyphs) != kNoErr)
  791. {
  792. /* This vDeleteFont does Release only. */
  793. vDeleteFont(pUFObjTo);
  794. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo);
  795. return nil;
  796. }
  797. /*
  798. * Now allocate for non-shared data.
  799. */
  800. pUFObjTo->pszFontName = nil;
  801. pUFObjTo->pszEncodeName = nil;
  802. pUFObjTo->pUpdatedEncoding = nil;
  803. /*
  804. * Allocate a buffer to hold both FontName and EncodeName. They will be
  805. * freed in UFOCleanUpData().
  806. */
  807. sNameLen = UFLstrlen(pszNewFontName) + 1; /* Extra 1 for NULL. */
  808. if (pszNewEncodingName)
  809. sEncodeLen = UFLstrlen(pszNewEncodingName) + 1;
  810. pUFObjTo->pszFontName = (char *)UFLNewPtr(pUFObjTo->pMem, sNameLen + sEncodeLen);
  811. if (pUFObjTo->pszFontName != nil)
  812. {
  813. StringCchCopyA(pUFObjTo->pszFontName, sNameLen / sizeof(char), pszNewFontName);
  814. if (pszNewEncodingName)
  815. {
  816. pUFObjTo->pszEncodeName = pUFObjTo->pszFontName + sNameLen;
  817. StringCchCopyA(pUFObjTo->pszEncodeName, sEncodeLen / sizeof(char), pszNewEncodingName);
  818. }
  819. }
  820. /* pszFontName should be ready/allocated - if not, cannot continue. */
  821. if ((pUFObjTo->pszFontName == nil) || (pUFObjTo->pszFontName[0] == '\0'))
  822. {
  823. /* This vDeleteFont does Release only. */
  824. vDeleteFont(pUFObjTo);
  825. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pszFontName);
  826. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo);
  827. return nil;
  828. }
  829. /*
  830. * BUT we need different EncodingVector for this newNamed copy if we need
  831. * to update it.
  832. */
  833. if ((pUFObjTo->pszEncodeName == nil) || (pUFObjTo->pszEncodeName[0] == '\0'))
  834. {
  835. pUFObjTo->pUpdatedEncoding = (unsigned char *)UFLNewPtr(pUFObjTo->pMem, GLYPH_SENT_BUFSIZE(256));
  836. }
  837. else
  838. {
  839. /* The encoding is supplied and so are the glyph/char names later. */
  840. pUFObjTo->pUpdatedEncoding = nil;
  841. }
  842. /*
  843. * Client's private data should be non-shared.
  844. */
  845. pUFObjTo->hClientData = pRequest->hData;
  846. /*
  847. * Setup Type 42 and CFF CID specific non-shared data.
  848. */
  849. if (IS_TYPE42CID_KEYEDFONT(pRequest->lDownloadFormat)
  850. || IS_CFFCID(pRequest->lDownloadFormat))
  851. {
  852. pUFObjTo->lDownloadFormat = pRequest->lDownloadFormat;
  853. if (IS_CFFCID(pRequest->lDownloadFormat))
  854. {
  855. /*
  856. * Need one more deeper level copy.
  857. */
  858. CFFFontStruct *pFont = (CFFFontStruct *)UFLNewPtr(pUFObjTo->pMem, sizeof (CFFFontStruct));
  859. if (pFont)
  860. {
  861. /*
  862. * Copy from the From CFFFontStruct object. This is a shared
  863. * object.
  864. */
  865. *pFont = *((CFFFontStruct *)pUFObjFrom->pAFont->hFont);
  866. /*
  867. * Initialization of UFLCFFFontInfo.ppFontData field is
  868. * necessary. Note that on this request only,
  869. UFLRequest.hFontInfo has the value for the field.
  870. */
  871. pFont->info.ppFontData = (void PTR_PREFIX **)pRequest->hFontInfo;
  872. /*
  873. * Set this object to its UFO object.
  874. */
  875. pUFObjTo->pAFont->hFont = (UFOHandle)pFont;
  876. }
  877. else
  878. {
  879. /* This vDeleteFont does Release only. */
  880. vDeleteFont(pUFObjTo);
  881. if (pFont)
  882. UFLDeletePtr(pUFObjTo->pMem, pFont);
  883. if (pUFObjTo->pszEncodeName)
  884. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pszEncodeName);
  885. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pszFontName);
  886. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo);
  887. return nil;
  888. }
  889. }
  890. /*
  891. * Put this UFO object into a special font initialization state
  892. * kFontInit2.
  893. */
  894. pUFObjTo->flState = kFontInit2;
  895. }
  896. /*
  897. * Reencode the font, or re-composefont a CID-keyed font in different
  898. * writing direction.
  899. */
  900. if (IS_TYPE42CID_KEYEDFONT(pRequest->lDownloadFormat)
  901. || IS_CFFCID(pRequest->lDownloadFormat))
  902. retVal = RecomposefontCIDFont(pUFObjFrom, pUFObjTo);
  903. else
  904. retVal = ReEncodePSFont(pUFObjFrom, pUFObjTo->pszFontName, pUFObjTo->pszEncodeName);
  905. if (kNoErr != retVal)
  906. {
  907. /* This vDeleteFont does Release only. */
  908. vDeleteFont(pUFObjTo);
  909. if (IS_CFFCID(pRequest->lDownloadFormat))
  910. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pAFont->hFont);
  911. if (pUFObjTo->pUpdatedEncoding)
  912. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pUpdatedEncoding);
  913. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo->pszFontName);
  914. UFLDeletePtr(pUFObjTo->pMem, pUFObjTo);
  915. pUFObjTo = nil;
  916. }
  917. return pUFObjTo;
  918. }
  919. void
  920. VSetNumGlyphs(
  921. UFOStruct *pUFO,
  922. unsigned long cNumGlyphs
  923. )
  924. {
  925. TTT1FontStruct *pFont = (TTT1FontStruct *) pUFO->pAFont->hFont;
  926. pFont->info.fData.cNumGlyphs = cNumGlyphs;
  927. return;
  928. }
  929. /* Fix bug 274008 */
  930. UFLBool
  931. ValidGlyphName(
  932. const UFLGlyphsInfo *pGlyphs,
  933. short i, /* ANSI index */
  934. unsigned short wIndex, /* Glyph Index */
  935. char *pGoodName
  936. )
  937. {
  938. UFLGlyphID *glyphs = pGlyphs->pGlyphIndices;
  939. if (i < pGlyphs->sCount)
  940. {
  941. if (UFLstrcmp(pGoodName, Notdef) == 0)
  942. {
  943. if (wIndex != (unsigned short)(glyphs[0] & 0x0000FFFF))
  944. return 0;
  945. }
  946. else if (UFLstrcmp(pGoodName, UFLSpace) == 0)
  947. {
  948. if (wIndex != (unsigned short)(glyphs[0x20] & 0x0000FFFF))
  949. return 0;
  950. }
  951. else if (UFLstrcmp(pGoodName, Hyphen) == 0)
  952. {
  953. if (wIndex != (unsigned short)(glyphs[0x2d] & 0x0000FFFF))
  954. return 0;
  955. }
  956. else if (UFLstrcmp(pGoodName, Bullet) == 0)
  957. {
  958. if (wIndex != (unsigned short)(glyphs[0x95] & 0x0000FFFF))
  959. return 0;
  960. }
  961. }
  962. return true;
  963. }
  964. UFLBool
  965. HostFontValidateUFO(
  966. UFOStruct *pUFObj,
  967. char **ppHostFontName
  968. )
  969. {
  970. /*
  971. * Check %hostfont% status.
  972. * %hostfont% printing is allowed when its PostScript font name
  973. * (PlatformID x/NameID 6) string in 'name' table is available.
  974. */
  975. UFLBool bResult = 0;
  976. unsigned long ulSize;
  977. if (ppHostFontName == nil)
  978. {
  979. HOSTFONT_INVALIDATE_UFO(pUFObj);
  980. return 0;
  981. }
  982. if (HOSTFONT_IS_VALID_UFO_HFDH(pUFObj))
  983. {
  984. if (pUFObj->ufoType == UFO_TYPE42)
  985. bResult = HOSTFONT_GETNAME(pUFObj, ppHostFontName, &ulSize, pUFObj->pFData->fontIndex);
  986. else
  987. bResult = HOSTFONT_GETNAME(pUFObj, ppHostFontName, &ulSize, 0);
  988. if (bResult)
  989. bResult = HOSTFONT_ISALLOWED(pUFObj, *ppHostFontName);
  990. if (bResult)
  991. {
  992. HOSTFONT_SAVE_CURRENTNAME(pUFObj, *ppHostFontName);
  993. HOSTFONT_VALIDATE_UFO(pUFObj);
  994. }
  995. else
  996. {
  997. HOSTFONT_SAVE_CURRENTNAME(pUFObj, *ppHostFontName);
  998. HOSTFONT_INVALIDATE_UFO(pUFObj);
  999. }
  1000. }
  1001. else
  1002. HOSTFONT_INVALIDATE_UFO(pUFObj);
  1003. return bResult;
  1004. }