263 lines
8.4 KiB
C
263 lines
8.4 KiB
C
/*****************************************************************************
|
|
*
|
|
* 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) ;
|
|
|
|
}
|
|
|
|
|