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.

2290 lines
61 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: xformgdi.cxx
  3. *
  4. * Contains all the mapping and coordinate functions.
  5. *
  6. * Created: 09-Nov-1990 16:49:36
  7. * Author: Wendy Wu [wendywu]
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. #define UNITS_PER_MILLIMETER_LOMETRIC 10 // .1 mm/unit
  13. #define UNITS_PER_MILLIMETER_HIMETRIC 100 // .01 mm/unit
  14. #define UNITS_PER_METER_LOENGLISH 3937 // (100 units/in) / (0.0254 m/in)
  15. #define UNITS_PER_METER_HIENGLISH 39370 // (1000 units/in) / (0.0254 mm/in)
  16. #define UNITS_PER_METER_TWIPS 56693 // (1440 units/in) / (0.0254 mm/in)
  17. #if DBG
  18. int giXformLevel = 0;
  19. #endif
  20. extern "C" BOOL
  21. ProbeAndConvertXFORM(
  22. XFORML *kpXform,
  23. XFORML *pXform
  24. );
  25. /******************************Public*Routine******************************\
  26. * GreGetMapMode(hdc)
  27. *
  28. * Get the mapping mode of the specified dc.
  29. *
  30. * History:
  31. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  32. * Wrote it.
  33. \**************************************************************************/
  34. int APIENTRY GreGetMapMode(
  35. HDC hdc)
  36. {
  37. DWORD dw = 0;
  38. XDCOBJ dco( hdc );
  39. if(dco.bValid())
  40. {
  41. dw = dco.ulMapMode();
  42. dco.vUnlockFast();
  43. }
  44. else
  45. {
  46. WARNING("Invalid DC passed to GreGetMapMode\n");
  47. }
  48. return(dw);
  49. }
  50. /******************************Public*Routine******************************\
  51. * GreGetViewportExt(hdc,pSize)
  52. *
  53. * Get the viewport extents of the specified dc.
  54. *
  55. * History:
  56. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  57. * Wrote it.
  58. \**************************************************************************/
  59. BOOL APIENTRY GreGetViewportExt(
  60. HDC hdc,
  61. PSIZE pSize)
  62. {
  63. return(GreGetDCPoint(hdc,DCPT_VPEXT,(PPOINTL)pSize));
  64. }
  65. /******************************Public*Routine******************************\
  66. * GreGetViewportOrg(hdc,pPoint)
  67. *
  68. * Get the viewport origin of the specified dc.
  69. *
  70. * History:
  71. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  72. * Wrote it.
  73. \**************************************************************************/
  74. BOOL APIENTRY GreGetViewportOrg(
  75. HDC hdc,
  76. LPPOINT pPoint)
  77. {
  78. return(GreGetDCPoint(hdc,DCPT_VPORG,(PPOINTL)pPoint));
  79. }
  80. /******************************Public*Routine******************************\
  81. * GreGetWindowExt(hdc,pSize)
  82. *
  83. * Get the window extents of the specified dc.
  84. *
  85. * History:
  86. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  87. * Wrote it.
  88. \**************************************************************************/
  89. BOOL APIENTRY GreGetWindowExt(
  90. HDC hdc,
  91. PSIZE pSize)
  92. {
  93. return(GreGetDCPoint(hdc,DCPT_WNDEXT,(PPOINTL)pSize));
  94. }
  95. /******************************Public*Routine******************************\
  96. * GreGetWindowOrg(hdc,pPoint)
  97. *
  98. * Get the window origin of the specified dc.
  99. *
  100. * History:
  101. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  102. * Wrote it.
  103. \**************************************************************************/
  104. BOOL APIENTRY GreGetWindowOrg(
  105. HDC hdc,
  106. LPPOINT pPoint)
  107. {
  108. return(GreGetDCPoint(hdc,DCPT_WNDORG,(PPOINTL)pPoint));
  109. }
  110. /******************************Public*Routine******************************\
  111. * GreSetViewportOrg(hdc,x,y,pPoint)
  112. *
  113. * Set the viewport origin of the specified dc.
  114. *
  115. * 15-Sep-1992 -by- Gerrit van Wingerden [gerritv]
  116. * Modified since xforms have moved to client side and this routine is
  117. * now only called by usersrv.
  118. *
  119. * History:
  120. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  121. * Wrote it.
  122. \**************************************************************************/
  123. BOOL APIENTRY GreSetViewportOrg(
  124. HDC hdc,
  125. int x,
  126. int y,
  127. LPPOINT pPoint)
  128. {
  129. DCOBJ dcox(hdc); // lock the dc object
  130. if (!dcox.bValid()) // check if lock is valid
  131. return(FALSE);
  132. if (MIRRORED_DC(dcox.pdc))
  133. x = -x;
  134. if (BLTOFXOK(x) && BLTOFXOK(y))
  135. {
  136. if (!dcox.pdc->bValidPtlCurrent())
  137. {
  138. ASSERTGDI(dcox.pdc->bValidPtfxCurrent(), "Both CPs invalid?");
  139. EXFORMOBJ exoDtoW(dcox, DEVICE_TO_WORLD);
  140. if (exoDtoW.bValid())
  141. exoDtoW.bXform(&dcox.ptfxCurrent(), &dcox.ptlCurrent(), 1);
  142. dcox.pdc->vValidatePtlCurrent();
  143. }
  144. // After the transform, the device space CP will be invalid:
  145. dcox.pdc->vInvalidatePtfxCurrent();
  146. // x, y of viewport origin can fit into 28 bits.
  147. // If we get here it means we've been called by USER and Viewport
  148. // and Window extents should be (1,1) and Window Orgs should be zero,
  149. // and the world transform shouldn't be set either.
  150. DONTUSE(pPoint); // pPoint is now ignored
  151. EXFORMOBJ xoWtoD(dcox, WORLD_TO_DEVICE);
  152. EFLOATEXT efDx((LONG) x);
  153. EFLOATEXT efDy((LONG) y);
  154. efDx.vTimes16();
  155. efDy.vTimes16();
  156. ASSERTGDI(xoWtoD.efM11().bIs16() ||
  157. (MIRRORED_DC(dcox.pdc) && xoWtoD.efM11().bIsNeg16()),
  158. "efM11 not 16 in GreSetViewportOrg or -16 in Mirroring Mode" );
  159. ASSERTGDI( xoWtoD.efM22().bIs16(),
  160. "efM22 not 16 in GreSetViewportOrg" );
  161. dcox.pdc->flSet_flXform( DEVICE_TO_WORLD_INVALID | PAGE_XLATE_CHANGED);
  162. //xoWtoD.vSetTranslations( efDx, efDy );
  163. dcox.pdc->lViewportOrgX(x);
  164. dcox.pdc->lViewportOrgY(y);
  165. xoWtoD.vInit(dcox, DEVICE_TO_WORLD);
  166. return(TRUE);
  167. }
  168. else
  169. return(FALSE);
  170. }
  171. /******************************Public*Routine******************************\
  172. * GreSetWindowOrg(hdc,x,y,pPoint)
  173. *
  174. * Set the window origin of the specified dc.
  175. *
  176. * History:
  177. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  178. * Wrote it.
  179. \**************************************************************************/
  180. BOOL APIENTRY GreSetWindowOrg(
  181. HDC hdc,
  182. int x,
  183. int y,
  184. LPPOINT pPoint)
  185. {
  186. DCOBJ dcox(hdc); // lock the dc object
  187. if (!dcox.bValid()) // check if lock is valid
  188. return(FALSE);
  189. // If we get here it means we've been called by USER and Viewport
  190. // and Window extents should be (1,1) and Viewport Orgs should be zero,
  191. // and the world transform shouldn't be set either.
  192. DONTUSE(pPoint); // pPoint is now ignored
  193. EXFORMOBJ xoWtoD(dcox, WORLD_TO_DEVICE);
  194. EFLOATEXT efDx((LONG) -x);
  195. EFLOATEXT efDy((LONG) -y);
  196. efDx.vTimes16();
  197. efDy.vTimes16();
  198. ASSERTGDI( xoWtoD.efM11().bIs16() ||
  199. (MIRRORED_DC(dcox.pdc) && xoWtoD.efM11().bIsNeg16()),
  200. "efM11 not 16 in GreSetViewportOrg" );
  201. ASSERTGDI( xoWtoD.efM22().bIs16(),
  202. "efM22 not 16 in GreSetViewportOrg" );
  203. if (!dcox.pdc->bValidPtlCurrent())
  204. {
  205. ASSERTGDI(dcox.pdc->bValidPtfxCurrent(), "Both CPs invalid?");
  206. EXFORMOBJ exoDtoW(dcox, DEVICE_TO_WORLD);
  207. if (exoDtoW.bValid())
  208. exoDtoW.bXform(&dcox.ptfxCurrent(), &dcox.ptlCurrent(), 1);
  209. dcox.pdc->vValidatePtlCurrent();
  210. }
  211. // After the transform, the device space CP will be invalid:
  212. dcox.pdc->vInvalidatePtfxCurrent();
  213. dcox.pdc->flSet_flXform( DEVICE_TO_WORLD_INVALID | PAGE_XLATE_CHANGED);
  214. //xoWtoD.vSetTranslations( efDx, efDy );
  215. //
  216. // save in DC for USER. Caution: these valuse must be restored before app
  217. // uses DC again
  218. //
  219. dcox.pdc->lWindowOrgX(x);
  220. dcox.pdc->lWindowOrgY(y);
  221. dcox.pdc->SetWindowOrgAndMirror(x);
  222. xoWtoD.vInit(dcox, DEVICE_TO_WORLD);
  223. return( TRUE );
  224. }
  225. /******************************Public*Routine******************************\
  226. * NtGdiConvertMetafileRect:
  227. *
  228. * Transform a RECT from inclusive-exclusive to inclusive-inclusive for
  229. * a rectangle recorded in a metafile.
  230. *
  231. * Arguments:
  232. *
  233. * hdc - current device context
  234. * rect - rtectangle to convert
  235. *
  236. * Return Value:
  237. *
  238. * MRI_OK,MRI_NULLBOX,MRI_ERROR
  239. *
  240. * History:
  241. *
  242. * 9-Apr-1996 -by- Mark Enstrom [marke]
  243. *
  244. \**************************************************************************/
  245. LONG APIENTRY
  246. NtGdiConvertMetafileRect(
  247. HDC hdc,
  248. PRECTL prect
  249. )
  250. {
  251. LONG lResult = MRI_ERROR;
  252. RECTL rclMeta;
  253. //
  254. // copy in rect structure
  255. //
  256. __try
  257. {
  258. rclMeta = ProbeAndReadStructure(prect,RECTL);
  259. lResult = MRI_OK;
  260. }
  261. __except(EXCEPTION_EXECUTE_HANDLER)
  262. {
  263. WARNINGX(22);
  264. }
  265. if (lResult == MRI_OK)
  266. {
  267. //
  268. // attempt to lock DC
  269. //
  270. DCOBJ dco(hdc);
  271. if (dco.bValid())
  272. {
  273. ERECTFX rectFX;
  274. BOOL bResult;
  275. //
  276. // DC must be in compatible mode
  277. //
  278. ASSERTGDI(dco.pdc->iGraphicsMode() == GM_COMPATIBLE,
  279. "NtGdiConvertMetafileRect: Map Mode is not GM_COMPATIBLE");
  280. //
  281. // transform rectangle points to device FX
  282. //
  283. {
  284. EXFORMOBJ xo(dco,XFORM_WORLD_TO_DEVICE);
  285. bResult = xo.bXform((PPOINTL)&rclMeta,(PPOINTFIX)&rectFX,2);
  286. }
  287. if (bResult)
  288. {
  289. //
  290. // order device point rectangle
  291. //
  292. rectFX.vOrder();
  293. //
  294. // adjust lower and right points for exclusive to inclusive
  295. //
  296. rectFX.xRight -= 16;
  297. rectFX.yBottom -= 16;
  298. //
  299. // check for empty rectFX
  300. //
  301. if ((rectFX.xRight < rectFX.xLeft) ||
  302. (rectFX.yBottom < rectFX.yTop))
  303. {
  304. lResult = MRI_NULLBOX;
  305. }
  306. //
  307. // convert back to logical space
  308. //
  309. EXFORMOBJ xoDev(dco,XFORM_DEVICE_TO_WORLD);
  310. bResult = xoDev.bXform((PPOINTFIX)&rectFX,(PPOINTL)&rclMeta,2);
  311. //
  312. // Write results to caller's buffer
  313. //
  314. if (bResult)
  315. {
  316. __try
  317. {
  318. ProbeAndWriteStructure(prect,rclMeta,RECT);
  319. }
  320. __except(EXCEPTION_EXECUTE_HANDLER)
  321. {
  322. WARNINGX(8);
  323. lResult = MRI_ERROR;
  324. }
  325. }
  326. else
  327. {
  328. lResult = MRI_ERROR;
  329. }
  330. }
  331. else
  332. {
  333. lResult = MRI_ERROR;
  334. }
  335. }
  336. else
  337. {
  338. lResult = MRI_ERROR;
  339. }
  340. }
  341. if (lResult == MRI_ERROR)
  342. {
  343. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  344. }
  345. return(lResult);
  346. }
  347. /******************************Public*Routine******************************\
  348. *
  349. *
  350. * History:
  351. * 02-Dec-1994 -by- Eric Kutter [erick]
  352. * Wrote it.
  353. \**************************************************************************/
  354. BOOL APIENTRY GreTransformPoints(
  355. HDC hdc,
  356. PPOINT pptIn,
  357. PPOINT pptOut,
  358. int c,
  359. int iMode
  360. )
  361. {
  362. XFORMPRINT(1,"GreTransformPoints, iMode = %ld\n",iMode);
  363. BOOL bResult = FALSE;
  364. DCOBJ dco(hdc); // lock the dc object
  365. if (dco.bValid()) // check if lock is valid
  366. {
  367. if (c <= 0) // check if there are points to convert
  368. {
  369. bResult = TRUE;
  370. }
  371. else
  372. {
  373. EXFORMOBJ xo(dco, (iMode == XFP_DPTOLP) ? XFORM_DEVICE_TO_WORLD : XFORM_WORLD_TO_DEVICE);
  374. if (xo.bValid())
  375. {
  376. switch (iMode)
  377. {
  378. case XFP_DPTOLP:
  379. case XFP_LPTODP:
  380. bResult = xo.bXform((PPOINTL)pptIn, (PPOINTL)pptOut, c);
  381. break;
  382. case XFP_LPTODPFX:
  383. bResult = xo.bXform((PPOINTL)pptIn, (PPOINTFIX)pptOut, c);
  384. break;
  385. default:
  386. WARNING("Invalid mode passed to GreTranformPoints\n");
  387. break;
  388. }
  389. }
  390. }
  391. }
  392. return(bResult);
  393. }
  394. /******************************Public*Routine******************************\
  395. * GreDPtoLP(hdc,ppt,nCount)
  396. *
  397. * Convert the given device points into logical points.
  398. *
  399. * History:
  400. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  401. * Wrote it.
  402. \**************************************************************************/
  403. BOOL APIENTRY GreDPtoLP(
  404. HDC hdc,
  405. LPPOINT ppt,
  406. int nCount)
  407. {
  408. return(GreTransformPoints(hdc,ppt,ppt,nCount,XFP_DPTOLP));
  409. }
  410. /******************************Public*Routine******************************\
  411. * GreLPtoDP(hdc,ppt,nCount)
  412. *
  413. * Convert the given logical points into device points.
  414. *
  415. * History:
  416. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  417. * Wrote it.
  418. \**************************************************************************/
  419. BOOL APIENTRY GreLPtoDP(
  420. HDC hdc,
  421. LPPOINT ppt,
  422. int nCount)
  423. {
  424. return(GreTransformPoints(hdc,ppt,ppt,nCount,XFP_LPTODP));
  425. }
  426. /******************************Private*Routine*****************************\
  427. * bWorldMatrixInRange(pmx)
  428. *
  429. * See if the coefficients of the world transform matrix are within
  430. * our minimum and maximum range.
  431. *
  432. * History:
  433. * 27-Nov-1990 -by- Wendy Wu [wendywu]
  434. * Wrote it.
  435. \**************************************************************************/
  436. BOOL bWorldMatrixInRange(PMATRIX pmx)
  437. {
  438. BOOL bRet;
  439. #if defined(_AMD64_) || defined(_IA64_) || defined(BUILD_WOW6432)
  440. /*
  441. EFLOAT ef = pmx->efM11;
  442. ef.vAbs();
  443. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  444. return(FALSE);
  445. ef = pmx->efM12;
  446. ef.vAbs();
  447. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  448. return(FALSE);
  449. ef = pmx->efM21;
  450. ef.vAbs();
  451. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  452. return(FALSE);
  453. ef = pmx->efM22;
  454. ef.vAbs();
  455. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  456. return(FALSE);
  457. ef = pmx->efDx;
  458. ef.vAbs();
  459. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  460. return(FALSE);
  461. ef = pmx->efDy;
  462. ef.vAbs();
  463. if ((ef < (FLOAT)MIN_WORLD_XFORM) || (ef > (FLOAT)MIN_WORLD_XFORM))
  464. return(FALSE);
  465. */
  466. bRet = TRUE;
  467. #else
  468. bRet =
  469. ((pmx->efM11.bExpLessThan(MAX_WORLD_XFORM_EXP)) &&
  470. (pmx->efM12.bExpLessThan(MAX_WORLD_XFORM_EXP)) &&
  471. (pmx->efM21.bExpLessThan(MAX_WORLD_XFORM_EXP)) &&
  472. (pmx->efM22.bExpLessThan(MAX_WORLD_XFORM_EXP)) &&
  473. (pmx->efDx.bExpLessThan(MAX_WORLD_XFORM_EXP)) &&
  474. (pmx->efDy.bExpLessThan(MAX_WORLD_XFORM_EXP)))
  475. ;
  476. #endif
  477. if (bRet)
  478. {
  479. // at this point bRet == TRUE. We have to figure out the cases
  480. // when the determinant is zero and set bRet to FALSE;
  481. // We do what we can to avoid multiplications in common cases
  482. // when figuring out if this is a singular trasform
  483. if (pmx->efM12.bIsZero() && pmx->efM21.bIsZero())
  484. {
  485. if (pmx->efM11.bIsZero() || pmx->efM22.bIsZero())
  486. bRet = FALSE;
  487. }
  488. else if (pmx->efM11.bIsZero() && pmx->efM22.bIsZero())
  489. {
  490. if (pmx->efM12.bIsZero() || pmx->efM21.bIsZero())
  491. bRet = FALSE;
  492. }
  493. else // general case, have to do multiplications
  494. {
  495. EFLOAT ef = pmx->efM11;
  496. ef *= pmx->efM22;
  497. EFLOAT ef1 = pmx->efM12;
  498. ef1 *= pmx->efM21;
  499. ef -= ef1; // determinant.
  500. if (ef.bIsZero())
  501. {
  502. bRet = FALSE;
  503. }
  504. }
  505. }
  506. return bRet;
  507. }
  508. /******************************Public*Routine******************************\
  509. * GreGetDeviceWidth(hdc)
  510. *
  511. * Get the device surface width of the specified dc.
  512. *
  513. * History:
  514. * 26-Jan-1998 -by- Mohamed Hassanin [mhamid]
  515. * Wrote it.
  516. \**************************************************************************/
  517. LONG APIENTRY
  518. GreGetDeviceWidth(HDC hdc)
  519. {
  520. DCOBJ dco(hdc);
  521. if (dco.bValid() != FALSE)
  522. {
  523. return (dco.pdc->GetDeviceWidth());
  524. }
  525. else
  526. {
  527. WARNING("Invalid DC passed to GreGetDeviceWidth\n");
  528. }
  529. return (GDI_ERROR);
  530. }
  531. /******************************Public*Routine******************************\
  532. * GreMirrorWindowOrg(hdc)
  533. *
  534. * Mirror the Window X Org. By calling MirrorWindowOrg
  535. *
  536. * History:
  537. * 26-Jan-1998 -by- Mohamed Hassanin [mhamid]
  538. * Wrote it.
  539. \**************************************************************************/
  540. BOOL APIENTRY
  541. GreMirrorWindowOrg(HDC hdc)
  542. {
  543. DCOBJ dco(hdc);
  544. if (dco.bValid() != FALSE)
  545. {
  546. dco.pdc->MirrorWindowOrg();
  547. return (TRUE);
  548. }
  549. return (FALSE);
  550. }
  551. /******************************Public*Routine******************************\
  552. * GreGetLayout
  553. *
  554. *
  555. * History:
  556. * Fri 12-Sep-1991 11:29 -by- Mohamed Hassanin [MHamid]
  557. * Wrote it.
  558. \**************************************************************************/
  559. DWORD APIENTRY
  560. GreGetLayout(HDC hdc)
  561. {
  562. DWORD dwRet = GDI_ERROR;
  563. DCOBJ dco(hdc);
  564. if (dco.bValid() != FALSE)
  565. {
  566. dwRet = dco.pdc->dwLayout();
  567. }
  568. return(dwRet);
  569. }
  570. /******************************Public*Routine******************************\
  571. * GreSetLayout
  572. *
  573. *
  574. * History:
  575. * Fri 12-Sep-1991 11:29 -by- Mohamed Hassanin [MHamid]
  576. * Wrote it.
  577. \**************************************************************************/
  578. DWORD APIENTRY
  579. GreSetLayout
  580. ( HDC hdc,
  581. LONG wox,
  582. DWORD dwLayout)
  583. {
  584. DCOBJ dco( hdc );
  585. if( !dco.bValid() )
  586. {
  587. WARNING("Xform update invalid hdc\n");
  588. return(GDI_ERROR);
  589. }
  590. return dco.pdc->dwSetLayout(wox, dwLayout);
  591. }
  592. /******************************Public*Routine******************************\
  593. * GreXformUpdate
  594. *
  595. * Updates the server's copy of the WtoD transform, transform related flags,
  596. * and viewport and window extents.
  597. *
  598. * History:
  599. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  600. * Wrote it.
  601. \**************************************************************************/
  602. BOOL GreXformUpdate
  603. ( HDC hdc,
  604. FLONG flXform,
  605. LONG wex,
  606. LONG wey,
  607. LONG vex,
  608. LONG vey,
  609. LONG mapMode,
  610. PVOID pvMatrix
  611. )
  612. {
  613. DCOBJ dco( hdc );
  614. if( !dco.bValid() )
  615. {
  616. WARNING("Xform update invalid hdc\n");
  617. return(FALSE);
  618. }
  619. // Copy window and viewport extents
  620. dco.pdc->vSet_szlWindowExt( wex, wey );
  621. dco.pdc->vSet_szlViewportExt( vex, vey );
  622. dco.pdc->ulMapMode( mapMode );
  623. // Save current position
  624. ASSERTGDI(dco.bValid(), "DC not valid");
  625. if (!dco.pdc->bValidPtlCurrent())
  626. {
  627. ASSERTGDI(dco.pdc->bValidPtfxCurrent(), "Both CPs invalid?");
  628. EXFORMOBJ exoDtoW(dco, DEVICE_TO_WORLD);
  629. if (exoDtoW.bValid())
  630. exoDtoW.bXform(&dco.ptfxCurrent(), &dco.ptlCurrent(), 1);
  631. dco.pdc->vValidatePtlCurrent();
  632. }
  633. // Set the flags
  634. dco.pdc->flResetflXform( flXform );
  635. dco.pdc->flSet_flXform( DEVICE_TO_WORLD_INVALID );
  636. // Set the new world transform
  637. RtlCopyMemory( (PVOID) &dco.pdc->mxWorldToDevice(), pvMatrix, sizeof( MATRIX ));
  638. RtlCopyMemory( (PVOID) &dco.pdc->mxUserWorldToDevice(), pvMatrix, sizeof( MATRIX ));
  639. // After the transform, the device space CP will be invalid:
  640. dco.pdc->vInvalidatePtfxCurrent();
  641. if( flXform & INVALIDATE_ATTRIBUTES )
  642. {
  643. EXFORMOBJ exo(dco, WORLD_TO_DEVICE);
  644. dco.pdc->vRealizeLineAttrs(exo);
  645. dco.pdc->vXformChange(TRUE);
  646. }
  647. return (TRUE);
  648. }
  649. /******************************Member*Function*****************************\
  650. * vConvertXformToMatrix
  651. *
  652. * Convert a xform structure into a matrix struct.
  653. *
  654. * History:
  655. * 27-Mar-1991 -by- Wendy Wu [wendywu]
  656. * Wrote it.
  657. \**************************************************************************/
  658. VOID vConvertXformToMatrix(CONST XFORML *pxf, PMATRIX pmx)
  659. {
  660. pmx->efM11 = pxf->eM11; // overloading operator = which covert
  661. pmx->efM12 = pxf->eM12; // IEEE float to our internal EFLOAT
  662. pmx->efM21 = pxf->eM21;
  663. pmx->efM22 = pxf->eM22;
  664. pmx->efDx = pxf->eDx;
  665. pmx->efDy = pxf->eDy;
  666. #if DBG
  667. if (!pmx->efDx.bEfToL(pmx->fxDx))
  668. WARNING("vConvertXformToMatrix:translation dx overflowed\n");
  669. if (!pmx->efDy.bEfToL(pmx->fxDy))
  670. WARNING("vConvertXformToMatrix:translation dy overflowed\n");
  671. #else
  672. pmx->efDx.bEfToL(pmx->fxDx);
  673. pmx->efDy.bEfToL(pmx->fxDy);
  674. #endif
  675. pmx->flAccel = XFORM_FORMAT_LTOL;
  676. if ((pmx->efDx == pmx->efDy) && pmx->efDy.bIsZero())
  677. pmx->flAccel |= XFORM_NO_TRANSLATION;
  678. if (pmx->efM12.bIsZero() && pmx->efM21.bIsZero())
  679. {
  680. pmx->flAccel |= XFORM_SCALE;
  681. if (pmx->efM11.bIs1() && pmx->efM22.bIs1())
  682. pmx->flAccel |= XFORM_UNITY;
  683. }
  684. }
  685. /******************************Private*Routine*****************************\
  686. * vMakeIso()
  687. *
  688. * Shrink viewport extents in one direction to match the aspect ratio of
  689. * the window.
  690. *
  691. * History:
  692. *
  693. * 05-Dec-1994 -by- Eric Kutter [erick]
  694. * Moved back to the server
  695. *
  696. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  697. * Modified for client side use.
  698. *
  699. * 09-Nov-1990 -by- Wendy Wu [wendywu]
  700. * Wrote it.
  701. \**************************************************************************/
  702. VOID DC::vMakeIso()
  703. {
  704. LONG lVpExt;
  705. EFLOAT efRes, efTemp, efTemp1;
  706. // Calculate the pixel aspect ratio efRes = ASPECTY / ASPECTX.
  707. if(lVirtualDevicePixelCx() != 0)
  708. {
  709. //
  710. // if lVirtualDeviceCx/Cy are set, use these, they are in micrometers
  711. // Otherwise use their millimeters counter part
  712. //
  713. if ((lVirtualDeviceCx()) != 0 && (lVirtualDeviceCy() != 0))
  714. {
  715. efTemp = lVirtualDevicePixelCx();
  716. efTemp1 = lVirtualDeviceCy();
  717. LONG lTemp = EngMulDiv(lVirtualDevicePixelCy(), lVirtualDeviceCx(), lVirtualDevicePixelCx());
  718. efRes = lTemp;
  719. efRes /= efTemp1;
  720. }
  721. else
  722. {
  723. efRes = lVirtualDevicePixelCy() * lVirtualDeviceMmCx();
  724. efTemp = lVirtualDevicePixelCx();
  725. efTemp1 = lVirtualDeviceMmCy();
  726. efRes /= efTemp;
  727. efRes /= efTemp1;
  728. }
  729. }
  730. else
  731. {
  732. PDEVOBJ po(hdev());
  733. ASSERTGDI(po.bValid(), "Invalid PDEV\n");
  734. efRes = (LONG)po.ulLogPixelsY();
  735. efTemp = (LONG)po.ulLogPixelsX();
  736. efRes /= efTemp;
  737. }
  738. // Our goal is to make the following formula true
  739. // VpExt.cy / VpExt.cx = (WdExt.cy / WdExt.cx) * (ASPECTY / ASPECTX)
  740. // Let's calculate VpExt.cy assuming VpExt.cx is the limiting factor.
  741. // VpExt.cy = (WdExt.cy * VpExt.cx) / WdExt.cx * efRes
  742. EFLOATEXT efVpExt = lWindowExtCy();
  743. efTemp = lViewportExtCx();
  744. efTemp1 = lWindowExtCx();
  745. efVpExt *= efTemp;
  746. efVpExt /= efTemp1;
  747. efVpExt *= efRes;
  748. efVpExt.bEfToL(lVpExt); // convert efloat to long
  749. lVpExt = ABS(lVpExt);
  750. // Shrink y if the |original VpExt.cy| > the |calculated VpExt.cy|
  751. // The original signs of the extents are preserved.
  752. if (lViewportExtCy() > 0)
  753. {
  754. if (lViewportExtCy() >= lVpExt)
  755. {
  756. lViewportExtCy(lVpExt);
  757. return;
  758. }
  759. }
  760. else
  761. {
  762. if (-lViewportExtCy() >= lVpExt)
  763. {
  764. lViewportExtCy(-lVpExt);
  765. return;
  766. }
  767. }
  768. // We know VpExt.cy is the real limiting factor. Let's calculate the correct
  769. // VpExt.cx.
  770. // VpExt.cx = (WdExt.cx * VpExt.cy) / WdExt.cy / Res
  771. efVpExt = lWindowExtCx();
  772. efTemp = lViewportExtCy();
  773. efTemp1 = lWindowExtCy();
  774. efVpExt *= efTemp;
  775. efVpExt /= efTemp1;
  776. efVpExt /= efRes;
  777. efVpExt.bEfToL(lVpExt);
  778. lVpExt = ABS(lVpExt);
  779. if(lViewportExtCx() > 0 )
  780. lViewportExtCx(lVpExt);
  781. else
  782. lViewportExtCx(-lVpExt);
  783. }
  784. /**************************************************************************\
  785. * NtGdiScaleViewportExtEx()
  786. *
  787. * History:
  788. * 07-Jun-1995 -by- Andre Vachon [andreva]
  789. * Wrote it.
  790. \**************************************************************************/
  791. BOOL
  792. NtGdiScaleViewportExtEx(
  793. HDC hdc,
  794. int xNum,
  795. int xDenom,
  796. int yNum,
  797. int yDenom,
  798. LPSIZE pszOut
  799. )
  800. {
  801. BOOL bRet = FALSE;
  802. DCOBJ dcox(hdc);
  803. if (dcox.bValid())
  804. {
  805. BOOL bNoExcept = TRUE;
  806. //
  807. // NOTE: NT 3.51 compatibility.
  808. // Even if the API failed (returned FALSE), the viewport was returned
  809. // properly - stay compatible with this.
  810. //
  811. if (pszOut)
  812. {
  813. __try
  814. {
  815. ProbeForWrite(pszOut,sizeof(SIZE), sizeof(DWORD));
  816. *pszOut = dcox.pdc->szlViewportExt();
  817. }
  818. __except(EXCEPTION_EXECUTE_HANDLER)
  819. {
  820. // SetLastError(GetExceptionCode());
  821. bNoExcept = FALSE;
  822. }
  823. }
  824. if (bNoExcept == TRUE)
  825. {
  826. // can't change extent if fixed scale
  827. if (dcox.ulMapMode() <= MM_MAX_FIXEDSCALE)
  828. {
  829. bRet = TRUE;
  830. }
  831. else
  832. {
  833. LONG lx, ly;
  834. if ((xDenom != 0) &&
  835. (yDenom != 0) &&
  836. ((lx = (dcox.pdc->lViewportExtCx() * xNum) / xDenom) != 0) &&
  837. ((ly = (dcox.pdc->lViewportExtCy() * yNum) / yDenom) != 0))
  838. {
  839. dcox.pdc->lViewportExtCx(lx);
  840. dcox.pdc->lViewportExtCy(ly);
  841. dcox.pdc->MirrorWindowOrg();
  842. dcox.pdc->vPageExtentsChanged();
  843. bRet = TRUE;
  844. }
  845. }
  846. }
  847. }
  848. return(bRet);
  849. }
  850. /******************************Public*Routine******************************\
  851. * GreScaleWindowExtEx()
  852. *
  853. * History:
  854. * 02-Dec-1994 -by- Eric Kutter [erick]
  855. * Wrote it.
  856. \**************************************************************************/
  857. BOOL GreScaleWindowExtEx(
  858. HDC hdc,
  859. int xNum,
  860. int xDenom,
  861. int yNum,
  862. int yDenom,
  863. PSIZE psizl)
  864. {
  865. BOOL bRet = FALSE;
  866. DCOBJ dcox(hdc); // lock the dc object
  867. if (dcox.bValid()) // check if lock is valid
  868. {
  869. if (psizl != (LPSIZE)NULL)
  870. {
  871. *psizl = dcox.pdc->szlWindowExt(); // fetch old extent
  872. if (MIRRORED_DC(dcox.pdc))
  873. psizl->cx = -psizl->cx;
  874. }
  875. // can't change extent if fixed scale
  876. if (dcox.ulMapMode() <= MM_MAX_FIXEDSCALE)
  877. {
  878. bRet = TRUE;
  879. }
  880. else
  881. {
  882. LONG lx, ly;
  883. if ((xDenom != 0) &&
  884. (yDenom != 0) &&
  885. ((lx = (dcox.pdc->lWindowExtCx() * xNum) / xDenom) != 0) &&
  886. ((ly = (dcox.pdc->lWindowExtCy() * yNum) / yDenom) != 0))
  887. {
  888. dcox.pdc->lWindowExtCx(lx);
  889. dcox.pdc->lWindowExtCy(ly);
  890. dcox.pdc->MirrorWindowOrg();
  891. dcox.pdc->vPageExtentsChanged();
  892. bRet = TRUE;
  893. }
  894. }
  895. }
  896. return(bRet);
  897. }
  898. /******************************Private*Routine*****************************\
  899. * vComputePageXform
  900. *
  901. * Compute the page to device scaling factors.
  902. *
  903. * History:
  904. * 05-Dec-1994 -by- Eric Kutter [erick]
  905. * Moved back to the server
  906. *
  907. *
  908. * 15-Dec-1992 -by- Wendy Wu [wendywu]
  909. * Wrote it.
  910. \**************************************************************************/
  911. VOID DC::vComputePageXform()
  912. {
  913. EFLOAT ef;
  914. EFLOATEXT efTemp;
  915. ef = LTOFX(lViewportExtCx());
  916. efTemp = lWindowExtCx();
  917. ef /= efTemp;
  918. efM11PtoD(ef);
  919. ef = LTOFX(lViewportExtCy());
  920. efTemp = lWindowExtCy();
  921. ef /= efTemp;
  922. efM22PtoD(ef);
  923. }
  924. /******************************Public*Routine******************************\
  925. *
  926. * int EngMulDiv
  927. * I am surprised that there is no system service routine to do this.
  928. * anyway I am just fixing the old routine
  929. *
  930. * History:
  931. * 15-Dec-1995 -by- Bodin Dresevic [BodinD]
  932. * Wrote it.
  933. \**************************************************************************/
  934. int EngMulDiv(
  935. int a,
  936. int b,
  937. int c)
  938. {
  939. LONGLONG ll;
  940. int iSign = 1;
  941. if (a < 0)
  942. {
  943. iSign = -iSign;
  944. a = -a;
  945. }
  946. if (b < 0)
  947. {
  948. iSign = -iSign;
  949. b = -b;
  950. }
  951. if (c != 0)
  952. {
  953. if (c < 0)
  954. {
  955. iSign = -iSign;
  956. c = -c;
  957. }
  958. ll = (LONGLONG)a;
  959. ll *= b;
  960. ll += (c/2); // used to add (c+1)/2 which is wrong
  961. ll /= c;
  962. // at this point ll is guaranteed to be > 0. Thus we will do
  963. // unsigned compare in the next step which generates two less instructions
  964. // on x86 [bodind]
  965. if ((ULONGLONG)ll > (ULONG)INT_MAX) // check for overflow:
  966. {
  967. if (iSign > 0)
  968. return INT_MAX;
  969. else
  970. return INT_MIN;
  971. }
  972. else
  973. {
  974. if (iSign > 0)
  975. return ((int)ll);
  976. else
  977. return (-(int)ll);
  978. }
  979. }
  980. else
  981. {
  982. ASSERTGDI(c, "EngMulDiv - c == 0\n");
  983. ASSERTGDI(a | b, "EngMulDiv - a|b == 0\n");
  984. if (iSign > 0)
  985. return INT_MAX;
  986. else
  987. return INT_MIN;
  988. }
  989. }
  990. /******************************Public*Routine******************************\
  991. * dwSetLayout
  992. *
  993. * Mirror the dc, by offsetting the window origin. If wox == -1, then the
  994. * window origin becomes mirrored by the DC window width as follows :
  995. * -((Device_Surface_Width * WindowExtX) / ViewportExtX) + LogicalWindowOrgX
  996. *
  997. * Otherwise mirroring is done by the specified wox amount :
  998. * (wox - Current Window X-Origin)
  999. *
  1000. * The function also changes windowExt.cx to be -1 so that positive x will
  1001. * go from right to left.
  1002. *
  1003. * History:
  1004. * 09-Dec-1997 -by- Mohammed Abdel-Hamid [mhamid]
  1005. * Wrote it.
  1006. \**************************************************************************/
  1007. DWORD DC::dwSetLayout(LONG wox, DWORD dwDefLayout)
  1008. {
  1009. POINTL ptWOrg, ptVOrg;
  1010. SIZEL SzWExt, SzVExt;
  1011. DWORD dwOldLayout;
  1012. dwOldLayout = dwLayout();
  1013. dwLayout(dwDefLayout);
  1014. if ((dwOldLayout & LAYOUT_ORIENTATIONMASK) == (dwDefLayout & LAYOUT_ORIENTATIONMASK)) {
  1015. return dwOldLayout;
  1016. }
  1017. vGet_szlWindowExt(&SzWExt);
  1018. vGet_ptlViewportOrg(&ptVOrg);
  1019. if (dwDefLayout & LAYOUT_RTL) {
  1020. //Set the rtl layout
  1021. ulMapMode(MM_ANISOTROPIC);
  1022. ASSERTGDI((SzWExt.cx > 0), "GreSetLayout WExt.cx < 0 Check it");
  1023. } else {
  1024. ASSERTGDI((SzWExt.cx < 0), "GreSetLayout WExt.cx > 0 Check it");
  1025. }
  1026. SzWExt.cx = -SzWExt.cx;
  1027. vSet_szlWindowExt(&SzWExt);
  1028. ptVOrg.x = -ptVOrg.x;
  1029. vSet_ptlViewportOrg(&ptVOrg);
  1030. if (wox == -1) {
  1031. MirrorWindowOrg();
  1032. } else {
  1033. vGet_ptlWindowOrg(&ptWOrg);
  1034. ptWOrg.x = wox - ptWOrg.x;
  1035. vSet_ptlWindowOrg(&ptWOrg);
  1036. }
  1037. //
  1038. // TA_CENTER equals 6 (0110 Bin) and TA_RIGHT equals 2 (0010 Binary) numerically.
  1039. // so be careful not to do 'flTextAlign() & TA_CENTER'
  1040. // since this will succeed for RIGHT aligned DCs
  1041. // and as a result, the TA_RIGHT bit won't get cleared. [samera]
  1042. //
  1043. if ((flTextAlign()&TA_CENTER) != TA_CENTER) {
  1044. flTextAlign(flTextAlign() ^ (TA_RIGHT));
  1045. }
  1046. if (bClockwise()) {
  1047. vClearClockwise();
  1048. } else {
  1049. vSetClockwise();
  1050. }
  1051. vPageExtentsChanged();
  1052. return dwOldLayout;
  1053. }
  1054. EFLOAT ef16 = {EFLOAT_16};
  1055. /******************************Public*Routine******************************\
  1056. * DC::iSetMapMode()
  1057. *
  1058. * History:
  1059. * 07-Dec-1994 -by- Eric Kutter [erick]
  1060. * Wrote it.
  1061. \**************************************************************************/
  1062. int DC::iSetMapMode(
  1063. int iMode)
  1064. {
  1065. int iOldMode;
  1066. DWORD dwOldLayout = 0;
  1067. // If the new map mode is not MM_ANISOTROPIC
  1068. // And the DC in a mirrored mode
  1069. // Then Turn off the mirroring and turn it on back after
  1070. // Setting the new mode.
  1071. if (iMode != MM_ANISOTROPIC) {
  1072. dwOldLayout = dwLayout();
  1073. if (dwOldLayout & LAYOUT_ORIENTATIONMASK) {
  1074. dwSetLayout(-1 , 0);
  1075. }
  1076. }
  1077. // If set to the old map mode, don't bother setting it again except
  1078. // with MM_ISOTROPIC in which the extents might have been changed.
  1079. iOldMode = ulMapMode();
  1080. if ((iMode != iOldMode) || (iMode == MM_ISOTROPIC))
  1081. {
  1082. if (iMode == MM_TEXT)
  1083. {
  1084. lWindowExtCx(1);
  1085. lWindowExtCy(1);
  1086. lViewportExtCx(1);
  1087. lViewportExtCy(1);
  1088. ulMapMode(iMode);
  1089. // We don't want to recalculate M11 and M22 in vUpdateWtoDXform().
  1090. // Set them correctly here so we can just recalculate translations
  1091. // in vUpdateWtoDXform().
  1092. efM11PtoD(ef16);
  1093. efM22PtoD(ef16);
  1094. mxWorldToDevice().efM11 = ef16;
  1095. mxWorldToDevice().efM22 = ef16;
  1096. mxWorldToDevice().flAccel = XFORM_FORMAT_LTOFX | XFORM_UNITY | XFORM_SCALE;
  1097. RtlCopyMemory(
  1098. (PVOID) &mxUserWorldToDevice(),
  1099. (PVOID) &mxWorldToDevice(),
  1100. sizeof( MATRIX ));
  1101. vSetFlagsMM_TEXT();
  1102. }
  1103. else if (iMode == MM_ANISOTROPIC)
  1104. {
  1105. ulMapMode(iMode);
  1106. vSetFlagsMM_ISO_OR_ANISO();
  1107. }
  1108. else if ((iMode < MM_MIN) || (iMode > MM_MAX))
  1109. {
  1110. return(0);
  1111. }
  1112. else if (lVirtualDevicePixelCx() == 0)
  1113. {
  1114. PDEVOBJ po(hdev());
  1115. ASSERTGDI(po.bValid(), "Invalid PDEV\n");
  1116. // Protect against dynamic mode changes while we compute values
  1117. // using ulHorzSize and ulVertSize:
  1118. DEVLOCKOBJ dlo(po);
  1119. // Get the size of the surface
  1120. lViewportExtCx(po.GdiInfo()->ulHorzRes);
  1121. lViewportExtCy(-(LONG)po.GdiInfo()->ulVertRes);
  1122. // Get the size of the device
  1123. switch (iMode)
  1124. {
  1125. case MM_LOMETRIC:
  1126. //
  1127. // n um. * (1 mm. / 1000 um.) * (10 LoMetric units/1 mm.) = y LoMet
  1128. //
  1129. lWindowExtCx((po.GdiInfo()->ulHorzSize + 50)/100);
  1130. lWindowExtCy((po.GdiInfo()->ulVertSize + 50)/100);
  1131. vSetFlagsMM_FIXED();
  1132. break;
  1133. case MM_HIMETRIC:
  1134. //
  1135. // n um. * (1 mm. / 1000 um.) * (100 HiMetric units/1 mm.) = y HiMet
  1136. //
  1137. lWindowExtCx((po.GdiInfo()->ulHorzSize + 5)/10);
  1138. lWindowExtCy((po.GdiInfo()->ulVertSize + 5)/10);
  1139. vSetFlagsMM_FIXED();
  1140. break;
  1141. case MM_LOENGLISH:
  1142. //
  1143. // n um. * (1 in. / 25400 um.) * (100 LoEng units/1 in.) = y LoEng
  1144. //
  1145. lWindowExtCx((po.GdiInfo()->ulHorzSize + 127)/254);
  1146. lWindowExtCy((po.GdiInfo()->ulVertSize + 127)/254);
  1147. vSetFlagsMM_FIXED();
  1148. break;
  1149. case MM_HIENGLISH:
  1150. //
  1151. // n um. * (1 in. / 25400 um.) * (1000 HiEng units/1 in.) = m HiEng
  1152. //
  1153. lWindowExtCx(EngMulDiv(po.GdiInfo()->ulHorzSize, 10, 254));
  1154. lWindowExtCy(EngMulDiv(po.GdiInfo()->ulVertSize, 10, 254));
  1155. vSetFlagsMM_FIXED();
  1156. break;
  1157. case MM_TWIPS:
  1158. //
  1159. // n um. * (1 in. / 25400 um.) * (1440 Twips/1 in.) = m Twips
  1160. //
  1161. lWindowExtCx(EngMulDiv(po.GdiInfo()->ulHorzSize, 144, 2540));
  1162. lWindowExtCy(EngMulDiv(po.GdiInfo()->ulVertSize, 144, 2540));
  1163. // If it's cached earlier, use it.
  1164. #if defined(_AMD64_) || defined(_IA64_) || defined(BUILD_WOW6432)
  1165. if (efM11_TWIPS().e == (FLOAT)0)
  1166. #else
  1167. if (efM11_TWIPS().i.lMant == 0)
  1168. #endif
  1169. {
  1170. vComputePageXform();
  1171. efM11_TWIPS(efM11PtoD());
  1172. efM22_TWIPS(efM22PtoD());
  1173. }
  1174. ulMapMode(MM_TWIPS);
  1175. // We don't want to recalculate M11 and M22 in vUpdateWtoDXform().
  1176. // Set them correctly here so we can just recalculate translations
  1177. // in vUpdateWtoDXform().
  1178. efM11PtoD(efM11_TWIPS());
  1179. efM22PtoD(efM22_TWIPS());
  1180. mxWorldToDevice().efM11 = efM11_TWIPS();
  1181. mxWorldToDevice().efM22 = efM22_TWIPS();
  1182. mxWorldToDevice().flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE;
  1183. RtlCopyMemory(
  1184. (PVOID) &mxUserWorldToDevice(),
  1185. (PVOID) &mxWorldToDevice(),
  1186. sizeof( MATRIX ));
  1187. vSetFlagsMM_FIXED_CACHED();
  1188. goto JUST_RETURN;
  1189. //
  1190. // we need to pass thru mirroring code if
  1191. // it is enabled so the followingis commented for
  1192. // the above line
  1193. // return(iOldMode);
  1194. //
  1195. case MM_ISOTROPIC:
  1196. lWindowExtCx((po.GdiInfo()->ulHorzSize + 50)/100);
  1197. lWindowExtCy((po.GdiInfo()->ulVertSize + 50)/100);
  1198. vSetFlagsMM_ISO_OR_ANISO();
  1199. break;
  1200. default:
  1201. return(0);
  1202. }
  1203. ulMapMode(iMode);
  1204. vPageExtentsChanged();
  1205. }
  1206. else
  1207. {
  1208. // Get the size of the virtual surface
  1209. lViewportExtCx(lVirtualDevicePixelCx());
  1210. lViewportExtCy(-lVirtualDevicePixelCy());
  1211. // Get the size of the virtual device
  1212. switch (iMode)
  1213. {
  1214. case MM_LOMETRIC:
  1215. //
  1216. // n mm. * (10 LoMetric units/1 mm.) = y LoMet
  1217. //
  1218. lWindowExtCx(10 * lVirtualDeviceMmCx());
  1219. lWindowExtCy(10 * lVirtualDeviceMmCy());
  1220. vSetFlagsMM_FIXED();
  1221. break;
  1222. case MM_HIMETRIC:
  1223. //
  1224. // n mm. * (100 HiMetric units/1 mm.) = y HiMet
  1225. //
  1226. lWindowExtCx(100 * lVirtualDeviceMmCx());
  1227. lWindowExtCy(100 * lVirtualDeviceMmCy());
  1228. vSetFlagsMM_FIXED();
  1229. break;
  1230. case MM_LOENGLISH:
  1231. //
  1232. // n mm. * (10 in./254 mm.) * (100 LoEng/1 in.) = y LoEng
  1233. //
  1234. lWindowExtCx(EngMulDiv(lVirtualDeviceMmCx(),1000, 254));
  1235. lWindowExtCy(EngMulDiv(lVirtualDeviceMmCy(),1000, 254));
  1236. vSetFlagsMM_FIXED();
  1237. break;
  1238. case MM_HIENGLISH:
  1239. //
  1240. // n mm. * (10 in./254 mm.) * (1000 LoEng/1 in.) = y LoEng
  1241. //
  1242. lWindowExtCx(EngMulDiv(lVirtualDeviceMmCx(),10000, 254));
  1243. lWindowExtCy(EngMulDiv(lVirtualDeviceMmCy(),10000, 254));
  1244. vSetFlagsMM_FIXED();
  1245. break;
  1246. case MM_TWIPS:
  1247. //
  1248. // n mm. * (10 in./254 mm.) * (1440 Twips/1 in.) = y Twips
  1249. //
  1250. lWindowExtCx(EngMulDiv(lVirtualDeviceMmCx(),14400, 254));
  1251. lWindowExtCy(EngMulDiv(lVirtualDeviceMmCy(),14400, 254));
  1252. vSetFlagsMM_FIXED();
  1253. break;
  1254. case MM_ISOTROPIC:
  1255. //
  1256. // n mm. * (10 LoMetric units/1 mm.) = y LoMet
  1257. //
  1258. lWindowExtCx(10 * lVirtualDeviceMmCx());
  1259. lWindowExtCy(10 * lVirtualDeviceMmCy());
  1260. vSetFlagsMM_ISO_OR_ANISO();
  1261. break;
  1262. default:
  1263. return(0);
  1264. }
  1265. ulMapMode(iMode);
  1266. vPageExtentsChanged();
  1267. }
  1268. JUST_RETURN:
  1269. // If turned the mirroring off then turn it on back.
  1270. if (dwOldLayout & LAYOUT_ORIENTATIONMASK) {
  1271. //And then set it again.
  1272. dwSetLayout(-1 , dwOldLayout);
  1273. }
  1274. }
  1275. return(iOldMode);
  1276. }
  1277. /******************************Public*Routine******************************\
  1278. * NtGdiSetVirtualResolution()
  1279. *
  1280. * Set the virtual resolution of the specified dc.
  1281. * The virtual resolution is used to compute transform matrix only.
  1282. * If the virtual units are all zeros, the default physical units are used.
  1283. * Otherwise, non of the units can be zero.
  1284. *
  1285. * Currently used by metafile component only.
  1286. *
  1287. * History:
  1288. *
  1289. * 05-Dec-1994 -by- Eric Kutter [erick]
  1290. * Moved back to the server
  1291. *
  1292. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  1293. * Modified for client side use.
  1294. *
  1295. * Tue Aug 27 13:04:11 1991 -by- Hock San Lee [hockl]
  1296. * Wrote it.
  1297. \**************************************************************************/
  1298. BOOL APIENTRY NtGdiSetVirtualResolution(
  1299. HDC hdc,
  1300. int cxVirtualDevicePixel, // Width of the virtual device in pels
  1301. int cyVirtualDevicePixel, // Height of the virtual device in pels
  1302. int cxVirtualDeviceMm, // Width of the virtual device in millimeters
  1303. int cyVirtualDeviceMm) // Height of the virtual device in millimeters
  1304. {
  1305. XFORMPRINT(1,"GreSetVirtualResolution\n",0);
  1306. BOOL bRet = FALSE;
  1307. // The units must be all zeros or all non-zeros.
  1308. if ((cxVirtualDevicePixel != 0 && cyVirtualDevicePixel != 0 &&
  1309. cxVirtualDeviceMm != 0 && cyVirtualDeviceMm != 0)
  1310. ||
  1311. (cxVirtualDevicePixel == 0 && cyVirtualDevicePixel == 0 &&
  1312. cxVirtualDeviceMm == 0 && cyVirtualDeviceMm == 0))
  1313. {
  1314. // now lock down the DC
  1315. DCOBJ dcox(hdc); // lock the dc object
  1316. if (dcox.bValid()) // check if lock is valid
  1317. {
  1318. dcox.pdc->lVirtualDevicePixelCx(cxVirtualDevicePixel);
  1319. dcox.pdc->lVirtualDevicePixelCy(cyVirtualDevicePixel);
  1320. dcox.pdc->lVirtualDeviceMmCx(cxVirtualDeviceMm);
  1321. dcox.pdc->lVirtualDeviceMmCy(cyVirtualDeviceMm);
  1322. bRet = TRUE;
  1323. }
  1324. }
  1325. return(bRet);
  1326. }
  1327. /******************************Public*Routine******************************\
  1328. * NtGdiSetSizeDevice()
  1329. *
  1330. * This is to compensate insufficient precision in SetVirtualResolution
  1331. *
  1332. * Modified for client side use.
  1333. *
  1334. * 5/17/99 -by- Lingyun Wang [lingyunw]
  1335. * Wrote it.
  1336. \**************************************************************************/
  1337. BOOL APIENTRY NtGdiSetSizeDevice(
  1338. HDC hdc,
  1339. int cxVirtualDevice, // Width of the virtual device in micrometers
  1340. int cyVirtualDevice) // Height of the virtual device in micrometers
  1341. {
  1342. BOOL bRet = FALSE;
  1343. // The units must be all zeros or all non-zeros.
  1344. if ((cxVirtualDevice != 0) && (cyVirtualDevice != 0))
  1345. {
  1346. // now lock down the DC
  1347. DCOBJ dcox(hdc); // lock the dc object
  1348. if (dcox.bValid()) // check if lock is valid
  1349. {
  1350. dcox.pdc->lVirtualDeviceCx(cxVirtualDevice);
  1351. dcox.pdc->lVirtualDeviceCy(cyVirtualDevice);
  1352. bRet = TRUE;
  1353. }
  1354. }
  1355. return(bRet);
  1356. }
  1357. /******************************Public*Routine******************************\
  1358. * GreGetTransform()
  1359. *
  1360. * History:
  1361. * 05-Dec-1994 -by- Eric Kutter [erick]
  1362. * Wrote it.
  1363. \**************************************************************************/
  1364. BOOL GreGetTransform(
  1365. HDC hdc,
  1366. DWORD iXform,
  1367. XFORML *pxf)
  1368. {
  1369. XFORMPRINT(1,"GreGetTransform - iXform = %ld\n",iXform);
  1370. BOOL bRet = FALSE;
  1371. // now lock down the DC
  1372. DCOBJ dcox(hdc);
  1373. if (dcox.bValid())
  1374. {
  1375. EXFORMOBJ xo(dcox,iXform);
  1376. MATRIX mx;
  1377. if (!xo.bValid() && (iXform == XFORM_PAGE_TO_DEVICE))
  1378. {
  1379. xo.vInitPageToDevice(dcox,&mx);
  1380. }
  1381. if (xo.bValid())
  1382. {
  1383. xo.vGetCoefficient(pxf);
  1384. bRet = TRUE;
  1385. }
  1386. }
  1387. return(bRet);
  1388. }
  1389. /******************************Public*Routine******************************\
  1390. * XformUpdate
  1391. *
  1392. * Sends update transform information to the server.
  1393. *
  1394. * History:
  1395. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  1396. * Wrote it.
  1397. \**************************************************************************/
  1398. VOID EXFORMOBJ::vInit(
  1399. XDCOBJ& dco,
  1400. ULONG iXform)
  1401. {
  1402. XFORMPRINT(1,"EXFORMOBJ::vInit - iXform = %lx\n",iXform);
  1403. if (dco.pdc->bDirtyXform())
  1404. {
  1405. // Save current position
  1406. if (!dco.pdc->bValidPtlCurrent())
  1407. {
  1408. ASSERTGDI(dco.pdc->bValidPtfxCurrent(), "Both CPs invalid?");
  1409. EXFORMOBJ exoDtoW(dco.pdc->mxDeviceToWorld());
  1410. if (exoDtoW.bValid())
  1411. exoDtoW.bXform(&dco.ptfxCurrent(), &dco.ptlCurrent(), 1);
  1412. dco.pdc->vValidatePtlCurrent();
  1413. }
  1414. // update the transforms
  1415. dco.pdc->vUpdateWtoDXform();
  1416. // After the transform, the device space CP will be invalid:
  1417. dco.pdc->vInvalidatePtfxCurrent();
  1418. if( dco.pdc->flXform() & INVALIDATE_ATTRIBUTES)
  1419. {
  1420. EXFORMOBJ exoWtoD(dco.pdc->mxWorldToDevice());
  1421. dco.pdc->vRealizeLineAttrs(exoWtoD);
  1422. dco.pdc->vXformChange(TRUE);
  1423. dco.pdc->flClr_flXform(INVALIDATE_ATTRIBUTES);
  1424. }
  1425. dco.pdc->flSet_flXform(DEVICE_TO_WORLD_INVALID);
  1426. }
  1427. switch (iXform)
  1428. {
  1429. case XFORM_WORLD_TO_DEVICE:
  1430. pmx = &dco.pdc->mxWorldToDevice();
  1431. XFORMPRINT(2,"EXFORM::vInit - WtoD, pmx = %p\n",pmx);
  1432. break;
  1433. case XFORM_DEVICE_TO_WORLD:
  1434. pmx = &dco.pdc->mxDeviceToWorld();
  1435. if (dco.pdc->flXform() & DEVICE_TO_WORLD_INVALID)
  1436. {
  1437. if (bInverse(dco.pdc->mxWorldToDevice()))
  1438. {
  1439. dco.pdc->flClr_flXform(DEVICE_TO_WORLD_INVALID);
  1440. RtlCopyMemory(
  1441. (PVOID)&dco.pdc->mxUserDeviceToWorld(),
  1442. (PVOID)pmx,
  1443. sizeof( MATRIX )
  1444. );
  1445. }
  1446. else
  1447. {
  1448. pmx = (PMATRIX)NULL;
  1449. }
  1450. XFORMPRINT(2,"EXFORM::vInit - DtoW was dirty, pmx = %p\n",pmx);
  1451. }
  1452. break;
  1453. case XFORM_WORLD_TO_PAGE:
  1454. XFORMPRINT(2,"EXFORM::vInit - WtoP, pmx = %p\n",pmx);
  1455. pmx = &dco.pdc->mxWorldToPage();
  1456. break;
  1457. default:
  1458. XFORMPRINT(2,"EXFORM::vInit - NULL",pmx);
  1459. pmx = NULL;
  1460. break;
  1461. }
  1462. }
  1463. /******************************Public*Routine******************************\
  1464. * EXFORMOBJ::vInitPageToDevice()
  1465. *
  1466. * History:
  1467. * 05-Dec-1994 -by- Eric Kutter [erick]
  1468. * Wrote it.
  1469. \**************************************************************************/
  1470. VOID EXFORMOBJ::vInitPageToDevice(
  1471. XDCOBJ& dco,
  1472. PMATRIX pmx_)
  1473. {
  1474. pmx = pmx_;
  1475. pmx->efM11 = dco.pdc->efM11PtoD();
  1476. pmx->efM12.vSetToZero();
  1477. pmx->efM21.vSetToZero();
  1478. pmx->efM22 = dco.pdc->efM22PtoD();
  1479. pmx->efDx = dco.pdc->efDxPtoD();
  1480. pmx->efDy = dco.pdc->efDyPtoD();
  1481. pmx->efDx.bEfToL(pmx->fxDx);
  1482. pmx->efDy.bEfToL(pmx->fxDy);
  1483. vComputeWtoDAccelFlags();
  1484. }
  1485. /******************************Private*Routine*****************************\
  1486. * vUpdateWtoDXform
  1487. *
  1488. * Update the world to device transform.
  1489. *
  1490. * History:
  1491. *
  1492. * 15-Dec-1992 -by- Wendy Wu [wendywu]
  1493. * Wrote it.
  1494. \**************************************************************************/
  1495. VOID DC::vUpdateWtoDXform()
  1496. {
  1497. PMATRIX pmx = &mxWorldToDevice();
  1498. if (bDirtyXlateOrExt())
  1499. {
  1500. if (bPageExtentsChanged())
  1501. {
  1502. // Recalculate the scaling factors for the page to device xform.
  1503. // M11 = ViewportExt.cx / WindowExt.cx
  1504. // M22 = ViewportExt.cy / WindowExt.cy
  1505. if (ulMapMode() == MM_ISOTROPIC)
  1506. vMakeIso();
  1507. if ((lWindowExtCx() == lViewportExtCx()) &&
  1508. (lWindowExtCy() == lViewportExtCy()))
  1509. {
  1510. efM11PtoD(ef16);
  1511. efM22PtoD(ef16);
  1512. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_UNITY | XFORM_SCALE;
  1513. flSet_flXform(PAGE_TO_DEVICE_SCALE_IDENTITY);
  1514. }
  1515. else
  1516. {
  1517. EFLOATEXT ef1;
  1518. EFLOATEXT ef2;
  1519. ef1 = LTOFX(lViewportExtCx());
  1520. ef2 = lWindowExtCx();
  1521. ef1 /= ef2;
  1522. efM11PtoD(ef1);
  1523. ef1 = LTOFX(lViewportExtCy());
  1524. ef2 = lWindowExtCy();
  1525. ef1 /= ef2;
  1526. efM22PtoD(ef1);
  1527. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE;
  1528. flClr_flXform(PAGE_TO_DEVICE_SCALE_IDENTITY | PAGE_TO_DEVICE_IDENTITY);
  1529. }
  1530. if (efM11PtoD().bIsNegative())
  1531. flSet_flXform(PTOD_EFM11_NEGATIVE);
  1532. else
  1533. flClr_flXform(PTOD_EFM11_NEGATIVE);
  1534. if (efM22PtoD().bIsNegative())
  1535. flSet_flXform(PTOD_EFM22_NEGATIVE);
  1536. else
  1537. flClr_flXform(PTOD_EFM22_NEGATIVE);
  1538. }
  1539. // Recalculate the translations for the page to device xform.
  1540. // Dx = ViewportOrg.x - (ViewportExt.cx / WindowExt.cx) * WindowOrg.x
  1541. // (ViewportExt.cx / WindowExt.cx) = efM11
  1542. // Dy = ViewportOrg.y - (ViewportExt.cy / WindowExt.cy) * WindowOrg.cy
  1543. // (ViewportExt.cy / WindowExt.cy) = efM22
  1544. if ((lWindowOrgX() == 0) &&
  1545. (lWindowOrgY() == 0))
  1546. {
  1547. if ((lViewportOrgX() == 0) &&
  1548. (lViewportOrgY() == 0))
  1549. {
  1550. EFLOAT efZ;
  1551. efZ.vSetToZero();
  1552. efDxPtoD(efZ);
  1553. efDyPtoD(efZ);
  1554. pmx->fxDx = 0;
  1555. pmx->fxDy = 0;
  1556. pmx->flAccel |= XFORM_NO_TRANSLATION;
  1557. if (bPageToDeviceScaleIdentity())
  1558. flSet_flXform(PAGE_TO_DEVICE_IDENTITY);
  1559. }
  1560. else
  1561. {
  1562. efDxPtoD(LTOFX(lViewportOrgX()));
  1563. efDyPtoD(LTOFX(lViewportOrgY()));
  1564. pmx->fxDx = LTOFX(lViewportOrgX());
  1565. pmx->fxDy = LTOFX(lViewportOrgY());
  1566. pmx->flAccel &= ~XFORM_NO_TRANSLATION;
  1567. flClr_flXform(PAGE_TO_DEVICE_IDENTITY);
  1568. }
  1569. }
  1570. else
  1571. {
  1572. flClr_flXform(PAGE_TO_DEVICE_IDENTITY);
  1573. pmx->flAccel &= ~XFORM_NO_TRANSLATION;
  1574. if (bPageToDeviceScaleIdentity())
  1575. {
  1576. efDxPtoD(LTOFX(-lWindowOrgX()));
  1577. efDyPtoD(LTOFX(-lWindowOrgY()));
  1578. if ((lViewportOrgX() != 0) ||
  1579. (lViewportOrgY() != 0))
  1580. {
  1581. goto ADD_VIEWPORT_ORG;
  1582. }
  1583. pmx->fxDx = LTOFX(-lWindowOrgX());
  1584. pmx->fxDy = LTOFX(-lWindowOrgY());
  1585. }
  1586. else
  1587. {
  1588. {
  1589. EFLOATEXT ef;
  1590. ef = -lWindowOrgX();
  1591. ef *= efrM11PtoD();
  1592. efDxPtoD(ef);
  1593. ef = -lWindowOrgY();
  1594. ef *= efrM22PtoD();
  1595. efDyPtoD(ef);
  1596. }
  1597. if ((lViewportOrgX()!= 0) ||
  1598. (lViewportOrgY() != 0))
  1599. {
  1600. ADD_VIEWPORT_ORG:
  1601. EFLOATEXT efXVO(LTOFX(lViewportOrgX()));
  1602. efXVO += efrDxPtoD();
  1603. efDxPtoD(efXVO);
  1604. EFLOATEXT efYVO(LTOFX(lViewportOrgY()));
  1605. efYVO += efrDyPtoD();
  1606. efDyPtoD(efYVO);
  1607. }
  1608. efDxPtoD().bEfToL(pmx->fxDx);
  1609. efDyPtoD().bEfToL(pmx->fxDy);
  1610. }
  1611. }
  1612. if (bWorldToPageIdentity())
  1613. {
  1614. // Copy the PAGE_TO_DEVICE xform to WORLD_TO_DEVICE.
  1615. // pmx->fxDx, fxDy and flAccel has been set earlier in this routine.
  1616. pmx->efM11 = efM11PtoD();
  1617. pmx->efM22 = efM22PtoD();
  1618. pmx->efM12.vSetToZero();
  1619. pmx->efM21.vSetToZero();
  1620. pmx->efDx = efDxPtoD();
  1621. pmx->efDy = efDyPtoD();
  1622. if (bPageToDeviceIdentity())
  1623. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE | XFORM_UNITY |
  1624. XFORM_NO_TRANSLATION;
  1625. else if (bPageToDeviceScaleIdentity())
  1626. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE | XFORM_UNITY;
  1627. else
  1628. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE;
  1629. flClr_flXform(PAGE_XLATE_CHANGED | PAGE_EXTENTS_CHANGED |
  1630. WORLD_XFORM_CHANGED);
  1631. RtlCopyMemory( (PVOID) &mxUserWorldToDevice(), pmx, sizeof( MATRIX ));
  1632. return;
  1633. }
  1634. }
  1635. else
  1636. {
  1637. if (bWorldToPageIdentity())
  1638. {
  1639. // World transform has changed to identity.
  1640. pmx->efM11 = efM11PtoD();
  1641. pmx->efM22 = efM22PtoD();
  1642. pmx->efM12.vSetToZero();
  1643. pmx->efM21.vSetToZero();
  1644. pmx->efDx = efDxPtoD();
  1645. pmx->efDy = efDyPtoD();
  1646. efDxPtoD().bEfToL(pmx->fxDx);
  1647. efDyPtoD().bEfToL(pmx->fxDy);
  1648. if (bPageToDeviceIdentity())
  1649. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE | XFORM_UNITY |
  1650. XFORM_NO_TRANSLATION;
  1651. else if (bPageToDeviceScaleIdentity())
  1652. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE | XFORM_UNITY;
  1653. else
  1654. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE;
  1655. flClr_flXform(PAGE_XLATE_CHANGED | PAGE_EXTENTS_CHANGED |
  1656. WORLD_XFORM_CHANGED);
  1657. RtlCopyMemory( (PVOID) &mxUserWorldToDevice(), pmx, sizeof( MATRIX ));
  1658. return;
  1659. }
  1660. }
  1661. // Multiply the world to page and page to device xform together.
  1662. PMATRIX pmxWtoP = &mxWorldToPage();
  1663. if (bPageToDeviceScaleIdentity())
  1664. {
  1665. RtlCopyMemory(pmx, pmxWtoP, offsetof(MATRIX, flAccel));
  1666. pmx->efM11.vTimes16();
  1667. pmx->efM12.vTimes16();
  1668. pmx->efM21.vTimes16();
  1669. pmx->efM22.vTimes16();
  1670. pmx->efDx.vTimes16();
  1671. pmx->efDy.vTimes16();
  1672. }
  1673. else
  1674. {
  1675. pmx->efM11.eqMul(pmxWtoP->efM11,efM11PtoD());
  1676. pmx->efM21.eqMul(pmxWtoP->efM21,efM11PtoD());
  1677. pmx->efM12.eqMul(pmxWtoP->efM12,efM22PtoD());
  1678. pmx->efM22.eqMul(pmxWtoP->efM22,efM22PtoD());
  1679. pmx->efDx.eqMul(pmxWtoP->efDx,efM11PtoD());
  1680. pmx->efDy.eqMul(pmxWtoP->efDy,efM22PtoD());
  1681. }
  1682. pmx->efDx += efrDxPtoD();
  1683. pmx->efDx.bEfToL(pmx->fxDx);
  1684. pmx->efDy += efrDyPtoD();
  1685. pmx->efDy.bEfToL(pmx->fxDy);
  1686. if (pmx->efM12.bIsZero() && pmx->efM21.bIsZero())
  1687. {
  1688. if (pmx->efM11.bIs16() && pmx->efM22.bIs16())
  1689. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE | XFORM_UNITY;
  1690. else
  1691. pmx->flAccel = XFORM_FORMAT_LTOFX | XFORM_SCALE;
  1692. }
  1693. else
  1694. {
  1695. pmx->flAccel = XFORM_FORMAT_LTOFX;
  1696. }
  1697. if ((pmx->fxDx == 0) && (pmx->fxDy == 0))
  1698. pmx->flAccel |= XFORM_NO_TRANSLATION;
  1699. flClr_flXform(PAGE_XLATE_CHANGED | PAGE_EXTENTS_CHANGED |
  1700. WORLD_XFORM_CHANGED);
  1701. RtlCopyMemory((PVOID)&mxUserWorldToDevice(),pmx,sizeof(MATRIX));
  1702. }
  1703. /******************************Private*Routine*****************************\
  1704. * bWordXformIdentity
  1705. *
  1706. * See is a world transform matrix is identity.
  1707. *
  1708. * History:
  1709. *
  1710. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  1711. * Modified for client side use.
  1712. *
  1713. * 26-Dec-1990 -by- Wendy Wu [wendywu]
  1714. * Wrote it.
  1715. \**************************************************************************/
  1716. BOOL bWorldXformIdentity(CONST XFORML *pxf)
  1717. {
  1718. return((pxf->eM11 == IEEE_1_0F) && (pxf->eM12 == IEEE_0_0F) &&
  1719. (pxf->eM21 == IEEE_0_0F) && (pxf->eM22 == IEEE_1_0F) &&
  1720. (pxf->eDx == IEEE_0_0F) && (pxf->eDy == IEEE_0_0F));
  1721. }
  1722. /******************************Public*Routine******************************\
  1723. * NtGdiModifyWorldTransform()
  1724. *
  1725. * History:
  1726. * 01-Nov-1994 -by- Eric Kutter [erick]
  1727. * Wrote it.
  1728. \**************************************************************************/
  1729. BOOL
  1730. APIENTRY
  1731. NtGdiModifyWorldTransform(
  1732. HDC hdc,
  1733. LPXFORM pxf,
  1734. DWORD iXform
  1735. )
  1736. {
  1737. XFORMPRINT(1,"GreModifyWorldTransform - iXform = %ld\n",iXform);
  1738. ASSERTGDI(sizeof(XFORM) == sizeof(XFORML),"sizeof(XFORM) != sizeof(XFORML)\n");
  1739. BOOL bRet = FALSE;
  1740. DCOBJ dcox(hdc);
  1741. if (dcox.bValid())
  1742. {
  1743. XFORML xf;
  1744. if (pxf)
  1745. {
  1746. bRet = ProbeAndConvertXFORM((XFORML *)pxf, &xf);
  1747. }
  1748. else
  1749. {
  1750. // must be identity to allow pxf == NULL
  1751. bRet = (iXform == MWT_IDENTITY);
  1752. }
  1753. if (bRet)
  1754. {
  1755. bRet = dcox.bModifyWorldTransform(&xf,iXform);
  1756. }
  1757. }
  1758. return(bRet);
  1759. }
  1760. /******************************Public*Routine******************************\
  1761. * XDCOBJ::bModifyWorldTransform()
  1762. *
  1763. * History:
  1764. * 07-Dec-1994 -by- Eric Kutter [erick]
  1765. * Wrote it.
  1766. \**************************************************************************/
  1767. BOOL XDCOBJ::bModifyWorldTransform(
  1768. CONST XFORML *pxf,
  1769. ULONG iMode)
  1770. {
  1771. BOOL bRet = FALSE;
  1772. MATRIX mx;
  1773. switch (iMode)
  1774. {
  1775. case MWT_SET:
  1776. if (!bWorldXformIdentity(pxf))
  1777. {
  1778. vConvertXformToMatrix(pxf, &mx);
  1779. if (bWorldMatrixInRange(&mx)) // check if the new world xform is
  1780. { // within the min, max range.
  1781. RtlCopyMemory(&pdc->mxWorldToPage(), &mx, offsetof(MATRIX, flAccel));
  1782. RtlCopyMemory(&pdc->mxUserWorldToPage(), &mx, offsetof(MATRIX, flAccel));
  1783. pdc->vClrWorldXformIdentity();
  1784. bRet = TRUE;
  1785. }
  1786. break;
  1787. }
  1788. //MWT_IDENTITY must follow MWT_SET. This will fall through if it is identity
  1789. case MWT_IDENTITY:
  1790. if (!pdc->bWorldToPageIdentity())
  1791. {
  1792. RtlCopyMemory(&pdc->mxWorldToPage(), &gmxIdentity_LToL, offsetof(MATRIX, flAccel));
  1793. RtlCopyMemory(&pdc->mxUserWorldToPage(), &gmxIdentity_LToL, offsetof(MATRIX, flAccel));
  1794. pdc->vSetWorldXformIdentity();
  1795. }
  1796. bRet = TRUE;
  1797. break;
  1798. case MWT_LEFTMULTIPLY:
  1799. case MWT_RIGHTMULTIPLY:
  1800. vConvertXformToMatrix(pxf,&mx);
  1801. if (!pdc->bWorldToPageIdentity())
  1802. {
  1803. EXFORMOBJ xoWtoP(*this,XFORM_WORLD_TO_PAGE);
  1804. if (!xoWtoP.bMultToWorld(&mx, iMode))
  1805. break;
  1806. }
  1807. if (!bWorldMatrixInRange(&mx)) // check if the new world xform is
  1808. break; // within the min, max range.
  1809. RtlCopyMemory( &pdc->mxWorldToPage(), &mx, offsetof(MATRIX, flAccel));
  1810. RtlCopyMemory( &pdc->mxUserWorldToPage(), &mx, offsetof(MATRIX, flAccel));
  1811. // Check if the resultant matrix is identity.
  1812. if (memcmp(&mx, &gmxIdentity_LToL, offsetof(MATRIX, flAccel)))
  1813. {
  1814. pdc->vClrWorldXformIdentity();
  1815. }
  1816. else
  1817. {
  1818. pdc->vSetWorldXformIdentity();
  1819. }
  1820. bRet = TRUE;
  1821. break;
  1822. default:
  1823. WARNING("invalid mode passed to GreModifyWorldTransform\n");
  1824. break;
  1825. }
  1826. return(bRet);
  1827. }
  1828. /******************************Public*Routine******************************\
  1829. * GreCombineTransform
  1830. *
  1831. * Concatenate two transforms together by (*pxfSrc1) x (*pxfSrc2).
  1832. *
  1833. * History:
  1834. *
  1835. * 6-Aug-1992 -by- Gerrit van Wingerden [gerritv]
  1836. * Modified for client side use.
  1837. *
  1838. * 24-Jan-1992 -by- Wendy Wu [wendywu]
  1839. * Wrote it.
  1840. \**************************************************************************/
  1841. BOOL GreCombineTransform(
  1842. XFORML *pxfDst,
  1843. XFORML *pxfSrc1,
  1844. XFORML *pxfSrc2)
  1845. {
  1846. MATRIX mx1,mx2,mxDst;
  1847. vConvertXformToMatrix(pxfSrc1, &mx1);
  1848. vConvertXformToMatrix(pxfSrc2, &mx2);
  1849. EXFORMOBJ xoDst(mxDst);
  1850. if (!xoDst.bMultiply(&mx1, &mx2))
  1851. return(FALSE);
  1852. xoDst.flAccel(XFORM_FORMAT_LTOL);
  1853. xoDst.vGetCoefficient(pxfDst);
  1854. return(TRUE);
  1855. }
  1856. /******************************Public*Routine******************************\
  1857. * NtGdiUpdateTransform
  1858. *
  1859. * This routine flushes the current transform
  1860. *
  1861. * History:
  1862. * 7/2/98 -by- Lingyun Wang [lingyunw]
  1863. \**************************************************************************/
  1864. BOOL NtGdiUpdateTransform(HDC hdc)
  1865. {
  1866. BOOL bRet = TRUE;
  1867. // update the transforms
  1868. XDCOBJ dco(hdc);
  1869. if (dco.bValid())
  1870. {
  1871. dco.pdc->vUpdateWtoDXform();
  1872. dco.vUnlock();
  1873. }
  1874. else
  1875. {
  1876. bRet = FALSE;
  1877. }
  1878. return (bRet);
  1879. }