https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8bdfdd5c17426b04f0451…
commit 8bdfdd5c17426b04f0451192e6f3fb12e0598161
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Apr 29 14:45:44 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Apr 29 14:45:44 2019 +0900
[WIN32SS][NTGDI][GDI32] Fix DPtoLP and NtGdiTransformPoints etc. (#1540)
Fix NtGdiTransformPoints, gdi32!DPtoLP, gdi32!LPtoDP and gdi32!SetMapMode functions.
Fix CORE-15983. CORE-15983
---
win32ss/gdi/gdi32/objects/coord.c | 58 ++++++++++++++++++++++-----------------
win32ss/gdi/ntgdi/coord.c | 26 ++++++++++++------
win32ss/gdi/ntgdi/coord.h | 3 ++
win32ss/gdi/ntgdi/xformobj.c | 22 ++++++++++++++-
win32ss/gdi/ntgdi/xformobj.h | 3 ++
5 files changed, 77 insertions(+), 35 deletions(-)
diff --git a/win32ss/gdi/gdi32/objects/coord.c b/win32ss/gdi/gdi32/objects/coord.c
index dd74b33946..a42fa1236b 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 58d236581b..adaee5f0ab 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(a)rectos.org)
+ * PROGRAMERS: Timo Kreuzer (timo.kreuzer(a)rectos.org)
+ * Katayama Hirofumi MZ (katayama.hirofumi.mz(a)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 dc3228dfad..9c7a75bbcd 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 e1d2241f2c..02216a5859 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 0c3ff2ee51..179890d86a 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);