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
This commit is contained in:
Timo Kreuzer 2014-12-18 08:11:50 +00:00
parent 620c12a295
commit a969022b08
3 changed files with 85 additions and 103 deletions

View file

@ -1048,31 +1048,25 @@ NtGdiFillRgn(
BOOL BOOL
APIENTRY APIENTRY
NtGdiFrameRgn( NtGdiFrameRgn(
HDC hDC, _In_ HDC hdc,
HRGN hRgn, _In_ HRGN hrgn,
HBRUSH hBrush, _In_ HBRUSH hbrush,
INT Width, _In_ INT xWidth,
INT Height) _In_ INT yHeight)
{ {
HRGN FrameRgn; HRGN hrgnFrame;
BOOL Ret; BOOL bResult;
FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0); hrgnFrame = GreCreateFrameRgn(hrgn, xWidth, yHeight);
if (FrameRgn == NULL) if (hrgnFrame == NULL)
{ {
return FALSE; return FALSE;
} }
if (!GreCreateFrameRgn(FrameRgn, hRgn, Width, Height)) bResult = NtGdiFillRgn(hdc, hrgnFrame, hbrush);
{
GreDeleteObject(FrameRgn);
return FALSE;
}
Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush); GreDeleteObject(hrgnFrame);
return bResult;
GreDeleteObject(FrameRgn);
return Ret;
} }
BOOL BOOL

View file

@ -1838,120 +1838,109 @@ REGION_CreateSimpleFrameRgn(
return TRUE; return TRUE;
} }
static
BOOL BOOL
FASTCALL REGION_bMakeFrameRegion(
GreCreateFrameRgn( _Inout_ PREGION prgnDest,
HRGN hDest, _In_ PREGION prgnSrc,
HRGN hSrc, _In_ INT cx,
INT x, _In_ INT cy)
INT y)
{ {
PREGION srcObj, destObj;
PRECTL rc;
ULONG i;
srcObj = RGNOBJAPI_Lock(hSrc, NULL); if (!REGION_NOT_EMPTY(prgnSrc))
if (srcObj == NULL)
{ {
return FALSE; return FALSE;
} }
if (!REGION_NOT_EMPTY(srcObj)) if (!REGION_CopyRegion(prgnDest, prgnSrc))
{ {
RGNOBJAPI_Unlock(srcObj);
return FALSE; return FALSE;
} }
destObj = RGNOBJAPI_Lock(hDest, NULL); if (REGION_Complexity(prgnSrc) == SIMPLEREGION)
if (destObj == NULL)
{ {
RGNOBJAPI_Unlock(srcObj); if (!REGION_CreateSimpleFrameRgn(prgnDest, cx, cy))
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; return FALSE;
} }
} }
else else
{ {
/* Original region moved to right */ /* Move the source region to the bottom-right */
rc = srcObj->Buffer; IntGdiOffsetRgn(prgnSrc, cx, cy);
for (i = 0; i < srcObj->rdh.nCount; i++)
{
rc->left += x;
rc->right += x;
rc++;
}
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 */ /* Move the source region to the bottom-left */
rc = srcObj->Buffer; IntGdiOffsetRgn(prgnSrc, -2 * cx, 0);
for (i = 0; i < srcObj->rdh.nCount; i++)
{
rc->left -= 2 * x;
rc->right -= 2 * x;
rc++;
}
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 */ /* Move the source region to the top-left */
rc = srcObj->Buffer; IntGdiOffsetRgn(prgnSrc, 0, -2 * cy);
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); /* Intersect with the source region (this crops the bottom-right frame) */
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
/* Original region moved up */ /* Move the source region to the top-right */
rc = srcObj->Buffer; IntGdiOffsetRgn(prgnSrc, 2 * cx, 0);
for (i = 0; i < srcObj->rdh.nCount; i++)
{
rc->top -= 2 * y;
rc->bottom -= 2 * y;
rc++;
}
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 */ /* Move the source region back to the original position */
rc = srcObj->Buffer; IntGdiOffsetRgn(prgnSrc, -cx, cy);
for (i = 0; i < srcObj->rdh.nCount; i++)
{
rc->top += y;
rc->bottom += y;
rc++;
}
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; 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 static
BOOL BOOL

View file

@ -53,11 +53,10 @@ VOID FASTCALL RGNOBJAPI_Unlock(PREGION);
PREGION FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT); PREGION FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT);
BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD); BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
BOOL HRGN
FASTCALL FASTCALL
GreCreateFrameRgn( GreCreateFrameRgn(
HRGN hDest, HRGN hrgn,
HRGN hSrc,
INT x, INT x,
INT y); INT y);