From: Katayama Hirofumi MZ Date: Mon, 29 Apr 2019 05:45:44 +0000 (+0900) Subject: [WIN32SS][NTGDI][GDI32] Fix DPtoLP and NtGdiTransformPoints etc. (#1540) X-Git-Tag: 0.4.14-dev~1088 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=8bdfdd5c17426b04f0451192e6f3fb12e0598161 [WIN32SS][NTGDI][GDI32] Fix DPtoLP and NtGdiTransformPoints etc. (#1540) Fix NtGdiTransformPoints, gdi32!DPtoLP, gdi32!LPtoDP and gdi32!SetMapMode functions. Fix CORE-15983. CORE-15983 --- diff --git a/win32ss/gdi/gdi32/objects/coord.c b/win32ss/gdi/gdi32/objects/coord.c index dd74b339462..a42fa1236b0 100644 --- a/win32ss/gdi/gdi32/objects/coord.c +++ b/win32ss/gdi/gdi32/objects/coord.c @@ -171,28 +171,35 @@ DPtoLP( _Inout_updates_(nCount) LPPOINT lpPoints, _In_ INT nCount) { -#if 0 - INT i; PDC_ATTR pdcattr; + SIZEL sizlView; - /* Get the DC attribute */ - pdcattr = GdiGetDcAttr(hdc); - if (!pdcattr) + if (nCount <= 0) + return TRUE; + + if (hdc == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - if (pdcattr->flXform & ANY_XFORM_CHANGES) + if (lpPoints == NULL) { - GdiFixupTransforms(pdcattr); + return TRUE; } - // FIXME: can this fail on Windows? - GdiTransformPoints(&pdcattr->mxDeviceToWorld, lpPoints, lpPoints, nCount); + pdcattr = GdiGetDcAttr(hdc); + if (pdcattr == NULL) + return FALSE; + + if (pdcattr->iMapMode == MM_ISOTROPIC) + { + if (NtGdiGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)&sizlView)) + { + if (sizlView.cx == 0 || sizlView.cy == 0) + return FALSE; + } + } - return TRUE; -#endif return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp); } @@ -203,28 +210,25 @@ LPtoDP( _Inout_updates_(nCount) LPPOINT lpPoints, _In_ INT nCount) { -#if 0 - INT i; PDC_ATTR pdcattr; - /* Get the DC attribute */ - pdcattr = GdiGetDcAttr(hdc); - if (!pdcattr) + if (nCount <= 0) + return TRUE; + + if (hdc == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - if (pdcattr->flXform & ANY_XFORM_CHANGES) + if (lpPoints == NULL) { - GdiFixupTransforms(pdcattr); + return TRUE; } - // FIXME: can this fail on Windows? - GdiTransformPoints(&pdcattr->mxWorldToDevice, lpPoints, lpPoints, nCount); + pdcattr = GdiGetDcAttr(hdc); + if (pdcattr == NULL) + return FALSE; - return TRUE; -#endif return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp); } @@ -490,6 +494,9 @@ SetViewportExtEx( (pdcattr->szlViewportExt.cy == nYExtent)) return TRUE; + if (nXExtent == 0 || nYExtent == 0) + return TRUE; + /* Only change viewport extension if we are in iso or aniso mode */ if ((pdcattr->iMapMode == MM_ISOTROPIC) || (pdcattr->iMapMode == MM_ANISOTROPIC)) @@ -512,7 +519,8 @@ SetViewportExtEx( NtGdiMirrorWindowOrg(hdc); /* Update xform flags */ - pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); + pdcattr->flXform |= (PAGE_EXTENTS_CHANGED | INVALIDATE_ATTRIBUTES | + DEVICE_TO_WORLD_INVALID); } return TRUE; diff --git a/win32ss/gdi/ntgdi/coord.c b/win32ss/gdi/ntgdi/coord.c index 58d236581b3..adaee5f0abb 100644 --- a/win32ss/gdi/ntgdi/coord.c +++ b/win32ss/gdi/ntgdi/coord.c @@ -3,7 +3,8 @@ * PROJECT: ReactOS kernel * PURPOSE: Coordinate systems * FILE: win32ss/gdi/ntgdi/coord.c - * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org) + * PROGRAMERS: Timo Kreuzer (timo.kreuzer@rectos.org) + * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ /* Coordinate translation overview @@ -195,7 +196,7 @@ DC_vUpdateWorldToDevice(PDC pdc) XFORMOBJ_iCombine(&xoWorldToDevice, &xoWorldToPage, &xoPageToDevice); /* Reset the flags */ - pdc->pdcattr->flXform &= ~(PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|WORLD_XFORM_CHANGED); + pdc->pdcattr->flXform &= ~WORLD_XFORM_CHANGED; } VOID @@ -213,7 +214,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; } @@ -377,10 +378,14 @@ NtGdiTransformPoints( if (Count <= 0) return TRUE; + if (!UnsafePtsIn || !UnsafePtOut) + { + return FALSE; + } + pdc = DC_LockDc(hDC); if (!pdc) { - EngSetLastError(ERROR_INVALID_PARAMETER); return FALSE; } @@ -595,7 +600,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); @@ -821,6 +826,9 @@ IntGdiSetMapMode( FLONG flXform; PDC_ATTR pdcattr = dc->pdcattr; + if (MapMode == pdcattr->iMapMode) + return MapMode; + flXform = 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); @@ -921,7 +929,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 +980,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 +1032,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 +1068,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 dc3228dfad8..9c7a75bbcd9 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_IsInvertible(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 e1d2241f2ca..02216a58591 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -3,7 +3,8 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: win32ss/gdi/ntgdi/xformobj.c * PURPOSE: XFORMOBJ API - * PROGRAMMER: Timo Kreuzer + * PROGRAMMERS: Timo Kreuzer + * Katayama Hirofumi MZ */ /** Includes ******************************************************************/ @@ -243,6 +244,25 @@ XFORMOBJ_iCombineXform( } } +BOOL FASTCALL +MX_IsInvertible(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 0c3ff2ee51e..179890d86a9 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_IsInvertible(IN PMATRIX pmx); +VOID FASTCALL MX_Set0(OUT PMATRIX pmx);