From fc26231290a756a80d1460f30835baed5c10f970 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 23 Sep 2014 20:21:13 +0000 Subject: [PATCH] [WIN32K] - Modify REGION_CropAndOffsetRegion to return the region complexity - Improve NtGdiIntersectClipRect to only allocate a new region, if we don't have one yet, otherwise crop it using REGION_CropAndOffsetRegion svn path=/trunk/; revision=64249 --- reactos/win32ss/gdi/ntgdi/cliprgn.c | 79 ++++++++++++++++++----------- reactos/win32ss/gdi/ntgdi/region.c | 30 +++++------ reactos/win32ss/gdi/ntgdi/region.h | 2 +- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/cliprgn.c b/reactos/win32ss/gdi/ntgdi/cliprgn.c index f6a89e382dd..9c962256d5c 100644 --- a/reactos/win32ss/gdi/ntgdi/cliprgn.c +++ b/reactos/win32ss/gdi/ntgdi/cliprgn.c @@ -241,54 +241,71 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC, return Result; } -int APIENTRY NtGdiIntersectClipRect(HDC hDC, - int LeftRect, - int TopRect, - int RightRect, - int BottomRect) +INT +APIENTRY +NtGdiIntersectClipRect( + _In_ HDC hdc, + _In_ INT xLeft, + _In_ INT yTop, + _In_ INT xRight, + _In_ INT yBottom) { - INT Result; - RECTL Rect; - PREGION pNewRgn; - PDC dc = DC_LockDc(hDC); + INT iComplexity; + RECTL rect; + PREGION prgnNew; + PDC pdc; DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n", - hDC, LeftRect, TopRect, RightRect, BottomRect); + hdc, xLeft, yTop, xRight, yBottom); - if (!dc) + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } - Rect.left = LeftRect; - Rect.top = TopRect; - Rect.right = RightRect; - Rect.bottom = BottomRect; - - IntLPtoDP(dc, (LPPOINT)&Rect, 2); + /* Convert coordinates to device space */ + rect.left = xLeft; + rect.top = yTop; + rect.right = xRight; + rect.bottom = yBottom; + IntLPtoDP(pdc, (LPPOINT)&rect, 2); - pNewRgn = IntSysCreateRectpRgnIndirect(&Rect); - if (!pNewRgn) + /* Check if we already have a clip region */ + if (pdc->dclevel.prgnClip != NULL) { - Result = ERROR; - } - else if (!dc->dclevel.prgnClip) - { - dc->dclevel.prgnClip = pNewRgn; - Result = SIMPLEREGION; + /* We have a region, crop it */ + iComplexity = REGION_CropAndOffsetRegion(pdc->dclevel.prgnClip, + pdc->dclevel.prgnClip, + &rect, + NULL); } else { - Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND); - REGION_Delete(pNewRgn); + /* We don't have a region yet, allocate a new one */ + prgnNew = IntSysCreateRectpRgnIndirect(&rect); + if (prgnNew == NULL) + { + iComplexity = ERROR; + } + else + { + /* Set the new region */ + pdc->dclevel.prgnClip = prgnNew; + iComplexity = SIMPLEREGION; + } } - if (Result != ERROR) - dc->fs |= DC_FLAG_DIRTY_RAO; - DC_UnlockDc(dc); + /* If we succeeded, mark the RAO region as dirty */ + if (iComplexity != ERROR) + pdc->fs |= DC_FLAG_DIRTY_RAO; - return Result; + /* Unlock the DC */ + DC_UnlockDc(pdc); + + return iComplexity; } int APIENTRY NtGdiOffsetClipRgn(HDC hDC, diff --git a/reactos/win32ss/gdi/ntgdi/region.c b/reactos/win32ss/gdi/ntgdi/region.c index 4efcc6f14dd..0c20aff642a 100644 --- a/reactos/win32ss/gdi/ntgdi/region.c +++ b/reactos/win32ss/gdi/ntgdi/region.c @@ -489,12 +489,12 @@ IntDumpRegion(HRGN hRgn) INT FASTCALL -REGION_Complexity( PROSRGNDATA obj ) +REGION_Complexity(PREGION prgn) { - if (!obj) return NULLREGION; - switch(obj->rdh.nCount) + if (!prgn) return NULLREGION; + switch(prgn->rdh.nCount) { - DPRINT("Region Complexity -> %lu",obj->rdh.nCount); + DPRINT("Region Complexity -> %lu", prgn->rdh.nCount); case 0: return NULLREGION; case 1: return SIMPLEREGION; default: return COMPLEXREGION; @@ -581,13 +581,13 @@ REGION_SetExtents(ROSRGNDATA *pReg) /*********************************************************************** * REGION_CropAndOffsetRegion */ -BOOL FASTCALL +INT +FASTCALL REGION_CropAndOffsetRegion( - PROSRGNDATA rgnDst, - PROSRGNDATA rgnSrc, + PREGION rgnDst, + PREGION rgnSrc, const RECTL *rect, - const POINTL *offset -) + const POINTL *offset) // FIXME: we should probably remove offset from here { POINT pt = {0,0}; const POINT *off = offset; @@ -602,13 +602,13 @@ REGION_CropAndOffsetRegion( if (off->x || off->y) xrect = rgnDst->Buffer; else - return TRUE; + return REGION_Complexity(rgnDst); } else { xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION); if(!xrect) - return FALSE; + return ERROR; if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound) ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // Free the old buffer. Will be assigned to xrect below. } @@ -669,7 +669,7 @@ REGION_CropAndOffsetRegion( PRECTL temp; temp = ExAllocatePoolWithTag(PagedPool, i * sizeof(RECT), TAG_REGION); if (!temp) - return FALSE; + return ERROR; if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound) ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // free the old buffer @@ -727,7 +727,7 @@ REGION_CropAndOffsetRegion( rgnDst->rdh.iType = RDH_RECTANGLES; } - return TRUE; + return REGION_Complexity(rgnDst); empty: if (!rgnDst->Buffer) @@ -739,10 +739,10 @@ empty: rgnDst->rdh.nRgnSize = RGN_DEFAULT_RECTS * sizeof(RECT); } else - return FALSE; + return ERROR; } EMPTY_REGION(rgnDst); - return TRUE; + return NULLREGION; } diff --git a/reactos/win32ss/gdi/ntgdi/region.h b/reactos/win32ss/gdi/ntgdi/region.h index bfc2c3ebe8a..e735b155fef 100644 --- a/reactos/win32ss/gdi/ntgdi/region.h +++ b/reactos/win32ss/gdi/ntgdi/region.h @@ -28,7 +28,7 @@ VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect); INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect); BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc); BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT); -BOOL FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off); +INT FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off); VOID FASTCALL REGION_SetRectRgn(PROSRGNDATA pRgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect); VOID NTAPI REGION_vCleanup(PVOID ObjectBody); -- 2.17.1