From a969022b08ea2eb9ebe6cf982970742f5f32a986 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 18 Dec 2014 08:11:50 +0000 Subject: [PATCH] [WIN32K] Rework GreCreateFrameRgn to return the new region. Implement the internal function REGION_bMakeFrameRegion doing the actual work. Fix frame calculation by moving the source region diagonal instead of only horizontal and vertical, use IntGdiOffsetRgn instead of manually fiddling with the rectangles. svn path=/trunk/; revision=65725 --- reactos/win32ss/gdi/ntgdi/bitblt.c | 30 +++--- reactos/win32ss/gdi/ntgdi/region.c | 153 +++++++++++++---------------- reactos/win32ss/gdi/ntgdi/region.h | 5 +- 3 files changed, 85 insertions(+), 103 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/bitblt.c b/reactos/win32ss/gdi/ntgdi/bitblt.c index e25f3b1a81c..d838ca1ce23 100644 --- a/reactos/win32ss/gdi/ntgdi/bitblt.c +++ b/reactos/win32ss/gdi/ntgdi/bitblt.c @@ -1048,31 +1048,25 @@ NtGdiFillRgn( BOOL APIENTRY NtGdiFrameRgn( - HDC hDC, - HRGN hRgn, - HBRUSH hBrush, - INT Width, - INT Height) + _In_ HDC hdc, + _In_ HRGN hrgn, + _In_ HBRUSH hbrush, + _In_ INT xWidth, + _In_ INT yHeight) { - HRGN FrameRgn; - BOOL Ret; + HRGN hrgnFrame; + BOOL bResult; - FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - if (FrameRgn == NULL) + hrgnFrame = GreCreateFrameRgn(hrgn, xWidth, yHeight); + if (hrgnFrame == NULL) { return FALSE; } - if (!GreCreateFrameRgn(FrameRgn, hRgn, Width, Height)) - { - GreDeleteObject(FrameRgn); - return FALSE; - } + bResult = NtGdiFillRgn(hdc, hrgnFrame, hbrush); - Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush); - - GreDeleteObject(FrameRgn); - return Ret; + GreDeleteObject(hrgnFrame); + return bResult; } BOOL diff --git a/reactos/win32ss/gdi/ntgdi/region.c b/reactos/win32ss/gdi/ntgdi/region.c index a155572c8ee..d0548245d40 100644 --- a/reactos/win32ss/gdi/ntgdi/region.c +++ b/reactos/win32ss/gdi/ntgdi/region.c @@ -1838,120 +1838,109 @@ REGION_CreateSimpleFrameRgn( return TRUE; } +static BOOL -FASTCALL -GreCreateFrameRgn( - HRGN hDest, - HRGN hSrc, - INT x, - INT y) +REGION_bMakeFrameRegion( + _Inout_ PREGION prgnDest, + _In_ PREGION prgnSrc, + _In_ INT cx, + _In_ INT cy) { - PREGION srcObj, destObj; - PRECTL rc; - ULONG i; - srcObj = RGNOBJAPI_Lock(hSrc, NULL); - if (srcObj == NULL) + if (!REGION_NOT_EMPTY(prgnSrc)) { return FALSE; } - if (!REGION_NOT_EMPTY(srcObj)) + if (!REGION_CopyRegion(prgnDest, prgnSrc)) { - RGNOBJAPI_Unlock(srcObj); return FALSE; } - destObj = RGNOBJAPI_Lock(hDest, NULL); - if (destObj == NULL) + if (REGION_Complexity(prgnSrc) == SIMPLEREGION) { - RGNOBJAPI_Unlock(srcObj); - return FALSE; - } - - EMPTY_REGION(destObj); - if (!REGION_CopyRegion(destObj, srcObj)) - { - RGNOBJAPI_Unlock(destObj); - RGNOBJAPI_Unlock(srcObj); - return FALSE; - } - - if (REGION_Complexity(srcObj) == SIMPLEREGION) - { - if (!REGION_CreateSimpleFrameRgn(destObj, x, y)) + if (!REGION_CreateSimpleFrameRgn(prgnDest, cx, cy)) { - EMPTY_REGION(destObj); - RGNOBJAPI_Unlock(destObj); - RGNOBJAPI_Unlock(srcObj); return FALSE; } } else { - /* Original region moved to right */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->left += x; - rc->right += x; - rc++; - } + /* Move the source region to the bottom-right */ + IntGdiOffsetRgn(prgnSrc, cx, cy); - REGION_IntersectRegion(destObj, destObj, srcObj); + /* Intersect with the source region (this crops the top-left frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); - /* Original region moved to left */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->left -= 2 * x; - rc->right -= 2 * x; - rc++; - } + /* Move the source region to the bottom-left */ + IntGdiOffsetRgn(prgnSrc, -2 * cx, 0); - REGION_IntersectRegion(destObj, destObj, srcObj); + /* Intersect with the source region (this crops the top-right frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); - /* Original region moved down */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->left += x; - rc->right += x; - rc->top += y; - rc->bottom += y; - rc++; - } + /* Move the source region to the top-left */ + IntGdiOffsetRgn(prgnSrc, 0, -2 * cy); - REGION_IntersectRegion(destObj, destObj, srcObj); + /* Intersect with the source region (this crops the bottom-right frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); - /* Original region moved up */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->top -= 2 * y; - rc->bottom -= 2 * y; - rc++; - } + /* Move the source region to the top-right */ + IntGdiOffsetRgn(prgnSrc, 2 * cx, 0); - REGION_IntersectRegion(destObj, destObj, srcObj); + /* Intersect with the source region (this crops the bottom-left frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); - /* Restore the original region */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->top += y; - rc->bottom += y; - rc++; - } + /* Move the source region back to the original position */ + IntGdiOffsetRgn(prgnSrc, -cx, cy); - REGION_SubtractRegion(destObj, srcObj, destObj); + /* Finally subtract the cropped region from the source */ + REGION_SubtractRegion(prgnDest, prgnSrc, prgnDest); } - RGNOBJAPI_Unlock(destObj); - RGNOBJAPI_Unlock(srcObj); return TRUE; } +HRGN +FASTCALL +GreCreateFrameRgn( + HRGN hrgn, + INT cx, + INT cy) +{ + PREGION prgnFrame, prgnSrc; + HRGN hrgnFrame; + + /* Allocate a new region */ + prgnFrame = REGION_AllocUserRgnWithHandle(1); + if (prgnFrame == NULL) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + /* Lock the source region */ + prgnSrc = RGNOBJAPI_Lock(hrgn, NULL); + if (prgnSrc == NULL) + { + REGION_Delete(prgnFrame); + return FALSE; + } + + if (REGION_bMakeFrameRegion(prgnFrame, prgnSrc, cx, cy)) + { + hrgnFrame = prgnFrame->BaseObject.hHmgr; + RGNOBJAPI_Unlock(prgnFrame); + } + else + { + REGION_Delete(prgnFrame); + hrgnFrame = NULL; + } + + RGNOBJAPI_Unlock(prgnSrc); + return hrgnFrame; +} + static BOOL diff --git a/reactos/win32ss/gdi/ntgdi/region.h b/reactos/win32ss/gdi/ntgdi/region.h index 48df46407ec..7ca9b535c12 100644 --- a/reactos/win32ss/gdi/ntgdi/region.h +++ b/reactos/win32ss/gdi/ntgdi/region.h @@ -53,11 +53,10 @@ VOID FASTCALL RGNOBJAPI_Unlock(PREGION); PREGION FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT); BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD); -BOOL +HRGN FASTCALL GreCreateFrameRgn( - HRGN hDest, - HRGN hSrc, + HRGN hrgn, INT x, INT y);