- Implement REGION_SubtractRectFromRgn
- Rewrite NtGdiExcludeClipRect, fixing a number of gdi32 apitests

svn path=/trunk/; revision=64260
This commit is contained in:
Timo Kreuzer 2014-09-24 21:23:03 +00:00
parent 4ef9449b30
commit ae5b9eb418
3 changed files with 71 additions and 29 deletions

View file

@ -190,55 +190,79 @@ NtGdiGetAppClipBox(
return iComplexity;
}
int APIENTRY NtGdiExcludeClipRect(HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect)
INT
APIENTRY
NtGdiExcludeClipRect(
_In_ HDC hdc,
_In_ INT xLeft,
_In_ INT yTop,
_In_ INT xRight,
_In_ INT yBottom)
{
INT Result;
RECTL Rect;
PREGION prgnNew;
PDC dc = DC_LockDc(hDC);
INT iComplexity;
RECTL rect;
PDC pdc;
if (!dc)
/* Lock the DC */
pdc = DC_LockDc(hdc);
if (pdc == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
Rect.left = LeftRect;
Rect.top = TopRect;
Rect.right = RightRect;
Rect.bottom = BottomRect;
/* Convert coordinates to device space */
rect.left = xLeft;
rect.top = yTop;
rect.right = xRight;
rect.bottom = yBottom;
RECTL_vMakeWellOrdered(&rect);
IntLPtoDP(pdc, (LPPOINT)&rect, 2);
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
if (!prgnNew)
/* Check if we already have a clip region */
if (pdc->dclevel.prgnClip != NULL)
{
Result = ERROR;
/* We have a region, subtract the rect */
iComplexity = REGION_SubtractRectFromRgn(pdc->dclevel.prgnClip,
pdc->dclevel.prgnClip,
&rect);
/* Emulate Windows behavior */
if (iComplexity == SIMPLEREGION)
iComplexity = COMPLEXREGION;
}
else
{
if (!dc->dclevel.prgnClip)
/* Check if the rect intersects with the window rect */
if (RECTL_bIntersectRect(&rect, &rect, &pdc->erclWindow))
{
dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
IntGdiCombineRgn(dc->dclevel.prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
Result = SIMPLEREGION;
/* It does. In this case create an empty region */
pdc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
iComplexity = NULLREGION;
}
else
{
Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgnNew, RGN_DIFF);
/* Otherwise, emulate strange Windows behavior... */
pdc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 1, 1);
iComplexity = COMPLEXREGION;
}
/* Check if creating the region failed */
if (pdc->dclevel.prgnClip == NULL)
{
/* Return error code */
iComplexity = ERROR;
}
REGION_Delete(prgnNew);
}
if (Result != ERROR)
dc->fs |= DC_FLAG_DIRTY_RAO;
DC_UnlockDc(dc);
/* If we succeeded, mark the RAO region as dirty */
if (iComplexity != ERROR)
pdc->fs |= DC_FLAG_DIRTY_RAO;
return Result;
/* Unlock the DC */
DC_UnlockDc(pdc);
return iComplexity;
}
INT

View file

@ -1773,6 +1773,23 @@ REGION_UnionRectWithRgn(
REGION_UnionRegion(rgn, rgn, &region);
}
INT
FASTCALL
REGION_SubtractRectFromRgn(
PREGION prgnDest,
PREGION prgnSrc,
const RECTL *prcl)
{
REGION rgnLocal;
rgnLocal.Buffer = &rgnLocal.rdh.rcBound;
rgnLocal.rdh.nCount = 1;
rgnLocal.rdh.nRgnSize = sizeof(RECT);
rgnLocal.rdh.rcBound = *prcl;
REGION_SubtractRegion(prgnDest, prgnSrc, &rgnLocal);
return REGION_Complexity(prgnDest);
}
BOOL FASTCALL
REGION_CreateSimpleFrameRgn(
PROSRGNDATA rgn,

View file

@ -25,6 +25,7 @@ typedef struct _ROSRGNDATA
PROSRGNDATA FASTCALL REGION_AllocRgnWithHandle(INT n);
PROSRGNDATA FASTCALL REGION_AllocUserRgnWithHandle(INT n);
VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
INT FASTCALL REGION_SubtractRectFromRgn(PREGION prgnDest, PREGION prgnSrc, const RECTL *prcl);
INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);