Author: tkreuzer Date: Thu Dec 18 08:11:50 2014 New Revision: 65725
URL: http://svn.reactos.org/svn/reactos?rev=65725&view=rev Log: [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.
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c trunk/reactos/win32ss/gdi/ntgdi/region.c trunk/reactos/win32ss/gdi/ntgdi/region.h
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitblt.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] Thu Dec 18 08:11:50 2014 @@ -1048,31 +1048,25 @@ BOOL APIENTRY NtGdiFrameRgn( - HDC hDC, - HRGN hRgn, - HBRUSH hBrush, - INT Width, - INT Height) -{ - HRGN FrameRgn; - BOOL Ret; - - FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - if (FrameRgn == NULL) - { - return FALSE; - } - - if (!GreCreateFrameRgn(FrameRgn, hRgn, Width, Height)) - { - GreDeleteObject(FrameRgn); - return FALSE; - } - - Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush); - - GreDeleteObject(FrameRgn); - return Ret; + _In_ HDC hdc, + _In_ HRGN hrgn, + _In_ HBRUSH hbrush, + _In_ INT xWidth, + _In_ INT yHeight) +{ + HRGN hrgnFrame; + BOOL bResult; + + hrgnFrame = GreCreateFrameRgn(hrgn, xWidth, yHeight); + if (hrgnFrame == NULL) + { + return FALSE; + } + + bResult = NtGdiFillRgn(hdc, hrgnFrame, hbrush); + + GreDeleteObject(hrgnFrame); + return bResult; }
BOOL
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] Thu Dec 18 08:11:50 2014 @@ -1838,118 +1838,107 @@ return TRUE; }
+static BOOL +REGION_bMakeFrameRegion( + _Inout_ PREGION prgnDest, + _In_ PREGION prgnSrc, + _In_ INT cx, + _In_ INT cy) +{ + + if (!REGION_NOT_EMPTY(prgnSrc)) + { + return FALSE; + } + + if (!REGION_CopyRegion(prgnDest, prgnSrc)) + { + return FALSE; + } + + if (REGION_Complexity(prgnSrc) == SIMPLEREGION) + { + if (!REGION_CreateSimpleFrameRgn(prgnDest, cx, cy)) + { + return FALSE; + } + } + else + { + /* Move the source region to the bottom-right */ + IntGdiOffsetRgn(prgnSrc, cx, cy); + + /* Intersect with the source region (this crops the top-left frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); + + /* Move the source region to the bottom-left */ + IntGdiOffsetRgn(prgnSrc, -2 * cx, 0); + + /* Intersect with the source region (this crops the top-right frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); + + /* Move the source region to the top-left */ + IntGdiOffsetRgn(prgnSrc, 0, -2 * cy); + + /* Intersect with the source region (this crops the bottom-right frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); + + /* Move the source region to the top-right */ + IntGdiOffsetRgn(prgnSrc, 2 * cx, 0); + + /* Intersect with the source region (this crops the bottom-left frame) */ + REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc); + + /* Move the source region back to the original position */ + IntGdiOffsetRgn(prgnSrc, -cx, cy); + + /* Finally subtract the cropped region from the source */ + REGION_SubtractRegion(prgnDest, prgnSrc, prgnDest); + } + + return TRUE; +} + +HRGN FASTCALL GreCreateFrameRgn( - HRGN hDest, - HRGN hSrc, - INT x, - INT y) -{ - PREGION srcObj, destObj; - PRECTL rc; - ULONG i; - - srcObj = RGNOBJAPI_Lock(hSrc, NULL); - if (srcObj == NULL) - { + 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_NOT_EMPTY(srcObj)) - { - RGNOBJAPI_Unlock(srcObj); - return FALSE; - } - - destObj = RGNOBJAPI_Lock(hDest, NULL); - if (destObj == NULL) - { - 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)) - { - EMPTY_REGION(destObj); - RGNOBJAPI_Unlock(destObj); - RGNOBJAPI_Unlock(srcObj); - return FALSE; - } + if (REGION_bMakeFrameRegion(prgnFrame, prgnSrc, cx, cy)) + { + hrgnFrame = prgnFrame->BaseObject.hHmgr; + RGNOBJAPI_Unlock(prgnFrame); } else { - /* Original region moved to right */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->left += x; - rc->right += x; - rc++; - } - - REGION_IntersectRegion(destObj, destObj, srcObj); - - /* 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++; - } - - REGION_IntersectRegion(destObj, destObj, srcObj); - - /* 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++; - } - - REGION_IntersectRegion(destObj, destObj, srcObj); - - /* Original region moved up */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->top -= 2 * y; - rc->bottom -= 2 * y; - rc++; - } - - REGION_IntersectRegion(destObj, destObj, srcObj); - - /* Restore the original region */ - rc = srcObj->Buffer; - for (i = 0; i < srcObj->rdh.nCount; i++) - { - rc->top += y; - rc->bottom += y; - rc++; - } - - REGION_SubtractRegion(destObj, srcObj, destObj); - } - - RGNOBJAPI_Unlock(destObj); - RGNOBJAPI_Unlock(srcObj); - return TRUE; + REGION_Delete(prgnFrame); + hrgnFrame = NULL; + } + + RGNOBJAPI_Unlock(prgnSrc); + return hrgnFrame; }
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] Thu Dec 18 08:11:50 2014 @@ -53,11 +53,10 @@ 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);