[ros-diffs] [gschneider] 42323: FloodFill: -Get rid of global variables for flood control -Translate the provided color to the surface, not the other way around (improves speed) -Rename the function to reflect the functionality -Add comments on how to implement support for hatched brushes and non-standard surfaces -Thanks to tkreuzer for feedback

gschneider at svn.reactos.org gschneider at svn.reactos.org
Sat Aug 1 16:39:41 CEST 2009


Author: gschneider
Date: Sat Aug  1 16:39:40 2009
New Revision: 42323

URL: http://svn.reactos.org/svn/reactos?rev=42323&view=rev
Log:
FloodFill:
-Get rid of global variables for flood control
-Translate the provided color to the surface, not the other way around (improves speed)
-Rename the function to reflect the functionality
-Add comments on how to implement support for hatched brushes and non-standard surfaces
-Thanks to tkreuzer for feedback

Modified:
    trunk/reactos/subsystems/win32/win32k/dib/dib.h
    trunk/reactos/subsystems/win32/win32k/dib/floodfill.c
    trunk/reactos/subsystems/win32/win32k/objects/fillshap.c

Modified: trunk/reactos/subsystems/win32/win32k/dib/dib.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib/dib.h?rev=42323&r1=42322&r2=42323&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/dib/dib.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/dib/dib.h [iso-8859-1] Sat Aug  1 16:39:40 2009
@@ -133,7 +133,7 @@
 BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
-BOOLEAN DIB_XXBPP_FloodFill(SURFOBJ*, BRUSHOBJ*, RECTL*, POINTL*, XLATEOBJ*, COLORREF, UINT);
+BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ*, BRUSHOBJ*, RECTL*, POINTL*, ULONG, UINT);
 
 extern unsigned char notmask[2];
 extern unsigned char altnotmask[2];

Modified: trunk/reactos/subsystems/win32/win32k/dib/floodfill.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib/floodfill.c?rev=42323&r1=42322&r2=42323&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/dib/floodfill.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/dib/floodfill.c [iso-8859-1] Sat Aug  1 16:39:40 2009
@@ -27,76 +27,72 @@
     ULONG y;
 } FLOODITEM;
 
-static ULONG floodLen = 0;
-static FLOODITEM *floodStart = NULL, *floodData = NULL;
+typedef struct _floodInfo
+{
+    ULONG floodLen;
+    FLOODITEM *floodStart;
+    FLOODITEM *floodData;
+} FLOODINFO;
 
-static __inline BOOL initFlood(RECTL *DstRect)
+static __inline BOOL initFlood(FLOODINFO *info, RECTL *DstRect)
 {
     ULONG width = DstRect->right - DstRect->left;
     ULONG height = DstRect->bottom - DstRect->top;
-    floodData = ExAllocatePoolWithTag(NonPagedPool, width * height * sizeof(FLOODITEM), TAG_DIB); 
-    if (floodData == NULL)
+    info->floodData = ExAllocatePoolWithTag(NonPagedPool, width * height * sizeof(FLOODITEM), TAG_DIB); 
+    if (info->floodData == NULL)
     {
         return FALSE;
     }
-    floodStart = (FLOODITEM*)((PBYTE)floodData + (width * height * sizeof(FLOODITEM)));
+    info->floodStart = (FLOODITEM*)((PBYTE)info->floodData + (width * height * sizeof(FLOODITEM)));
     return TRUE;
 }
-static __inline VOID finalizeFlood()
+static __inline VOID finalizeFlood(FLOODINFO *info)
 {
-    ExFreePoolWithTag(floodData, TAG_DIB);
+    ExFreePoolWithTag(info->floodData, TAG_DIB);
 }
-static __inline VOID addItemFlood(ULONG x, 
+static __inline VOID addItemFlood(FLOODINFO *info,
+                                  ULONG x, 
                                   ULONG y, 
                                   SURFOBJ *DstSurf, 
                                   RECTL *DstRect, 
-                                  XLATEOBJ* ColorTranslation, 
-                                  COLORREF Color, 
+                                  ULONG Color, 
                                   BOOL isSurf)
 {
     if (x >= DstRect->left && x <= DstRect->right &&
         y >= DstRect->top && y <= DstRect->bottom)
     {
-        if (isSurf == TRUE && XLATEOBJ_iXlate(ColorTranslation, 
-            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y)) != Color)
+        if (isSurf == TRUE && 
+            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) != Color)
         {
             return;
         }
-        else if (isSurf == FALSE && XLATEOBJ_iXlate(ColorTranslation, 
-            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y)) == Color)
+        else if (isSurf == FALSE &&
+            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) == Color)
         {
             return;
         }
-        floodStart--;
-        floodStart->x = x;
-        floodStart->y = y;
-        floodLen++;
+        info->floodStart--;
+        info->floodStart->x = x;
+        info->floodStart->y = y;
+        info->floodLen++;
     }
 }
-static __inline VOID removeItemFlood()
+static __inline VOID removeItemFlood(FLOODINFO *info)
 {
-    floodStart++;
-    floodLen--;
-}
-static __inline BOOL isEmptyFlood()
-{
-    if (floodLen == 0)
-    {
-        return TRUE;
-    }
-    return FALSE;
+    info->floodStart++;
+    info->floodLen--;
 }
 
-BOOLEAN DIB_XXBPP_FloodFill(SURFOBJ *DstSurf, 
-                            BRUSHOBJ *Brush, 
-                            RECTL *DstRect, 
-                            POINTL *Origin,
-                            XLATEOBJ *ColorTranslation,
-                            COLORREF Color, 
-                            UINT FillType)
+BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ *DstSurf, 
+                                 BRUSHOBJ *Brush, 
+                                 RECTL *DstRect, 
+                                 POINTL *Origin,
+                                 ULONG ConvColor, 
+                                 UINT FillType)
 {
     ULONG x, y;
     ULONG BrushColor;
+    FLOODINFO flood = {0, NULL, NULL};
 
     BrushColor = Brush->iSolidColor;
     x = Origin->x;
@@ -105,59 +101,66 @@
     if (FillType == FLOODFILLBORDER)
     {
         /* Check if the start pixel has the border color */
-        if (XLATEOBJ_iXlate(ColorTranslation, 
-            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y)) == Color)
+        if (DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) == ConvColor)
         {
             return FALSE;
         }
 
-        if (initFlood(DstRect) == FALSE)
+        if (initFlood(&flood, DstRect) == FALSE)
         {
             return FALSE;
         }
-        addItemFlood(x, y, DstSurf, DstRect, ColorTranslation, Color, FALSE);
-        while (!isEmptyFlood()) 
+        addItemFlood(&flood, x, y, DstSurf, DstRect, ConvColor, FALSE);
+        while (flood.floodLen != 0) 
         {
-            x = floodStart->x;
-            y = floodStart->y;
-            removeItemFlood();
+            x = flood.floodStart->x;
+            y = flood.floodStart->y;
+            removeItemFlood(&flood);
 
             DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_PutPixel(DstSurf, x, y, BrushColor);
-            addItemFlood(x, y + 1, DstSurf, DstRect, ColorTranslation, Color, FALSE);
-            addItemFlood(x, y - 1, DstSurf, DstRect, ColorTranslation, Color, FALSE);
-            addItemFlood(x + 1, y, DstSurf, DstRect, ColorTranslation, Color, FALSE);
-            addItemFlood(x - 1, y, DstSurf, DstRect, ColorTranslation, Color, FALSE);
+            addItemFlood(&flood, x, y + 1, DstSurf, DstRect, ConvColor, FALSE);
+            addItemFlood(&flood, x, y - 1, DstSurf, DstRect, ConvColor, FALSE);
+            addItemFlood(&flood, x + 1, y, DstSurf, DstRect, ConvColor, FALSE);
+            addItemFlood(&flood, x - 1, y, DstSurf, DstRect, ConvColor, FALSE);
+            if (flood.floodStart <= flood.floodData)
+            {   
+                DPRINT1("Couldn't finish flooding!\n");
+                return FALSE;
+            }
         }
-        finalizeFlood();
+        finalizeFlood(&flood);
     }
     else if (FillType == FLOODFILLSURFACE)
     {
         /* Check if the start pixel has the surface color */
-        if (XLATEOBJ_iXlate(ColorTranslation, 
-            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y)) != Color)
+        if (DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) != ConvColor)
         {
             return FALSE;
         }
 
-        if (initFlood(DstRect) == FALSE)
+        if (initFlood(&flood, DstRect) == FALSE)
         {
             return FALSE;
         }
-        addItemFlood(x, y, DstSurf, DstRect, ColorTranslation, Color, TRUE);
-        while (!isEmptyFlood()) 
+        addItemFlood(&flood, x, y, DstSurf, DstRect, ConvColor, TRUE);
+        while (flood.floodLen != 0) 
         {
-            x = floodStart->x;
-            y = floodStart->y;
-            removeItemFlood();
+            x = flood.floodStart->x;
+            y = flood.floodStart->y;
+            removeItemFlood(&flood);
 
             DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_PutPixel(DstSurf, x, y, BrushColor);
-            addItemFlood(x, y + 1, DstSurf, DstRect, ColorTranslation, Color, TRUE);
-            addItemFlood(x, y - 1, DstSurf, DstRect, ColorTranslation, Color, TRUE);
-            addItemFlood(x + 1, y, DstSurf, DstRect, ColorTranslation, Color, TRUE);
-            addItemFlood(x - 1, y, DstSurf, DstRect, ColorTranslation, Color, TRUE);
-
+            addItemFlood(&flood, x, y + 1, DstSurf, DstRect, ConvColor, TRUE);
+            addItemFlood(&flood, x, y - 1, DstSurf, DstRect, ConvColor, TRUE);
+            addItemFlood(&flood, x + 1, y, DstSurf, DstRect, ConvColor, TRUE);
+            addItemFlood(&flood, x - 1, y, DstSurf, DstRect, ConvColor, TRUE);
+            if (flood.floodStart <= flood.floodData)
+            {   
+                DPRINT1("Couldn't finish flooding!\n");
+                return FALSE;
+            }
         }
-        finalizeFlood();
+        finalizeFlood(&flood);
     }
     else
     {

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=42323&r1=42322&r2=42323&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] Sat Aug  1 16:39:40 2009
@@ -1070,13 +1070,14 @@
     UINT  FillType)
 {
     PDC dc;
-    PDC_ATTR pdcattr;
-    SURFACE *psurf = NULL;
-    HPALETTE Pal = 0;
-    XLATEOBJ *XlateObj = NULL;
+    PDC_ATTR   pdcattr;
+    SURFACE    *psurf = NULL;
+    HPALETTE   Pal = 0;
+    XLATEOBJ   *XlateObj = NULL;
     BOOL       Ret = FALSE;
     RECTL      DestRect;
     POINTL     Pt;
+    ULONG      ConvColor;
 
     dc = DC_LockDc(hDC);
     if (!dc)
@@ -1118,11 +1119,16 @@
 
     Pal = dc->dclevel.pSurface->hDIBPalette;
     if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault;
-    XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal);
-
+    XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, PAL_RGB, Pal, NULL);
+
+    /* Only solid fills supported for now
+     * How to support pattern brushes and non standard surfaces (not offering dib functions):
+     * Version a (most likely slow): call DrvPatBlt for every pixel
+     * Version b: create a flood mask and let MaskBlt blit a masked brush */
     if (XlateObj != NULL)
     {
-        Ret = DIB_XXBPP_FloodFill(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, XlateObj, Color, FillType);
+        ConvColor = XLATEOBJ_iXlate(XlateObj, Color);
+        Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
         EngDeleteXlate(XlateObj);
     }
 




More information about the Ros-diffs mailing list