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

/*****************************************************************************
*
* xforms - Entry points for Win32 to Win 16 converter
*
* Date: 7/1/91
* Author: Jeffrey Newman (c-jeffn)
*
* Copyright 1991 Microsoft Corp
*----------------------------------------------------------------------------
*
* September 21, 1991
* Updated [20-Dec-1991]
*
* Transformations in the Win32 to Win16 translator.
*
* We are now supporting coordinate transformations from any
* map mode to any map mode.
*
* Where:
* W is the record-time-world to record-time-device xform.
* (aka metafile-world to metafile-device.)
* D is the record-time device to play-time-device xform.
* (aka metafile-device to reference-device.)
* P is the play-time-device to play-time-page xform.
* (aka reference-device to reference-logical (or page).)
*
* W is the transformation defined by the world xform, map mode, window org,
* window extent, viewport org, and viewport extent in the
* Win32 metafile. This transform is also known as the world to
* device xform.
*
* The normal composite xform is:
*
* W D P
* ^ ^ ^ ^
* | | | +- coordinate recorded in the win16 metafile.
* | | | play-time-page coordinates (aka reference-logical)
* | | +---- play-time-device (reference-device) coordinates.
* | +------ record-time device (metafile-device) coordinates.
* +-------- world coordinates, recorded in Win32 metafile
*
* The following comment is from Hockl's mail about transforms.
*
* Message 11:
* From hockl Thu Dec 19 11:50:54 1991
* To: c-jeffn
* Cc: johnc
* Subject: Transform hints for the 32-16 converter
* Date: Thu Dec 19 11:46:40 1991
*
* Here are some transform hints for the converter:
*
* A. Issue the following records immediately following the 16-bit header
* record:
*
* 1. SetMapMode - use the given mapping mode, it is MM_ANISOTROPIC
* in most cases.
*
* 2. SetWindowOrg - use the upper left coordinates of the rclFrame.
* The coordinates are in the logical units of the reference DC. So
* you have to convert .01mm to the reference device coordinates, then
* to the logical coordinates. You can use the third transform
* defined in B.4 below to convert device coordinates to the logical
* coordinates of the reference device. (Note the conversion formula
* for LPtoDP is defined as Dx = (Lx - xWO) * xVE/xWE + xVO and so on).
* This record is required to translate the converted picture to the
* origin (see comments in GetMetaFileBitsEx).
*
* 3. SetWindowExt - use the extents of the rclFrame.
* xExt = rclFrame.right - rclFrame.left;
* yExt = rclFrame.bottom - rclFrame.top;
* The extents are in the device units of the reference DC. So
* you have to convert .01mm to the reference device units.
*
* These three records should always be generated. Note that
* SetWindowExt has no effect in all fixed mapping modes (e.g.
* MM_LOENGLISH and MM_TEXT) and will have no effect when the converted
* metafile is played.
*
* B. Once you have issued the records, you need to use a xform helper DC
* to convert the coordinates of all drawing orders. To do this, you
* need to do the following:
*
* 1. Create a xform helper DC. This is a display info DC.
*
* 2. Call SetVirtualResolution to set the xform helper DC to that of
* the metafile. Use the metafile header's szlDevice and
* szlMillimeters values to set the resolution. This is to ensure
* that the help DC maps the logical coordinates to the device
* coordinates of the original metafile device. If you reuse this
* helper DC in conversion, make sure you initialize the transforms
* using SetMapMode, ModifyWorldTransform, SetWindowOrgEx and
* SetViewportOrgEx. You can use the same code in the
* CreateMetaFileEx function.
*
* 3. Once you have set up the xform helper DC, you should play all
* 32-bit xform calls into the helper DC. But never emit any
* xform records in the converter. Everytime the xform is changed
* in the helper DC, you need to get the world to device xform
* (xformWDHelper) from the helper DC. The xformWDHelper is used to
* convert the coordinates of the drawing orders subsequently.
* You can get it using the GetTransform(hdcHelper,XFORM_WORLD_TO_DEVICE)
* private API.
*
* 4. To convert drawing order coordinates, you pass them through three
* transforms. The first is the xformWDHelper as computed above. It
* converts all logical coordiates into the device coordinates of
* the original metafile device. Note that this coordinates may
* be different from the conversion's reference device. For example,
* the metafile may be created for a printer but the conversion is
* requested for the display. The second transform therefore scales
* the coordinates from the metafile device to the reference device.
* The scaled coordinates are in MM_TEXT units. So we need the third
* transform to convert the coordinates into the requested mapmode
* units. For MM_TEXT, MM_ANISOTROPIC and MM_ISOTROPIC mapmode, this
* is the identity transform. For the other mapmodes, this is a scale
* transform. The scale transform maps the device units of the
* reference device to the logical units and can be computed using
* szlDevice, szlMillimeters of the reference device (not the metafile
* device!) and some predefined constants (to map millimeter to
* english, for example). Note that in these fixed mapping modes, the
* y-axis goes in the opposite direction. So make sure that the eM22
* component of the third transform is negative. As you can see, the
* second and third transform never change in the duration of the
* conversion. So you can combine them into one to optimize computation
* of the composite transform. The composite transfom makes up of the
* three transforms and is used to convert drawing order coordinates
* into coordinates for the converted metafile.
*
* C. To display a converted metafile in Windows 3.0, do the following before
* calling PlayMetaFile:
*
* 1. If the mapmode is MM_ANISOTROPIC, which is 99.9% of the time, call
* SetMapMode(MM_ANISOTROPIC), SetViewportOrigin and SetViewportExt.
* The viewport origin defines the upper left corner of the display area
* and the viewport origin defines the extent of the display area. Both
* are in device units.
*
* 2. If the mapmode is MM_ISOTROPIC, which is strange, call
* SetMapMode(MM_ISOTROPIC), SetViewportOrigin and SetViewportExt.
* This is almost the same as C.1 above.
*
* 3. If the mapmode is others, the metafile has a fixed physical size
* and cannot be scaled easily without a lot of heck in the application.
* Call SetViewportOrigin to define the upper left corner of the display
* area. The origin is in device coordinates.
*
* I hope these steps are clear. If you have any questions, feel free to
* give me a call.
*
* HockL
*
*
*
******************************************************************************/
#include "precomp.h"
#pragma hdrstop
BOOL WINAPI GetTransform(HDC hdc,DWORD iXform,LPXFORM pxform);
BOOL WINAPI SetVirtualResolution(HDC hdc,
int cxDevice,
int cyDevice,
int cxMillimeters,
int cyMillimeters);
BOOL bComputeCompositeXform(PLOCALDC pLocalDC) ;
VOID vInitRecDevToPlayDevXform(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header) ;
/*
[19-Dec-1991]
A note about transformations.
We will map into any map mode (when the converter is complete).
We will use a helper DC to compute our transformation matrices.
All the Win32 APIs that effect transformations or map modes
will be sent to a helper DC. The helper DC will return a transform
matrix that converts from World Coordinates to Device Coordinates.
This transformation matrix is: xformRWorldToRDev.
xformRWorldToRDev is combined with the xformRDevToPPage matrix to produce
the xformRWorldToPPage matrix. All coordinates are mapped through the
xformRWorldToPPage matrix.
*/
XFORM xformIdentity = {(FLOAT) 1.0,
(FLOAT) 0.0,
(FLOAT) 0.0,
(FLOAT) 1.0,
(FLOAT) 0.0,
(FLOAT) 0.0 } ;
/****************************************************************************
* Initialize all the matrices.
****************************************************************************/
// Units per millimeter array. It must be in the order of MM_LOMETRIC,
// MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS.
FLOAT aeUnitsPerMM[5] = { 10.0f, 100.0f, 3.937f, 39.37f, 56.6928f };
BOOL bInitXformMatrices(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header)
{
// Init xformRDevToPDev.
vInitRecDevToPlayDevXform(pLocalDC, pmf32header) ;
// Init xformPDevToPPage and xformPPageToPDev.
// (aka reference-device to reference-logical) transform.
switch(pLocalDC->iMapMode)
{
case MM_TEXT:
case MM_ANISOTROPIC:
case MM_ISOTROPIC:
pLocalDC->xformPDevToPPage = xformIdentity ;
pLocalDC->xformPPageToPDev = xformIdentity ;
break ;
case MM_LOMETRIC:
case MM_HIMETRIC:
case MM_LOENGLISH:
case MM_HIENGLISH:
case MM_TWIPS:
{
FLOAT exUnitsPerPel;
FLOAT eyUnitsPerPel;
// Compute units per pixel.
exUnitsPerPel = (FLOAT) pLocalDC->cxPlayDevMM
/ (FLOAT) pLocalDC->cxPlayDevPels
* aeUnitsPerMM[pLocalDC->iMapMode - MM_LOMETRIC];
eyUnitsPerPel = (FLOAT) pLocalDC->cyPlayDevMM
/ (FLOAT) pLocalDC->cyPlayDevPels
* aeUnitsPerMM[pLocalDC->iMapMode - MM_LOMETRIC];
pLocalDC->xformPDevToPPage.eM11 = exUnitsPerPel;
pLocalDC->xformPDevToPPage.eM12 = 0.0f;
pLocalDC->xformPDevToPPage.eM21 = 0.0f;
pLocalDC->xformPDevToPPage.eM22 = -eyUnitsPerPel;
pLocalDC->xformPDevToPPage.eDx = 0.0f;
pLocalDC->xformPDevToPPage.eDy = 0.0f;
pLocalDC->xformPPageToPDev.eM11 = 1.0f / exUnitsPerPel;
pLocalDC->xformPPageToPDev.eM12 = 0.0f;
pLocalDC->xformPPageToPDev.eM21 = 0.0f;
pLocalDC->xformPPageToPDev.eM22 = -1.0f / eyUnitsPerPel;
pLocalDC->xformPPageToPDev.eDx = 0.0f;
pLocalDC->xformPPageToPDev.eDy = 0.0f;
}
break ;
}
// Init xformRDevToPPage.
// This xform is used in the SelectClipRegion code.
if (!CombineTransform(&pLocalDC->xformRDevToPPage,
&pLocalDC->xformRDevToPDev,
&pLocalDC->xformPDevToPPage))
{
RIP("MF3216: InitXformMatrices, CombineTransform failed\n");
return(FALSE);
}
// We are going to use the helper DC to compute the
// Record-time-World to Record-time-Device transform.
// Set the Helper DC virtual resolution to the Metafiles
// resolution.
if (!SetVirtualResolution(pLocalDC->hdcHelper,
(INT) pmf32header->szlDevice.cx,
(INT) pmf32header->szlDevice.cy,
(INT) pmf32header->szlMillimeters.cx,
(INT) pmf32header->szlMillimeters.cy))
{
RIP("MF3216: InitXformMatrices, SetVirtualResolution failed \n") ;
return(FALSE);
}
// Init other matrices.
return(bComputeCompositeXform(pLocalDC));
}
/****************************************************************************
* Initialize the Record-time to Play-time scalers. (xformRDevToPDev)
****************************************************************************/
VOID vInitRecDevToPlayDevXform(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header)
{
FLOAT ecxRecDevPels,
ecyRecDevPels,
ecxRecDevMM,
ecyRecDevMM,
ecxPlayDevPels,
ecyPlayDevPels,
ecxPlayDevMM,
ecyPlayDevMM,
exMillsPerPelRec,
eyMillsPerPelRec,
exMillsPerPelPlay,
eyMillsPerPelPlay ;
// Pickup the physical dimensions of the record-time
// device, both in pels and millimeters.
// Converts them to floats
ecxRecDevPels = (FLOAT) pmf32header->szlDevice.cx ;
ecyRecDevPels = (FLOAT) pmf32header->szlDevice.cy ;
ecxRecDevMM = (FLOAT) pmf32header->szlMillimeters.cx ;
ecyRecDevMM = (FLOAT) pmf32header->szlMillimeters.cy ;
// convert the Play-time device dimensions to floats.
ecxPlayDevPels = (FLOAT) pLocalDC->cxPlayDevPels ;
ecyPlayDevPels = (FLOAT) pLocalDC->cyPlayDevPels ;
ecxPlayDevMM = (FLOAT) pLocalDC->cxPlayDevMM ;
ecyPlayDevMM = (FLOAT) pLocalDC->cyPlayDevMM ;
// Calucalte the pels per millimeter for both the record-time
// and play-time devices.
exMillsPerPelRec = ecxRecDevMM / ecxRecDevPels ;
eyMillsPerPelRec = ecyRecDevMM / ecyRecDevPels ;
exMillsPerPelPlay = ecxPlayDevMM / ecxPlayDevPels ;
eyMillsPerPelPlay = ecyPlayDevMM / ecyPlayDevPels ;
// Init the Record-time-device to the Play-time-device transform.
// aka the Metafile-device to the Reference-device transform.
pLocalDC->xformRDevToPDev.eM11 = exMillsPerPelRec / exMillsPerPelPlay ;
pLocalDC->xformRDevToPDev.eM12 = (FLOAT) 0.0 ;
pLocalDC->xformRDevToPDev.eDx = (FLOAT) 0.0 ;
pLocalDC->xformRDevToPDev.eM21 = (FLOAT) 0.0 ;
pLocalDC->xformRDevToPDev.eM22 = eyMillsPerPelRec / eyMillsPerPelPlay ;
pLocalDC->xformRDevToPDev.eDy = (FLOAT) 0.0 ;
return;
}
#if 0
/***************************************************************************
* vInvertMatrix - Invert a matrix
**************************************************************************/
VOID vInvertMatrix(PXFORM pxformSrc, PINVERSMATRIX pinvxfm)
{
FLOAT eM11, eM12, eM21, eM22, eDx, eDy,
detA ;
// dereference the matrix elements, just to make the rest of this
// routine more readable.
eM11 = pxformSrc->eM11 ;
eM12 = pxformSrc->eM12 ;
eM21 = pxformSrc->eM21 ;
eM22 = pxformSrc->eM22 ;
eDx = pxformSrc->eDx ;
eDy = pxformSrc->eDy ;
// First determine the determinant of the source matrix.
detA = (eM11 * eM22) - (eM11 * eDy) ;
pinvxfm->a1 = eM22 / detA ;
pinvxfm->a2 = -(eM21 / detA) ;
pinvxfm->a3 = ((eM21 * eDy) - (eDx * eM22)) / detA ;
pinvxfm->b1 = -(eM12 / detA) ;
pinvxfm->b2 = eM11 / detA ;
pinvxfm->b3 = -(((eM11 * eDy) - (eDx * eM12)) / detA) ;
pinvxfm->c1 = (FLOAT) 0.0 ;
pinvxfm->c2 = (FLOAT) 0.0 ;
pinvxfm->c3 = ((eM11 * eM22) - (eM21 * eM12)) / detA ;
// This is just for testing.
pinvxfm->a1 = pxformSrc->eM11 ;
pinvxfm->a2 = pxformSrc->eM12 ;
pinvxfm->a3 = (FLOAT) 0.0 ;
pinvxfm->b1 = pxformSrc->eM21 ;
pinvxfm->b2 = pxformSrc->eM22 ;
pinvxfm->b3 = (FLOAT) 0.0 ;
pinvxfm->c1 = pxformSrc->eDx ;
pinvxfm->c2 = pxformSrc->eDy ;
pinvxfm->c3 = (FLOAT) 1.0 ;
return ;
}
#endif // 0
/***************************************************************************
* XformPDevToPPage - Do a transform on the array of points passed in.
*
* This does the play-time (reference) device to
* play-time (reference) page (logical) transformation.
**************************************************************************/
BOOL bXformPDevToPPage(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
{
BOOL b ;
b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformPDevToPPage) ;
return (b) ;
}
/***************************************************************************
* XformPPageToPDev - Do a transform on the array of points passed in.
*
* This does the play-time (reference) page (logical) to
* play-time (reference) device transformation.
**************************************************************************/
BOOL bXformPPageToPDev(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
{
BOOL b ;
b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformPPageToPDev) ;
return (b) ;
}
/***************************************************************************
* XformRWorldToRDev - Do a transform on the array of points passed in.
*
* This does the Record-time (metafile) world to
* record-time device translation.
**************************************************************************/
BOOL bXformRWorldToRDev(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
{
BOOL b ;
b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRWorldToRDev) ;
return (b) ;
}
/***************************************************************************
* XformRDevToRWorld - Do a transform on the array of points passed in.
*
* This does the Record-device (metafile) world to
* record-time world translation.
**************************************************************************/
BOOL bXformRDevToRWorld(PLOCALDC pLocalDC, PPOINTL aptl, INT nCount)
{
BOOL b ;
b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRDevToRWorld) ;
return (b) ;
}
/***************************************************************************
* XformRWorldToPPage - Do a transform on the array of points passed in.
*
* This is the workhorse translation routine.
* This translates from record-time-world (aka metafile-world)
* to record-time-device (aka metafile-device) then from
* record-time-device (aka metafile-device) to play-time-device
* (aka reference-device) then from play-time-device
* (aka reference-device) to play-time-page (reference-logical)
* space.
**************************************************************************/
BOOL bXformRWorldToPPage(PLOCALDC pLocalDC, PPOINTL aptl, DWORD nCount)
{
BOOL b ;
b = bXformWorkhorse(aptl, nCount, &pLocalDC->xformRWorldToPPage) ;
return (b) ;
}
/***************************************************************************
* bXformWorkhorse - Transformation Workhorse.
**************************************************************************/
BOOL bXformWorkhorse(PPOINTL aptl, DWORD nCount, PXFORM pXform)
{
INT i ;
FLOAT x, y ;
BOOL b ;
FLOAT fx, fy;
for (i = 0 ; i < (INT) nCount ; i++)
{
x = (FLOAT) aptl[i].x ;
y = (FLOAT) aptl[i].y ;
fx = (x * pXform->eM11 + y * pXform->eM21 + pXform->eDx) ;
fy = (x * pXform->eM12 + y * pXform->eM22 + pXform->eDy) ;
aptl[i].x = (LONG) (fx + ((fx < 0.0) ? -0.5f : 0.5f)) ;
aptl[i].y = (LONG) (fy + ((fy < 0.0) ? -0.5f : 0.5f)) ;
}
// Do the coordinate overflow detection.
b = bCoordinateOverflowTest((PLONG) aptl, nCount * 2) ;
return (b) ;
}
/***************************************************************************
* vXformWorkhorseFloat - Transformation Workhorse.
**************************************************************************/
VOID vXformWorkhorseFloat(PPOINTFL aptfl, UINT nCount, PXFORM pXform)
{
UINT i ;
FLOAT x, y ;
for (i = 0 ; i < nCount ; i++)
{
x = aptfl[i].x ;
y = aptfl[i].y ;
aptfl[i].x = x * pXform->eM11 + y * pXform->eM21 + pXform->eDx;
aptfl[i].y = x * pXform->eM12 + y * pXform->eM22 + pXform->eDy;
}
}
/*****************************************************************************
* iMagnitudeXform - Transform the magnitude of a number from
* Record-time-World to Play-time-Page coordinate space.
*****************************************************************************/
INT iMagnitudeXform (PLOCALDC pLocalDC, INT value, INT iType)
{
PXFORM pxform ;
INT iRet ;
pxform = &(pLocalDC->xformRWorldToPPage) ;
iRet = iMagXformWorkhorse (value, pxform, iType) ;
return (iRet) ;
}
/*****************************************************************************
* iMagXformWorkhorse - get the magnitude component of a translated vector
*****************************************************************************/
INT iMagXformWorkhorse (INT value, PXFORM pxform, INT iType)
{
POINTFL aptfl[2] ;
FLOAT x1, y1, x2, y2;
double emag ;
// Create a vector, from (0,0) to the point.
aptfl[0].x = 0.0f ;
aptfl[0].y = 0.0f ;
if (iType == CX_MAG)
{
aptfl[1].x = (FLOAT) value ;
aptfl[1].y = 0.0f ;
}
else
{
aptfl[1].x = 0.0f ;
aptfl[1].y = (FLOAT) value ;
}
vXformWorkhorseFloat(aptfl, 2, pxform);
// Now get the magnitude
x1 = aptfl[0].x ;
y1 = aptfl[0].y ;
x2 = aptfl[1].x ;
y2 = aptfl[1].y ;
emag = sqrt((double) ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))) ;
return((INT) (emag + (double) 0.5f));
}
/*****************************************************************************
* bRotationTest -
* return - TRUE if there is a rotation or shear in this xform
* FALSE if there is none.
*****************************************************************************/
BOOL bRotationTest(PXFORM pxform)
{
BOOL b ;
if ( (pxform->eM12 != (FLOAT) 0.0)
|| (pxform->eM21 != (FLOAT) 0.0)
)
{
b = TRUE ;
}
else
{
b = FALSE ;
}
return(b) ;
}
/***************************************************************************
* SetMapMode - Win32 to Win16 Metafile Converter Entry Point
*
* All the map mode translations are done by the helper DC.
* The Helper DC always transforms to device, then we combine the
* MetafileWorldToDevice with the DeviceToPage transform.
* This becomes the Win32 to Win16 transform.
*
* Some of the metafiles converted from Win16 to Win32 do not
* define a Viewport extent. Since the Isotropic and AnIsotropic
* map modes are undefined if either the Viewport Extent or the Window
* Extent are undefined we will default the Viewport extent to the
* device extent in the Win32 metafile header.
**************************************************************************/
BOOL WINAPI DoSetMapMode
(
PLOCALDC pLocalDC,
DWORD ulMapMode
)
{
BOOL b ;
if (!SetMapMode(pLocalDC->hdcHelper, ulMapMode))
{
ASSERTGDI(FALSE, "MF3216: DoSetMapMode failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* ScaleWindowsExtEx - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoScaleWindowExt
(
PLOCALDC pLocalDC,
INT Xnum,
INT Xdenom,
INT Ynum,
INT Ydenom
)
{
BOOL b ;
// Set the Windows extent
if (!ScaleWindowExtEx(pLocalDC->hdcHelper,
Xnum, Xdenom,
Ynum, Ydenom,
(LPSIZE) 0))
{
ASSERTGDI(FALSE, "MF3216: DoScaleWindowExt failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* ScaleViewportExtEx - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoScaleViewportExt
(
PLOCALDC pLocalDC,
INT Xnum,
INT Xdenom,
INT Ynum,
INT Ydenom
)
{
BOOL b ;
// Set the viewport extent
if (!ScaleViewportExtEx(pLocalDC->hdcHelper,
Xnum, Xdenom,
Ynum, Ydenom,
(LPSIZE) 0))
{
ASSERTGDI(FALSE, "MF3216: DoScaleViewportExt failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* SetViewportExtEx - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoSetViewportExt
(
PLOCALDC pLocalDC,
int x,
int y
)
{
BOOL b ;
// Set the viewport extent
if (!SetViewportExtEx(pLocalDC->hdcHelper, x, y, (LPSIZE) 0))
{
ASSERTGDI(FALSE, "MF3216: DoSetViewportExt failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* SetViewportOrgEx - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoSetViewportOrg
(
PLOCALDC pLocalDC,
int x,
int y
)
{
BOOL b ;
// Set the viewport origin
if (!SetViewportOrgEx(pLocalDC->hdcHelper, x, y, (LPPOINT) 0))
{
ASSERTGDI(FALSE, "MF3216: DoSetViewportOrg failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* SetWindowExtEx - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoSetWindowExt
(
PLOCALDC pLocalDC,
int x,
int y
)
{
BOOL b ;
// Set the window extent
if (!SetWindowExtEx(pLocalDC->hdcHelper, x, y, (LPSIZE) 0))
{
ASSERTGDI(FALSE, "MF3216: DoSetWindowExt failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* SetWindowOrgEx - Win32 to Win16 Metafile Converter Entry Point
*
* Since we will always record TWIPS in the Win16 metafile,
* we will transform the WindowOrg from the current MapMode to
* TWIPS. Then we will set the Dx and Dy elements of the Viewport
* transformation matrix.
*
**************************************************************************/
BOOL WINAPI DoSetWindowOrg
(
PLOCALDC pLocalDC,
int x,
int y
)
{
BOOL b ;
// Set the window origin
if (!SetWindowOrgEx(pLocalDC->hdcHelper, x, y, (LPPOINT) 0))
{
ASSERTGDI(FALSE, "MF3216: DoSetWindowOrg failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* SetWorldTransform - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoSetWorldTransform
(
PLOCALDC pLocalDC,
PXFORM pxf
)
{
BOOL b ;
// Set the world xform in the helper DC.
if (!SetWorldTransform(pLocalDC->hdcHelper, pxf))
{
ASSERTGDI(FALSE, "MF3216: DoSetWorldTransform failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/***************************************************************************
* ModifyWorldTransform - Win32 to Win16 Metafile Converter Entry Point
**************************************************************************/
BOOL WINAPI DoModifyWorldTransform
(
PLOCALDC pLocalDC,
PXFORM pxf,
DWORD imode
)
{
BOOL b ;
// Set the world xform in the helper DC.
if (!ModifyWorldTransform(pLocalDC->hdcHelper, pxf, imode))
{
ASSERTGDI(FALSE, "MF3216: DoModifyWorldTransform failed\n");
return(FALSE);
}
b = bComputeCompositeXform(pLocalDC) ;
return (b) ;
}
/****************************************************************************
* bComputeCompositeXform - Compute the composite Xforms.
*
* The following transforms are re-computed:
*
* xformRWorldToRDev
* xformRDevToRWorld
* xformRWorldToPPage
*
****************************************************************************/
BOOL bComputeCompositeXform(PLOCALDC pLocalDC)
{
BOOL b ;
// Recompute xformRWorldToRDev.
// Get the record-time world to record-time device xform
// from the helper DC
b = GetTransform(pLocalDC->hdcHelper,
XFORM_WORLD_TO_DEVICE,
&pLocalDC->xformRWorldToRDev) ;
if (b == FALSE)
{
RIP("MF3216: bComputeCompositeXform - GetTransform (RWorld to RDev) failed \n") ;
goto error_exit ;
}
// Recompute xformRDevToRWorld.
// Get the record-time-device to record-time-world xform
b = GetTransform(pLocalDC->hdcHelper,
XFORM_DEVICE_TO_WORLD,
&pLocalDC->xformRDevToRWorld) ;
if (b == FALSE)
{
RIP("MF3216: bComputeCompositeXform - GetTransform (RDev To RWorld) failed \n") ;
goto error_exit ;
}
// Recompute xformRWorldToPPage.
b = CombineTransform(&pLocalDC->xformRWorldToPPage,
&pLocalDC->xformRWorldToRDev,
&pLocalDC->xformRDevToPPage);
if (b == FALSE)
{
RIP("MF3216: bComputeCompositeXform - CombineTransform failed\n");
goto error_exit ;
}
// Recompute transform flags.
if (pLocalDC->xformRWorldToRDev.eM12 != (FLOAT) 0.0
|| pLocalDC->xformRWorldToRDev.eM21 != (FLOAT) 0.0)
pLocalDC->flags |= STRANGE_XFORM ;
else
pLocalDC->flags &= ~STRANGE_XFORM ;
error_exit:
return(b) ;
}
/***************************************************************************
* bCoordinateOverflowTest - Test for 1 16 bit coordinate overflow
*
* RETURNS: FALSE if there is a coordinate overflow
* TRUE if there is no overflow.
**************************************************************************/
BOOL bCoordinateOverflowTest(PLONG pCoordinates, INT nCount)
{
BOOL b ;
INT i, j ;
b = TRUE ;
for (i = 0 ; i < nCount ; i++)
{
j = pCoordinates[i] ;
if (j < -32768 || j > 32767)
{
b = FALSE ;
SetLastError(ERROR_ARITHMETIC_OVERFLOW);
RIP("MF3216: bCoordinateOverflowTest, coordinate overflow\n") ;
break ;
}
}
return(b) ;
}