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... ============================================================================== --- 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... ============================================================================== --- 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/obj... ============================================================================== --- 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); }