mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 09:10:56 +00:00
[WIN32K]
- Implement REGION_bXformRgn - Move IntGdiPaintRgn ro bitblt.c svn path=/trunk/; revision=65728
This commit is contained in:
parent
095f2182e8
commit
9697fb6e1e
3 changed files with 203 additions and 107 deletions
|
@ -1010,6 +1010,81 @@ NtGdiPolyPatBlt(
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
REGION_LPTODP(
|
||||||
|
_In_ PDC pdc,
|
||||||
|
_Inout_ PREGION prgnDest,
|
||||||
|
_In_ PREGION prgnSrc)
|
||||||
|
{
|
||||||
|
if (IntGdiCombineRgn(prgnDest, prgnSrc, NULL, RGN_COPY) == ERROR)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return REGION_bXformRgn(prgnDest, &pdc->dclevel.mxWorldToDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
IntGdiPaintRgn(
|
||||||
|
PDC dc,
|
||||||
|
PREGION Rgn)
|
||||||
|
{
|
||||||
|
PREGION VisRgn;
|
||||||
|
XCLIPOBJ ClipRegion;
|
||||||
|
BOOL bRet = FALSE;
|
||||||
|
POINTL BrushOrigin;
|
||||||
|
SURFACE *psurf;
|
||||||
|
PDC_ATTR pdcattr;
|
||||||
|
|
||||||
|
if ((dc == NULL) || (Rgn == NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pdcattr = dc->pdcattr;
|
||||||
|
|
||||||
|
ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)));
|
||||||
|
|
||||||
|
VisRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||||
|
if (VisRgn == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform region into device co-ords
|
||||||
|
if (!REGION_LPTODP(dc, VisRgn, Rgn) ||
|
||||||
|
IntGdiOffsetRgn(VisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
|
||||||
|
{
|
||||||
|
REGION_Delete(VisRgn);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dc->prgnRao)
|
||||||
|
IntGdiCombineRgn(VisRgn, VisRgn, dc->prgnRao, RGN_AND);
|
||||||
|
|
||||||
|
IntEngInitClipObj(&ClipRegion);
|
||||||
|
IntEngUpdateClipRegion(&ClipRegion,
|
||||||
|
VisRgn->rdh.nCount,
|
||||||
|
VisRgn->Buffer,
|
||||||
|
&VisRgn->rdh.rcBound );
|
||||||
|
|
||||||
|
BrushOrigin.x = pdcattr->ptlBrushOrigin.x;
|
||||||
|
BrushOrigin.y = pdcattr->ptlBrushOrigin.y;
|
||||||
|
psurf = dc->dclevel.pSurface;
|
||||||
|
/* FIXME: Handle psurf == NULL !!!! */
|
||||||
|
|
||||||
|
bRet = IntEngPaint(&psurf->SurfObj,
|
||||||
|
&ClipRegion.ClipObj,
|
||||||
|
&dc->eboFill.BrushObject,
|
||||||
|
&BrushOrigin,
|
||||||
|
0xFFFF); // FIXME: Don't know what to put here
|
||||||
|
|
||||||
|
REGION_Delete(VisRgn);
|
||||||
|
IntEngFreeClipResources(&ClipRegion);
|
||||||
|
|
||||||
|
// Fill the region
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtGdiFillRgn(
|
NtGdiFillRgn(
|
||||||
|
|
|
@ -1941,65 +1941,138 @@ GreCreateFrameRgn(
|
||||||
return hrgnFrame;
|
return hrgnFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_LPTODP(
|
REGION_bXformRgn(
|
||||||
_In_ PDC dc,
|
_Inout_ PREGION prgn,
|
||||||
_Inout_ PREGION RgnDest,
|
_In_ PMATRIX pmx)
|
||||||
_In_ PREGION RgnSrc)
|
|
||||||
{
|
{
|
||||||
RECTL *pCurRect, *pEndRect;
|
XFORMOBJ xo;
|
||||||
RECTL tmpRect;
|
ULONG i, j, cjSize;
|
||||||
PDC_ATTR pdcattr;
|
PPOINT ppt;
|
||||||
|
PULONG pcPoints;
|
||||||
|
RECT rect;
|
||||||
|
BOOL bResult;
|
||||||
|
|
||||||
if (dc == NULL)
|
/* Check if this is a scaling only matrix (off-diagonal elements are 0 */
|
||||||
return FALSE;
|
if (pmx->flAccel & XFORM_SCALE)
|
||||||
pdcattr = dc->pdcattr;
|
|
||||||
|
|
||||||
if (pdcattr->iMapMode == MM_TEXT) // Requires only a translation
|
|
||||||
{
|
{
|
||||||
if (IntGdiCombineRgn(RgnDest, RgnSrc, 0, RGN_COPY) == ERROR)
|
/* Check if this is a translation only matrix */
|
||||||
|
if (pmx->flAccel & XFORM_UNITY)
|
||||||
|
{
|
||||||
|
/* Just offset the region */
|
||||||
|
return IntGdiOffsetRgn(prgn, (pmx->fxDx + 8) / 16, (pmx->fxDy + 8) / 16) != ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Initialize the xform object */
|
||||||
|
XFORMOBJ_vInit(&xo, pmx);
|
||||||
|
|
||||||
|
/* Scaling can move the rects out of the coordinate space, so
|
||||||
|
* we first need to check whether we can apply the transformation
|
||||||
|
* on the bounds rect without modifying the region */
|
||||||
|
if (!XFORMOBJ_bApplyXform(&xo, XF_LTOL, 2, &prgn->rdh.rcBound, &rect))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the xform to the rects in the region */
|
||||||
|
if (!XFORMOBJ_bApplyXform(&xo,
|
||||||
|
XF_LTOL,
|
||||||
|
prgn->rdh.nCount * 2,
|
||||||
|
prgn->Buffer,
|
||||||
|
prgn->Buffer))
|
||||||
|
{
|
||||||
|
/* This can not happen, since we already checked the bounds! */
|
||||||
|
NT_ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset bounds */
|
||||||
|
RECTL_vSetEmptyRect(&prgn->rdh.rcBound);
|
||||||
|
|
||||||
|
/* Loop all rects in the region */
|
||||||
|
for (i = 0; i < prgn->rdh.nCount; i++)
|
||||||
|
{
|
||||||
|
/* Make sure the rect is well-ordered after the xform */
|
||||||
|
RECTL_vMakeWellOrdered(&prgn->Buffer[i]);
|
||||||
|
|
||||||
|
/* Update bounds */
|
||||||
|
RECTL_bUnionRect(&prgn->rdh.rcBound,
|
||||||
|
&prgn->rdh.rcBound,
|
||||||
|
&prgn->Buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop all rects in the region */
|
||||||
|
for (i = 0; i < prgn->rdh.nCount - 1; i++)
|
||||||
|
{
|
||||||
|
for (j = i; i < prgn->rdh.nCount; i++)
|
||||||
|
{
|
||||||
|
NT_ASSERT(prgn->Buffer[i].top < prgn->Buffer[i].bottom);
|
||||||
|
NT_ASSERT(prgn->Buffer[j].top >= prgn->Buffer[i].top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Allocate a buffer for the polygons */
|
||||||
|
cjSize = prgn->rdh.nCount * (4 * sizeof(POINT) + sizeof(ULONG));
|
||||||
|
ppt = ExAllocatePoolWithTag(PagedPool, cjSize, GDITAG_REGION);
|
||||||
|
if (ppt == NULL)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
IntGdiOffsetRgn(RgnDest,
|
|
||||||
pdcattr->ptlViewportOrg.x - pdcattr->ptlWindowOrg.x,
|
|
||||||
pdcattr->ptlViewportOrg.y - pdcattr->ptlWindowOrg.y);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
EMPTY_REGION(RgnDest);
|
|
||||||
|
|
||||||
pEndRect = RgnSrc->Buffer + RgnSrc->rdh.nCount;
|
|
||||||
for (pCurRect = RgnSrc->Buffer; pCurRect < pEndRect; pCurRect++)
|
|
||||||
{
|
|
||||||
tmpRect = *pCurRect;
|
|
||||||
tmpRect.left = XLPTODP(pdcattr, tmpRect.left);
|
|
||||||
tmpRect.top = YLPTODP(pdcattr, tmpRect.top);
|
|
||||||
tmpRect.right = XLPTODP(pdcattr, tmpRect.right);
|
|
||||||
tmpRect.bottom = YLPTODP(pdcattr, tmpRect.bottom);
|
|
||||||
|
|
||||||
if (tmpRect.left > tmpRect.right)
|
|
||||||
{
|
|
||||||
INT tmp = tmpRect.left;
|
|
||||||
tmpRect.left = tmpRect.right;
|
|
||||||
tmpRect.right = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpRect.top > tmpRect.bottom)
|
/* Fill the buffer with the rects */
|
||||||
|
pcPoints = (PULONG)&ppt[4 * prgn->rdh.nCount];
|
||||||
|
for (i = 0; i < prgn->rdh.nCount; i++)
|
||||||
{
|
{
|
||||||
INT tmp = tmpRect.top;
|
/* Make sure the rect is within the legal range */
|
||||||
tmpRect.top = tmpRect.bottom;
|
pcPoints[i] = 4;
|
||||||
tmpRect.bottom = tmp;
|
ppt[4 * i + 0].x = prgn->Buffer[i].left;
|
||||||
|
ppt[4 * i + 0].y = prgn->Buffer[i].top;
|
||||||
|
ppt[4 * i + 1].x = prgn->Buffer[i].right;
|
||||||
|
ppt[4 * i + 1].y = prgn->Buffer[i].top;
|
||||||
|
ppt[4 * i + 2].x = prgn->Buffer[i].right;
|
||||||
|
ppt[4 * i + 2].y = prgn->Buffer[i].bottom;
|
||||||
|
ppt[4 * i + 3].x = prgn->Buffer[i].left;
|
||||||
|
ppt[4 * i + 3].y = prgn->Buffer[i].bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
REGION_UnionRectWithRgn(RgnDest, &tmpRect);
|
/* Initialize the xform object */
|
||||||
|
XFORMOBJ_vInit(&xo, pmx);
|
||||||
|
|
||||||
|
/* Apply the xform to the rects in the buffer */
|
||||||
|
if (!XFORMOBJ_bApplyXform(&xo,
|
||||||
|
XF_LTOL,
|
||||||
|
prgn->rdh.nCount * 2,
|
||||||
|
ppt,
|
||||||
|
ppt))
|
||||||
|
{
|
||||||
|
/* This means, there were coordinates that would go outside of
|
||||||
|
the coordinate space after the transformation */
|
||||||
|
ExFreePoolWithTag(ppt, GDITAG_REGION);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now use the polygons to create a polygon region */
|
||||||
|
bResult = REGION_SetPolyPolygonRgn(prgn,
|
||||||
|
ppt,
|
||||||
|
pcPoints,
|
||||||
|
prgn->rdh.nCount,
|
||||||
|
WINDING);
|
||||||
|
|
||||||
|
/* Free the polygon buffer */
|
||||||
|
ExFreePoolWithTag(ppt, GDITAG_REGION);
|
||||||
|
|
||||||
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PREGION
|
PREGION
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_AllocRgnWithHandle(
|
REGION_AllocRgnWithHandle(
|
||||||
|
@ -2385,66 +2458,6 @@ IntGdiGetRgnBox(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
|
||||||
FASTCALL
|
|
||||||
IntGdiPaintRgn(
|
|
||||||
PDC dc,
|
|
||||||
PREGION Rgn)
|
|
||||||
{
|
|
||||||
PREGION VisRgn;
|
|
||||||
XCLIPOBJ ClipRegion;
|
|
||||||
BOOL bRet = FALSE;
|
|
||||||
POINTL BrushOrigin;
|
|
||||||
SURFACE *psurf;
|
|
||||||
PDC_ATTR pdcattr;
|
|
||||||
|
|
||||||
if ((dc == NULL) || (Rgn == NULL))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pdcattr = dc->pdcattr;
|
|
||||||
|
|
||||||
ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)));
|
|
||||||
|
|
||||||
VisRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
|
|
||||||
if (VisRgn == NULL)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform region into device co-ords
|
|
||||||
if (!REGION_LPTODP(dc, VisRgn, Rgn) ||
|
|
||||||
IntGdiOffsetRgn(VisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
|
|
||||||
{
|
|
||||||
REGION_Delete(VisRgn);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dc->prgnRao)
|
|
||||||
IntGdiCombineRgn(VisRgn, VisRgn, dc->prgnRao, RGN_AND);
|
|
||||||
|
|
||||||
IntEngInitClipObj(&ClipRegion);
|
|
||||||
IntEngUpdateClipRegion(&ClipRegion,
|
|
||||||
VisRgn->rdh.nCount,
|
|
||||||
VisRgn->Buffer,
|
|
||||||
&VisRgn->rdh.rcBound );
|
|
||||||
|
|
||||||
BrushOrigin.x = pdcattr->ptlBrushOrigin.x;
|
|
||||||
BrushOrigin.y = pdcattr->ptlBrushOrigin.y;
|
|
||||||
psurf = dc->dclevel.pSurface;
|
|
||||||
/* FIXME: Handle psurf == NULL !!!! */
|
|
||||||
|
|
||||||
bRet = IntEngPaint(&psurf->SurfObj,
|
|
||||||
&ClipRegion.ClipObj,
|
|
||||||
&dc->eboFill.BrushObject,
|
|
||||||
&BrushOrigin,
|
|
||||||
0xFFFF); // FIXME: Don't know what to put here
|
|
||||||
|
|
||||||
REGION_Delete(VisRgn);
|
|
||||||
IntEngFreeClipResources(&ClipRegion);
|
|
||||||
|
|
||||||
// Fill the region
|
|
||||||
return bRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
@ -3204,8 +3217,10 @@ REGION_SetPolyPolygonRgn(
|
||||||
* are in the Winding active edge table. */
|
* are in the Winding active edge table. */
|
||||||
if (pWETE == pAET)
|
if (pWETE == pAET)
|
||||||
{
|
{
|
||||||
pts->x = pAET->bres.minor_axis, pts->y = y;
|
pts->x = pAET->bres.minor_axis;
|
||||||
pts++, iPts++;
|
pts->y = y;
|
||||||
|
pts++;
|
||||||
|
iPts++;
|
||||||
|
|
||||||
/* Send out the buffer */
|
/* Send out the buffer */
|
||||||
if (iPts == NUMPTSTOBUFFER)
|
if (iPts == NUMPTSTOBUFFER)
|
||||||
|
@ -3245,7 +3260,7 @@ REGION_SetPolyPolygonRgn(
|
||||||
REGION_FreeStorage(SLLBlock.next);
|
REGION_FreeStorage(SLLBlock.next);
|
||||||
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, prgn);
|
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, prgn);
|
||||||
|
|
||||||
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;)
|
for (curPtBlock = FirstPtBlock.next; numFullPtBlocks-- > 0;)
|
||||||
{
|
{
|
||||||
tmpPtBlock = curPtBlock->next;
|
tmpPtBlock = curPtBlock->next;
|
||||||
ExFreePoolWithTag(curPtBlock, TAG_REGION);
|
ExFreePoolWithTag(curPtBlock, TAG_REGION);
|
||||||
|
|
|
@ -39,6 +39,12 @@ VOID NTAPI REGION_vCleanup(PVOID ObjectBody);
|
||||||
VOID FASTCALL REGION_Delete(PREGION);
|
VOID FASTCALL REGION_Delete(PREGION);
|
||||||
INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*);
|
INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
REGION_bXformRgn(
|
||||||
|
_Inout_ PREGION prgn,
|
||||||
|
_In_ PMATRIX pmx);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
REGION_SetPolyPolygonRgn(
|
REGION_SetPolyPolygonRgn(
|
||||||
|
|
Loading…
Reference in a new issue