optimize FrameRgn for simple rectangular regions

svn path=/trunk/; revision=29938
This commit is contained in:
Thomas Bluemel 2007-10-28 20:07:28 +00:00
parent c65189cc6f
commit 6477a25b3a

View file

@ -1755,6 +1755,77 @@ void FASTCALL REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn)
REGION_UnionRegion(rgn, rgn, &region); REGION_UnionRegion(rgn, rgn, &region);
} }
BOOL FASTCALL REGION_CreateSimpleFrameRgn(PROSRGNDATA rgn, INT x, INT y)
{
RECT rc[4];
PRECT prc;
if (x != 0 || y != 0)
{
prc = rc;
if (rgn->rdh.rcBound.bottom - rgn->rdh.rcBound.top > y * 2 &&
rgn->rdh.rcBound.right - rgn->rdh.rcBound.left > x * 2)
{
if (y != 0)
{
/* top rectangle */
prc->left = rgn->rdh.rcBound.left;
prc->top = rgn->rdh.rcBound.top;
prc->right = rgn->rdh.rcBound.right;
prc->bottom = prc->top + y;
prc++;
}
if (x != 0)
{
/* left rectangle */
prc->left = rgn->rdh.rcBound.left;
prc->top = rgn->rdh.rcBound.top + y;
prc->right = prc->left + x;
prc->bottom = rgn->rdh.rcBound.bottom - y;
prc++;
/* right rectangle */
prc->left = rgn->rdh.rcBound.right - x;
prc->top = rgn->rdh.rcBound.top + y;
prc->right = rgn->rdh.rcBound.right;
prc->bottom = rgn->rdh.rcBound.bottom - y;
prc++;
}
if (y != 0)
{
/* bottom rectangle */
prc->left = rgn->rdh.rcBound.left;
prc->top = rgn->rdh.rcBound.bottom - y;
prc->right = rgn->rdh.rcBound.right;
prc->bottom = rgn->rdh.rcBound.bottom;
prc++;
}
}
if (prc != rc)
{
/* The frame results in a complex region. rcBounds remains
the same, though. */
rgn->rdh.nCount = (DWORD)(prc - rc);
ASSERT(rgn->rdh.nCount > 1);
rgn->rdh.nRgnSize = rgn->rdh.nCount * sizeof(RECT);
rgn->Buffer = ExAllocatePoolWithTag( PagedPool, rgn->rdh.nRgnSize, TAG_REGION);
if (!rgn->Buffer)
{
rgn->rdh.nRgnSize = 0;
return FALSE;
}
COPY_RECTS(rgn->Buffer, rc, rgn->rdh.nCount);
}
}
return TRUE;
}
BOOL FASTCALL REGION_CreateFrameRgn(HRGN hDest, HRGN hSrc, INT x, INT y) BOOL FASTCALL REGION_CreateFrameRgn(HRGN hDest, HRGN hSrc, INT x, INT y)
{ {
PROSRGNDATA srcObj, destObj; PROSRGNDATA srcObj, destObj;
@ -1784,57 +1855,70 @@ BOOL FASTCALL REGION_CreateFrameRgn(HRGN hDest, HRGN hSrc, INT x, INT y)
return FALSE; return FALSE;
} }
/* Original region moved to right */ if (srcObj->rdh.iType == SIMPLEREGION)
rc = (PRECT)srcObj->Buffer;
for (i = 0; i < srcObj->rdh.nCount; i++)
{ {
rc->left += x; if (!REGION_CreateSimpleFrameRgn(destObj, x, y))
rc->right += x; {
rc++; EMPTY_REGION(destObj);
RGNDATA_UnlockRgn(destObj);
RGNDATA_UnlockRgn(srcObj);
return FALSE;
}
} }
REGION_IntersectRegion(destObj, destObj, srcObj); else
{
/* Original region moved to right */
rc = (PRECT)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 */ /* Original region moved to left */
rc = (PRECT)srcObj->Buffer; rc = (PRECT)srcObj->Buffer;
for (i = 0; i < srcObj->rdh.nCount; i++) for (i = 0; i < srcObj->rdh.nCount; i++)
{ {
rc->left -= 2 * x; rc->left -= 2 * x;
rc->right -= 2 * x; rc->right -= 2 * x;
rc++; rc++;
} }
REGION_IntersectRegion(destObj, destObj, srcObj); REGION_IntersectRegion(destObj, destObj, srcObj);
/* Original region moved down */ /* Original region moved down */
rc = (PRECT)srcObj->Buffer; rc = (PRECT)srcObj->Buffer;
for (i = 0; i < srcObj->rdh.nCount; i++) for (i = 0; i < srcObj->rdh.nCount; i++)
{ {
rc->left += x; rc->left += x;
rc->right += x; rc->right += x;
rc->top += y; rc->top += y;
rc->bottom += y; rc->bottom += y;
rc++; rc++;
} }
REGION_IntersectRegion(destObj, destObj, srcObj); REGION_IntersectRegion(destObj, destObj, srcObj);
/* Original region moved up */ /* Original region moved up */
rc = (PRECT)srcObj->Buffer; rc = (PRECT)srcObj->Buffer;
for (i = 0; i < srcObj->rdh.nCount; i++) for (i = 0; i < srcObj->rdh.nCount; i++)
{ {
rc->top -= 2 * y; rc->top -= 2 * y;
rc->bottom -= 2 * y; rc->bottom -= 2 * y;
rc++; rc++;
} }
REGION_IntersectRegion(destObj, destObj, srcObj); REGION_IntersectRegion(destObj, destObj, srcObj);
/* Restore the original region */ /* Restore the original region */
rc = (PRECT)srcObj->Buffer; rc = (PRECT)srcObj->Buffer;
for (i = 0; i < srcObj->rdh.nCount; i++) for (i = 0; i < srcObj->rdh.nCount; i++)
{ {
rc->top += y; rc->top += y;
rc->bottom += y; rc->bottom += y;
rc++; rc++;
}
REGION_SubtractRegion(destObj, srcObj, destObj);
} }
REGION_SubtractRegion(destObj, srcObj, destObj);
RGNDATA_UnlockRgn(destObj); RGNDATA_UnlockRgn(destObj);
RGNDATA_UnlockRgn(srcObj); RGNDATA_UnlockRgn(srcObj);