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.

1385 lines
44 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fntxform.cxx
  3. *
  4. * Created: 02-Feb-1993 16:33:14
  5. * Author: Kirk Olynyk [kirko]
  6. *
  7. * Copyright (c) 1991-1999 Microsoft Corporation
  8. \**************************************************************************/
  9. #ifdef COMMENT_BLOCK
  10. Author of these notes: BodinD
  11. Differences between vector fonts and tt fonts in win31 + notes about what
  12. nt does in these cases
  13. 1) Italicization
  14. for vector fonts it is done is device space (wrong)
  15. after notional to device transform has been applied
  16. for tt fonts it is done right, font is first italicized in notional
  17. space and then notional to device transform is applied.
  18. on NT I italicized both vector and tt fonts in notional space.
  19. 2) emboldening
  20. On NT I was able to fix vector fonts so as to shift
  21. the glyph in the direction of baseline (which may be different
  22. from x axis if esc != 0) thus preserving
  23. rotational invariance of emboldened vector fonts. (check it out, it is cool)
  24. for NT 5.0 we will have this also working for TT.
  25. 3) scaling properties under anisotropic page to device transform
  26. tt fonts scale ISOtropically which clearly is wrong for
  27. ANISOtropic page to device transform. The isotropic scaling factor
  28. for tt fonts is the ABSOLUTE VALUE value of the yy component
  29. of the page to device transform. From here it follows that
  30. tt fonts igore the request to flip x and/or y axis
  31. and the text is always written left to right up side up.
  32. unlike tt fonts, vector fonts do scale ANISOtropically given
  33. the anisotropic page to device xform. The request to flip
  34. y axis is ignored (like for tt fonts). If the tranform
  35. requests the flip of text in x axis, the text comes out GARBLED.
  36. (DavidW, please, give it a try)
  37. on NT I emulated this behavior in COMPATIBLE mode, execpt for the
  38. GARBLED "mode" for vector fonts. In ADVANCED mode I made both vt and tt
  39. fonts respect xform and behave in the same fashion wrt xforms.
  40. 4) interpretation of escapement and orientation
  41. in tt case escapement is intepreted as DEVICE space concept
  42. What this means is that after notional to world and world to
  43. device scaling factors are applied the font is rotated in device space.
  44. (conceptually wrong but agrees with win31 spec).
  45. in vector font case escapement is intepreted as WORLD space concept
  46. font is first rotated in world space and then world (page) to device
  47. transform is applied.
  48. (conceptually correct but it disagrees with with win31 spec)
  49. on NT I went through excruiciating pain to emulate this behavior
  50. under COMPATIBLE mode. In ADVANCED mode, vector and tt fonts
  51. behave the same and esc and orientation are interpreted as WORLD
  52. space concepts.
  53. 5) behavior in case of (esc != orientation)
  54. tt fonts set orientation = esc
  55. vector fonts snap orientation to the nearest multiple of
  56. 90 degrees relative to orientation.
  57. (e.g. esc=300, or = -500 => esc = 300, or = - 600)
  58. (DavidW, please, give it a try, also please use anisotropic
  59. xform with window extents (-1,1))
  60. on NT we emulate this behavior for in COMPATIBLE mode,
  61. except for snapp orientation "fetature". The motivation is that
  62. apps will explicitely set orientation and escapement to differ
  63. by +/- 900, if they want it, rather than make use
  64. of "snapping feature". In advanced mode if esc!=orientation
  65. we use egg-shell algorithm to render text.
  66. #endif COMMENT_BLOCK
  67. #include "precomp.hxx"
  68. #include "flhack.hxx"
  69. // We include winuserp.h for the app compatibility #define GACF2_MSSHELLDLG
  70. #include "winuserp.h"
  71. //
  72. // external procedures from draweng.cxx
  73. //
  74. extern BOOL gbShellFontCompatible;
  75. EFLOAT efCos(EFLOAT x);
  76. EFLOAT efSin(EFLOAT x);
  77. /******************************Public*Routine******************************\
  78. * lGetDefaultWorldHeight *
  79. * *
  80. * "If lfHeight is zero, a reasonable default size is substituted." *
  81. * [SDK Vol 2]. Fortunately, the device driver is kind enough to *
  82. * suggest a nice height (in pixels). We shall return this suggestion *
  83. * in World corrdinates. *
  84. * *
  85. * History: *
  86. * Thu 23-Jul-1992 13:01:49 by Kirk Olynyk [kirko] *
  87. * Wrote it. *
  88. \**************************************************************************/
  89. LONG
  90. lGetDefaultWorldHeight(
  91. DCOBJ *pdco
  92. )
  93. {
  94. LONG lfHeight;
  95. {
  96. PDEVOBJ pdo(pdco->hdev());
  97. if (!pdo.bValid())
  98. {
  99. RIP("gdisrv!MAPPER:MAPPER -- invalid DCOBJ\n");
  100. return(FM_EMERGENCY_DEFAULT_HEIGHT);
  101. }
  102. LFONTOBJ lfo(pdo.hlfntDefault());
  103. if (!lfo.bValid())
  104. {
  105. RIP("gdisrv!MAPPER::MAPPER -- invalid LFONTOBJ\n");
  106. return(FM_EMERGENCY_DEFAULT_HEIGHT);
  107. }
  108. lfHeight = lfo.plfw()->lfHeight;
  109. }
  110. //
  111. // Now I must transform this default height in pixels to a height
  112. // in World coordinates. Then this default height must be written
  113. // into the LFONTOBJ supplied by the DC.
  114. //
  115. if (!pdco->pdc->bWorldToDeviceIdentity())
  116. {
  117. //
  118. // Calculate the scaling factor along the y direction
  119. // The correct thing to do might be to take the
  120. // scaling factor along the ascender direction [kirko]
  121. //
  122. EFLOAT efT;
  123. efT.eqMul(pdco->pdc->efM21(),pdco->pdc->efM21());
  124. EFLOAT efU;
  125. efU.eqMul(pdco->pdc->efM22(),pdco->pdc->efM22());
  126. efU.eqAdd(efU,efT);
  127. efU.eqSqrt(efU);
  128. // at this point efU scales from world to device
  129. efT.vSetToOne();
  130. efU.eqDiv(efT,efU);
  131. // at this point efU scales from device to world
  132. lfHeight = lCvt(efU,FIX_FROM_LONG(lfHeight));
  133. }
  134. // insure against a trivial default height
  135. if (lfHeight == 0)
  136. {
  137. return(FM_EMERGENCY_DEFAULT_HEIGHT);
  138. }
  139. //
  140. // This value should be the character height and not the CELL height for
  141. // Win 3.1 compatability. Fine Windows apps like CA Super Project will
  142. // have clipped text if this isn't the case. [gerritv]
  143. //
  144. lfHeight *= -1;
  145. return(lfHeight);
  146. }
  147. /******************************Public*Routine******************************\
  148. * vGetNtoW
  149. *
  150. * Calculates the notional to world transformation for fonts. This
  151. * includes that funny factor of -1 for the different mapping modes
  152. *
  153. * Called by:
  154. * bGetNtoW [FONTMAP.CXX]
  155. *
  156. * History:
  157. * Wed 15-Apr-1992 15:35:10 by Kirk Olynyk [kirko]
  158. * Wrote it.
  159. \**************************************************************************/
  160. LONG lNormAngle(LONG lAngle);
  161. VOID vGetNtoW
  162. (
  163. MATRIX *pmx, // destination for transform
  164. LOGFONTW *pelfw, // wish list
  165. IFIOBJ& ifio, // font to be used
  166. DCOBJ *pdco
  167. )
  168. {
  169. LONG lAngle,lfHeight;
  170. EFLOAT efHeightScale,efWidthScale;
  171. lfHeight = pelfw->lfHeight;
  172. if (lfHeight == 0)
  173. {
  174. lfHeight = lGetDefaultWorldHeight(pdco);
  175. }
  176. ASSERTGDI(lfHeight,"gdisrv!vGetNtoW -- zero lfHeight\n");
  177. // compute the height scale:
  178. {
  179. EFLOAT efHeightNum,efHeightDen;
  180. if (lfHeight > 0)
  181. {
  182. efHeightNum = lfHeight;
  183. efHeightDen = ifio.lfHeight();
  184. }
  185. else if (lfHeight < 0)
  186. {
  187. efHeightNum = -lfHeight;
  188. efHeightDen = (LONG) ifio.fwdUnitsPerEm();
  189. }
  190. efHeightScale.eqDiv(efHeightNum,efHeightDen);
  191. }
  192. // compute the width scale:
  193. POINTL ptlRes;
  194. if (pelfw->lfWidth != 0)
  195. {
  196. EFLOAT efWidthNum,efWidthDen;
  197. ptlRes.x = ptlRes.y = 1;
  198. if (ifio.lfWidth() >= 0)
  199. {
  200. efWidthNum = (LONG) ABS(pelfw->lfWidth);
  201. efWidthDen = ifio.lfWidth();
  202. efWidthScale.eqDiv(efWidthNum,efWidthDen);
  203. }
  204. else
  205. {
  206. RIP(" gdisrv!vGetNtoW -- bad fwdAveCharWidth\n");
  207. efWidthScale = efHeightScale;
  208. }
  209. }
  210. else
  211. {
  212. ptlRes = *ifio.pptlAspect();
  213. efWidthScale = efHeightScale;
  214. }
  215. // make sure that fonts look the same on printers of different resolutions:
  216. PDEVOBJ pdo(pdco->hdev());
  217. if (pdo.bValid())
  218. {
  219. if (pdo.ulLogPixelsX() != pdo.ulLogPixelsY())
  220. {
  221. ptlRes.y *= (LONG)pdo.ulLogPixelsX();
  222. ptlRes.x *= (LONG)pdo.ulLogPixelsY();
  223. }
  224. }
  225. else
  226. {
  227. RIP("gdisrv!bGetNtoW, pdevobj problem\n");
  228. }
  229. pmx->efM11.vSetToZero();
  230. pmx->efM12.vSetToZero();
  231. pmx->efM21.vSetToZero();
  232. pmx->efM22.vSetToZero();
  233. // Get the orientation from the LOGFONT. Win 3.1 treats the orientation
  234. // as a rotation towards the negative y-axis. We do the same, which
  235. // requires adjustment for some map modes.
  236. lAngle = pelfw->lfOrientation;
  237. if (pdco->pdc->bYisUp())
  238. lAngle = 3600-lAngle;
  239. lAngle = lNormAngle(lAngle);
  240. switch (lAngle)
  241. {
  242. case 0 * ORIENTATION_90_DEG:
  243. pmx->efM11 = efWidthScale;
  244. pmx->efM22 = efHeightScale;
  245. if (!pdco->pdc->bYisUp())
  246. {
  247. pmx->efM22.vNegate();
  248. }
  249. break;
  250. case 1 * ORIENTATION_90_DEG:
  251. pmx->efM12 = efWidthScale;
  252. pmx->efM21 = efHeightScale;
  253. if (!pdco->pdc->bYisUp())
  254. {
  255. pmx->efM12.vNegate();
  256. }
  257. pmx->efM21.vNegate();
  258. break;
  259. case 2 * ORIENTATION_90_DEG:
  260. pmx->efM11 = efWidthScale;
  261. pmx->efM22 = efHeightScale;
  262. pmx->efM11.vNegate();
  263. if (pdco->pdc->bYisUp())
  264. {
  265. pmx->efM22.vNegate();
  266. }
  267. break;
  268. case 3 * ORIENTATION_90_DEG:
  269. pmx->efM12 = efWidthScale;
  270. pmx->efM21 = efHeightScale;
  271. if (pdco->pdc->bYisUp())
  272. {
  273. pmx->efM12.vNegate();
  274. }
  275. break;
  276. default:
  277. {
  278. EFLOATEXT efAngle = lAngle;
  279. efAngle /= (LONG) 10;
  280. EFLOAT efCosine = efCos(efAngle);
  281. EFLOAT efSine = efSin(efAngle);
  282. pmx->efM11.eqMul(efWidthScale, efCosine);
  283. pmx->efM22.eqMul(efHeightScale,efCosine);
  284. pmx->efM12.eqMul(efWidthScale, efSine);
  285. pmx->efM21.eqMul(efHeightScale,efSine);
  286. }
  287. pmx->efM21.vNegate();
  288. if (!pdco->pdc->bYisUp())
  289. {
  290. pmx->efM12.vNegate();
  291. pmx->efM22.vNegate();
  292. }
  293. break;
  294. }
  295. // adjust for non-square resolution:
  296. if (pdo.ulLogPixelsX() != pdo.ulLogPixelsY())
  297. {
  298. EFLOATEXT efTmp = (LONG)pdo.ulLogPixelsX();
  299. efTmp /= (LONG)pdo.ulLogPixelsY();
  300. if (pelfw->lfWidth == 0)
  301. {
  302. pmx->efM11 *= efTmp;
  303. pmx->efM21 *= efTmp;
  304. }
  305. else
  306. {
  307. pmx->efM12 /= efTmp;
  308. pmx->efM21 *= efTmp;
  309. }
  310. }
  311. EXFORMOBJ xoNW(pmx, DONT_COMPUTE_FLAGS);
  312. xoNW.vRemoveTranslation();
  313. xoNW.vComputeAccelFlags();
  314. }
  315. //
  316. // galFloat -- an array of LONG's that represent the IEEE floating
  317. // point equivalents of the integers corresponding
  318. // to the indices
  319. //
  320. LONG
  321. galFloat[] = {
  322. 0x00000000, // = 0.0
  323. 0x3f800000, // = 1.0
  324. 0x40000000, // = 2.0
  325. 0x40400000, // = 3.0
  326. 0x40800000, // = 4.0
  327. 0x40a00000, // = 5.0
  328. 0x40c00000, // = 6.0
  329. 0x40e00000, // = 7.0
  330. 0x41000000 // = 8.0
  331. };
  332. LONG
  333. galFloatNeg[] = {
  334. 0x00000000, // = 0.0
  335. 0xBf800000, // = -1.0
  336. 0xC0000000, // = -2.0
  337. 0xC0400000, // = -3.0
  338. 0xC0800000, // = -4.0
  339. 0xC0a00000, // = -5.0
  340. 0xC0c00000, // = -6.0
  341. 0xC0e00000, // = -7.0
  342. 0xC1000000 // = -8.0
  343. };
  344. /******************************Public*Routine******************************\
  345. * bGetNtoD
  346. *
  347. * Get the notional to device transform for the font drivers
  348. *
  349. * Called by:
  350. * PFEOBJ::bSetFontXform [PFEOBJ.CXX]
  351. *
  352. * History:
  353. * Tue 12-Jan-1993 11:58:41 by Kirk Olynyk [kirko]
  354. * Added a quick code path for non-transformable (bitmap) fonts.
  355. * Wed 15-Apr-1992 15:09:22 by Kirk Olynyk [kirko]
  356. * Wrote it.
  357. \**************************************************************************/
  358. BOOL
  359. bGetNtoD(
  360. FD_XFORM *pfdx, // pointer to the buffer to recieve the
  361. // notional to device transformation for the
  362. // font driver. There are a couple of
  363. // important things to remember. First,
  364. // according to the conventions of the ISO
  365. // committee, the coordinate space for notional
  366. // (font designer) spaces are cartesian.
  367. // However, due to a series of errors on my part
  368. // [kirko] the convention that is used by the
  369. // DDI is that the notional to device transformation
  370. // passed over the DDI assumes that both the notional
  371. // and the device space are anti-Cartesian, that is,
  372. // positive y increases in the downward direction.
  373. // The fontdriver assumes that
  374. // one unit in device space corresponds to the
  375. // distance between pixels. This is different from
  376. // GDI's internal view, where one device unit
  377. // corresponds to a sub-pixel unit.
  378. LOGFONTW *pelfw, // points to the extended logical font defining
  379. // the font that is requested by the application.
  380. // Units are ususally in World coordinates.
  381. IFIOBJ& ifio, // font to be used
  382. DCOBJ *pdco, // the device context defines the transforms between
  383. // the various coordinate spaces.
  384. POINTL* const pptlSim
  385. )
  386. {
  387. MATRIX mxNW, mxND;
  388. if(( pptlSim->x ) && !ifio.bContinuousScaling())
  389. {
  390. //
  391. // This code path is for bitmap / non-scalable fonts. The notional
  392. // to device transformation is determined by simply looking up
  393. // the scaling factors for both the x-direction and y-direcion
  394. //
  395. #if DBG
  396. if (!(0 < pptlSim->x && pptlSim->x <= sizeof(galFloat)/sizeof(LONG)))
  397. {
  398. DbgPrint("\t*pptlSim = (%d,%d)\n",pptlSim->x,pptlSim->y);
  399. RIP("gre -- bad *pptlSim\n");
  400. //
  401. // bogus fix up for debugging purposes only
  402. //
  403. pptlSim->x = 1;
  404. pptlSim->y = 1;
  405. }
  406. #endif
  407. ULONG uAngle = 0;
  408. if( ifio.b90DegreeRotations() )
  409. {
  410. // If the WorldToDeive transform is not identity,
  411. // We have to consider WToD Xform for font orientation
  412. // This is only for Advanced Mode
  413. if(!(pdco->pdc->bWorldToDeviceIdentity()) )
  414. {
  415. INT s11,s12,s21,s22;
  416. EXFORMOBJ xo(*pdco,WORLD_TO_DEVICE);
  417. // Get Matrix element
  418. // lSignum() returns -1, if the element is minus value, otherwise 1
  419. s11 = (INT) xo.efM11().lSignum();
  420. s12 = (INT) xo.efM12().lSignum();
  421. s21 = (INT) xo.efM21().lSignum();
  422. s22 = (INT) xo.efM22().lSignum();
  423. // Check mapping mode
  424. if (pdco->pdc->bYisUp())
  425. {
  426. s21 = -s21;
  427. s22 = -s22;
  428. uAngle = 3600 - lNormAngle( pelfw->lfOrientation );
  429. }
  430. else
  431. {
  432. uAngle = lNormAngle( pelfw->lfOrientation );
  433. }
  434. // Compute font orientation on distination device
  435. //
  436. // This logic depend on that -1 is represented as All bits are ON.
  437. uAngle = (ULONG)( lNormAngle
  438. (
  439. uAngle
  440. + (s12 & 900)
  441. + (s11 & 1800)
  442. + (s21 & 2700)
  443. ) / ORIENTATION_90_DEG
  444. );
  445. }
  446. else
  447. {
  448. uAngle = (ULONG)(lNormAngle(pelfw->lfOrientation) /
  449. ORIENTATION_90_DEG );
  450. }
  451. }
  452. switch( uAngle )
  453. {
  454. case 0: // 0 Degrees
  455. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[pptlSim->x]);
  456. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[0 ]);
  457. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[0 ]);
  458. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloatNeg[pptlSim->y]);
  459. break;
  460. case 1: // 90 Degrees
  461. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloatNeg[pptlSim->x]);
  462. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[0 ]);
  463. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[0 ]);
  464. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloatNeg[pptlSim->y]);
  465. break;
  466. case 2: // 180 Degrees
  467. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloatNeg[pptlSim->x]);
  468. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[0 ]);
  469. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[0 ]);
  470. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[pptlSim->y]);
  471. break;
  472. case 3: // 270 Degress
  473. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[pptlSim->y]);
  474. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[0 ]);
  475. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[0 ]);
  476. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[pptlSim->x]);
  477. break;
  478. default:
  479. WARNING("bGetNtoD():Invalid Angle\n");
  480. break;
  481. }
  482. return(TRUE);
  483. }
  484. vGetNtoW(&mxNW, pelfw, ifio, pdco);
  485. EXFORMOBJ xoND(&mxND, DONT_COMPUTE_FLAGS);
  486. if ( pdco->pdc->bWorldToDeviceIdentity() == FALSE)
  487. {
  488. if (!xoND.bMultiply(&mxNW,&pdco->pdc->mxWorldToDevice()))
  489. {
  490. return(FALSE);
  491. }
  492. //
  493. // Compensate for the fact that for the font driver, one
  494. // device unit corresponds to the distance between pixels,
  495. // whereas for the engine, one device unit corresponds to
  496. // 1/16'th the way between pixels
  497. //
  498. mxND.efM11.vDivBy16();
  499. mxND.efM12.vDivBy16();
  500. mxND.efM21.vDivBy16();
  501. mxND.efM22.vDivBy16();
  502. }
  503. else
  504. {
  505. mxND = mxNW;
  506. }
  507. SET_FLOAT_WITH_LONG(pfdx->eXX,mxND.efM11.lEfToF());
  508. SET_FLOAT_WITH_LONG(pfdx->eXY,mxND.efM12.lEfToF());
  509. SET_FLOAT_WITH_LONG(pfdx->eYX,mxND.efM21.lEfToF());
  510. SET_FLOAT_WITH_LONG(pfdx->eYY,mxND.efM22.lEfToF());
  511. return(TRUE);
  512. }
  513. /******************************Public*Routine******************************\
  514. *
  515. * bGetNtoW_Win31
  516. *
  517. * Computes notional to world transform for the compatible
  518. * mode Basically, computes notional to device transform in
  519. * win31 style using page to device transform (ignoring
  520. * possibly exhistent world to page transform. then page to
  521. * device is factored out leaving us with win31 style crippled
  522. * notional to world transform. As to the page to device
  523. * transform, either the one in the dc is used, or if this
  524. * routine has a metafile client, then page to device
  525. * transform of the recording device is used. Metafile code
  526. * stored this transform in the dc.
  527. *
  528. * Called by:
  529. * bGetNtoD_Win31 [FONTMAP.CXX]
  530. *
  531. * History:
  532. * 24-Nov-1992 -by- Bodin Dresevic [BodinD]
  533. * Wrote it.
  534. \**************************************************************************/
  535. BOOL
  536. bGetNtoW_Win31(
  537. MATRIX *pmxNW, // store the result here
  538. LOGFONTW *pelfw, // points to the extended logical font defining
  539. // the font that is requested by the application.
  540. // Units are ususally in World coordinates.
  541. IFIOBJ& ifio, // font to be used
  542. DCOBJ *pdco, // the device context defines the transforms between
  543. // the various coordinate spaces.
  544. FLONG fl, // The flags supported are:
  545. //
  546. // ND_IGNORE_ESC_AND_ORIENT
  547. //
  548. // The presence of this flag indicates that
  549. // the escapement and orientation values
  550. // of the LOGFONT should be ignored. This
  551. // is used for GetGlyphOutline which ignores
  552. // these values on Win 3.1. Corel Draw 5.0
  553. // relies on this behavior to print rotated
  554. // text.
  555. //
  556. BOOL bIsLinkedFont // is passed in as TRUE if the font is linked, FALSE otherwise
  557. )
  558. {
  559. ASSERTGDI(
  560. (fl & ~(ND_IGNORE_ESC_AND_ORIENT | ND_IGNORE_MAP_MODE)) == 0,
  561. "gdisrv!NtoW_Win31 -- bad value for fl\n"
  562. );
  563. LONG lfHeight;
  564. EFLOAT efHeightScale,
  565. efHeightNum,
  566. efHeightDen,
  567. efWidthScale,
  568. efWidthDen,
  569. efDefaultScale;
  570. if (ifio.lfWidth() == 0)
  571. {
  572. WARNING("gdisrv!bGetNtoW_Win31, AvgChW\n");
  573. }
  574. BOOL bUseMeta = pdco->pdc->bUseMetaPtoD();
  575. BOOL bDoXform = (!(fl & ND_IGNORE_MAP_MODE) &&
  576. (bUseMeta || !pdco->pdc->bPageToDeviceScaleIdentity()));
  577. BOOL bPD11Is1 = TRUE; // efPD11 == 1
  578. BOOL bPD22IsNeg = FALSE; // efPD22 is negative
  579. EFLOATEXT efPD11;
  580. if ((lfHeight = pelfw->lfHeight) == 0)
  581. {
  582. lfHeight = lGetDefaultWorldHeight(pdco);
  583. }
  584. ASSERTGDI(lfHeight,"gdisrv!vGetNtoW -- zero lfHeight\n");
  585. // dchinn 9/16/98:
  586. // A fix to the Visual FoxPro 5.0 hcw.exe bug. The bug is that the
  587. // dialog boxes in hcw.exe are designed with 8pt MS Shell Dlg
  588. // (at 96dpi, that's 11ppem), but the text in the dialog appears
  589. // as 12ppem in NT 5. A possible contributing reason for this bug
  590. // is that the default shell dialog font in NT 4 is MS Sans Serif, which
  591. // is a bitmap font with only sizes 8, 10, 12, 14, 18, 24. The default
  592. // shell dialog font for NT 5 is Microsoft Sans Serif, which is an OpenType
  593. // (TrueType) font. Perhaps FoxPro somehow hardcodes 12ppem somewhere.
  594. // The fix here is that if the logfont is for the MS Shell Dlg at 12ppem
  595. // then we actually use an lfHeight of 11ppem.
  596. //
  597. // We only adjust for negative lfHeight because when lfHeight is negative,
  598. // the logfont is requesting an em height (as opposed to ascender plus
  599. // descender if lfHeight is positive).
  600. //
  601. // Well, change of heart, Lotus notes is asking for lfHeight == +15,
  602. // expecting to get the same size font as ms sans serif at lfHeight = -11;
  603. // so we have to adjust for positive lfHeights as well [bodind]
  604. //
  605. // Finally, this table of conversions below handles the case when
  606. // small fonts is set on the system (not large fonts)
  607. // (actually, it handles the lowest size for large fonts
  608. // and two smallest sizes for small fonts [bodind])
  609. if (gbShellFontCompatible &&
  610. !_wcsicmp(pelfw->lfFaceName, L"MS Shell Dlg") &&
  611. !bIsLinkedFont) // don't do font size collapsing if dealing with a linked font
  612. {
  613. if (lfHeight > 0)
  614. {
  615. // sizes 12 and 13 are mapped to 14 because in bitmap font there is
  616. // no size smaller than 14. But we do not want to map everything from
  617. // 1 to 15 to 14 for tt, we only want to bump up as few sizes as needed to
  618. // get the backwards compat with nt 40 in the shell.
  619. if ((lfHeight >= 12) && (lfHeight <= 15))
  620. {
  621. lfHeight = 14; // same as -11 for ms sans serif
  622. }
  623. else if ((lfHeight > 15) && (lfHeight <= 19))
  624. {
  625. lfHeight = 16; // same as -13 for ms sans serif
  626. }
  627. }
  628. else // lfHeight < 0
  629. {
  630. // sizes -9 and -10 are mapped to -11 because in bitmap font there is
  631. // no size smaller than -11. But we do not want to map everything from
  632. // -11 to -15 to 14 for tt, we only want to bump up as few sizes as needed to
  633. // get the backwards compat with nt 40 in the shell.
  634. if ((lfHeight >= -12) && (lfHeight <= -9))
  635. {
  636. lfHeight = -11; // fixes older version of outlook and janna contact dialogs
  637. }
  638. else if ((lfHeight > -16) && (lfHeight <= -13))
  639. {
  640. lfHeight = -13; // just in case
  641. }
  642. }
  643. #if 0
  644. if (gbShellFontCompatible && !_wcsicmp(pelfw->lfFaceName, L"MS Shell Dlg") && ((lfHeight == -12) || (lfHeight == -14)
  645. || (lfHeight == -15) || (lfHeight == -17) || (lfHeight == -18) || (lfHeight > -11)
  646. || ((lfHeight > -24) && (lfHeight < -19))
  647. || ((lfHeight > -32) && (lfHeight < -24)) || (lfHeight < -32)
  648. ))
  649. {
  650. DbgPrint("\tNTFONT: MS Shell Dlg used at size %d ppem\n, dialog may be clipped",-lfHeight);
  651. }
  652. #endif
  653. }
  654. if (lfHeight > 0)
  655. {
  656. efHeightNum = (LONG)lfHeight;
  657. efHeightDen = (LONG)ifio.lfHeight();
  658. }
  659. else // lfHeight < 0
  660. {
  661. efHeightNum = (LONG)(-lfHeight);
  662. efHeightDen = (LONG) ifio.fwdUnitsPerEm();
  663. }
  664. efDefaultScale.eqDiv(efHeightNum,efHeightDen);
  665. pmxNW->efM22 = efDefaultScale;
  666. efHeightScale = efDefaultScale;
  667. if (bDoXform)
  668. {
  669. EFLOATEXT efPD22;
  670. // first check if hock wants us to use his page to device scale factors
  671. if (bUseMeta)
  672. {
  673. efPD11 = pdco->pdc->efMetaPtoD11();
  674. efPD22 = pdco->pdc->efMetaPtoD22();
  675. }
  676. else if (!pdco->pdc->bPageToDeviceScaleIdentity())
  677. {
  678. if (!pdco->pdc->bWorldToPageIdentity())
  679. {
  680. // need to compute page to device scaling coefficients
  681. // that will be used in computing crippled win31 style
  682. // notional to world scaling coefficients
  683. // This is because PtoD is not stored on the server side
  684. // any more. This somewhat slow code path is infrequent
  685. // and not perf critical
  686. EFLOATEXT efTmp;
  687. efPD11 = pdco->pdc->lViewportExtCx();
  688. efTmp = pdco->pdc->lWindowExtCx();
  689. efPD11.eqDiv(efPD11,efTmp);
  690. efPD22 = pdco->pdc->lViewportExtCy();
  691. efTmp = pdco->pdc->lWindowExtCy();
  692. efPD22.eqDiv(efPD22,efTmp);
  693. }
  694. else // page to device == world to device:
  695. {
  696. efPD11 = pdco->pdc->efM11();
  697. efPD22 = pdco->pdc->efM22();
  698. // Compensate for the fact that for the font driver, one
  699. // device unit corresponds to the distance between pixels,
  700. // whereas for the engine, one device unit corresponds to
  701. // 1/16'th the way between pixels
  702. efPD11.vDivBy16();
  703. efPD22.vDivBy16();
  704. ASSERTGDI(pdco->pdc->efM12().bIsZero(), "GDISRV: nonzero m12 IN WIN31 MODE\n");
  705. ASSERTGDI(pdco->pdc->efM21().bIsZero(), "GDISRV: nonzero m21 IN WIN31 MODE\n");
  706. }
  707. }
  708. #if DBG
  709. else
  710. RIP("gdisrv!ntow_win31\n");
  711. #endif
  712. bPD11Is1 = efPD11.bIs1();
  713. bPD22IsNeg = efPD22.bIsNegative();
  714. if (!efPD22.bIs1())
  715. efHeightScale.eqMul(efHeightScale,efPD22);
  716. // In win31 possible y flip or x flip on the text are not respected
  717. // so that signs do not make it into the xform
  718. efHeightScale.vAbs();
  719. }
  720. if (bPD22IsNeg)
  721. {
  722. // change the sign if necessary so that
  723. // pmxNW->efM22 * efPtoD22 == efHeightScale, which is enforced to be > 0
  724. pmxNW->efM22.vNegate();
  725. }
  726. PDEVOBJ pdo(pdco->hdev());
  727. if (!pdo.bValid())
  728. {
  729. RIP("gdisrv!bGetNtoW_Win31, pdevobj problem\n");
  730. return FALSE;
  731. }
  732. // In the case that lfWidth is zero or in the MSBADWIDTH case we will need
  733. // to adjust efWidthScale if VerRes != HorRez
  734. BOOL bMustCheckResolution = TRUE;
  735. if (pelfw->lfWidth)
  736. {
  737. // This makes no sense, but has to be here for win31 compatibility.
  738. // Win31 is computing the number of
  739. // pixels in x direction of the avgchar width scaled along y.
  740. // I find this a little bizzare [bodind]
  741. EFLOAT efAveChPixelWidth;
  742. efAveChPixelWidth = (LONG) ifio.fwdAveCharWidth();
  743. // take the resolution into account,
  744. #if 0
  745. if ((pdo.ulLogPixelsX() != pdo.ulLogPixelsY()) && !bUseMeta)
  746. {
  747. EFLOAT efTmp;
  748. efTmp = (LONG)pdo.ulLogPixelsY();
  749. efAveChPixelWidth.eqMul(efAveChPixelWidth,efTmp);
  750. efTmp = (LONG)pdo.ulLogPixelsX();
  751. efAveChPixelWidth.eqDiv(efAveChPixelWidth,efTmp);
  752. }
  753. #endif
  754. efWidthDen = efAveChPixelWidth; // save the result for later
  755. efAveChPixelWidth.eqMul(efAveChPixelWidth,efHeightScale);
  756. LONG lAvChPixelW, lReqPixelWidth;
  757. // requested width in pixels:
  758. EFLOAT efReqPixelWidth;
  759. lReqPixelWidth = (LONG)ABS(pelfw->lfWidth);
  760. efReqPixelWidth = lReqPixelWidth;
  761. BOOL bOk = TRUE;
  762. if (bDoXform)
  763. {
  764. if (!bPD11Is1)
  765. {
  766. efReqPixelWidth.eqMul(efReqPixelWidth,efPD11);
  767. bOk = efReqPixelWidth.bEfToL(lReqPixelWidth);
  768. }
  769. efReqPixelWidth.vAbs();
  770. if (lReqPixelWidth < 0)
  771. lReqPixelWidth = -lReqPixelWidth;
  772. }
  773. // win 31 does not allow tt fonts of zero width. This makes sense,
  774. // as we know rasterizer chokes on these.
  775. // Win31 does not allow fonts that are very wide either.
  776. // The code below is exactly what win31 is doing. Win31 has a bogus
  777. // criterion for determining a cut off for width.
  778. // Below this cut off, because of the bug in win31 code,
  779. // the text goes from right to left.
  780. // For even smaller lfWidth
  781. // we get the expected "good" behavior. NT eliminates the Win31 bug
  782. // where for range of lfWidhts width scaling factor is negative.
  783. if
  784. (
  785. (
  786. efAveChPixelWidth.bEfToL(lAvChPixelW) &&
  787. (lAvChPixelW > 0) && // not too narrow !
  788. bOk &&
  789. ((lReqPixelWidth / 256) < lAvChPixelW) // bogus win31 criterion
  790. )
  791. ||
  792. ifio.bStroke() // vector fonts can be arbitrarily wide or narrow
  793. )
  794. {
  795. bMustCheckResolution = FALSE;
  796. efWidthScale.eqDiv(efReqPixelWidth,efWidthDen);
  797. }
  798. /*
  799. else
  800. {
  801. // win31 in either of these cases branches into MSFBadWidth case
  802. // which is equivalent to setting lfWidth == 0 [bodind]
  803. }
  804. */
  805. }
  806. if (bMustCheckResolution)
  807. {
  808. // must compute width scale because it has not been
  809. // computed in lfWidth != 0 case
  810. if (ifio.bStroke())
  811. {
  812. // win31 behaves differently for vector fonts:
  813. // unlike tt fonts, vector fonts stretch along x, respecting
  814. // page to device xform. However, they ignore the request to flip
  815. // either x or y axis
  816. efWidthScale = efDefaultScale;
  817. if (!bPD11Is1)
  818. {
  819. efWidthScale.eqMul(efWidthScale,efPD11);
  820. efWidthScale.vAbs();
  821. }
  822. }
  823. else
  824. {
  825. // tt fonts make x scaling the same as y scaling,
  826. efWidthScale = efHeightScale;
  827. }
  828. POINTL ptlRes = *ifio.pptlAspect();
  829. // If VertRez != HorRez and we are using the default width we need to
  830. // adjust for the differences in resolution.
  831. // This is done in order to ensure that fonts look the same on printers
  832. // of different resolutions [bodind]
  833. if ((pdo.ulLogPixelsX() != pdo.ulLogPixelsY()) && !bUseMeta)
  834. {
  835. ptlRes.y *= (LONG)pdo.ulLogPixelsX();
  836. ptlRes.x *= (LONG)pdo.ulLogPixelsY();
  837. }
  838. if (ptlRes.x != ptlRes.y)
  839. {
  840. EFLOAT efTmp;
  841. efTmp = ptlRes.y;
  842. efWidthScale *= efTmp ;
  843. efTmp = ptlRes.x;
  844. efWidthScale /= efTmp;
  845. }
  846. }
  847. // now that we have width scale we can compute pmxNW->efM11. We factor out
  848. // (PtoD)11 out of width scale to obtain the effective NW x scale:
  849. if (!bPD11Is1)
  850. pmxNW->efM11.eqDiv(efWidthScale,efPD11);
  851. else
  852. pmxNW->efM11 = efWidthScale;
  853. pmxNW->efDx.vSetToZero();
  854. pmxNW->efDy.vSetToZero();
  855. pmxNW->efM12.vSetToZero();
  856. pmxNW->efM21.vSetToZero();
  857. EXFORMOBJ xoNW(pmxNW, DONT_COMPUTE_FLAGS);
  858. // see if orientation angle has to be taken into account:
  859. if (ifio.bStroke())
  860. {
  861. // allow esc != orientation for vector fonts because win31 does it
  862. // also note that for vector fonts Orientation is treated as world space
  863. // concept, so we multiply here before applying world to device transform
  864. // while for tt fonts esc is treated as device space concept so that
  865. // this multiplication is occuring after world to page transform is applied
  866. if (pelfw->lfOrientation)
  867. {
  868. EFLOATEXT efAngle = pelfw->lfOrientation;
  869. efAngle /= (LONG) 10;
  870. MATRIX mxRot, mxTmp;
  871. mxRot.efM11 = efCos(efAngle);
  872. mxRot.efM22 = mxRot.efM11;
  873. mxRot.efM12 = efSin(efAngle);
  874. mxRot.efM21 = mxRot.efM12;
  875. mxRot.efM21.vNegate();
  876. mxRot.efDx.vSetToZero();
  877. mxRot.efDy.vSetToZero();
  878. mxTmp = *pmxNW;
  879. if (!xoNW.bMultiply(&mxTmp,&mxRot))
  880. return FALSE;
  881. }
  882. }
  883. // take into account different orientation of y axes of notional
  884. // and world spaces:
  885. pmxNW->efM12.vNegate();
  886. pmxNW->efM22.vNegate();
  887. xoNW.vComputeAccelFlags();
  888. return(TRUE);
  889. }
  890. /******************************Public*Routine******************************\
  891. *
  892. * BOOL bParityViolatingXform(DCOBJ *pdco)
  893. *
  894. * History:
  895. * 04-Jun-1993 -by- Bodin Dresevic [BodinD]
  896. * Wrote it.
  897. \**************************************************************************/
  898. BOOL bParityViolatingXform(DCOBJ *pdco)
  899. {
  900. if (pdco->pdc->bWorldToPageIdentity())
  901. {
  902. if (pdco->pdc->bPageToDeviceScaleIdentity())
  903. {
  904. // identity except maybe for translations
  905. return FALSE;
  906. }
  907. return (pdco->pdc->efM11().lSignum() != pdco->pdc->efM22().lSignum());
  908. }
  909. else
  910. {
  911. // we are in the metafile code
  912. return( pdco->pdc->efMetaPtoD11().lSignum() != pdco->pdc->efMetaPtoD22().lSignum() );
  913. }
  914. }
  915. /******************************Public*Routine******************************\
  916. *
  917. * bGetNtoD_Win31
  918. *
  919. * Called by:
  920. * PFEOBJ::bSetFontXform [PFEOBJ.CXX]
  921. *
  922. * History:
  923. * Tue 12-Jan-1993 11:58:41 by Kirk Olynyk [kirko]
  924. * Added a quick code path for non-transformable (bitmap) fonts.
  925. * 30-Sep-1992 -by- Bodin Dresevic [BodinD]
  926. * Wrote it.
  927. \**************************************************************************/
  928. BOOL
  929. bGetNtoD_Win31(
  930. FD_XFORM *pfdx, // pointer to the buffer to recieve the
  931. // notional to device transformation for the
  932. // font driver. There are a couple of
  933. // important things to remember. First,
  934. // according to the conventions of the ISO
  935. // committee, the coordinate space for notional
  936. // (font designer) spaces are cartesian.
  937. // However, due to a series of errors on my part
  938. // [kirko] the convention that is used by the
  939. // DDI is that the notional to device transformation
  940. // passed over the DDI assumes that both the notional
  941. // and the device space are anti-Cartesian, that is,
  942. // positive y increases in the downward direction.
  943. // The fontdriver assumes that
  944. // one unit in device space corresponds to the
  945. // distance between pixels. This is different from
  946. // GDI's internal view, where one device unit
  947. // corresponds to a sub-pixel unit.
  948. LOGFONTW *pelfw, // points to the extended logical font defining
  949. // the font that is requested by the application.
  950. // Units are ususally in World coordinates.
  951. IFIOBJ& ifio, // font to be used
  952. DCOBJ *pdco, // the device context defines the transforms between
  953. // the various coordinate spaces.
  954. FLONG fl, // The flags supported are:
  955. //
  956. // ND_IGNORE_ESC_AND_ORIENT
  957. //
  958. // The presence of this flag indicates that
  959. // the escapement and orientation values
  960. // of the LOGFONT should be ignored. This
  961. // is used for GetGlyphOutline which ignores
  962. // these values on Win 3.1. Corel Draw 5.0
  963. // relies on this behavior to print rotated
  964. // text.
  965. //
  966. POINTL * const pptlSim,
  967. BOOL bIsLinkedFont // is passed in as TRUE if the font is linked, FALSE otherwise
  968. )
  969. {
  970. MATRIX mxNW, mxND;
  971. ASSERTGDI(
  972. (fl & ~(ND_IGNORE_ESC_AND_ORIENT | ND_IGNORE_MAP_MODE))== 0,
  973. "gdisrv!bGetNtoD_Win31 -- bad value for fl\n"
  974. );
  975. if((pptlSim->x) && !ifio.bContinuousScaling())
  976. {
  977. //
  978. // This code path is for bitmap / non-scalable fonts. The notional
  979. // to device transformation is determined by simply looking up
  980. // the scaling factors for both the x-direction and y-direcion
  981. //
  982. #if DBG
  983. if (!(0 < pptlSim->x && pptlSim->x <= sizeof(galFloat)/sizeof(LONG)))
  984. {
  985. DbgPrint("\t*pptlSim = (%d,%d)\n",pptlSim->x,pptlSim->y);
  986. RIP("gre -- bad *pptlSim\n");
  987. }
  988. #endif
  989. // Win3.1J ignore orientation anytime. But use escapement for rotate Glyph data.
  990. // If the font driver that this font provide , has not arbitality flag.
  991. // Angle should be 0 , 900 , 1800 or 2700
  992. // for Win31J compatibility
  993. ULONG uAngle = 0;
  994. if (gbDBCSCodePage)
  995. {
  996. if( ifio.b90DegreeRotations() )
  997. {
  998. if (pdco->pdc->bYisUp())
  999. uAngle = (ULONG)(((3600-lNormAngle(pelfw->lfEscapement)) /
  1000. ORIENTATION_90_DEG) % 4);
  1001. else
  1002. uAngle = (ULONG)( lNormAngle(pelfw->lfEscapement) /
  1003. ORIENTATION_90_DEG );
  1004. }
  1005. }
  1006. switch( uAngle )
  1007. {
  1008. case 0: // 0 Degrees
  1009. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[pptlSim->x]);
  1010. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[0 ]);
  1011. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[0 ]);
  1012. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloatNeg[pptlSim->y]);
  1013. break;
  1014. case 1: // 90 Degrees
  1015. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloatNeg[pptlSim->x]);
  1016. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[0 ]);
  1017. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[0 ]);
  1018. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloatNeg[pptlSim->y]);
  1019. break;
  1020. case 2: // 180 Degrees
  1021. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloatNeg[pptlSim->x]);
  1022. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[0 ]);
  1023. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[0 ]);
  1024. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[pptlSim->y]);
  1025. break;
  1026. case 3: // 270 Degress
  1027. SET_FLOAT_WITH_LONG(pfdx->eXY,galFloat[pptlSim->y]);
  1028. SET_FLOAT_WITH_LONG(pfdx->eXX,galFloat[0 ]);
  1029. SET_FLOAT_WITH_LONG(pfdx->eYY,galFloat[0 ]);
  1030. SET_FLOAT_WITH_LONG(pfdx->eYX,galFloat[pptlSim->x]);
  1031. break;
  1032. default:
  1033. WARNING("bGetNtoD_Win31():Invalid Angle\n");
  1034. break;
  1035. }
  1036. return(TRUE);
  1037. }
  1038. if (!bGetNtoW_Win31(&mxNW, pelfw, ifio, pdco, fl, bIsLinkedFont))
  1039. return FALSE;
  1040. EXFORMOBJ xoND(&mxND, DONT_COMPUTE_FLAGS);
  1041. if( (pdco->pdc->bWorldToDeviceIdentity() == FALSE) &&
  1042. !(fl & ND_IGNORE_MAP_MODE) )
  1043. {
  1044. if (!xoND.bMultiply(&mxNW,&pdco->pdc->mxWorldToDevice()))
  1045. {
  1046. return(FALSE);
  1047. }
  1048. //
  1049. // Compensate for the fact that for the font driver, one
  1050. // device unit corresponds to the distance between pixels,
  1051. // whereas for the engine, one device unit corresponds to
  1052. // 1/16'th the way between pixels
  1053. //
  1054. mxND.efM11.vDivBy16();
  1055. mxND.efM12.vDivBy16();
  1056. mxND.efM21.vDivBy16();
  1057. mxND.efM22.vDivBy16();
  1058. }
  1059. else
  1060. {
  1061. mxND = mxNW;
  1062. }
  1063. if (!ifio.bStroke())
  1064. {
  1065. // for tt fonts escapement and orientation are treated as
  1066. // device space concepts. That is why for these fonts we apply
  1067. // rotation by lAngle last
  1068. LONG lAngle;
  1069. if( ifio.b90DegreeRotations() )
  1070. {
  1071. lAngle = (LONG)( ( lNormAngle(pelfw->lfEscapement)
  1072. / ORIENTATION_90_DEG ) % 4 ) * ORIENTATION_90_DEG;
  1073. }
  1074. else // ifio.bArbXform() is TRUE
  1075. {
  1076. lAngle = pelfw->lfEscapement;
  1077. }
  1078. if(lAngle != 0 && (!(fl & ND_IGNORE_ESC_AND_ORIENT) || gbDBCSCodePage))
  1079. {
  1080. // more of win31 compatability: the line below would make sense
  1081. // if this was y -> -y type of xform. But they also do it
  1082. // for x -> -x xform. [bodind]
  1083. if (bParityViolatingXform(pdco))
  1084. {
  1085. lAngle = -lAngle;
  1086. }
  1087. EFLOATEXT efAngle = lAngle;
  1088. efAngle /= (LONG) 10;
  1089. MATRIX mxRot, mxTmp;
  1090. mxRot.efM11 = efCos(efAngle);
  1091. mxRot.efM22 = mxRot.efM11;
  1092. mxRot.efM12 = efSin(efAngle);
  1093. mxRot.efM21 = mxRot.efM12;
  1094. mxRot.efM12.vNegate();
  1095. mxRot.efDx.vSetToZero();
  1096. mxRot.efDy.vSetToZero();
  1097. mxTmp = mxND;
  1098. if (!xoND.bMultiply(&mxTmp,&mxRot))
  1099. return FALSE;
  1100. }
  1101. // adjust for nonsquare resolution
  1102. PDEVOBJ pdo(pdco->hdev());
  1103. if (pdo.ulLogPixelsX() != pdo.ulLogPixelsY())
  1104. {
  1105. EFLOATEXT efTmp = (LONG)pdo.ulLogPixelsX();
  1106. efTmp /= (LONG)pdo.ulLogPixelsY();
  1107. MATRIX mxW2D = pdco->pdc->mxWorldToDevice();
  1108. if(mxW2D.efM12.bIsZero() && mxW2D.efM21.bIsZero()){// for 1,4 -up printing
  1109. mxND.efM12 /= efTmp;
  1110. mxND.efM21 *= efTmp;
  1111. }
  1112. else{ // for 2, 6-up printing, i.e. 270 rotation
  1113. mxND.efM11 *= efTmp;
  1114. mxND.efM22 /= efTmp;
  1115. }
  1116. }
  1117. }
  1118. SET_FLOAT_WITH_LONG(pfdx->eXX,mxND.efM11.lEfToF());
  1119. SET_FLOAT_WITH_LONG(pfdx->eXY,mxND.efM12.lEfToF());
  1120. SET_FLOAT_WITH_LONG(pfdx->eYX,mxND.efM21.lEfToF());
  1121. SET_FLOAT_WITH_LONG(pfdx->eYY,mxND.efM22.lEfToF());
  1122. return(TRUE);
  1123. }