- Rewrite coordinate transformation code to use XFORMOBJ apis instead of using floating point in kernel mode. As a small present fix 14 gdi32_winetests (5 mapping, 9 bitmap)
I disabled some RtoL code, since it didn't work anyway and caused more bugs than it fixed.

svn path=/trunk/; revision=56236
This commit is contained in:
Timo Kreuzer 2012-03-26 14:35:58 +00:00
parent 4cde806076
commit 6539718c1d
10 changed files with 476 additions and 298 deletions

View file

@ -100,10 +100,16 @@ typedef enum _TRANSFORMTYPE
/* MATRIX flAccel flags */
enum
{
MX_SCALE = 1,
MX_IDENTITYSCALE = 2,
MX_INTEGER = 4,
MX_NOTRANSLATE = 8,
XFORM_SCALE = 1,
XFORM_UNITY = 2,
XFORM_Y_NEG = 4,
XFORM_FORMAT_LTOFX = 8,
XFORM_FORMAT_FXTOL = 0x10,
XFORM_FORMAT_LTOL = 0x20,
XFORM_NO_TRANSLATION = 0x40,
/* Reactos specific */
XFORM_INTEGER = 0x1000,
};
typedef enum GDIObjType
@ -548,7 +554,7 @@ typedef VOID (APIENTRY *PFN_DrvMovePanning)(LONG, LONG, FLONG);
//
typedef struct _DRIVER_FUNCTIONS
{
PFN_DrvEnablePDEV EnablePDEV;
PFN_DrvEnablePDEV EnablePDEV;
PFN_DrvCompletePDEV CompletePDEV;
PFN_DrvDisablePDEV DisablePDEV;
PFN_DrvEnableSurface EnableSurface;
@ -584,10 +590,10 @@ typedef struct _DRIVER_FUNCTIONS
PFN_DrvStartPage StartPage;
PFN_DrvEndDoc EndDoc;
PFN_DrvStartDoc StartDoc;
PVOID Unknown3;
PVOID Unknown3;
PFN_DrvGetGlyphMode GetGlyphMode;
PFN_DrvSynchronize Synchronize;
PVOID Unknown4;
PVOID Unknown4;
PFN_DrvSaveScreenBits SaveScreenBits;
PFN_DrvGetModes GetModes;
PFN_DrvFree Free;
@ -641,7 +647,7 @@ typedef struct _DRIVER_FUNCTIONS
PVOID Reserved9;
PVOID Reserved10;
PVOID Reserved11; /* 92 */
/* ReactOS specify */
PFN_DrvEnableDriver EnableDriver; //ReactOS Extra
} DRIVER_FUNCTIONS, *PDRIVER_FUNCTIONS;

View file

@ -81,6 +81,22 @@
#define PARAM1 8
#define PARAM2 12
/** Globals **/
/* extern const FLOATOBJ gef0; */
PUBLIC _gef0
_gef0:
.long 0, 0
/* extern const FLOATOBJ gef1; */
PUBLIC _gef1
_gef1:
.long HEX(40000000), HEX(00000002)
/* extern const FLOATOBJ gef16; */
PUBLIC _gef16
_gef16:
.long HEX(40000000), HEX(00000006)
/******************************************************************************
* VOID
* APIENTRY

View file

@ -45,8 +45,72 @@ InvertXform(
XFORMOBJ_iGetXform(&xo, pxformDest);
}
VOID
FASTCALL
DC_vFixIsotropicMapping(PDC pdc);
VOID
FASTCALL
DC_vUpdateWorldToDevice(PDC pdc);
VOID
FASTCALL
DC_vUpdateDeviceToWorld(PDC pdc);
PSIZEL
FORCEINLINE
DC_pszlViewportExt(PDC pdc)
{
PDC_ATTR pdcattr = pdc->pdcattr;
/* Check if we need isotropic fixup */
if ((pdcattr->flXform & PAGE_EXTENTS_CHANGED) &&
(pdcattr->iMapMode == MM_ISOTROPIC))
{
/* Fixup viewport extension */
DC_vFixIsotropicMapping(pdc);
}
return &pdcattr->szlViewportExt;
}
PMATRIX
FORCEINLINE
DC_pmxWorldToPage(PDC pdc)
{
return &pdc->pdcattr->mxWorldToPage;
}
PMATRIX
FORCEINLINE
DC_pmxWorldToDevice(PDC pdc)
{
/* Check if world or page xform was changed */
if (pdc->pdcattr->flXform & (PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|WORLD_XFORM_CHANGED))
{
/* Update the world-to-device xform */
DC_vUpdateWorldToDevice(pdc);
}
return &pdc->pdcattr->mxWorldToDevice;
}
PMATRIX
FORCEINLINE
DC_pmxDeviceToWorld(PDC pdc)
{
/* Check if the device-to-world xform is invalid */
if (pdc->pdcattr->flXform & DEVICE_TO_WORLD_INVALID)
{
/* Update the world-to-device xform */
DC_vUpdateDeviceToWorld(pdc);
}
return &pdc->pdcattr->mxDeviceToWorld;
}
VOID
FORCEINLINE
void
DC_vXformDeviceToWorld(
IN PDC pdc,
IN ULONG cNumPoints,
@ -54,13 +118,15 @@ DC_vXformDeviceToWorld(
IN PPOINTL pptlSource)
{
XFORMOBJ xo;
PMATRIX pmx;
XFORMOBJ_vInit(&xo, &pdc->dclevel.mxDeviceToWorld);
pmx = DC_pmxDeviceToWorld(pdc);
XFORMOBJ_vInit(&xo, pmx);
XFORMOBJ_bApplyXform(&xo, XF_LTOL, cNumPoints, pptlDest, pptlSource);
}
VOID
FORCEINLINE
void
DC_vXformWorldToDevice(
IN PDC pdc,
IN ULONG cNumPoints,
@ -68,18 +134,27 @@ DC_vXformWorldToDevice(
IN PPOINTL pptlSource)
{
XFORMOBJ xo;
PMATRIX pmx;
XFORMOBJ_vInit(&xo, &pdc->dclevel.mxWorldToDevice);
pmx = DC_pmxWorldToDevice(pdc);
XFORMOBJ_vInit(&xo, pmx);
XFORMOBJ_bApplyXform(&xo, XF_LTOL, cNumPoints, pptlDest, pptlSource);
}
int APIENTRY IntGdiSetMapMode(PDC, int);
BOOL NTAPI
IntGdiCombineTransform(
XFORML *pxformDest,
XFORML *pxform1,
XFORML *pxform2);
BOOL
FASTCALL
IntGdiModifyWorldTransform(PDC pDc,
CONST LPXFORM lpXForm,
DWORD Mode);
NTAPI
GreModifyWorldTransform(
PDC pdc,
const XFORML *pXForm,
DWORD dwMode);
VOID FASTCALL IntMirrorWindowOrg(PDC);
void FASTCALL IntFixIsotropicMapping(PDC);

View file

@ -1,6 +1,6 @@
#pragma once
#if defined(_X86_)
#if defined(_M_IX86)
FORCEINLINE
BOOL
@ -54,6 +54,15 @@ _FLOATOBJ_Equal1(FLOATOBJ *pf)
return (pef->lMant == 0x40000000 && pef->lExp == 2);
}
extern const FLOATOBJ gef0;
extern const FLOATOBJ gef1;
extern const FLOATOBJ gef16;
#define FLOATOBJ_0 {0x00000000, 0x00000000}
#define FLOATOBJ_1 {0x40000000, 0x00000002}
#define FLOATOBJ_16 {0x40000000, 0x00000006}
#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
#define FLOATOBJ_Set0(fo) (fo)->ul1 = 0; (fo)->ul2 = 0;
#define FLOATOBJ_Set1(fo) (fo)->ul1 = 0x40000000; (fo)->ul2 = 2;
@ -66,7 +75,16 @@ _FLOATOBJ_Equal1(FLOATOBJ *pf)
#define _FLOATOBJ_Equal1(pf) (*(pf) == 1.)
#define _FLOATOBJ_GetFix(pf) ((LONG)(*(pf) * 16.))
#define FLOATOBJ_Set0(fo) *(fo) = 0;
#define FLOATOBJ_0 0.
#define FLOATOBJ_1 1.
#define FLOATOBJ_16 16.
#define FLOATOBJ_1_16 (1./16.)
#define gef0 FLOATOBJ_0
#define gef1 FLOATOBJ_1
#define gef16 FLOATOBJ_16
#define FLOATOBJ_Set0(fo) *(fo) = 0;
#define FLOATOBJ_Set1(fo) *(fo) = 1;
#endif

View file

@ -80,13 +80,6 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
CONST PDEVMODEW InitData,
BOOL CreateAsIC);
/* Coord functions */
BOOL FASTCALL
IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2);
/* Stock objects */
VOID FASTCALL

View file

@ -3,7 +3,65 @@
* PROJECT: ReactOS kernel
* PURPOSE: Coordinate systems
* FILE: subsystems/win32/win32k/objects/coord.c
* PROGRAMER: Unknown
* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
*/
/* Coordinate translation overview
* -------------------------------
*
* Windows uses 3 different coordinate systems, referred to as world space,
* page space and device space.
*
* Device space:
* This is the coordinate system of the physical device that displays the
* graphics. One unit matches one pixel of the surface. The coordinate system
* is always orthogonal.
*
* Page space:
* This is the coordinate system on the screen or on the paper layout for
* printer devices. The coordinate system is also orthogonal but one unit
* does not neccesarily match one pixel. Instead there are different mapping
* modes that can be set using SetMapMode() that specify how page space units
* are transformed into device space units. These mapping modes are:
* - MM_TEXT: One unit matches one unit in device space (one pixel)
* - MM_TWIPS One unit matches 1/20 point (1/1440 inch)
* - MM_LOMETRIC: One unit matches 0.1 millimeter
* - MM_HIMETRIC: One unit matches 0.01 millimeter
* - MM_LOENGLISH: One unit matches 0.01 inch
* - MM_HIENGLISH: One unit matches 0.001 inch
* - MM_ISOTROPIC:
* - MM_ANISOTROPIC:
* If the mapping mode is either MM_ISOTROPIC or MM_ANISOTROPIC, the actual
* transormation is calculated from the window and viewport extension.
* The window extension can be set using SetWindowExtEx() and describes the
* extents of an arbitrary window (not to confuse with the gui element!) in
* page space coordinates.
* The viewport extension can be set using SetViewportExtEx() and describes
* the extent of the same window in device space coordinates. If the mapping
* mode is MM_ISOTROPIC one of the viewport extensions can be adjusted by GDI
* to make sure the mapping stays isotropic, that is it has the same x/y ratio
* as the window extension.
*
* World space:
* World space is the coordinate system that is used for all GDI drawing
* operations. The metrics of this coordinate system depend on the DCs
* graphics mode, which can be set using SetGraphicsMode().
* If the graphics mode is GM_COMPATIBLE, world space is identical to page
* space and no additional transformation is applied.
* If the graphics mode is GM_ADVANCED, an arbitrary coordinate transformation
* can be set using SetWorldTransform(), which is applied to transform world
* space coordinates into page space coordinates.
*
* User mode data
* All coordinate translation data is stored in the dc attribute, so the values
* might be invalid. This has to be taken into account. Integer values might be
* zero, so when a division is made, the value has to be read first and then
* checked! For floating point values (FLOATOBJ as well) these restrictions do
* not apply, since we cannot get dividy-by-zero exceptions.
* Though the result might be a completely random and invalid value, if it was
* messed with in an illegal way in user mode. This is not a problem, since the
* result of coordinate transformations are never expected to be "valid" values.
* In the worst case, the drawing operation draws rubbish into the DC.
*/
/* INCLUDES ******************************************************************/
@ -12,140 +70,183 @@
#define NDEBUG
#include <debug.h>
C_ASSERT(sizeof(XFORML) == sizeof(XFORM));
/* GLOBALS *******************************************************************/
const MATRIX gmxIdentity =
{
FLOATOBJ_1, FLOATOBJ_0,
FLOATOBJ_0, FLOATOBJ_1,
FLOATOBJ_0, FLOATOBJ_0,
0, 0, XFORM_NO_TRANSLATION|XFORM_FORMAT_LTOL|XFORM_UNITY|XFORM_SCALE
};
/* FUNCTIONS *****************************************************************/
void FASTCALL
IntFixIsotropicMapping(PDC pdc)
VOID
FASTCALL
DC_vFixIsotropicMapping(PDC pdc)
{
PDC_ATTR pdcattr;
LONG fx, fy, s;
LONG64 fx, fy;
LONG s;
SIZEL szlWindowExt, szlViewportExt;
ASSERT(pdc->pdcattr->iMapMode == MM_ISOTROPIC);
/* Get a pointer to the DC_ATTR */
pdcattr = pdc->pdcattr;
/* Read the extents, we rely on non-null values */
szlWindowExt = pdcattr->szlWindowExt;
szlViewportExt = pdcattr->szlViewportExt;
/* Check if all values are valid */
if (pdcattr->szlWindowExt.cx == 0 || pdcattr->szlWindowExt.cy == 0 ||
pdcattr->szlViewportExt.cx == 0 || pdcattr->szlViewportExt.cy == 0)
if ((szlWindowExt.cx == 0) || (szlWindowExt.cy == 0) ||
(szlViewportExt.cx == 0) || (szlViewportExt.cy == 0))
{
/* Don't recalculate */
/* Someone put rubbish into the fields, just ignore it. */
return;
}
fx = abs(pdcattr->szlWindowExt.cx * pdcattr->szlViewportExt.cy);
fy = abs(pdcattr->szlWindowExt.cy * pdcattr->szlViewportExt.cx);
fx = abs((LONG64)szlWindowExt.cx * szlViewportExt.cy);
fy = abs((LONG64)szlWindowExt.cy * szlViewportExt.cx);
if (fy > fx)
if (fx < fy)
{
s = pdcattr->szlWindowExt.cy * pdcattr->szlViewportExt.cx > 0 ? 1 : -1;
pdcattr->szlViewportExt.cx = s * fx / pdcattr->szlWindowExt.cy;
s = (szlWindowExt.cy ^ szlViewportExt.cx) > 0 ? 1 : -1;
pdcattr->szlViewportExt.cx = (LONG)(fx * s / szlWindowExt.cy);
}
else if (fx > fy)
{
s = pdcattr->szlWindowExt.cx * pdcattr->szlViewportExt.cy > 0 ? 1 : -1;
pdcattr->szlViewportExt.cy = s * fy / pdcattr->szlWindowExt.cx;
}
}
// FIXME: Don't use floating point in the kernel!
void IntWindowToViewPort(PDC_ATTR pdcattr, LPXFORM xformWnd2Vport)
{
FLOAT scaleX, scaleY;
scaleX = (pdcattr->szlWindowExt.cx ? (FLOAT)pdcattr->szlViewportExt.cx / (FLOAT)pdcattr->szlWindowExt.cx : 0.0f);
scaleY = (pdcattr->szlWindowExt.cy ? (FLOAT)pdcattr->szlViewportExt.cy / (FLOAT)pdcattr->szlWindowExt.cy : 0.0f);
xformWnd2Vport->eM11 = scaleX;
xformWnd2Vport->eM12 = 0.0;
xformWnd2Vport->eM21 = 0.0;
xformWnd2Vport->eM22 = scaleY;
xformWnd2Vport->eDx = (FLOAT)pdcattr->ptlViewportOrg.x - scaleX * (FLOAT)pdcattr->ptlWindowOrg.x;
xformWnd2Vport->eDy = (FLOAT)pdcattr->ptlViewportOrg.y - scaleY * (FLOAT)pdcattr->ptlWindowOrg.y;
}
// FIXME: Use XFORMOBJECT!
VOID FASTCALL
DC_UpdateXforms(PDC dc)
{
XFORM xformWnd2Vport;
PDC_ATTR pdcattr = dc->pdcattr;
XFORM xformWorld2Vport, xformWorld2Wnd, xformVport2World;
/* Construct a transformation to do the window-to-viewport conversion */
IntWindowToViewPort(pdcattr, &xformWnd2Vport);
/* Combine with the world transformation */
MatrixS2XForm(&xformWorld2Vport, &dc->dclevel.mxWorldToDevice);
MatrixS2XForm(&xformWorld2Wnd, &dc->dclevel.mxWorldToPage);
IntGdiCombineTransform(&xformWorld2Vport, &xformWorld2Wnd, &xformWnd2Vport);
/* Create inverse of world-to-viewport transformation */
MatrixS2XForm(&xformVport2World, &dc->dclevel.mxDeviceToWorld);
if (DC_InvertXform(&xformWorld2Vport, &xformVport2World))
{
pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
}
else
{
pdcattr->flXform |= DEVICE_TO_WORLD_INVALID;
s = (szlWindowExt.cx ^ szlViewportExt.cy) > 0 ? 1 : -1;
pdcattr->szlViewportExt.cy = (LONG)(fy * s / szlWindowExt.cx);
}
/* Update transformation matrices */
XForm2MatrixS(&dc->dclevel.mxWorldToDevice, &xformWorld2Vport);
XForm2MatrixS(&dc->dclevel.mxDeviceToWorld, &xformVport2World);
/* Reset the flag */
pdc->pdcattr->flXform &= ~PAGE_EXTENTS_CHANGED;
}
VOID
FASTCALL
DC_vUpdateViewportExt(PDC pdc)
DC_vGetPageToDevice(PDC pdc, MATRIX *pmx)
{
PDC_ATTR pdcattr;
PDC_ATTR pdcattr = pdc->pdcattr;
PSIZEL pszlViewPortExt;
/* Get a pointer to the dc attribute */
pdcattr = pdc->pdcattr;
/* Get the viewport extension */
pszlViewPortExt = DC_pszlViewportExt(pdc);
/* Check if we need to recalculate */
if (pdcattr->flXform & PAGE_EXTENTS_CHANGED)
/* No shearing / rotation */
FLOATOBJ_SetLong(&pmx->efM12, 0);
FLOATOBJ_SetLong(&pmx->efM21, 0);
/* Calculate scaling */
if (pdcattr->szlWindowExt.cx != 0)
{
/* Check if we need to do isotropic fixup */
if (pdcattr->iMapMode == MM_ISOTROPIC)
{
IntFixIsotropicMapping(pdc);
}
/* Update xforms, CHECKME: really done here? */
DC_UpdateXforms(pdc);
FLOATOBJ_SetLong(&pmx->efM11, pszlViewPortExt->cx);
FLOATOBJ_DivLong(&pmx->efM11, pdcattr->szlWindowExt.cx);
}
else
FLOATOBJ_SetLong(&pmx->efM11, 1);
if (pdcattr->szlWindowExt.cy != 0)
{
FLOATOBJ_SetLong(&pmx->efM22, pszlViewPortExt->cy);
FLOATOBJ_DivLong(&pmx->efM22, pdcattr->szlWindowExt.cy);
}
else
FLOATOBJ_SetLong(&pmx->efM22, 1);
/* Calculate x offset */
FLOATOBJ_SetLong(&pmx->efDx, -pdcattr->ptlWindowOrg.x);
FLOATOBJ_Mul(&pmx->efDx, &pmx->efM11);
FLOATOBJ_AddLong(&pmx->efDx, pdcattr->ptlViewportOrg.x);
/* Calculate y offset */
FLOATOBJ_SetLong(&pmx->efDy, -pdcattr->ptlWindowOrg.y);
FLOATOBJ_Mul(&pmx->efDy, &pmx->efM22);
FLOATOBJ_AddLong(&pmx->efDy, pdcattr->ptlViewportOrg.y);
}
// FIXME: Don't use floating point in the kernel! use XFORMOBJ function
BOOL FASTCALL
IntGdiCombineTransform(
LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2)
VOID
FASTCALL
DC_vUpdateWorldToDevice(PDC pdc)
{
XFORM xformTemp;
XFORMOBJ xoPageToDevice, xoWorldToPage, xoWorldToDevice;
MATRIX mxPageToDevice;
/* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2)
// FIXME: make sure world-to-page is valid!
/* Construct a transformation to do the page-to-device conversion */
DC_vGetPageToDevice(pdc, &mxPageToDevice);
XFORMOBJ_vInit(&xoPageToDevice, &mxPageToDevice);
/* Recalculate the world-to-device xform */
XFORMOBJ_vInit(&xoWorldToPage, &pdc->pdcattr->mxWorldToPage);
XFORMOBJ_vInit(&xoWorldToDevice, &pdc->pdcattr->mxWorldToDevice);
XFORMOBJ_iCombine(&xoWorldToDevice, &xoWorldToPage, &xoPageToDevice);
/* Reset the flags */
pdc->pdcattr->flXform &= ~(PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|WORLD_XFORM_CHANGED);
}
VOID
FASTCALL
DC_vUpdateDeviceToWorld(PDC pdc)
{
XFORMOBJ xoWorldToDevice, xoDeviceToWorld;
PMATRIX pmxWorldToDevice;
/* Get the world-to-device translation */
pmxWorldToDevice = DC_pmxWorldToDevice(pdc);
XFORMOBJ_vInit(&xoWorldToDevice, pmxWorldToDevice);
/* Create inverse of world-to-device transformation */
XFORMOBJ_vInit(&xoDeviceToWorld, &pdc->pdcattr->mxDeviceToWorld);
if (XFORMOBJ_iInverse(&xoDeviceToWorld, &xoWorldToDevice) == DDI_ERROR)
{
return FALSE;
// FIXME: do we need to reset anything?
return;
}
/* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */
xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
*XFormResult = xformTemp;
/* Reset the flag */
pdc->pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
}
BOOL
NTAPI
GreCombineTransform(
XFORML *pxformDest,
XFORML *pxform1,
XFORML *pxform2)
{
MATRIX mxDest, mx1, mx2;
XFORMOBJ xoDest, xo1, xo2;
/* Check for illegal parameters */
if (!pxformDest || !pxform1 || !pxform2) return FALSE;
/* Initialize XFORMOBJs */
XFORMOBJ_vInit(&xoDest, &mxDest);
XFORMOBJ_vInit(&xo1, &mx1);
XFORMOBJ_vInit(&xo2, &mx2);
/* Convert the XFORMLs into XFORMOBJs */
XFORMOBJ_iSetXform(&xo1, pxform1);
XFORMOBJ_iSetXform(&xo2, pxform2);
/* Combine them */
XFORMOBJ_iCombine(&xoDest, &xo1, &xo2);
/* Translate back into XFORML */
XFORMOBJ_iGetXform(&xoDest, pxformDest);
return TRUE;
}
// FIXME: Should be XFORML and use XFORMOBJ functions
BOOL
APIENTRY
NtGdiCombineTransform(
@ -160,9 +261,9 @@ NtGdiCombineTransform(
ProbeForWrite(UnsafeXFormResult, sizeof(XFORM), 1);
ProbeForRead(Unsafexform1, sizeof(XFORM), 1);
ProbeForRead(Unsafexform2, sizeof(XFORM), 1);
Ret = IntGdiCombineTransform(UnsafeXFormResult,
Unsafexform1,
Unsafexform2);
Ret = GreCombineTransform((XFORML*)UnsafeXFormResult,
(XFORML*)Unsafexform1,
(XFORML*)Unsafexform2);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -177,61 +278,71 @@ NtGdiCombineTransform(
BOOL
APIENTRY
NtGdiGetTransform(
HDC hDC,
HDC hdc,
DWORD iXform,
LPXFORM XForm)
LPXFORM pXForm)
{
PDC pdc;
NTSTATUS Status = STATUS_SUCCESS;
BOOL ret = TRUE;
MATRIX mxPageToDevice;
XFORMOBJ xo;
PMATRIX pmx;
if (!XForm)
if (!pXForm)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdc = DC_LockDc(hDC);
pdc = DC_LockDc(hdc);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
switch (iXform)
{
case GdiWorldSpaceToPageSpace:
pmx = DC_pmxWorldToPage(pdc);
break;
case GdiWorldSpaceToDeviceSpace:
pmx = DC_pmxWorldToDevice(pdc);
break;
case GdiDeviceSpaceToWorldSpace:
pmx = DC_pmxDeviceToWorld(pdc);
break;
case GdiPageSpaceToDeviceSpace:
DC_vGetPageToDevice(pdc, &mxPageToDevice);
pmx = &mxPageToDevice;
break;
default:
DPRINT1("Unknown transform %lu\n", iXform);
ret = FALSE;
goto leave;
}
/* Initialize an XFORMOBJ */
XFORMOBJ_vInit(&xo, pmx);
_SEH2_TRY
{
ProbeForWrite(XForm, sizeof(XFORM), 1);
switch (iXform)
{
case GdiWorldSpaceToPageSpace:
MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToPage);
break;
case GdiWorldSpaceToDeviceSpace:
MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToDevice);
break;
case GdiPageSpaceToDeviceSpace:
IntWindowToViewPort(pdc->pdcattr, XForm);
break;
case GdiDeviceSpaceToWorldSpace:
MatrixS2XForm(XForm, &pdc->dclevel.mxDeviceToWorld);
break;
default:
DPRINT1("Unknown transform %lu\n", iXform);
Status = STATUS_INVALID_PARAMETER;
break;
}
ProbeForWrite(pXForm, sizeof(XFORML), 1);
XFORMOBJ_iGetXform(&xo, (XFORML*)pXForm);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
ret = FALSE;
}
_SEH2_END;
leave:
DC_UnlockDc(pdc);
return NT_SUCCESS(Status);
return ret;
}
@ -295,11 +406,11 @@ NtGdiTransformPoints(
switch (iMode)
{
case GdiDpToLp:
IntDPtoLP(pdc, Points, Count);
DC_vXformDeviceToWorld(pdc, Count, Points, Points);
break;
case GdiLpToDp:
IntLPtoDP(pdc, Points, Count);
DC_vXformWorldToDevice(pdc, Count, Points, Points);
break;
case 2: // Not supported yet. Need testing.
@ -331,78 +442,78 @@ leave:
return ret;
}
// FIXME: Don't use floating point in the kernel
BOOL
FASTCALL
IntGdiModifyWorldTransform(
PDC pDc,
CONST LPXFORM lpXForm,
DWORD Mode)
NTAPI
GreModifyWorldTransform(
PDC pdc,
const XFORML *pxform,
DWORD dwMode)
{
XFORM xformWorld2Wnd;
ASSERT(pDc);
MATRIX mxSrc;
XFORMOBJ xoSrc, xoDC;
switch (Mode)
switch (dwMode)
{
case MWT_IDENTITY:
xformWorld2Wnd.eM11 = 1.0f;
xformWorld2Wnd.eM12 = 0.0f;
xformWorld2Wnd.eM21 = 0.0f;
xformWorld2Wnd.eM22 = 1.0f;
xformWorld2Wnd.eDx = 0.0f;
xformWorld2Wnd.eDy = 0.0f;
XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
pdc->pdcattr->mxWorldToPage = gmxIdentity;
break;
case MWT_LEFTMULTIPLY:
MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
IntGdiCombineTransform(&xformWorld2Wnd, lpXForm, &xformWorld2Wnd);
XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
XFORMOBJ_vInit(&xoSrc, &mxSrc);
XFORMOBJ_iSetXform(&xoSrc, pxform);
XFORMOBJ_iCombine(&xoDC, &xoSrc, &xoDC);
break;
case MWT_RIGHTMULTIPLY:
MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
IntGdiCombineTransform(&xformWorld2Wnd, &xformWorld2Wnd, lpXForm);
XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
XFORMOBJ_vInit(&xoSrc, &mxSrc);
XFORMOBJ_iSetXform(&xoSrc, pxform);
XFORMOBJ_iCombine(&xoDC, &xoDC, &xoSrc);
break;
case MWT_MAX+1: // Must be MWT_SET????
XForm2MatrixS(&pDc->dclevel.mxWorldToPage, lpXForm); // Do it like Wine.
XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
XFORMOBJ_iSetXform(&xoDC, pxform);
break;
default:
return FALSE;
}
DC_UpdateXforms(pDc);
/*Set invalidation flags */
pdc->pdcattr->flXform |= WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID;
return TRUE;
}
BOOL
APIENTRY
NtGdiModifyWorldTransform(
HDC hDC,
LPXFORM UnsafeXForm,
DWORD Mode)
HDC hdc,
LPXFORM pxformUnsafe,
DWORD dwMode)
{
PDC dc;
XFORM SafeXForm; // FIXME: Use XFORML
PDC pdc;
XFORML xformSafe;
BOOL Ret = TRUE;
dc = DC_LockDc(hDC);
if (!dc)
pdc = DC_LockDc(hdc);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
// The xform is permitted to be NULL for MWT_IDENTITY.
// However, if it is not NULL, then it must be valid even though it is not used.
if (UnsafeXForm != NULL || Mode != MWT_IDENTITY)
/* The xform is permitted to be NULL for MWT_IDENTITY.
* However, if it is not NULL, then it must be valid even
* though it is not used. */
if (pxformUnsafe != NULL || dwMode != MWT_IDENTITY)
{
_SEH2_TRY
{
ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
ProbeForRead(pxformUnsafe, sizeof(XFORML), 1);
RtlCopyMemory(&xformSafe, pxformUnsafe, sizeof(XFORML));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -411,9 +522,9 @@ NtGdiModifyWorldTransform(
_SEH2_END;
}
// Safe to handle kernel mode data.
if (Ret) Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
DC_UnlockDc(dc);
/* Safe to handle kernel mode data. */
if (Ret) Ret = GreModifyWorldTransform(pdc, &xformSafe, dwMode);
DC_UnlockDc(pdc);
return Ret;
}
@ -469,7 +580,8 @@ NtGdiOffsetViewportOrgEx(
}
pdcattr->ptlViewportOrg.x += XOffset;
pdcattr->ptlViewportOrg.y += YOffset;
DC_UpdateXforms(dc);
pdcattr->flXform |= PAGE_XLATE_CHANGED;
DC_UnlockDc(dc);
return TRUE;
@ -520,8 +632,8 @@ NtGdiOffsetWindowOrgEx(
pdcattr->ptlWindowOrg.x += XOffset;
pdcattr->ptlWindowOrg.y += YOffset;
pdcattr->flXform |= PAGE_XLATE_CHANGED;
DC_UpdateXforms(dc);
DC_UnlockDc(dc);
return TRUE;
@ -554,6 +666,7 @@ NtGdiScaleViewportExtEx(
{
if (Xdenom && Ydenom)
{
DC_pszlViewportExt(pDC);
X = Xnum * pdcattr->szlViewportExt.cx / Xdenom;
if (X)
{
@ -562,6 +675,7 @@ NtGdiScaleViewportExtEx(
{
pdcattr->szlViewportExt.cx = X;
pdcattr->szlViewportExt.cy = Y;
pdcattr->flXform |= PAGE_XLATE_CHANGED;
IntMirrorWindowOrg(pDC);
@ -571,9 +685,8 @@ NtGdiScaleViewportExtEx(
if (pdcattr->iMapMode == MM_ISOTROPIC)
{
IntFixIsotropicMapping(pDC);
DC_vFixIsotropicMapping(pDC);
}
DC_UpdateXforms(pDC);
Ret = TRUE;
}
@ -671,9 +784,6 @@ NtGdiScaleWindowExtEx(
pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
if (pdcattr->iMapMode == MM_ISOTROPIC) IntFixIsotropicMapping(pDC);
DC_UpdateXforms(pDC);
Ret = TRUE;
}
}
@ -698,6 +808,9 @@ IntGdiSetMapMode(
PrevMapMode = pdcattr->iMapMode;
pdcattr->iMapMode = MapMode;
pdcattr->flXform &= ~(ISO_OR_ANISO_MAP_MODE|PTOD_EFM22_NEGATIVE|
PTOD_EFM11_NEGATIVE|POSITIVE_Y_IS_UP|PAGE_TO_DEVICE_SCALE_IDENTITY|
PAGE_TO_DEVICE_IDENTITY);
switch (MapMode)
{
@ -706,10 +819,7 @@ IntGdiSetMapMode(
pdcattr->szlWindowExt.cy = 1;
pdcattr->szlViewportExt.cx = 1;
pdcattr->szlViewportExt.cy = 1;
pdcattr->flXform &= ~(ISO_OR_ANISO_MAP_MODE|PTOD_EFM22_NEGATIVE|
PTOD_EFM11_NEGATIVE|POSITIVE_Y_IS_UP);
pdcattr->flXform |= (PAGE_XLATE_CHANGED|PAGE_TO_DEVICE_SCALE_IDENTITY|
INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
pdcattr->flXform |= PAGE_TO_DEVICE_SCALE_IDENTITY;
break;
case MM_ISOTROPIC:
@ -760,7 +870,9 @@ IntGdiSetMapMode(
pdcattr->iMapMode = PrevMapMode;
PrevMapMode = 0;
}
DC_UpdateXforms(dc);
pdcattr->flXform |= (PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|
INVALIDATE_ATTRIBUTES|DEVICE_TO_PAGE_INVALID|DEVICE_TO_WORLD_INVALID);
return PrevMapMode;
}
@ -811,8 +923,8 @@ NtGdiSetViewportOrgEx(
pdcattr->ptlViewportOrg.x = X;
pdcattr->ptlViewportOrg.y = Y;
pdcattr->flXform |= PAGE_XLATE_CHANGED;
DC_UpdateXforms(dc);
DC_UnlockDc(dc);
return TRUE;
@ -863,8 +975,8 @@ NtGdiSetWindowOrgEx(
pdcattr->ptlWindowOrg.x = X;
pdcattr->ptlWindowOrg.y = Y;
pdcattr->flXform |= PAGE_XLATE_CHANGED;
DC_UpdateXforms(dc);
DC_UnlockDc(dc);
return TRUE;
@ -896,6 +1008,7 @@ IntMirrorWindowOrg(PDC dc)
X = (X * pdcattr->szlWindowExt.cx) / pdcattr->szlViewportExt.cx;
pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx - X; // Now set the inverted win origion.
pdcattr->flXform |= PAGE_XLATE_CHANGED;
return;
}
@ -918,13 +1031,13 @@ DC_vSetLayout(
pdcattr->iMapMode = MM_ANISOTROPIC;
}
pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy;
pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x;
//pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy;
//pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x;
if (wox == -1)
IntMirrorWindowOrg(pdc);
else
pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x;
//if (wox == -1)
// IntMirrorWindowOrg(pdc);
//else
// pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x;
if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT;
@ -956,8 +1069,7 @@ NtGdiSetLayout(
IN DWORD dwLayout)
{
PDC pdc;
PDC_ATTR pdcattr;
DWORD oLayout;
DWORD dwOldLayout;
pdc = DC_LockDc(hdc);
if (!pdc)
@ -965,13 +1077,12 @@ NtGdiSetLayout(
EngSetLastError(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
pdcattr = pdc->pdcattr;
oLayout = pdcattr->dwLayout;
dwOldLayout = pdc->pdcattr->dwLayout;
DC_vSetLayout(pdc, wox, dwLayout);
DC_UnlockDc(pdc);
return oLayout;
return dwOldLayout;
}
/*
@ -1041,7 +1152,6 @@ NtGdiSetSizeDevice(
pdcattr->szlVirtualDeviceSize.cx = cxVirtualDevice;
pdcattr->szlVirtualDeviceSize.cy = cyVirtualDevice;
// DC_UpdateXforms(dc);
DC_UnlockDc(dc);
return TRUE;
@ -1087,51 +1197,19 @@ NtGdiSetVirtualResolution(
pdcattr->szlVirtualDeviceMm.cx = cxVirtualDeviceMm;
pdcattr->szlVirtualDeviceMm.cy = cyVirtualDeviceMm;
// DC_UpdateXforms(dc);
// DC_vUpdateXforms(dc);
DC_UnlockDc(dc);
return TRUE;
}
// FIXME: Don't use floating point in the kernel!
BOOL FASTCALL
DC_InvertXform(const XFORM *xformSrc,
XFORM *xformDest)
{
FLOAT determinant;
determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
if (determinant > -1e-12 && determinant < 1e-12)
{
return FALSE;
}
xformDest->eM11 = xformSrc->eM22 / determinant;
xformDest->eM12 = -xformSrc->eM12 / determinant;
xformDest->eM21 = -xformSrc->eM21 / determinant;
xformDest->eM22 = xformSrc->eM11 / determinant;
xformDest->eDx = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
xformDest->eDy = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;
return TRUE;
}
LONG FASTCALL
IntCalcFillOrigin(PDC pdc)
{
pdc->ptlFillOrigin.x = pdc->dclevel.ptlBrushOrigin.x + pdc->ptlDCOrig.x;
pdc->ptlFillOrigin.y = pdc->dclevel.ptlBrushOrigin.y + pdc->ptlDCOrig.y;
return pdc->ptlFillOrigin.y;
}
PPOINTL
FASTCALL
IntptlBrushOrigin(PDC pdc, LONG x, LONG y )
{
pdc->dclevel.ptlBrushOrigin.x = x;
pdc->dclevel.ptlBrushOrigin.y = y;
IntCalcFillOrigin(pdc);
pdc->ptlFillOrigin.x = pdc->dclevel.ptlBrushOrigin.x + pdc->ptlDCOrig.x;
pdc->ptlFillOrigin.y = pdc->dclevel.ptlBrushOrigin.y + pdc->ptlDCOrig.y;
return &pdc->dclevel.ptlBrushOrigin;
}
@ -1163,6 +1241,7 @@ NtGdiGetDCPoint(
DC *pdc;
POINTL SafePoint;
SIZE Size;
PSIZEL pszlViewportExt;
NTSTATUS Status = STATUS_SUCCESS;
if (!Point)
@ -1181,9 +1260,9 @@ NtGdiGetDCPoint(
switch (iPoint)
{
case GdiGetViewPortExt:
DC_vUpdateViewportExt(pdc);
SafePoint.x = pdc->pdcattr->szlViewportExt.cx;
SafePoint.y = pdc->pdcattr->szlViewportExt.cy;
pszlViewportExt = DC_pszlViewportExt(pdc);
SafePoint.x = pszlViewportExt->cx;
SafePoint.y = pszlViewportExt->cy;
break;
case GdiGetWindowExt:

View file

@ -17,23 +17,6 @@
PSURFACE psurfDefaultBitmap = NULL;
PBRUSH pbrDefaultBrush = NULL;
// FIXME: These should go to floatobj.h or something
#ifdef _M_IX86
#define FLOATOBJ_0 {0x00000000, 0x00000000}
#define FLOATOBJ_1 {0x40000000, 0x00000002}
#define FLOATOBJ_16 {0x40000000, 0x00000006}
#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
#else
#define FLOATOBJ_0 0.
#define FLOATOBJ_1 1.
#define FLOATOBJ_16 16.
#define FLOATOBJ_1_16 (1./16.)
#endif
static const FLOATOBJ gef0 = FLOATOBJ_0;
static const FLOATOBJ gef1 = FLOATOBJ_1;
static const FLOATOBJ gef16 = FLOATOBJ_16;
static const MATRIX gmxWorldToDeviceDefault =
{
FLOATOBJ_16, FLOATOBJ_0,

View file

@ -663,7 +663,7 @@ NtGdiRectangle(HDC hDC,
}
/* Do we rotate or shear? */
if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
if (!(dc->dclevel.mxWorldToDevice.flAccel & XFORM_SCALE))
{
POINTL DestCoords[4];
ULONG PolyCounts = 4;

View file

@ -1424,8 +1424,7 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
/* Save the mapping mode info */
mapMode = pdcattr->iMapMode;
DC_vUpdateViewportExt(dc);
szViewportExt = dc->pdcattr->szlViewportExt;
szViewportExt = *DC_pszlViewportExt(dc);
ptViewportOrg = dc->pdcattr->ptlViewportOrg;
szWindowExt = dc->pdcattr->szlWindowExt;
ptWindowOrg = dc->pdcattr->ptlWindowOrg;
@ -1440,7 +1439,7 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
pdcattr->ptlWindowOrg.y = 0;
graphicsMode = pdcattr->iGraphicsMode;
pdcattr->iGraphicsMode = GM_ADVANCED;
IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY);
GreModifyWorldTransform(dc, (XFORML*)&xform, MWT_IDENTITY);
pdcattr->iGraphicsMode = graphicsMode;
/* Allocate enough memory for the worst case without beziers (one PT_MOVETO

View file

@ -95,13 +95,13 @@ FORCEINLINE
ULONG
HintFromAccel(ULONG flAccel)
{
switch (flAccel & (MX_NOTRANSLATE | MX_IDENTITYSCALE | MX_SCALE))
switch (flAccel & (XFORM_SCALE|XFORM_UNITY|XFORM_NO_TRANSLATION))
{
case (MX_SCALE | MX_IDENTITYSCALE | MX_NOTRANSLATE):
case (XFORM_SCALE|XFORM_UNITY|XFORM_NO_TRANSLATION):
return GX_IDENTITY;
case (MX_SCALE | MX_IDENTITYSCALE):
case (XFORM_SCALE|XFORM_UNITY):
return GX_OFFSET;
case MX_SCALE:
case XFORM_SCALE:
return GX_SCALE;
default:
return GX_GENERAL;
@ -126,25 +126,25 @@ XFORMOBJ_UpdateAccel(
if (FLOATOBJ_Equal0(&pmx->efDx) &&
FLOATOBJ_Equal0(&pmx->efDy))
{
pmx->flAccel |= MX_NOTRANSLATE;
pmx->flAccel |= XFORM_NO_TRANSLATION;
}
if (FLOATOBJ_Equal0(&pmx->efM12) &&
FLOATOBJ_Equal0(&pmx->efM21))
{
pmx->flAccel |= MX_SCALE;
pmx->flAccel |= XFORM_SCALE;
}
if (FLOATOBJ_Equal1(&pmx->efM11) &&
FLOATOBJ_Equal1(&pmx->efM22))
{
pmx->flAccel |= MX_IDENTITYSCALE;
pmx->flAccel |= XFORM_UNITY;
}
if (FLOATOBJ_IsLong(&pmx->efM11) && FLOATOBJ_IsLong(&pmx->efM12) &&
FLOATOBJ_IsLong(&pmx->efM21) && FLOATOBJ_IsLong(&pmx->efM22))
{
pmx->flAccel |= MX_INTEGER;
pmx->flAccel |= XFORM_INTEGER;
}
return HintFromAccel(pmx->flAccel);
@ -253,10 +253,18 @@ XFORMOBJ_iInverse(
{
PMATRIX pmxDst, pmxSrc;
FLOATOBJ foDet;
XFORM xformSrc;
union
{
FLOAT Float;
LONG Long;
} eDet;
pmxDst = XFORMOBJ_pmx(pxoDst);
pmxSrc = XFORMOBJ_pmx(pxoSrc);
XFORMOBJ_iGetXform(pxoSrc, (XFORML*)&xformSrc);
/* det = M11 * M22 - M12 * M21 */
MulSub(&foDet, &pmxSrc->efM11, &pmxSrc->efM22, &pmxSrc->efM12, &pmxSrc->efM21);
@ -266,6 +274,8 @@ XFORMOBJ_iInverse(
return DDI_ERROR;
}
eDet.Long = FLOATOBJ_GetFloat(&foDet);
/* Calculate adj(A) / det(A) */
pmxDst->efM11 = pmxSrc->efM22;
FLOATOBJ_Div(&pmxDst->efM11, &foDet);
@ -274,10 +284,10 @@ XFORMOBJ_iInverse(
/* The other 2 are negative, negate foDet for that */
FLOATOBJ_Neg(&foDet);
pmxDst->efM12 = pmxSrc->efM21;
pmxDst->efM12 = pmxSrc->efM12;
FLOATOBJ_Div(&pmxDst->efM12, &foDet);
pmxDst->efM21 = pmxSrc->efM12;
FLOATOBJ_Div(&pmxDst->efM22, &foDet);
pmxDst->efM21 = pmxSrc->efM21;
FLOATOBJ_Div(&pmxDst->efM21, &foDet);
/* Update accelerators and return complexity */
return XFORMOBJ_UpdateAccel(pxoDst);
@ -300,13 +310,13 @@ XFORMOBJ_bXformFixPoints(
pmx = XFORMOBJ_pmx(pxo);
flAccel = pmx->flAccel;
if ((flAccel & (MX_SCALE|MX_IDENTITYSCALE)) == (MX_SCALE|MX_IDENTITYSCALE))
if ((flAccel & (XFORM_SCALE|XFORM_UNITY)) == (XFORM_SCALE|XFORM_UNITY))
{
/* Identity transformation, nothing todo */
}
else if (flAccel & MX_INTEGER)
else if (flAccel & XFORM_INTEGER)
{
if (flAccel & MX_IDENTITYSCALE)
if (flAccel & XFORM_UNITY)
{
/* 1-scale integer transform */
i = cPoints - 1;
@ -319,7 +329,7 @@ XFORMOBJ_bXformFixPoints(
}
while (--i >= 0);
}
else if (flAccel & MX_SCALE)
else if (flAccel & XFORM_SCALE)
{
/* Diagonal integer transform */
i = cPoints - 1;
@ -346,7 +356,7 @@ XFORMOBJ_bXformFixPoints(
while (--i >= 0);
}
}
else if (flAccel & MX_IDENTITYSCALE)
else if (flAccel & XFORM_UNITY)
{
/* 1-scale transform */
i = cPoints - 1;
@ -361,7 +371,7 @@ XFORMOBJ_bXformFixPoints(
}
while (--i >= 0);
}
else if (flAccel & MX_SCALE)
else if (flAccel & XFORM_SCALE)
{
/* Diagonal float transform */
i = cPoints - 1;
@ -390,13 +400,12 @@ XFORMOBJ_bXformFixPoints(
while (--i >= 0);
}
if (!(pmx->flAccel & MX_NOTRANSLATE))
if (!(pmx->flAccel & XFORM_NO_TRANSLATION))
{
/* Translate points */
i = cPoints - 1;
do
{
// DPRINT1("Translating Points (%d,%d)->(%d,%d)\n", pptOut[i].x, pptOut[i].y, pptOut[i].x + pmx->fxDx, pptOut[i].y + pmx->fxDy);
pptOut[i].x += pmx->fxDx;
pptOut[i].y += pmx->fxDy;
}