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.c... ============================================================================== --- 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);