diff --git a/win32ss/gdi/ntgdi/coord.c b/win32ss/gdi/ntgdi/coord.c index 58d236581b..0f7c1ed191 100644 --- a/win32ss/gdi/ntgdi/coord.c +++ b/win32ss/gdi/ntgdi/coord.c @@ -213,7 +213,7 @@ DC_vUpdateDeviceToWorld(PDC pdc) XFORMOBJ_vInit(&xoDeviceToWorld, &pdc->pdcattr->mxDeviceToWorld); if (XFORMOBJ_iInverse(&xoDeviceToWorld, &xoWorldToDevice) == DDI_ERROR) { - // FIXME: do we need to reset anything? + MX_Set0(&pdc->pdcattr->mxDeviceToWorld); return; } @@ -411,6 +411,13 @@ NtGdiTransformPoints( switch (iMode) { case GdiDpToLp: + if (pdc->pdcattr->iMapMode == MM_ISOTROPIC && + (pdc->pdcattr->szlViewportExt.cx * pdc->pdcattr->szlWindowExt.cy != + pdc->pdcattr->szlWindowExt.cx * pdc->pdcattr->szlViewportExt.cy)) + { + ret = FALSE; + goto leave; + } DC_vXformDeviceToWorld(pdc, Count, Points, Points); break; @@ -595,7 +602,7 @@ NtGdiOffsetViewportOrgEx( } pdcattr->ptlViewportOrg.x += XOffset; pdcattr->ptlViewportOrg.y += YOffset; - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED | DEVICE_TO_WORLD_INVALID; DC_UnlockDc(dc); @@ -921,7 +928,7 @@ GreSetViewportOrgEx( pdcattr->ptlViewportOrg.x = X; pdcattr->ptlViewportOrg.y = Y; - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED | DEVICE_TO_WORLD_INVALID; DC_UnlockDc(dc); return TRUE; @@ -972,7 +979,7 @@ NtGdiSetViewportOrgEx( pdcattr->ptlViewportOrg.x = X; pdcattr->ptlViewportOrg.y = Y; - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED | DEVICE_TO_WORLD_INVALID; DC_UnlockDc(dc); @@ -1024,7 +1031,7 @@ NtGdiSetWindowOrgEx( pdcattr->ptlWindowOrg.x = X; pdcattr->ptlWindowOrg.y = Y; - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED | DEVICE_TO_WORLD_INVALID; DC_UnlockDc(dc); @@ -1060,7 +1067,7 @@ IntMirrorWindowOrg(PDC dc) X = (X * pdcattr->szlWindowExt.cx) / cx; pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx - X; // Now set the inverted win origion. - pdcattr->flXform |= PAGE_XLATE_CHANGED; + pdcattr->flXform |= PAGE_XLATE_CHANGED | DEVICE_TO_WORLD_INVALID; return; } diff --git a/win32ss/gdi/ntgdi/coord.h b/win32ss/gdi/ntgdi/coord.h index 9993ef527a..2cb5af0298 100644 --- a/win32ss/gdi/ntgdi/coord.h +++ b/win32ss/gdi/ntgdi/coord.h @@ -131,6 +131,9 @@ DC_vXformDeviceToWorld( PMATRIX pmx; pmx = DC_pmxDeviceToWorld(pdc); + if (!MX_IsValid(pmx)) + return; + XFORMOBJ_vInit(&xo, pmx); XFORMOBJ_bApplyXform(&xo, XF_LTOL, cNumPoints, pptlDest, pptlSource); } diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index 0d938df687..ea798f1e7b 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -243,6 +243,25 @@ XFORMOBJ_iCombineXform( } } +BOOL FASTCALL +MX_IsValid(IN PMATRIX pmx) +{ + FLOATOBJ foDet; + MulSub(&foDet, &pmx->efM11, &pmx->efM22, &pmx->efM12, &pmx->efM21); + return !FLOATOBJ_Equal0(&foDet); +} + +VOID FASTCALL +MX_Set0(OUT PMATRIX pmx) +{ + FLOATOBJ_Set0(&pmx->efM11); + FLOATOBJ_Set0(&pmx->efM12); + FLOATOBJ_Set0(&pmx->efM21); + FLOATOBJ_Set0(&pmx->efM22); + FLOATOBJ_Set0(&pmx->efDx); + FLOATOBJ_Set0(&pmx->efDy); +} + /* * A^-1 = adj(A) / det(AT) * A^-1 = 1/(a*d - b*c) * (a22,-a12,a21,-a11) diff --git a/win32ss/gdi/ntgdi/xformobj.h b/win32ss/gdi/ntgdi/xformobj.h index 4adeb3d818..4cb9dd3bf9 100644 --- a/win32ss/gdi/ntgdi/xformobj.h +++ b/win32ss/gdi/ntgdi/xformobj.h @@ -74,3 +74,6 @@ XFORMOBJ_bApplyXform( IN ULONG cPoints, IN PVOID pvIn, OUT PVOID pvOut); + +BOOL FASTCALL MX_IsValid(IN PMATRIX pmx); +VOID FASTCALL MX_Set0(OUT PMATRIX pmx);