mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:02:58 +00:00
[WIN32K]
Improve REGION_bMakeFrameRegion and REGION_bMakeSimpleFrameRgn svn path=/trunk/; revision=65734
This commit is contained in:
parent
fe261bd6e2
commit
542d41ba8b
1 changed files with 132 additions and 97 deletions
|
@ -1759,80 +1759,92 @@ REGION_SubtractRectFromRgn(
|
||||||
return REGION_Complexity(prgnDest);
|
return REGION_Complexity(prgnDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
REGION_bMakeSimpleFrameRgn(
|
||||||
REGION_CreateSimpleFrameRgn(
|
_Inout_ PREGION prgn,
|
||||||
PREGION rgn,
|
_In_ PRECTL prclSrc,
|
||||||
INT x,
|
_In_ INT cx,
|
||||||
INT y)
|
_In_ INT cy)
|
||||||
{
|
{
|
||||||
RECTL rc[4];
|
RECTL arcl[4];
|
||||||
PRECTL prc;
|
UINT i;
|
||||||
|
|
||||||
if ((x != 0) || (y != 0))
|
NT_ASSERT((cx >= 0) && (cy >= 0));
|
||||||
{
|
NT_ASSERT((prclSrc->bottom > prclSrc->top) &&
|
||||||
prc = rc;
|
(prclSrc->right > prclSrc->left));
|
||||||
|
|
||||||
if ((rgn->rdh.rcBound.bottom - rgn->rdh.rcBound.top > y * 2) &&
|
/* Start with an empty region */
|
||||||
(rgn->rdh.rcBound.right - rgn->rdh.rcBound.left > x * 2))
|
EMPTY_REGION(prgn);
|
||||||
|
|
||||||
|
/* Check for the case where the frame covers the whole rect */
|
||||||
|
if (((prclSrc->bottom - prclSrc->top) <= cy * 2) ||
|
||||||
|
((prclSrc->right - prclSrc->left) <= cx * 2))
|
||||||
{
|
{
|
||||||
if (y != 0)
|
prgn->rdh.rcBound = *prclSrc;
|
||||||
|
prgn->Buffer[0] = *prclSrc;
|
||||||
|
prgn->rdh.nCount = 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if (cy != 0)
|
||||||
{
|
{
|
||||||
/* Top rectangle */
|
/* Top rectangle */
|
||||||
prc->left = rgn->rdh.rcBound.left;
|
arcl[i].left = prclSrc->left;
|
||||||
prc->top = rgn->rdh.rcBound.top;
|
arcl[i].top = prclSrc->top;
|
||||||
prc->right = rgn->rdh.rcBound.right;
|
arcl[i].right = prclSrc->right;
|
||||||
prc->bottom = prc->top + y;
|
arcl[i].bottom = prclSrc->top + cy;
|
||||||
prc++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x != 0)
|
if (cx != 0)
|
||||||
{
|
{
|
||||||
/* Left rectangle */
|
/* Left rectangle */
|
||||||
prc->left = rgn->rdh.rcBound.left;
|
arcl[i].left = prclSrc->left;
|
||||||
prc->top = rgn->rdh.rcBound.top + y;
|
arcl[i].top = prclSrc->top + cy;
|
||||||
prc->right = prc->left + x;
|
arcl[i].right = prclSrc->left + cx;
|
||||||
prc->bottom = rgn->rdh.rcBound.bottom - y;
|
arcl[i].bottom = prclSrc->bottom - cy;
|
||||||
prc++;
|
i++;
|
||||||
|
|
||||||
/* Right rectangle */
|
/* Right rectangle */
|
||||||
prc->left = rgn->rdh.rcBound.right - x;
|
arcl[i].left = prclSrc->right - cx;
|
||||||
prc->top = rgn->rdh.rcBound.top + y;
|
arcl[i].top = prclSrc->top + cy;
|
||||||
prc->right = rgn->rdh.rcBound.right;
|
arcl[i].right = prclSrc->right;
|
||||||
prc->bottom = rgn->rdh.rcBound.bottom - y;
|
arcl[i].bottom = prclSrc->bottom - cy;
|
||||||
prc++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y != 0)
|
if (cy != 0)
|
||||||
{
|
{
|
||||||
/* Bottom rectangle */
|
/* Bottom rectangle */
|
||||||
prc->left = rgn->rdh.rcBound.left;
|
arcl[i].left = prclSrc->left;
|
||||||
prc->top = rgn->rdh.rcBound.bottom - y;
|
arcl[i].top = prclSrc->bottom - cy;
|
||||||
prc->right = rgn->rdh.rcBound.right;
|
arcl[i].right = prclSrc->right;
|
||||||
prc->bottom = rgn->rdh.rcBound.bottom;
|
arcl[i].bottom = prclSrc->bottom;
|
||||||
prc++;
|
i++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prc != rc)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
/* The frame results in a complex region. rcBounds remains
|
/* The frame results in a complex region. rcBounds remains
|
||||||
the same, though. */
|
the same, though. */
|
||||||
rgn->rdh.nCount = (DWORD)(prc - rc);
|
prgn->rdh.nCount = i;
|
||||||
ASSERT(rgn->rdh.nCount > 1);
|
NT_ASSERT(prgn->rdh.nCount > 1);
|
||||||
rgn->rdh.nRgnSize = rgn->rdh.nCount * sizeof(RECT);
|
prgn->rdh.nRgnSize = prgn->rdh.nCount * sizeof(RECT);
|
||||||
rgn->Buffer = ExAllocatePoolWithTag(PagedPool,
|
NT_ASSERT(prgn->Buffer == &prgn->rdh.rcBound);
|
||||||
rgn->rdh.nRgnSize,
|
prgn->Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
prgn->rdh.nRgnSize,
|
||||||
TAG_REGION);
|
TAG_REGION);
|
||||||
if (rgn->Buffer == NULL)
|
if (prgn->Buffer == NULL)
|
||||||
{
|
{
|
||||||
rgn->rdh.nRgnSize = 0;
|
prgn->rdh.nRgnSize = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PRAGMA_WARNING_SUPPRESS(__WARNING_MAYBE_UNINIT_VAR) // rc is initialized
|
_PRAGMA_WARNING_SUPPRESS(__WARNING_MAYBE_UNINIT_VAR) // arcl is initialized
|
||||||
COPY_RECTS(rgn->Buffer, rc, rgn->rdh.nCount);
|
COPY_RECTS(prgn->Buffer, arcl, prgn->rdh.nCount);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1842,60 +1854,83 @@ static
|
||||||
BOOL
|
BOOL
|
||||||
REGION_bMakeFrameRegion(
|
REGION_bMakeFrameRegion(
|
||||||
_Inout_ PREGION prgnDest,
|
_Inout_ PREGION prgnDest,
|
||||||
_In_ PREGION prgnSrc,
|
_Inout_ PREGION prgnSrc,
|
||||||
_In_ INT cx,
|
_In_ INT cx,
|
||||||
_In_ INT cy)
|
_In_ INT cy)
|
||||||
{
|
{
|
||||||
|
/* Handle negative cx / cy */
|
||||||
|
cx = abs(cx);
|
||||||
|
cy = abs(cy);
|
||||||
|
|
||||||
|
/* Check border size (the cast is necessary to catch cx/cy == INT_MIN!) */
|
||||||
|
if (((UINT)cx > MAX_COORD) || ((UINT)cy > MAX_COORD))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fail on empty source region */
|
||||||
if (!REGION_NOT_EMPTY(prgnSrc))
|
if (!REGION_NOT_EMPTY(prgnSrc))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle trivial case */
|
||||||
|
if ((cx == 0) && (cy == 0))
|
||||||
|
{
|
||||||
|
EMPTY_REGION(prgnDest);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle simple source region */
|
||||||
|
if (REGION_Complexity(prgnSrc) == SIMPLEREGION)
|
||||||
|
{
|
||||||
|
return REGION_bMakeSimpleFrameRgn(prgnDest, &prgnSrc->rdh.rcBound, cx, cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we can move the region to create the frame region */
|
||||||
|
if ((prgnSrc->rdh.rcBound.left < (MIN_COORD + cx)) ||
|
||||||
|
(prgnSrc->rdh.rcBound.top < (MIN_COORD + cy)) ||
|
||||||
|
(prgnSrc->rdh.rcBound.right > (MAX_COORD - cx)) ||
|
||||||
|
(prgnSrc->rdh.rcBound.bottom > (MAX_COORD - cy)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the source region */
|
||||||
if (!REGION_CopyRegion(prgnDest, prgnSrc))
|
if (!REGION_CopyRegion(prgnDest, prgnSrc))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (REGION_Complexity(prgnSrc) == SIMPLEREGION)
|
|
||||||
{
|
|
||||||
if (!REGION_CreateSimpleFrameRgn(prgnDest, cx, cy))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Move the source region to the bottom-right */
|
/* Move the source region to the bottom-right */
|
||||||
REGION_bOffsetRgn(prgnSrc, cx, cy);
|
NT_VERIFY(REGION_bOffsetRgn(prgnSrc, cx, cy));
|
||||||
|
|
||||||
/* Intersect with the source region (this crops the top-left frame) */
|
/* Intersect with the source region (this crops the top-left frame) */
|
||||||
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
||||||
|
|
||||||
/* Move the source region to the bottom-left */
|
/* Move the source region to the bottom-left */
|
||||||
REGION_bOffsetRgn(prgnSrc, -2 * cx, 0);
|
NT_VERIFY(REGION_bOffsetRgn(prgnSrc, -2 * cx, 0));
|
||||||
|
|
||||||
/* Intersect with the source region (this crops the top-right frame) */
|
/* Intersect with the source region (this crops the top-right frame) */
|
||||||
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
||||||
|
|
||||||
/* Move the source region to the top-left */
|
/* Move the source region to the top-left */
|
||||||
REGION_bOffsetRgn(prgnSrc, 0, -2 * cy);
|
NT_VERIFY(REGION_bOffsetRgn(prgnSrc, 0, -2 * cy));
|
||||||
|
|
||||||
/* Intersect with the source region (this crops the bottom-right frame) */
|
/* Intersect with the source region (this crops the bottom-right frame) */
|
||||||
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
||||||
|
|
||||||
/* Move the source region to the top-right */
|
/* Move the source region to the top-right */
|
||||||
REGION_bOffsetRgn(prgnSrc, 2 * cx, 0);
|
NT_VERIFY(REGION_bOffsetRgn(prgnSrc, 2 * cx, 0));
|
||||||
|
|
||||||
/* Intersect with the source region (this crops the bottom-left frame) */
|
/* Intersect with the source region (this crops the bottom-left frame) */
|
||||||
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
REGION_IntersectRegion(prgnDest, prgnDest, prgnSrc);
|
||||||
|
|
||||||
/* Move the source region back to the original position */
|
/* Move the source region back to the original position */
|
||||||
REGION_bOffsetRgn(prgnSrc, -cx, cy);
|
NT_VERIFY(REGION_bOffsetRgn(prgnSrc, -cx, cy));
|
||||||
|
|
||||||
/* Finally subtract the cropped region from the source */
|
/* Finally subtract the cropped region from the source */
|
||||||
REGION_SubtractRegion(prgnDest, prgnSrc, prgnDest);
|
REGION_SubtractRegion(prgnDest, prgnSrc, prgnDest);
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue