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.

2274 lines
73 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fontsup.cxx
  3. *
  4. * Supplementary services needed by fonts.
  5. *
  6. * Currently consists mostly of UNICODE<->ASCII routines stolen from BodinD's
  7. * Windows bitmap font driver.
  8. *
  9. * Created: 21-Jan-1991 10:14:53
  10. * Author: Gilman Wong [gilmanw]
  11. *
  12. * Copyright (c) 1990-1999 Microsoft Corporation
  13. *
  14. *
  15. \**************************************************************************/
  16. #include "precomp.hxx"
  17. #include "grerc.h"
  18. VOID vArctan(EFLOAT, EFLOAT,EFLOAT&, LONG&);
  19. BOOL bValidFont(IFIMETRICS *);
  20. // typedef struct tagTHREADINFO *PTHREADINFO;
  21. extern "C" DWORD GetAppCompatFlags(PVOID);
  22. extern "C" BOOL InitializeScripts();
  23. #pragma alloc_text(INIT, InitializeScripts)
  24. VOID vIFIMetricsToEnumLogFontW (
  25. ENUMLOGFONTW *pelfw,
  26. IFIMETRICS *pifi
  27. )
  28. {
  29. IFIOBJ ifio(pifi);
  30. pelfw->elfLogFont.lfHeight = ifio.lfHeight();
  31. pelfw->elfLogFont.lfWidth = ifio.lfWidth();
  32. pelfw->elfLogFont.lfWeight = ifio.lfWeight();
  33. pelfw->elfLogFont.lfItalic = ifio.lfItalic();
  34. pelfw->elfLogFont.lfUnderline = ifio.lfUnderline();
  35. pelfw->elfLogFont.lfStrikeOut = ifio.lfStrikeOut();
  36. pelfw->elfLogFont.lfCharSet = ifio.lfCharSet();
  37. pelfw->elfLogFont.lfEscapement = ifio.lfEscapement();
  38. pelfw->elfLogFont.lfOrientation = ifio.lfOrientation();
  39. pelfw->elfLogFont.lfPitchAndFamily = ifio.lfPitchAndFamily();
  40. // These are special IFIOBJ methods that return Win 3.1 compatible
  41. // enumeration values.
  42. pelfw->elfLogFont.lfOutPrecision = ifio.lfOutPrecisionEnum();
  43. pelfw->elfLogFont.lfClipPrecision = ifio.lfClipPrecisionEnum();
  44. pelfw->elfLogFont.lfQuality = ifio.lfQualityEnum();
  45. //
  46. // Copy the name strings making sure that they are zero terminated
  47. //
  48. wcsncpy(pelfw->elfLogFont.lfFaceName,ifio.pwszFamilyName(),LF_FACESIZE);
  49. pelfw->elfLogFont.lfFaceName[LF_FACESIZE-1] = 0;
  50. wcsncpy(pelfw->elfFullName,ifio.pwszFaceName(),LF_FULLFACESIZE);
  51. pelfw->elfFullName[LF_FULLFACESIZE-1] = 0;
  52. wcsncpy(pelfw->elfStyle,ifio.pwszStyleName(),LF_FACESIZE);
  53. pelfw->elfStyle[LF_FACESIZE-1] = 0;
  54. }
  55. VOID vLookupScript(ULONG lfCharSet, WCHAR *pwszScript);
  56. /******************************Public*Routine******************************\
  57. *
  58. *
  59. * Units are in NOTIONAL units since font is not realized.
  60. *
  61. * History:
  62. * Fri 16-Aug-1991 22:01:17 by Kirk Olynyk [kirko]
  63. * Wrote it.
  64. \**************************************************************************/
  65. VOID vIFIMetricsToEnumLogFontExDvW (
  66. ENUMLOGFONTEXDVW * plfw,
  67. IFIMETRICS *pifi
  68. )
  69. {
  70. vIFIMetricsToEnumLogFontW ((ENUMLOGFONTW *)plfw,pifi);
  71. // lookup script, not ENUMLOGFONTW but is in ENUMLOGFONTEX
  72. vLookupScript((ULONG)pifi->jWinCharSet, (WCHAR *)plfw->elfEnumLogfontEx.elfScript);
  73. // pick the design vector
  74. ULONG cAxes = 0;
  75. if (pifi->flInfo & FM_INFO_TECH_MM)
  76. {
  77. PTRDIFF dpDesVec = 0;
  78. DESIGNVECTOR *pdvSrc;
  79. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, dpDesignVector))
  80. {
  81. dpDesVec = ((IFIEXTRA *)(pifi + 1))->dpDesignVector;
  82. pdvSrc = (DESIGNVECTOR *)((BYTE *)pifi + dpDesVec);
  83. cAxes = pdvSrc->dvNumAxes;
  84. if (cAxes > MM_MAX_NUMAXES)
  85. cAxes = MM_MAX_NUMAXES;
  86. RtlCopyMemory(&plfw->elfDesignVector, pdvSrc, (SIZE_T)SIZEOFDV(cAxes));
  87. plfw->elfDesignVector.dvNumAxes = cAxes;
  88. }
  89. else
  90. {
  91. ASSERTGDI(dpDesVec, "dpDesignVector == 0 for mm instance\n");
  92. plfw->elfDesignVector.dvReserved = STAMP_DESIGNVECTOR;
  93. plfw->elfDesignVector.dvNumAxes = 0;
  94. }
  95. }
  96. else
  97. {
  98. plfw->elfDesignVector.dvReserved = STAMP_DESIGNVECTOR;
  99. plfw->elfDesignVector.dvNumAxes = 0;
  100. }
  101. }
  102. /******************************Public*Routine******************************\
  103. * BOOL bIFIMetricsToLogFontW2 *
  104. * *
  105. * Used during font enumeration. *
  106. * *
  107. * Fill a LOGFONT structure using the information in a IFIMETRICS *
  108. * structure. *
  109. * *
  110. * The following fields need to be transformed by the Device to World *
  111. * transform: *
  112. * *
  113. * lfHeight (from pifi->fwdMaxBaselineExt) *
  114. * lfWidth (from pifi->fwdAveCharWidth) *
  115. * *
  116. * In the case of scalable fonts, these quantities are first prescaled *
  117. * into *
  118. * device units to be the equivalent of a 24 point font. *
  119. * This is for Win 3.1 *
  120. * compatibility with EnumFonts. *
  121. * *
  122. * Return: *
  123. * TRUE if successful, FALSE if an error occurs. *
  124. * *
  125. * History: *
  126. * 9-Oct-1991 by Gilman Wong [gilmanw] *
  127. * Added scalable font support. *
  128. * Wed 14-Aug-1991 13:42:22 by Kirk Olynyk [kirko] *
  129. * Changed the LOGFONTA to a LOGFONTW. *
  130. * 02-May-1991 -by- Gilman Wong [gilmanw] *
  131. * Wrote it. *
  132. \**************************************************************************/
  133. BOOL bIFIMetricsToLogFontW2 (
  134. DCOBJ &dco,
  135. ENUMLOGFONTEXW *pelfw,
  136. PIFIMETRICS pifi,
  137. EFLOATEXT efScale
  138. )
  139. {
  140. IFIOBJ ifio(pifi);
  141. // do all the conversions except for the height and width
  142. vIFIMetricsToEnumLogFontW((ENUMLOGFONTW *)pelfw,pifi);
  143. if (ifio.bContinuousScaling())
  144. {
  145. pelfw->elfLogFont.lfWidth = lCvt(efScale, ifio.lfWidth());
  146. pelfw->elfLogFont.lfHeight = lCvt(efScale, ifio.lfHeight());
  147. }
  148. //
  149. // At this point the height and width of the logical font are in pixel units
  150. // in device space. We must still transform these to world coordiantes
  151. //
  152. EXFORMOBJ xoToWorld(dco, DEVICE_TO_WORLD);
  153. if (!xoToWorld.bValid())
  154. {
  155. WARNING("gdisrv!bIFIMetricsToLogFontW2(): EXFORMOBJ constructor failed\n");
  156. return (FALSE);
  157. }
  158. // Only if not identity transform do we need to do anything more.
  159. if (!xoToWorld.bTranslationsOnly())
  160. {
  161. EFLOATEXT efA, efB;
  162. {
  163. //
  164. // efB == baseline scaling factor
  165. //
  166. EVECTORFL evflB;
  167. EVECTORFL evflA(ifio.pptlBaseline()->x,ifio.pptlBaseline()->y);
  168. efB.eqLength(evflA);
  169. evflB.eqDiv(evflA,efB);
  170. if (!xoToWorld.bXform(evflB))
  171. {
  172. WARNING("gdisrv!bIFIMetricsToLogFontW2(): transform failed\n");
  173. return (FALSE);
  174. }
  175. efB.eqLength(evflB);
  176. }
  177. pelfw->elfLogFont.lfWidth = lCvt(efB, pelfw->elfLogFont.lfWidth);
  178. {
  179. //
  180. // efA == ascender scaling factor
  181. //
  182. EVECTORFL evflB;
  183. EVECTORFL evflA(-ifio.pptlBaseline()->y,ifio.pptlBaseline()->x);
  184. efA.eqLength(evflA);
  185. evflB.eqDiv(evflA,efA);
  186. if (!xoToWorld.bXform(evflB))
  187. {
  188. WARNING("gdisrv!bIFIMetricsToLogFontW2(): transform failed\n");
  189. return (FALSE);
  190. }
  191. efA.eqLength(evflB);
  192. }
  193. pelfw->elfLogFont.lfHeight = lCvt(efA, pelfw->elfLogFont.lfHeight);
  194. }
  195. return(TRUE);
  196. }
  197. #ifndef FE_SB //moved to ifiobjr.hxx
  198. /*********************************Class************************************\
  199. * class IFIOBJR: public IFIOBJ
  200. *
  201. * History:
  202. * Tue 22-Dec-1992 14:05:24 by Kirk Olynyk [kirko]
  203. * Wrote it.
  204. \**************************************************************************/
  205. class IFIOBJR : public IFIOBJ
  206. {
  207. public:
  208. FONTDIFF fd;
  209. LONG lMaxCharWidth;
  210. LONG lAveCharWidth;
  211. LONG lInternalLeading;
  212. LONG lExternalLeading;
  213. LONG lDigitizedAspectX;
  214. LONG lDigitizedAspectY;
  215. IFIOBJR(const IFIMETRICS *pifi_, RFONTOBJ& rfo_, DCOBJ& dco);
  216. BYTE tmItalic()
  217. {
  218. return((BYTE) ((FM_SEL_ITALIC & fd.fsSelection)?255:0));
  219. }
  220. LONG tmMaxCharWidth()
  221. {
  222. return(lMaxCharWidth);
  223. }
  224. LONG tmAveCharWidth()
  225. {
  226. return(lAveCharWidth);
  227. }
  228. LONG tmInternalLeading()
  229. {
  230. return(lInternalLeading);
  231. }
  232. LONG tmExternalLeading()
  233. {
  234. return(lExternalLeading);
  235. }
  236. LONG tmWeight()
  237. {
  238. return((LONG) (fd.usWinWeight));
  239. }
  240. FSHORT fsSimSelection()
  241. {
  242. return(fd.fsSelection);
  243. }
  244. LONG tmDigitizedAspectX()
  245. {
  246. return lDigitizedAspectX;
  247. }
  248. LONG tmDigitizedAspectY()
  249. {
  250. return lDigitizedAspectY;
  251. }
  252. };
  253. /******************************Member*Function*****************************\
  254. * IFIOBJR::IFIOBJR *
  255. * *
  256. * This is where I place all of the knowlege of how to get the metrics *
  257. * for simulated for simulated fonts. *
  258. * *
  259. * History: *
  260. * Wed 24-Mar-1993 23:32:23 -by- Charles Whitmer [chuckwh] *
  261. * Made it respect the proper conventions when copying the FONTDIFF. A *
  262. * bold simulation on an italic font is a BoldItalic simulation, etc. *
  263. * *
  264. * Tue 22-Dec-1992 14:18:11 by Kirk Olynyk [kirko] *
  265. * Wrote it. *
  266. \**************************************************************************/
  267. IFIOBJR::IFIOBJR(const IFIMETRICS *pifi_, RFONTOBJ& rfo_, DCOBJ& dco) : IFIOBJ(pifi_)
  268. {
  269. FONTSIM *pfs = (FONTSIM*) (((BYTE*) pifi) + pifi->dpFontSim);
  270. switch (rfo_.pfo()->flFontType & (FO_SIM_BOLD+FO_SIM_ITALIC))
  271. {
  272. case 0:
  273. fd.bWeight = pifi->panose.bWeight ;
  274. fd.usWinWeight = pifi->usWinWeight ;
  275. fd.fsSelection = pifi->fsSelection ;
  276. fd.fwdAveCharWidth = pifi->fwdAveCharWidth ;
  277. fd.fwdMaxCharInc = pifi->fwdMaxCharInc ;
  278. fd.ptlCaret = pifi->ptlCaret ;
  279. break;
  280. case FO_SIM_BOLD:
  281. // If base (physical) font is already italic, emboldening yields
  282. // a bold-italic simulation.
  283. if (pifi->fsSelection & FM_SEL_ITALIC)
  284. fd = *((FONTDIFF*) (((BYTE*) pfs) + pfs->dpBoldItalic));
  285. else
  286. fd = *((FONTDIFF*) (((BYTE*) pfs) + pfs->dpBold));
  287. break;
  288. case FO_SIM_ITALIC:
  289. // If base (physical) font is already bold, italicization yields
  290. // a bold-italic simulation.
  291. if (pifi->fsSelection & FM_SEL_BOLD)
  292. fd = *((FONTDIFF*) (((BYTE*) pfs) + pfs->dpBoldItalic));
  293. else
  294. fd = *((FONTDIFF*) (((BYTE*) pfs) + pfs->dpItalic));
  295. break;
  296. case FO_SIM_BOLD+FO_SIM_ITALIC:
  297. fd = *((FONTDIFF*) (((BYTE*) pfs) + pfs->dpBoldItalic));
  298. break;
  299. }
  300. lAveCharWidth = (LONG) fd.fwdAveCharWidth;
  301. lMaxCharWidth = (LONG) fd.fwdMaxCharInc;
  302. lExternalLeading = (LONG) fwdExternalLeading();
  303. lInternalLeading = (LONG) fwdInternalLeading();
  304. if (!bContinuousScaling())
  305. {
  306. {
  307. const LONG lx = rfo_.pptlSim()->x;
  308. if (lx > 1)
  309. {
  310. lAveCharWidth *= lx;
  311. lMaxCharWidth *= lx;
  312. }
  313. }
  314. {
  315. const LONG ly = rfo_.pptlSim()->y;
  316. if (ly > 1)
  317. {
  318. lExternalLeading *= ly;
  319. lInternalLeading *= ly;
  320. }
  321. }
  322. }
  323. // [Windows 3.1 compatibility]
  324. // If TrueType font, then we need to substitute the device resolution for
  325. // the aspect ratio.
  326. if (bTrueType())
  327. {
  328. PDEVOBJ pdo(dco.hdev());
  329. ASSERTGDI(pdo.bValid(), "ctIFIOBJR(): bad HDEV in DC\n");
  330. // [Windows 3.1 compatibility]
  331. // Win 3.1 has these swapped. It puts VertRes in tmDigitizedAspectX
  332. // and HorzRes in tmDigitizedAspectY.
  333. lDigitizedAspectX = (LONG) pdo.ulLogPixelsY();
  334. lDigitizedAspectY = (LONG) pdo.ulLogPixelsX();
  335. }
  336. else
  337. {
  338. // [Windows 3.1 compatibility]
  339. // Win 3.1 has these swapped. It puts VertRes in tmDigitizedAspectX
  340. // and HorzRes in tmDigitizedAspectY.
  341. lDigitizedAspectX = pptlAspect()->y * rfo_.pptlSim()->y;
  342. lDigitizedAspectY = pptlAspect()->x * rfo_.pptlSim()->x;
  343. }
  344. }
  345. #endif
  346. /******************************Public*Routine******************************\
  347. * BOOL bIFIMetricsToTextMetricW (
  348. * RFONTOBJ &rfo,
  349. * DCOBJ &dco,
  350. * PTEXTMETRICW ptmw,
  351. * PIFIMETRICS pifi
  352. * )
  353. *
  354. * Fill a TEXTMETRIC structure based on information from an IFIMETRICS
  355. * structure.
  356. *
  357. * Everything returned in World (or Logical) coordinates. To that end,
  358. * the following fields must be transformed by either the Notional to
  359. * World transform (for scalable fonts) or the Device to World transform
  360. * (for bitmap fonts):
  361. *
  362. * tmHeight (from pifi->fwdMaxBaselineExt)
  363. * tmMaxCharWidth (from pifi->fwdMaxCharInc)
  364. * tmAveCharWidth (from pifi->fwdAveCharWidth)
  365. * tmAscent (from pifi->fwdMaxAscender)
  366. * tmInternalLeading (from pifi->fwdInternalLeading)
  367. * tmExternalLeading (from pifi->fwdExternalLeading)
  368. *
  369. * Return:
  370. * TRUE if successful, FALSE if an error occurs.
  371. *
  372. * totaly stolen from GilmanW
  373. *
  374. * History:
  375. * 9-Oct-1991 by Gilman Wong [gilmanw]
  376. * Added scalable font support.
  377. * 20-Aug-1991 -by- Bodin Dresevic [BodinD]
  378. * Wrote it.
  379. \**************************************************************************/
  380. BOOL
  381. bIFIMetricsToTextMetricWStrict( // strict means unicode values only [bodind]
  382. RFONTOBJ &rfo ,
  383. DCOBJ &dco ,
  384. TEXTMETRICW *ptmw,
  385. IFIMETRICS *pifi
  386. )
  387. {
  388. IFIOBJR ifio(pifi,rfo,dco);
  389. //
  390. // At low pixels per Em, the Height and ascender do not scaler linearly
  391. // so we take the results directly from the realization
  392. //
  393. if (dco.pdc->bWorldToDeviceIdentity())
  394. {
  395. ptmw->tmHeight = LONG_FLOOR_OF_FIX(rfo.fxMaxExtent() + FIX_HALF);
  396. ptmw->tmAscent = LONG_FLOOR_OF_FIX(rfo.fxMaxAscent() + FIX_HALF);
  397. ptmw->tmOverhang = rfo.lOverhang();
  398. }
  399. else
  400. {
  401. ptmw->tmHeight = lCvt(rfo.efDtoWAscent_31(),(LONG)rfo.fxMaxExtent());
  402. ptmw->tmAscent = lCvt(rfo.efDtoWAscent_31(),(LONG)rfo.fxMaxAscent());
  403. ptmw->tmOverhang = lCvt(rfo.efDtoWBase_31(), rfo.lOverhang() << 4);
  404. }
  405. if (!ifio.bContinuousScaling())
  406. {
  407. if (dco.pdc->bWorldToDeviceIdentity())
  408. {
  409. ptmw->tmMaxCharWidth = ifio.tmMaxCharWidth();
  410. ptmw->tmAveCharWidth = ifio.tmAveCharWidth();
  411. ptmw->tmInternalLeading = ifio.tmInternalLeading();
  412. ptmw->tmExternalLeading = ifio.tmExternalLeading();
  413. }
  414. else
  415. {
  416. ptmw->tmMaxCharWidth
  417. = lCvt(rfo.efDtoWBase_31(),((LONG) ifio.tmMaxCharWidth()) << 4);
  418. ptmw->tmAveCharWidth
  419. = lCvt(rfo.efDtoWBase_31(),((LONG) ifio.tmAveCharWidth()) << 4);
  420. ptmw->tmInternalLeading
  421. = lCvt(rfo.efDtoWAscent_31(),((LONG) ifio.tmInternalLeading()) << 4);
  422. ptmw->tmExternalLeading
  423. = lCvt(rfo.efDtoWAscent_31(),((LONG) ifio.tmExternalLeading()) << 4);
  424. }
  425. }
  426. else
  427. {
  428. if (rfo.lNonLinearIntLeading() == MINLONG)
  429. {
  430. // Rather than scaling the notional internal leading, try
  431. // to get closer to HINTED internal leading by computing it
  432. // as the difference between the HINTED height and UNHINTED
  433. // EmHeight.
  434. ptmw->tmInternalLeading =
  435. ptmw->tmHeight
  436. - lCvt(rfo.efNtoWScaleAscender(),ifio.fwdUnitsPerEm());
  437. }
  438. else
  439. {
  440. // But if the font provider has given us a hinted internal leading,
  441. // just use it.
  442. ptmw->tmInternalLeading =
  443. lCvt(rfo.efDtoWAscent_31(),rfo.lNonLinearIntLeading());
  444. }
  445. // Either scale the external leading linearly from N to W, or back
  446. // transform the device units version returned from the font provider.
  447. if (rfo.lNonLinearExtLeading() == MINLONG)
  448. {
  449. ptmw->tmExternalLeading =
  450. lCvt(rfo.efNtoWScaleAscender(),ifio.fwdExternalLeading());
  451. }
  452. else
  453. {
  454. ptmw->tmExternalLeading =
  455. lCvt(rfo.efDtoWAscent_31(),rfo.lNonLinearExtLeading());
  456. }
  457. if (rfo.lNonLinearMaxCharWidth() == MINLONG)
  458. {
  459. ptmw->tmMaxCharWidth =
  460. lCvt(rfo.efNtoWScaleBaseline(), ifio.tmMaxCharWidth());
  461. }
  462. else
  463. {
  464. // But if the font provider has given us a hinted value, we use it
  465. ptmw->tmMaxCharWidth =
  466. lCvt(rfo.efDtoWBase_31(),rfo.lNonLinearMaxCharWidth());
  467. }
  468. if (rfo.lNonLinearAvgCharWidth() == MINLONG)
  469. {
  470. ptmw->tmAveCharWidth =
  471. lCvt(rfo.efNtoWScaleBaseline(), ifio.tmAveCharWidth());
  472. }
  473. else
  474. {
  475. // But if the font provider has given us a hinted value, we use it
  476. ptmw->tmAveCharWidth =
  477. lCvt(rfo.efDtoWBase_31(),rfo.lNonLinearAvgCharWidth());
  478. }
  479. }
  480. //
  481. // height = ascender + descender, by definition
  482. //
  483. ptmw->tmDescent = ptmw->tmHeight - ptmw->tmAscent;
  484. //
  485. // The rest of these are not transform dependent.
  486. //
  487. ptmw->tmWeight = ifio.tmWeight();
  488. ptmw->tmItalic = ifio.tmItalic();
  489. ptmw->tmUnderlined = ifio.lfUnderline();
  490. ptmw->tmStruckOut = ifio.lfStrikeOut();
  491. // Better check the simulation flags for underline and strikeout.
  492. {
  493. FLONG flSim = dco.pdc->flSimulationFlags();
  494. // If simulated, set underline and strike out flags.
  495. ptmw->tmUnderlined = (flSim & TSIM_UNDERLINE1) ? 0xff : FALSE;
  496. ptmw->tmStruckOut = (flSim & TSIM_STRIKEOUT) ? 0xff : FALSE;
  497. }
  498. ptmw->tmFirstChar = ifio.wcFirstChar() ;
  499. ptmw->tmLastChar = ifio.wcLastChar() ;
  500. ptmw->tmDefaultChar = ifio.wcDefaultChar();
  501. ptmw->tmBreakChar = ifio.wcBreakChar() ;
  502. // New in win95: depending on charset in the logfont and charsets
  503. // available in the font we return the tmCharset that the mapper has decided
  504. // is the best. At this stage the claim is that mapping has already
  505. // occured and that the charset stored in the dc must not be dirty.
  506. //ASSERTGDI(!(dco.ulDirty() & DIRTY_CHARSET),
  507. // "bIFIMetricsToTextMetricW, charset is dirty\n");
  508. ptmw->tmCharSet = (BYTE)(dco.pdc->iCS_CP() >> 16);
  509. // [Windows 3.1 compatibility]
  510. // TMPF_DEVICE really means whether the device realized this font or
  511. // GDI realized it. Under Win 3.1 printer drivers can realize True Type
  512. // fonts. When the TC_RA_ABLE flag isn't set the driver's realization will
  513. // be chosen and TMPF_DEVICE flag should be set.
  514. // Word97-J has problem to print vertically,
  515. // So we need to get rid of TMPF_DEVICE to make print correctly
  516. if (ifio.bTrueType())
  517. {
  518. PDEVOBJ pdo(dco.hdev());
  519. ASSERTGDI(pdo.bValid(), "PDEVOBJ constructor failed\n");
  520. BOOL bWin31Device = (!pdo.bDisplayPDEV() &&
  521. !(pdo.flTextCaps() & TC_RA_ABLE ) &&
  522. (dco.pdc->iGraphicsMode() == GM_COMPATIBLE) &&
  523. !(gbDBCSCodePage && (GetAppCompatFlags(NULL) & GACF_TTIGNOREDDEVICE)));
  524. // Note that we check the PDEV directly rather than the DC because
  525. // DCOBJ::bDisplay() is not TRUE for display ICs (just display DCs
  526. // which are DCTYPE_DIRECT).
  527. ptmw->tmPitchAndFamily = ifio.tmPitchAndFamily()
  528. | ( (bWin31Device) ? TMPF_DEVICE : 0);
  529. }
  530. else
  531. {
  532. ptmw->tmPitchAndFamily = ifio.tmPitchAndFamily()
  533. | (rfo.bDeviceFont() ? TMPF_DEVICE : 0)
  534. | (((pifi->flInfo & FM_INFO_TECH_OUTLINE_NOT_TRUETYPE) && !(gbDBCSCodePage && (GetAppCompatFlags(NULL) & GACF_TTIGNOREDDEVICE))) ? (TMPF_VECTOR|TMPF_DEVICE): 0);
  535. }
  536. ptmw->tmDigitizedAspectX = ifio.tmDigitizedAspectX();
  537. ptmw->tmDigitizedAspectY = ifio.tmDigitizedAspectY();
  538. return(TRUE);
  539. }
  540. /******************************Public*Routine******************************\
  541. * bGetTextMetrics
  542. *
  543. *
  544. * History:
  545. * 5-5-2000 -by- Yung-Jen Tony Tsai [YungT]
  546. * Wrote it.
  547. \**************************************************************************/
  548. BOOL bGetTextMetrics(
  549. RFONTOBJ &rfo ,
  550. DCOBJ &dco ,
  551. TMW_INTERNAL *ptmi
  552. )
  553. {
  554. BOOL bRet = FALSE;
  555. // Get cached TextMetrics if available.
  556. if (rfo.bValid())
  557. {
  558. if( rfo.ptmw() != NULL )
  559. {
  560. *ptmi = *(rfo.ptmw());
  561. // time to fix underscore, strikeout and charset. The point is that
  562. // bFindRFONT may have found an old realization that corresponded
  563. // to different values of these parameters in the logfont.
  564. FLONG flSim = dco.pdc->flSimulationFlags();
  565. ptmi->tmw.tmUnderlined = (flSim & TSIM_UNDERLINE1) ? 0xff : FALSE;
  566. ptmi->tmw.tmStruckOut = (flSim & TSIM_STRIKEOUT) ? 0xff : FALSE;
  567. // New in win95: depending on charset in the logfont and charsets
  568. // available in the font we return the tmCharset
  569. // that the mapper has decided is the best.
  570. // At this stage the claim is that mapping has already
  571. // occured and that the charset stored in the dc must not be dirty.
  572. ptmi->tmw.tmCharSet = (BYTE)(dco.pdc->iCS_CP() >> 16);
  573. bRet = TRUE;
  574. }
  575. else
  576. {
  577. // Get PFE user object from RFONT
  578. PFEOBJ pfeo (rfo.ppfe());
  579. ASSERTGDI(pfeo.bValid(), "ERROR invalid ppfe in valid rfo");
  580. bRet = (BOOL) bIFIMetricsToTextMetricW(rfo, dco, ptmi, pfeo.pifi());
  581. }
  582. }
  583. return bRet;
  584. }
  585. /******************************Public*Routine******************************\
  586. * bIFIMetricsToTextMetricW(
  587. *
  588. * tacks on ansi values
  589. *
  590. * History:
  591. * 27-Jan-1993 -by- Bodin Dresevic [BodinD]
  592. * Wrote it.
  593. \**************************************************************************/
  594. BOOL
  595. bIFIMetricsToTextMetricW(
  596. RFONTOBJ &rfo ,
  597. DCOBJ &dco ,
  598. TMW_INTERNAL *ptmi,
  599. IFIMETRICS *pifi
  600. )
  601. {
  602. ASSERTGDI(rfo.ptmw() == NULL, "bIFIFMetricToTextMetricsW TEXTMETRIC already cached\n");
  603. BOOL bRet = bIFIMetricsToTextMetricWStrict(rfo,dco,&ptmi->tmw,pifi);
  604. ptmi->tmdTmw.chFirst = pifi->chFirstChar ;
  605. ptmi->tmdTmw.chLast = pifi->chLastChar ;
  606. ptmi->tmdTmw.chDefault = pifi->chDefaultChar;
  607. ptmi->tmdTmw.chBreak = pifi->chBreakChar ;
  608. if( bRet )
  609. {
  610. TMW_INTERNAL *ptmw = (TMW_INTERNAL*) PALLOCMEM(sizeof(TMW_INTERNAL),'wmtG');
  611. if( ptmw == NULL )
  612. {
  613. WARNING("bIFIMetricsToTextMetricW unable to alloc mem for cached TEXTMETRICS\n");
  614. }
  615. else
  616. {
  617. rfo.ptmwSet( ptmw );
  618. *ptmw = *ptmi;
  619. }
  620. }
  621. return (bRet);
  622. }
  623. /******************************Public*Routine******************************\
  624. * bIFIMetricsToTextMetricW2
  625. *
  626. * Used during font enumeration.
  627. *
  628. * Fill a NEWTEXTMETRICW structure based on information from an IFIMETRICS
  629. * structure.
  630. *
  631. * The following fields need to be transformed by the Device to World
  632. * transform:
  633. *
  634. * tmHeight (from pifi->fwdMaxBaselineExt)
  635. * tmMaxCharWidth (from pifi->fwdMaxCharInc)
  636. * tmAveCharWidth (from pifi->fwdAveCharWidth)
  637. * tmAscent (from pifi->fwdMaxAscender)
  638. * tmInternalLeading (from pifi->fwdInternalLeading)
  639. * tmExternalLeading (from pifi->fwdExternalLeading)
  640. *
  641. * In the case of scalable fonts, these quantities are first prescaled into
  642. * device units to be the equivalent of a 24 point font. This is for Win 3.1
  643. * compatibility with EnumFonts.
  644. *
  645. * Returns:
  646. * TRUE if successful, FALSE if an error occurs.
  647. *
  648. * totaly stolen from GilmanW
  649. *
  650. * History:
  651. * 9-Oct-1991 by Gilman Wong [gilmanw]
  652. * Added scalable font support.
  653. * 20-Aug-1991 -by- Bodin Dresevic [BodinD]
  654. * Wrote it.
  655. \**************************************************************************/
  656. BOOL bIFIMetricsToTextMetricW2 (
  657. DCOBJ &dco,
  658. NTMW_INTERNAL * pntmi,
  659. PFEOBJ &pfeo,
  660. BOOL bDeviceFont,
  661. ULONG iEnumType,
  662. EFLOATEXT efScale,
  663. LONG tmDigitizedAspectX,
  664. LONG tmDigitizedAspectY
  665. )
  666. {
  667. PIFIMETRICS pifi = pfeo.pifi();
  668. PNEWTEXTMETRICW ptmw = &pntmi->entmw.etmNewTextMetricEx.ntmTm;
  669. IFIOBJ ifio(pifi);
  670. // Validate the font before proceeding
  671. if( !bValidFont(pifi) )
  672. {
  673. WARNING("bIFIMetricsToTextMetricW2 called with bad IFIMETRICS\n");
  674. return FALSE;
  675. }
  676. // If scalable font, then return following metrics as if font were realized at
  677. // 24 points.
  678. if (ifio.bContinuousScaling())
  679. {
  680. ptmw->tmHeight = lCvt(efScale, ifio.lfHeight());
  681. // Now we need to adjust the scale factor due to roundoff in the height.
  682. // This will more closely approximate the NtoW scale computed if ever this
  683. // font gets selected.
  684. efScale = (LONG) ptmw->tmHeight;
  685. efScale /= (LONG) ifio.lfHeight();
  686. // Use scaling factor to convert from IFIMETRICS to TEXTMETRIC fields.
  687. ptmw->tmAscent = lCvt(efScale, (LONG) ifio.fwdWinAscender());
  688. ptmw->tmInternalLeading = lCvt(efScale, (LONG) ifio.fwdInternalLeading());
  689. ptmw->tmExternalLeading = lCvt(efScale, (LONG) ifio.fwdExternalLeading());
  690. ptmw->tmAveCharWidth = lCvt(efScale, (LONG) ifio.fwdAveCharWidth());
  691. ptmw->tmMaxCharWidth = lCvt(efScale, (LONG) ifio.fwdMaxCharInc());
  692. } /* if */
  693. // Its a bitmap font, so no prescaling to 24 point needed.
  694. else
  695. {
  696. ptmw->tmHeight = ifio.lfHeight();
  697. ptmw->tmAscent = ifio.fwdWinAscender();
  698. ptmw->tmInternalLeading = ifio.fwdInternalLeading();
  699. ptmw->tmExternalLeading = ifio.fwdExternalLeading();
  700. ptmw->tmAveCharWidth = ifio.fwdAveCharWidth();
  701. ptmw->tmMaxCharWidth = ifio.fwdMaxCharInc();
  702. } /* else */
  703. // Now that all fonts are:
  704. //
  705. // Bitmap fonts -- in device units
  706. // Scalable fonts -- artificially scaled to 24 point device
  707. // units (a 'la Win 3.1)
  708. //
  709. // put them through the Device to World transform.
  710. EXFORMOBJ xoToWorld(dco, DEVICE_TO_WORLD);
  711. if (!xoToWorld.bValid())
  712. {
  713. WARNING("gdisrv!bIFIMetricsToTextMetricW2(): EXFORMOBJ constructor failed\n");
  714. return (FALSE);
  715. }
  716. // Only if not identity transform do we need to do anything more.
  717. if (!xoToWorld.bTranslationsOnly())
  718. {
  719. EFLOATEXT efX, efY;
  720. // efX == horizontal scaling factor (Device to World)
  721. EVECTORFL evflH(1,0); // device space unit vector (x-axis)
  722. if (!xoToWorld.bXform(evflH))
  723. {
  724. WARNING("gdisrv!bIFIMetricsToTextMetricW2(): transform failed\n");
  725. return (FALSE);
  726. }
  727. efX.eqLength(evflH);
  728. // efY == vertical scaling factor (Device to World)
  729. EVECTORFL evflV(0,1); // device space unit vector (y-axis)
  730. if (!xoToWorld.bXform(evflV))
  731. {
  732. WARNING("gdisrv!bIFIMetricsToTextMetricW2(): transform failed\n");
  733. return (FALSE);
  734. }
  735. efY.eqLength(evflV);
  736. // Convert from device to world using scaling factors.
  737. ptmw->tmHeight = lCvt(efY, (LONG) ptmw->tmHeight);
  738. ptmw->tmAscent = lCvt(efY, (LONG) ptmw->tmAscent);
  739. ptmw->tmAveCharWidth = lCvt(efX, (LONG) ptmw->tmAveCharWidth);
  740. ptmw->tmMaxCharWidth = lCvt(efX, (LONG) ptmw->tmMaxCharWidth);
  741. ptmw->tmInternalLeading = lCvt(efY, (LONG) ptmw->tmInternalLeading);
  742. ptmw->tmExternalLeading = lCvt(efY, (LONG) ptmw->tmExternalLeading);
  743. } /* if */
  744. // these are now passed in, computed in the calling routine
  745. ptmw->tmDigitizedAspectX = tmDigitizedAspectX;
  746. ptmw->tmDigitizedAspectY = tmDigitizedAspectY;
  747. // The rest are pretty easy (no transformation of IFIMETRICS needed)
  748. ptmw->tmDescent = ptmw->tmHeight - ptmw->tmAscent;
  749. ptmw->tmWeight = ifio.lfWeight();
  750. ptmw->tmItalic = ifio.lfItalic();
  751. ptmw->tmUnderlined = ifio.lfUnderline();
  752. ptmw->tmStruckOut = ifio.lfStrikeOut();
  753. ptmw->tmFirstChar = ifio.wcFirstChar();
  754. ptmw->tmLastChar = ifio.wcLastChar();
  755. ptmw->tmDefaultChar = ifio.wcDefaultChar();
  756. ptmw->tmBreakChar = ifio.wcBreakChar();
  757. ptmw->tmCharSet = ifio.lfCharSet();
  758. // [Windows 3.1 compatibility]
  759. //
  760. // Note that the tmPitchAndFamily is computed slightly differently than
  761. // in bIFIMetricsToTextMetricWStrict. That's because the enumeration
  762. // does not hack the tmPitchAndFamily to make TrueType fonts look like
  763. // device fonts. Enumeration does this in the flFontType flags passed
  764. // back to the callback function. On the other hand, GetTextMetrics, which
  765. // bIFIMetricsToTextMetricWStrict services, does the hack in tmPitchAndFamily.
  766. ptmw->tmPitchAndFamily = ifio.tmPitchAndFamily()
  767. | ((bDeviceFont) ? TMPF_DEVICE : 0)
  768. | ((pifi->flInfo & FM_INFO_TECH_OUTLINE_NOT_TRUETYPE) ? (TMPF_VECTOR|TMPF_DEVICE): 0);
  769. // The simulated faces are not enumerated, so this is 0.
  770. ptmw->tmOverhang = 0;
  771. // If TrueType, then fill in the new NEWTEXTMETRICW fields.
  772. // Comment wrong: we shall do it for every font
  773. ptmw->ntmFlags = 0;
  774. if (!ifio.bBold() && !ifio.bItalic())
  775. ptmw->ntmFlags |= NTM_REGULAR;
  776. else
  777. {
  778. if (ifio.bItalic())
  779. ptmw->ntmFlags |= NTM_ITALIC;
  780. if (ifio.bBold())
  781. ptmw->ntmFlags |= NTM_BOLD;
  782. }
  783. if (pifi->flInfo & FM_INFO_NONNEGATIVE_AC)
  784. ptmw->ntmFlags |= NTM_NONNEGATIVE_AC;
  785. if (pifi->flInfo & FM_INFO_TECH_TYPE1)
  786. {
  787. if (pifi->flInfo & FM_INFO_TECH_MM)
  788. ptmw->ntmFlags |= NTM_MULTIPLEMASTER;
  789. if (pifi->flInfo & FM_INFO_TECH_CFF)
  790. ptmw->ntmFlags |= NTM_PS_OPENTYPE; // proper, not true type
  791. else
  792. ptmw->ntmFlags |= NTM_TYPE1; // old fashioned t1 screen font
  793. }
  794. if (pifi->flInfo & FM_INFO_DSIG)
  795. {
  796. ptmw->ntmFlags |= NTM_DSIG;
  797. if (pifi->flInfo & FM_INFO_TECH_TRUETYPE)
  798. ptmw->ntmFlags |= NTM_TT_OPENTYPE;
  799. }
  800. ptmw->ntmSizeEM = ifio.fwdUnitsPerEm();
  801. ptmw->ntmCellHeight = (UINT) ifio.lfHeight();;
  802. ptmw->ntmAvgWidth = ifio.fwdAveCharWidth();
  803. pntmi->tmdNtmw.chFirst = pifi->chFirstChar ;
  804. pntmi->tmdNtmw.chLast = pifi->chLastChar ;
  805. pntmi->tmdNtmw.chDefault = pifi->chDefaultChar;
  806. pntmi->tmdNtmw.chBreak = pifi->chBreakChar ;
  807. PTRDIFF dpFontSig = 0;
  808. if (pfeo.pifi()->cjIfiExtra > offsetof(IFIEXTRA, dpFontSig))
  809. {
  810. dpFontSig = ((IFIEXTRA *)(pfeo.pifi() + 1))->dpFontSig;
  811. }
  812. if (dpFontSig)
  813. {
  814. // this is only going to work in the next release of win95 (win96?)
  815. // according to DavidMS, and we have right now in SUR
  816. pntmi->entmw.etmNewTextMetricEx.ntmFontSig = *((FONTSIGNATURE *)
  817. ((BYTE *)pifi + dpFontSig));
  818. }
  819. else // do not bother and waste time, will not be used anyway
  820. {
  821. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsUsb[0] = 0;
  822. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsUsb[1] = 0;
  823. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsUsb[2] = 0;
  824. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsUsb[3] = 0;
  825. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsCsb[0] = 0;
  826. pntmi->entmw.etmNewTextMetricEx.ntmFontSig.fsCsb[1] = 0;
  827. }
  828. return (TRUE);
  829. }
  830. INT
  831. LOADSTRING(
  832. HANDLE hinst,
  833. UINT id,
  834. PWSTR pwstr,
  835. INT bufsize
  836. )
  837. /*++
  838. Routine Description:
  839. Loads a string resource from the resource file associated with a
  840. specified module, copies the string into a buffer, and appends a
  841. terminating null character.
  842. Arguments:
  843. hinst handle to the module containing the string resource
  844. id ID of the string to be loaded
  845. pwstr points to the buffer to receive the string
  846. bufsize size of the buffer, in characters.
  847. Return Value:
  848. Return value is the number of characters copied into the buffer, not
  849. including the null-terminating character. If pwst is NULL then it
  850. just returns the size of the string.
  851. I stole this from the pscript driver [gerritv]
  852. --*/
  853. #define WINRT_STRING 6 // string resource type
  854. {
  855. ULONG size;
  856. // String Tables are broken up into 16 string segments.
  857. // Find the segment containing the string we are interested in.
  858. const WCHAR * pwstrBuffer = (PWSTR) EngFindResource(hinst, (id>>4)+1, WINRT_STRING, &size);
  859. if (pwstrBuffer == NULL ) {
  860. WARNING("Gre:LOADSTRING failed.\n");
  861. bufsize = 0;
  862. } else {
  863. const WCHAR * pwstrEnd = pwstrBuffer + size / sizeof(WCHAR);
  864. INT length = 0;
  865. // Move past the other strings in this segment.
  866. id &= 0x0F;
  867. while (pwstrBuffer < pwstrEnd) {
  868. // PASCAL style string - first char is length
  869. length = *pwstrBuffer++;
  870. if(id-- == 0 ) {
  871. break;
  872. }
  873. pwstrBuffer += length;
  874. }
  875. if(!pwstr)
  876. {
  877. return(length);
  878. }
  879. if (pwstrBuffer < pwstrEnd) {
  880. // Truncate the string if it's longer than max buffer size
  881. if (--bufsize > length)
  882. bufsize = length;
  883. memcpy(pwstr, pwstrBuffer, bufsize*sizeof(WCHAR));
  884. } else {
  885. WARNING("Gre:LOADSTRING Bad string resource.\n");
  886. bufsize = 0;
  887. }
  888. }
  889. if (pwstr)
  890. {
  891. pwstr[bufsize] = L'\0';
  892. }
  893. return bufsize;
  894. }
  895. #ifdef _HYDRA_
  896. DWORD gdwOffset;
  897. #endif
  898. typedef struct _CHSET_SCRIPT
  899. {
  900. ULONG ulCharSet;
  901. WCHAR *pwszScript;
  902. } CHSET_SCRIPT;
  903. CHSET_SCRIPT aScripts[NUMBER_OF_SCRIPTS];
  904. /********************************************************************************
  905. * BOOL InitializeScripts()
  906. *
  907. * Initialize script names from resource strings in win32k.sys
  908. *
  909. * This function intializes the script names from the string resources compiled
  910. * into win32k.sys. The string should be in the following format: xxx:string
  911. * where xxx is an ascii decimal respresentation of a charset value and string
  912. * the script that is associated with that charset.
  913. *
  914. * History
  915. * 3-5-95 16:00:54 by Gerrit van Wingerden [gerritv]
  916. * Wrote it.
  917. *
  918. ********************************************************************************/
  919. extern "C" BOOL InitializeScripts()
  920. {
  921. HANDLE h;
  922. BOOL ReturnValue = FALSE;
  923. if(h = EngLoadModule(L"win32k.sys"))
  924. {
  925. UINT u;
  926. DWORD TotalSizeInWChars = 0;
  927. PWCHAR pStringBuffer = NULL;
  928. // first compute the total size of all the strings
  929. for(u = 0; u < NUMBER_OF_SCRIPTS; u++)
  930. {
  931. INT StringSize;
  932. StringSize = LOADSTRING(h, u, NULL, 0);
  933. if(!StringSize)
  934. {
  935. WARNING("InitializeScripts unable to LOADSTRING\n");
  936. break;
  937. }
  938. TotalSizeInWChars += StringSize + 1;
  939. }
  940. // allocate buffer if computation above is successful
  941. if(u == NUMBER_OF_SCRIPTS)
  942. {
  943. pStringBuffer =
  944. (PWCHAR) PALLOCMEM(TotalSizeInWChars * sizeof(WCHAR),'lscG');
  945. }
  946. aScripts[0].pwszScript = NULL; // don't leave this unitialized
  947. // if buffer allocated, read each string into buffer
  948. if(pStringBuffer)
  949. {
  950. // next read in each string
  951. for(u = 0; u < NUMBER_OF_SCRIPTS; u++)
  952. {
  953. INT StringSize;
  954. aScripts[u].pwszScript = pStringBuffer;
  955. StringSize = LOADSTRING(h, u, pStringBuffer, TotalSizeInWChars) + 1;
  956. pStringBuffer += StringSize;
  957. TotalSizeInWChars -= StringSize;
  958. aScripts[u].ulCharSet = 0;
  959. // Once we've read in the string, parse the charset component.
  960. // The string will be in the form "xxx:script", where xxx
  961. // is the ascii decimal representation of the string
  962. while(*(aScripts[u].pwszScript) &&
  963. *(aScripts[u].pwszScript) != (WCHAR) ':')
  964. {
  965. aScripts[u].ulCharSet *= 10;
  966. aScripts[u].ulCharSet +=
  967. *(aScripts[u].pwszScript) - (WCHAR) '0';
  968. aScripts[u].pwszScript += 1;
  969. #ifdef _HYDRA_
  970. if (u == 0)
  971. gdwOffset++;
  972. #endif
  973. }
  974. // add 1000 to the charset value to be compatible with other code
  975. aScripts[u].ulCharSet += 1000;
  976. ASSERTGDI(*aScripts[u].pwszScript == (WCHAR) ':',
  977. "InitializeScript missing colon\n");
  978. // move past the colon
  979. aScripts[u].pwszScript += 1;
  980. #ifdef _HYDRA_
  981. if (u == 0)
  982. gdwOffset++;
  983. #endif
  984. }
  985. ASSERTGDI((TotalSizeInWChars == 0), "InitializeScripts: TotalSize != 0\n");
  986. ReturnValue = TRUE;
  987. }
  988. EngFreeModule(h);
  989. }
  990. return(ReturnValue);
  991. }
  992. #ifdef _HYDRA_
  993. /******************************Public*Routine******************************\
  994. * MultiUserGreDeleteScripts
  995. *
  996. * For MultiUserGreCleanup (Hydra) cleanup.
  997. *
  998. * History:
  999. * 09-Feb-1998 -by- Gilman Wong [gilmanw]
  1000. * Wrote it.
  1001. \**************************************************************************/
  1002. VOID MultiUserGreDeleteScripts()
  1003. {
  1004. WCHAR* pszBuffer;
  1005. if (aScripts[0].pwszScript) {
  1006. pszBuffer = aScripts[0].pwszScript;
  1007. pszBuffer -= gdwOffset;
  1008. VFREEMEM(pszBuffer);
  1009. }
  1010. }
  1011. #endif
  1012. /******************************Public*Routine******************************\
  1013. * vLookupScript
  1014. *
  1015. * Copy the script name corresponding to the specified character set.
  1016. * Copy the SCRIPT_UNKNOWN string if character set not found in the table.
  1017. *
  1018. \**************************************************************************/
  1019. VOID vLookupScript(ULONG lfCharSet, WCHAR *pwszScript)
  1020. {
  1021. //MAYBE replace linear search by binary search
  1022. UINT i;
  1023. ULONG ulStrlen;
  1024. lfCharSet += 1000;
  1025. for (i = 0; i < NUMBER_OF_SCRIPTS; i++)
  1026. if (aScripts[i].ulCharSet == lfCharSet)
  1027. break;
  1028. wcscpy(pwszScript, (i<NUMBER_OF_SCRIPTS) ? aScripts[i].pwszScript :
  1029. aScripts[SCRIPT_UNKNOWN].pwszScript);
  1030. }
  1031. /******************************Public*Routine******************************\
  1032. * SIZE_T cjCopyFontDataW
  1033. *
  1034. * Copies data needed for EnumFonts callback function from the IFIMETRICS
  1035. * data of the given font.
  1036. *
  1037. * Because the font is not realized (notice: no RFONTOBJ& passed in), all
  1038. * units remain in NOTIONAL.
  1039. *
  1040. * Two parameters may influence the family name passed back. If
  1041. * efsty is EFSTYLE_OTHER, then the face name should be substituted for
  1042. * the family name. If pwszFamilyOverride is !NULL, then it should
  1043. * replace the family name. pwszFamilyOverride has precedence over efsty.
  1044. * Both of these behaviors are for Win3.1 compatibility.
  1045. *
  1046. * Note: pefdw is user memory, which might be asynchronously changed
  1047. * at any time. So, we cannot trust any values read from that buffer.
  1048. *
  1049. * Returns:
  1050. * The number of bytes copied, 0 if error occurs.
  1051. *
  1052. * History:
  1053. * 9-Oct-1991 by Gilman Wong [gilmanw]
  1054. * Added scalable font support.
  1055. * 03-Sep-1991 -by- Bodin Dresevic [BodinD]
  1056. * Wrote it.
  1057. \**************************************************************************/
  1058. SIZE_T cjCopyFontDataW (
  1059. DCOBJ &dco,
  1060. PENUMFONTDATAW pefdw,
  1061. PFEOBJ &pfeo,
  1062. ULONG efsty, // based on style, may need to change family name to facename
  1063. PWSZ pwszFamilyOverride, // if this is !NULL, this is used as family name
  1064. ULONG lfCharSetOverride,
  1065. BOOL bCharSetOverride, // tell us if overrides should be used
  1066. ULONG iEnumType // enumeration type, tells how to fill the data
  1067. )
  1068. {
  1069. PIFIMETRICS pifi = pfeo.pifi();
  1070. BOOL bDevice = pfeo.bDeviceFont();
  1071. EFLOATEXT efScale;
  1072. ULONG cjEfdw;
  1073. ULONG dpNtmi;
  1074. IFIOBJ ifio(pifi);
  1075. LONG tmDigitizedAspectX = ifio.pptlAspect()->y;
  1076. LONG tmDigitizedAspectY = ifio.pptlAspect()->x;
  1077. PDEVOBJ pdo(dco.hdev());
  1078. if (!pdo.bValid())
  1079. {
  1080. WARNING("gdisrv!cjCopyFontDataW(): PDEVOBJ constructor failed\n");
  1081. return ((SIZE_T)0);
  1082. }
  1083. if (!bValidFont(pifi))
  1084. {
  1085. WARNING("cjCopyFontDataW() called with invalid ITIMETRICS\n");
  1086. return ((SIZE_T)0);
  1087. }
  1088. if (bDevice && !ifio.bContinuousScaling())
  1089. {
  1090. tmDigitizedAspectX = pdo.ulLogPixelsX();
  1091. tmDigitizedAspectY = pdo.ulLogPixelsY();
  1092. }
  1093. // Calculate the scale factor
  1094. if (ifio.bContinuousScaling())
  1095. {
  1096. // According to the bizzare convention of Win 3.1, scalable fonts are
  1097. // reported at a default physical height
  1098. // notice the inversion in x,y for win31 compat.
  1099. if (ifio.lfOutPrecision() == OUT_OUTLINE_PRECIS)
  1100. {
  1101. tmDigitizedAspectX = pdo.ulLogPixelsY();
  1102. tmDigitizedAspectY = pdo.ulLogPixelsX();
  1103. }
  1104. if (bDevice)
  1105. {
  1106. // on win95 pcl does not scale at all, ie we could use
  1107. // efScale = (LONG)1; for pcl and we would win95 compat.
  1108. // but,since this does not seem to be reasonable, we shall
  1109. // use the same strategy for ps and pcl unless we find an app
  1110. // which is broken because of this incompatibility. [bodind]
  1111. HLFONT hlfntDef;
  1112. hlfntDef = pdo.hlfntDefault();
  1113. if (!hlfntDef)
  1114. {
  1115. WARNING("gdisrv!cjCopyFontDataW(): PDEVOBJ.hlfntDefault failed\n");
  1116. return ((SIZE_T)0);
  1117. }
  1118. LFONTOBJ lfo(hlfntDef);
  1119. if (!lfo.bValid())
  1120. {
  1121. WARNING("gdisrv!cjCopyFontDataW(): LFONTOBJ constructor failed\n");
  1122. return ((SIZE_T)0);
  1123. }
  1124. if (lfo.plfw()->lfHeight < 0)
  1125. {
  1126. // already in pixels
  1127. efScale = (-lfo.plfw()->lfHeight);
  1128. efScale /= ifio.fwdUnitsPerEm();
  1129. }
  1130. else
  1131. {
  1132. efScale = (LONG)lfo.plfw()->lfHeight;
  1133. efScale /= (LONG) ifio.lfHeight();
  1134. }
  1135. }
  1136. else // screen fonts
  1137. {
  1138. // efScale = Em-Height (pixels) / Em-Height (font units)
  1139. efScale = (LONG) DEFAULT_SCALABLE_FONT_HEIGHT_IN_POINTS;
  1140. efScale /= (LONG) POINTS_PER_INCH;
  1141. efScale *= (LONG) pdo.ulLogPixelsY();
  1142. efScale /= (LONG) ifio.fwdUnitsPerEm();
  1143. }
  1144. }
  1145. // Convert IFIMETRICS into EXTLOGFONTW.
  1146. if (!bIFIMetricsToLogFontW2(dco, &pefdw->elfexw.elfEnumLogfontEx, pifi, (EFLOATEXT)efScale))
  1147. return ((SIZE_T) 0);
  1148. // compute the offset to ntmi
  1149. // use kernel memory (cjEfdw and dpNtmi) to store these values
  1150. pefdw->cjEfdw = cjEfdw = pfeo.cjEfdwPFE();
  1151. pefdw->dpNtmi = dpNtmi = pfeo.dpNtmi();
  1152. // copy out mm info, if any
  1153. NTMW_INTERNAL *pntmi = (NTMW_INTERNAL *)((BYTE *)pefdw + dpNtmi);
  1154. ULONG cAxes = 0;
  1155. if (pifi->flInfo & FM_INFO_TECH_MM)
  1156. {
  1157. PTRDIFF dpDesVec = 0;
  1158. DESIGNVECTOR *pdvSrc;
  1159. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, dpDesignVector))
  1160. {
  1161. dpDesVec = ((IFIEXTRA *)(pifi + 1))->dpDesignVector;
  1162. pdvSrc = (DESIGNVECTOR *)((BYTE *)pifi + dpDesVec);
  1163. cAxes = pdvSrc->dvNumAxes;
  1164. if (cAxes > MM_MAX_NUMAXES)
  1165. cAxes = MM_MAX_NUMAXES;
  1166. RtlCopyMemory(&pefdw->elfexw.elfDesignVector, pdvSrc, (SIZE_T)SIZEOFDV(cAxes));
  1167. pefdw->elfexw.elfDesignVector.dvNumAxes = cAxes;
  1168. }
  1169. else
  1170. {
  1171. ASSERTGDI(dpDesVec, "dpDesignVector == 0 for mm instance\n");
  1172. pefdw->elfexw.elfDesignVector.dvReserved = STAMP_DESIGNVECTOR;
  1173. pefdw->elfexw.elfDesignVector.dvNumAxes = 0;
  1174. }
  1175. }
  1176. else
  1177. {
  1178. pefdw->elfexw.elfDesignVector.dvReserved = STAMP_DESIGNVECTOR;
  1179. pefdw->elfexw.elfDesignVector.dvNumAxes = 0;
  1180. }
  1181. // base font:
  1182. if (pifi->flInfo & FM_INFO_TECH_MM)
  1183. {
  1184. PTRDIFF dpAXIW = 0;
  1185. AXESLISTW *paxlSrc;
  1186. if (pifi->cjIfiExtra > offsetof(IFIEXTRA, dpAxesInfoW))
  1187. {
  1188. dpAXIW = ((IFIEXTRA *)(pifi + 1))->dpAxesInfoW;
  1189. paxlSrc = (AXESLISTW *)((BYTE*)pifi + dpAXIW);
  1190. RtlCopyMemory(&pntmi->entmw.etmAxesList, paxlSrc, SIZEOFAXIW(cAxes));
  1191. }
  1192. else
  1193. {
  1194. ASSERTGDI(dpAXIW, "AxesInfoW needed for base MM font\n");
  1195. pntmi->entmw.etmAxesList.axlReserved = STAMP_AXESLIST;
  1196. pntmi->entmw.etmAxesList.axlNumAxes = 0;
  1197. }
  1198. }
  1199. else
  1200. {
  1201. pntmi->entmw.etmAxesList.axlReserved = STAMP_AXESLIST;
  1202. pntmi->entmw.etmAxesList.axlNumAxes = 0;
  1203. }
  1204. // Convert IFIMETRICS into TEXTMETRICSW.
  1205. if (!bIFIMetricsToTextMetricW2(dco,
  1206. pntmi,
  1207. pfeo,
  1208. (BOOL) bDevice,
  1209. iEnumType,
  1210. (EFLOATEXT)efScale,
  1211. tmDigitizedAspectX,
  1212. tmDigitizedAspectY))
  1213. return ((SIZE_T) 0);
  1214. // let us see if charset override should be used:
  1215. if (bCharSetOverride)
  1216. {
  1217. pefdw->elfexw.elfEnumLogfontEx.elfLogFont.lfCharSet = (BYTE)lfCharSetOverride;
  1218. pntmi->entmw.etmNewTextMetricEx.ntmTm.tmCharSet = (BYTE)lfCharSetOverride;
  1219. }
  1220. // we used to do this only if (iEnumType == TYPE_ENUMFONTFAMILIESEX)
  1221. // but there is no reason to make this distinction, for EnumFonts and
  1222. // EnumFontFamilies, the apps will simply not rely on this information
  1223. // being there and correct.
  1224. if(bCharSetOverride)
  1225. {
  1226. vLookupScript(lfCharSetOverride, (WCHAR *)pefdw->elfexw.elfEnumLogfontEx.elfScript);
  1227. }
  1228. else
  1229. {
  1230. pefdw->elfexw.elfEnumLogfontEx.elfScript[0] = L'\0'; // empty string
  1231. }
  1232. // If pwszFamilyOverride is valid, then use it as the lfFaceName in LOGFONT.
  1233. if ( pwszFamilyOverride != (PWSZ) NULL )
  1234. {
  1235. wcsncpy(
  1236. pefdw->elfexw.elfEnumLogfontEx.elfLogFont.lfFaceName,
  1237. pwszFamilyOverride,
  1238. LF_FACESIZE
  1239. );
  1240. pefdw->elfexw.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] = 0;
  1241. }
  1242. else
  1243. {
  1244. // Otherwise, if efsty is EFSTYLE_OTHER, replace family name (lfFaceName)
  1245. // with face name (elfFullName).
  1246. if ( efsty == EFSTYLE_OTHER )
  1247. {
  1248. wcsncpy(
  1249. pefdw->elfexw.elfEnumLogfontEx.elfLogFont.lfFaceName,
  1250. pefdw->elfexw.elfEnumLogfontEx.elfFullName,
  1251. LF_FACESIZE
  1252. );
  1253. pefdw->elfexw.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] = 0;
  1254. }
  1255. }
  1256. // Compute the FontType flags.
  1257. pefdw->flType = 0;
  1258. if (ifio.bTrueType())
  1259. {
  1260. //
  1261. // [Windows 3.1 compatibility]
  1262. // Win 3.1 hacks TrueType to look like device fonts on printers if the
  1263. // text caps for the DC are not TC_RA_ABLE
  1264. //
  1265. // Note that we check the PDEV directly rather than the DC because
  1266. // DCOBJ::bDisplay() is not TRUE for display ICs (just display DCs
  1267. // which are DCTYPE_DIRECT).
  1268. //
  1269. BOOL bWin31Device = (!pdo.bDisplayPDEV() &&
  1270. !(pdo.flTextCaps() & TC_RA_ABLE ) &&
  1271. (dco.pdc->iGraphicsMode() == GM_COMPATIBLE));
  1272. pefdw->flType |= (TRUETYPE_FONTTYPE | (bWin31Device ? DEVICE_FONTTYPE : 0));
  1273. }
  1274. else if (ifio.bBitmap())
  1275. {
  1276. pefdw->flType |= RASTER_FONTTYPE;
  1277. }
  1278. else if (pifi->flInfo & FM_INFO_TECH_TYPE1)
  1279. {
  1280. // See if this is an old fashioned pfm,pfb Type1 installation.
  1281. // ATM for Win95 enumerates such fonts as device, and many apps that
  1282. // expect ATM to be installed on the system also expect Type1 fonts to
  1283. // be enumerated as DEVICE_FONTTYPE. These apps often do not show Type1
  1284. // fonts in their menus unless we change flType to DEVICE_FONTTTYPE,
  1285. // even though, strictly speaking, these are screen fonts.
  1286. // for the same reason we set this bit for ps open type fonts
  1287. pefdw->flType |= DEVICE_FONTTYPE;
  1288. }
  1289. if (bDevice)
  1290. {
  1291. // If scalable device font, then ONLY the DEVICE_FONTTYPE bit is set.
  1292. if ( ifio.bContinuousScaling() )
  1293. pefdw->flType = DEVICE_FONTTYPE;
  1294. // Otherwise, the DEVICE_FONTTYPE bit is added to the others.
  1295. else
  1296. pefdw->flType |= DEVICE_FONTTYPE;
  1297. // If scalable printer font AND printer does not set any of the
  1298. // scalability flags in TEXTCAPS, then set the ENUMFONT_SCALE_HACK
  1299. // flag. Client-side code will enumerate the font back in several
  1300. // different sizes (see Win95 code, drivers\printer\universa\unidrv\
  1301. // enumobj.c, function UniEnumDFonts() for more details).
  1302. //
  1303. // Note that (according to ZhanW in PSD) on Win95, device fonts that
  1304. // support integral scaling are not reported as such. Instead, each
  1305. // size is returned as if it were a non-scalable font.
  1306. if ( (pdo.ulTechnology() == DT_RASPRINTER) &&
  1307. !(pdo.flTextCaps() & TC_SA_CONTIN) &&
  1308. ifio.bContinuousScaling() )
  1309. {
  1310. pefdw->flType |= ENUMFONT_SCALE_HACK;
  1311. }
  1312. }
  1313. return cjEfdw;
  1314. }
  1315. /******************************Public*Routine******************************\
  1316. *
  1317. * SIZE_T cjOTMASize
  1318. *
  1319. * Similar to cjOTMW, except that 0 is returned if any of the
  1320. * bAnsiSize calls fail to compute the length of the hypothetic ansi string.
  1321. * pcjowmw is always returned valid
  1322. *
  1323. * This routine is very general and it should also work for DBCS case.
  1324. * Possible optmization:
  1325. * verify that bAnsiSize checks for DBCS and if not DBCS, immediately
  1326. * returns cjUni/2 [bodind]
  1327. *
  1328. * History:
  1329. * 20-Feb-1993 -by- Bodin Dresevic [BodinD]
  1330. * Wrote it.
  1331. \**************************************************************************/
  1332. #define bAnsiSize(a,b,c) (NT_SUCCESS(RtlUnicodeToMultiByteSize((a),(b),(c))))
  1333. UINT cjOTMAWSize (
  1334. PIFIMETRICS pifi, // compute size of OTM produced by this buffer
  1335. UINT *pcjotmw
  1336. )
  1337. {
  1338. IFIOBJ ifio(pifi);
  1339. ULONG cjUni, cjAnsi, cjotma;
  1340. BOOL bTmp = TRUE;
  1341. // + 4 for terminating zeros
  1342. cjotma = sizeof(OUTLINETEXTMETRICA) + 4;
  1343. *pcjotmw = ALIGN4(sizeof(OUTLINETEXTMETRICW)) + 4*sizeof(WCHAR);
  1344. cjUni = sizeof(WCHAR) * wcslen(ifio.pwszFamilyName());
  1345. bTmp &= bAnsiSize(&cjAnsi,ifio.pwszFamilyName(),cjUni);
  1346. cjotma += cjAnsi;
  1347. *pcjotmw += (UINT)cjUni;
  1348. cjUni = sizeof(WCHAR) * wcslen(ifio.pwszFaceName());
  1349. bTmp &= bAnsiSize(&cjAnsi,ifio.pwszFaceName(),cjUni);
  1350. cjotma += cjAnsi;
  1351. *pcjotmw += (UINT)cjUni;
  1352. cjUni = sizeof(WCHAR) * wcslen(ifio.pwszStyleName());
  1353. bTmp &= bAnsiSize(&cjAnsi,ifio.pwszStyleName(),cjUni);
  1354. cjotma += cjAnsi;
  1355. *pcjotmw += (UINT)cjUni;
  1356. cjUni = sizeof(WCHAR) * wcslen(ifio.pwszUniqueName());
  1357. bTmp &= bAnsiSize(&cjAnsi,ifio.pwszUniqueName(),cjUni);
  1358. cjotma += cjAnsi;
  1359. *pcjotmw += (UINT)cjUni;
  1360. // if any of bAnsiSize calls failed, return zero
  1361. if (!bTmp)
  1362. {
  1363. cjotma = 0;
  1364. }
  1365. return (UINT)cjotma;
  1366. }
  1367. /******************************Public*Routine******************************\
  1368. * cjIFIMetricsToOTM
  1369. *
  1370. * Converts an IFIMETRICS structure into an OUTLINETEXTMETRICW structure.
  1371. * If input buffer size is greater than the offset of the first string
  1372. * pointer, it is assumed that ALL the strings are to be copied and that
  1373. * the buffer is big enough.
  1374. *
  1375. * While the OUTLINETEXTMETRICW structure is supposed to contain pointers
  1376. * to the strings, this function treats those fields as PTRDIFFs. The caller
  1377. * is responsible for fixing up the structure to contain pointers. This
  1378. * is intended to support copying this structure directly across the client-
  1379. * server interface.
  1380. *
  1381. * Size (including strings) can be computed by calling cjOTMSize.
  1382. *
  1383. * Note: the beginning of the first string is DWORD aligned immediately
  1384. * following the OUTLINETEXTMETRICW structure in the buffer, but
  1385. * subsequent strings are only WORD aligned.
  1386. *
  1387. * Warning: this function does not check to see if the buffer size is
  1388. * big enough. It is ASSUMED, so must be guaranteed by the
  1389. * calling function.
  1390. *
  1391. * Returns:
  1392. * Size of data copied (in bytes), 0 if an error occurred.
  1393. *
  1394. * Wed 27-Jan-1993 -by- Bodin Dresevic [BodinD]
  1395. * update: added tmd.ch ... stuff
  1396. *
  1397. * History:
  1398. * 21-Feb-1992 -by- Gilman Wong [gilmanw]
  1399. * Wrote it.
  1400. \**************************************************************************/
  1401. ULONGSIZE_T cjIFIMetricsToOTMW(
  1402. TMDIFF *ptmd,
  1403. OUTLINETEXTMETRICW *potmw,
  1404. RFONTOBJ &rfo, // need to convert TEXTMETRICS
  1405. DCOBJ &dco, // need to convert TEXTMETRICS
  1406. PIFIMETRICS pifi, // input buffer
  1407. BOOL bStrings // copy strings too
  1408. )
  1409. {
  1410. ULONGSIZE_T cjRet = 0;
  1411. IFIOBJR ifio(pifi, rfo, dco);
  1412. if (!bValidFont(pifi))
  1413. {
  1414. WARNING("gdisrv!cjIFIMetricsToOTM(): invalid font IFIMETRICS\n");
  1415. return (cjRet);
  1416. }
  1417. // Do conversion to fill in TEXTMETRICW field.
  1418. if (!bIFIMetricsToTextMetricWStrict(rfo,dco,&potmw->otmTextMetrics,pifi))
  1419. {
  1420. WARNING("gdisrv!cjIFIMetricsToOTM(): error converting to TEXTMETRIC\n");
  1421. return (cjRet);
  1422. }
  1423. ptmd->chFirst = pifi->chFirstChar ;
  1424. ptmd->chLast = pifi->chLastChar ;
  1425. ptmd->chDefault = pifi->chDefaultChar;
  1426. ptmd->chBreak = pifi->chBreakChar ;
  1427. // If not identity transform, do the transform.
  1428. if ( !rfo.bNtoWIdentity() )
  1429. {
  1430. EFLOAT efBaseline;
  1431. EFLOAT efAscender;
  1432. efBaseline = rfo.efNtoWScaleBaseline(); // cache locally
  1433. efAscender = rfo.efNtoWScaleAscender(); // cache locally
  1434. //
  1435. // CharSlopeRise & CharSlopeRun
  1436. //
  1437. if (efBaseline == efAscender)
  1438. {
  1439. //
  1440. // if the scaling is isotropic then we can use the notional
  1441. // space values of the rise and run
  1442. //
  1443. potmw->otmsCharSlopeRise = (int) ifio.pptlCaret()->y;
  1444. potmw->otmsCharSlopeRun = (int) ifio.pptlCaret()->x;
  1445. }
  1446. else
  1447. {
  1448. if (efAscender.bIsZero())
  1449. {
  1450. RIP("GDI32!cjIFIMetricsToOTMW -- zero efAscender");
  1451. potmw->otmsCharSlopeRise = (int) ifio.pptlCaret()->y;
  1452. potmw->otmsCharSlopeRun = (int) ifio.pptlCaret()->x;
  1453. }
  1454. else
  1455. {
  1456. EFLOAT efTemp = efBaseline;
  1457. efTemp.eqDiv(efBaseline,efAscender);
  1458. potmw->otmsCharSlopeRise = (int) ifio.pptlCaret()->y;
  1459. potmw->otmsCharSlopeRun = (int) lCvt(efTemp, ifio.pptlCaret()->x);
  1460. }
  1461. }
  1462. potmw->otmEMSquare = (UINT) ifio.fwdUnitsPerEm();
  1463. potmw->otmAscent = (int) lCvt(efAscender, (LONG) ifio.fwdTypoAscender());
  1464. potmw->otmDescent = (int) lCvt(efAscender, (LONG) ifio.fwdTypoDescender());
  1465. potmw->otmLineGap = (UINT) lCvt(efAscender, (LONG) ifio.fwdTypoLineGap());
  1466. potmw->otmrcFontBox.top = (int)lCvt(efAscender, ifio.prclFontBox()->top);
  1467. potmw->otmrcFontBox.left = (int)lCvt(efBaseline, ifio.prclFontBox()->left);
  1468. potmw->otmrcFontBox.bottom = (int)lCvt(efAscender, ifio.prclFontBox()->bottom);
  1469. potmw->otmrcFontBox.right = (int)lCvt(efBaseline, ifio.prclFontBox()->right);
  1470. potmw->otmMacAscent = (UINT) lCvt(efAscender, (LONG) ifio.fwdMacAscender());
  1471. potmw->otmMacDescent = (int) lCvt(efAscender, (LONG) ifio.fwdMacDescender());
  1472. potmw->otmMacLineGap = (int) lCvt(efAscender, (LONG) ifio.fwdMacLineGap());
  1473. potmw->otmptSubscriptSize.x = lCvt(efBaseline, (LONG) ifio.fwdSubscriptXSize());
  1474. potmw->otmptSubscriptSize.y = lCvt(efAscender, (LONG) ifio.fwdSubscriptYSize());
  1475. potmw->otmptSubscriptOffset.x = lCvt(efBaseline, (LONG) ifio.fwdSubscriptXOffset());
  1476. potmw->otmptSubscriptOffset.y = lCvt(efAscender, (LONG) ifio.fwdSubscriptYOffset());
  1477. potmw->otmptSuperscriptSize.x = lCvt(efBaseline, (LONG) ifio.fwdSubscriptXSize());
  1478. potmw->otmptSuperscriptSize.y = lCvt(efAscender, (LONG) ifio.fwdSubscriptYSize());
  1479. potmw->otmptSuperscriptOffset.x = lCvt(efBaseline, (LONG) ifio.fwdSuperscriptXOffset());
  1480. potmw->otmptSuperscriptOffset.y = lCvt(efAscender, (LONG) ifio.fwdSuperscriptYOffset());
  1481. potmw->otmsStrikeoutSize = (UINT) lCvt(efAscender, (LONG) ifio.fwdStrikeoutSize());
  1482. potmw->otmsStrikeoutPosition = (int) lCvt(efAscender, (LONG) ifio.fwdStrikeoutPosition());
  1483. potmw->otmsUnderscoreSize = (UINT) lCvt(efAscender, (LONG) ifio.fwdUnderscoreSize());
  1484. potmw->otmsUnderscorePosition = (int) lCvt(efAscender, (LONG) ifio.fwdUnderscorePosition());
  1485. potmw->otmsXHeight = (UINT) lCvt(efAscender, (LONG) ifio.fwdXHeight());
  1486. potmw->otmsCapEmHeight = (UINT) lCvt(efAscender, (LONG) ifio.fwdCapHeight());
  1487. } /* if */
  1488. // Otherwise, copy straight out of the IFIMETRICS
  1489. else
  1490. {
  1491. potmw->otmsCharSlopeRise = (int) ifio.pptlCaret()->y;
  1492. potmw->otmsCharSlopeRun = (int) ifio.pptlCaret()->x;
  1493. potmw->otmEMSquare = ifio.fwdUnitsPerEm();
  1494. potmw->otmAscent = ifio.fwdTypoAscender();
  1495. potmw->otmDescent = ifio.fwdTypoDescender();
  1496. potmw->otmLineGap = (UINT)ifio.fwdTypoLineGap();
  1497. potmw->otmrcFontBox.left = ifio.prclFontBox()->left;
  1498. potmw->otmrcFontBox.top = ifio.prclFontBox()->top;
  1499. potmw->otmrcFontBox.right = ifio.prclFontBox()->right;
  1500. potmw->otmrcFontBox.bottom = ifio.prclFontBox()->bottom;
  1501. potmw->otmMacAscent = ifio.fwdMacAscender();
  1502. potmw->otmMacDescent = ifio.fwdMacDescender();
  1503. potmw->otmMacLineGap = ifio.fwdMacLineGap();
  1504. potmw->otmptSubscriptSize.x = ifio.fwdSubscriptXSize();
  1505. potmw->otmptSubscriptSize.y = ifio.fwdSubscriptYSize();
  1506. potmw->otmptSubscriptOffset.x = ifio.fwdSubscriptXOffset();
  1507. potmw->otmptSubscriptOffset.y = ifio.fwdSubscriptYOffset();
  1508. potmw->otmptSuperscriptSize.x = ifio.fwdSuperscriptXSize();
  1509. potmw->otmptSuperscriptSize.y = ifio.fwdSuperscriptYSize();
  1510. potmw->otmptSuperscriptOffset.x = ifio.fwdSuperscriptXOffset();
  1511. potmw->otmptSuperscriptOffset.y = ifio.fwdSuperscriptYOffset();
  1512. potmw->otmsStrikeoutSize = ifio.fwdStrikeoutSize();
  1513. potmw->otmsStrikeoutPosition = ifio.fwdStrikeoutPosition();
  1514. potmw->otmsUnderscoreSize = ifio.fwdUnderscoreSize();
  1515. potmw->otmsUnderscorePosition = ifio.fwdUnderscorePosition();
  1516. potmw->otmsXHeight = ifio.fwdXHeight();
  1517. potmw->otmsCapEmHeight = ifio.fwdCapHeight();
  1518. } /* else */
  1519. // Set the italic angle. This is in tenths of a degree.
  1520. potmw->otmItalicAngle = ifio.lItalicAngle();
  1521. // Calculate the Italics angle. This is measured CCW from "vertical up"
  1522. // in tenths of degrees. It can be determined from the otmCharSlopeRise
  1523. // and the otmCharSlopeRun.
  1524. if
  1525. (
  1526. potmw->otmItalicAngle==0 &&
  1527. !(ifio.pptlCaret()->y > 0 && ifio.pptlCaret()->x == 0)
  1528. )
  1529. {
  1530. EFLOAT efltTheta;
  1531. LONG lDummy;
  1532. EFLOATEXT efX(ifio.pptlCaret()->y);
  1533. EFLOATEXT efY(-ifio.pptlCaret()->x);
  1534. vArctan(efX,efY,efltTheta,lDummy);
  1535. // this way of rounding is less precise than first multiplying efltTheta
  1536. // by 10 and then doing conversion to LONG, but this is win31 precission.
  1537. // They could have as well returned this in degrees rather than in
  1538. // tenths of degrees [bodind]
  1539. potmw->otmItalicAngle = (LONG)lCvt(efltTheta,(LONG)10);
  1540. // convert [0,360) angles to (-180,180] to be consistent with win31
  1541. if (potmw->otmItalicAngle > 1800)
  1542. potmw->otmItalicAngle -= 3600;
  1543. }
  1544. // The rest of these do not require transformation of IFIMETRICS info.
  1545. UINT cjotma = cjOTMAWSize(pifi,&potmw->otmSize);
  1546. potmw->otmPanoseNumber = *ifio.pPanose();
  1547. potmw->otmfsSelection = ifio.fsSimSelection();
  1548. potmw->otmfsType = ifio.fsType();
  1549. potmw->otmusMinimumPPEM = ifio.fwdLowestPPEm();
  1550. // set offsets to stings to zero if string are not needed
  1551. if (!bStrings)
  1552. {
  1553. potmw->otmpFamilyName = (PSTR) NULL;
  1554. potmw->otmpFaceName = (PSTR) NULL;
  1555. potmw->otmpStyleName = (PSTR) NULL;
  1556. potmw->otmpFullName = (PSTR) NULL;
  1557. }
  1558. else // strings are required
  1559. {
  1560. // This pointer is where we will write the strings.
  1561. PWSZ pwsz = (PWSZ) ((PBYTE) potmw + ALIGN4(sizeof(OUTLINETEXTMETRICW)));
  1562. // Set up pointer as a PTRDIFF, copy the family name.
  1563. potmw->otmpFamilyName = (PSTR) ( (PBYTE) pwsz - (PBYTE) potmw );
  1564. wcscpy(pwsz, ifio.pwszFamilyName());
  1565. pwsz += wcslen(pwsz) + 1; // move pointer to next string
  1566. // Set up pointer as a PTRDIFF, copy the face name.
  1567. potmw->otmpFaceName = (PSTR) ( (PBYTE) pwsz - (PBYTE) potmw );
  1568. wcscpy(pwsz, ifio.pwszFaceName());
  1569. pwsz += wcslen(pwsz) + 1; // move pointer to next string
  1570. // Set up pointer as a PTRDIFF, copy the style name.
  1571. potmw->otmpStyleName = (PSTR) ( (PBYTE) pwsz - (PBYTE) potmw );
  1572. wcscpy(pwsz, ifio.pwszStyleName());
  1573. pwsz += wcslen(pwsz) + 1; // move pointer to next string
  1574. // Set up pointer as a PTRDIFF, copy the full name.
  1575. potmw->otmpFullName = (PSTR) ( (PBYTE) pwsz - (PBYTE) potmw );
  1576. wcscpy(pwsz, ifio.pwszUniqueName());
  1577. // Return length (with strings) This was conveniently cached
  1578. // away in otmSize.
  1579. return(potmw->otmSize);
  1580. }
  1581. // Return length (with or without strings) This was conveniently cached
  1582. // away in otmSize.
  1583. return sizeof(OUTLINETEXTMETRICW);
  1584. }
  1585. /******************************Public*Routine******************************\
  1586. * BOOL bIFIMetricsToLogFont (
  1587. * PLOGFONT plf,
  1588. * PIFIMETRICS pifi
  1589. * )
  1590. *
  1591. * Fill a LOGFONT structure using the information in a IFIMETRICS structure.
  1592. * Units are in NOTIONAL units since font is not realized.
  1593. * Called only by control panel private api's.
  1594. *
  1595. * History:
  1596. * 02-May-1991 -by- Gilman Wong [gilmanw]
  1597. * Wrote it.
  1598. \**************************************************************************/
  1599. VOID vIFIMetricsToLogFontW (
  1600. PLOGFONTW plf,
  1601. PIFIMETRICS pifi
  1602. )
  1603. {
  1604. IFIOBJ ifio(pifi);
  1605. // We will override this with a hack here so that all heights are fixed
  1606. // at 24 pels. This will work because this is the routine that builds
  1607. // the LOGFONTs for GetFontResourceInfo.
  1608. //
  1609. // No function other than GetFontResourceInfo should call this function
  1610. // or this hack will screw them over.
  1611. // If scalable font, set the em height to 24 pel.
  1612. if (ifio.bContinuousScaling())
  1613. {
  1614. plf->lfHeight = -24;
  1615. plf->lfWidth = 0; // don't care, it will be automatically set proportionally
  1616. }
  1617. // Its a bitmap font, so Notional units are OK.
  1618. else
  1619. {
  1620. plf->lfHeight = ifio.lfHeight();
  1621. plf->lfWidth = ifio.lfWidth();
  1622. }
  1623. plf->lfWeight = ifio.lfWeight();
  1624. plf->lfItalic = ifio.lfItalic();
  1625. plf->lfUnderline = ifio.lfUnderline();
  1626. plf->lfStrikeOut = ifio.lfStrikeOut();
  1627. plf->lfEscapement = ifio.lfEscapement();
  1628. plf->lfOrientation = ifio.lfOrientation();
  1629. // to ensure round trip:
  1630. // font file name ->
  1631. // logfont returned by GetFontResourceInfoW ->
  1632. // back to the font that lives in this font file
  1633. if (pifi->dpCharSets)
  1634. {
  1635. BYTE *ajCharsets = (BYTE *)pifi + pifi->dpCharSets;
  1636. plf->lfCharSet = ajCharsets[0]; // guarantees round trip
  1637. }
  1638. else
  1639. {
  1640. plf->lfCharSet = pifi->jWinCharSet;
  1641. }
  1642. plf->lfOutPrecision = ifio.lfOutPrecision();
  1643. plf->lfClipPrecision = ifio.lfClipPrecision();
  1644. plf->lfQuality = ifio.lfQuality();
  1645. plf->lfPitchAndFamily = ifio.lfPitchAndFamily();
  1646. wcsncpy(plf->lfFaceName, ifio.pwszFamilyName(), LF_FACESIZE);
  1647. plf->lfFaceName[LF_FACESIZE-1] = 0;
  1648. }
  1649. /******************************Public*Routine******************************\
  1650. *
  1651. * cjIFIMetricsToETM
  1652. *
  1653. * History:
  1654. * 19-Oct-1993 -by- Bodin Dresevic [BodinD]
  1655. * Wrote it.
  1656. \**************************************************************************/
  1657. VOID vIFIMetricsToETM(
  1658. EXTTEXTMETRIC *petm,
  1659. RFONTOBJ& rfo,
  1660. DCOBJ& dco,
  1661. IFIMETRICS *pifi
  1662. )
  1663. {
  1664. LONG lHeight;
  1665. IFIOBJR ifio(pifi, rfo, dco);
  1666. // IFIOBJ ifio(pifi);
  1667. petm->etmSize = sizeof(EXTTEXTMETRIC);
  1668. // Windows returns everything in notional units except for etmPointSize
  1669. // which is the size in points of the realization in the DC at the time
  1670. // Aldus Escap is called so we do that here.
  1671. // First get the Em height in device units
  1672. lHeight = LONG_FLOOR_OF_FIX(rfo.fxMaxExtent() + FIX_HALF);
  1673. // now get internal leading:
  1674. if (!ifio.bContinuousScaling())
  1675. {
  1676. lHeight -= (LONG)ifio.tmInternalLeading();
  1677. }
  1678. else
  1679. {
  1680. if (rfo.lNonLinearIntLeading() == MINLONG)
  1681. {
  1682. // Set up transform.
  1683. MATRIX mx;
  1684. EXFORMOBJ xo(&mx, DONT_COMPUTE_FLAGS | XFORM_FORMAT_LTOFX);
  1685. ASSERTGDI(xo.bValid(), "GreGetETM, xform\n");
  1686. rfo.vSetNotionalToDevice(xo);
  1687. POINTL ptlHt;
  1688. ptlHt.x = 0;
  1689. ptlHt.y = ifio.fwdUnitsPerEm();
  1690. EVECTORFL evtflHt(ptlHt.x,ptlHt.y);
  1691. xo.bXform(evtflHt);
  1692. EFLOAT ef;
  1693. ef.eqLength(*(POINTFL *) &evtflHt);
  1694. lHeight = lCvt(ef,1);
  1695. }
  1696. else
  1697. {
  1698. // But if the font provider has given us a hinted internal leading,
  1699. // just use it.
  1700. lHeight -= rfo.lNonLinearIntLeading();
  1701. }
  1702. }
  1703. PDEVOBJ po(dco.hdev());
  1704. ASSERTGDI(po.bValid(), "Invalid PDEV");
  1705. //
  1706. // Next convert to points
  1707. //
  1708. {
  1709. LONG lDenom = (LONG) po.ulLogPixelsY();
  1710. LONGLONG ll = (LONGLONG) lHeight;
  1711. ll = ll * 72 + (LONGLONG) (lDenom / 2);
  1712. if (ll > LONG_MAX)
  1713. {
  1714. lHeight = (LONG) (ll / (LONGLONG) lDenom);
  1715. }
  1716. else
  1717. {
  1718. lHeight = ((LONG) ll) / lDenom;
  1719. }
  1720. }
  1721. //
  1722. // The following line of code is forced upon us by the
  1723. // principle that it is better to be Win 3.1 compatible
  1724. // that it is to be correct
  1725. //
  1726. petm->etmPointSize = 20 * (SHORT) lHeight; // convert to twips
  1727. petm->etmOrientation = 0 ;
  1728. petm->etmMasterHeight = ifio.fwdUnitsPerEm();
  1729. petm->etmMinScale = ifio.fwdLowestPPEm();
  1730. petm->etmMaxScale = 0x4000;
  1731. petm->etmMasterUnits = ifio.fwdUnitsPerEm();
  1732. petm->etmCapHeight = ifio.fwdTypoAscender();
  1733. petm->etmXHeight = ifio.fwdXHeight();
  1734. petm->etmLowerCaseAscent = ifio.fwdTypoAscender();
  1735. petm->etmLowerCaseDescent = - ifio.fwdTypoDescender();
  1736. petm->etmSlant = (UINT)(- (INT) ifio.lItalicAngle());
  1737. petm->etmSuperScript = (SHORT) ifio.fwdSuperscriptYOffset();
  1738. petm->etmSubScript = (SHORT) ifio.fwdSubscriptYOffset();
  1739. petm->etmSuperScriptSize = (SHORT) ifio.fwdSuperscriptYSize();
  1740. petm->etmSubScriptSize = (SHORT) ifio.fwdSubscriptYSize();
  1741. petm->etmUnderlineOffset = (SHORT) ifio.fwdUnderscorePosition();
  1742. petm->etmUnderlineWidth = (SHORT) ifio.fwdUnderscoreSize();
  1743. petm->etmDoubleUpperUnderlineOffset =
  1744. ifio.fwdUnderscorePosition() >> 1;
  1745. petm->etmDoubleLowerUnderlineOffset =
  1746. (SHORT)(ifio.fwdUnderscorePosition());
  1747. petm->etmDoubleUpperUnderlineWidth =
  1748. petm->etmDoubleLowerUnderlineWidth =
  1749. ifio.fwdUnderscoreSize() >> 1;
  1750. petm->etmStrikeOutOffset = (SHORT)(ifio.fwdStrikeoutPosition());
  1751. petm->etmStrikeOutWidth = (SHORT)(ifio.fwdStrikeoutSize());
  1752. petm->etmNKernPairs = (WORD) pifi->cKerningPairs;
  1753. petm->etmNKernTracks = 0;
  1754. }
  1755. /********************************************************************************
  1756. * GreNameEscape(LPWSTR, int, int, LPSTR, int, LPSTR)
  1757. *
  1758. * Named escape functionality for installable font drivers.
  1759. *
  1760. * This function allows an escape to be sent to a font driver.
  1761. *
  1762. * History
  1763. * 3-5-95 16:00:54 by Gerrit van Wingerden [gerritv]
  1764. * Wrote it.
  1765. *
  1766. ********************************************************************************/
  1767. INT
  1768. GreNamedEscape(
  1769. LPWSTR pDriver, // Identifies the file name of the font driver
  1770. int iEscape, // Specifies the escape function to be performed.
  1771. int cjIn, // Number of bytes of data pointed to by pvIn.
  1772. LPSTR pvIn, // Points to the input data.
  1773. int cjOut, // Number of bytes of data pointed to by pvOut.
  1774. LPSTR pvOut // Points to the structure to receive output.
  1775. )
  1776. {
  1777. GDIFunctionID(GreNamedEscape);
  1778. WCHAR PathBuffer[MAX_PATH];
  1779. UNICODE_STRING usDriverPath;
  1780. usDriverPath.Length = 0;
  1781. usDriverPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
  1782. usDriverPath.Buffer = PathBuffer;
  1783. RtlAppendUnicodeToString(&usDriverPath,L"\\SystemRoot\\System32\\");
  1784. RtlAppendUnicodeToString(&usDriverPath,pDriver);
  1785. GreAcquireSemaphoreEx(ghsemDriverMgmt, SEMORDER_DRIVERMGMT, NULL);
  1786. PPDEV ppDevList = gppdevList;
  1787. do
  1788. {
  1789. PDEVOBJ pdo((HDEV)ppDevList);
  1790. // first find the driver, make sure the paths match and the
  1791. // driver is really a font driver (that way no one can make
  1792. // a DrvEscape call with a NULL surface to printer driver)
  1793. if (pdo.ppdev->fl & PDEV_FONTDRIVER)
  1794. {
  1795. if ((ppDevList == gppdevATMFD && !_wcsicmp(pDriver, L"atmfd.dll")) ||
  1796. pdo.MatchingLDEVImage(usDriverPath))
  1797. {
  1798. if (PPFNVALID(pdo, Escape))
  1799. {
  1800. // dont make the call while holding the semaphore
  1801. GreReleaseSemaphoreEx(ghsemDriverMgmt);
  1802. return( pdo.Escape)( NULL, (ULONG)iEscape, (ULONG)cjIn, pvIn, (ULONG)cjOut, pvOut );
  1803. }
  1804. }
  1805. }
  1806. } while(ppDevList = ppDevList->ppdevNext);
  1807. GreReleaseSemaphoreEx(ghsemDriverMgmt);
  1808. return(0);
  1809. }