From 6a17ab3c5e351401fbf2b548b6f8f73033e68e71 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 28 Jul 2012 18:31:24 +0000 Subject: [PATCH] [WIN32K] - Take translation into account when inverting an XFORMOBJ - Always use the matrices from the DCATTR instead of DCLEVEL - Mark Device-to-World translation as invalid when the Window Origin is modified Fixes 7088 See issue #7088 for more details. svn path=/trunk/; revision=56970 --- reactos/win32ss/gdi/ntgdi/coord.c | 4 +--- reactos/win32ss/gdi/ntgdi/fillshap.c | 2 +- reactos/win32ss/gdi/ntgdi/freetype.c | 2 +- reactos/win32ss/gdi/ntgdi/gdifloat.h | 4 ++-- reactos/win32ss/gdi/ntgdi/path.c | 8 ++++---- reactos/win32ss/gdi/ntgdi/xformobj.c | 10 ++++++++++ 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/coord.c b/reactos/win32ss/gdi/ntgdi/coord.c index d3a1a661782..f4fb6262478 100644 --- a/reactos/win32ss/gdi/ntgdi/coord.c +++ b/reactos/win32ss/gdi/ntgdi/coord.c @@ -635,7 +635,7 @@ NtGdiOffsetWindowOrgEx( pdcattr->ptlWindowOrg.x += XOffset; pdcattr->ptlWindowOrg.y += YOffset; - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID; DC_UnlockDc(dc); @@ -1052,8 +1052,6 @@ DC_vSetLayout( pdcattr->flXform |= (PAGE_EXTENTS_CHANGED | INVALIDATE_ATTRIBUTES | DEVICE_TO_WORLD_INVALID); - -// DC_UpdateXforms(pdc); } // NtGdiSetLayout diff --git a/reactos/win32ss/gdi/ntgdi/fillshap.c b/reactos/win32ss/gdi/ntgdi/fillshap.c index 846398d11a9..551bea4f74b 100644 --- a/reactos/win32ss/gdi/ntgdi/fillshap.c +++ b/reactos/win32ss/gdi/ntgdi/fillshap.c @@ -663,7 +663,7 @@ NtGdiRectangle(HDC hDC, } /* Do we rotate or shear? */ - if (!(dc->dclevel.mxWorldToDevice.flAccel & XFORM_SCALE)) + if (!(dc->pdcattr->mxWorldToDevice.flAccel & XFORM_SCALE)) { POINTL DestCoords[4]; ULONG PolyCounts = 4; diff --git a/reactos/win32ss/gdi/ntgdi/freetype.c b/reactos/win32ss/gdi/ntgdi/freetype.c index 9461b117c1c..201cb9bd197 100644 --- a/reactos/win32ss/gdi/ntgdi/freetype.c +++ b/reactos/win32ss/gdi/ntgdi/freetype.c @@ -1490,7 +1490,7 @@ ftGdiGetGlyphOutline( pdcattr = dc->pdcattr; - MatrixS2XForm(&xForm, &dc->dclevel.mxWorldToDevice); + MatrixS2XForm(&xForm, &dc->pdcattr->mxWorldToDevice); eM11 = xForm.eM11; hFont = pdcattr->hlfntNew; diff --git a/reactos/win32ss/gdi/ntgdi/gdifloat.h b/reactos/win32ss/gdi/ntgdi/gdifloat.h index 566388fc7fe..25bd1b2969b 100644 --- a/reactos/win32ss/gdi/ntgdi/gdifloat.h +++ b/reactos/win32ss/gdi/ntgdi/gdifloat.h @@ -23,8 +23,8 @@ static __inline void INTERNAL_LPTODP_FLOAT(DC *dc, FLOAT_POINT *point) { FLOAT x, y; XFORM xformWorld2Vport; - - MatrixS2XForm(&xformWorld2Vport, &dc->dclevel.mxWorldToDevice); + + MatrixS2XForm(&xformWorld2Vport, &dc->pdcattr->mxWorldToDevice); /* Perform the transformation */ x = point->x; diff --git a/reactos/win32ss/gdi/ntgdi/path.c b/reactos/win32ss/gdi/ntgdi/path.c index 315b95e21e5..bfafeec9bee 100644 --- a/reactos/win32ss/gdi/ntgdi/path.c +++ b/reactos/win32ss/gdi/ntgdi/path.c @@ -76,7 +76,7 @@ GdiPathDPtoLP(PDC pdc, PPOINT ppt, INT count) { XFORMOBJ xo; - XFORMOBJ_vInit(&xo, &pdc->dclevel.mxDeviceToWorld); + XFORMOBJ_vInit(&xo, &pdc->pdcattr->mxDeviceToWorld); return XFORMOBJ_bApplyXform(&xo, XF_LTOL, count, (PPOINTL)ppt, (PPOINTL)ppt); } @@ -124,7 +124,7 @@ PATH_FillPath( PDC dc, PPATH pPath ) * tests show that resetting the graphics mode to GM_COMPATIBLE does * not reset the world transform. */ - MatrixS2XForm(&xform, &dc->dclevel.mxWorldToPage); + MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage); /* Set MM_TEXT */ // IntGdiSetMapMode( dc, MM_TEXT ); @@ -1429,7 +1429,7 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath) szWindowExt = dc->pdcattr->szlWindowExt; ptWindowOrg = dc->pdcattr->ptlWindowOrg; - MatrixS2XForm(&xform, &dc->dclevel.mxWorldToPage); + MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage); /* Set MM_TEXT */ pdcattr->iMapMode = MM_TEXT; @@ -1556,7 +1556,7 @@ end: pdcattr->ptlViewportOrg.y = ptViewportOrg.y; /* Restore the world transform */ - XForm2MatrixS(&dc->dclevel.mxWorldToPage, &xform); + XForm2MatrixS(&dc->pdcattr->mxWorldToPage, &xform); /* If we've moved the current point then get its new position which will be in device (MM_TEXT) co-ords, convert it to diff --git a/reactos/win32ss/gdi/ntgdi/xformobj.c b/reactos/win32ss/gdi/ntgdi/xformobj.c index 6492174439d..a4b0b185ef1 100644 --- a/reactos/win32ss/gdi/ntgdi/xformobj.c +++ b/reactos/win32ss/gdi/ntgdi/xformobj.c @@ -289,6 +289,16 @@ XFORMOBJ_iInverse( pmxDst->efM21 = pmxSrc->efM21; FLOATOBJ_Div(&pmxDst->efM21, &foDet); + /* Calculate the inverted x shift: Dx' = -Dx * M11' - Dy * M21' */ + pmxDst->efDx = pmxSrc->efDx; + FLOATOBJ_Neg(&pmxDst->efDx); + MulSub(&pmxDst->efDx, &pmxDst->efDx, &pmxDst->efM11, &pmxSrc->efDy, &pmxDst->efM21); + + /* Calculate the inverted y shift: Dy' = -Dy * M22' - Dx * M12' */ + pmxDst->efDy = pmxSrc->efDy; + FLOATOBJ_Neg(&pmxDst->efDy); + MulSub(&pmxDst->efDy, &pmxDst->efDy, &pmxDst->efM22, &pmxSrc->efDx, &pmxDst->efM12); + /* Update accelerators and return complexity */ return XFORMOBJ_UpdateAccel(pxoDst); }