- Rename SetRectRgnEx to IntSetRectRgn and make it usermode only
- Implement IntSetNullRgn
- Improve SetRectRgn code and enable the usermode part

svn path=/trunk/; revision=65739
This commit is contained in:
Timo Kreuzer 2014-12-18 08:13:14 +00:00
parent f3f9526d93
commit 217eef81d8

View file

@ -189,21 +189,36 @@ MirrorRgnDC(HDC hdc, HRGN hRgn, HRGN *phRgn)
FORCEINLINE FORCEINLINE
ULONG ULONG
SetRectRgnEx( IntSetNullRgn(
HRGN hrgn, _Inout_ PRGN_ATTR prgnattr)
PRGN_ATTR prgnattr,
INT xLeft,
INT yTop,
INT xRight,
INT yBottom)
{ {
if (!SetRectRgn(hrgn, xLeft, yTop, xRight, yBottom)) prgnattr->iComplexity = NULLREGION;
{ prgnattr->AttrFlags |= ATTR_RGN_DIRTY;
return ERROR; return NULLREGION;
} }
return prgnattr->iComplexity; FORCEINLINE
ULONG
IntSetRectRgn(
_Inout_ PRGN_ATTR prgnattr,
_In_ INT xLeft,
_In_ INT yTop,
_In_ INT xRight,
_In_ INT yBottom)
{
ASSERT(xLeft <= xRight);
ASSERT(yTop <= yBottom);
if ((xLeft == xRight) || (yTop == yBottom))
return IntSetNullRgn(prgnattr);
prgnattr->iComplexity = SIMPLEREGION;
prgnattr->Rect.left = xLeft;
prgnattr->Rect.top = yTop;
prgnattr->Rect.right = xRight;
prgnattr->Rect.bottom = yBottom;
prgnattr->AttrFlags |= ATTR_RGN_DIRTY;
return SIMPLEREGION;
} }
/* /*
@ -240,17 +255,16 @@ CombineRgn(
if (prngattrSrc1->iComplexity == NULLREGION) if (prngattrSrc1->iComplexity == NULLREGION)
{ {
/* The dest region is a NULLREGION, too */ /* The dest region is a NULLREGION, too */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* We already know that the source region cannot be complex, so /* We already know that the source region cannot be complex, so
create a rect region from the bounds of the source rect */ create a rect region from the bounds of the source rect */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom);
prngattrSrc1->Rect.bottom);
} }
/* For all other operations we need hrgnSrc2 */ /* For all other operations we need hrgnSrc2 */
@ -270,23 +284,22 @@ CombineRgn(
(prngattrSrc2->iComplexity == NULLREGION)) (prngattrSrc2->iComplexity == NULLREGION))
{ {
/* Result is also a NULLREGION */ /* Result is also a NULLREGION */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* Get the intersection of the 2 rects */ /* Get the intersection of the 2 rects */
if (!IntersectRect(&rcTemp, &prngattrSrc1->Rect, &prngattrSrc2->Rect)) if (!IntersectRect(&rcTemp, &prngattrSrc1->Rect, &prngattrSrc2->Rect))
{ {
/* The rects do not intersect, result is a NULLREGION */ /* The rects do not intersect, result is a NULLREGION */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* Use the intersection of the rects */ /* Use the intersection of the rects */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, rcTemp.left,
rcTemp.left, rcTemp.top,
rcTemp.top, rcTemp.right,
rcTemp.right, rcTemp.bottom);
rcTemp.bottom);
} }
/* Handle RGN_DIFF */ /* Handle RGN_DIFF */
@ -296,7 +309,7 @@ CombineRgn(
if (prngattrSrc1->iComplexity == NULLREGION) if (prngattrSrc1->iComplexity == NULLREGION)
{ {
/* The result is a NULLREGION as well */ /* The result is a NULLREGION as well */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* Get the intersection of the 2 rects */ /* Get the intersection of the 2 rects */
@ -304,12 +317,11 @@ CombineRgn(
!IntersectRect(&rcTemp, &prngattrSrc1->Rect, &prngattrSrc2->Rect)) !IntersectRect(&rcTemp, &prngattrSrc1->Rect, &prngattrSrc2->Rect))
{ {
/* The rects do not intersect, dest equals source 1 */ /* The rects do not intersect, dest equals source 1 */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom);
prngattrSrc1->Rect.bottom);
} }
/* We need to check is whether we can subtract the rects. For that /* We need to check is whether we can subtract the rects. For that
@ -319,7 +331,7 @@ CombineRgn(
if (!SubtractRect(&rcTemp, &prngattrSrc1->Rect, &rcTemp)) if (!SubtractRect(&rcTemp, &prngattrSrc1->Rect, &rcTemp))
{ {
/* The result is a NULLREGION */ /* The result is a NULLREGION */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* Now check if the result of SubtractRect matches the source 1 rect. /* Now check if the result of SubtractRect matches the source 1 rect.
@ -330,12 +342,11 @@ CombineRgn(
if (!EqualRect(&rcTemp, &prngattrSrc1->Rect)) if (!EqualRect(&rcTemp, &prngattrSrc1->Rect))
{ {
/* We got a properly subtracted rect, so use it. */ /* We got a properly subtracted rect, so use it. */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, rcTemp.left,
rcTemp.left, rcTemp.top,
rcTemp.top, rcTemp.right,
rcTemp.right, rcTemp.bottom);
rcTemp.bottom);
} }
/* The result would be a complex region, go to win32k */ /* The result would be a complex region, go to win32k */
@ -352,28 +363,26 @@ CombineRgn(
if (prngattrSrc2->iComplexity == NULLREGION) if (prngattrSrc2->iComplexity == NULLREGION)
{ {
/* Both are NULLREGIONs, result is also a NULLREGION */ /* Both are NULLREGIONs, result is also a NULLREGION */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
/* The result is equal to source 2 */ /* The result is equal to source 2 */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc2->Rect.left,
prngattrSrc2->Rect.left, prngattrSrc2->Rect.top,
prngattrSrc2->Rect.top, prngattrSrc2->Rect.right,
prngattrSrc2->Rect.right, prngattrSrc2->Rect.bottom );
prngattrSrc2->Rect.bottom );
} }
/* Check if only source 2 is a NULLREGION */ /* Check if only source 2 is a NULLREGION */
if (prngattrSrc2->iComplexity == NULLREGION) if (prngattrSrc2->iComplexity == NULLREGION)
{ {
/* The result is equal to source 1 */ /* The result is equal to source 1 */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom);
prngattrSrc1->Rect.bottom);
} }
/* Do the rects have the same x extent */ /* Do the rects have the same x extent */
@ -388,17 +397,16 @@ CombineRgn(
if (iCombineMode == RGN_OR) if (iCombineMode == RGN_OR)
{ {
/* The result is equal to source 1 */ /* The result is equal to source 1 */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom );
prngattrSrc1->Rect.bottom );
} }
else else
{ {
/* XORing with itself yields an empty region */ /* XORing with itself yields an empty region */
return SetRectRgn(hrgnDest, 0, 0, 0, 0) ? NULLREGION : ERROR; return IntSetNullRgn(prngattrDest);
} }
} }
@ -414,34 +422,31 @@ CombineRgn(
if (iCombineMode == RGN_OR) if (iCombineMode == RGN_OR)
{ {
/* Use the maximum extent of both rects combined */ /* Use the maximum extent of both rects combined */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, min(prngattrSrc1->Rect.top, prngattrSrc2->Rect.top),
min(prngattrSrc1->Rect.top, prngattrSrc2->Rect.top), prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, max(prngattrSrc1->Rect.bottom, prngattrSrc2->Rect.bottom));
max(prngattrSrc1->Rect.bottom, prngattrSrc2->Rect.bottom));
} }
/* Check if the rects are adjacent */ /* Check if the rects are adjacent */
if (prngattrSrc2->Rect.bottom == prngattrSrc1->Rect.top) if (prngattrSrc2->Rect.bottom == prngattrSrc1->Rect.top)
{ {
/* The result is the combined rects */ /* The result is the combined rects */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc2->Rect.top,
prngattrSrc2->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom );
prngattrSrc1->Rect.bottom );
} }
else if (prngattrSrc2->Rect.top == prngattrSrc1->Rect.bottom) else if (prngattrSrc2->Rect.top == prngattrSrc1->Rect.bottom)
{ {
/* The result is the combined rects */ /* The result is the combined rects */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc2->Rect.bottom );
prngattrSrc2->Rect.bottom );
} }
/* When we are here, this is RGN_XOR and the rects overlap */ /* When we are here, this is RGN_XOR and the rects overlap */
@ -464,34 +469,31 @@ CombineRgn(
if (iCombineMode == RGN_OR) if (iCombineMode == RGN_OR)
{ {
/* Use the maximum extent of both rects combined */ /* Use the maximum extent of both rects combined */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, min(prngattrSrc1->Rect.left, prngattrSrc2->Rect.left),
min(prngattrSrc1->Rect.left, prngattrSrc2->Rect.left), prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, max(prngattrSrc1->Rect.right, prngattrSrc2->Rect.right),
max(prngattrSrc1->Rect.right, prngattrSrc2->Rect.right), prngattrSrc1->Rect.bottom);
prngattrSrc1->Rect.bottom);
} }
/* Check if the rects are adjacent */ /* Check if the rects are adjacent */
if (prngattrSrc2->Rect.right == prngattrSrc1->Rect.left) if (prngattrSrc2->Rect.right == prngattrSrc1->Rect.left)
{ {
/* The result is the combined rects */ /* The result is the combined rects */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc2->Rect.left,
prngattrSrc2->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom );
prngattrSrc1->Rect.bottom );
} }
else if (prngattrSrc2->Rect.left == prngattrSrc1->Rect.right) else if (prngattrSrc2->Rect.left == prngattrSrc1->Rect.right)
{ {
/* The result is the combined rects */ /* The result is the combined rects */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc2->Rect.right,
prngattrSrc2->Rect.right, prngattrSrc1->Rect.bottom );
prngattrSrc1->Rect.bottom );
} }
/* When we are here, this is RGN_XOR and the rects overlap */ /* When we are here, this is RGN_XOR and the rects overlap */
@ -510,12 +512,11 @@ CombineRgn(
(prngattrSrc1->Rect.bottom >= prngattrSrc2->Rect.bottom)) (prngattrSrc1->Rect.bottom >= prngattrSrc2->Rect.bottom))
{ {
/* Rect 1 contains rect 2, use it */ /* Rect 1 contains rect 2, use it */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc1->Rect.left,
prngattrSrc1->Rect.left, prngattrSrc1->Rect.top,
prngattrSrc1->Rect.top, prngattrSrc1->Rect.right,
prngattrSrc1->Rect.right, prngattrSrc1->Rect.bottom );
prngattrSrc1->Rect.bottom );
} }
} }
else else
@ -526,12 +527,11 @@ CombineRgn(
(prngattrSrc2->Rect.bottom >= prngattrSrc1->Rect.bottom)) (prngattrSrc2->Rect.bottom >= prngattrSrc1->Rect.bottom))
{ {
/* Rect 2 contains rect 1, use it */ /* Rect 2 contains rect 1, use it */
return SetRectRgnEx(hrgnDest, return IntSetRectRgn(prngattrDest,
prngattrDest, prngattrSrc2->Rect.left,
prngattrSrc2->Rect.left, prngattrSrc2->Rect.top,
prngattrSrc2->Rect.top, prngattrSrc2->Rect.right,
prngattrSrc2->Rect.right, prngattrSrc2->Rect.bottom );
prngattrSrc2->Rect.bottom );
} }
} }
} }
@ -1154,44 +1154,54 @@ SelectClipRgn(
*/ */
BOOL BOOL
WINAPI WINAPI
SetRectRgn(HRGN hrgn, SetRectRgn(
int nLeftRect, _In_ HRGN hrgn,
int nTopRect, _In_ INT xLeft,
int nRightRect, _In_ INT yTop,
int nBottomRect) _In_ INT xRight,
_In_ INT yBottom)
{ {
PRGN_ATTR Rgn_Attr; PRGN_ATTR prngattr;
//if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) /* Try to get the region attribute */
return NtGdiSetRectRgn(hrgn, nLeftRect, nTopRect, nRightRect, nBottomRect); prngattr = GdiGetRgnAttr(hrgn);
if (prngattr == NULL)
if ((nLeftRect == nRightRect) || (nTopRect == nBottomRect))
{ {
Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY; return NtGdiSetRectRgn(hrgn, xLeft, yTop, xRight, yBottom);
Rgn_Attr->iComplexity = NULLREGION; }
Rgn_Attr->Rect.left = Rgn_Attr->Rect.top =
Rgn_Attr->Rect.right = Rgn_Attr->Rect.bottom = 0; /* check for NULL region */
if ((xLeft == xRight) || (yTop == yBottom))
{
IntSetNullRgn(prngattr);
return TRUE; return TRUE;
} }
Rgn_Attr->Rect.left = nLeftRect; if (xLeft > xRight)
Rgn_Attr->Rect.top = nTopRect;
Rgn_Attr->Rect.right = nRightRect;
Rgn_Attr->Rect.bottom = nBottomRect;
if(nLeftRect > nRightRect)
{ {
Rgn_Attr->Rect.left = nRightRect; prngattr->Rect.left = xRight;
Rgn_Attr->Rect.right = nLeftRect; prngattr->Rect.right = xLeft;
} }
if(nTopRect > nBottomRect) else
{ {
Rgn_Attr->Rect.top = nBottomRect; prngattr->Rect.left = xLeft;
Rgn_Attr->Rect.bottom = nTopRect; prngattr->Rect.right = xRight;
} }
Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY ; if (yTop > yBottom)
Rgn_Attr->iComplexity = SIMPLEREGION; {
prngattr->Rect.top = yBottom;
prngattr->Rect.bottom = yTop;
}
else
{
prngattr->Rect.top = yTop;
prngattr->Rect.bottom = yBottom;
}
prngattr->AttrFlags |= ATTR_RGN_DIRTY ;
prngattr->iComplexity = SIMPLEREGION;
return TRUE; return TRUE;
} }