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);