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?rev=65728&r1=65727&r2=65728&view=diff
==============================================================================
--- 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?rev=65728&r1=65727&r2=65728&view=diff
==============================================================================
--- 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?rev=65728&r1=65727&r2=65728&view=diff
==============================================================================
--- 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


Reply via email to