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/di…
==============================================================================
--- 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/di…
==============================================================================
--- 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/ob…
==============================================================================
--- 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);
}