- Modify REGION_CropAndOffsetRegion to return the region complexity
- Improve NtGdiIntersectClipRect to only allocate a new region, if we don't have one yet, otherwise crop it using REGION_CropAndOffsetRegion

svn path=/trunk/; revision=64249
This commit is contained in:
Timo Kreuzer 2014-09-23 20:21:13 +00:00
parent 515ead4a5d
commit fc26231290
3 changed files with 64 additions and 47 deletions

View file

@ -241,54 +241,71 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC,
return Result;
}
int APIENTRY NtGdiIntersectClipRect(HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect)
INT
APIENTRY
NtGdiIntersectClipRect(
_In_ HDC hdc,
_In_ INT xLeft,
_In_ INT yTop,
_In_ INT xRight,
_In_ INT yBottom)
{
INT Result;
RECTL Rect;
PREGION pNewRgn;
PDC dc = DC_LockDc(hDC);
INT iComplexity;
RECTL rect;
PREGION prgnNew;
PDC pdc;
DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
hDC, LeftRect, TopRect, RightRect, BottomRect);
hdc, xLeft, yTop, xRight, yBottom);
if (!dc)
/* Lock the DC */
pdc = DC_LockDc(hdc);
if (!pdc)
{
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;
IntLPtoDP(pdc, (LPPOINT)&rect, 2);
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
pNewRgn = IntSysCreateRectpRgnIndirect(&Rect);
if (!pNewRgn)
/* Check if we already have a clip region */
if (pdc->dclevel.prgnClip != NULL)
{
Result = ERROR;
}
else if (!dc->dclevel.prgnClip)
{
dc->dclevel.prgnClip = pNewRgn;
Result = SIMPLEREGION;
/* We have a region, crop it */
iComplexity = REGION_CropAndOffsetRegion(pdc->dclevel.prgnClip,
pdc->dclevel.prgnClip,
&rect,
NULL);
}
else
{
Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND);
REGION_Delete(pNewRgn);
/* We don't have a region yet, allocate a new one */
prgnNew = IntSysCreateRectpRgnIndirect(&rect);
if (prgnNew == NULL)
{
iComplexity = ERROR;
}
else
{
/* Set the new region */
pdc->dclevel.prgnClip = prgnNew;
iComplexity = SIMPLEREGION;
}
}
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 APIENTRY NtGdiOffsetClipRgn(HDC hDC,

View file

@ -489,12 +489,12 @@ IntDumpRegion(HRGN hRgn)
INT
FASTCALL
REGION_Complexity( PROSRGNDATA obj )
REGION_Complexity(PREGION prgn)
{
if (!obj) return NULLREGION;
switch(obj->rdh.nCount)
if (!prgn) return NULLREGION;
switch(prgn->rdh.nCount)
{
DPRINT("Region Complexity -> %lu",obj->rdh.nCount);
DPRINT("Region Complexity -> %lu", prgn->rdh.nCount);
case 0: return NULLREGION;
case 1: return SIMPLEREGION;
default: return COMPLEXREGION;
@ -581,13 +581,13 @@ REGION_SetExtents(ROSRGNDATA *pReg)
/***********************************************************************
* REGION_CropAndOffsetRegion
*/
BOOL FASTCALL
INT
FASTCALL
REGION_CropAndOffsetRegion(
PROSRGNDATA rgnDst,
PROSRGNDATA rgnSrc,
PREGION rgnDst,
PREGION rgnSrc,
const RECTL *rect,
const POINTL *offset
)
const POINTL *offset) // FIXME: we should probably remove offset from here
{
POINT pt = {0,0};
const POINT *off = offset;
@ -602,13 +602,13 @@ REGION_CropAndOffsetRegion(
if (off->x || off->y)
xrect = rgnDst->Buffer;
else
return TRUE;
return REGION_Complexity(rgnDst);
}
else
{
xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION);
if(!xrect)
return FALSE;
return ERROR;
if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // Free the old buffer. Will be assigned to xrect below.
}
@ -669,7 +669,7 @@ REGION_CropAndOffsetRegion(
PRECTL temp;
temp = ExAllocatePoolWithTag(PagedPool, i * sizeof(RECT), TAG_REGION);
if (!temp)
return FALSE;
return ERROR;
if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // free the old buffer
@ -727,7 +727,7 @@ REGION_CropAndOffsetRegion(
rgnDst->rdh.iType = RDH_RECTANGLES;
}
return TRUE;
return REGION_Complexity(rgnDst);
empty:
if (!rgnDst->Buffer)
@ -739,10 +739,10 @@ empty:
rgnDst->rdh.nRgnSize = RGN_DEFAULT_RECTS * sizeof(RECT);
}
else
return FALSE;
return ERROR;
}
EMPTY_REGION(rgnDst);
return TRUE;
return NULLREGION;
}

View file

@ -28,7 +28,7 @@ VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);
BOOL FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
INT FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
VOID FASTCALL REGION_SetRectRgn(PROSRGNDATA pRgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
VOID NTAPI REGION_vCleanup(PVOID ObjectBody);