[NtGDI] Fix ExtSelectClipRgn Tests
[reactos.git] / win32ss / gdi / ntgdi / fillshap.c
index a185073..c18ff00 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * PROJECT:         ReactOS win32 kernel mode subsystem
  * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            subsystems/win32/win32k/objects/fillshap.c
+ * FILE:            win32ss/gdi/ntgdi/fillshap.c
  * PURPOSE:         fillshap
  * PROGRAMMER:
  */
@@ -81,8 +81,11 @@ IntGdiPolygon(PDC    dc,
         pbrFill = dc->dclevel.pbrFill;
         pbrLine = dc->dclevel.pbrLine;
         psurf = dc->dclevel.pSurface;
-        /* FIXME: psurf can be NULL!!!! don't assert but handle this case gracefully! */
-        ASSERT(psurf);
+        if (psurf == NULL)
+        {
+            /* Memory DC without a bitmap selected, nothing to do. */
+            return TRUE;
+        }
 
         /* Now fill the polygon with the current fill brush. */
         if (!(pbrFill->flAttrs & BR_IS_NULL))
@@ -112,7 +115,7 @@ IntGdiPolygon(PDC    dc,
 //                                 Points[1].x, Points[1].y );
 
                 ret = IntEngLineTo(&psurf->SurfObj,
-                                   dc->rosdc.CombinedClip,
+                                   (CLIPOBJ *)&dc->co,
                                    &dc->eboLine.BrushObject,
                                    Points[i].x,          /* From */
                                    Points[i].y,
@@ -126,7 +129,7 @@ IntGdiPolygon(PDC    dc,
             if (ret)
             {
                 ret = IntEngLineTo(&psurf->SurfObj,
-                                   dc->rosdc.CombinedClip,
+                                   (CLIPOBJ *)&dc->co,
                                    &dc->eboLine.BrushObject,
                                    Points[Count-1].x, /* From */
                                    Points[Count-1].y,
@@ -159,6 +162,24 @@ IntGdiPolyPolygon(DC      *dc,
     return TRUE;
 }
 
+BOOL FASTCALL
+IntPolygon(HDC hdc, POINT *Point, int Count)
+{
+    BOOL bResult;
+    PDC pdc;
+
+    pdc = DC_LockDc(hdc);
+    if (pdc == NULL)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    bResult = IntGdiPolygon(pdc, Point, Count);
+
+    DC_UnlockDc(pdc);
+    return bResult;
+}
 
 
 /******************************************************************************/
@@ -193,20 +214,12 @@ NtGdiEllipse(
     PBRUSH pFillBrushObj;
     BRUSH tmpFillBrushObj;
 
-    if ((Left == Right) || (Top == Bottom)) return TRUE;
-
     dc = DC_LockDc(hDC);
     if (dc == NULL)
     {
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
     }
-    if (dc->dctype == DC_TYPE_INFO)
-    {
-       DC_UnlockDc(dc);
-       /* Yes, Windows really returns TRUE in this case */
-       return TRUE;
-    }
 
     if (PATH_IsPathOpen(dc->dclevel))
     {
@@ -215,6 +228,15 @@ NtGdiEllipse(
         return ret;
     }
 
+    ////
+    //// Could this use PATH_CheckCorners ?
+    ////
+    if ((Left == Right) || (Top == Bottom))
+    {
+       DC_UnlockDc(dc);
+       return TRUE;
+    }
+
     if (Right < Left)
     {
        INT tmp = Right; Right = Left; Left = tmp;
@@ -223,6 +245,7 @@ NtGdiEllipse(
     {
        INT tmp = Bottom; Bottom = Top; Top = tmp;
     }
+    ////
 
     pdcattr = dc->pdcattr;
 
@@ -241,7 +264,7 @@ NtGdiEllipse(
         return FALSE;
     }
 
-    PenOrigWidth = PenWidth = pbrush->ptPenWidth.x;
+    PenOrigWidth = PenWidth = pbrush->lWidth;
     if (pbrush->ulPenStyle == PS_NULL) PenWidth = 0;
 
     if (pbrush->ulPenStyle == PS_INSIDEFRAME)
@@ -255,7 +278,7 @@ NtGdiEllipse(
     }
 
     if (!PenWidth) PenWidth = 1;
-    pbrush->ptPenWidth.x = PenWidth;
+    pbrush->lWidth = PenWidth;
 
     RectBounds.left   = Left;
     RectBounds.right  = Right;
@@ -295,6 +318,9 @@ NtGdiEllipse(
         //tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
         tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
         tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;
+
+        DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
+
         ret = IntFillEllipse( dc,
                               CenterX - RadiusX,
                               CenterY - RadiusY,
@@ -302,17 +328,21 @@ NtGdiEllipse(
                               RadiusY*2, // Height
                               &tmpFillBrushObj);
         BRUSH_ShareUnlockBrush(pFillBrushObj);
-    }
 
-    if (ret)
-       ret = IntDrawEllipse( dc,
-                             CenterX - RadiusX,
-                             CenterY - RadiusY,
-                             RadiusX*2, // Width
-                             RadiusY*2, // Height
-                             pbrush);
+        if (ret)
+        {
+           ret = IntDrawEllipse( dc,
+                                 CenterX - RadiusX,
+                                 CenterY - RadiusY,
+                                 RadiusX*2, // Width
+                                 RadiusY*2, // Height
+                                 pbrush);
+        }
 
-    pbrush->ptPenWidth.x = PenOrigWidth;
+        DC_vFinishBlit(dc, NULL);
+    }
+
+    pbrush->lWidth = PenOrigWidth;
     PEN_ShareUnlockPen(pbrush);
     DC_UnlockDc(dc);
     DPRINT("Ellipse Exit.\n");
@@ -440,10 +470,13 @@ NtGdiPolyPolyDraw( IN HDC hDC,
     /* Special handling for GdiPolyPolyRgn */
     if (iFunc == GdiPolyPolyRgn)
     {
-        HRGN hRgn;
-        hRgn = IntCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, (INT_PTR)hDC);
+        INT iMode = (INT)(UINT_PTR)hDC;
+        HRGN hrgn;
+
+        hrgn = GreCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, iMode);
+
         ExFreePoolWithTag(pTemp, TAG_SHAPE);
-        return (ULONG_PTR)hRgn;
+        return (ULONG_PTR)hrgn;
     }
 
     dc = DC_LockDc(hDC);
@@ -454,16 +487,7 @@ NtGdiPolyPolyDraw( IN HDC hDC,
         return FALSE;
     }
 
-    if (dc->dctype == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(dc);
-        ExFreePoolWithTag(pTemp, TAG_SHAPE);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
-
-    DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                            NULL, dc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
     if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(dc);
@@ -542,6 +566,11 @@ IntRectangle(PDC dc,
     DestRect.top    += dc->ptlDCOrig.y;
     DestRect.bottom += dc->ptlDCOrig.y;
 
+    if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
+    {
+       IntUpdateBoundsRect(dc, &DestRect);
+    }
+
     /* In GM_COMPATIBLE, don't include bottom and right edges */
     if (pdcattr->iGraphicsMode == GM_COMPATIBLE)
     {
@@ -549,7 +578,7 @@ IntRectangle(PDC dc,
         DestRect.bottom--;
     }
 
-    DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+    DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(dc);
@@ -568,7 +597,7 @@ IntRectangle(PDC dc,
     psurf = dc->dclevel.pSurface;
     if (!psurf)
     {
-        ret = FALSE;
+        ret = TRUE;
         goto cleanup;
     }
 
@@ -582,7 +611,7 @@ IntRectangle(PDC dc,
             ret = IntEngBitBlt(&psurf->SurfObj,
                                NULL,
                                NULL,
-                               dc->rosdc.CombinedClip,
+                               (CLIPOBJ *)&dc->co,
                                NULL,
                                &DestRect,
                                NULL,
@@ -601,28 +630,28 @@ IntRectangle(PDC dc,
     {
         Mix = ROP2_TO_MIX(pdcattr->jROP2);
         ret = ret && IntEngLineTo(&psurf->SurfObj,
-                                  dc->rosdc.CombinedClip,
+                                  (CLIPOBJ *)&dc->co,
                                   &dc->eboLine.BrushObject,
                                   DestRect.left, DestRect.top, DestRect.right, DestRect.top,
                                   &DestRect, // Bounding rectangle
                                   Mix);
 
         ret = ret && IntEngLineTo(&psurf->SurfObj,
-                                  dc->rosdc.CombinedClip,
+                                  (CLIPOBJ *)&dc->co,
                                   &dc->eboLine.BrushObject,
                                   DestRect.right, DestRect.top, DestRect.right, DestRect.bottom,
                                   &DestRect, // Bounding rectangle
                                   Mix);
 
         ret = ret && IntEngLineTo(&psurf->SurfObj,
-                                  dc->rosdc.CombinedClip,
+                                  (CLIPOBJ *)&dc->co,
                                   &dc->eboLine.BrushObject,
                                   DestRect.right, DestRect.bottom, DestRect.left, DestRect.bottom,
                                   &DestRect, // Bounding rectangle
                                   Mix);
 
         ret = ret && IntEngLineTo(&psurf->SurfObj,
-                                  dc->rosdc.CombinedClip,
+                                  (CLIPOBJ *)&dc->co,
                                   &dc->eboLine.BrushObject,
                                   DestRect.left, DestRect.bottom, DestRect.left, DestRect.top,
                                   &DestRect, // Bounding rectangle
@@ -655,12 +684,6 @@ NtGdiRectangle(HDC  hDC,
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
-    if (dc->dctype == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(dc);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
 
     /* Do we rotate or shear? */
     if (!(dc->pdcattr->mxWorldToDevice.flAccel & XFORM_SCALE))
@@ -740,7 +763,7 @@ IntRoundRect(
         return FALSE;
     }
 
-    PenOrigWidth = PenWidth = pbrLine->ptPenWidth.x;
+    PenOrigWidth = PenWidth = pbrLine->lWidth;
     if (pbrLine->ulPenStyle == PS_NULL) PenWidth = 0;
 
     if (pbrLine->ulPenStyle == PS_INSIDEFRAME)
@@ -754,7 +777,7 @@ IntRoundRect(
     }
 
     if (!PenWidth) PenWidth = 1;
-    pbrLine->ptPenWidth.x = PenWidth;
+    pbrLine->lWidth = PenWidth;
 
     RectBounds.left = Left;
     RectBounds.top = Top;
@@ -777,6 +800,9 @@ IntRoundRect(
     }
     else
     {
+
+        DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
+
         RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp));
         brushTemp.ptOrigin.x += RectBounds.left - Left;
         brushTemp.ptOrigin.y += RectBounds.top - Top;
@@ -789,19 +815,24 @@ IntRoundRect(
                                 yCurveDiameter,
                                 &brushTemp);
         BRUSH_ShareUnlockBrush(pbrFill);
+
+        if (ret)
+        {
+           ret = IntDrawRoundRect( dc,
+                      RectBounds.left,
+                       RectBounds.top,
+                     RectBounds.right,
+                    RectBounds.bottom,
+                       xCurveDiameter,
+                       yCurveDiameter,
+                       pbrLine);
+        }
+
+        DC_vFinishBlit(dc, NULL);
     }
 
-    if (ret)
-       ret = IntDrawRoundRect( dc,
-                  RectBounds.left,
-                   RectBounds.top,
-                 RectBounds.right,
-                RectBounds.bottom,
-                   xCurveDiameter,
-                   yCurveDiameter,
-                   pbrLine);
-
-    pbrLine->ptPenWidth.x = PenOrigWidth;
+
+    pbrLine->lWidth = PenOrigWidth;
     PEN_ShareUnlockPen(pbrLine);
     return ret;
 }
@@ -826,12 +857,6 @@ NtGdiRoundRect(
         DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
         EngSetLastError(ERROR_INVALID_HANDLE);
     }
-    else if (dc->dctype == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(dc);
-        /* Yes, Windows really returns TRUE in this case */
-        ret = TRUE;
-    }
     else
     {
         ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
@@ -896,15 +921,7 @@ GreGradientFill(
         return FALSE;
     }
 
-    if(pdc->dctype == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(pdc);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
-
-    psurf = pdc->dclevel.pSurface;
-    if(!psurf)
+    if (!pdc->dclevel.pSurface)
     {
         /* Memory DC with no surface selected */
         DC_UnlockDc(pdc);
@@ -928,20 +945,31 @@ GreGradientFill(
     rclExtent.top    += pdc->ptlDCOrig.y;
     rclExtent.bottom += pdc->ptlDCOrig.y;
 
+    if (RECTL_bIsEmptyRect(&rclExtent))
+    {
+        DC_UnlockDc(pdc);
+        return TRUE;
+    }
+
     ptlDitherOrg.x = ptlDitherOrg.y = 0;
     IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
 
     ptlDitherOrg.x += pdc->ptlDCOrig.x;
     ptlDitherOrg.y += pdc->ptlDCOrig.y;
 
-    EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
+   if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
+   {
+      IntUpdateBoundsRect(pdc, &rclExtent);
+   }
 
-    ASSERT(pdc->rosdc.CombinedClip);
+    DC_vPrepareDCsForBlit(pdc, &rclExtent, NULL, NULL);
 
-    DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
+    psurf = pdc->dclevel.pSurface;
+
+    EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
 
     bRet = IntEngGradientFill(&psurf->SurfObj,
-                             pdc->rosdc.CombinedClip,
+                             (CLIPOBJ *)&pdc->co,
                              &exlo.xlo,
                              pVertex,
                              nVertex,
@@ -1044,13 +1072,16 @@ NtGdiExtFloodFill(
     UINT  FillType)
 {
     PDC dc;
+#if 0
     PDC_ATTR   pdcattr;
-    SURFACE    *psurf = NULL;
+#endif
+    SURFACE    *psurf;
     EXLATEOBJ  exlo;
     BOOL       Ret = FALSE;
     RECTL      DestRect;
     POINTL     Pt;
     ULONG      ConvColor;
+    PREGION    prgn;
 
     dc = DC_LockDc(hDC);
     if (!dc)
@@ -1058,36 +1089,45 @@ NtGdiExtFloodFill(
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
-    if (dc->dctype == DC_TYPE_INFO)
+
+    if (!dc->dclevel.pSurface)
     {
-        DC_UnlockDc(dc);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
+        Ret = TRUE;
+        goto cleanup;
     }
 
+#if 0
     pdcattr = dc->pdcattr;
-
-    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
-        DC_vUpdateFillBrush(dc);
-
-    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
-        DC_vUpdateLineBrush(dc);
+#endif
 
     Pt.x = XStart;
     Pt.y = YStart;
     IntLPtoDP(dc, (LPPOINT)&Pt, 1);
 
-    Ret = NtGdiPtInRegion(dc->rosdc.hGCClipRgn, Pt.x, Pt.y);
-    if (Ret)
-        IntGdiGetRgnBox(dc->rosdc.hGCClipRgn,(LPRECT)&DestRect);
-    else
-        goto cleanup;
+    DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
     psurf = dc->dclevel.pSurface;
-    if (!psurf)
+
+    prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+    if (prgn)
     {
-        Ret = FALSE;
-        goto cleanup;
+        Ret = REGION_PtInRegion(prgn, Pt.x, Pt.y);
+        if (Ret)
+            REGION_GetRgnBox(prgn, (LPRECT)&DestRect);
+        else
+        {
+            DC_vFinishBlit(dc, NULL);
+            goto cleanup;
+        }
+    }
+    else
+    {
+        RECTL_vSetRect(&DestRect, 0, 0, psurf->SurfObj.sizlBitmap.cx, psurf->SurfObj.sizlBitmap.cy);
+    }
+
+    if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
+    {
+       IntUpdateBoundsRect(dc, &DestRect);
     }
 
     EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
@@ -1099,6 +1139,8 @@ NtGdiExtFloodFill(
     ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
     Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
 
+    DC_vFinishBlit(dc, NULL);
+
     EXLATEOBJ_vCleanup(&exlo);
 
 cleanup: