Author: tkreuzer
Date: Wed Sep 24 21:23:03 2014
New Revision: 64260
URL:
http://svn.reactos.org/svn/reactos?rev=64260&view=rev
Log:
[WIN32K]
- Implement REGION_SubtractRectFromRgn
- Rewrite NtGdiExcludeClipRect, fixing a number of gdi32 apitests
Modified:
trunk/reactos/win32ss/gdi/ntgdi/cliprgn.c
trunk/reactos/win32ss/gdi/ntgdi/region.c
trunk/reactos/win32ss/gdi/ntgdi/region.h
Modified: trunk/reactos/win32ss/gdi/ntgdi/cliprgn.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/cliprgn.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/cliprgn.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/cliprgn.c [iso-8859-1] Wed Sep 24 21:23:03 2014
@@ -190,55 +190,79 @@
return iComplexity;
}
-int APIENTRY NtGdiExcludeClipRect(HDC hDC,
- int LeftRect,
- int TopRect,
- int RightRect,
- int BottomRect)
-{
- INT Result;
- RECTL Rect;
- PREGION prgnNew;
- PDC dc = DC_LockDc(hDC);
-
- if (!dc)
+INT
+APIENTRY
+NtGdiExcludeClipRect(
+ _In_ HDC hdc,
+ _In_ INT xLeft,
+ _In_ INT yTop,
+ _In_ INT xRight,
+ _In_ INT yBottom)
+{
+ INT iComplexity;
+ RECTL rect;
+ PDC pdc;
+
+ /* Lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (pdc == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
- Rect.left = LeftRect;
- Rect.top = TopRect;
- Rect.right = RightRect;
- Rect.bottom = BottomRect;
-
- IntLPtoDP(dc, (LPPOINT)&Rect, 2);
-
- prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
- if (!prgnNew)
- {
- Result = ERROR;
- }
- else
- {
- if (!dc->dclevel.prgnClip)
- {
- dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
- IntGdiCombineRgn(dc->dclevel.prgnClip, dc->prgnVis, prgnNew,
RGN_DIFF);
- Result = SIMPLEREGION;
+ /* Convert coordinates to device space */
+ rect.left = xLeft;
+ rect.top = yTop;
+ rect.right = xRight;
+ rect.bottom = yBottom;
+ RECTL_vMakeWellOrdered(&rect);
+ IntLPtoDP(pdc, (LPPOINT)&rect, 2);
+
+ /* Check if we already have a clip region */
+ if (pdc->dclevel.prgnClip != NULL)
+ {
+ /* We have a region, subtract the rect */
+ iComplexity = REGION_SubtractRectFromRgn(pdc->dclevel.prgnClip,
+ pdc->dclevel.prgnClip,
+ &rect);
+
+ /* Emulate Windows behavior */
+ if (iComplexity == SIMPLEREGION)
+ iComplexity = COMPLEXREGION;
+ }
+ else
+ {
+ /* Check if the rect intersects with the window rect */
+ if (RECTL_bIntersectRect(&rect, &rect, &pdc->erclWindow))
+ {
+ /* It does. In this case create an empty region */
+ pdc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+ iComplexity = NULLREGION;
}
else
{
- Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip,
prgnNew, RGN_DIFF);
- }
- REGION_Delete(prgnNew);
- }
- if (Result != ERROR)
- dc->fs |= DC_FLAG_DIRTY_RAO;
-
- DC_UnlockDc(dc);
-
- return Result;
+ /* Otherwise, emulate strange Windows behavior... */
+ pdc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 1, 1);
+ iComplexity = COMPLEXREGION;
+ }
+
+ /* Check if creating the region failed */
+ if (pdc->dclevel.prgnClip == NULL)
+ {
+ /* Return error code */
+ iComplexity = ERROR;
+ }
+ }
+
+ /* If we succeeded, mark the RAO region as dirty */
+ if (iComplexity != ERROR)
+ pdc->fs |= DC_FLAG_DIRTY_RAO;
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ return iComplexity;
}
INT
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] Wed Sep 24 21:23:03 2014
@@ -1773,6 +1773,23 @@
REGION_UnionRegion(rgn, rgn, ®ion);
}
+INT
+FASTCALL
+REGION_SubtractRectFromRgn(
+ PREGION prgnDest,
+ PREGION prgnSrc,
+ const RECTL *prcl)
+{
+ REGION rgnLocal;
+
+ rgnLocal.Buffer = &rgnLocal.rdh.rcBound;
+ rgnLocal.rdh.nCount = 1;
+ rgnLocal.rdh.nRgnSize = sizeof(RECT);
+ rgnLocal.rdh.rcBound = *prcl;
+ REGION_SubtractRegion(prgnDest, prgnSrc, &rgnLocal);
+ return REGION_Complexity(prgnDest);
+}
+
BOOL FASTCALL
REGION_CreateSimpleFrameRgn(
PROSRGNDATA rgn,
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.h…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/region.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/region.h [iso-8859-1] Wed Sep 24 21:23:03 2014
@@ -25,6 +25,7 @@
PROSRGNDATA FASTCALL REGION_AllocRgnWithHandle(INT n);
PROSRGNDATA FASTCALL REGION_AllocUserRgnWithHandle(INT n);
VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
+INT FASTCALL REGION_SubtractRectFromRgn(PREGION prgnDest, PREGION prgnSrc, const RECTL
*prcl);
INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);