[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 00:53:44 CEST 2009
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">
>
>
>
>
More information about the Ros-dev
mailing list