/***************************************************************************** * * Preamble - Preamble routines for MF3216 * * Date: 7/18/91 * Author: Jeffrey Newman (c-jeffn) * * Copyright 1991 Microsoft Corp *****************************************************************************/ #include "precomp.h" #pragma hdrstop BOOL bSetWindowOrgAndExtToFrame(PLOCALDC pLocalDC, RECTL frame); extern fnSetVirtualResolution pfnSetVirtualResolution; BOOL GetFrameBounds(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header, RECTL *frameOut) { FLOAT ecxPpmmPlay, // cx pixels per millimeter play ecyPpmmPlay, // cy pixels per millimeter play ecx01PpmmPlay, // cx pixels per .01 millimeter play ecy01PpmmPlay, // cy pixels per .01 millimeter play ecxPelsFrame, // cx play-time frame in device units ecyPelsFrame, // cy play-time frame in device units exPelsFrame, // x play-time frame in device units eyPelsFrame ; // y play-time frame in device units INT cxFrame, // cx Picture Frame cyFrame, // cy Picture Frame xFrame, // x Picture Frame yFrame ; // y Picture Frame SIZEL szlFrame ; POINTL ptlFrame ; ASSERT(frameOut != NULL); // Calculate the play-time (reference) pixels per millimeter. ecxPpmmPlay = (FLOAT) pLocalDC->cxPlayDevPels / (FLOAT) pLocalDC->cxPlayDevMM ; ecyPpmmPlay = (FLOAT) pLocalDC->cyPlayDevPels / (FLOAT) pLocalDC->cyPlayDevMM ; // Scale the pixels per millimeter to pixels per .01 millimeters. ecx01PpmmPlay = ecxPpmmPlay / 100.0f ; ecy01PpmmPlay = ecyPpmmPlay / 100.0f ; // Pickup the fram origin xFrame = pmf32header->rclFrame.left ; yFrame = pmf32header->rclFrame.top ; // Translate the frame origin to play-time-device units. exPelsFrame = ecx01PpmmPlay * (FLOAT) xFrame ; eyPelsFrame = ecy01PpmmPlay * (FLOAT) yFrame ; // Convert the Frame origin to play-time-page units. // (aka reference-logical units.) ptlFrame.x = (LONG) (exPelsFrame * pLocalDC->xformPDevToPPage.eM11 + 0.5f); ptlFrame.y = (LONG) (eyPelsFrame * pLocalDC->xformPDevToPPage.eM22 + 0.5f); if (!bCoordinateOverflowTest((PLONG) &ptlFrame, 2)) return(FALSE); // Calculate the Frame width and height. cxFrame = pmf32header->rclFrame.right - pmf32header->rclFrame.left ; cyFrame = pmf32header->rclFrame.bottom - pmf32header->rclFrame.top ; if (cxFrame < 0) { ptlFrame.x += cxFrame; cxFrame = -cxFrame; } if (cyFrame < 0) { ptlFrame.y += cyFrame; cyFrame = -cyFrame; } // Convert the frame width and height into play-time-device units. // (aka reference-device units.) ecxPelsFrame = ecx01PpmmPlay * (FLOAT) cxFrame ; ecyPelsFrame = ecy01PpmmPlay * (FLOAT) cyFrame ; // Translate the play-time device units into play-time-page units. // (aka reference-device to reference-logical units.) // This is an identity transform for MM_ANISOTROPIC mode. For other // fixed mapping modes, the SetWindowExt record has no effect. // The Frame is Inclusive-Inclusive so add 1 to make the WindowExt // Inclusive-Exclusive szlFrame.cx = (LONG) (ecxPelsFrame + 1.5f); szlFrame.cy = (LONG) (ecyPelsFrame + 1.5f); if (!bCoordinateOverflowTest((PLONG) &szlFrame, 2)) return(FALSE); frameOut->left = ptlFrame.x; frameOut->top = ptlFrame.y; frameOut->right = szlFrame.cx + ptlFrame.x; frameOut->bottom = szlFrame.cy + ptlFrame.y; return(TRUE); } /*---------------------------------------------------------------------------- * DoHeader - Emit the Win16 metafile header *---------------------------------------------------------------------------*/ BOOL APIENTRY DoHeader(PLOCALDC pLocalDC, PENHMETAHEADER pemfheader) { BOOL b ; RECTL frameBounds; b = bInitHandleTableManager(pLocalDC, pemfheader) ; if (b == FALSE) goto error_exit ; b = bInitXformMatrices(pLocalDC, pemfheader, &frameBounds) ; if (b == FALSE) goto error_exit ; if (pfnSetVirtualResolution == NULL) { INT swap; // On Win9x create the helper DC here pLocalDC->hdcHelper = CreateCompatibleDC (NULL); if (pLocalDC->hdcHelper == (HDC) 0) { return FALSE; } pLocalDC->hbmpMem = CreateCompatibleBitmap(pLocalDC->hdcHelper, frameBounds.right - frameBounds.left, frameBounds.bottom - frameBounds.top); if (pLocalDC->hbmpMem == (HBITMAP) 0) { return FALSE; } SelectObject(pLocalDC->hdcHelper, pLocalDC->hbmpMem); frameBounds.right -= frameBounds.left; frameBounds.bottom -= frameBounds.top; frameBounds.left = frameBounds.top = 0; } // The metafile will always be memory based. pLocalDC->mf16Header.mtType = MEMORYMETAFILE ; pLocalDC->mf16Header.mtVersion = 0x300 ; // magic number for Win3.0 pLocalDC->mf16Header.mtHeaderSize = sizeof (METAHEADER) / 2 ; // Init fields to 0. They will be updated at the end of translation. pLocalDC->mf16Header.mtSize = 0 ; pLocalDC->mf16Header.mtNoObjects = 0 ; pLocalDC->mf16Header.mtMaxRecord = 0 ; // NOTE: We need a max record size. pLocalDC->mf16Header.mtNoParameters = 0 ; // Emit the MF16 metafile header to the metafile. b = bEmit(pLocalDC, &pLocalDC->mf16Header, sizeof(METAHEADER)) ; if (b == FALSE) goto error_exit ; if (pLocalDC->flags & INCLUDE_W32MF_COMMENT) { b = bHandleWin32Comment(pLocalDC) ; if (b == FALSE) goto error_exit ; } // Prepare the transform for the 16-bit metafile. See comments in // xforms.c. // Emit the Win16 MapMode record b = bEmitWin16SetMapMode(pLocalDC, LOWORD(pLocalDC->iMapMode)) ; if (b == FALSE) goto error_exit ; // Set the Win16 metafile WindowExt to the size of the frame // in play-time device units. b = bSetWindowOrgAndExtToFrame(pLocalDC, frameBounds) ; if (b == FALSE) { RIPS("MF3216: DoHeader, bSetWindowOrgAndExtToFrame failure\n") ; goto error_exit ; } error_exit: return(b) ; } /*---------------------------------------------------------------------------- * Calculate and Emit into the Win16 metafile a Window origin * and extent drawing order * that will set the Window Origin and Extent to the size of the picture frame in * play-time-page (reference-logical) units. *---------------------------------------------------------------------------*/ BOOL bSetWindowOrgAndExtToFrame(PLOCALDC pLocalDC, RECTL frame) { // Set the Window origin. if (!bEmitWin16SetWindowOrg(pLocalDC, (SHORT) frame.left, (SHORT) frame.top)) { RIPS("MF3216: bEmitWin16SetWindowOrg failed\n") ; return(FALSE); } if (!bEmitWin16SetWindowExt(pLocalDC, (SHORT) (frame.right - frame.left), (SHORT) (frame.bottom - frame.top))) { RIPS("MF3216: bEmitWin16SetWindowExt failed\n") ; return(FALSE); } return(TRUE); } /*---------------------------------------------------------------------------- * UpdateMf16Header - Update the metafile header with the: * metafile size, * number of objects, * the max record size. *---------------------------------------------------------------------------*/ BOOL bUpdateMf16Header(PLOCALDC pLocalDC) { BOOL b ; INT iCpTemp ; // Fill in the missing info in the Win16 metafile header. pLocalDC->mf16Header.mtSize = pLocalDC->ulBytesEmitted / 2 ; pLocalDC->mf16Header.mtNoObjects = (WORD) (pLocalDC->nObjectHighWaterMark + 1) ; pLocalDC->mf16Header.mtMaxRecord = pLocalDC->ulMaxRecord ; // Reset the output buffer index to the beginning of the buffer. iCpTemp = pLocalDC->ulBytesEmitted ; pLocalDC->ulBytesEmitted = 0 ; // re-emit the Win16 metafile header. b = bEmit(pLocalDC, &pLocalDC->mf16Header, (DWORD) sizeof (pLocalDC->mf16Header)) ; pLocalDC->ulBytesEmitted = iCpTemp ; return (b) ; }