Author: tkreuzer Date: Mon Mar 26 14:35:58 2012 New Revision: 56236
URL: http://svn.reactos.org/svn/reactos?rev=56236&view=rev Log: [WIN32K] - 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.
Modified: trunk/reactos/include/reactos/win32k/ntgdityp.h trunk/reactos/subsystems/win32/win32k/eng/i386/floatobj.S trunk/reactos/subsystems/win32/win32k/include/coord.h trunk/reactos/subsystems/win32/win32k/include/floatobj.h trunk/reactos/subsystems/win32/win32k/include/intgdi.h trunk/reactos/subsystems/win32/win32k/objects/coord.c trunk/reactos/subsystems/win32/win32k/objects/dclife.c trunk/reactos/subsystems/win32/win32k/objects/fillshap.c trunk/reactos/subsystems/win32/win32k/objects/path.c trunk/reactos/subsystems/win32/win32k/objects/xformobj.c
Modified: trunk/reactos/include/reactos/win32k/ntgdityp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntgd... ============================================================================== --- trunk/reactos/include/reactos/win32k/ntgdityp.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/win32k/ntgdityp.h [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -100,10 +100,16 @@ /* 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 struct _DRIVER_FUNCTIONS { - PFN_DrvEnablePDEV EnablePDEV; + PFN_DrvEnablePDEV EnablePDEV; PFN_DrvCompletePDEV CompletePDEV; PFN_DrvDisablePDEV DisablePDEV; PFN_DrvEnableSurface EnableSurface; @@ -584,10 +590,10 @@ 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 @@ PVOID Reserved9; PVOID Reserved10; PVOID Reserved11; /* 92 */ - + /* ReactOS specify */ PFN_DrvEnableDriver EnableDriver; //ReactOS Extra } DRIVER_FUNCTIONS, *PDRIVER_FUNCTIONS;
Modified: trunk/reactos/subsystems/win32/win32k/eng/i386/floatobj.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/eng... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/eng/i386/floatobj.S [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/eng/i386/floatobj.S [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -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
Modified: trunk/reactos/subsystems/win32/win32k/include/coord.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/coord.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/coord.h [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -45,8 +45,72 @@ XFORMOBJ_iGetXform(&xo, pxformDest); }
+VOID +FASTCALL +DC_vFixIsotropicMapping(PDC pdc); + +VOID +FASTCALL +DC_vUpdateWorldToDevice(PDC pdc); + +VOID +FASTCALL +DC_vUpdateDeviceToWorld(PDC pdc); + +PSIZEL FORCEINLINE -void +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 DC_vXformDeviceToWorld( IN PDC pdc, IN ULONG cNumPoints, @@ -54,13 +118,15 @@ 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 @@ 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);
Modified: trunk/reactos/subsystems/win32/win32k/include/floatobj.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/floatobj.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/floatobj.h [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -1,6 +1,6 @@ #pragma once
-#if defined(_X86_) +#if defined(_M_IX86)
FORCEINLINE BOOL @@ -54,6 +54,15 @@ 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 @@ #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
Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -80,13 +80,6 @@ CONST PDEVMODEW InitData, BOOL CreateAsIC);
-/* Coord functions */ - -BOOL FASTCALL -IntGdiCombineTransform(LPXFORM XFormResult, - LPXFORM xform1, - LPXFORM xform2); - /* Stock objects */
VOID FASTCALL
Modified: trunk/reactos/subsystems/win32/win32k/objects/coord.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/coord.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/coord.c [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -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) - { - /* Don't recalculate */ + if ((szlWindowExt.cx == 0) || (szlWindowExt.cy == 0) || + (szlViewportExt.cx == 0) || (szlViewportExt.cy == 0)) + { + /* 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); - - if (fy > fx) - { - s = pdcattr->szlWindowExt.cy * pdcattr->szlViewportExt.cx > 0 ? 1 : -1; - pdcattr->szlViewportExt.cx = s * fx / pdcattr->szlWindowExt.cy; + fx = abs((LONG64)szlWindowExt.cx * szlViewportExt.cy); + fy = abs((LONG64)szlWindowExt.cy * szlViewportExt.cx); + + if (fx < fy) + { + 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; - } - - /* Update transformation matrices */ - XForm2MatrixS(&dc->dclevel.mxWorldToDevice, &xformWorld2Vport); - XForm2MatrixS(&dc->dclevel.mxDeviceToWorld, &xformVport2World); + s = (szlWindowExt.cx ^ szlViewportExt.cy) > 0 ? 1 : -1; + pdcattr->szlViewportExt.cy = (LONG)(fy * s / szlWindowExt.cx); + } + + /* Reset the flag */ + pdc->pdcattr->flXform &= ~PAGE_EXTENTS_CHANGED; }
VOID FASTCALL -DC_vUpdateViewportExt(PDC pdc) -{ - PDC_ATTR pdcattr; - - /* Get a pointer to the dc attribute */ - pdcattr = pdc->pdcattr; - - /* Check if we need to recalculate */ - if (pdcattr->flXform & PAGE_EXTENTS_CHANGED) - { - /* Check if we need to do isotropic fixup */ - if (pdcattr->iMapMode == MM_ISOTROPIC) - { - IntFixIsotropicMapping(pdc); - } - - /* Update xforms, CHECKME: really done here? */ - DC_UpdateXforms(pdc); - } -} - -// FIXME: Don't use floating point in the kernel! use XFORMOBJ function -BOOL FASTCALL -IntGdiCombineTransform( - LPXFORM XFormResult, - LPXFORM xform1, - LPXFORM xform2) -{ - XFORM xformTemp; +DC_vGetPageToDevice(PDC pdc, MATRIX *pmx) +{ + PDC_ATTR pdcattr = pdc->pdcattr; + PSIZEL pszlViewPortExt; + + /* Get the viewport extension */ + pszlViewPortExt = DC_pszlViewportExt(pdc); + + /* No shearing / rotation */ + FLOATOBJ_SetLong(&pmx->efM12, 0); + FLOATOBJ_SetLong(&pmx->efM21, 0); + + /* Calculate scaling */ + if (pdcattr->szlWindowExt.cx != 0) + { + 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); +} + +VOID +FASTCALL +DC_vUpdateWorldToDevice(PDC pdc) +{ + XFORMOBJ xoPageToDevice, xoWorldToPage, xoWorldToDevice; + MATRIX mxPageToDevice; + + // 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) + { + // FIXME: do we need to reset anything? + return; + } + + /* 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 (!XFormResult || !xform1 || !xform2) - { - return FALSE; - } - - /* 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; + 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 @@ 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 @@ BOOL APIENTRY NtGdiGetTransform( - HDC hDC, + HDC hdc, DWORD iXform, - LPXFORM XForm) + LPXFORM pXForm) { PDC pdc; - NTSTATUS Status = STATUS_SUCCESS; - - if (!XForm) + BOOL ret = TRUE; + MATRIX mxPageToDevice; + XFORMOBJ xo; + PMATRIX pmx; + + 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 @@ 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 @@ return ret; }
-// FIXME: Don't use floating point in the kernel -BOOL -FASTCALL -IntGdiModifyWorldTransform( - PDC pDc, - CONST LPXFORM lpXForm, - DWORD Mode) -{ - XFORM xformWorld2Wnd; - ASSERT(pDc); - - switch (Mode) +BOOL +NTAPI +GreModifyWorldTransform( + PDC pdc, + const XFORML *pxform, + DWORD dwMode) +{ + MATRIX mxSrc; + XFORMOBJ xoSrc, xoDC; + + 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) -{ - PDC dc; - XFORM SafeXForm; // FIXME: Use XFORML + HDC hdc, + LPXFORM pxformUnsafe, + DWORD dwMode) +{ + 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 @@ _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 @@ } 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 @@
pdcattr->ptlWindowOrg.x += XOffset; pdcattr->ptlWindowOrg.y += YOffset; - - DC_UpdateXforms(dc); + pdcattr->flXform |= PAGE_XLATE_CHANGED; + DC_UnlockDc(dc);
return TRUE; @@ -554,6 +666,7 @@ { if (Xdenom && Ydenom) { + DC_pszlViewportExt(pDC); X = Xnum * pdcattr->szlViewportExt.cx / Xdenom; if (X) { @@ -562,6 +675,7 @@ { pdcattr->szlViewportExt.cx = X; pdcattr->szlViewportExt.cy = Y; + pdcattr->flXform |= PAGE_XLATE_CHANGED;
IntMirrorWindowOrg(pDC);
@@ -571,9 +685,8 @@
if (pdcattr->iMapMode == MM_ISOTROPIC) { - IntFixIsotropicMapping(pDC); + DC_vFixIsotropicMapping(pDC); } - DC_UpdateXforms(pDC);
Ret = TRUE; } @@ -671,9 +784,6 @@
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 @@ 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 @@ 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 @@ 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 @@
pdcattr->ptlViewportOrg.x = X; pdcattr->ptlViewportOrg.y = Y; - - DC_UpdateXforms(dc); + pdcattr->flXform |= PAGE_XLATE_CHANGED; + DC_UnlockDc(dc);
return TRUE; @@ -863,8 +975,8 @@
pdcattr->ptlWindowOrg.x = X; pdcattr->ptlWindowOrg.y = Y; - - DC_UpdateXforms(dc); + pdcattr->flXform |= PAGE_XLATE_CHANGED; + DC_UnlockDc(dc);
return TRUE; @@ -896,6 +1008,7 @@ 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 @@ pdcattr->iMapMode = MM_ANISOTROPIC; }
- 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; + //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 (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT;
@@ -956,8 +1069,7 @@ IN DWORD dwLayout) { PDC pdc; - PDC_ATTR pdcattr; - DWORD oLayout; + DWORD dwOldLayout;
pdc = DC_LockDc(hdc); if (!pdc) @@ -965,13 +1077,12 @@ 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 @@ pdcattr->szlVirtualDeviceSize.cx = cxVirtualDevice; pdcattr->szlVirtualDeviceSize.cy = cyVirtualDevice;
-// DC_UpdateXforms(dc); DC_UnlockDc(dc);
return TRUE; @@ -1087,42 +1197,9 @@ 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 @@ -1131,7 +1208,8 @@ { 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 @@ DC *pdc; POINTL SafePoint; SIZE Size; + PSIZEL pszlViewportExt; NTSTATUS Status = STATUS_SUCCESS;
if (!Point) @@ -1181,9 +1260,9 @@ 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:
Modified: trunk/reactos/subsystems/win32/win32k/objects/dclife.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -16,23 +16,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 = {
Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -663,7 +663,7 @@ }
/* 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;
Modified: trunk/reactos/subsystems/win32/win32k/objects/path.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -1424,8 +1424,7 @@ /* 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 @@ 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
Modified: trunk/reactos/subsystems/win32/win32k/objects/xformobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/xformobj.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/xformobj.c [iso-8859-1] Mon Mar 26 14:35:58 2012 @@ -95,13 +95,13 @@ ULONG HintFromAccel(ULONG flAccel) { - switch (flAccel & (MX_NOTRANSLATE | MX_IDENTITYSCALE | MX_SCALE)) - { - case (MX_SCALE | MX_IDENTITYSCALE | MX_NOTRANSLATE): + switch (flAccel & (XFORM_SCALE|XFORM_UNITY|XFORM_NO_TRANSLATION)) + { + 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 @@ 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 @@ { 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);
@@ -265,6 +273,8 @@ /* Determinant is 0! */ return DDI_ERROR; } + + eDet.Long = FLOATOBJ_GetFloat(&foDet);
/* Calculate adj(A) / det(A) */ pmxDst->efM11 = pmxSrc->efM22; @@ -274,10 +284,10 @@
/* 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 @@ 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) - { - if (flAccel & MX_IDENTITYSCALE) + else if (flAccel & XFORM_INTEGER) + { + if (flAccel & XFORM_UNITY) { /* 1-scale integer transform */ i = cPoints - 1; @@ -319,7 +329,7 @@ } while (--i >= 0); } - else if (flAccel & MX_SCALE) + else if (flAccel & XFORM_SCALE) { /* Diagonal integer transform */ i = cPoints - 1; @@ -346,7 +356,7 @@ while (--i >= 0); } } - else if (flAccel & MX_IDENTITYSCALE) + else if (flAccel & XFORM_UNITY) { /* 1-scale transform */ i = cPoints - 1; @@ -361,7 +371,7 @@ } while (--i >= 0); } - else if (flAccel & MX_SCALE) + else if (flAccel & XFORM_SCALE) { /* Diagonal float transform */ i = cPoints - 1; @@ -390,13 +400,12 @@ 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; }