[ros-dev] [ros-diffs] [gschneider] 42311: - Implement Floodfill: iterative four neighbors version - Details for this algorithm are described in the comments - Nice with the paint clone since the bucket fill tool works now

Timo Kreuzer timo.kreuzer at web.de
Sat Aug 1 01:34:45 CEST 2009


and

3.) How do you expect this to work with anything else then standard
format surfaces?


Timo Kreuzer schrieb:
> 1.) Why are you using global variables?
> 2.) Why are you using an XLATEOBJ inside the fill loop?
>
>
> gschneider at svn.reactos.org schrieb:
>   
>> Author: gschneider
>> Date: Fri Jul 31 17:41:09 2009
>> New Revision: 42311
>>
>> URL: http://svn.reactos.org/svn/reactos?rev=42311&view=rev
>> Log:
>> - Implement Floodfill: iterative four neighbors version
>> - Details for this algorithm are described in the comments
>> - Nice with the paint clone since the bucket fill tool works now
>>
>> Added:
>>     trunk/reactos/subsystems/win32/win32k/dib/floodfill.c   (with props)
>> Modified:
>>     trunk/reactos/subsystems/win32/win32k/dib/dib.h
>>     trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
>>     trunk/reactos/subsystems/win32/win32k/win32k.rbuild
>>
>> 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=42311&r1=42310&r2=42311&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] Fri Jul 31 17:41:09 2009
>> @@ -133,6 +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);
>>  
>>  extern unsigned char notmask[2];
>>  extern unsigned char altnotmask[2];
>>
>> Added: trunk/reactos/subsystems/win32/win32k/dib/floodfill.c
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib/floodfill.c?rev=42311&view=auto
>> ==============================================================================
>> --- trunk/reactos/subsystems/win32/win32k/dib/floodfill.c (added)
>> +++ trunk/reactos/subsystems/win32/win32k/dib/floodfill.c [iso-8859-1] Fri Jul 31 17:41:09 2009
>> @@ -1,0 +1,168 @@
>> +/* 
>> + * COPYRIGHT:         See COPYING in the top level directory
>> + * PROJECT:           ReactOS win32 subsystem
>> + * PURPOSE:           Flood filling support
>> + * FILE:              subsystems/win32/win32k/dib/floodfill.c
>> + * PROGRAMMER:        Gregor Schneider, <grschneider AT gmail DOT com>
>> + */
>> +
>> +#include <w32k.h>
>> +
>> +#define NDEBUG
>> +#include <debug.h>
>> +
>> +/*
>> +*  This floodfill algorithm is an iterative four neighbors version. It works with an internal stack like data structure.
>> +*  The stack is kept in an array, sized for the worst case scenario of having to add all pixels of the surface.
>> +*  This avoids having to allocate and free memory blocks  all the time. The stack grows from the end of the array towards the start.
>> +*  All pixels are checked before being added, against belonging to the fill rule (FLOODFILLBORDER or FLOODFILLSURFACE) 
>> +*  and the position in respect to the clip region. This guarantees all pixels lying on the stack belong to the filled surface.
>> +*  Further optimisations of the algorithm are possible.
>> +*/
>> +
>> +/* Floodfil helper structures and functions */
>> +typedef struct _floodItem
>> +{
>> +    ULONG x;
>> +    ULONG y;
>> +} FLOODITEM;
>> +
>> +static ULONG floodLen = 0;
>> +static FLOODITEM *floodStart = NULL, *floodData = NULL;
>> +
>> +static __inline BOOL initFlood(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)
>> +    {
>> +        return FALSE;
>> +    }
>> +    floodStart = (FLOODITEM*)((PBYTE)floodData + (width * height * sizeof(FLOODITEM)));
>> +    return TRUE;
>> +}
>> +static __inline VOID finalizeFlood()
>> +{
>> +    ExFreePoolWithTag(floodData, TAG_DIB);
>> +}
>> +static __inline VOID addItemFlood(ULONG x, 
>> +                                  ULONG y, 
>> +                                  SURFOBJ *DstSurf, 
>> +                                  RECTL *DstRect, 
>> +                                  XLATEOBJ* ColorTranslation, 
>> +                                  COLORREF 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)
>> +        {
>> +            return;
>> +        }
>> +        else if (isSurf == FALSE && XLATEOBJ_iXlate(ColorTranslation, 
>> +            DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y)) == Color)
>> +        {
>> +            return;
>> +        }
>> +        floodStart--;
>> +        floodStart->x = x;
>> +        floodStart->y = y;
>> +        floodLen++;
>> +    }
>> +}
>> +static __inline VOID removeItemFlood()
>> +{
>> +    floodStart++;
>> +    floodLen--;
>> +}
>> +static __inline BOOL isEmptyFlood()
>> +{
>> +    if (floodLen == 0)
>> +    {
>> +        return TRUE;
>> +    }
>> +    return FALSE;
>> +}
>> +
>> +BOOLEAN DIB_XXBPP_FloodFill(SURFOBJ *DstSurf, 
>> +                            BRUSHOBJ *Brush, 
>> +                            RECTL *DstRect, 
>> +                            POINTL *Origin,
>> +                            XLATEOBJ *ColorTranslation,
>> +                            COLORREF Color, 
>> +                            UINT FillType)
>> +{
>> +    ULONG x, y;
>> +    ULONG BrushColor;
>> +
>> +    BrushColor = Brush->iSolidColor;
>> +    x = Origin->x;
>> +    y = Origin->y;
>> +
>> +    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)
>> +        {
>> +            return FALSE;
>> +        }
>> +
>> +        if (initFlood(DstRect) == FALSE)
>> +        {
>> +            return FALSE;
>> +        }
>> +        addItemFlood(x, y, DstSurf, DstRect, ColorTranslation, Color, FALSE);
>> +        while (!isEmptyFlood()) 
>> +        {
>> +            x = floodStart->x;
>> +            y = floodStart->y;
>> +            removeItemFlood();
>> +
>> +            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);
>> +        }
>> +        finalizeFlood();
>> +    }
>> +    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)
>> +        {
>> +            return FALSE;
>> +        }
>> +
>> +        if (initFlood(DstRect) == FALSE)
>> +        {
>> +            return FALSE;
>> +        }
>> +        addItemFlood(x, y, DstSurf, DstRect, ColorTranslation, Color, TRUE);
>> +        while (!isEmptyFlood()) 
>> +        {
>> +            x = floodStart->x;
>> +            y = floodStart->y;
>> +            removeItemFlood();
>> +
>> +            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);
>> +
>> +        }
>> +        finalizeFlood();
>> +    }
>> +    else
>> +    {
>> +        DPRINT1("Unsupported FloodFill type!\n");
>> +        return FALSE;
>> +    }
>> +    return TRUE;
>> +}
>>
>> Propchange: trunk/reactos/subsystems/win32/win32k/dib/floodfill.c
>> ------------------------------------------------------------------------------
>>     svn:eol-style = native
>>
>> 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=42311&r1=42310&r2=42311&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] Fri Jul 31 17:41:09 2009
>> @@ -1072,12 +1072,11 @@
>>      PDC dc;
>>      PDC_ATTR pdcattr;
>>      SURFACE *psurf = NULL;
>> -    PBRUSH pbrFill = NULL;
>> +    HPALETTE Pal = 0;
>> +    XLATEOBJ *XlateObj = NULL;
>>      BOOL       Ret = FALSE;
>>      RECTL      DestRect;
>>      POINTL     Pt;
>> -
>> -    DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
>>  
>>      dc = DC_LockDc(hDC);
>>      if (!dc)
>> @@ -1110,17 +1109,21 @@
>>      else
>>          goto cleanup;
>>  
>> -    pbrFill = dc->dclevel.pbrFill;
>> -    if (!pbrFill)
>> +    psurf = dc->dclevel.pSurface;
>> +    if (!psurf)
>>      {
>>          Ret = FALSE;
>>          goto cleanup;
>>      }
>> -    psurf = dc->dclevel.pSurface;
>> -    if (!psurf)
>> -    {
>> -        Ret = FALSE;
>> -        goto cleanup;
>> +
>> +    Pal = dc->dclevel.pSurface->hDIBPalette;
>> +    if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault;
>> +    XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal);
>> +
>> +    if (XlateObj != NULL)
>> +    {
>> +        Ret = DIB_XXBPP_FloodFill(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, XlateObj, Color, FillType);
>> +        EngDeleteXlate(XlateObj);
>>      }
>>  
>>  cleanup:
>>
>> Modified: trunk/reactos/subsystems/win32/win32k/win32k.rbuild
>> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/win32k.rbuild?rev=42311&r1=42310&r2=42311&view=diff
>> ==============================================================================
>> --- trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] (original)
>> +++ trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] Fri Jul 31 17:41:09 2009
>> @@ -31,6 +31,7 @@
>>  		<file>dib32bpp.c</file>
>>  		<file>dibXXbpp.c</file>
>>  		<file>dib.c</file>
>> +		<file>floodfill.c</file>
>>  
>>  		<if property="ARCH" value="i386">
>>  			<directory name="i386">
>>
>>
>>
>>   
>>     
>
>
> _______________________________________________
> Ros-dev mailing list
> Ros-dev at reactos.org
> http://www.reactos.org/mailman/listinfo/ros-dev
>
>   

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-dev/attachments/20090801/255c5d35/attachment.htm 


More information about the Ros-dev mailing list