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.

1879 lines
52 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pfeobj.cxx
  3. *
  4. * Non-inline methods for physical font entry objects.
  5. *
  6. * Created: 30-Oct-1990 09:32:48
  7. * Author: Gilman Wong [gilmanw]
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. // #pragma warning (disable: 4509)
  12. #include "precomp.hxx"
  13. #include "flhack.hxx"
  14. BOOL bExtendGlyphSet(FD_GLYPHSET **ppfdgIn, FD_GLYPHSET **ppfdgOut);
  15. INT
  16. __cdecl CompareRoutine(WCHAR *pwc1, WCHAR *pwc2)
  17. {
  18. return(*pwc1-*pwc2);
  19. }
  20. /******************************Public*Routine******************************\
  21. *
  22. * ULONG cComputeGISET
  23. *
  24. * similar to cComputeGlyphSet in mapfile.c, computes the number of
  25. *(_wcsicmp(pwszFaceName, pFaceName) == 0)* distinct glyph handles in a font and the number of runs, ie. number of
  26. * contiguous ranges of glyph handles
  27. *
  28. *
  29. * History:
  30. * 03-Aug-1995 -by- Bodin Dresevic [BodinD]
  31. * Wrote it.
  32. \**************************************************************************/
  33. ULONG cComputeGISET (
  34. USHORT * pgi,
  35. ULONG cgi,
  36. GISET * pgiset,
  37. ULONG cGiRuns
  38. )
  39. {
  40. ULONG iRun, iFirst, iFirstNext;
  41. ULONG cgiTotal = 0, cgiRun;
  42. // now compute cRuns if pgiset == 0 and fill the glyphset if pgiset != 0
  43. for (iFirst = 0, iRun = 0; iFirst < cgi; iRun++, iFirst = iFirstNext)
  44. {
  45. // find iFirst corresponding to the next range.
  46. for (iFirstNext = iFirst + 1; iFirstNext < cgi; iFirstNext++)
  47. {
  48. if ((pgi[iFirstNext] - pgi[iFirstNext - 1]) > 1)
  49. break;
  50. }
  51. // note that this line here covers the case when there are repetitions
  52. // in the pgi array.
  53. cgiRun = pgi[iFirstNext-1] - pgi[iFirst] + 1;
  54. cgiTotal += cgiRun;
  55. if (pgiset != NULL)
  56. {
  57. pgiset->agirun[iRun].giLow = pgi[iFirst];
  58. pgiset->agirun[iRun].cgi = (USHORT) cgiRun;
  59. }
  60. }
  61. // store results if need be
  62. if (pgiset != NULL)
  63. {
  64. ASSERTGDI(iRun == cGiRuns, "gdisrv! iRun != cRun\n");
  65. pgiset->cGiRuns = cGiRuns;
  66. // init the sum before entering the loop
  67. pgiset->cgiTotal = cgiTotal;
  68. }
  69. return iRun;
  70. }
  71. /******************************Public*Routine******************************\
  72. *
  73. * bComputeGISET, similar to ComputeGlyphSet, only for gi's
  74. *
  75. * History:
  76. * 03-Aug-1995 -by- Bodin Dresevic [BodinD]
  77. * Wrote it.
  78. \**************************************************************************/
  79. #include "stdlib.h"
  80. VOID vSortPlacebo
  81. (
  82. USHORT *pwc,
  83. ULONG cChar
  84. )
  85. {
  86. ULONG i;
  87. for (i = 1; i < cChar; i++)
  88. {
  89. // upon every entry to this loop the array 0,1,..., (i-1) will be sorted
  90. INT j;
  91. WCHAR wcTmp = pwc[i];
  92. for (j = i - 1; (j >= 0) && (pwc[j] > wcTmp); j--)
  93. {
  94. pwc[j+1] = pwc[j];
  95. }
  96. pwc[j+1] = wcTmp;
  97. }
  98. }
  99. BOOL bComputeGISET(IFIMETRICS * pifi, PFE * ppfe, GISET **ppgiset)
  100. {
  101. BOOL bRet = TRUE;
  102. *ppgiset = NULL;
  103. GISET *pgiset;
  104. PFEOBJ pfeObj(ppfe);
  105. PFFOBJ pffo(pfeObj.pPFF());
  106. PFD_GLYPHSET pfdg = NULL;
  107. BOOL bTT = (BOOL)(pffo.hdev() == (HDEV) gppdevTrueType);
  108. if (!bTT)
  109. {
  110. if (!(pfdg = pfeObj.pfdg()))
  111. {
  112. return FALSE;
  113. }
  114. }
  115. if (bTT || (pfdg->flAccel & (GS_16BIT_HANDLES | GS_8BIT_HANDLES)))
  116. {
  117. // first check if this is an accelerated case where handles are the same
  118. // as glyph indicies
  119. ULONG cig = 0;
  120. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, cig))
  121. {
  122. cig = ((IFIEXTRA *)(pifi + 1))->cig;
  123. }
  124. if (bTT && (cig == 0)) // most likely a corrupt font
  125. {
  126. return FALSE;
  127. }
  128. if (cig)
  129. {
  130. // one run only from zero to (cig-1);
  131. if (pgiset = (GISET*)PALLOCMEM(offsetof(GISET,agirun) + 1 * sizeof(GIRUN),'slgG'))
  132. {
  133. // now fill in the array of runs
  134. pgiset->cgiTotal = cig;
  135. pgiset->cGiRuns = 1;
  136. pgiset->agirun[0].giLow = 0;
  137. pgiset->agirun[0].cgi = (USHORT)cig;
  138. // we are done now
  139. *ppgiset = pgiset;
  140. }
  141. else
  142. {
  143. bRet = FALSE;
  144. }
  145. }
  146. else
  147. {
  148. // one of the goofy fonts, we will do as before
  149. USHORT *pgi, *pgiBegin;
  150. // aloc tmp buffer to contain glyph handles of all glyphs in the font
  151. if (pgiBegin = (USHORT*)PALLOCMEM(pfdg->cGlyphsSupported * sizeof(USHORT),'slgG'))
  152. {
  153. pgi = pgiBegin;
  154. for (ULONG iRun = 0; iRun < pfdg->cRuns; iRun++)
  155. {
  156. HGLYPH *phg, *phgEnd;
  157. phg = pfdg->awcrun[iRun].phg;
  158. if (phg) // non unicode handles
  159. {
  160. phgEnd = phg + pfdg->awcrun[iRun].cGlyphs;
  161. for ( ; phg < phgEnd; pgi++, phg++)
  162. *pgi = (USHORT)(*phg);
  163. }
  164. else // unicode handles
  165. {
  166. USHORT wcLo = pfdg->awcrun[iRun].wcLow;
  167. USHORT wcHi = wcLo + pfdg->awcrun[iRun].cGlyphs - 1;
  168. for ( ; wcLo <= wcHi; wcLo++, phg++)
  169. *pgi = wcLo;
  170. }
  171. }
  172. // now sort the array of glyph indicies. This array will be mostly
  173. // sorted so that our algorithm is efficient
  174. qsort((void*)pgiBegin, pfdg->cGlyphsSupported, sizeof(WORD),
  175. (int (__cdecl *)(const void *, const void *))CompareRoutine);
  176. // once the array is sorted we can easily compute the number of giRuns
  177. ULONG cGiRun = cComputeGISET(pgiBegin, pfdg->cGlyphsSupported, NULL, 0);
  178. if (pgiset = (GISET*)PALLOCMEM(offsetof(GISET,agirun) + cGiRun * sizeof(GIRUN),'slgG'))
  179. {
  180. // now fill in the array of runs
  181. cComputeGISET(pgiBegin, pfdg->cGlyphsSupported, pgiset, cGiRun);
  182. *ppgiset = pgiset;
  183. }
  184. else
  185. {
  186. bRet = FALSE;
  187. }
  188. VFREEMEM(pgiBegin);
  189. }
  190. else
  191. {
  192. bRet = FALSE;
  193. }
  194. }
  195. }
  196. if (!bTT)
  197. pfeObj.vFreepfdg();
  198. return bRet;
  199. }
  200. //
  201. // This is used to give ppfe->pkp something to point to if a driver
  202. // error occurs. That way, we won't waste time calling the driver
  203. // again.
  204. //
  205. FD_KERNINGPAIR gkpNothing = { 0, 0, 0 };
  206. static ULONG ulTimerPFE = 0;
  207. /******************************Public*Routine******************************\
  208. * VOID PFEOBJ::vDelete() *
  209. * *
  210. * Destroy the PFE physical font entry object. *
  211. * *
  212. * History: *
  213. * 30-Oct-1990 -by- Gilman Wong [gilmanw] *
  214. * Wrote it. *
  215. \**************************************************************************/
  216. VOID PFEOBJ::vDelete()
  217. {
  218. PDEVOBJ pdo(ppfe->pPFF->hdev);
  219. // Save driver allocated resources in PFECLEANUP so that we can later
  220. // call the driver to free them.
  221. if ((ppfe->pifi->jWinCharSet == SYMBOL_CHARSET) &&
  222. (ppfe->pfdg != NULL) &&
  223. (ppfe->pfdg->flAccel & GS_EXTENDED))
  224. {
  225. VFREEMEM(ppfe->pfdg);
  226. }
  227. else
  228. {
  229. if ((ppfe->pfdg != NULL) && PPFNVALID(pdo,Free))
  230. {
  231. pdo.Free(ppfe->pfdg, ppfe->idfdg);
  232. }
  233. }
  234. if (PPFNVALID(pdo,Free))
  235. {
  236. pdo.Free(ppfe->pifi, ppfe->idifi);
  237. if (ppfe->pkp != &gkpNothing)
  238. {
  239. pdo.Free(ppfe->pkp , ppfe->idkp );
  240. }
  241. }
  242. ppfe->pfdg = NULL;
  243. ppfe->pifi = NULL;
  244. ppfe->pkp = NULL;
  245. if (ppfe->pgiset)
  246. {
  247. VFREEMEM(ppfe->pgiset);
  248. ppfe->pgiset = NULL;
  249. }
  250. // Free object memory and invalidate pointer.
  251. ppfe = PPFENULL;
  252. }
  253. /******************************Public*Routine******************************\
  254. * dpNtmi()
  255. *
  256. * offset to NTMW_INTERNAL within ENUMFONTDATAW, needed in enumeration
  257. *
  258. * History:
  259. * 19-Nov-1996 -by- Bodin Dresevic [BodinD]
  260. * Wrote it.
  261. \**************************************************************************/
  262. ULONG PFEOBJ::dpNtmi()
  263. {
  264. ULONG dpRet = DP_NTMI0;
  265. if (ppfe->pifi->flInfo & FM_INFO_TECH_MM)
  266. {
  267. PTRDIFF dpDesVec = 0;
  268. DESIGNVECTOR *pdvSrc;
  269. if (ppfe->pifi->cjIfiExtra > offsetof(IFIEXTRA, dpDesignVector))
  270. {
  271. dpDesVec = ((IFIEXTRA *)(ppfe->pifi + 1))->dpDesignVector;
  272. pdvSrc = (DESIGNVECTOR *)((BYTE *)ppfe->pifi + dpDesVec);
  273. dpRet += (pdvSrc->dvNumAxes * sizeof(LONG));
  274. }
  275. else
  276. {
  277. DbgPrint("Test it %d %d \n", ppfe->pifi->cjIfiExtra, offsetof(IFIEXTRA, dpDesignVector));
  278. ASSERTGDI(dpDesVec, "dpDesignVector == 0 for mm instance\n");
  279. }
  280. }
  281. return dpRet;
  282. }
  283. /******************************Public*Routine******************************\
  284. *
  285. * IsAnyCharsetDbcs
  286. *
  287. * Does this font support any DBCS charset?
  288. *
  289. * History:
  290. * 22-Jun-1998 -by- Bodin Dresevic [BodinD]
  291. * Wrote it.
  292. \**************************************************************************/
  293. extern "C" BOOL IsAnyCharsetDbcs(IFIMETRICS *pifi)
  294. {
  295. BOOL bRet = FALSE;
  296. if (IS_ANY_DBCS_CHARSET(pifi->jWinCharSet))
  297. return TRUE;
  298. if (pifi->dpCharSets)
  299. {
  300. BYTE *aCharSets = (BYTE *)pifi + pifi->dpCharSets;
  301. for ( ;*aCharSets != DEFAULT_CHARSET; aCharSets++)
  302. {
  303. if (IS_ANY_DBCS_CHARSET(*aCharSets))
  304. {
  305. bRet = TRUE;
  306. break;
  307. }
  308. }
  309. }
  310. return bRet;
  311. }
  312. /******************************Public*Routine******************************\
  313. * PFEOBG::pfdg()
  314. *
  315. * If pfdg is NULL then we need to get it from font driver
  316. * If pfdg is valid then we only need to return it.
  317. *
  318. * Return
  319. * FD_GLYPHSET *
  320. *
  321. * History
  322. * 08-March-1999 -by- Yung-Jen Tony Tsai [yungt]
  323. * Wrote it.
  324. \**************************************************************************/
  325. FD_GLYPHSET * PFEOBJ::pfdg()
  326. {
  327. PFFOBJ pffo(pPFF());
  328. PDEVOBJ pdo(pffo.hdev());
  329. BOOL bFreeTmp = FALSE;
  330. FD_GLYPHSET *pfdgTmp = NULL;
  331. ULONG_PTR idGlyphSet;
  332. GreAcquireSemaphore(ghsemGlyphSet);
  333. if (ppfe->pfdg == NULL)
  334. {
  335. ASSERTGDI(ppfe->cPfdgRef == 0, "PFEOBJ::pfdg is not matched with cRef\n");
  336. GreReleaseSemaphore(ghsemGlyphSet);
  337. BOOL bUMPD = pdo.bUMPD();
  338. pfdgTmp = (FD_GLYPHSET *) pdo.QueryFontTree(pffo.dhpdev(),
  339. pffo.hff(),
  340. iFont(),
  341. QFT_GLYPHSET,
  342. &idGlyphSet);
  343. GreAcquireSemaphore(ghsemGlyphSet);
  344. if (pfdgTmp)
  345. {
  346. if (ppfe->pfdg == NULL)
  347. {
  348. ppfe->pfdg = pfdgTmp;
  349. ppfe->idfdg = idGlyphSet;
  350. // For UMPD
  351. if (bUMPD)
  352. {
  353. if (ppfe->pifi->jWinCharSet == SYMBOL_CHARSET)
  354. {
  355. FD_GLYPHSET *pfdgNew = NULL;
  356. if (bExtendGlyphSet(&pfdgTmp, &pfdgNew))
  357. {
  358. bFreeTmp = TRUE;
  359. ppfe->pfdg = pfdgNew;
  360. }
  361. }
  362. }
  363. }
  364. else
  365. bFreeTmp = TRUE;
  366. }
  367. }
  368. if (ppfe->pfdg)
  369. ppfe->cPfdgRef++;
  370. GreReleaseSemaphore(ghsemGlyphSet);
  371. if (bFreeTmp)
  372. {
  373. if (PPFNVALID(pdo,Free))
  374. {
  375. pdo.Free(pfdgTmp, idGlyphSet);
  376. }
  377. }
  378. return ppfe->pfdg;
  379. }
  380. extern "C" VOID ttfdFreeGlyphset(ULONG_PTR iFile, ULONG iFace);
  381. /******************************Public*Routine******************************\
  382. * PFEOBG::vFreepfdg()
  383. *
  384. * If pfdg is valid then we free it.
  385. * If pfdg is NULL then return.
  386. *
  387. * Return
  388. * VOID
  389. *
  390. * History
  391. * 08-March-1999 -by- Yung-Jen Tony Tsai [yungt]
  392. * Wrote it.
  393. \**************************************************************************/
  394. VOID PFEOBJ::vFreepfdg()
  395. {
  396. PFFOBJ pffo(pPFF());
  397. FD_GLYPHSET *pfdgTmp = NULL;
  398. ULONG_PTR idGlyphSet;
  399. GreAcquireSemaphore(ghsemGlyphSet);
  400. ASSERTGDI(ppfe->cPfdgRef, "cRef of pfdg is wrong\n");
  401. ppfe->cPfdgRef--;
  402. if (ppfe->cPfdgRef == 0)
  403. {
  404. if (pffo.hdev() == (HDEV) gppdevTrueType)
  405. {
  406. ttfdFreeGlyphset(pffo.hff(), iFont()) ;
  407. ppfe->pfdg = NULL;
  408. }
  409. else
  410. {
  411. PDEVOBJ pdo(pffo.hdev());
  412. if (pdo.bUMPD() && PPFNVALID(pdo,Free))
  413. {
  414. if ((ppfe->pifi->jWinCharSet == SYMBOL_CHARSET) &&
  415. (ppfe->pfdg != NULL) &&
  416. (ppfe->pfdg->flAccel & GS_EXTENDED))
  417. {
  418. VFREEMEM(ppfe->pfdg);
  419. }
  420. else
  421. {
  422. pfdgTmp = ppfe->pfdg;
  423. idGlyphSet = ppfe->idfdg;
  424. }
  425. ppfe->pfdg = NULL;
  426. }
  427. }
  428. }
  429. GreReleaseSemaphore(ghsemGlyphSet);
  430. if (pfdgTmp)
  431. {
  432. PDEVOBJ pdo(pffo.hdev());
  433. pdo.Free(pfdgTmp, idGlyphSet);
  434. }
  435. return;
  436. }
  437. /******************************Public*Routine******************************\
  438. *
  439. * PFEOBJ::flFontType()
  440. *
  441. * Computes the flags defining the type of this font. Allowed flags are
  442. * identical to the flType flags returned in font enumeration.
  443. *
  444. * Return:
  445. * The flags.
  446. *
  447. * History:
  448. * 04-Mar-1992 -by- Gilman Wong [gilmanw]
  449. * Wrote it.
  450. \**************************************************************************/
  451. FLONG PFEOBJ::flFontType()
  452. {
  453. FLONG flRet;
  454. IFIOBJ ifio(pifi());
  455. // Compute the FontType flags, simulations are irrelevant
  456. flRet =
  457. ifio.bTrueType() ?
  458. TRUETYPE_FONTTYPE : (ifio.bBitmap() ? RASTER_FONTTYPE : 0);
  459. // Add the device flag if this is also a device specific font.
  460. flRet |= (bDeviceFont()) ? DEVICE_FONTTYPE : 0;
  461. // check if this is a postscript font
  462. if (pifi()->flInfo & FM_INFO_TECH_TYPE1)
  463. {
  464. flRet |= FO_POSTSCRIPT;
  465. if (pifi()->flInfo & FM_INFO_TECH_MM)
  466. flRet |= FO_MULTIPLEMASTER;
  467. if (pifi()->flInfo & FM_INFO_TECH_CFF)
  468. flRet |= FO_CFF;
  469. }
  470. if (ppfe->flPFE & PFE_DBCS_FONT)
  471. {
  472. flRet |= FO_DBCS_FONT;
  473. if (ppfe->flPFE & PFE_VERT_FACE)
  474. flRet |= FO_VERT_FACE;
  475. }
  476. return (flRet);
  477. }
  478. /******************************Public*Routine******************************\
  479. * PFEOBJ::efstyCompute()
  480. *
  481. * Compute the ENUMFONTSTYLE from the IFIMETRICS.
  482. *
  483. * Returns:
  484. * The ENUMFONTSTYLE of font. Note that EFSTYLE_SKIP and EFSTYLE_OTHER are
  485. * not legal return values for this function. These values are used only
  486. * to mark fonts for which another font already exists that fills our
  487. * category for a given enumeration of a family.
  488. *
  489. * History:
  490. * 04-Aug-1992 -by- Gilman Wong [gilmanw]
  491. * Wrote it.
  492. \**************************************************************************/
  493. ENUMFONTSTYLE PFEOBJ::efstyCompute()
  494. {
  495. IFIOBJ ifio(pifi());
  496. switch (ifio.fsSelection() & (FM_SEL_ITALIC | FM_SEL_BOLD) )
  497. {
  498. case FM_SEL_ITALIC:
  499. return EFSTYLE_ITALIC;
  500. case FM_SEL_BOLD:
  501. return EFSTYLE_BOLD;
  502. case FM_SEL_ITALIC | FM_SEL_BOLD:
  503. return EFSTYLE_BOLDITALIC;
  504. default:
  505. return EFSTYLE_REGULAR;
  506. }
  507. }
  508. /******************************Public*Routine******************************\
  509. * COUNT PFEOBJ::cKernPairs *
  510. * *
  511. * Retrieve the pointer to the array of kerning pairs for this font face. *
  512. * The kerning pair array is loaded on demand, so it may or may not already *
  513. * be cached in the PFE. *
  514. * *
  515. * Returns: *
  516. * Count of kerning pairs. *
  517. * *
  518. * History: *
  519. * Mon 22-Mar-1993 21:31:15 -by- Charles Whitmer [chuckwh] *
  520. * WARNING: Never access a pkp (pointer to a kerning pair) without an *
  521. * exception handler! The kerning pairs could be living in a file across *
  522. * the net or even on removable media. I've added the try-except here. *
  523. * *
  524. * 29-Oct-1992 -by- Gilman Wong [gilmanw] *
  525. * Wrote it. *
  526. \**************************************************************************/
  527. COUNT PFEOBJ::cKernPairs(FD_KERNINGPAIR **ppkp)
  528. {
  529. //
  530. // If the pointer cached in the PFE isn't NULL, we already have the answer.
  531. //
  532. if ( (*ppkp = ppfe->pkp) != (FD_KERNINGPAIR *) NULL )
  533. return ppfe->ckp;
  534. //
  535. // Create a PFFOBJ. Needed to create driver user object as well as
  536. // provide info needed to call driver function.
  537. //
  538. PFFOBJ pffo(pPFF());
  539. ASSERTGDI(pffo.bValid(), "gdisrv!cKernPairsPFEOBJ(): invalid PPFF\n");
  540. PDEVOBJ pdo(pffo.hdev());
  541. if ( (ppfe->pkp = (FD_KERNINGPAIR*)
  542. pdo.QueryFontTree(
  543. pffo.dhpdev(),
  544. pffo.hff(),
  545. ppfe->iFont,
  546. QFT_KERNPAIRS,
  547. &ppfe->idkp)) == (FD_KERNINGPAIR *) NULL )
  548. {
  549. //
  550. // Font has no kerning pairs and didn't even bother to send back
  551. // an empty list. By setting pointer to a zeroed FD_KERNINGPAIR and
  552. // setting count to zero, we will bail out early and avoid calling
  553. // the driver.
  554. //
  555. ppfe->pkp = &gkpNothing;
  556. ppfe->ckp = 0;
  557. return 0;
  558. }
  559. // Find the end of the kerning pair array (indicated by a zeroed out
  560. // FD_KERNINGPAIR structure).
  561. FD_KERNINGPAIR *pkpEnd = ppfe->pkp;
  562. // Be careful, the table isn't guaranteed to stay around!
  563. __try
  564. {
  565. while ((pkpEnd->wcFirst) || (pkpEnd->wcSecond) || (pkpEnd->fwdKern))
  566. pkpEnd += 1;
  567. }
  568. __except (EXCEPTION_EXECUTE_HANDLER)
  569. {
  570. pkpEnd = ppfe->pkp = &gkpNothing;
  571. }
  572. // Return the kerning pair pointer.
  573. *ppkp = ppfe->pkp;
  574. //
  575. // Return count (difference between the beginning and end pointers).
  576. //
  577. //Sundown truncation
  578. ASSERT4GB((LONGLONG)(pkpEnd - ppfe->pkp));
  579. return (ppfe->ckp = (ULONG)(pkpEnd - ppfe->pkp));
  580. }
  581. /******************************Public*Routine******************************\
  582. * bValidFont
  583. *
  584. * Last minute sanity checks to prevent a font that may crash the system
  585. * from getting in. We're primarily looking for things like potential
  586. * divide-by-zero errors, etc.
  587. *
  588. * History:
  589. * 30-Apr-1993 -by- Gilman Wong [gilmanw]
  590. * Wrote it.
  591. \**************************************************************************/
  592. BOOL bValidFont(IFIMETRICS *pifi)
  593. {
  594. BOOL bRet = TRUE;
  595. // Em height is used to compute scaling factors. Must not be zero or
  596. // divide-by-zero may result.
  597. if (pifi->fwdUnitsPerEm == 0)
  598. {
  599. WARNING("bValidFont(): fwdUnitsPerEm is zero\n");
  600. bRet = FALSE;
  601. }
  602. // Font height is used to compute scaling factors. Must not be zero or
  603. // divide-by-zero may result.
  604. if ((pifi->fwdWinAscender + pifi->fwdWinDescender) == 0)
  605. {
  606. WARNING("bValidFont(): font height is zero\n");
  607. bRet = FALSE;
  608. }
  609. return bRet;
  610. }
  611. /******************************Public*Routine******************************\
  612. * BOOL PFEMEMOBJ::bInit
  613. *
  614. * This function copies data into the PFE from the supplied buffer. The
  615. * calling routine should use the PFEMEMOBJ to create a PFE large enough
  616. *
  617. * History:
  618. * 14-Jan-1991 -by- Gilman Wong [gilmanw]
  619. * Wrote it.
  620. \**************************************************************************/
  621. BOOL PFEMEMOBJ::bInit
  622. (
  623. PPFF pPFF, // handle to root PFF
  624. ULONG iFont, // index of font
  625. FD_GLYPHSET *pfdg, // ptr to wc-->hg map
  626. ULONG_PTR idfdg, // driver ID for wc-->hg map
  627. PIFIMETRICS pifi, // ptr to IFIMETRICS
  628. ULONG_PTR idifi, // driver ID for IFIMETRICS
  629. BOOL bDeviceFont, // mark as device font
  630. PUNIVERSAL_FONT_ID pufi, // PFE_UFIMATCH flag for remote printing
  631. BOOL bEUDC // mark as EUDC font
  632. )
  633. {
  634. // Check font's validity. This is not a comprehensive check, but rather
  635. // a last minute check for things that may make the engine crash. Each
  636. // font/device driver still needs to make an effort to weed out its own
  637. // bad fonts.
  638. if (!bValidFont(pifi))
  639. {
  640. WARNING("PFEMEMOBJ::bInit(): rejecting REALLY bad font\n");
  641. return FALSE;
  642. }
  643. // init non-table stuff
  644. ppfe->pPFF = pPFF;
  645. ppfe->iFont = iFont;
  646. ppfe->pfdg = pfdg;
  647. ppfe->idfdg = idfdg;
  648. ppfe->pifi = pifi;
  649. ppfe->idifi = idifi;
  650. ppfe->pkp = (FD_KERNINGPAIR *) NULL;
  651. ppfe->idkp = (ULONG_PTR) NULL;
  652. ppfe->ckp = 0;
  653. ppfe->flPFE = 0;
  654. ppfe->pid = 0;
  655. ppfe->tid = 0;
  656. ppfe->cPfdgRef = 0;
  657. IFIOBJ ifio(ppfe->pifi);
  658. if (IsAnyCharsetDbcs(ppfe->pifi))
  659. ppfe->flPFE |= PFE_DBCS_FONT;
  660. if (*ifio.pwszFamilyName() == U_COMMERCIAL_AT)
  661. ppfe->flPFE |= PFE_VERT_FACE;
  662. // for base font attach full axes info, else, do not.
  663. ppfe->cjEfdwPFE = ALIGN4(dpNtmi() + CJ_NTMI0);
  664. if (pifi->flInfo & FM_INFO_TECH_MM) // if base mm font
  665. {
  666. PTRDIFF dpAXIW = 0;
  667. AXESLISTW *paxlSrc;
  668. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, dpAxesInfoW))
  669. {
  670. dpAXIW = ((IFIEXTRA *)(pifi + 1))->dpAxesInfoW;
  671. paxlSrc = (AXESLISTW *)((BYTE*)pifi + dpAXIW);
  672. ppfe->cjEfdwPFE += (paxlSrc->axlNumAxes * sizeof(AXISINFOW));
  673. }
  674. else
  675. {
  676. ASSERTGDI(dpAXIW, "AxesInfoW needed for base MM font\n");
  677. }
  678. }
  679. ASSERTGDI(ppfe->cjEfdwPFE >= CJ_EFDW0, "cjEfdwPFE problem\n");
  680. if (bDeviceFont)
  681. {
  682. ppfe->flPFE |= PFE_DEVICEFONT;
  683. }
  684. else if(pPFF->ppfv && (pPFF->ppfv[0]->pwszPath == NULL))
  685. {
  686. // CAUTION: It is enough to check one font only to determine if remote
  687. // or memory
  688. if (pPFF->flState & PFF_STATE_MEMORY_FONT)
  689. {
  690. ppfe->flPFE |= PFE_MEMORYFONT;
  691. }
  692. else
  693. {
  694. ppfe->flPFE |= PFE_REMOTEFONT;
  695. }
  696. ppfe->pid = W32GetCurrentPID();
  697. ppfe->tid = (PW32THREAD)PsGetCurrentThread();
  698. }
  699. // For remote printing, fonts are added to the public font table with FR_NOT_ENUM and PFE_UFIMATCH
  700. // flags set so that other process won't be able to enum or map the fonts.
  701. if (pufi)
  702. {
  703. ppfe->flPFE |= PFE_UFIMATCH;
  704. }
  705. #ifdef FE_SB
  706. if( bEUDC )
  707. {
  708. ppfe->flPFE |= PFE_EUDC;
  709. }
  710. // mark it as a SBCS system font if the facename is right
  711. PWSZ pwszFace = ifio.pwszFaceName();
  712. if(pwszFace[0] == '@')
  713. {
  714. pwszFace += 1;
  715. }
  716. if(!_wcsicmp(pwszFace,L"SYSTEM") ||
  717. !_wcsicmp(pwszFace,L"FIXEDSYS") ||
  718. !_wcsicmp(pwszFace,L"TERMINAL") ||
  719. ((!_wcsicmp(pwszFace,L"SMALL FONTS") &&
  720. ifio.lfCharSet() == SHIFTJIS_CHARSET)))
  721. {
  722. ppfe->flPFE |= PFE_SBCS_SYSTEM;
  723. }
  724. // Initialize EUDC QUICKLOOKUP Table
  725. //
  726. // These field was used, if this font is loaded as FaceName/Default linked EUDC.
  727. //
  728. ppfe->ql.puiBits = NULL;
  729. ppfe->ql.wcLow = 1;
  730. ppfe->ql.wcHigh = 0;
  731. #endif
  732. // Record and increment the time stamp.
  733. ppfe->ulTimeStamp = ulTimerPFE;
  734. InterlockedIncrement((LONG *) &ulTimerPFE);
  735. // Precalculate stuff from the IFIMETRICS.
  736. ppfe->iOrientation = ifio.lfOrientation();
  737. // Compute UFI stuff
  738. if( ifio.TypeOneID() )
  739. {
  740. ppfe->ufi.Index = ifio.TypeOneID();
  741. ppfe->ufi.CheckSum = TYPE1_FONT_TYPE;
  742. }
  743. else
  744. {
  745. ppfe->ufi.CheckSum = pPFF->ulCheckSum;
  746. ppfe->ufi.Index = iFont;
  747. if (pufi)
  748. {
  749. // need to ensure that ufi of this pfe on the server machine is
  750. // the same as it used to be on the client. Client side ufi
  751. // one of the pfe's corresponding to this font is pointed to by pufi.
  752. ppfe->ufi.Index += ((pufi->Index - 1) & ~1);
  753. }
  754. }
  755. // init the GISET
  756. if(!bComputeGISET(pifi, ppfe, &ppfe->pgiset))
  757. return FALSE;
  758. // initialize cAlt for this family name, the number of entries in font sub
  759. // table that point to this fam name.
  760. ppfe->cAlt = 0;
  761. // only tt fonts with multiple charsets can be multiply enumerated
  762. // as being both themselves and whatever font sub table claims they are
  763. if (ppfe->pifi->dpCharSets)
  764. {
  765. PFONTSUB pfs = gpfsTable;
  766. PFONTSUB pfsEnd = gpfsTable + gcfsTable;
  767. WCHAR awchCapName[LF_FACESIZE];
  768. // Want case insensitive search, so capitalize the name.
  769. cCapString(awchCapName, ifio.pwszFamilyName() , LF_FACESIZE);
  770. // Scan through the font substitution table for the key string.
  771. PWCHAR pwcA;
  772. PWCHAR pwcB;
  773. for (; pfs < pfsEnd; pfs++)
  774. {
  775. // Do the following inline for speed:
  776. //
  777. // if (!wcsncmpi(pwchFacename, pfs->fcsFace.awch, LF_FACESIZE))
  778. // return (pfs->fcsAltFace.awch);
  779. // only those entries in the Font Substitution which have the form
  780. // face1,charset1=face2,charset2
  781. // where both charset1 and charset2 are valid charsets
  782. // count for enumeration purposes.
  783. if (!(pfs->fcsAltFace.fjFlags | pfs->fcsFace.fjFlags))
  784. {
  785. for (pwcA=awchCapName,pwcB=pfs->fcsAltFace.awch; *pwcA==*pwcB; pwcA++,pwcB++)
  786. {
  787. if (*pwcA == 0)
  788. {
  789. ppfe->aiFamilyName[ppfe->cAlt++] = (BYTE)(pfs-gpfsTable);
  790. break;
  791. }
  792. }
  793. }
  794. }
  795. }
  796. return TRUE;
  797. }
  798. BOOL PFEOBJ::bCheckFamilyName(const WCHAR * pwszFaceName, BOOL bIgonreVertical, BOOL *pbAliasMatch)
  799. {
  800. PWSZ pFaceName;
  801. BOOL bRet;
  802. if (pbAliasMatch)
  803. {
  804. *pbAliasMatch = FALSE;
  805. }
  806. pFaceName = (PWSZ) (((BYTE*) ppfe->pifi) + ppfe->pifi->dpwszFamilyName);
  807. if (bIgonreVertical && (*pFaceName == L'@'))
  808. pFaceName++;
  809. bRet = (_wcsicmp(pwszFaceName, pFaceName) == 0);
  810. if (!bRet && (ppfe->pifi->flInfo & FM_INFO_FAMILY_EQUIV))
  811. {
  812. pFaceName += (wcslen(pFaceName) + 1);
  813. while(!bRet && *pFaceName)
  814. {
  815. if (bIgonreVertical && (*pFaceName == L'@'))
  816. pFaceName++;
  817. bRet = (_wcsicmp(pwszFaceName, pFaceName) == 0);
  818. pFaceName += (wcslen(pFaceName) + 1);
  819. }
  820. // for the font mapper only: If match is found among family name aliases,
  821. // increase the font mapping penalty
  822. if (pbAliasMatch)
  823. {
  824. *pbAliasMatch = bRet;
  825. }
  826. }
  827. return bRet;
  828. }
  829. /******************************Public*Routine******************************\
  830. * BOOL PFEOBJ::bFilterNotEnum()
  831. *
  832. * Used by bFilterOut() in GreEnumOpen(). It checks whether the pfe should
  833. * be filtered out because it is either an embedded font or it is loaded to
  834. * the system with FR_NOT_ENUM bit set.
  835. *
  836. * Returns:
  837. * TRUE if embedded or FR_NOT_ENUM set, FALSE otherwise.
  838. *
  839. * History:
  840. *
  841. * 12-Jun-1996 -by- Xudong Wu [TessieW]
  842. * Wrote it.
  843. \**************************************************************************/
  844. BOOL PFEOBJ::bFilterNotEnum()
  845. {
  846. PFFOBJ pffo(pPFF());
  847. ASSERTGDI(pffo.bValid(), "win32k!PFEOBJ::bFilterEmbPvt(): invalid PPFF\n");
  848. PVTDATA *pPvtData;
  849. BOOL bRet = TRUE;
  850. if (pffo.bInPrivatePFT())
  851. {
  852. // Look for a PvtData block for the current process
  853. if ((pPvtData = pffo.pPvtDataMatch()) && (pPvtData->cNotEnum == 0))
  854. {
  855. bRet = FALSE;
  856. }
  857. }
  858. // public fonts, filter out FR_NOT_ENUM only
  859. else if (pffo.cLoaded())
  860. {
  861. bRet = FALSE;
  862. }
  863. return bRet;
  864. }
  865. /***********************Public*Routine***********************\
  866. * BOOL PFEOBJ::bPrivate()
  867. *
  868. * Determine whether the pfe is in private PFT table
  869. *
  870. * History:
  871. *
  872. * 16-April-1997 -by- Xudong Wu [TessieW]
  873. * Wrote it.
  874. *************************************************************/
  875. BOOL PFEOBJ::bPrivate()
  876. {
  877. return (ppfe->pPFF->pPFT == gpPFTPrivate);
  878. }
  879. /******************************Public*Routine******************************\
  880. * BOOL PFEOBJ::bEmbedOk()
  881. *
  882. * Determine if the font is added as embedded by the current process
  883. *
  884. * Returns:
  885. * TRUE if the font is added by the current process as embedded font
  886. * FALSE otherwise.
  887. *
  888. * History:
  889. *
  890. * 24-Sept-1996 -by- Xudong Wu [TessieW]
  891. * Wrote it.
  892. \**************************************************************************/
  893. BOOL PFEOBJ::bEmbedOk()
  894. {
  895. PVTDATA *pPvtData;
  896. PFFOBJ pffo(pPFF());
  897. ASSERTGDI(pffo.bValid(), "win32k!PFEOBJ::bEmbedOk(): invalid PPFF\n");
  898. ASSERTGDI(pffo.bInPrivatePFT(), "win32k!PFEOBJ::bEmbedOk(): pfe not in private PFT\n");
  899. // embedded font added by the current process
  900. if ((pPvtData = pffo.pPvtDataMatch()) && (pPvtData->fl & (FRW_EMB_TID | FRW_EMB_PID)))
  901. {
  902. return TRUE;
  903. }
  904. return FALSE;
  905. }
  906. /******************************Public*Routine******************************\
  907. * BOOL PFEOBJ::bEmbPvtOk()
  908. *
  909. * Determine whether the current process has right to mapping this font
  910. *
  911. * Returns:
  912. * TRUE pfe in public PFT or
  913. * font has been loaded into Private PFT by the current process
  914. *
  915. * FALSE otherwise
  916. *
  917. * History:
  918. *
  919. * 24-Sept-1996 -by- Xudong Wu [TessieW]
  920. * Wrote it.
  921. \**************************************************************************/
  922. BOOL PFEOBJ::bEmbPvtOk()
  923. {
  924. PFFOBJ pffo(pPFF());
  925. ASSERTGDI(pffo.bValid(), "win32k!PFEOBJ::bEmbPvtOk(): invalid PPFF\n");
  926. // can't find the current process ID in the PvtData link list
  927. if (pffo.bInPrivatePFT() && (pffo.pPvtDataMatch() == NULL))
  928. {
  929. return FALSE;
  930. }
  931. return TRUE;
  932. }
  933. /******************************Public*Routine******************************\
  934. * HPFEC PFEOBJ::hpfecGet()
  935. *
  936. * Get the handle of PFE collect, a new object to reduce the consumption of object handle
  937. *
  938. * Returns:
  939. * Hanlde of PFEC object
  940. * History:
  941. *
  942. * 2-June-1996 -by- Yung-Jen Tony Tsai [YungT]
  943. * Wrote it.
  944. \**************************************************************************/
  945. HPFEC PFEOBJ::hpfecGet()
  946. {
  947. PFFOBJ pffo(ppfe->pPFF);
  948. ASSERTGDI(((HPFEC)pffo.pfec()->hGet()) != HPFEC_INVALID, " PFEOBJ::hpfecGet error\n");
  949. return((HPFEC)pffo.pfec()->hGet());
  950. }
  951. /******************************Public*Routine******************************\
  952. * BOOL PFEOBJ::bFilteredOut(EFFILTER_INFO *peffi)
  953. *
  954. * Determine if this PFE should be rejected from the enumeration. Various
  955. * filtering parameters are passed in via the EFFILTER_INFO structure.
  956. *
  957. * Returns:
  958. * TRUE if font should be rejected, FALSE otherwise.
  959. *
  960. * History:
  961. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  962. * Wrote it.
  963. \**************************************************************************/
  964. BOOL PFEOBJ::bFilteredOut(EFFILTER_INFO *peffi)
  965. {
  966. IFIOBJ ifio(pifi());
  967. // Always filter out "dead" (fonts waiting to be deleted) fonts and "ghost"
  968. // fonts.
  969. if ( bDead() || ifio.bGhostFont() )
  970. return TRUE;
  971. #ifdef FE_SB
  972. // Always filter out fonts that have been loaded as EUDC fonts.
  973. if( bEUDC() )
  974. return TRUE;
  975. #endif
  976. // Raster font filtering.
  977. if (peffi->bRasterFilter && ifio.bBitmap())
  978. return TRUE;
  979. // TrueType font filtering. The flag is somewhat of a misnomer as it
  980. // is intended to exclude TrueType, even though the flag is named
  981. // bNonTrueTypeFilter.
  982. if (peffi->bNonTrueTypeFilter && ifio.bTrueType())
  983. return(TRUE);
  984. // Non-TrueType font filtering. The flag is somewhat of a misnomer as it
  985. // is intended to exclude non-TrueType, even though the flag is named
  986. // bTrueTypeFilter.
  987. if (peffi->bTrueTypeFilter && !ifio.bTrueType())
  988. return TRUE;
  989. // Aspect ratio filtering. If an engine bitmap font, we will filter out
  990. // unsuitable resolutions.
  991. if ( peffi->bAspectFilter
  992. && (!bDeviceFont())
  993. && ifio.bBitmap()
  994. && ( (peffi->ptlDeviceAspect.x != ifio.pptlAspect()->x)
  995. || (peffi->ptlDeviceAspect.y != ifio.pptlAspect()->y) ) )
  996. return TRUE;
  997. // GACF_TTIGNORERASTERDUPE compatibility flag filtering.
  998. // If any raster fonts exist in the same list as a TrueType font, then
  999. // they should be excluded.
  1000. if ( peffi->bTrueTypeDupeFilter
  1001. && peffi->cTrueType
  1002. && ifio.bBitmap())
  1003. return TRUE;
  1004. // Filter out embedded fonts or the fonts with FR_NOT_ENUM bit set.
  1005. if (bFilterNotEnum())
  1006. return TRUE;
  1007. // In the case of a Generic text driver we must filter out all engine fonts
  1008. if( ( peffi->bEngineFilter ) && !bDeviceFont() )
  1009. {
  1010. return(TRUE);
  1011. }
  1012. // if this is a remote/memory font we don't want to enumerate it
  1013. if( ppfe->flPFE & (PFE_REMOTEFONT | PFE_MEMORYFONT) )
  1014. {
  1015. return(TRUE);
  1016. }
  1017. // finally check out if the font should be eliminated from the
  1018. // enumeration because it does not contain the charset requested:
  1019. if (peffi->lfCharSetFilter != DEFAULT_CHARSET)
  1020. {
  1021. // the specific charset has been requested, let us see if the font
  1022. // in question supports it:
  1023. BYTE jCharSet = jMapCharset((BYTE)peffi->lfCharSetFilter, *this);
  1024. if (jCharSet != (BYTE)peffi->lfCharSetFilter)
  1025. return TRUE; // does not support it, filter this font out.
  1026. }
  1027. // Passed all tests.
  1028. return FALSE;
  1029. }
  1030. #if DBG
  1031. /******************************Public*Routine******************************\
  1032. * VOID PFEOBJ::vDump ()
  1033. *
  1034. * Debugging code.
  1035. *
  1036. * History:
  1037. * 25-Feb-1991 -by- Gilman Wong [gilmanw]
  1038. * Wrote it.
  1039. \**************************************************************************/
  1040. VOID PFEOBJ::vPrint()
  1041. {
  1042. IFIOBJ ifio(pifi());
  1043. DbgPrint("\nContents of PFE, PPFE = 0x%p\n", ppfeGet());
  1044. DbgPrint("pPFF = 0x%p\n", ppfe->pPFF);
  1045. DbgPrint("iFont = 0x%lx\n", ppfe->iFont);
  1046. DbgPrint("lfHeight = 0x%x\n", ifio.lfHeight());
  1047. DbgPrint(
  1048. "Family Name = %ws\n",
  1049. ifio.pwszFamilyName()
  1050. );
  1051. DbgPrint(
  1052. "Face Name = %ws\n",
  1053. ifio.pwszFaceName()
  1054. );
  1055. DbgPrint(
  1056. "Unique Name = %s\n\n",
  1057. ifio.pwszUniqueName()
  1058. );
  1059. }
  1060. /******************************Public*Routine******************************\
  1061. * VOID PFEOBJ::vDumpIFI ()
  1062. *
  1063. * Debugging code. Prints PFE header and IFI metrics.
  1064. *
  1065. \**************************************************************************/
  1066. VOID PFEOBJ::vPrintAll()
  1067. {
  1068. DbgPrint("\nContents of PFE, PPFE = 0x%p\n", ppfeGet());
  1069. DbgPrint("pPFF = 0x%p\n", ppfe->pPFF);
  1070. DbgPrint("iFont = 0x%p\n", ppfe->iFont);
  1071. DbgPrint("IFI Metrics\n");
  1072. vPrintIFIMETRICS(ppfe->pifi);
  1073. DbgPrint("\n");
  1074. }
  1075. #endif
  1076. /******************************Public*Routine******************************\
  1077. * EFSMEMOBJ::EFSMEMOBJ(COUNT cefe)
  1078. *
  1079. * Constructor for font enumeration state (EFSTATE) memory object.
  1080. *
  1081. * History:
  1082. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1083. * Wrote it.
  1084. \**************************************************************************/
  1085. EFSMEMOBJ::EFSMEMOBJ(COUNT cefe, ULONG iEnumType_)
  1086. {
  1087. fs = 0;
  1088. pefs = (PEFSTATE) HmgAlloc((offsetof(EFSTATE, aefe) + cefe * sizeof(EFENTRY)),
  1089. EFSTATE_TYPE,
  1090. HMGR_ALLOC_LOCK);
  1091. if (pefs != PEFSTATENULL)
  1092. {
  1093. vInit(cefe, iEnumType_);
  1094. }
  1095. }
  1096. /******************************Public*Routine******************************\
  1097. * EFSMEMOBJ::~EFSMEMOBJ()
  1098. *
  1099. * Destructor for font enumeration state (EFSTATE) memory object.
  1100. *
  1101. * History:
  1102. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1103. * Wrote it.
  1104. \**************************************************************************/
  1105. EFSMEMOBJ::~EFSMEMOBJ()
  1106. {
  1107. // If object pointer not null, try to free the object's memory.
  1108. if (pefs != PEFSTATENULL)
  1109. {
  1110. if (fs & EFSMO_KEEPIT)
  1111. {
  1112. DEC_EXCLUSIVE_REF_CNT(pefs);
  1113. }
  1114. else
  1115. {
  1116. #if DBG
  1117. if (pefs->cExclusiveLock != 1)
  1118. {
  1119. RIP("Not 1 EFSMEMOBJ\n");
  1120. }
  1121. #endif
  1122. HmgFree((HOBJ) pefs->hGet());
  1123. }
  1124. pefs = NULL;
  1125. }
  1126. }
  1127. #define EFS_QUANTUM 16
  1128. /******************************Public*Routine******************************\
  1129. * BOOL EFSOBJ::bGrow
  1130. *
  1131. * Expand the EFENTRY table by the quantum amount.
  1132. *
  1133. * Returns:
  1134. * TRUE if successful, FALSE if failed.
  1135. *
  1136. * History:
  1137. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1138. * Wrote it.
  1139. \**************************************************************************/
  1140. BOOL EFSOBJ::bGrow (COUNT cefeMinIncrement)
  1141. {
  1142. COUNT cefe;
  1143. BOOL bRet = FALSE;
  1144. // Allocate a new EFSTATE bigger by the quantum amount.
  1145. cefe = (COUNT) (pefs->pefeBufferEnd - pefs->aefe);
  1146. if (cefeMinIncrement < EFS_QUANTUM)
  1147. cefeMinIncrement = EFS_QUANTUM;
  1148. cefe += cefeMinIncrement;
  1149. EFSMEMOBJ efsmo(cefe, this->pefs->iEnumType);
  1150. // Validate new EFSTATE.
  1151. if (efsmo.bValid())
  1152. {
  1153. // Copy the enumeration table.
  1154. efsmo.vXerox(pefs);
  1155. // Swap the EFSTATEs.
  1156. if (HmgSwapHandleContents((HOBJ) hefs(),0,(HOBJ) efsmo.hefs(),0,EFSTATE_TYPE))
  1157. {
  1158. // swap pointers
  1159. PEFSTATE pefsTmp = pefs;
  1160. pefs = efsmo.pefs;
  1161. efsmo.pefs = pefsTmp; // destructor will delete old PFT
  1162. bRet = TRUE;
  1163. }
  1164. else
  1165. WARNING("gdisrv!bGrowEFSOBJ(): handle swap failed\n");
  1166. }
  1167. else
  1168. WARNING("bGrowEFSOBJ failed alloc\n");
  1169. return(bRet);
  1170. }
  1171. /******************************Public*Routine******************************\
  1172. * BOOL EFSOBJ::bAdd *
  1173. * *
  1174. * Add a new EFENTRY to the table with the HPFE and ENUMFONTSTYLE. *
  1175. * *
  1176. * Returns: *
  1177. * FALSE if an error occurs, TRUE otherwise. *
  1178. * *
  1179. * History: *
  1180. * 07-Aug-1992 -by- Gilman Wong [gilmanw] *
  1181. * Wrote it. *
  1182. \**************************************************************************/
  1183. BOOL EFSOBJ::bAdd(PFE *ppfe, ENUMFONTSTYLE efsty, FLONG fl, ULONG lfCharSetFilter)
  1184. {
  1185. // Check if the buffer needs to be expanded.
  1186. COUNT cefeMinIncrement = 1; // will always enumerate at least one pfe
  1187. // if EnumFontFamilies is called, will enumerate the font under cAlt more names
  1188. if (!(fl & FL_ENUMFAMILIESEX))
  1189. cefeMinIncrement += ppfe->cAlt;
  1190. // if EnumFontFamiliesEx is called, and this font supports multiple charsets,
  1191. // this font will be enumerated no more than MAXCHARSETS times.
  1192. if
  1193. (
  1194. (fl & FL_ENUMFAMILIESEX) &&
  1195. (lfCharSetFilter == DEFAULT_CHARSET) &&
  1196. ppfe->pifi->dpCharSets
  1197. )
  1198. {
  1199. cefeMinIncrement = MAXCHARSETS;
  1200. }
  1201. if ((pefs->pefeDataEnd + cefeMinIncrement) >= pefs->pefeBufferEnd)
  1202. {
  1203. if (!bGrow(cefeMinIncrement))
  1204. {
  1205. // Error code will be saved for us.
  1206. WARNING("gdisrv!EFSOBJ__bAdd: cannot grow enumeration table\n");
  1207. return FALSE;
  1208. }
  1209. }
  1210. // Add the new data and increment the data pointer.
  1211. PFEOBJ pfeo(ppfe);
  1212. HPFEC hpfec = pfeo.hpfecGet();
  1213. ULONG iFont = ppfe->iFont;
  1214. pefs->pefeDataEnd->hpfec = hpfec;
  1215. pefs->pefeDataEnd->iFont = iFont;
  1216. pefs->pefeDataEnd->efsty = efsty;
  1217. pefs->pefeDataEnd->fjOverride = 0; // do not override
  1218. if (fl & FL_ENUMFAMILIESEX)
  1219. pefs->pefeDataEnd->fjOverride |= FJ_CHARSETOVERRIDE;
  1220. pefs->pefeDataEnd->jCharSetOverride = (BYTE)lfCharSetFilter;
  1221. pefs->pefeDataEnd += 1;
  1222. pefs->cjEfdwTotal += ppfe->cjEfdwPFE;
  1223. // now check if called from EnumFonts or EnumFontFamilies so that the
  1224. // names from the
  1225. // [FontSubstitutes] section in the registry also need to be enumerated
  1226. if (!(fl & FL_ENUMFAMILIESEX) && ppfe->cAlt) // alt names have to be enumerated too
  1227. {
  1228. for (ULONG i = 0; i < ppfe->cAlt; i++)
  1229. {
  1230. // the same hpfe, style etc. all the time, only lie about the name and charset
  1231. pefs->pefeDataEnd->hpfec = hpfec;
  1232. pefs->pefeDataEnd->iFont = iFont;
  1233. pefs->pefeDataEnd->efsty = efsty;
  1234. pefs->pefeDataEnd->fjOverride = (FJ_FAMILYOVERRIDE | FJ_CHARSETOVERRIDE); // do override
  1235. pefs->pefeDataEnd->iOverride = ppfe->aiFamilyName[i];
  1236. pefs->pefeDataEnd->jCharSetOverride =
  1237. gpfsTable[pefs->pefeDataEnd->iOverride].fcsFace.jCharSet;
  1238. pefs->pefeDataEnd += 1;
  1239. pefs->cjEfdwTotal += ppfe->cjEfdwPFE;
  1240. }
  1241. }
  1242. // now see if this is called from EnumFontFamiliesEx
  1243. if ((fl & FL_ENUMFAMILIESEX) && (lfCharSetFilter == DEFAULT_CHARSET))
  1244. {
  1245. // The font needs to be enumerated once for every charset it supports
  1246. if (ppfe->pifi->dpCharSets)
  1247. {
  1248. BYTE *ajCharSets = (BYTE*)ppfe->pifi + ppfe->pifi->dpCharSets;
  1249. BYTE *ajCharSetsEnd = ajCharSets + MAXCHARSETS;
  1250. // first fix up the one entry we just filled above
  1251. (pefs->pefeDataEnd-1)->jCharSetOverride = ajCharSets[0];
  1252. // this is from win95-J sources:
  1253. #define FEOEM_CHARSET 254
  1254. for
  1255. (
  1256. BYTE *pjCharSets = ajCharSets + 1; // skip the first one, used already
  1257. (*pjCharSets != DEFAULT_CHARSET) &&
  1258. (*pjCharSets != OEM_CHARSET) &&
  1259. (*pjCharSets != FEOEM_CHARSET) &&
  1260. (pjCharSets < ajCharSetsEnd) ;
  1261. pjCharSets++
  1262. )
  1263. {
  1264. // the same hpfe, style etc. all the time, only lie about the name and charset
  1265. pefs->pefeDataEnd->hpfec = hpfec;
  1266. pefs->pefeDataEnd->iFont = iFont;
  1267. pefs->pefeDataEnd->efsty = efsty;
  1268. pefs->pefeDataEnd->fjOverride = FJ_CHARSETOVERRIDE;
  1269. pefs->pefeDataEnd->iOverride = 0;
  1270. pefs->pefeDataEnd->jCharSetOverride = *pjCharSets;
  1271. pefs->pefeDataEnd += 1;
  1272. pefs->cjEfdwTotal += ppfe->cjEfdwPFE;
  1273. }
  1274. }
  1275. else // fix up the one entry we just filled above
  1276. {
  1277. (pefs->pefeDataEnd-1)->jCharSetOverride = ppfe->pifi->jWinCharSet;
  1278. }
  1279. }
  1280. // Success.
  1281. return TRUE;
  1282. }
  1283. /******************************Public*Routine******************************\
  1284. * VOID EFSOBJ::vDelete ()
  1285. *
  1286. * Destroy the font enumeration state (EFSTATE) memory object.
  1287. *
  1288. * History:
  1289. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1290. * Wrote it.
  1291. \**************************************************************************/
  1292. VOID EFSOBJ::vDeleteEFSOBJ()
  1293. {
  1294. HmgFree((HOBJ) pefs->hGet());
  1295. pefs = PEFSTATENULL;
  1296. }
  1297. /******************************Member*Function*****************************\
  1298. * VOID EFSMEMOBJ::vInit
  1299. *
  1300. * Initialize the EFSTATE object.
  1301. *
  1302. * History:
  1303. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1304. * Wrote it.
  1305. \**************************************************************************/
  1306. VOID EFSMEMOBJ::vInit(COUNT cefe, ULONG iEnumType_)
  1307. {
  1308. // HPFE array empty, so initialize all pointer to the beginning of the array.
  1309. pefs->pefeDataEnd = pefs->aefe;
  1310. pefs->pefeEnumNext = pefs->aefe;
  1311. // Except for this one. Set this one to the end of the buffer.
  1312. pefs->pefeBufferEnd = &pefs->aefe[cefe];
  1313. // Initialize the alternate name to NULL.
  1314. pefs->pfsubOverride = NULL;
  1315. // init the enum type:
  1316. pefs->iEnumType = iEnumType_;
  1317. // empty for now, total enumeration data size is zero
  1318. pefs->cjEfdwTotal = 0;
  1319. // We don't need to bother with initializing the array.
  1320. }
  1321. /******************************Public*Routine******************************\
  1322. * VOID EFSMEMOBJ::vXerox(EFSTATE *pefeSrc)
  1323. *
  1324. * Copy the EFENTRYs from the source EFSTATE's table into this EFSTATE's table.
  1325. * The internal pointers will be updated to be consistent with the data.
  1326. *
  1327. * History:
  1328. * 07-Aug-1992 -by- Gilman Wong [gilmanw]
  1329. * Wrote it.
  1330. \**************************************************************************/
  1331. VOID EFSMEMOBJ::vXerox(EFSTATE *pefsSrc)
  1332. {
  1333. //
  1334. // Compute size of the table.
  1335. //
  1336. // Sundown truncation
  1337. ASSERT4GB ((ULONGLONG)(pefs->pefeDataEnd - pefs->aefe));
  1338. COUNT cefe = (COUNT)(pefsSrc->pefeDataEnd - pefsSrc->aefe);
  1339. ASSERTGDI (
  1340. cefe >= (COUNT)(pefs->pefeDataEnd - pefs->aefe),
  1341. "gdisrv!vXeroxEFSMEMOBJ(): table to small\n"
  1342. );
  1343. //
  1344. // Copy entries.
  1345. //
  1346. RtlCopyMemory((PVOID) pefs->aefe, (PVOID) pefsSrc->aefe, (SIZE_T) cefe * sizeof(EFENTRY));
  1347. // Fixup the data pointer and size of enumeration data
  1348. pefs->pefeDataEnd = pefs->aefe + cefe;
  1349. pefs->cjEfdwTotal = pefsSrc->cjEfdwTotal;
  1350. // iEnumType has been set at the vInit time, it does not have to be reset now.
  1351. // Therefore we are done.
  1352. }
  1353. /******************************Public*Routine******************************\
  1354. * bSetEFSTATEOwner
  1355. *
  1356. * Set the owner of the EFSTATE
  1357. *
  1358. * if the owner is set to OBJECTOWNER_NONE, this EFSTATE will not be useable
  1359. * until bSetEFSTATEOwner is called to explicitly give the lfnt to someone else.
  1360. *
  1361. * History:
  1362. * 07-Aug-1992 by Gilman Wong [gilmanw]
  1363. * Wrote it.
  1364. \**************************************************************************/
  1365. BOOL
  1366. bSetEFSTATEOwner(
  1367. HEFS hefs,
  1368. W32PID lPid)
  1369. {
  1370. if (lPid == OBJECT_OWNER_CURRENT)
  1371. {
  1372. lPid = W32GetCurrentPID();
  1373. }
  1374. return HmgSetOwner((HOBJ) hefs, lPid, EFSTATE_TYPE);
  1375. }
  1376. /******************************Public*Routine******************************\
  1377. * BOOL bSetFontXform
  1378. *
  1379. * Sets the FD_XFORM such that it can be used to realize the physical font
  1380. * with the dimensions specified in the wish list coordinates). The
  1381. * World to Device xform (with translations removed) is also returned.
  1382. *
  1383. * Returns:
  1384. * TRUE if successful, FALSE if an error occurs.
  1385. *
  1386. * History:
  1387. * Tue 27-Oct-1992 23:18:39 by Kirk Olynyk [kirko]
  1388. * Moved it from PFEOBJ.CXX
  1389. * 19-Sep-1991 -by- Gilman Wong [gilmanw]
  1390. * Wrote it.
  1391. \**************************************************************************/
  1392. BOOL
  1393. PFEOBJ::bSetFontXform (
  1394. XDCOBJ &dco, // realize for this device
  1395. LOGFONTW *pelfw, // wish list (in logical coords)
  1396. PFD_XFORM pfd_xf, // font transform
  1397. FLONG fl,
  1398. FLONG flSim,
  1399. POINTL* const pptlSim,
  1400. IFIOBJ& ifio,
  1401. BOOL bIsLinkedFont // TRUE if the font is linked, FALSE otherwise
  1402. )
  1403. {
  1404. BOOL bRet;
  1405. EXFORMOBJ xo(dco, WORLD_TO_DEVICE); // synchronize the transformation
  1406. if(dco.pdc->iGraphicsMode() == GM_COMPATIBLE)
  1407. {
  1408. bRet = bGetNtoD_Win31(
  1409. pfd_xf,
  1410. pelfw,
  1411. ifio,
  1412. (DCOBJ *)&dco,
  1413. fl,
  1414. pptlSim,
  1415. bIsLinkedFont
  1416. );
  1417. }
  1418. else // GM_ADVANCED
  1419. {
  1420. bRet = bGetNtoD(
  1421. pfd_xf,
  1422. pelfw,
  1423. ifio,
  1424. (DCOBJ *)&dco,
  1425. pptlSim
  1426. );
  1427. }
  1428. if (!bRet)
  1429. {
  1430. WARNING(
  1431. "gdisrv!bSetFontXformPFEOBJ(): failed to get Notional to World xform\n"
  1432. );
  1433. return FALSE;
  1434. }
  1435. //
  1436. // The next line two lines of code flips the sign of the Notional y-coordinates
  1437. // The effect is that the XFORMOBJ passed over the DDI makes the assumption that
  1438. // Notional space is such that the y-coordinate increases towards the bottom.
  1439. // This is opposite to the usual conventions of notional space and the font
  1440. // driver writers must be made aware of this historical anomaly.
  1441. //
  1442. NEGATE_IEEE_FLOAT(pfd_xf->eYX);
  1443. NEGATE_IEEE_FLOAT(pfd_xf->eYY);
  1444. //
  1445. // If the font can be scaled isotropicslly only then we make sure that we send
  1446. // to the font driver isotropic transformations.
  1447. //
  1448. // If a device has set the TA_CR_90 bit, then it is possible
  1449. // that we will send to the driver a transformation that is equivalent to an isotropic
  1450. // transformation rotated by a multiple of 90 degress. This is the reason for the
  1451. // second line of this transformation.
  1452. //
  1453. if (ifio.bIsotropicScalingOnly())
  1454. {
  1455. *(LONG*)&(pfd_xf->eXX) = *(LONG*)&(pfd_xf->eYY);
  1456. *(LONG*)&(pfd_xf->eXY) = *(LONG*)&(pfd_xf->eYX);
  1457. NEGATE_IEEE_FLOAT(pfd_xf->eXY);
  1458. }
  1459. return (TRUE);
  1460. }
  1461. /******************************Public*Routine******************************\
  1462. * PFE * PFECOBJ::GetPFE(ULONG iFont)
  1463. *
  1464. * Get PFE from PFE collect, a new object to reduce the consumption of object handle
  1465. *
  1466. * Returns:
  1467. * memory pointer of PFE
  1468. * History:
  1469. *
  1470. * 2-June-1996 -by- Yung-Jen Tony Tsai [YungT]
  1471. * Wrote it.
  1472. \**************************************************************************/
  1473. PFE * PFECOBJ::GetPFE(ULONG iFont)
  1474. {
  1475. PFE * ppfe = NULL;
  1476. if (ppfec)
  1477. {
  1478. ASSERTGDI(ppfec->pvPFE, "PFECOBJ::GetPFE ppfset->pvPFE is null \n");
  1479. ppfe = (PFE *) ((PBYTE) ppfec->pvPFE + ((iFont - 1) * ppfec->cjPFE));
  1480. }
  1481. return ppfe;
  1482. }
  1483. /******************************Public*Routine******************************\
  1484. * HPFEC PFECOBJ::GetHPFEC()
  1485. *
  1486. * Get handle of PFEC from PFE collect, a new object to reduce the consumption of object handle
  1487. *
  1488. * Returns:
  1489. * Handle of PFEC
  1490. * History:
  1491. *
  1492. * 2-June-1996 -by- Yung-Jen Tony Tsai [YungT]
  1493. * Wrote it.
  1494. \**************************************************************************/
  1495. HPFEC PFECOBJ::GetHPFEC()
  1496. {
  1497. ASSERTGDI(ppfec, "PFECOBJ::GetHPFEC ppfec is NULL \n");
  1498. return((HPFEC) ppfec->hGet());
  1499. }