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.

2276 lines
66 KiB

  1. /*********************************************************************************
  2. * misceudc.cxx
  3. *
  4. * This file contains EUDC specific methods for various GRE object. I am moving
  5. * them to a separate file to make it easier to modify them after checkin freezes.
  6. * Once FE_SB ifdefs are removed we will probably want to move these object back
  7. * to the appropriate xxxobj.cxx files.
  8. *
  9. * 5-1-96 Gerrit van Wingerden [gerritv]
  10. *
  11. * Copyright (c) 1996-1999 Microsoft Corporation
  12. ********************************************************************************/
  13. #include "precomp.hxx"
  14. extern HSEMAPHORE ghsemEUDC2;
  15. LONG lNormAngle(LONG lAngle);
  16. /******************************Public*Routine******************************\
  17. * GLYPHDATA *RFONTOBJ::pgdGetEudcMetrics()
  18. *
  19. * 9-29-1993 Gerrit van Wingerden [gerritv]
  20. * Wrote it.
  21. \**************************************************************************/
  22. GLYPHDATA *RFONTOBJ::pgdGetEudcMetrics(WCHAR wc, RFONTOBJ* prfoBase)
  23. {
  24. if (prfnt->wcgp == NULL)
  25. {
  26. if (!bAllocateCache(prfoBase))
  27. {
  28. return(NULL);
  29. }
  30. }
  31. if (prfnt->wcgp->cRuns == 0)
  32. {
  33. WARNING("EUDC -- pgdGetEudcMetrics - empty glyphset\n");
  34. return pgdDefault();
  35. }
  36. GPRUN *pwcRun = prfnt->wcgp->agpRun; // initialize with guess for loop below
  37. GLYPHDATA *wpgd;
  38. // Find the correct run, if any.
  39. // Try the current run first.
  40. UINT swc = (UINT)wc - pwcRun->wcLow;
  41. if ( swc >= pwcRun->cGlyphs )
  42. {
  43. pwcRun = gprunFindRun(wc);
  44. swc = (UINT)wc - pwcRun->wcLow;
  45. if ( swc < pwcRun->cGlyphs )
  46. {
  47. wpgd = pwcRun->apgd[swc];
  48. }
  49. else
  50. {
  51. return(NULL);
  52. }
  53. }
  54. else
  55. {
  56. // Look up entry in current run
  57. // This path should go in line
  58. wpgd = pwcRun->apgd[swc];
  59. }
  60. // check to make sure in cache, insert if needed
  61. if ( wpgd == NULL )
  62. {
  63. // This path should go out of line
  64. if ( !bInsertMetrics(&pwcRun->apgd[swc], wc) )
  65. {
  66. // when insert fails trying to get just metrics, it is a hard
  67. // failure. Get out of here!
  68. WARNING("EUDC -- bGetGlyphMetrics - bInsertMetrics failed\n");
  69. return(NULL);
  70. }
  71. wpgd = pwcRun->apgd[swc];
  72. }
  73. return wpgd;
  74. }
  75. /******************************Public*Routine******************************\
  76. * GLYPHDATA *RFONTOBJ::pgdGetEudcMetricsPlus()
  77. *
  78. *
  79. * 9-29-1993 Gerrit van Wingerden [gerritv]
  80. * Wrote it.
  81. \**************************************************************************/
  82. GLYPHDATA *RFONTOBJ::pgdGetEudcMetricsPlus
  83. (
  84. WCHAR wc,
  85. RFONTOBJ* prfoBase
  86. )
  87. {
  88. if (prfnt->wcgp == NULL)
  89. {
  90. if (!bAllocateCache(prfoBase))
  91. {
  92. return(NULL);
  93. }
  94. }
  95. if (prfnt->wcgp->cRuns == 0)
  96. {
  97. WARNING("EUDC -- pgdGetEudcMetricsPlus - empty glyphset\n");
  98. return pgdDefault();
  99. }
  100. GPRUN *pwcRun = prfnt->wcgp->agpRun; // initialize with guess for loop below
  101. GLYPHDATA *wpgd;
  102. // Find the correct run, if any.
  103. // Try the current run first.
  104. UINT swc = (UINT)wc - pwcRun->wcLow;
  105. if ( swc >= pwcRun->cGlyphs )
  106. {
  107. pwcRun = gprunFindRun(wc);
  108. swc = (UINT)wc - pwcRun->wcLow;
  109. if ( swc < pwcRun->cGlyphs )
  110. {
  111. wpgd = pwcRun->apgd[swc];
  112. }
  113. else
  114. {
  115. return(NULL);
  116. }
  117. }
  118. else
  119. {
  120. // Look up entry in current run
  121. // This path should go in line
  122. wpgd = pwcRun->apgd[swc];
  123. }
  124. // check to make sure in cache, insert if needed
  125. if ( wpgd == NULL )
  126. {
  127. // This path should go out of line
  128. if ( !bInsertMetricsPlus(&pwcRun->apgd[swc], wc) )
  129. {
  130. // when insert fails trying to get just metrics, it is a hard
  131. // failure. Get out of here!
  132. WARNING("EUDC -- bGetGlyphMetricsPlus - bInsertMetrics failed\n");
  133. return(NULL);
  134. }
  135. wpgd = pwcRun->apgd[swc];
  136. }
  137. // Don't bother inserting glyphs since we are going to force the driver to
  138. // enum anyway.
  139. return wpgd;
  140. }
  141. /******************************Public*Routine******************************\
  142. * RFONTOBJ::bCheckEudcFontCaps
  143. *
  144. * History:
  145. * 9-Nov-93 -by- Hideyuki Nagase
  146. * Wrote it.
  147. \**************************************************************************/
  148. BOOL RFONTOBJ::bCheckEudcFontCaps
  149. (
  150. IFIOBJ &ifioEudc
  151. )
  152. {
  153. // Check FontLink configuration.
  154. if( ulFontLinkControl & FLINK_DISABLE_LINK_BY_FONTTYPE )
  155. {
  156. // Fontlink for Device font is disabled ?
  157. if( bDeviceFont() )
  158. {
  159. if( ulFontLinkControl & FLINK_DISABLE_DEVFONT )
  160. {
  161. return(FALSE);
  162. }
  163. }
  164. else
  165. {
  166. // Fontlink for TrueType font is disabled ?
  167. if( (ulFontLinkControl & FLINK_DISABLE_TTFONT) &&
  168. (prfnt->flInfo & FM_INFO_TECH_TRUETYPE ) )
  169. {
  170. return( FALSE );
  171. }
  172. // Fontlink for Vector font is disabled ?
  173. if( (ulFontLinkControl & FLINK_DISABLE_VECTORFONT) &&
  174. (prfnt->flInfo & FM_INFO_TECH_STROKE ) )
  175. {
  176. return( FALSE );
  177. }
  178. // Fontlink for Bitmap font is disabled ?
  179. if( (ulFontLinkControl & FLINK_DISABLE_BITMAPFONT) &&
  180. (prfnt->flInfo & FM_INFO_TECH_BITMAP ) )
  181. {
  182. return( FALSE );
  183. }
  184. }
  185. }
  186. BOOL bRotIs90Degree;
  187. // Can EUDC font do arbitarary tramsforms ?
  188. if( ifioEudc.bArbXforms() )
  189. return( TRUE );
  190. // Can its Orientation degree be divided by 900 ?
  191. bRotIs90Degree = (prfnt->ulOrientation % 900) == 0;
  192. // if the Orientation is 0, 90, 270, 360... and the EUDC font can be
  193. // rotated by 90 degrees, we accept this link.
  194. if( ifioEudc.b90DegreeRotations() && bRotIs90Degree )
  195. return( TRUE );
  196. // if not, we reject this link.
  197. return( FALSE );
  198. }
  199. /******************************Public*Routine******************************\
  200. * IsSingularEudcGlyph
  201. *
  202. * History:
  203. *
  204. * 25-Jul-95 -by- Hideyuki Nagase
  205. * Wrote it.
  206. \**************************************************************************/
  207. BOOL IsSingularEudcGlyph
  208. (
  209. GLYPHDATA *wpgd, BOOL bSimulatedBold
  210. )
  211. {
  212. //
  213. // Determine this is really registerd EUDC glyph or not.
  214. //
  215. // [NT 3.51 code for reference]
  216. //
  217. // if( wpgd->rclInk.left == 0 &&
  218. // wpgd->rclInk.top == 0 &&
  219. // (wpgd->rclInk.right == 0 || wpgd->rclInk.right == 1) &&
  220. // (wpgd->rclInk.bottom == 0 || wpgd->rclInk.bottom == 1)
  221. // )
  222. // return( TRUE );
  223. //
  224. // This glyph does not have advance width, it might be non-registered
  225. // character, then return TRUE to let replace this with EUDC default
  226. // character.
  227. //
  228. // dchinn 5/12/99: The code used to use the bSimulatedBold flag.
  229. // If bSimulatedBold were TRUE and if fxD == 0x10, then we return TRUE.
  230. // That code is no longer needed because ClaudeBe made a change elsewhere
  231. // to leave fxD as 0x00 when doing bold simulation. So, the test below
  232. // is correct whether or not bSimulatedBold is TRUE.
  233. if( wpgd->fxD == 0 ) return( TRUE );
  234. //
  235. // Otherwise, use this glyph.
  236. //
  237. return( FALSE );
  238. }
  239. BOOL RFONTOBJ::bInitSystemTT(XDCOBJ &dco)
  240. {
  241. UINT iPfeOffset = (prfnt->bVertical ? PFE_VERTICAL : PFE_NORMAL);
  242. RFONTOBJ rfo;
  243. EUDCLOGFONT SystemTTLogfont;
  244. ComputeEUDCLogfont(&SystemTTLogfont, dco);
  245. PFE *ppfeSystem = (gappfeSystemDBCS[iPfeOffset] == NULL) ?
  246. gappfeSystemDBCS[PFE_NORMAL] : gappfeSystemDBCS[iPfeOffset];
  247. rfo.vInit(dco,ppfeSystem,&SystemTTLogfont,FALSE );
  248. if( rfo.bValid() )
  249. {
  250. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  251. "vInitSystemTT() -- linking system DBCS font");
  252. prfnt->prfntSystemTT = rfo.prfntFont();
  253. }
  254. return(prfnt->prfntSystemTT != NULL);
  255. }
  256. GLYPHDATA *RFONTOBJ::FindLinkedGlyphDataPlus
  257. (
  258. XDCOBJ *pdco,
  259. ESTROBJ *pto,
  260. WCHAR wc,
  261. COUNT index,
  262. COUNT c,
  263. BOOL *pbAccel,
  264. BOOL bSystemTTSearch,
  265. BOOL bGetBits
  266. )
  267. {
  268. GLYPHDATA *wpgd;
  269. LONG *plPartition = pto ? pto->plPartitionGet() : NULL;
  270. // don't setup system EUDC font if there are remote links
  271. if(!pdco->uNumberOfLinkedUFIs() && bSystemTTSearch && bIsSystemTTGlyph(wc))
  272. {
  273. if(!prfnt->prfntSystemTT)
  274. {
  275. WARNING("Error initializing TT system font 2\n");
  276. return(pgdDefault());
  277. }
  278. if(pto && !(pto->bSystemPartitionInit()))
  279. {
  280. // this call can't fail for the SystemTT case
  281. pto->bPartitionInit(c,0,FALSE);
  282. }
  283. // mark the glyph as coming from a SystemTT font
  284. RFONTTMPOBJ rfo;
  285. rfo.vInit(prfnt->prfntSystemTT);
  286. if(rfo.bValid() &&
  287. (wpgd = bGetBits ? rfo.pgdGetEudcMetricsPlus(wc, this) : rfo.pgdGetEudcMetrics(wc, this)))
  288. {
  289. if (pto)
  290. {
  291. ASSERTGDI(pto->bSystemPartitionInit(),
  292. "FindLinkedGlyphDataPlus: FontLink partition no initialized\n");
  293. pto->vTTSysGlyphsInc();
  294. plPartition[index] = EUDCTYPE_SYSTEM_TT_FONT;
  295. // turn off accelerator since we're going to mess with the driver
  296. *pbAccel = FALSE;
  297. }
  298. return(wpgd);
  299. }
  300. else
  301. {
  302. return(pgdDefault());
  303. }
  304. }
  305. // next search through all the EUDC fonts in order to see if the glyph is one of them
  306. for( UINT uiFont = 0;
  307. uiFont < prfnt->uiNumLinks;
  308. uiFont ++ )
  309. {
  310. RFONTTMPOBJ rfo;
  311. rfo.vInit( prfnt->paprfntFaceName[uiFont] );
  312. if(rfo.bValid())
  313. {
  314. if( (wpgd = bGetBits ? rfo.pgdGetEudcMetricsPlus(wc, this)
  315. : rfo.pgdGetEudcMetrics(wc, this)) != NULL )
  316. {
  317. if( !IsSingularEudcGlyph(wpgd, rfo.pfo()->flFontType & FO_SIM_BOLD) )
  318. {
  319. if (pto)
  320. {
  321. plPartition[index] = EUDCTYPE_FACENAME + uiFont;
  322. pto->vFaceNameInc(uiFont);
  323. // turn off accelerator since we're going to mess with the driver
  324. *pbAccel = FALSE;
  325. }
  326. return( wpgd );
  327. }
  328. }
  329. }
  330. }
  331. // see if the glyph is in the DEFAULT EUDC font
  332. if( prfnt->prfntDefEUDC != NULL )
  333. {
  334. RFONTTMPOBJ rfo( prfnt->prfntDefEUDC );
  335. if (rfo.bValid())
  336. {
  337. wpgd = bGetBits ? rfo.pgdGetEudcMetricsPlus(wc, this)
  338. : rfo.pgdGetEudcMetrics(wc, this);
  339. if( wpgd != NULL )
  340. {
  341. if( !IsSingularEudcGlyph(wpgd, rfo.pfo()->flFontType & FO_SIM_BOLD) )
  342. {
  343. if (pto)
  344. {
  345. // mark this character as an EUDC character
  346. plPartition[index] = EUDCTYPE_DEFAULT;
  347. // increment count of Sys EUDC glyphs
  348. pto->vDefGlyphsInc();
  349. // turn off accelerator since we're going to mess with the driver
  350. *pbAccel = FALSE;
  351. }
  352. return( wpgd );
  353. }
  354. }
  355. }
  356. }
  357. // see if the glyph is in the SYSTEM-WIDE EUDC font
  358. if( prfnt->prfntSysEUDC != NULL )
  359. {
  360. RFONTTMPOBJ rfo( prfnt->prfntSysEUDC );
  361. if (rfo.bValid())
  362. {
  363. wpgd = bGetBits ? rfo.pgdGetEudcMetricsPlus(wc, this)
  364. : rfo.pgdGetEudcMetrics(wc, this);
  365. if( wpgd != NULL )
  366. {
  367. if( !IsSingularEudcGlyph(wpgd, rfo.pfo()->flFontType & FO_SIM_BOLD))
  368. {
  369. if (pto)
  370. {
  371. // mark this character as an EUDC characte and indicate that there
  372. // are EUDC glyphs in the font
  373. plPartition[index] = EUDCTYPE_SYSTEM_WIDE;
  374. pto->vSysGlyphsInc();
  375. // turn off accelerator since we're going to mess with the driver
  376. *pbAccel = FALSE;
  377. }
  378. return( wpgd );
  379. }
  380. }
  381. }
  382. }
  383. return( NULL );
  384. }
  385. /******************************Public*Routine******************************\
  386. * RFONTOBJ::wpgdGetLinkMetricsPlus
  387. *
  388. * If GetGlyphMetricsPlus encounters a default character call off to this
  389. * routine to try and get it from the EUDC and face name linked fonts.
  390. *
  391. * History:
  392. *
  393. * 19-Jan-95 -by- Hideyuki Nagase
  394. * Rewrote it.
  395. *
  396. * 14-Jul-93 -by- Gerrit van Wingerden
  397. * Wrote it.
  398. \**************************************************************************/
  399. GLYPHDATA *RFONTOBJ::wpgdGetLinkMetricsPlus
  400. (
  401. XDCOBJ *pdco,
  402. ESTROBJ *pto,
  403. WCHAR *pwc,
  404. WCHAR *pwcInit,
  405. COUNT c,
  406. BOOL *pbAccel,
  407. BOOL bGetBits
  408. )
  409. {
  410. GLYPHDATA *wpgd;
  411. WCHAR *pwcCurrent = pwc;
  412. WCHAR *pwcEnd = pwcInit + c;
  413. // bLinkingTurnedOff forces linking to be turned off. It will be TRUE
  414. // when we are printing an EMF file that originated on a machine that
  415. // had no fontlinking turned on
  416. if(pdco == NULL ||
  417. pdco->bLinkingTurnedOff() ||
  418. (!gbAnyLinkedFonts && !IS_SYSTEM_EUDC_PRESENT() && (pdco->uNumberOfLinkedUFIs() == 0)))
  419. {
  420. return(pgdDefault());
  421. }
  422. for (; (pwcCurrent < pwcEnd && (*pwcCurrent >= 0x80) && (*pwcCurrent <= 0x9F) ); pwcCurrent+=1)
  423. {
  424. }
  425. if (pwcCurrent == pwcEnd)
  426. {
  427. // all the characters are in the range 0x80 to 0x9F
  428. // we don't want to look through font linking for characters in that range
  429. // this is a performance issue to avoid calling font linking code on English system with
  430. // far east language pack installed
  431. // client side caching is requesting through iGetPublicWidthTable() the width for ANSI codes
  432. // 0x00 to 0xFF, those code are converted to Unicode. Some code in the range 0x80->0x9F
  433. // are not converted and stay in that range causing the linked fonts to be loaded to look for those characters
  434. // Unicode in that range belong to the C1 controls, it doesn't make sense to look for them through
  435. // font linking, see Windows bug 157772.
  436. return(pgdDefault());
  437. }
  438. // always initialize the System TT to avoid a deadlock situation
  439. if (!pdco->uNumberOfLinkedUFIs() && prfnt->bIsSystemFont)
  440. {
  441. if((!prfnt->prfntSystemTT) && !bInitSystemTT(*pdco))
  442. {
  443. WARNING("Error initializing TT system font 4\n");
  444. }
  445. else
  446. {
  447. GreAcquireSemaphore(prfnt->hsemEUDC);
  448. if(!(prfnt->flEUDCState & TT_SYSTEM_INITIALIZED))
  449. {
  450. INCREMENTEUDCCOUNT;
  451. RFONTTMPOBJ rfo(prfnt->prfntSystemTT);
  452. rfo.vGetCache();
  453. prfnt->flEUDCState |= TT_SYSTEM_INITIALIZED;
  454. }
  455. GreReleaseSemaphore(prfnt->hsemEUDC);
  456. }
  457. }
  458. // if this is an SBCS system font and the glyph exists in the DBCS TT system front
  459. // grab it from there
  460. if(!pdco->uNumberOfLinkedUFIs() && bIsSystemTTGlyph(*pwc))
  461. {
  462. if(!prfnt->prfntSystemTT)
  463. {
  464. WARNING("Invalid prfntSystemTT\n");
  465. return(pgdDefault());
  466. }
  467. if(pto && !(pto->bSystemPartitionInit()))
  468. {
  469. // this call can't fail for the SystemTT case
  470. pto->bPartitionInit(c,0,FALSE);
  471. }
  472. // mark the glyph as coming from a SystemTT font
  473. RFONTTMPOBJ rfo;
  474. rfo.vInit(prfnt->prfntSystemTT);
  475. if(rfo.bValid() &&
  476. (wpgd = (bGetBits ? rfo.pgdGetEudcMetricsPlus(*pwc, this)
  477. : rfo.pgdGetEudcMetrics(*pwc, this))))
  478. {
  479. if (pto)
  480. {
  481. ASSERTGDI(pto->bSystemPartitionInit(),
  482. "wpgdGetLinkMetricsPlus: FontLink partition no initialized\n");
  483. LONG *plPartition = pto->plPartitionGet();
  484. pto->vTTSysGlyphsInc();
  485. plPartition[pwc-pwcInit] = EUDCTYPE_SYSTEM_TT_FONT;
  486. // turn off accelerator since we're going to mess with the driver
  487. *pbAccel = FALSE;
  488. }
  489. return(wpgd);
  490. }
  491. else
  492. {
  493. return(pgdDefault());
  494. }
  495. }
  496. // if the codepoint is not in any linked font or the EUDC information is
  497. // being changed just return the default character
  498. if(!pdco->uNumberOfLinkedUFIs() &&!bIsLinkedGlyph( *pwc ))
  499. {
  500. return( pgdDefault() );
  501. }
  502. // initialize EUDC fonts if we haven't done so already
  503. {
  504. GreAcquireSemaphore(prfnt->hsemEUDC);
  505. if( !( prfnt->flEUDCState & EUDC_INITIALIZED ) )
  506. {
  507. // this value will be decremented in RFONTOBJ::dtHelper()
  508. INCREMENTEUDCCOUNT;
  509. FLINKMESSAGE2(DEBUG_FONTLINK_RFONT,
  510. "wpgdGetLinkMetricsPlus():No request to change EUDC data %d\n", gcEUDCCount);
  511. vInitEUDC( *pdco );
  512. // lock the font cache semaphores for any EUDC rfonts linked to this font
  513. if( prfnt->prfntSysEUDC != NULL )
  514. {
  515. // lock the SystemEUDC RFONT cache
  516. RFONTTMPOBJ rfo( prfnt->prfntSysEUDC );
  517. rfo.vGetCache();
  518. }
  519. if( prfnt->prfntDefEUDC != NULL )
  520. {
  521. RFONTTMPOBJ rfo( prfnt->prfntDefEUDC );
  522. rfo.vGetCache();
  523. }
  524. for( UINT ii = 0; ii < prfnt->uiNumLinks; ii++ )
  525. {
  526. if( prfnt->paprfntFaceName[ii] != NULL )
  527. {
  528. RFONTTMPOBJ rfo( prfnt->paprfntFaceName[ii] );
  529. rfo.vGetCache();
  530. }
  531. }
  532. prfnt->flEUDCState |= EUDC_INITIALIZED;
  533. }
  534. GreReleaseSemaphore(prfnt->hsemEUDC);
  535. }
  536. if (pto && !(pto->bPartitionInit()) )
  537. {
  538. // Sets up partitioning pointers and glyph counts in the ESTROBJ.
  539. if( !(pto->bPartitionInit(c,prfnt->uiNumLinks,TRUE)) )
  540. {
  541. return( pgdDefault() );
  542. }
  543. }
  544. // Find linked font GLYPHDATA
  545. wpgd = FindLinkedGlyphDataPlus(
  546. pdco,pto,*pwc,(COUNT)(pwc-pwcInit),c,pbAccel,FALSE, bGetBits);
  547. if( wpgd == NULL )
  548. {
  549. // load EudcDefault Char GlyphData from "Base font".
  550. wpgd = bGetBits ?
  551. pgdGetEudcMetricsPlus(EudcDefaultChar, NULL) :
  552. pgdGetEudcMetrics(EudcDefaultChar, NULL);
  553. if( wpgd != NULL )
  554. {
  555. return( wpgd );
  556. }
  557. // load EudcDefault Char GlyphData from "Linked font".
  558. wpgd = FindLinkedGlyphDataPlus(pdco,pto,EudcDefaultChar,(COUNT)(pwc-pwcInit),c,pbAccel,TRUE, bGetBits);
  559. if( wpgd != NULL )
  560. {
  561. return( wpgd );
  562. }
  563. // Otherwise return default char of base font.
  564. return( pgdDefault() );
  565. }
  566. return( wpgd );
  567. }
  568. /******************************Public*Routine******************************\
  569. * RFONTOBJ::dtHelper()
  570. *
  571. * Thu 12-Jan-1995 15:00:00 -by- Hideyuki Nagase [hideyukn]
  572. * Rewrote it.
  573. **************************************************************************/
  574. VOID RFONTOBJ::dtHelper(BOOL bReleaseEUDC2)
  575. {
  576. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,"Calling dtHelper()\n");
  577. GreAcquireSemaphore(prfnt->hsemEUDC);
  578. // if SystemTT RFONTOBJ was used release it
  579. if((prfnt->flEUDCState & TT_SYSTEM_INITIALIZED) &&
  580. !(prfnt->flEUDCState & EUDC_NO_CACHE))
  581. {
  582. if (prfnt->prfntSystemTT)
  583. {
  584. RFONTTMPOBJ rfo(prfnt->prfntSystemTT);
  585. rfo.vReleaseCache();
  586. DECREMENTEUDCCOUNT;
  587. }
  588. }
  589. // if EUDC was initizlized for this RFONTOBJ, clean up its.
  590. if( prfnt->flEUDCState & EUDC_INITIALIZED )
  591. {
  592. if(!(prfnt->flEUDCState & EUDC_NO_CACHE))
  593. {
  594. for( INT ii = prfnt->uiNumLinks - 1; ii >= 0; ii-- )
  595. {
  596. if( prfnt->paprfntFaceName[ii] != NULL )
  597. {
  598. RFONTTMPOBJ rfo( prfnt->paprfntFaceName[ii] );
  599. rfo.vReleaseCache();
  600. }
  601. }
  602. if( prfnt->prfntDefEUDC != NULL )
  603. {
  604. RFONTTMPOBJ rfo( prfnt->prfntDefEUDC );
  605. rfo.vReleaseCache();
  606. }
  607. if( prfnt->prfntSysEUDC != NULL )
  608. {
  609. RFONTTMPOBJ rfo( prfnt->prfntSysEUDC );
  610. rfo.vReleaseCache();
  611. }
  612. }
  613. if (bReleaseEUDC2)
  614. {
  615. ASSERTGDI(gcEUDCCount > 0, "gcEUDCCount <= 0\n");
  616. DECREMENTEUDCCOUNT;
  617. }
  618. }
  619. prfnt->flEUDCState &= ~(EUDC_INITIALIZED|TT_SYSTEM_INITIALIZED|EUDC_NO_CACHE);
  620. GreReleaseSemaphore(prfnt->hsemEUDC);
  621. }
  622. /******************************************************************************
  623. * void RFONTOBJ::ComputeEUDCLogfont(EUDCLOGFONT*)
  624. *
  625. * This function computes an EUDCLOGFONT from a base font.
  626. *
  627. *****************************************************************************/
  628. void RFONTOBJ::ComputeEUDCLogfont(EUDCLOGFONT *pEudcLogfont, XDCOBJ& dco)
  629. {
  630. PDEVOBJ pdo(dco.hdev());
  631. LFONTOBJ lfo(dco.pdc->hlfntCur(), &pdo);
  632. PFEOBJ pfeo(prfnt->ppfe);
  633. RFONTTMPOBJ rfoT(prfnt);
  634. DCOBJ dcoT(dco.hdc());
  635. IFIOBJR ifio(pfeo.pifi(),rfoT,dcoT);
  636. BOOL bFixedPitch = FALSE;
  637. if (!lfo.bValid())
  638. return;
  639. pEudcLogfont->fsSelection = ifio.fsSelection();
  640. pEudcLogfont->flBaseFontType = pfo()->flFontType;
  641. pEudcLogfont->lBaseHeight = lfo.lHeight();
  642. pEudcLogfont->lBaseWidth = lfo.lWidth();
  643. pEudcLogfont->lEscapement = lfo.lEscapement();
  644. pEudcLogfont->ulOrientation = lfo.ulOrientation();
  645. LONG lInternalLeading = 0;
  646. if(ifio.bFixedPitch())
  647. bFixedPitch = TRUE;
  648. // We have to try to scale linked font as exactly same size as base font.
  649. if( !(pEudcLogfont->bContinuousScaling = ifio.bContinuousScaling()) )
  650. {
  651. if (dco.pdc->bWorldToDeviceIdentity())
  652. {
  653. // We only need to get the AveCharWidth for FIX_PITCH
  654. if (bFixedPitch)
  655. pEudcLogfont->lBaseWidth = ifio.fwdAveCharWidth();
  656. // these are special case hacks to get better linking with Ms San Serif
  657. // we force a bitmap for size 8 and 10 and also use ascent based
  658. // mapping for all other size.
  659. //
  660. // Old comment:
  661. // for NT 5.0 make this more general
  662. // and make it configurable in the registry.
  663. //
  664. if(!_wcsicmp(ifio.pwszFaceName(), L"Ms Sans Serif"))
  665. {
  666. if(fxMaxExtent() > LTOFX(12) && fxMaxExtent() < LTOFX(17))
  667. {
  668. pEudcLogfont->lBaseHeight = 12;
  669. }
  670. else
  671. {
  672. pEudcLogfont->lBaseHeight =
  673. LONG_FLOOR_OF_FIX(fxMaxAscent() + FIX_HALF);
  674. }
  675. }
  676. else
  677. if(ulFontLinkControl & FLINK_SCALE_EUDC_BY_HEIGHT)
  678. {
  679. pEudcLogfont->lBaseHeight = LONG_FLOOR_OF_FIX(fxMaxExtent() + FIX_HALF);
  680. }
  681. else
  682. {
  683. pEudcLogfont->lBaseHeight = LONG_FLOOR_OF_FIX(fxMaxAscent() + FIX_HALF);
  684. }
  685. }
  686. else
  687. {
  688. if (bFixedPitch)
  689. pEudcLogfont->lBaseWidth = lCvt(efDtoWBase_31(),((LONG) ifio.fwdAveCharWidth()) << 4);
  690. if (ulFontLinkControl & FLINK_SCALE_EUDC_BY_HEIGHT)
  691. {
  692. pEudcLogfont->lBaseHeight = lCvt(efDtoWAscent_31(),(LONG) fxMaxExtent());
  693. }
  694. else
  695. {
  696. pEudcLogfont->lBaseHeight = lCvt(efDtoWAscent_31(),(LONG) fxMaxAscent());
  697. }
  698. }
  699. // Multiply raster interger scaling value.
  700. // (Only for Width, Height was already scaled value.)
  701. if (bFixedPitch)
  702. pEudcLogfont->lBaseWidth *= prfnt->ptlSim.x;
  703. FLINKMESSAGE(DEBUG_FONTLINK_DUMP,"GDISRV:BaseFont is RASTER font\n");
  704. }
  705. else
  706. {
  707. LONG lBaseHeight;
  708. if (dco.pdc->bWorldToDeviceIdentity())
  709. {
  710. lBaseHeight = LONG_FLOOR_OF_FIX(fxMaxExtent() + FIX_HALF);
  711. }
  712. else
  713. {
  714. lBaseHeight = lCvt(efDtoWAscent_31(),(LONG) fxMaxExtent());
  715. }
  716. if (lNonLinearIntLeading() == MINLONG)
  717. {
  718. // Rather than scaling the notional internal leading, try
  719. // to get closer to HINTED internal leading by computing it
  720. // as the difference between the HINTED height and UNHINTED
  721. // EmHeight.
  722. lInternalLeading = lBaseHeight - lCvt(efNtoWScaleAscender(),ifio.fwdUnitsPerEm());
  723. if (bFixedPitch)
  724. pEudcLogfont->lBaseWidth = lCvt(efNtoWScaleBaseline(), ifio.tmAveCharWidth());
  725. }
  726. else
  727. {
  728. // But if the font provider has given us a hinted internal leading,
  729. // just use it.
  730. lInternalLeading =
  731. lCvt(efDtoWAscent_31(),lNonLinearIntLeading());
  732. if (bFixedPitch)
  733. pEudcLogfont->lBaseWidth = lCvt(efDtoWBase_31(), lNonLinearAvgCharWidth());
  734. }
  735. // Check we should eliminate the internal leading for EUDC size.
  736. if( lInternalLeading < 0 )
  737. pEudcLogfont->lBaseHeight = lBaseHeight + lInternalLeading;
  738. else
  739. pEudcLogfont->lBaseHeight = lBaseHeight - lInternalLeading;
  740. if ((pEudcLogfont->lBaseHeight <= 13))
  741. {
  742. if (pEudcLogfont->lBaseHeight == 11 && lBaseHeight >= 12)
  743. pEudcLogfont->lBaseHeight = 12;
  744. else if (pEudcLogfont->lBaseHeight == 13 && lBaseHeight >= 15)
  745. pEudcLogfont->lBaseHeight = 15;
  746. }
  747. }
  748. // if the base font is Raster font. we need to adjust escapement/orientation.
  749. // because they can not generate arbitaraty rotated glyphs.
  750. if(!(ifio.bArbXforms()))
  751. {
  752. if( ifio.b90DegreeRotations() )
  753. {
  754. // font provider can support per 90 degree rotations.
  755. if( pEudcLogfont->ulOrientation )
  756. {
  757. ULONG ulTemp;
  758. ulTemp = lNormAngle(pEudcLogfont->ulOrientation);
  759. pEudcLogfont->ulOrientation =
  760. (ulTemp / ORIENTATION_90_DEG) * ORIENTATION_90_DEG;
  761. if( (dco.pdc->bYisUp()) && (ulTemp % ORIENTATION_90_DEG))
  762. pEudcLogfont->ulOrientation =
  763. lNormAngle(pEudcLogfont->ulOrientation + ORIENTATION_90_DEG);
  764. }
  765. if( pEudcLogfont->lEscapement )
  766. {
  767. LONG lTemp;
  768. lTemp = lNormAngle(pEudcLogfont->lEscapement);
  769. pEudcLogfont->lEscapement =
  770. (lTemp / ORIENTATION_90_DEG) * ORIENTATION_90_DEG;
  771. if( (dco.pdc->bYisUp()) && (lTemp % ORIENTATION_90_DEG))
  772. pEudcLogfont->lEscapement =
  773. lNormAngle(pEudcLogfont->lEscapement + ORIENTATION_90_DEG);
  774. }
  775. }
  776. else
  777. {
  778. // font provider can generate only horizontal glyph
  779. pEudcLogfont->ulOrientation = 0L;
  780. pEudcLogfont->lEscapement = 0L;
  781. }
  782. }
  783. #if DBG
  784. if(gflEUDCDebug & DEBUG_FONTLINK_DUMP)
  785. {
  786. DbgPrint(" Base font face name %ws \n", ifio.pwszFaceName());
  787. DbgPrint("GDISRV:lBaseWidth = %d\n",pEudcLogfont->lBaseWidth);
  788. DbgPrint("GDISRV:lBaseHeight = %d\n",pEudcLogfont->lBaseHeight);
  789. DbgPrint("GDISRV:lInternalL = %d\n",lInternalLeading);
  790. DbgPrint("GDISRV:lEscapement = %d\n",pEudcLogfont->lEscapement);
  791. DbgPrint("GDISRV:lOrientation = %d\n",pEudcLogfont->ulOrientation);
  792. }
  793. #endif
  794. }
  795. /******************************************************************************
  796. * PFE *ppfeFromUFI(PUNIVERSAL_FONT_ID pufi)
  797. *
  798. * Given a UFI, returns a corresponding PFE. This function assume the caller
  799. * has grabed the ghsemPublicPFT semaphore.
  800. *
  801. *****************************************************************************/
  802. PFE *ppfeFromUFI(PUNIVERSAL_FONT_ID pufi)
  803. {
  804. PUBLIC_PFTOBJ pfto;
  805. FHOBJ fho(&pfto.pPFT->pfhUFI);
  806. HASHBUCKET *pbkt;
  807. PFE *ppfeRet = NULL;
  808. pbkt = fho.pbktSearch( NULL, (UINT*)NULL, pufi );
  809. if( pbkt != NULL )
  810. {
  811. PFELINK *ppfel;
  812. for (ppfel = pbkt->ppfelEnumHead ; ppfel; ppfel = ppfel->ppfelNext)
  813. {
  814. PFEOBJ pfeo (ppfel->ppfe);
  815. // if the UFI's match and (in the case of a remote font) the process
  816. // that created the remote font is the same as the current one then
  817. // we've got a match
  818. if(UFI_SAME_FACE(pfeo.pUFI(),pufi) && pfeo.SameProccess())
  819. {
  820. if( pfeo.bDead() )
  821. {
  822. WARNING("MAPPER::bFoundForcedMatch mapped to dead PFE\n");
  823. }
  824. else
  825. {
  826. ppfeRet = ppfel->ppfe;
  827. break;
  828. }
  829. }
  830. }
  831. #if DBG
  832. if (!ppfel)
  833. {
  834. WARNING1("ppfeFromUFI couldn't map to PFE\n");
  835. }
  836. #endif
  837. }
  838. else
  839. {
  840. WARNING("ppfeFromUFI pbkt is NULL\n");
  841. }
  842. return ppfeRet;
  843. }
  844. void RFONTOBJ::vInitEUDCRemote(XDCOBJ& dco)
  845. {
  846. #if DBG
  847. DbgPrint("calling remote vinit\n");
  848. #endif // DBG
  849. if((prfnt->paprfntFaceName != NULL) &&
  850. (prfnt->paprfntFaceName[0] != NULL))
  851. {
  852. // If there is at least one facename link then the remote links must be initialized.
  853. // The set of links for a particular RFONT will never change during a print
  854. // job and the RFONT can only be used for this print-job (PDEV). Thus we
  855. // don't have to check a time stamp or anything else to determine if the links
  856. // have changed and can simply return.
  857. return;
  858. }
  859. // remote UFIs get treated as facename links so first initialize the facename array
  860. if(prfnt->paprfntFaceName == (PRFONT *)NULL)
  861. {
  862. if(dco.uNumberOfLinkedUFIs() > QUICK_FACE_NAME_LINKS)
  863. {
  864. if(!(prfnt->paprfntFaceName =
  865. (PRFONT *)PALLOCMEM(dco.uNumberOfLinkedUFIs() * sizeof(PRFONT),'flnk')))
  866. {
  867. WARNING("vInitEUDCRemote: out of memory\n");
  868. return;
  869. }
  870. }
  871. else
  872. {
  873. prfnt->paprfntFaceName = prfnt->aprfntQuickBuff;
  874. }
  875. }
  876. prfnt->uiNumLinks = 0;
  877. // Lock and Validate the LFONTOBJ user object.
  878. UINT u;
  879. PFEOBJ pfeo(prfnt->ppfe);
  880. PDEVOBJ pdo(dco.hdev());
  881. LFONTOBJ lfo(dco.pdc->hlfntCur(), &pdo);
  882. RFONTTMPOBJ rfoT(prfnt);
  883. DCOBJ dcoT(dco.hdc());
  884. IFIOBJR ifio(pfeo.pifi(),rfoT,dcoT);
  885. // Fill up LogFont for EUDC.
  886. EUDCLOGFONT EudcLogFont;
  887. ComputeEUDCLogfont(&EudcLogFont, dco);
  888. for(u = 0; u < dco.uNumberOfLinkedUFIs(); u++)
  889. {
  890. {
  891. // this set of brackets is to make sure the ppfref descructor gets called
  892. PFE *ppfe;
  893. PFFREFOBJ pffref;
  894. RFONTOBJ rfo;
  895. #if DBG
  896. DbgPrint("Trying to get pfe %d\n", u);
  897. #endif // DBG
  898. {
  899. SEMOBJ so(ghsemPublicPFT);
  900. if(ppfe = ppfeFromUFI(&dco.pufiLinkedFonts()[u]))
  901. {
  902. PFEOBJ pfeo1(ppfe);
  903. pffref.vInitRef(pfeo1.pPFF());
  904. #if DBG
  905. DbgPrint("Found it\n");
  906. #endif // DBG
  907. }
  908. }
  909. if(ppfe)
  910. {
  911. rfo.vInit(dco, ppfe, &EudcLogFont, FALSE);
  912. if(rfo.bValid())
  913. {
  914. #if DBG
  915. DbgPrint("Got a valid RFONT ENTRY\n");
  916. #endif // DBG
  917. prfnt->paprfntFaceName[prfnt->uiNumLinks++] =
  918. rfo.prfntFont();
  919. }
  920. }
  921. }
  922. }
  923. #if DBG
  924. DbgPrint("done: font has %d remote links\n", prfnt->uiNumLinks);
  925. #endif // DBG
  926. }
  927. /******************************Public*Routine******************************\
  928. * RFONTOBJ::vInitEUDC( XDCOBJ )
  929. *
  930. * This routine is called during text out when the first character that isn't
  931. * in the base font is encountered. vInitEUDC will then realize any EUDC RFONTS
  932. * (if they haven't already been realized on previous text outs) so that they
  933. * can possibly be used if the character(s) are in the EUDC fonts.
  934. *
  935. * Thu 12-Jan-1995 15:00:00 -by- Hideyuki Nagase [hideyukn]
  936. * Wrote it.
  937. \**************************************************************************/
  938. VOID RFONTOBJ::vInitEUDC( XDCOBJ& dco )
  939. {
  940. if(dco.uNumberOfLinkedUFIs())
  941. {
  942. vInitEUDCRemote(dco);
  943. return;
  944. }
  945. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  946. "Calling vInitEUDC()\n");
  947. // If we have already initialized System EUDC font, and NOT have
  948. // any FaceName Linked font, we have nothing to do in this function.
  949. PFEOBJ pfeo(prfnt->ppfe);
  950. // In most cases, we have the system EUDC font, at least.
  951. // If the system eudc was initizlied, we might short-cut the eudc realization.
  952. if((prfnt->prfntSysEUDC != NULL) || (!IS_SYSTEM_EUDC_PRESENT()))
  953. {
  954. // if default eudc scheme is disabled or is already initizlied. we can
  955. // short-cut the realization.
  956. if((!bFinallyInitializeFontAssocDefault && !gbSystemDBCSFontEnabled) ||
  957. (prfnt->prfntDefEUDC != NULL) )
  958. {
  959. // if there is no facename eudc for this font or, is already initizlied
  960. // we can return here...
  961. if((pfeo.pGetLinkedFontEntry() == NULL) ||
  962. ((prfnt->paprfntFaceName != NULL) &&
  963. (pfeo.pGetLinkedFontEntry() != NULL) &&
  964. (prfnt->bFilledEudcArray == TRUE) &&
  965. (prfnt->ulTimeStamp == pfeo.ulGetLinkTimeStamp())))
  966. {
  967. return;
  968. }
  969. }
  970. }
  971. // Lock and Validate the LFONTOBJ user object.
  972. PDEVOBJ pdo(dco.hdev());
  973. LFONTOBJ lfo(dco.pdc->hlfntCur(), &pdo);
  974. RFONTTMPOBJ rfoT(prfnt);
  975. DCOBJ dcoT(dco.hdc());
  976. IFIOBJR ifio(pfeo.pifi(),rfoT,dcoT);
  977. // Fill up LogFont for EUDC.
  978. EUDCLOGFONT EudcLogFont;
  979. ComputeEUDCLogfont(&EudcLogFont, dco);
  980. // first handle the system EUDC font
  981. UINT iPfeOffset = (prfnt->bVertical ? PFE_VERTICAL : PFE_NORMAL);
  982. if((prfnt->prfntSysEUDC == NULL) &&
  983. (gappfeSysEUDC[iPfeOffset] != NULL))
  984. {
  985. RFONTOBJ rfo;
  986. PFEOBJ pfeoEudc(gappfeSysEUDC[iPfeOffset]);
  987. IFIOBJ ifioEudc(pfeoEudc.pifi());
  988. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  989. "Connecting System wide EUDC font....\n");
  990. // check Eudc font capacity
  991. if(!bCheckEudcFontCaps(ifioEudc))
  992. {
  993. // font capacity is not match we won't use system eudc.
  994. prfnt->prfntSysEUDC = (RFONT *)NULL;
  995. }
  996. else
  997. {
  998. rfo.vInit( dco,
  999. gappfeSysEUDC[iPfeOffset],
  1000. &EudcLogFont,
  1001. FALSE ); // prfnt->cache.bSmallMetrics );
  1002. if( rfo.bValid() )
  1003. {
  1004. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  1005. "vInitEUDC() -- linking System EUDC\n");
  1006. prfnt->prfntSysEUDC = rfo.prfntFont();
  1007. }
  1008. }
  1009. }
  1010. // next handle default links
  1011. if(bFinallyInitializeFontAssocDefault && (prfnt->prfntDefEUDC == NULL))
  1012. {
  1013. BYTE jWinCharSet = (ifio.lfCharSet());
  1014. BYTE jFamily = (ifio.lfPitchAndFamily() & 0xF0);
  1015. UINT iIndex = (jFamily >> 4);
  1016. BOOL bEnableDefaultLink = FALSE;
  1017. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  1018. "Connecting Default EUDC font....\n");
  1019. // Check default font association is disabled for this charset or not.
  1020. switch (jWinCharSet)
  1021. {
  1022. case ANSI_CHARSET:
  1023. case OEM_CHARSET:
  1024. case SYMBOL_CHARSET:
  1025. //
  1026. // following code is equal to
  1027. //
  1028. // if ((Char == ANSI_CHARSET && fFontAssocStatus & ANSI_ASSOC) ||
  1029. // (Char == OEM_CHARSET && fFontAssocStatus & OEM_ASSOC) ||
  1030. // (Char == SYMBOL_CHARSET && fFontAssocStatus & SYMBOL_ASSOC) )
  1031. //
  1032. if( ((jWinCharSet + 2) & 0xf) & fFontAssocStatus )
  1033. {
  1034. bEnableDefaultLink = TRUE;
  1035. }
  1036. else
  1037. bEnableDefaultLink = FALSE;
  1038. break;
  1039. default:
  1040. bEnableDefaultLink = FALSE;
  1041. break;
  1042. }
  1043. if( bEnableDefaultLink )
  1044. {
  1045. // Check the value is valid or not.
  1046. if( iIndex < NUMBER_OF_FONTASSOC_DEFAULT )
  1047. {
  1048. ASSERTGDI( (FontAssocDefaultTable[iIndex].DefaultFontType == jFamily),
  1049. "GDISRV:FONTASSOC DEFAULT:Family index is wrong\n");
  1050. // if the registry data for specified family's default is ivalid
  1051. // use default.....
  1052. if( !FontAssocDefaultTable[iIndex].ValidRegData )
  1053. {
  1054. iIndex = (NUMBER_OF_FONTASSOC_DEFAULT-1);
  1055. }
  1056. }
  1057. else
  1058. {
  1059. // iIndex is out of range, use default one....
  1060. WARNING("GDISRV:FontAssoc:Family is strange, use default\n");
  1061. iIndex = (NUMBER_OF_FONTASSOC_DEFAULT-1);
  1062. }
  1063. // If vertical font is selected for base font, but the vertical font for
  1064. // default EUDC is not available, but normal font is provided, use normal
  1065. // font.
  1066. if((iPfeOffset == PFE_VERTICAL) &&
  1067. (FontAssocDefaultTable[iIndex].DefaultFontPFEs[PFE_VERTICAL] ==
  1068. PPFENULL) &&
  1069. (FontAssocDefaultTable[iIndex].DefaultFontPFEs[PFE_NORMAL] != PPFENULL))
  1070. {
  1071. iPfeOffset = PFE_NORMAL;
  1072. }
  1073. RFONTOBJ rfo;
  1074. PFEOBJ pfeoEudc(FontAssocDefaultTable[iIndex].DefaultFontPFEs[iPfeOffset]);
  1075. // Check the PFE in default table is valid or not.
  1076. if( pfeoEudc.bValid() )
  1077. {
  1078. IFIOBJ ifioEudc(pfeoEudc.pifi());
  1079. if( !bCheckEudcFontCaps(ifioEudc) )
  1080. {
  1081. prfnt->prfntDefEUDC = (RFONT *)NULL;
  1082. }
  1083. else
  1084. {
  1085. rfo.vInit( dco,
  1086. FontAssocDefaultTable[iIndex].DefaultFontPFEs[iPfeOffset],
  1087. &EudcLogFont,
  1088. FALSE ); // prfnt->cache.bSmallMetrics );
  1089. if( rfo.bValid() )
  1090. {
  1091. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  1092. "vInitEUDC() -- linking default EUDC\n");
  1093. prfnt->prfntDefEUDC = rfo.prfntFont();
  1094. }
  1095. }
  1096. }
  1097. }
  1098. else
  1099. {
  1100. // FontAssociation is disabled for this charset.
  1101. prfnt->prfntDefEUDC = (RFONT *)NULL;
  1102. }
  1103. }
  1104. else
  1105. {
  1106. prfnt->prfntDefEUDC = NULL;
  1107. }
  1108. // next handle all the face name links
  1109. if(pfeo.pGetLinkedFontEntry() != NULL)
  1110. {
  1111. BOOL bNeedToBeFilled = !(prfnt->bFilledEudcArray);
  1112. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,"Connecting Face name EUDC font....\n");
  1113. //
  1114. // if this RFONT has linked RFONT array and its linked font information
  1115. // is dated, just update it here..
  1116. //
  1117. if((prfnt->paprfntFaceName != NULL) &&
  1118. (prfnt->ulTimeStamp != pfeo.ulGetLinkTimeStamp()))
  1119. {
  1120. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,
  1121. "vInitEUDC():This RFONT is dated, now updating...\n");
  1122. //
  1123. // Inactivating old linked RFONT.
  1124. //
  1125. // if Eudc font that is linked to this RFONT was removed, the removed
  1126. // RFONT entry contains NULL, and its Eudc RFONT is already killed during
  1127. // EudcUnloadLinkW() function. then we should inactivate all Eudc RFONT that
  1128. // is still Active (Not Killed)..
  1129. //
  1130. for( UINT ii = 0 ; ii < prfnt->uiNumLinks ; ii++ )
  1131. {
  1132. //
  1133. // Check Eudc RFONT is still active..
  1134. //
  1135. if( prfnt->paprfntFaceName[ii] != NULL )
  1136. {
  1137. RFONTTMPOBJ rfoTmp( prfnt->paprfntFaceName[ii] );
  1138. #if DBG
  1139. if( gflEUDCDebug & DEBUG_FONTLINK_RFONT )
  1140. {
  1141. DbgPrint("vInitEUDC() deactivating linked font %x\n",
  1142. prfnt->paprfntFaceName[ii]);
  1143. }
  1144. #endif
  1145. rfoTmp.bMakeInactiveHelper((PRFONT *)NULL);
  1146. prfnt->paprfntFaceName[ii] = NULL;
  1147. }
  1148. }
  1149. //
  1150. // Free this Array if it was allocated..
  1151. //
  1152. if( prfnt->paprfntFaceName != prfnt->aprfntQuickBuff )
  1153. VFREEMEM( prfnt->paprfntFaceName );
  1154. //
  1155. // Invalidate the pointer.
  1156. //
  1157. prfnt->paprfntFaceName = (PRFONT *)NULL;
  1158. prfnt->uiNumLinks = 0;
  1159. }
  1160. if( prfnt->paprfntFaceName == (PRFONT *)NULL )
  1161. {
  1162. if(pfeo.pGetLinkedFontEntry()->uiNumLinks > QUICK_FACE_NAME_LINKS)
  1163. {
  1164. prfnt->paprfntFaceName =
  1165. (PRFONT *)PALLOCMEM(pfeo.pGetLinkedFontEntry()->uiNumLinks *
  1166. sizeof(PRFONT),'flnk');
  1167. }
  1168. else
  1169. {
  1170. prfnt->paprfntFaceName = prfnt->aprfntQuickBuff;
  1171. }
  1172. bNeedToBeFilled = TRUE;
  1173. }
  1174. if( bNeedToBeFilled )
  1175. {
  1176. PLIST_ENTRY p = pfeo.pGetLinkedFontList()->Flink;
  1177. UINT uiRfont = 0;
  1178. while( p != pfeo.pGetLinkedFontList() )
  1179. {
  1180. #if DBG
  1181. if( gflEUDCDebug & DEBUG_FONTLINK_RFONT )
  1182. {
  1183. DbgPrint("vInitEUDC() -- linking FaceName %d\n", uiRfont);
  1184. }
  1185. #endif
  1186. PPFEDATA ppfeData = CONTAINING_RECORD(p,PFEDATA,linkedFontList);
  1187. //
  1188. // Check this linked font have Vertical facename or not,
  1189. // if it doesn't have, use normal facename...
  1190. //
  1191. UINT iPfeOffsetLocal;
  1192. if( ppfeData->appfe[iPfeOffset] == NULL )
  1193. iPfeOffsetLocal = PFE_NORMAL;
  1194. else
  1195. iPfeOffsetLocal = iPfeOffset;
  1196. PFEOBJ pfeoEudc(ppfeData->appfe[iPfeOffsetLocal]);
  1197. IFIOBJ ifioEudc(pfeoEudc.pifi());
  1198. if( bCheckEudcFontCaps(ifioEudc) )
  1199. {
  1200. RFONTOBJ rfo;
  1201. rfo.vInit( dco,
  1202. ppfeData->appfe[iPfeOffsetLocal],
  1203. &EudcLogFont,
  1204. FALSE ); // prfnt->cache.bSmallMetrics );
  1205. if( rfo.bValid() )
  1206. {
  1207. ASSERTGDI(uiRfont < pfeo.pGetLinkedFontEntry()->uiNumLinks ,
  1208. "uiRfont >= pfeo.uiNumLinks\n");
  1209. prfnt->paprfntFaceName[uiRfont] = rfo.prfntFont();
  1210. //
  1211. // Increase real linked font number.
  1212. //
  1213. uiRfont++;
  1214. }
  1215. }
  1216. p = p->Flink;
  1217. }
  1218. prfnt->uiNumLinks = uiRfont;
  1219. prfnt->ulTimeStamp = pfeo.ulGetLinkTimeStamp();
  1220. prfnt->bFilledEudcArray = TRUE;
  1221. }
  1222. }
  1223. else
  1224. {
  1225. // if this PFE has no eudc link list..
  1226. // the pointer to linked RFONT array should be NULL.
  1227. ASSERTGDI(prfnt->paprfntFaceName == NULL,
  1228. "vInitEUDC():The font has not linked font, but has its Array\n");
  1229. }
  1230. #if DBG
  1231. if(gflEUDCDebug & DEBUG_FONTLINK_DUMP) lfo.vDump();
  1232. #endif
  1233. }
  1234. /******************************Public*Routine******************************\
  1235. * RFONTOBJ::vInit (DCOBJ, PFE*, LONG, FIX)
  1236. *
  1237. * This is a special constructor used for EUDC fonts. Rather than use the
  1238. * LOGFONT currently selected into the DC to map to a PFE, it is passed in
  1239. * a PFE. If lBaseWidth of lBaseHeight is non-zero vInit will try to realize a
  1240. * font with width and height as close as possible to those lBaseWidth/Height.
  1241. *
  1242. * Tue 24-Oct-1995 12:00:00 -by- Hideyuki Nagase [hideyukn]
  1243. * Rewrote it.
  1244. *
  1245. * Thu 23-Feb-1995 10:00:00 -by- Hideyuki Nagase [hideyukn]
  1246. * SmallMetrics support.
  1247. *
  1248. * Fri 25-Mar-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
  1249. * Wrote it.
  1250. \**************************************************************************/
  1251. VOID RFONTOBJ::vInit(
  1252. XDCOBJ &dco,
  1253. PFE *ppfeEUDCFont,
  1254. EUDCLOGFONT *pEudcLogFont,
  1255. BOOL bSmallMetrics
  1256. )
  1257. {
  1258. SEMOBJ sem(ghsemEUDC2);
  1259. BOOL bNeedPaths = dco.pdc->bActive() ? TRUE : FALSE;
  1260. FLINKMESSAGE(DEBUG_FONTLINK_RFONT,"gdisrv!vInit():Initializing EUDC font.\n");
  1261. ASSERTGDI(bSmallMetrics == FALSE,"gdisrv!bSmallMetrics is 1 for EUDC font\n");
  1262. BOOL bRet = FALSE;
  1263. // Get PDEV user object (need for bFindRFONT).
  1264. // This must be done before the ghsemPublicPFT is locked down.
  1265. PDEVOBJ pdo(dco.hdev());
  1266. ASSERTGDI(pdo.bValid(), "gdisrv!RFONTOBJ(dco): bad pdev in dc\n");
  1267. // Lock and Validate the LFONTOBJ user object.
  1268. LFONTOBJ lfo(dco.pdc->hlfntCur(), &pdo);
  1269. if (!lfo.bValid())
  1270. {
  1271. WARNING("gdisrv!RFONTOBJ(dco): bad LFONT handle\n");
  1272. prfnt = PRFNTNULL; // mark RFONTOBJ invalid
  1273. return;
  1274. }
  1275. // Now we're ready to track down this RFONT we want...
  1276. // Compute the Notional to Device transform for this realization.
  1277. PFEOBJ pfeo(ppfeEUDCFont);
  1278. IFIOBJ ifio(pfeo.pifi());
  1279. ASSERTGDI(pfeo.bValid(), "gdisrv!RFONTOBJ(dco): bad ppfe from mapping\n");
  1280. // Set bold and italic simulation flags if neccesary
  1281. FLONG flSim = 0;
  1282. // if base font is originally italialized or simulated, we
  1283. // also generate italic font.
  1284. if ( (pEudcLogFont->flBaseFontType & FO_SIM_ITALIC) ||
  1285. (pEudcLogFont->fsSelection & FM_SEL_ITALIC) )
  1286. {
  1287. flSim |= lfo.flEudcFontItalicSimFlags(ifio.bNonSimItalic(),
  1288. ifio.bSimItalic());
  1289. }
  1290. // If the basefont is BMP font then we only embolden the linked font for Display
  1291. // If the basefont is scalable then we embolden linked font at any device.
  1292. if ( (pdo.bDisplayPDEV() || pEudcLogFont->bContinuousScaling) &&
  1293. ((pEudcLogFont->fsSelection & FM_SEL_BOLD) ||
  1294. (pEudcLogFont->flBaseFontType & FO_SIM_BOLD)))
  1295. {
  1296. flSim |= lfo.flEudcFontBoldSimFlags((USHORT)ifio.lfWeight());
  1297. }
  1298. //
  1299. //
  1300. // We won't set bold simulation flag to font driver.
  1301. // This is for following situation.
  1302. // if the base font is FIXED_PITCH font, and enbolden, then
  1303. // we need to scale EUDC font as same width of based font.
  1304. // but font enbolden simulation is depend on the font driver, we
  1305. // might not get exact same witdh of scaled eudc font.
  1306. //
  1307. //
  1308. // this is needed only by ttfd to support win31 hack: VDMX XFORM QUANTIZING
  1309. // NOTE: in the case that the requested height is 0 we will pick a default
  1310. // value which represent the character height and not the cell height for
  1311. // Win 3.1 compatibility. Thus I have he changed this check to be <= 0
  1312. // from just < 0. [gerritv]
  1313. //
  1314. if (ifio.bTrueType() && (lfo.plfw()->lfHeight <= 0))
  1315. flSim |= FO_EM_HEIGHT;
  1316. // Now we need to check if the base font is going to be antialiased,
  1317. // if so we also want to antialias the linked font, if it is capable of it
  1318. if ((pEudcLogFont->flBaseFontType & FO_GRAY16) && (pfeo.pifi()->flInfo & FM_INFO_4BPP))
  1319. {
  1320. flSim |= (pEudcLogFont->flBaseFontType & (FO_GRAY16 | FO_CLEARTYPE_X));
  1321. }
  1322. // Hack the width of the logfont to get same width of eudc font as base font.
  1323. LONG lWidthSave = lfo.lWidth( pEudcLogFont->lBaseWidth );
  1324. LONG lHeightSave = lfo.lHeight( pEudcLogFont->lBaseHeight );
  1325. ULONG ulOrientationSave = lfo.ulOrientation( pEudcLogFont->ulOrientation );
  1326. ULONG lEscapementSave = lfo.lEscapement( pEudcLogFont->lEscapement );
  1327. FD_XFORM fdx; // realize with this notional to device xform
  1328. POINTL ptlSim; // for bitmap scaling simulations
  1329. if (!ifio.bContinuousScaling())
  1330. {
  1331. WARNING("EUDC font could not be ContinuousScaling\n");
  1332. prfnt = PRFNTNULL; // mark RFONTOBJ invalid
  1333. return;
  1334. }
  1335. else
  1336. {
  1337. ptlSim.x = 1; ptlSim.y = 1; // this will be not used for scalable font...
  1338. }
  1339. bRet = pfeo.bSetFontXform(dco, lfo.plfw(), &fdx,
  1340. 0,
  1341. flSim,
  1342. (POINTL* const) &ptlSim,
  1343. ifio,
  1344. TRUE // font is linked
  1345. );
  1346. // if bSetFontXform() was fail, return here....
  1347. if( !bRet )
  1348. {
  1349. lfo.lWidth( lWidthSave );
  1350. lfo.lHeight( lHeightSave );
  1351. lfo.ulOrientation( ulOrientationSave );
  1352. lfo.lEscapement( lEscapementSave );
  1353. WARNING("gdisrv!RFONTOBJ(dco): failed to compute font transform\n");
  1354. prfnt = PRFNTNULL; // mark RFONTOBJ invalid
  1355. return;
  1356. }
  1357. // Tell PFF about this new reference, and then release the global sem.
  1358. // Note that vInitRef() must be called while holding the semaphore.
  1359. PFFREFOBJ pffref;
  1360. {
  1361. SEMOBJ so(ghsemPublicPFT);
  1362. pffref.vInitRef(pfeo.pPFF());
  1363. }
  1364. // go find the font
  1365. EXFORMOBJ xoWtoD(dco.pdc->mxWorldToDevice());
  1366. ASSERTGDI(xoWtoD.bValid(), "gdisrv!RFONTOBJ(dco) - \n");
  1367. // Attempt to find an RFONT in the lists cached off the PDEV. Its transform,
  1368. // simulation state, style, etc. all must match.
  1369. if ( bFindRFONT(&fdx,
  1370. flSim,
  1371. 0, // lfo.pelfw()->elfStyleSize,
  1372. pdo,
  1373. &xoWtoD,
  1374. ppfeEUDCFont,
  1375. bNeedPaths,
  1376. dco.pdc->iGraphicsMode(),
  1377. bSmallMetrics,
  1378. RFONT_TYPE_UNICODE // must be unicode for EUDC
  1379. ) )
  1380. {
  1381. FLINKMESSAGE2(DEBUG_FONTLINK_RFONT,"EUDC RFONT is %x\n",prfnt);
  1382. // now restore the old width
  1383. lfo.lWidth( lWidthSave );
  1384. lfo.lHeight( lHeightSave );
  1385. lfo.ulOrientation( ulOrientationSave );
  1386. lfo.lEscapement( lEscapementSave );
  1387. // Grab cache semaphore.
  1388. vGetCache();
  1389. dco.pdc->vXformChange(FALSE);
  1390. return;
  1391. }
  1392. // If we get here, we couldn't find an appropriate font realization.
  1393. // Now, we are going to create one just for us to use.
  1394. bRet = bRealizeFont(&dco,
  1395. &pdo,
  1396. lfo.pelfw(),
  1397. ppfeEUDCFont,
  1398. &fdx,
  1399. (POINTL* const) &ptlSim,
  1400. flSim,
  1401. 0, // lfo.pelfw()->elfStyleSize,
  1402. bNeedPaths,
  1403. bSmallMetrics,
  1404. RFONT_TYPE_UNICODE
  1405. );
  1406. // now restore the old width
  1407. lfo.lWidth( lWidthSave );
  1408. lfo.lHeight( lHeightSave );
  1409. lfo.ulOrientation( ulOrientationSave );
  1410. lfo.lEscapement( lEscapementSave );
  1411. if( !bRet )
  1412. {
  1413. WARNING("gdisrv!RFONTOBJ(dco): realization failed, RFONTOBJ invalidated\n");
  1414. prfnt = PRFNTNULL; // mark RFONTOBJ invalid
  1415. return;
  1416. }
  1417. ASSERTGDI(bValid(), "gdisrv!RFONTOBJ(dco): invalid hrfnt from realization\n");
  1418. // We created a new RFONT, we better hold the PFF reference!
  1419. pffref.vKeepIt();
  1420. // Finally, grab the cache semaphore.
  1421. vGetCache();
  1422. dco.pdc->vXformChange(FALSE);
  1423. FLINKMESSAGE2(DEBUG_FONTLINK_RFONT,"EUDC RFONT is %x\n",prfnt);
  1424. return;
  1425. }
  1426. /******************************Public*Routine******************************\
  1427. * BOOL RFONTOBJ::bIsLinkedGlyph (WCHAR wc)
  1428. *
  1429. * Does a quick check to see if a character is in either the system EUDC
  1430. * font or a font that has been linked to this RFONT.
  1431. *
  1432. * Tue 17-Jan-1995 14:00:00 -by- Hideyuki Nagase [hideyukn]
  1433. * Rewrote it.
  1434. *
  1435. * Wed 11-Aug-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
  1436. * Wrote it.
  1437. \**************************************************************************/
  1438. #define IS_PRIVATE_EUDC_AREA(wc) \
  1439. (((wc) >= 0xE000) && ((wc) <= 0xF8FF))
  1440. BOOL RFONTOBJ::bIsLinkedGlyph( WCHAR wc )
  1441. {
  1442. GreAcquireSemaphore( ghsemEUDC1 );
  1443. // we don't release ghsemEUDC1 mutex here, we have to guard the current eudc
  1444. // link data. All of the API that change eudc data, try to hold this
  1445. // mutex, if we hold it, nobody can process the request...
  1446. //
  1447. // if another thread will change eudc link between this thread is in after
  1448. // release the mutex (end of this function) and before we increment gcEUDCCount
  1449. // in vInitEUDC(). In the case, this function might return TRUE for non-linked
  1450. // char or return FALSE for linked char, but we don't need to worry about this.
  1451. // because following line in wpgdGetLinkMetricsPlus() will returns NULL and
  1452. // we will return default char. the cost is only time..
  1453. BOOL bRet = FALSE;
  1454. // EudcDefaultChar should be displayed for 'Private User Area', when there is no
  1455. // font are linked. (font's default character should not be came up).
  1456. if( IS_PRIVATE_EUDC_AREA(wc) )
  1457. {
  1458. bRet = TRUE;
  1459. }
  1460. if( (bRet == FALSE) && IS_SYSTEM_EUDC_PRESENT() && IS_IN_SYSTEM_EUDC(wc) )
  1461. {
  1462. bRet = TRUE;
  1463. }
  1464. if( (bRet == FALSE) && bFinallyInitializeFontAssocDefault )
  1465. {
  1466. //
  1467. // THIS CODEPATH SHOULD BE OPTIMIZED....
  1468. //
  1469. // UNDER_CONSTRUCTION.
  1470. //
  1471. UINT iPfeOffset = (prfnt->bVertical ? PFE_VERTICAL : PFE_NORMAL);
  1472. PFEOBJ pfeo(prfnt->ppfe);
  1473. IFIOBJ ifio(pfeo.pifi());
  1474. BYTE jFamily = (ifio.lfPitchAndFamily() & 0xF0);
  1475. UINT iIndex = (jFamily >> 4);
  1476. //
  1477. // Check the value is valid or not.
  1478. //
  1479. if( iIndex < NUMBER_OF_FONTASSOC_DEFAULT )
  1480. {
  1481. ASSERTGDI( (FontAssocDefaultTable[iIndex].DefaultFontType == jFamily),
  1482. "GDISRV:FONTASSOC DEFAULT:Family index is wrong\n");
  1483. //
  1484. // if the registry data for specified family's default is ivalid
  1485. // use default.....
  1486. //
  1487. if( !FontAssocDefaultTable[iIndex].ValidRegData )
  1488. {
  1489. iIndex = (NUMBER_OF_FONTASSOC_DEFAULT-1);
  1490. }
  1491. }
  1492. else
  1493. {
  1494. //
  1495. // iIndex is out of range, use default..
  1496. //
  1497. WARNING("GDISRV:FontAssoc:Family is strange, use default\n");
  1498. iIndex = (NUMBER_OF_FONTASSOC_DEFAULT-1);
  1499. }
  1500. //
  1501. // If vertical font is selected for base font, but the vertical font for
  1502. // default EUDC is not available, but normal font is provided, use normal
  1503. // font.
  1504. //
  1505. if( (iPfeOffset == PFE_VERTICAL) &&
  1506. (FontAssocDefaultTable[iIndex].DefaultFontPFEs[PFE_VERTICAL] == PPFENULL) &&
  1507. (FontAssocDefaultTable[iIndex].DefaultFontPFEs[PFE_NORMAL] != PPFENULL))
  1508. {
  1509. iPfeOffset = PFE_NORMAL;
  1510. }
  1511. PFEOBJ pfeoEudc(FontAssocDefaultTable[iIndex].DefaultFontPFEs[iPfeOffset]);
  1512. //
  1513. // Check the PFE in default table is valid or not.
  1514. //
  1515. if( pfeoEudc.bValid() )
  1516. {
  1517. if( IS_IN_FACENAME_LINK( pfeoEudc.pql(), wc ))
  1518. {
  1519. bRet = TRUE;
  1520. }
  1521. }
  1522. }
  1523. else
  1524. if(gbSystemDBCSFontEnabled)
  1525. {
  1526. PFEOBJ pfeo(prfnt->ppfe);
  1527. if(pfeo.bSBCSSystemFont())
  1528. {
  1529. // we assume that the set of glyphs is the same for the vertical and
  1530. // non vertical PFE's so for simplicity always use the normal pfe.
  1531. PFEOBJ pfeSystemDBCSFont(gappfeSystemDBCS[PFE_NORMAL]);
  1532. ASSERTGDI(pfeSystemDBCSFont.bValid(),
  1533. "bIsLinkedGlyph: invalid SystemDBCSFont pfe\n");
  1534. if(IS_IN_FACENAME_LINK(pfeSystemDBCSFont.pql(),wc))
  1535. {
  1536. bRet = TRUE;
  1537. }
  1538. }
  1539. }
  1540. // Walk through FaceName link list if we haven't found it yet.
  1541. if( bRet == FALSE )
  1542. {
  1543. //
  1544. // Is this a FaceName EUDC character ?
  1545. //
  1546. UINT iPfeOffset = (prfnt->bVertical ? PFE_VERTICAL : PFE_NORMAL);
  1547. PFEOBJ pfeo(prfnt->ppfe);
  1548. PLIST_ENTRY p = pfeo.pGetLinkedFontList()->Flink;
  1549. //
  1550. // Scan the linked font list for this base font.
  1551. //
  1552. while( p != pfeo.pGetLinkedFontList() )
  1553. {
  1554. PPFEDATA ppfeData = CONTAINING_RECORD(p,PFEDATA,linkedFontList);
  1555. //
  1556. // Check this linked font have Vertical facename or not,
  1557. // if it doesn't have, use normal facename...
  1558. //
  1559. UINT iPfeOffsetLocal;
  1560. if( ppfeData->appfe[iPfeOffset] == NULL )
  1561. iPfeOffsetLocal = PFE_NORMAL;
  1562. else
  1563. iPfeOffsetLocal = iPfeOffset;
  1564. PFEOBJ pfeoEudc(ppfeData->appfe[iPfeOffsetLocal]);
  1565. ASSERTGDI( pfeoEudc.pql() != NULL ,
  1566. "bIsLinkedGlyph() pfeoEudc.pql() == NULL\n" );
  1567. if(IS_IN_FACENAME_LINK( pfeoEudc.pql(), wc ))
  1568. {
  1569. bRet = TRUE;
  1570. break;
  1571. }
  1572. p = p->Flink;
  1573. }
  1574. }
  1575. GreReleaseSemaphore( ghsemEUDC1 );
  1576. return(bRet);
  1577. }
  1578. /******************************Public*Routine******************************\
  1579. * BOOL STROBJ_bEnumLinked (pstro,pc,ppgpos)
  1580. *
  1581. * The glyph enumerator.
  1582. *
  1583. * History:
  1584. * Tue 28-Sep-1993 11:37:00 -by- Gerrit van Wingerden
  1585. * Converted to a special helper function to handle linked fonts.
  1586. *
  1587. * Tue 17-Mar-1992 10:35:05 -by- Charles Whitmer [chuckwh]
  1588. * Simplified it and gave it the quick exit. Also let drivers call here
  1589. * direct.
  1590. *
  1591. * 02-Oct-1991 -by- Bodin Dresevic [BodinD]
  1592. * Wrote it.
  1593. \**************************************************************************/
  1594. BOOL STROBJ_bEnumLinked(ESTROBJ *peso, ULONG *pc,PGLYPHPOS *ppgpos)
  1595. {
  1596. // Quick exit.
  1597. if( peso->cgposCopied == 0 )
  1598. {
  1599. for( peso->plNext = peso->plPartition, peso->pgpNext = peso->pgpos;
  1600. *(peso->plNext) != peso->lCurrentFont;
  1601. (peso->pgpNext)++, (peso->plNext)++ );
  1602. {
  1603. }
  1604. }
  1605. else
  1606. {
  1607. if( peso->cgposCopied == peso->cGlyphs )
  1608. {
  1609. // no more glyphs so just return
  1610. *pc = 0;
  1611. return(FALSE);
  1612. }
  1613. else
  1614. {
  1615. // find next glyph
  1616. for( (peso->plNext)++, (peso->pgpNext)++;
  1617. *(peso->plNext) != (peso->lCurrentFont);
  1618. (peso->pgpNext)++, (peso->plNext)++ );
  1619. {
  1620. }
  1621. }
  1622. }
  1623. if (peso->prfo == NULL) // check for journaling
  1624. {
  1625. WARNING("ESTROBJ::bEnum(), bitmap font, prfo == NULL\n");
  1626. *pc = 0;
  1627. return(FALSE);
  1628. }
  1629. if( peso->prfo->cGetGlyphData(1,peso->pgpNext) == 0 )
  1630. {
  1631. WARNING("couldn't get glyph for some reason\n");
  1632. *pc = 0;
  1633. return(FALSE);
  1634. }
  1635. peso->cgposCopied += 1; // update enumeration state
  1636. *pc = 1;
  1637. *ppgpos = peso->pgpNext;
  1638. return(peso->cgposCopied < peso->cGlyphs); // TRUE => more to come.
  1639. }
  1640. /******************************Public*Routine******************************\
  1641. * VOID ESTROBJ fxBaseLineAdjust( _fxBaseLineAdjust )
  1642. *
  1643. * History:
  1644. * 24-Dec-1993 -by- Hideyuki Nagase
  1645. * Wrote it.
  1646. \**************************************************************************/
  1647. VOID ESTROBJ::ptlBaseLineAdjustSet( POINTL& _ptlBaseLineAdjust )
  1648. {
  1649. INT ii;
  1650. UINT uFound;
  1651. ptlBaseLineAdjust = _ptlBaseLineAdjust;
  1652. if( !(ptlBaseLineAdjust.x || ptlBaseLineAdjust.y) )
  1653. return;
  1654. for( ii = 0,uFound = 0 ; uFound < cGlyphs ; ii++ )
  1655. {
  1656. if( plPartition[ii] == lCurrentFont )
  1657. {
  1658. pgpos[ii].ptl.x += ptlBaseLineAdjust.x;
  1659. pgpos[ii].ptl.y += ptlBaseLineAdjust.y;
  1660. uFound++;
  1661. }
  1662. }
  1663. }
  1664. /******************************Public*Routine******************************\
  1665. * BOOL ESTROBJ bPartitionInit( c, uiNumLinks )
  1666. *
  1667. * History:
  1668. * 29-Nov-1995 -by- Hideyuki Nagase
  1669. * Add initialize for FaceNameGlyphs array.
  1670. *
  1671. * 29-Sep-1993 -by- Gerrit van Wingerden
  1672. * Wrote it.
  1673. \**************************************************************************/
  1674. BOOL ESTROBJ::bPartitionInit(COUNT c, UINT uiNumLinks, BOOL bEudcInit)
  1675. {
  1676. // Always initialize at least for the SystemTTEUDC Font. We can't initialize
  1677. // the EUDC specific stuff until we've called RFONTOBJ::vInitEUDC, something
  1678. // we won't do when just outputing System DBCS glyphs
  1679. // the first thing we should do is clear the SO_ZERO_BEARINGS and
  1680. // SO_CHAR_INC_EQUAL_BM_BASE flags in the TEXOBJ since this will turn
  1681. // off potentially fatal optimizations in the H3 case.
  1682. flAccel &= ~(SO_CHAR_INC_EQUAL_BM_BASE|SO_ZERO_BEARINGS);
  1683. if(!(flTO & TO_SYS_PARTITION))
  1684. {
  1685. plPartition = (LONG*) &pgpos[c];
  1686. pwcPartition = (WCHAR*) &plPartition[c];
  1687. RtlZeroMemory((VOID*)plPartition, c * sizeof(LONG));
  1688. pacFaceNameGlyphs = NULL;
  1689. cSysGlyphs = 0;
  1690. cDefGlyphs = 0;
  1691. cTTSysGlyphs = 0;
  1692. flTO |= TO_SYS_PARTITION;
  1693. }
  1694. if(bEudcInit)
  1695. {
  1696. if( uiNumLinks >= QUICK_FACE_NAME_LINKS )
  1697. {
  1698. pacFaceNameGlyphs = (ULONG *) PALLOCMEM(uiNumLinks * sizeof(UINT),'flnk');
  1699. if (pacFaceNameGlyphs == (ULONG *) NULL)
  1700. {
  1701. // if we fail allocate memory, we just cancel eudc output.
  1702. return (FALSE);
  1703. }
  1704. flTO |= TO_ALLOC_FACENAME;
  1705. }
  1706. else
  1707. {
  1708. pacFaceNameGlyphs = acFaceNameGlyphs;
  1709. RtlZeroMemory((VOID*) pacFaceNameGlyphs, uiNumLinks * sizeof(UINT));
  1710. }
  1711. flTO |= TO_PARTITION_INIT;
  1712. }
  1713. return (TRUE);
  1714. }
  1715. /****************************************************************************
  1716. * RFONTOBJ::GetLinkedFontUFIs
  1717. *
  1718. * This routine returns the UFI's for the font(s) that are linked to this
  1719. * RFONT. If pufi is NULL, simply returns the number of UFI's linked to
  1720. * this RFONT.
  1721. *
  1722. *****************************************************************************/
  1723. INT RFONTOBJ::GetLinkedFontUFIs(XDCOBJ& dco, PUNIVERSAL_FONT_ID pufi, INT NumUFIs)
  1724. {
  1725. UINT u;
  1726. INT UFICount = 0;
  1727. // check pui
  1728. if (NumUFIs && pufi == NULL)
  1729. {
  1730. WARNING("RFONTOBJ::GetLinkedFontUFIs() pufi == NULL but NumUFIs != 0\n");
  1731. return (0);
  1732. }
  1733. // initialize system TT font if applicable
  1734. if(prfnt->bIsSystemFont)
  1735. {
  1736. if((!prfnt->prfntSystemTT) && !bInitSystemTT(dco))
  1737. {
  1738. WARNING("Error initializing TT system font 5\n");
  1739. return(0);
  1740. }
  1741. prfnt->flEUDCState |= EUDC_NO_CACHE;
  1742. }
  1743. // initialize EUDC fonts if we haven't done so already
  1744. {
  1745. GreAcquireSemaphore(prfnt->hsemEUDC);
  1746. if( !( prfnt->flEUDCState & EUDC_INITIALIZED ) )
  1747. {
  1748. // this value will be decremented in RFONTOBJ::dtHelper()
  1749. INCREMENTEUDCCOUNT;
  1750. vInitEUDC(dco);
  1751. prfnt->flEUDCState |= (EUDC_INITIALIZED | EUDC_NO_CACHE);
  1752. }
  1753. GreReleaseSemaphore(prfnt->hsemEUDC);
  1754. }
  1755. if(prfnt->prfntSystemTT)
  1756. {
  1757. if(UFICount++ < NumUFIs)
  1758. {
  1759. RFONTTMPOBJ rfo(prfnt->prfntSystemTT);
  1760. rfo.vUFI(pufi);
  1761. pufi++;
  1762. }
  1763. }
  1764. for(u = 0; u < prfnt->uiNumLinks; u++)
  1765. {
  1766. ASSERTGDI(prfnt->paprfntFaceName[u],"GDI:uGetLinkedFonts: null facename font\n");
  1767. if(UFICount++ < NumUFIs)
  1768. {
  1769. RFONTTMPOBJ rfo(prfnt->paprfntFaceName[u]);
  1770. rfo.vUFI(pufi);
  1771. pufi++;
  1772. }
  1773. }
  1774. if(prfnt->prfntDefEUDC)
  1775. {
  1776. if(UFICount++ < NumUFIs)
  1777. {
  1778. RFONTTMPOBJ rfo(prfnt->prfntDefEUDC);
  1779. rfo.vUFI(pufi);
  1780. pufi++;
  1781. }
  1782. }
  1783. if(prfnt->prfntSysEUDC)
  1784. {
  1785. if(UFICount++ < NumUFIs)
  1786. {
  1787. RFONTTMPOBJ rfo(prfnt->prfntSysEUDC);
  1788. rfo.vUFI(pufi);
  1789. pufi++;
  1790. }
  1791. }
  1792. return(UFICount);
  1793. }