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.

955 lines
32 KiB

  1. /*****************************************************************************
  2. *
  3. * xforms - Entry points for Win32 to Win 16 converter
  4. *
  5. * Date: 7/1/91
  6. * Author: Jeffrey Newman (c-jeffn)
  7. *
  8. * Copyright 1991 Microsoft Corp
  9. *----------------------------------------------------------------------------
  10. *
  11. * September 21, 1991
  12. * Updated [20-Dec-1991]
  13. *
  14. * Transformations in the Win32 to Win16 translator.
  15. *
  16. * We are now supporting coordinate transformations from any
  17. * map mode to any map mode.
  18. *
  19. * Where:
  20. * W is the record-time-world to record-time-device xform.
  21. * (aka metafile-world to metafile-device.)
  22. * D is the record-time device to play-time-device xform.
  23. * (aka metafile-device to reference-device.)
  24. * P is the play-time-device to play-time-page xform.
  25. * (aka reference-device to reference-logical (or page).)
  26. *
  27. * W is the transformation defined by the world xform, map mode, window org,
  28. * window extent, viewport org, and viewport extent in the
  29. * Win32 metafile. This transform is also known as the world to
  30. * device xform.
  31. *
  32. * The normal composite xform is:
  33. *
  34. * W D P
  35. * ^ ^ ^ ^
  36. * | | | +- coordinate recorded in the win16 metafile.
  37. * | | | play-time-page coordinates (aka reference-logical)
  38. * | | +---- play-time-device (reference-device) coordinates.
  39. * | +------ record-time device (metafile-device) coordinates.
  40. * +-------- world coordinates, recorded in Win32 metafile
  41. *
  42. * The following comment is from Hockl's mail about transforms.
  43. *
  44. * Message 11:
  45. * From hockl Thu Dec 19 11:50:54 1991
  46. * To: c-jeffn
  47. * Cc: johnc
  48. * Subject: Transform hints for the 32-16 converter
  49. * Date: Thu Dec 19 11:46:40 1991
  50. *
  51. * Here are some transform hints for the converter:
  52. *
  53. * A. Issue the following records immediately following the 16-bit header
  54. * record:
  55. *
  56. * 1. SetMapMode - use the given mapping mode, it is MM_ANISOTROPIC
  57. * in most cases.
  58. *
  59. * 2. SetWindowOrg - use the upper left coordinates of the rclFrame.
  60. * The coordinates are in the logical units of the reference DC. So
  61. * you have to convert .01mm to the reference device coordinates, then
  62. * to the logical coordinates. You can use the third transform
  63. * defined in B.4 below to convert device coordinates to the logical
  64. * coordinates of the reference device. (Note the conversion formula
  65. * for LPtoDP is defined as Dx = (Lx - xWO) * xVE/xWE + xVO and so on).
  66. * This record is required to translate the converted picture to the
  67. * origin (see comments in GetMetaFileBitsEx).
  68. *
  69. * 3. SetWindowExt - use the extents of the rclFrame.
  70. * xExt = rclFrame.right - rclFrame.left;
  71. * yExt = rclFrame.bottom - rclFrame.top;
  72. * The extents are in the device units of the reference DC. So
  73. * you have to convert .01mm to the reference device units.
  74. *
  75. * These three records should always be generated. Note that
  76. * SetWindowExt has no effect in all fixed mapping modes (e.g.
  77. * MM_LOENGLISH and MM_TEXT) and will have no effect when the converted
  78. * metafile is played.
  79. *
  80. * B. Once you have issued the records, you need to use a xform helper DC
  81. * to convert the coordinates of all drawing orders. To do this, you
  82. * need to do the following:
  83. *
  84. * 1. Create a xform helper DC. This is a display info DC.
  85. *
  86. * 2. Call SetVirtualResolution to set the xform helper DC to that of
  87. * the metafile. Use the metafile header's szlDevice and
  88. * szlMillimeters values to set the resolution. This is to ensure
  89. * that the help DC maps the logical coordinates to the device
  90. * coordinates of the original metafile device. If you reuse this
  91. * helper DC in conversion, make sure you initialize the transforms
  92. * using SetMapMode, ModifyWorldTransform, SetWindowOrgEx and
  93. * SetViewportOrgEx. You can use the same code in the
  94. * CreateMetaFileEx function.
  95. *
  96. * 3. Once you have set up the xform helper DC, you should play all
  97. * 32-bit xform calls into the helper DC. But never emit any
  98. * xform records in the converter. Everytime the xform is changed
  99. * in the helper DC, you need to get the world to device xform
  100. * (xformWDHelper) from the helper DC. The xformWDHelper is used to
  101. * convert the coordinates of the drawing orders subsequently.
  102. * You can get it using the GetTransform(hdcHelper,XFORM_WORLD_TO_DEVICE)
  103. * private API.
  104. *
  105. * 4. To convert drawing order coordinates, you pass them through three
  106. * transforms. The first is the xformWDHelper as computed above. It
  107. * converts all logical coordiates into the device coordinates of
  108. * the original metafile device. Note that this coordinates may
  109. * be different from the conversion's reference device. For example,
  110. * the metafile may be created for a printer but the conversion is
  111. * requested for the display. The second transform therefore scales
  112. * the coordinates from the metafile device to the reference device.
  113. * The scaled coordinates are in MM_TEXT units. So we need the third
  114. * transform to convert the coordinates into the requested mapmode
  115. * units. For MM_TEXT, MM_ANISOTROPIC and MM_ISOTROPIC mapmode, this
  116. * is the identity transform. For the other mapmodes, this is a scale
  117. * transform. The scale transform maps the device units of the
  118. * reference device to the logical units and can be computed using
  119. * szlDevice, szlMillimeters of the reference device (not the metafile
  120. * device!) and some predefined constants (to map millimeter to
  121. * english, for example). Note that in these fixed mapping modes, the
  122. * y-axis goes in the opposite direction. So make sure that the eM22
  123. * component of the third transform is negative. As you can see, the
  124. * second and third transform never change in the duration of the
  125. * conversion. So you can combine them into one to optimize computation
  126. * of the composite transform. The composite transfom makes up of the
  127. * three transforms and is used to convert drawing order coordinates
  128. * into coordinates for the converted metafile.
  129. *
  130. * C. To display a converted metafile in Windows 3.0, do the following before
  131. * calling PlayMetaFile:
  132. *
  133. * 1. If the mapmode is MM_ANISOTROPIC, which is 99.9% of the time, call
  134. * SetMapMode(MM_ANISOTROPIC), SetViewportOrigin and SetViewportExt.
  135. * The viewport origin defines the upper left corner of the display area
  136. * and the viewport origin defines the extent of the display area. Both
  137. * are in device units.
  138. *
  139. * 2. If the mapmode is MM_ISOTROPIC, which is strange, call
  140. * SetMapMode(MM_ISOTROPIC), SetViewportOrigin and SetViewportExt.
  141. * This is almost the same as C.1 above.
  142. *
  143. * 3. If the mapmode is others, the metafile has a fixed physical size
  144. * and cannot be scaled easily without a lot of heck in the application.
  145. * Call SetViewportOrigin to define the upper left corner of the display
  146. * area. The origin is in device coordinates.
  147. *
  148. * I hope these steps are clear. If you have any questions, feel free to
  149. * give me a call.
  150. *
  151. * HockL
  152. *
  153. *
  154. *
  155. ******************************************************************************/
  156. #include "precomp.h"
  157. #pragma hdrstop
  158. BOOL WINAPI GetTransform(HDC hdc,DWORD iXform,LPXFORM pxform);
  159. BOOL WINAPI SetVirtualResolution(HDC hdc,
  160. int cxDevice,
  161. int cyDevice,
  162. int cxMillimeters,
  163. int cyMillimeters);
  164. BOOL bComputeCompositeXform(PLOCALDC pLocalDC) ;
  165. VOID vInitRecDevToPlayDevXform(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header) ;
  166. /*
  167. [19-Dec-1991]
  168. A note about transformations.
  169. We will map into any map mode (when the converter is complete).
  170. We will use a helper DC to compute our transformation matrices.
  171. All the Win32 APIs that effect transformations or map modes
  172. will be sent to a helper DC. The helper DC will return a transform
  173. matrix that converts from World Coordinates to Device Coordinates.
  174. This transformation matrix is: xformRWorldToRDev.
  175. xformRWorldToRDev is combined with the xformRDevToPPage matrix to produce
  176. the xformRWorldToPPage matrix. All coordinates are mapped through the
  177. xformRWorldToPPage matrix.
  178. */
  179. XFORM xformIdentity = {(FLOAT) 1.0,
  180. (FLOAT) 0.0,
  181. (FLOAT) 0.0,
  182. (FLOAT) 1.0,
  183. (FLOAT) 0.0,
  184. (FLOAT) 0.0 } ;
  185. /****************************************************************************
  186. * Initialize all the matrices.
  187. ****************************************************************************/
  188. // Units per millimeter array. It must be in the order of MM_LOMETRIC,
  189. // MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS.
  190. FLOAT aeUnitsPerMM[5] = { 10.0f, 100.0f, 3.937f, 39.37f, 56.6928f };
  191. BOOL bInitXformMatrices(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header)
  192. {
  193. // Init xformRDevToPDev.
  194. vInitRecDevToPlayDevXform(pLocalDC, pmf32header) ;
  195. // Init xformPDevToPPage and xformPPageToPDev.
  196. // (aka reference-device to reference-logical) transform.
  197. switch(pLocalDC->iMapMode)
  198. {
  199. case MM_TEXT:
  200. case MM_ANISOTROPIC:
  201. case MM_ISOTROPIC:
  202. pLocalDC->xformPDevToPPage = xformIdentity ;
  203. pLocalDC->xformPPageToPDev = xformIdentity ;
  204. break ;
  205. case MM_LOMETRIC:
  206. case MM_HIMETRIC:
  207. case MM_LOENGLISH:
  208. case MM_HIENGLISH:
  209. case MM_TWIPS:
  210. {
  211. FLOAT exUnitsPerPel;
  212. FLOAT eyUnitsPerPel;
  213. // Compute units per pixel.
  214. exUnitsPerPel = (FLOAT) pLocalDC->cxPlayDevMM
  215. / (FLOAT) pLocalDC->cxPlayDevPels
  216. * aeUnitsPerMM[pLocalDC->iMapMode - MM_LOMETRIC];
  217. eyUnitsPerPel = (FLOAT) pLocalDC->cyPlayDevMM
  218. / (FLOAT) pLocalDC->cyPlayDevPels
  219. * aeUnitsPerMM[pLocalDC->iMapMode - MM_LOMETRIC];
  220. pLocalDC->xformPDevToPPage.eM11 = exUnitsPerPel;
  221. pLocalDC->xformPDevToPPage.eM12 = 0.0f;
  222. pLocalDC->xformPDevToPPage.eM21 = 0.0f;
  223. pLocalDC->xformPDevToPPage.eM22 = -eyUnitsPerPel;
  224. pLocalDC->xformPDevToPPage.eDx = 0.0f;
  225. pLocalDC->xformPDevToPPage.eDy = 0.0f;
  226. pLocalDC->xformPPageToPDev.eM11 = 1.0f / exUnitsPerPel;
  227. pLocalDC->xformPPageToPDev.eM12 = 0.0f;
  228. pLocalDC->xformPPageToPDev.eM21 = 0.0f;
  229. pLocalDC->xformPPageToPDev.eM22 = -1.0f / eyUnitsPerPel;
  230. pLocalDC->xformPPageToPDev.eDx = 0.0f;
  231. pLocalDC->xformPPageToPDev.eDy = 0.0f;
  232. }
  233. break ;
  234. }
  235. // Init xformRDevToPPage.
  236. // This xform is used in the SelectClipRegion code.
  237. if (!CombineTransform(&pLocalDC->xformRDevToPPage,
  238. &pLocalDC->xformRDevToPDev,
  239. &pLocalDC->xformPDevToPPage))
  240. {
  241. RIP("MF3216: InitXformMatrices, CombineTransform failed\n");
  242. return(FALSE);
  243. }
  244. // We are going to use the helper DC to compute the
  245. // Record-time-World to Record-time-Device transform.
  246. // Set the Helper DC virtual resolution to the Metafiles
  247. // resolution.
  248. if (!SetVirtualResolution(pLocalDC->hdcHelper,
  249. (INT) pmf32header->szlDevice.cx,
  250. (INT) pmf32header->szlDevice.cy,
  251. (INT) pmf32header->szlMillimeters.cx,
  252. (INT) pmf32header->szlMillimeters.cy))
  253. {
  254. RIP("MF3216: InitXformMatrices, SetVirtualResolution failed \n") ;
  255. return(FALSE);
  256. }
  257. // Init other matrices.
  258. return(bComputeCompositeXform(pLocalDC));
  259. }
  260. /****************************************************************************
  261. * Initialize the Record-time to Play-time scalers. (xformRDevToPDev)
  262. ****************************************************************************/
  263. VOID vInitRecDevToPlayDevXform(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header)
  264. {
  265. FLOAT ecxRecDevPels,
  266. ecyRecDevPels,
  267. ecxRecDevMM,
  268. ecyRecDevMM,
  269. ecxPlayDevPels,
  270. ecyPlayDevPels,
  271. ecxPlayDevMM,
  272. ecyPlayDevMM,
  273. exMillsPerPelRec,
  274. eyMillsPerPelRec,
  275. exMillsPerPelPlay,
  276. eyMillsPerPelPlay ;
  277. // Pickup the physical dimensions of the record-time
  278. // device, both in pels and millimeters.
  279. // Converts them to floats
  280. ecxRecDevPels = (FLOAT) pmf32header->szlDevice.cx ;
  281. ecyRecDevPels = (FLOAT) pmf32header->szlDevice.cy ;
  282. ecxRecDevMM = (FLOAT) pmf32header->szlMillimeters.cx ;
  283. ecyRecDevMM = (FLOAT) pmf32header->szlMillimeters.cy ;
  284. // convert the Play-time device dimensions to floats.
  285. ecxPlayDevPels = (FLOAT) pLocalDC->cxPlayDevPels ;
  286. ecyPlayDevPels = (FLOAT) pLocalDC->cyPlayDevPels ;
  287. ecxPlayDevMM = (FLOAT) pLocalDC->cxPlayDevMM ;
  288. ecyPlayDevMM = (FLOAT) pLocalDC->cyPlayDevMM ;
  289. // Calucalte the pels per millimeter for both the record-time
  290. // and play-time devices.
  291. exMillsPerPelRec = ecxRecDevMM / ecxRecDevPels ;
  292. eyMillsPerPelRec = ecyRecDevMM / ecyRecDevPels ;
  293. exMillsPerPelPlay = ecxPlayDevMM / ecxPlayDevPels ;
  294. eyMillsPerPelPlay = ecyPlayDevMM / ecyPlayDevPels ;
  295. // Init the Record-time-device to the Play-time-device transform.
  296. // aka the Metafile-device to the Reference-device transform.
  297. pLocalDC->xformRDevToPDev.eM11 = exMillsPerPelRec / exMillsPerPelPlay ;
  298. pLocalDC->xformRDevToPDev.eM12 = (FLOAT) 0.0 ;
  299. pLocalDC->xformRDevToPDev.eDx = (FLOAT) 0.0 ;
  300. pLocalDC->xformRDevToPDev.eM21 = (FLOAT) 0.0 ;
  301. pLocalDC->xformRDevToPDev.eM22 = eyMillsPerPelRec / eyMillsPerPelPlay ;
  302. pLocalDC->xformRDevToPDev.eDy = (FLOAT) 0.0 ;
  303. return;
  304. }
  305. #if 0
  306. /***************************************************************************
  307. * vInvertMatrix - Invert a matrix
  308. **************************************************************************/
  309. VOID vInvertMatrix(PXFORM pxformSrc, PINVERSMATRIX pinvxfm)
  310. {
  311. FLOAT eM11, eM12, eM21, eM22, eDx, eDy,
  312. detA ;
  313. // dereference the matrix elements, just to make the rest of this
  314. // routine more readable.
  315. eM11 = pxformSrc->eM11 ;
  316. eM12 = pxformSrc->eM12 ;
  317. eM21 = pxformSrc->eM21 ;
  318. eM22 = pxformSrc->eM22 ;
  319. eDx = pxformSrc->eDx ;
  320. eDy = pxformSrc->eDy ;
  321. // First determine the determinant of the source matrix.
  322. detA = (eM11 * eM22) - (eM11 * eDy) ;
  323. pinvxfm->a1 = eM22 / detA ;
  324. pinvxfm->a2 = -(eM21 / detA) ;
  325. pinvxfm->a3 = ((eM21 * eDy) - (eDx * eM22)) / detA ;
  326. pinvxfm->b1 = -(eM12 / detA) ;
  327. pinvxfm->b2 = eM11 / detA ;
  328. pinvxfm->b3 = -(((eM11 * eDy) - (eDx * eM12)) / detA) ;
  329. pinvxfm->c1 = (FLOAT) 0.0 ;
  330. pinvxfm->c2 = (FLOAT) 0.0 ;
  331. pinvxfm->c3 = ((eM11 * eM22) - (eM21 * eM12)) / detA ;
  332. // This is just for testing.
  333. pinvxfm->a1 = pxformSrc->eM11 ;
  334. pinvxfm->a2 = pxformSrc->eM12 ;
  335. pinvxfm->a3 = (FLOAT) 0.0 ;
  336. pinvxfm->b1 = pxformSrc->eM21 ;
  337. pinvxfm->b2 = pxformSrc->eM22 ;
  338. pinvxfm->b3 = (FLOAT) 0.0 ;
  339. pinvxfm->c1 = pxformSrc->eDx ;
  340. pinvxfm->c2 = pxformSrc->eDy ;
  341. pinvxfm->c3 = (FLOAT) 1.0 ;
  342. return ;
  343. }
  344. #endif // 0
  345. /***************************************************************************
  346. * XformPDevToPPage - Do a transform on the array of points passed in.
  347. *
  348. * This does the play-time (reference) device to
  349. * play-time (reference) page (logical) transformation.
  350. **************************************************************************/
  351. BOOL bXformPDevToPPage(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
  352. {
  353. BOOL b ;
  354. b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformPDevToPPage) ;
  355. return (b) ;
  356. }
  357. /***************************************************************************
  358. * XformPPageToPDev - Do a transform on the array of points passed in.
  359. *
  360. * This does the play-time (reference) page (logical) to
  361. * play-time (reference) device transformation.
  362. **************************************************************************/
  363. BOOL bXformPPageToPDev(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
  364. {
  365. BOOL b ;
  366. b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformPPageToPDev) ;
  367. return (b) ;
  368. }
  369. /***************************************************************************
  370. * XformRWorldToRDev - Do a transform on the array of points passed in.
  371. *
  372. * This does the Record-time (metafile) world to
  373. * record-time device translation.
  374. **************************************************************************/
  375. BOOL bXformRWorldToRDev(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
  376. {
  377. BOOL b ;
  378. b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRWorldToRDev) ;
  379. return (b) ;
  380. }
  381. /***************************************************************************
  382. * XformRDevToRWorld - Do a transform on the array of points passed in.
  383. *
  384. * This does the Record-device (metafile) world to
  385. * record-time world translation.
  386. **************************************************************************/
  387. BOOL bXformRDevToRWorld(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
  388. {
  389. BOOL b ;
  390. b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRDevToRWorld) ;
  391. return (b) ;
  392. }
  393. /***************************************************************************
  394. * XformRWorldToPPage - Do a transform on the array of points passed in.
  395. *
  396. * This is the workhorse translation routine.
  397. * This translates from record-time-world (aka metafile-world)
  398. * to record-time-device (aka metafile-device) then from
  399. * record-time-device (aka metafile-device) to play-time-device
  400. * (aka reference-device) then from play-time-device
  401. * (aka reference-device) to play-time-page (reference-logical)
  402. * space.
  403. **************************************************************************/
  404. BOOL bXformRWorldToPPage(PLOCALDC pLocalDC, PPOINTL aptl, DWORD nCount)
  405. {
  406. BOOL b ;
  407. b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRWorldToPPage) ;
  408. return (b) ;
  409. }
  410. /***************************************************************************
  411. * bXformWorkhorse - Transformation Workhorse.
  412. **************************************************************************/
  413. BOOL bXformWorkhorse(PPOINTL aptl, DWORD nCount, PXFORM pXform)
  414. {
  415. INT i ;
  416. FLOAT x, y ;
  417. BOOL b ;
  418. FLOAT fx, fy;
  419. for (i = 0 ; i < (INT) nCount ; i++)
  420. {
  421. x = (FLOAT) aptl[i].x ;
  422. y = (FLOAT) aptl[i].y ;
  423. fx = (x * pXform->eM11 + y * pXform->eM21 + pXform->eDx) ;
  424. fy = (x * pXform->eM12 + y * pXform->eM22 + pXform->eDy) ;
  425. aptl[i].x = (LONG) (fx + ((fx < 0.0) ? -0.5f : 0.5f)) ;
  426. aptl[i].y = (LONG) (fy + ((fy < 0.0) ? -0.5f : 0.5f)) ;
  427. }
  428. // Do the coordinate overflow detection.
  429. b = bCoordinateOverflowTest((PLONG) aptl, nCount * 2) ;
  430. return (b) ;
  431. }
  432. /***************************************************************************
  433. * vXformWorkhorseFloat - Transformation Workhorse.
  434. **************************************************************************/
  435. VOID vXformWorkhorseFloat(PPOINTFL aptfl, UINT nCount, PXFORM pXform)
  436. {
  437. UINT i ;
  438. FLOAT x, y ;
  439. for (i = 0 ; i < nCount ; i++)
  440. {
  441. x = aptfl[i].x ;
  442. y = aptfl[i].y ;
  443. aptfl[i].x = x * pXform->eM11 + y * pXform->eM21 + pXform->eDx;
  444. aptfl[i].y = x * pXform->eM12 + y * pXform->eM22 + pXform->eDy;
  445. }
  446. }
  447. /*****************************************************************************
  448. * iMagnitudeXform - Transform the magnitude of a number from
  449. * Record-time-World to Play-time-Page coordinate space.
  450. *****************************************************************************/
  451. INT iMagnitudeXform (PLOCALDC pLocalDC, INT value, INT iType)
  452. {
  453. PXFORM pxform ;
  454. INT iRet ;
  455. pxform = &(pLocalDC->xformRWorldToPPage) ;
  456. iRet = iMagXformWorkhorse (value, pxform, iType) ;
  457. return (iRet) ;
  458. }
  459. /*****************************************************************************
  460. * iMagXformWorkhorse - get the magnitude component of a translated vector
  461. *****************************************************************************/
  462. INT iMagXformWorkhorse (INT value, PXFORM pxform, INT iType)
  463. {
  464. POINTFL aptfl[2] ;
  465. FLOAT x1, y1, x2, y2;
  466. double emag ;
  467. // Create a vector, from (0,0) to the point.
  468. aptfl[0].x = 0.0f ;
  469. aptfl[0].y = 0.0f ;
  470. if (iType == CX_MAG)
  471. {
  472. aptfl[1].x = (FLOAT) value ;
  473. aptfl[1].y = 0.0f ;
  474. }
  475. else
  476. {
  477. aptfl[1].x = 0.0f ;
  478. aptfl[1].y = (FLOAT) value ;
  479. }
  480. vXformWorkhorseFloat(aptfl, 2, pxform);
  481. // Now get the magnitude
  482. x1 = aptfl[0].x ;
  483. y1 = aptfl[0].y ;
  484. x2 = aptfl[1].x ;
  485. y2 = aptfl[1].y ;
  486. emag = sqrt((double) ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) ;
  487. return((INT) (emag + (double) 0.5f));
  488. }
  489. /*****************************************************************************
  490. * bRotationTest -
  491. * return - TRUE if there is a rotation or shear in this xform
  492. * FALSE if there is none.
  493. *****************************************************************************/
  494. BOOL bRotationTest(PXFORM pxform)
  495. {
  496. BOOL b ;
  497. if ( (pxform->eM12 != (FLOAT) 0.0)
  498. || (pxform->eM21 != (FLOAT) 0.0)
  499. )
  500. {
  501. b = TRUE ;
  502. }
  503. else
  504. {
  505. b = FALSE ;
  506. }
  507. return(b) ;
  508. }
  509. /***************************************************************************
  510. * SetMapMode - Win32 to Win16 Metafile Converter Entry Point
  511. *
  512. * All the map mode translations are done by the helper DC.
  513. * The Helper DC always transforms to device, then we combine the
  514. * MetafileWorldToDevice with the DeviceToPage transform.
  515. * This becomes the Win32 to Win16 transform.
  516. *
  517. * Some of the metafiles converted from Win16 to Win32 do not
  518. * define a Viewport extent. Since the Isotropic and AnIsotropic
  519. * map modes are undefined if either the Viewport Extent or the Window
  520. * Extent are undefined we will default the Viewport extent to the
  521. * device extent in the Win32 metafile header.
  522. **************************************************************************/
  523. BOOL WINAPI DoSetMapMode
  524. (
  525. PLOCALDC pLocalDC,
  526. DWORD ulMapMode
  527. )
  528. {
  529. BOOL b ;
  530. if (!SetMapMode(pLocalDC->hdcHelper, ulMapMode))
  531. {
  532. ASSERTGDI(FALSE, "MF3216: DoSetMapMode failed\n");
  533. return(FALSE);
  534. }
  535. b = bComputeCompositeXform(pLocalDC) ;
  536. return (b) ;
  537. }
  538. /***************************************************************************
  539. * ScaleWindowsExtEx - Win32 to Win16 Metafile Converter Entry Point
  540. **************************************************************************/
  541. BOOL WINAPI DoScaleWindowExt
  542. (
  543. PLOCALDC pLocalDC,
  544. INT Xnum,
  545. INT Xdenom,
  546. INT Ynum,
  547. INT Ydenom
  548. )
  549. {
  550. BOOL b ;
  551. // Set the Windows extent
  552. if (!ScaleWindowExtEx(pLocalDC->hdcHelper,
  553. Xnum, Xdenom,
  554. Ynum, Ydenom,
  555. (LPSIZE) 0))
  556. {
  557. ASSERTGDI(FALSE, "MF3216: DoScaleWindowExt failed\n");
  558. return(FALSE);
  559. }
  560. b = bComputeCompositeXform(pLocalDC) ;
  561. return (b) ;
  562. }
  563. /***************************************************************************
  564. * ScaleViewportExtEx - Win32 to Win16 Metafile Converter Entry Point
  565. **************************************************************************/
  566. BOOL WINAPI DoScaleViewportExt
  567. (
  568. PLOCALDC pLocalDC,
  569. INT Xnum,
  570. INT Xdenom,
  571. INT Ynum,
  572. INT Ydenom
  573. )
  574. {
  575. BOOL b ;
  576. // Set the viewport extent
  577. if (!ScaleViewportExtEx(pLocalDC->hdcHelper,
  578. Xnum, Xdenom,
  579. Ynum, Ydenom,
  580. (LPSIZE) 0))
  581. {
  582. ASSERTGDI(FALSE, "MF3216: DoScaleViewportExt failed\n");
  583. return(FALSE);
  584. }
  585. b = bComputeCompositeXform(pLocalDC) ;
  586. return (b) ;
  587. }
  588. /***************************************************************************
  589. * SetViewportExtEx - Win32 to Win16 Metafile Converter Entry Point
  590. **************************************************************************/
  591. BOOL WINAPI DoSetViewportExt
  592. (
  593. PLOCALDC pLocalDC,
  594. int x,
  595. int y
  596. )
  597. {
  598. BOOL b ;
  599. // Set the viewport extent
  600. if (!SetViewportExtEx(pLocalDC->hdcHelper, x, y, (LPSIZE) 0))
  601. {
  602. ASSERTGDI(FALSE, "MF3216: DoSetViewportExt failed\n");
  603. return(FALSE);
  604. }
  605. b = bComputeCompositeXform(pLocalDC) ;
  606. return (b) ;
  607. }
  608. /***************************************************************************
  609. * SetViewportOrgEx - Win32 to Win16 Metafile Converter Entry Point
  610. **************************************************************************/
  611. BOOL WINAPI DoSetViewportOrg
  612. (
  613. PLOCALDC pLocalDC,
  614. int x,
  615. int y
  616. )
  617. {
  618. BOOL b ;
  619. // Set the viewport origin
  620. if (!SetViewportOrgEx(pLocalDC->hdcHelper, x, y, (LPPOINT) 0))
  621. {
  622. ASSERTGDI(FALSE, "MF3216: DoSetViewportOrg failed\n");
  623. return(FALSE);
  624. }
  625. b = bComputeCompositeXform(pLocalDC) ;
  626. return (b) ;
  627. }
  628. /***************************************************************************
  629. * SetWindowExtEx - Win32 to Win16 Metafile Converter Entry Point
  630. **************************************************************************/
  631. BOOL WINAPI DoSetWindowExt
  632. (
  633. PLOCALDC pLocalDC,
  634. int x,
  635. int y
  636. )
  637. {
  638. BOOL b ;
  639. // Set the window extent
  640. if (!SetWindowExtEx(pLocalDC->hdcHelper, x, y, (LPSIZE) 0))
  641. {
  642. ASSERTGDI(FALSE, "MF3216: DoSetWindowExt failed\n");
  643. return(FALSE);
  644. }
  645. b = bComputeCompositeXform(pLocalDC) ;
  646. return (b) ;
  647. }
  648. /***************************************************************************
  649. * SetWindowOrgEx - Win32 to Win16 Metafile Converter Entry Point
  650. *
  651. * Since we will always record TWIPS in the Win16 metafile,
  652. * we will transform the WindowOrg from the current MapMode to
  653. * TWIPS. Then we will set the Dx and Dy elements of the Viewport
  654. * transformation matrix.
  655. *
  656. **************************************************************************/
  657. BOOL WINAPI DoSetWindowOrg
  658. (
  659. PLOCALDC pLocalDC,
  660. int x,
  661. int y
  662. )
  663. {
  664. BOOL b ;
  665. // Set the window origin
  666. if (!SetWindowOrgEx(pLocalDC->hdcHelper, x, y, (LPPOINT) 0))
  667. {
  668. ASSERTGDI(FALSE, "MF3216: DoSetWindowOrg failed\n");
  669. return(FALSE);
  670. }
  671. b = bComputeCompositeXform(pLocalDC) ;
  672. return (b) ;
  673. }
  674. /***************************************************************************
  675. * SetWorldTransform - Win32 to Win16 Metafile Converter Entry Point
  676. **************************************************************************/
  677. BOOL WINAPI DoSetWorldTransform
  678. (
  679. PLOCALDC pLocalDC,
  680. PXFORM pxf
  681. )
  682. {
  683. BOOL b ;
  684. // Set the world xform in the helper DC.
  685. if (!SetWorldTransform(pLocalDC->hdcHelper, pxf))
  686. {
  687. ASSERTGDI(FALSE, "MF3216: DoSetWorldTransform failed\n");
  688. return(FALSE);
  689. }
  690. b = bComputeCompositeXform(pLocalDC) ;
  691. return (b) ;
  692. }
  693. /***************************************************************************
  694. * ModifyWorldTransform - Win32 to Win16 Metafile Converter Entry Point
  695. **************************************************************************/
  696. BOOL WINAPI DoModifyWorldTransform
  697. (
  698. PLOCALDC pLocalDC,
  699. PXFORM pxf,
  700. DWORD imode
  701. )
  702. {
  703. BOOL b ;
  704. // Set the world xform in the helper DC.
  705. if (!ModifyWorldTransform(pLocalDC->hdcHelper, pxf, imode))
  706. {
  707. ASSERTGDI(FALSE, "MF3216: DoModifyWorldTransform failed\n");
  708. return(FALSE);
  709. }
  710. b = bComputeCompositeXform(pLocalDC) ;
  711. return (b) ;
  712. }
  713. /****************************************************************************
  714. * bComputeCompositeXform - Compute the composite Xforms.
  715. *
  716. * The following transforms are re-computed:
  717. *
  718. * xformRWorldToRDev
  719. * xformRDevToRWorld
  720. * xformRWorldToPPage
  721. *
  722. ****************************************************************************/
  723. BOOL bComputeCompositeXform(PLOCALDC pLocalDC)
  724. {
  725. BOOL b ;
  726. // Recompute xformRWorldToRDev.
  727. // Get the record-time world to record-time device xform
  728. // from the helper DC
  729. b = GetTransform(pLocalDC->hdcHelper,
  730. XFORM_WORLD_TO_DEVICE,
  731. &pLocalDC->xformRWorldToRDev) ;
  732. if (b == FALSE)
  733. {
  734. RIP("MF3216: bComputeCompositeXform - GetTransform (RWorld to RDev) failed \n") ;
  735. goto error_exit ;
  736. }
  737. // Recompute xformRDevToRWorld.
  738. // Get the record-time-device to record-time-world xform
  739. b = GetTransform(pLocalDC->hdcHelper,
  740. XFORM_DEVICE_TO_WORLD,
  741. &pLocalDC->xformRDevToRWorld) ;
  742. if (b == FALSE)
  743. {
  744. RIP("MF3216: bComputeCompositeXform - GetTransform (RDev To RWorld) failed \n") ;
  745. goto error_exit ;
  746. }
  747. // Recompute xformRWorldToPPage.
  748. b = CombineTransform(&pLocalDC->xformRWorldToPPage,
  749. &pLocalDC->xformRWorldToRDev,
  750. &pLocalDC->xformRDevToPPage);
  751. if (b == FALSE)
  752. {
  753. RIP("MF3216: bComputeCompositeXform - CombineTransform failed\n");
  754. goto error_exit ;
  755. }
  756. // Recompute transform flags.
  757. if (pLocalDC->xformRWorldToRDev.eM12 != (FLOAT) 0.0
  758. || pLocalDC->xformRWorldToRDev.eM21 != (FLOAT) 0.0)
  759. pLocalDC->flags |= STRANGE_XFORM ;
  760. else
  761. pLocalDC->flags &= ~STRANGE_XFORM ;
  762. error_exit:
  763. return(b) ;
  764. }
  765. /***************************************************************************
  766. * bCoordinateOverflowTest - Test for 1 16 bit coordinate overflow
  767. *
  768. * RETURNS: FALSE if there is a coordinate overflow
  769. * TRUE if there is no overflow.
  770. **************************************************************************/
  771. BOOL bCoordinateOverflowTest(PLONG pCoordinates, INT nCount)
  772. {
  773. BOOL b ;
  774. INT i, j ;
  775. b = TRUE ;
  776. for (i = 0 ; i < nCount ; i++)
  777. {
  778. j = pCoordinates[i] ;
  779. if (j < -32768 || j > 32767)
  780. {
  781. b = FALSE ;
  782. SetLastError(ERROR_ARITHMETIC_OVERFLOW);
  783. RIP("MF3216: bCoordinateOverflowTest, coordinate overflow\n") ;
  784. break ;
  785. }
  786. }
  787. return(b) ;
  788. }