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

View file

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