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.

262 lines
8.4 KiB

  1. /*****************************************************************************
  2. *
  3. * Preamble - Preamble routines for MF3216
  4. *
  5. * Date: 7/18/91
  6. * Author: Jeffrey Newman (c-jeffn)
  7. *
  8. * Copyright 1991 Microsoft Corp
  9. *****************************************************************************/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. BOOL bSetWindowOrgAndExtToFrame(PLOCALDC pLocalDC, RECTL frame);
  13. extern fnSetVirtualResolution pfnSetVirtualResolution;
  14. BOOL GetFrameBounds(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header, RECTL *frameOut)
  15. {
  16. FLOAT ecxPpmmPlay, // cx pixels per millimeter play
  17. ecyPpmmPlay, // cy pixels per millimeter play
  18. ecx01PpmmPlay, // cx pixels per .01 millimeter play
  19. ecy01PpmmPlay, // cy pixels per .01 millimeter play
  20. ecxPelsFrame, // cx play-time frame in device units
  21. ecyPelsFrame, // cy play-time frame in device units
  22. exPelsFrame, // x play-time frame in device units
  23. eyPelsFrame ; // y play-time frame in device units
  24. INT cxFrame, // cx Picture Frame
  25. cyFrame, // cy Picture Frame
  26. xFrame, // x Picture Frame
  27. yFrame ; // y Picture Frame
  28. SIZEL szlFrame ;
  29. POINTL ptlFrame ;
  30. ASSERT(frameOut != NULL);
  31. // Calculate the play-time (reference) pixels per millimeter.
  32. ecxPpmmPlay = (FLOAT) pLocalDC->cxPlayDevPels / (FLOAT) pLocalDC->cxPlayDevMM ;
  33. ecyPpmmPlay = (FLOAT) pLocalDC->cyPlayDevPels / (FLOAT) pLocalDC->cyPlayDevMM ;
  34. // Scale the pixels per millimeter to pixels per .01 millimeters.
  35. ecx01PpmmPlay = ecxPpmmPlay / 100.0f ;
  36. ecy01PpmmPlay = ecyPpmmPlay / 100.0f ;
  37. // Pickup the fram origin
  38. xFrame = pmf32header->rclFrame.left ;
  39. yFrame = pmf32header->rclFrame.top ;
  40. // Translate the frame origin to play-time-device units.
  41. exPelsFrame = ecx01PpmmPlay * (FLOAT) xFrame ;
  42. eyPelsFrame = ecy01PpmmPlay * (FLOAT) yFrame ;
  43. // Convert the Frame origin to play-time-page units.
  44. // (aka reference-logical units.)
  45. ptlFrame.x = (LONG) (exPelsFrame * pLocalDC->xformPDevToPPage.eM11 + 0.5f);
  46. ptlFrame.y = (LONG) (eyPelsFrame * pLocalDC->xformPDevToPPage.eM22 + 0.5f);
  47. if (!bCoordinateOverflowTest((PLONG) &ptlFrame, 2))
  48. return(FALSE);
  49. // Calculate the Frame width and height.
  50. cxFrame = pmf32header->rclFrame.right - pmf32header->rclFrame.left ;
  51. cyFrame = pmf32header->rclFrame.bottom - pmf32header->rclFrame.top ;
  52. if (cxFrame < 0)
  53. {
  54. ptlFrame.x += cxFrame;
  55. cxFrame = -cxFrame;
  56. }
  57. if (cyFrame < 0)
  58. {
  59. ptlFrame.y += cyFrame;
  60. cyFrame = -cyFrame;
  61. }
  62. // Convert the frame width and height into play-time-device units.
  63. // (aka reference-device units.)
  64. ecxPelsFrame = ecx01PpmmPlay * (FLOAT) cxFrame ;
  65. ecyPelsFrame = ecy01PpmmPlay * (FLOAT) cyFrame ;
  66. // Translate the play-time device units into play-time-page units.
  67. // (aka reference-device to reference-logical units.)
  68. // This is an identity transform for MM_ANISOTROPIC mode. For other
  69. // fixed mapping modes, the SetWindowExt record has no effect.
  70. // The Frame is Inclusive-Inclusive so add 1 to make the WindowExt
  71. // Inclusive-Exclusive
  72. szlFrame.cx = (LONG) (ecxPelsFrame + 1.5f);
  73. szlFrame.cy = (LONG) (ecyPelsFrame + 1.5f);
  74. if (!bCoordinateOverflowTest((PLONG) &szlFrame, 2))
  75. return(FALSE);
  76. frameOut->left = ptlFrame.x;
  77. frameOut->top = ptlFrame.y;
  78. frameOut->right = szlFrame.cx + ptlFrame.x;
  79. frameOut->bottom = szlFrame.cy + ptlFrame.y;
  80. return(TRUE);
  81. }
  82. /*----------------------------------------------------------------------------
  83. * DoHeader - Emit the Win16 metafile header
  84. *---------------------------------------------------------------------------*/
  85. BOOL APIENTRY DoHeader(PLOCALDC pLocalDC, PENHMETAHEADER pemfheader)
  86. {
  87. BOOL b ;
  88. RECTL frameBounds;
  89. b = bInitHandleTableManager(pLocalDC, pemfheader) ;
  90. if (b == FALSE)
  91. goto error_exit ;
  92. b = bInitXformMatrices(pLocalDC, pemfheader, &frameBounds) ;
  93. if (b == FALSE)
  94. goto error_exit ;
  95. if (pfnSetVirtualResolution == NULL)
  96. {
  97. INT swap;
  98. // On Win9x create the helper DC here
  99. pLocalDC->hdcHelper = CreateCompatibleDC (NULL);
  100. if (pLocalDC->hdcHelper == (HDC) 0)
  101. {
  102. return FALSE;
  103. }
  104. pLocalDC->hbmpMem = CreateCompatibleBitmap(pLocalDC->hdcHelper,
  105. frameBounds.right - frameBounds.left,
  106. frameBounds.bottom - frameBounds.top);
  107. if (pLocalDC->hbmpMem == (HBITMAP) 0)
  108. {
  109. return FALSE;
  110. }
  111. SelectObject(pLocalDC->hdcHelper, pLocalDC->hbmpMem);
  112. frameBounds.right -= frameBounds.left;
  113. frameBounds.bottom -= frameBounds.top;
  114. frameBounds.left = frameBounds.top = 0;
  115. }
  116. // The metafile will always be memory based.
  117. pLocalDC->mf16Header.mtType = MEMORYMETAFILE ;
  118. pLocalDC->mf16Header.mtVersion = 0x300 ; // magic number for Win3.0
  119. pLocalDC->mf16Header.mtHeaderSize = sizeof (METAHEADER) / 2 ;
  120. // Init fields to 0. They will be updated at the end of translation.
  121. pLocalDC->mf16Header.mtSize = 0 ;
  122. pLocalDC->mf16Header.mtNoObjects = 0 ;
  123. pLocalDC->mf16Header.mtMaxRecord = 0 ; // NOTE: We need a max record size.
  124. pLocalDC->mf16Header.mtNoParameters = 0 ;
  125. // Emit the MF16 metafile header to the metafile.
  126. b = bEmit(pLocalDC, &pLocalDC->mf16Header, sizeof(METAHEADER)) ;
  127. if (b == FALSE)
  128. goto error_exit ;
  129. if (pLocalDC->flags & INCLUDE_W32MF_COMMENT)
  130. {
  131. b = bHandleWin32Comment(pLocalDC) ;
  132. if (b == FALSE)
  133. goto error_exit ;
  134. }
  135. // Prepare the transform for the 16-bit metafile. See comments in
  136. // xforms.c.
  137. // Emit the Win16 MapMode record
  138. b = bEmitWin16SetMapMode(pLocalDC, LOWORD(pLocalDC->iMapMode)) ;
  139. if (b == FALSE)
  140. goto error_exit ;
  141. // Set the Win16 metafile WindowExt to the size of the frame
  142. // in play-time device units.
  143. b = bSetWindowOrgAndExtToFrame(pLocalDC, frameBounds) ;
  144. if (b == FALSE)
  145. {
  146. RIPS("MF3216: DoHeader, bSetWindowOrgAndExtToFrame failure\n") ;
  147. goto error_exit ;
  148. }
  149. error_exit:
  150. return(b) ;
  151. }
  152. /*----------------------------------------------------------------------------
  153. * Calculate and Emit into the Win16 metafile a Window origin
  154. * and extent drawing order
  155. * that will set the Window Origin and Extent to the size of the picture frame in
  156. * play-time-page (reference-logical) units.
  157. *---------------------------------------------------------------------------*/
  158. BOOL bSetWindowOrgAndExtToFrame(PLOCALDC pLocalDC, RECTL frame)
  159. {
  160. // Set the Window origin.
  161. if (!bEmitWin16SetWindowOrg(pLocalDC,
  162. (SHORT) frame.left,
  163. (SHORT) frame.top))
  164. {
  165. RIPS("MF3216: bEmitWin16SetWindowOrg failed\n") ;
  166. return(FALSE);
  167. }
  168. if (!bEmitWin16SetWindowExt(pLocalDC,
  169. (SHORT) (frame.right - frame.left),
  170. (SHORT) (frame.bottom - frame.top)))
  171. {
  172. RIPS("MF3216: bEmitWin16SetWindowExt failed\n") ;
  173. return(FALSE);
  174. }
  175. return(TRUE);
  176. }
  177. /*----------------------------------------------------------------------------
  178. * UpdateMf16Header - Update the metafile header with the:
  179. * metafile size,
  180. * number of objects,
  181. * the max record size.
  182. *---------------------------------------------------------------------------*/
  183. BOOL bUpdateMf16Header(PLOCALDC pLocalDC)
  184. {
  185. BOOL b ;
  186. INT iCpTemp ;
  187. // Fill in the missing info in the Win16 metafile header.
  188. pLocalDC->mf16Header.mtSize = pLocalDC->ulBytesEmitted / 2 ;
  189. pLocalDC->mf16Header.mtNoObjects = (WORD) (pLocalDC->nObjectHighWaterMark + 1) ;
  190. pLocalDC->mf16Header.mtMaxRecord = pLocalDC->ulMaxRecord ;
  191. // Reset the output buffer index to the beginning of the buffer.
  192. iCpTemp = pLocalDC->ulBytesEmitted ;
  193. pLocalDC->ulBytesEmitted = 0 ;
  194. // re-emit the Win16 metafile header.
  195. b = bEmit(pLocalDC, &pLocalDC->mf16Header, (DWORD) sizeof (pLocalDC->mf16Header)) ;
  196. pLocalDC->ulBytesEmitted = iCpTemp ;
  197. return (b) ;
  198. }