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.

520 lines
19 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: lfntobj.cxx
  3. *
  4. * Non-inline methods for logical font 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. \**************************************************************************/
  12. #include "precomp.hxx"
  13. #include "winsta.h"
  14. extern PW32PROCESS gpidSpool;
  15. extern "C" USHORT gProtocolType;
  16. #define IsRemoteConnection() (gProtocolType != PROTOCOL_CONSOLE)
  17. /******************************Public*Routine******************************\
  18. * GreSetLFONTOwner
  19. *
  20. * Set the owner of the LFONT
  21. *
  22. \**************************************************************************/
  23. BOOL
  24. GreSetLFONTOwner(
  25. HLFONT hlfnt,
  26. W32PID lPid)
  27. {
  28. if (lPid == OBJECT_OWNER_CURRENT)
  29. {
  30. lPid = W32GetCurrentPID();
  31. }
  32. return(HmgSetOwner((HOBJ)hlfnt, lPid, LFONT_TYPE));
  33. }
  34. /******************************Public*Routine******************************\
  35. * LFONTOBJ::LFONTOBJ (HLFONT hlfnt, PDEVOBJ * ppdo)
  36. *
  37. * Constructor for a logical font user object.
  38. *
  39. * This constructor is a little trickier than most because the handle coming
  40. * in may reference one of the "aliased" stock fonts. These stock fonts, rather
  41. * than representing a single "wish list" of attributes, represent a set of
  42. * such lists. Which member of the set is being referenced is determined by
  43. * the calling application's default display or PDEV (i.e., we ask the PDEV
  44. * for the real HLFONT handle).
  45. *
  46. * The strategy is the constructor locks the handle passed in and checks the
  47. * type. If its not an aliased LFONT, then we're done. If it is an aliased
  48. * font, the aliased HLFONT handle is released and a PDEVOBJ is queried for
  49. * the appropriate HFLONT handle to lock.
  50. *
  51. * History:
  52. * Thu 23-Sep-1993 -by- Patrick Haluptzok [patrickh]
  53. * SSS
  54. *
  55. * 30-Oct-1990 -by- Gilman Wong [gilmanw]
  56. * Wrote it.
  57. \**************************************************************************/
  58. LFONTOBJ::LFONTOBJ (HLFONT hlfnt, PDEVOBJ* ppdo)
  59. {
  60. plfnt = (PLFONT) HmgShareLock((HOBJ)hlfnt, LFONT_TYPE);
  61. //
  62. // Check for aliased LFONT.
  63. //
  64. if ((plfnt != NULL) && (plfnt->fl & LF_FLAG_ALIASED))
  65. {
  66. HDEV hDev = UserGetHDEV();
  67. //
  68. // This is an aliased font. Save type.
  69. //
  70. LFTYPE lftSave = plfnt->lft;
  71. // Release the aliased LFONT.
  72. DEC_SHARE_REF_CNT_LAZY_DEL_LOGFONT(plfnt);
  73. plfnt = NULL;
  74. PDEVOBJ pdo(hDev);
  75. if (!ppdo)
  76. {
  77. ppdo = &pdo;
  78. }
  79. if (ppdo->bValid())
  80. {
  81. //
  82. // Grab appropriate HLFONT from the PDEV.
  83. //
  84. switch (lftSave)
  85. {
  86. case LF_TYPE_DEVICE_DEFAULT:
  87. hlfnt = ppdo->hlfntDefault();
  88. break;
  89. case LF_TYPE_ANSI_FIXED:
  90. hlfnt = ppdo->hlfntAnsiFixed();
  91. break;
  92. case LF_TYPE_ANSI_VARIABLE:
  93. hlfnt = ppdo->hlfntAnsiVariable();
  94. break;
  95. default:
  96. RIP("LFONTOBJ has invalid type for aliased font");
  97. }
  98. plfnt = (PLFONT) HmgShareLock((HOBJ)hlfnt, LFONT_TYPE);
  99. }
  100. }
  101. }
  102. /******************************Public*Routine******************************\
  103. * LFONTOBJ::ppfeMapFont
  104. *
  105. * Note:
  106. * RFONTOBJ constructor, which is the only function (so far) to call
  107. * this, grabs the ghsemPublicPFT semaphore prior to calling this to
  108. * make PFT tree stable before scanning it during mapping.
  109. *
  110. * Returns:
  111. * Handle to a realized font (HRFONT) that is a close or exact match to
  112. * this logical font. HRFONT_INVALID returned if an error occurs.
  113. *
  114. * History:
  115. * 24-Sept-1996 -by- Xudong Wu [TessieW]
  116. * If a suitable pfe found in map cache, we still need to check whether the
  117. * current process has the right to map the font.
  118. *
  119. * 11-Dec-1990 -by- Gilman Wong [gilmanw]
  120. * Wrote it.
  121. \**************************************************************************/
  122. PFE *LFONTOBJ::ppfeMapFont (
  123. XDCOBJ& dco,
  124. FLONG *pflSim,
  125. POINTL *pptlSim,
  126. FLONG *pflAboutMatch,
  127. BOOL bIndexFont
  128. )
  129. {
  130. int i; // index into mapcache array
  131. MAPCACHE* mapcache = plfnt->mapcache;
  132. PFE* ppfe = PPFENULL; // return value
  133. MATRIX& matrix = dco.pdc->mxWorldToDevice();
  134. HDEV hdev = dco.hdev();
  135. ULONG iBitmapFormat = 0; // important in anti-aliased case
  136. FLONG flGray = 0;
  137. #if DBG
  138. if (gflFontDebug & DEBUG_PPFEMAPFONT)
  139. {
  140. KdPrint(("Font Mapping: \"%ws\" hlfnt = %p hdc = %p\n",plfnt->wcCapFacename, hlfnt(),dco.hdc()));
  141. KdBreakPoint();
  142. }
  143. #endif
  144. // If we are in a path bracket, we never look in the map cache (the mapping
  145. // is also never put in the cache). We'll just run the font mapper. We
  146. // could cache path bracketed font mappings, but we would have to add a flag
  147. // or type to the MAPCACHE structure and add an extra comparison inside the
  148. // mapcache scanning loop. Since we currently consider text in paths to be
  149. // the exception rather than the rule, we have decided not eat the cost of
  150. // of the extra compare in the pathological case rather than in the common
  151. // case.
  152. if (!dco.pdc->bActive())
  153. {
  154. // If anitaliasing is requested and possible then set FO_GRAY16 in flGray
  155. BYTE jQual = plfw()->lfQuality;
  156. if (dco.bDisplay() || dco.dctp() == DCTYPE_MEMORY)
  157. {
  158. if
  159. (
  160. ((gulFontInformation & FE_AA_ON) && jQual != NONANTIALIASED_QUALITY) ||
  161. (jQual == ANTIALIASED_QUALITY) || (jQual == CLEARTYPE_QUALITY) || (jQual == CLEARTYPE_NATURAL_QUALITY)
  162. )
  163. {
  164. // WINBUG 152724 07/31/2000 claudebe
  165. // Terminal server now allow more than 256 colors. Text antialiazing rendered on the server is very slow.
  166. // We decided for Whistler to turn off text antialiazing under terminal client session.
  167. // For Blackcomb we will provide the terminal server team with a text antialiazing library that they can use on the // client to generate text antialiazing on the client.
  168. if (!IsRemoteConnection() && (dco.pdc->bHasSurface()))
  169. {
  170. // Acquire the handle manager lock while we look at the
  171. // surface to protect against dynamic mode changing.
  172. MLOCKFAST mo;
  173. switch ( iBitmapFormat = dco.pdc->pSurface()->so.iBitmapFormat )
  174. {
  175. case BMF_16BPP:
  176. case BMF_24BPP:
  177. case BMF_32BPP:
  178. flGray = FO_GRAY16; // request antialiased font
  179. if ( jQual == CLEARTYPE_NATURAL_QUALITY )
  180. flGray |= FO_CLEARTYPENATURAL_X | FO_CLEARTYPE_X;
  181. else if ((jQual == CLEARTYPE_QUALITY) || (gulFontInformation & FE_CT_ON))
  182. flGray |= FO_CLEARTYPE_X;
  183. break;
  184. default:
  185. break;
  186. }
  187. }
  188. }
  189. }
  190. // Scan the map cache for a suitable mapping.
  191. // Skip the cache if it is glyph index.
  192. if (!bIndexFont)
  193. {
  194. for ( i = 0; i < plfnt->cMapsInCache; i += 1)
  195. {
  196. // For a mapping to be suitable, the device must match AND
  197. // the transforms (neglecting translation) must match.
  198. // There are more restrictions for antialiased text (see below)
  199. if ( (hdev == mapcache[i].hdev) &&
  200. (mapcache[i].efM11 == matrix.efM11) &&
  201. (mapcache[i].efM12 == matrix.efM12) &&
  202. (mapcache[i].efM21 == matrix.efM21) &&
  203. (mapcache[i].efM22 == matrix.efM22)
  204. )
  205. {
  206. // We found it. Check that it's still valid.
  207. HPFECOBJ pfecobj(mapcache[i].hpfec);
  208. PFEOBJ pfeo(pfecobj.GetPFE(mapcache[i].iFont));
  209. if ( !pfeo.bValid() )
  210. {
  211. WARNING1("Invalid ppfe in mapping cache\n");
  212. }
  213. else
  214. {
  215. // The cached notional to device transform is unchanged.
  216. // The cached mapping is good if:
  217. //
  218. //
  219. // A. the application is requesting antialiased text and
  220. // the cached text was also requested to be antialiased
  221. // Moreover, in the antialiased case, the bitmap format
  222. // must be the same.
  223. // or
  224. //
  225. // B. the application is not requesting antialiasing
  226. // and the cached text was not requested to be antialiased
  227. // Need to check whether the current process has the right
  228. // to mapping the font.
  229. if (pfeo.bEmbPvtOk() || (gpidSpool == (PW32PROCESS)W32GetCurrentProcess()))
  230. {
  231. if ( flGray ) // requesting antialiased text?
  232. { // yes
  233. if ((mapcache[i].flSim & (FO_GRAY16 | FO_CLEARTYPE_X)) == flGray)
  234. { // yes
  235. if (iBitmapFormat == mapcache[i].iBitmapFormat) // same format?
  236. { // yes
  237. ppfe = pfeo.ppfeGet(); // cached mapping is good
  238. }
  239. }
  240. }
  241. else if ( !(mapcache[i].flSim & FO_GRAY16) )
  242. {
  243. ppfe = pfeo.ppfeGet();
  244. }
  245. }
  246. }
  247. if ( ppfe ) // cached mapping good?
  248. { // yes -- update simulation flags
  249. *pflSim = mapcache[i].flSim;
  250. pptlSim->x = mapcache[i].ptlSim.x;
  251. pptlSim->y = mapcache[i].ptlSim.y;
  252. *pflAboutMatch = mapcache[i].flAboutMatch;
  253. break;
  254. }
  255. else
  256. { // cached mapping is not good
  257. // Remove the mapping so we don't run into it again.
  258. if ( (i+1) < plfnt->cMapsInCache )
  259. {
  260. RtlMoveMemory
  261. (
  262. (PVOID) &mapcache[i],
  263. (PVOID) &mapcache[i+1],
  264. (UINT) (((PBYTE) &mapcache[plfnt->cMapsInCache]) - ((PBYTE) &mapcache[i+1]))
  265. );
  266. }
  267. plfnt->cMapsInCache -= 1; // correct the map count
  268. // current position is no longer a rejected candidate,
  269. // so go back one index
  270. i -= 1;
  271. }
  272. }
  273. }
  274. }
  275. }
  276. if ( !ppfe )
  277. {
  278. // Call the font mapper with the Win 3.1 compatible weighting and max
  279. // penalties. If the LOGFONT is a stock object, transforms are ignored
  280. // (i.e., the LOGFONT is implied to be in pixel coordinates (MM_TEXT)).
  281. //
  282. // The result is stuffed into the map cache if we are not in a
  283. // path bracket.
  284. //
  285. // Note. ppfeGetAMatch() modifies sets FO_SIM_BOLD and FO_SIM_ITALIC
  286. // in *pflSim as is necessary -- it does not set FO_GRAY16
  287. // which is set in this routine after this call.
  288. ppfe = ppfeGetAMatch(
  289. dco,
  290. pelfw(),
  291. plfnt->wcCapFacename,
  292. ULONG_MAX-1,
  293. (plfnt->fl & LF_FLAG_STOCK) ? FM_BIT_PIXEL_COORD : 0,
  294. pflSim,
  295. pptlSim,
  296. pflAboutMatch,
  297. bIndexFont
  298. );
  299. PFEOBJ pfeo(ppfe);
  300. if ( !pfeo.bValid() )
  301. {
  302. RIP("Bad return value from ppfeGetAMatch\n");
  303. }
  304. else if (!dco.pdc->bActive())
  305. {
  306. ASSERTGDI( !(*pflSim & FO_GRAY16), "ppfeGetAMatch erroneously set FO_GRAY16\n");
  307. // If the application is requesting antialiased text and the font is
  308. // capable then we set the FO_GRAY16 bit in *pflSim. Note that this
  309. // does not guarantee that the font driver will antialiase the text
  310. // only that GDI will suggest to the font driver that the font
  311. // be antialiased.
  312. if (flGray && (pfeo.pifi()->flInfo & FM_INFO_4BPP))
  313. {
  314. *pflSim |= FO_GRAY16;
  315. if
  316. (
  317. // (dco.flGraphicsCaps2() & GCAPS2_CLEARTYPE_X) && // commented out only for now
  318. (dco.bDisplay() || (dco.dctp() == DCTYPE_MEMORY)) &&
  319. dco.pdc->bHasSurface() &&
  320. (pfeo.pifi()->flInfo & FM_INFO_TECH_TRUETYPE) && // to be removed if ps fonts start supporting ClearType
  321. (pelfw()->elfEnumLogfontEx.elfLogFont.lfQuality != ANTIALIASED_QUALITY) &&
  322. ((pelfw()->elfEnumLogfontEx.elfLogFont.lfQuality == CLEARTYPE_QUALITY) ||
  323. (pelfw()->elfEnumLogfontEx.elfLogFont.lfQuality == CLEARTYPE_NATURAL_QUALITY) ||
  324. ((gulFontInformation & FE_CT_ON) && (gulFontInformation & FE_AA_ON)))
  325. )
  326. {
  327. if(pelfw()->elfEnumLogfontEx.elfLogFont.lfQuality == CLEARTYPE_NATURAL_QUALITY)
  328. *pflSim |= FO_CLEARTYPENATURAL_X | FO_CLEARTYPE_X;
  329. else
  330. *pflSim |= FO_CLEARTYPE_X;
  331. }
  332. }
  333. // Not in cache, so do the map and put it in the cache
  334. // if it is not glyph index.
  335. if (!bIndexFont)
  336. {
  337. // Check to see if we are past the max. number of cached mappings.
  338. // If the limit is exceeded, flush the cache by resetting the
  339. // the count.
  340. if (i >= MAXCACHEENTRIES)
  341. {
  342. i = plfnt->cMapsInCache = 0;
  343. }
  344. // Update cache information for the new mapping.
  345. mapcache[i].hpfec = pfeo.hpfecGet();
  346. mapcache[i].iFont = pfeo.iFont();
  347. mapcache[i].hdev = hdev;
  348. mapcache[i].flSim = *pflSim;
  349. mapcache[i].ptlSim.x = pptlSim->x;
  350. mapcache[i].ptlSim.y = pptlSim->y;
  351. mapcache[i].efM11 = matrix.efM11;
  352. mapcache[i].efM12 = matrix.efM12;
  353. mapcache[i].efM21 = matrix.efM21;
  354. mapcache[i].efM22 = matrix.efM22;
  355. mapcache[i].flAboutMatch = *pflAboutMatch;
  356. mapcache[i].iBitmapFormat = iBitmapFormat;
  357. plfnt->cMapsInCache += 1;
  358. }
  359. }
  360. }
  361. // if successfull, update the charset and code page info in the dc:
  362. if (ppfe)
  363. {
  364. // new font mapping may have occurred as a result of w->d xform change,
  365. // GraphicsMode change. Also when this routine is called from
  366. // RFONTOBJ::bInit, the new mapping may have occured as a result of
  367. // asking for pathobj instead of bitmap realization. In other words
  368. // It is not necessary at this point to have DIRTY_CHARSET bit set,
  369. // (which only happens when a new logfont is selected in the DC).
  370. // Any of these factors could cause the change of the font selected
  371. // in the dc and therefore also of the corresponding CodePage i.e. CharSet.
  372. #if 0
  373. if (!(dco.ulDirty() & DIRTY_CHARSET))
  374. {
  375. if (dco.pdc->iCS_CP() != (*pflAboutMatch >> 8))
  376. {
  377. DbgPrint("ppfe: 0x%p, iCS_CP: 0x%lx, flAboutMatch: 0x%p\n",
  378. ppfe, dco.pdc->iCS_CP(), *pflAboutMatch);
  379. RIP("ppfeMapFont, dco.pdc->iCS_CP is bogus\n");
  380. }
  381. }
  382. #endif
  383. #ifdef FE_SB
  384. // If font association is turned on for this character set then we need
  385. // to force the code page to ANSI so that ANSI apps can get a the DBCS
  386. // in the font via ANSI api's. We do this unless the user has set the
  387. // override bit in the LOGFONT.
  388. if(fFontAssocStatus &&
  389. !(plfw()->lfClipPrecision & CLIP_DFA_DISABLE))
  390. {
  391. UINT Charset = (*pflAboutMatch >> 24) & 0xFF;
  392. if((Charset == ANSI_CHARSET && fFontAssocStatus & ANSI_ASSOC) ||
  393. (Charset == OEM_CHARSET && fFontAssocStatus & OEM_ASSOC))
  394. // (Charset == OEM_CHARSET && fFontAssocStatus & OEM_ASSOC) ||
  395. // we might want to keep the codepage as CP_SYMBOL??????
  396. // (Charset == SYMBOL_CHARSET && fFontAssocStatus & SYMBOL_ASSOC))
  397. {
  398. USHORT AnsiCodePage, OemCodePage;
  399. RtlGetDefaultCodePage(&AnsiCodePage,&OemCodePage);
  400. *pflAboutMatch = (*pflAboutMatch & 0xFF0000FF) | (AnsiCodePage << 8);
  401. }
  402. }
  403. #endif
  404. dco.pdc->iCS_CP(*pflAboutMatch >> 8);
  405. // clean the DIRTY_CHARSET bit
  406. dco.ulDirtySub(DIRTY_CHARSET);
  407. }
  408. return (ppfe);
  409. }
  410. #if DBG
  411. /******************************Public*Routine******************************\
  412. * VOID LFONTOBJ::vDump ()
  413. *
  414. * Debugging code.
  415. *
  416. * History:
  417. * 25-Feb-1991 -by- Gilman Wong [gilmanw]
  418. * Wrote it.
  419. \**************************************************************************/
  420. VOID LFONTOBJ::vDump ()
  421. {
  422. DbgPrint("\nContents of LFONT, HLFONT = 0x%lx\n", hlfnt());
  423. if (hlfnt() == STOCKOBJ_SYSFONT)
  424. DbgPrint("S Y S T E M F O N T \n");
  425. if (hlfnt() == STOCKOBJ_SYSFIXEDFONT)
  426. DbgPrint("S Y S T E M F I X E D F O N T \n");
  427. if (hlfnt() == STOCKOBJ_OEMFIXEDFONT)
  428. DbgPrint("O E M F I X E D F O N T \n");
  429. if (hlfnt() == STOCKOBJ_DEFAULTDEVFONT)
  430. DbgPrint("D E V I C E D E F A U L T F O N T \n");
  431. if (hlfnt() == STOCKOBJ_ANSIFIXEDFONT)
  432. DbgPrint("A N S I F I X E D F O N T \n");
  433. if (hlfnt() == STOCKOBJ_ANSIVARFONT)
  434. DbgPrint("A N S I V A R I A B L E F O N T \n");
  435. if (hlfnt() == STOCKOBJ_DEFAULTGUIFONT)
  436. DbgPrint("D E F A U L T G U I F O N T \n");
  437. DbgPrint("LOGFONT \n");
  438. DbgPrint(" lfHeight = %d\n", plfnt->elfw.elfLogFont.lfHeight);
  439. DbgPrint(" lfWidth = %d\n", plfnt->elfw.elfLogFont.lfWidth);
  440. DbgPrint(" lfFaceName = %ws\n", plfnt->elfw.elfLogFont.lfFaceName);
  441. DbgPrint("\n");
  442. }
  443. #endif