Author: tkreuzer Date: Thu Dec 18 08:12:06 2014 New Revision: 65728
URL: http://svn.reactos.org/svn/reactos?rev=65728&view=rev Log: [WIN32K] - Implement REGION_bXformRgn - Move IntGdiPaintRgn ro bitblt.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c trunk/reactos/win32ss/gdi/ntgdi/region.c trunk/reactos/win32ss/gdi/ntgdi/region.h
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitblt.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] Thu Dec 18 08:12:06 2014 @@ -1010,6 +1010,81 @@ 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 APIENTRY NtGdiFillRgn(
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] Thu Dec 18 08:12:06 2014 @@ -1941,64 +1941,137 @@ return hrgnFrame; }
- -static BOOL FASTCALL -REGION_LPTODP( - _In_ PDC dc, - _Inout_ PREGION RgnDest, - _In_ PREGION RgnSrc) -{ - RECTL *pCurRect, *pEndRect; - RECTL tmpRect; - PDC_ATTR pdcattr; - - if (dc == NULL) - return FALSE; - pdcattr = dc->pdcattr; - - if (pdcattr->iMapMode == MM_TEXT) // Requires only a translation - { - if (IntGdiCombineRgn(RgnDest, RgnSrc, 0, RGN_COPY) == ERROR) +REGION_bXformRgn( + _Inout_ PREGION prgn, + _In_ PMATRIX pmx) +{ + XFORMOBJ xo; + ULONG i, j, cjSize; + PPOINT ppt; + PULONG pcPoints; + RECT rect; + BOOL bResult; + + /* Check if this is a scaling only matrix (off-diagonal elements are 0 */ + if (pmx->flAccel & XFORM_SCALE) + { + /* 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; - - 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) - { - INT tmp = tmpRect.top; - tmpRect.top = tmpRect.bottom; - tmpRect.bottom = tmp; - } - - REGION_UnionRectWithRgn(RgnDest, &tmpRect); - } - - return TRUE; -} + } + + /* Fill the buffer with the rects */ + pcPoints = (PULONG)&ppt[4 * prgn->rdh.nCount]; + for (i = 0; i < prgn->rdh.nCount; i++) + { + /* Make sure the rect is within the legal range */ + pcPoints[i] = 4; + 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; + } + + /* 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; + } + +} +
PREGION FASTCALL @@ -2385,66 +2458,6 @@ 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 FASTCALL @@ -3204,8 +3217,10 @@ * are in the Winding active edge table. */ if (pWETE == pAET) { - pts->x = pAET->bres.minor_axis, pts->y = y; - pts++, iPts++; + pts->x = pAET->bres.minor_axis; + pts->y = y; + pts++; + iPts++;
/* Send out the buffer */ if (iPts == NUMPTSTOBUFFER) @@ -3245,7 +3260,7 @@ REGION_FreeStorage(SLLBlock.next); REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, prgn);
- for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) + for (curPtBlock = FirstPtBlock.next; numFullPtBlocks-- > 0;) { tmpPtBlock = curPtBlock->next; ExFreePoolWithTag(curPtBlock, TAG_REGION);
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.h?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/region.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/region.h [iso-8859-1] Thu Dec 18 08:12:06 2014 @@ -38,6 +38,12 @@ VOID NTAPI REGION_vCleanup(PVOID ObjectBody); VOID FASTCALL REGION_Delete(PREGION); INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*); + +BOOL +FASTCALL +REGION_bXformRgn( + _Inout_ PREGION prgn, + _In_ PMATRIX pmx);
BOOL FASTCALL