[ros-diffs] [jimtabor] 40051: - Patch by Evgeniy Boltik: Fix Rectangle, Ellipse, RoundRect and Polygon.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Mon Mar 16 04:21:00 CET 2009


Author: jimtabor
Date: Mon Mar 16 06:21:00 2009
New Revision: 40051

URL: http://svn.reactos.org/svn/reactos?rev=40051&view=rev
Log:
- Patch by Evgeniy Boltik: Fix Rectangle, Ellipse, RoundRect and Polygon.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/paint.h
    trunk/reactos/subsystems/win32/win32k/objects/drawing.c
    trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
    trunk/reactos/subsystems/win32/win32k/objects/polyfill.c

Modified: trunk/reactos/subsystems/win32/win32k/include/paint.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/paint.h?rev=40051&r1=40050&r2=40051&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/paint.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/paint.h [iso-8859-1] Mon Mar 16 06:21:00 2009
@@ -3,5 +3,7 @@
 
 BOOL APIENTRY FillSolid (SURFOBJ* Surface, RECTL* Dimensions, ULONG iColor);
 BOOL APIENTRY FillPolygon ( DC* dc, SURFACE* pSurface, BRUSHOBJ* BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect );
+BOOL FASTCALL IntFillPolygon(PDC dc, SURFACE *psurf, BRUSHOBJ *BrushObj,
+    CONST PPOINT Points, int Count, RECTL DestRect, POINTL *BrushOrigin);
 
 #endif /* _WIN32K_PAINT_H */

Modified: trunk/reactos/subsystems/win32/win32k/objects/drawing.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/drawing.c?rev=40051&r1=40050&r2=40051&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] Mon Mar 16 06:21:00 2009
@@ -1337,26 +1337,10 @@
                 INT XLeft,
                 INT YLeft,
                 INT Width,
-                INT Height)
-{
-  BOOL ret;
-  PDC_ATTR Dc_Attr;
-  PGDIBRUSHOBJ FillBrushObj;
-
-  Dc_Attr = dc->pDc_Attr;
-  if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
-  FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
-  if (NULL == FillBrushObj)   
-  {
-      DPRINT1("FillEllipse Fail\n");
-      SetLastWin32Error(ERROR_INTERNAL_ERROR);
-      return FALSE;
-  }
-  ret = (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), FillBrushObj);
-
-  BRUSHOBJ_UnlockBrush(FillBrushObj);    
-  return ret;
+                INT Height, 
+                PGDIBRUSHOBJ FillBrushObj)
+{
+  return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), FillBrushObj);
 }
 
 BOOL
@@ -1367,23 +1351,12 @@
                   INT Right,
                   INT Bottom,
                   INT Wellipse,
-                  INT Hellipse)
-{
-  PDC_ATTR Dc_Attr;
-  PGDIBRUSHOBJ FillBrushObj;
+                  INT Hellipse, 
+                  PGDIBRUSHOBJ FillBrushObj)
+{
   Rect r;
   int rx, ry; /* radius in x and y directions */
 
-  Dc_Attr = dc->pDc_Attr;
-  if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
-  FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
-  if (NULL == FillBrushObj)   
-  {
-      DPRINT1("FillEllipse Fail\n");
-      SetLastWin32Error(ERROR_INTERNAL_ERROR);
-      return FALSE;
-  }
   //           x    y          Width          Height
   r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
   rx = Wellipse/2;
@@ -1432,7 +1405,6 @@
      app_fill_rect(dc, rect(r.x, r.y+ry+1, r.width, r.height-ry-ry), FillBrushObj, FALSE);
   }
 
-  BRUSHOBJ_UnlockBrush(FillBrushObj);    
   return TRUE;
 }
 

Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/fillshap.c?rev=40051&r1=40050&r2=40051&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Mon Mar 16 06:21:00 2009
@@ -44,9 +44,9 @@
 #define Rsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
 #define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
 
-BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height);
+BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, PGDIBRUSHOBJ FillBrushObj);
 BOOL FASTCALL IntDrawEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, PGDIBRUSHOBJ PenBrushObj);
-BOOL FASTCALL IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse);
+BOOL FASTCALL IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse, PGDIBRUSHOBJ FillBrushObj);
 BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse, PGDIBRUSHOBJ PenBrushObj);
 
 BOOL FASTCALL
@@ -61,7 +61,10 @@
     RECTL DestRect;
     int CurrentPoint;
     PDC_ATTR Dc_Attr;
-
+    POINTL BrushOrigin;
+//    int Left;
+//    int Top;
+    
     ASSERT(dc); // caller's responsibility to pass a valid dc
 
     if (!Points || Count < 2 )
@@ -69,6 +72,16 @@
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
+
+/*
+    //Find start x, y
+    Left = Points[0].x;
+    Top  = Points[0].y;
+    for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) {
+      Left = min(Left, Points[CurrentPoint].x);
+      Top  = min(Top, Points[CurrentPoint].y);
+    }
+*/
 
     Dc_Attr = dc->pDc_Attr;
     if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
@@ -111,8 +124,12 @@
         /* Now fill the polygon with the current brush. */
         if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
         {
+            BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+            BrushOrigin.x += dc->ptlDCOrig.x;
+            BrushOrigin.y += dc->ptlDCOrig.y;
             IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
-            ret = FillPolygon ( dc, psurf, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), Points, Count, DestRect );
+            ret = IntFillPolygon (dc, psurf, &FillBrushInst.BrushObject, Points, Count, 
+                  DestRect, &BrushOrigin);
         }
         if (FillBrushObj)
             BRUSHOBJ_UnlockBrush(FillBrushObj);
@@ -213,6 +230,8 @@
     BOOL ret = TRUE;
     LONG PenWidth, PenOrigWidth;
     LONG RadiusX, RadiusY, CenterX, CenterY;
+    PGDIBRUSHOBJ pFillBrushObj;
+    GDIBRUSHOBJ tmpFillBrushObj;
 
     if ((Left == Right) || (Top == Bottom)) return TRUE;
 
@@ -303,11 +322,29 @@
     DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n",
                CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
 
-    ret = IntFillEllipse( dc,
-                          CenterX - RadiusX,
-                          CenterY - RadiusY,
-                          RadiusX*2, // Width
-                          RadiusY*2); // Height
+    pFillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+    if (NULL == pFillBrushObj)   
+    {
+        DPRINT1("FillEllipse Fail\n");
+        SetLastWin32Error(ERROR_INTERNAL_ERROR);
+        ret = FALSE;
+    }
+    else
+    {
+        RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj));
+//        tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left;
+//        tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
+        tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
+        tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;
+        ret = IntFillEllipse( dc,
+                              CenterX - RadiusX,
+                              CenterY - RadiusY,
+                              RadiusX*2, // Width
+                              RadiusY*2, // Height
+                              &tmpFillBrushObj);
+        BRUSHOBJ_UnlockBrush(pFillBrushObj);
+    }
+
     if (ret)
        ret = IntDrawEllipse( dc,
                              CenterX - RadiusX,
@@ -512,6 +549,7 @@
     RECTL      DestRect;
     MIX        Mix;
     PDC_ATTR Dc_Attr;
+    POINTL BrushOrigin;
 
     ASSERT ( dc ); // caller's responsibility to set this up
 
@@ -581,6 +619,9 @@
     {
         if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
         {
+            BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+            BrushOrigin.x += dc->ptlDCOrig.x;
+            BrushOrigin.y += dc->ptlDCOrig.y;
             IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
             ret = IntEngBitBlt(&psurf->SurfObj,
                                NULL,
@@ -591,7 +632,7 @@
                                NULL,
                                NULL,
                                &FillBrushInst.BrushObject,
-                               NULL,
+                               &BrushOrigin,
                                ROP3_TO_ROP4(PATCOPY));
         }
     }
@@ -697,6 +738,8 @@
     RECTL RectBounds;
     LONG PenWidth, PenOrigWidth;
     BOOL ret = TRUE; // default to success
+    PGDIBRUSHOBJ pFillBrushObj;
+    GDIBRUSHOBJ tmpFillBrushObj;
 
     ASSERT ( dc ); // caller's responsibility to set this up
 
@@ -763,13 +806,29 @@
     RectBounds.right  += dc->ptlDCOrig.x;
     RectBounds.bottom += dc->ptlDCOrig.y;
 
-    ret = IntFillRoundRect( dc,
-               RectBounds.left,
-                RectBounds.top,
-              RectBounds.right,
-             RectBounds.bottom,
-                xCurveDiameter,
-                yCurveDiameter);
+    pFillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+    if (NULL == pFillBrushObj)   
+    {
+        DPRINT1("FillRound Fail\n");
+        SetLastWin32Error(ERROR_INTERNAL_ERROR);
+        ret = FALSE;
+    } 
+    else
+    {
+        RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj));
+        tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left;
+        tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
+        ret = IntFillRoundRect( dc,
+                                RectBounds.left,
+                                RectBounds.top,
+                                RectBounds.right,
+                                RectBounds.bottom,
+                                xCurveDiameter,
+                                yCurveDiameter,
+                                &tmpFillBrushObj);
+        BRUSHOBJ_UnlockBrush(pFillBrushObj);
+    }
+
     if (ret)
        ret = IntDrawRoundRect( dc,
                   RectBounds.left,
@@ -1048,95 +1107,93 @@
     COLORREF  Color,
     UINT  FillType)
 {
-  PDC dc;
-  PDC_ATTR Dc_Attr;
-  SURFACE *psurf = NULL;
-  PGDIBRUSHOBJ FillBrushObj = NULL;
-  GDIBRUSHINST FillBrushInst;
-  BOOL       Ret = FALSE;
-  RECTL      DestRect;
-  POINTL     Pt;
-//  MIX        Mix;
-
-  DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
-
-  dc = DC_LockDc(hDC);
-  if (!dc)
-  {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
-      return FALSE;
-  }
-  if (dc->DC_Type == DC_TYPE_INFO)
-  {
-      DC_UnlockDc(dc);
-      /* Yes, Windows really returns TRUE in this case */
-      return TRUE;
-  }
-
-  Dc_Attr = dc->pDc_Attr;
-  if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
-  if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY)
-     IntGdiSelectPen(dc,Dc_Attr->hpen);
-
-  if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY)
-     IntGdiSelectBrush(dc,Dc_Attr->hbrush);
-
-  Pt.x = XStart;
-  Pt.y = YStart;
-  IntLPtoDP(dc, (LPPOINT)&Pt, 1);
-
-  Ret = NtGdiPtInRegion(dc->w.hGCClipRgn, Pt.x, Pt.y);
-  if (Ret)
-     IntGdiGetRgnBox(dc->w.hGCClipRgn,(LPRECT)&DestRect);
-  else
-     goto cleanup;
-
-  FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
-  if (!FillBrushObj)
-  {
-      Ret = FALSE;
-      goto cleanup;
-  }
-  psurf = SURFACE_LockSurface(dc->w.hBitmap);
-  if (!psurf)
-  {
-      Ret = FALSE;
-      goto cleanup;
-  }
-
-  if ( FillBrushObj && (FillType == FLOODFILLBORDER))
-  {
-     if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
-     {
-        FillBrushObj->BrushAttr.lbColor = Color;
-        IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
-        Ret = IntEngBitBlt(&psurf->SurfObj,
-                               NULL,
-                               NULL,
-                               dc->CombinedClip,
-                               NULL,
-                               &DestRect,
-                               NULL,
-                               NULL,
+    PDC dc;
+    PDC_ATTR Dc_Attr;
+    SURFACE *psurf = NULL;
+    PGDIBRUSHOBJ FillBrushObj = NULL;
+    GDIBRUSHINST FillBrushInst;
+    BOOL       Ret = FALSE;
+    RECTL      DestRect;
+    POINTL     Pt;
+    POINTL BrushOrigin;
+
+    DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
+
+    dc = DC_LockDc(hDC);
+    if (!dc)
+    {
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+    if (dc->DC_Type == DC_TYPE_INFO)
+    {
+        DC_UnlockDc(dc);
+        /* Yes, Windows really returns TRUE in this case */
+        return TRUE;
+    }
+
+    Dc_Attr = dc->pDc_Attr;
+    if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+
+    if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY)
+        IntGdiSelectPen(dc,Dc_Attr->hpen);
+
+    if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY)
+        IntGdiSelectBrush(dc,Dc_Attr->hbrush);
+
+    Pt.x = XStart;
+    Pt.y = YStart;
+    IntLPtoDP(dc, (LPPOINT)&Pt, 1);
+
+    Ret = NtGdiPtInRegion(dc->w.hGCClipRgn, Pt.x, Pt.y);
+    if (Ret)
+        IntGdiGetRgnBox(dc->w.hGCClipRgn,(LPRECT)&DestRect);
+    else
+        goto cleanup;
+
+    FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+    if (!FillBrushObj)
+    {
+        Ret = FALSE;
+        goto cleanup;
+    }
+    psurf = SURFACE_LockSurface(dc->w.hBitmap);
+    if (!psurf)
+    {
+        Ret = FALSE;
+        goto cleanup;
+    }
+
+    if ( FillBrushObj && (FillType == FLOODFILLBORDER))
+    {
+        if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+        {
+            FillBrushObj->BrushAttr.lbColor = Color;
+            BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+            BrushOrigin.x += dc->ptlDCOrig.x;
+            BrushOrigin.y += dc->ptlDCOrig.y;
+            IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
+            Ret = IntEngBitBlt(&psurf->SurfObj, NULL, NULL,
+                               dc->CombinedClip, NULL,
+                               &DestRect, NULL, NULL,
                                &FillBrushInst.BrushObject,
-                               NULL,
+                               &BrushOrigin,
                                ROP3_TO_ROP4(PATCOPY));
-     }
-  }
-  else
-  {
-  }
+        }
+    }
+    else
+    {
+    }
 
 cleanup:
-  if (FillBrushObj)
-      BRUSHOBJ_UnlockBrush(FillBrushObj);
-
-  if (psurf)
-     SURFACE_UnlockSurface(psurf);
-
-  DC_UnlockDc(dc);
-  return Ret;
+    if (FillBrushObj)
+        BRUSHOBJ_UnlockBrush(FillBrushObj);
+
+    if (psurf)
+        SURFACE_UnlockSurface(psurf);
+
+    DC_UnlockDc(dc);
+    return Ret;
 }
 
 /* EOF */

Modified: trunk/reactos/subsystems/win32/win32k/objects/polyfill.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/polyfill.c?rev=40051&r1=40050&r2=40051&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/polyfill.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/polyfill.c [iso-8859-1] Mon Mar 16 06:21:00 2009
@@ -600,4 +600,76 @@
 
   return TRUE;
 }
+
+BOOL FASTCALL
+IntFillPolygon(
+    PDC dc,
+    SURFACE *psurf,
+    BRUSHOBJ *BrushObj,
+    CONST PPOINT Points,
+    int Count,
+    RECTL DestRect, 
+    POINTL *BrushOrigin)
+{
+    FILL_EDGE_LIST *list = 0;
+    FILL_EDGE *ActiveHead = 0;
+    FILL_EDGE *pLeft, *pRight;
+    int ScanLine;
+  
+    //DPRINT("IntFillPolygon\n");
+
+    /* Create Edge List. */
+    list = POLYGONFILL_MakeEdgeList(Points, Count);
+    /* DEBUG_PRINT_EDGELIST(list); */
+    if (NULL == list)
+        return FALSE;
+
+    /* For each Scanline from DestRect.top to DestRect.bottom, determine line segments to draw */
+    for ( ScanLine = DestRect.top; ScanLine < DestRect.bottom; ++ScanLine )
+    {
+        POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
+        //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
+
+        if ( !ActiveHead )
+          return FALSE;
+
+        pLeft = ActiveHead;
+        pRight = pLeft->pNext;
+        ASSERT(pRight);
+
+        while ( NULL != pRight )
+        {
+            int x1 = pLeft->XIntercept[0];
+            int x2 = pRight->XIntercept[1];
+            if ( x2 > x1 )
+            {
+                RECTL LineRect;
+                LineRect.top = ScanLine;
+                LineRect.bottom = ScanLine + 1;
+                LineRect.left = x1;
+                LineRect.right = x2;
+
+                IntEngBitBlt(&psurf->SurfObj,
+                                 NULL,
+                                 NULL,
+                                 dc->CombinedClip,
+                                 NULL,
+                                 &LineRect,
+                                 NULL,
+                                 NULL,
+                                 BrushObj,
+                                 BrushOrigin,
+                                 ROP3_TO_ROP4(PATCOPY));
+            }
+            pLeft = pRight->pNext;
+            pRight = pLeft ? pLeft->pNext : NULL;
+        }   
+    }
+
+    /* Free Edge List. If any are left. */
+    POLYGONFILL_DestroyEdgeList(list);
+
+    return TRUE;
+}
+
 /* EOF */



More information about the Ros-diffs mailing list