ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

floodfill.c
Go to the documentation of this file.
00001 /* 
00002 * COPYRIGHT:         See COPYING in the top level directory
00003 * PROJECT:           ReactOS win32 subsystem
00004 * PURPOSE:           Flood filling support
00005 * FILE:              subsystems/win32/win32k/dib/floodfill.c
00006 * PROGRAMMER:        Gregor Schneider, <grschneider AT gmail DOT com>
00007 */
00008 
00009 #include <win32k.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 /*
00015 *  This floodfill algorithm is an iterative four neighbors version. It works with an internal stack like data structure.
00016 *  The stack is kept in an array, sized for the worst case scenario of having to add all pixels of the surface.
00017 *  This avoids having to allocate and free memory blocks  all the time. The stack grows from the end of the array towards the start.
00018 *  All pixels are checked before being added, against belonging to the fill rule (FLOODFILLBORDER or FLOODFILLSURFACE) 
00019 *  and the position in respect to the clip region. This guarantees all pixels lying on the stack belong to the filled surface.
00020 *  Further optimisations of the algorithm are possible.
00021 */
00022 
00023 /* Floodfil helper structures and functions */
00024 typedef struct _floodItem
00025 {
00026   ULONG x;
00027   ULONG y;
00028 } FLOODITEM;
00029 
00030 typedef struct _floodInfo
00031 {
00032   ULONG floodLen;
00033   FLOODITEM *floodStart;
00034   FLOODITEM *floodData;
00035 } FLOODINFO;
00036 
00037 static __inline BOOL initFlood(FLOODINFO *info, RECTL *DstRect)
00038 {
00039   ULONG width = DstRect->right - DstRect->left;
00040   ULONG height = DstRect->bottom - DstRect->top;
00041   info->floodData = ExAllocatePoolWithTag(NonPagedPool, width * height * sizeof(FLOODITEM), TAG_DIB); 
00042   if (info->floodData == NULL)
00043   {
00044     return FALSE;
00045   }
00046   info->floodStart = info->floodData + (width * height);
00047   DPRINT("Allocated flood stack from %p to %p\n", info->floodData, info->floodStart);
00048   return TRUE;
00049 }
00050 static __inline VOID finalizeFlood(FLOODINFO *info)
00051 {
00052   ExFreePoolWithTag(info->floodData, TAG_DIB);
00053 }
00054 static __inline VOID addItemFlood(FLOODINFO *info,
00055                                   ULONG x, 
00056                                   ULONG y, 
00057                                   SURFOBJ *DstSurf, 
00058                                   RECTL *DstRect, 
00059                                   ULONG Color, 
00060                                   BOOL isSurf)
00061 {
00062   if (RECTL_bPointInRect(DstRect,x,y))
00063   {
00064     if (isSurf == TRUE && 
00065       DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) != Color)
00066     {
00067       return;
00068     }
00069     else if (isSurf == FALSE &&
00070       DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) == Color)
00071     {
00072       return;
00073     }
00074     info->floodStart--;
00075     info->floodStart->x = x;
00076     info->floodStart->y = y;
00077     info->floodLen++;
00078   }
00079 }
00080 static __inline VOID removeItemFlood(FLOODINFO *info)
00081 {
00082   info->floodStart++;
00083   info->floodLen--;
00084 }
00085 
00086 BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ *DstSurf, 
00087                                  BRUSHOBJ *Brush, 
00088                                  RECTL *DstRect, 
00089                                  POINTL *Origin,
00090                                  ULONG ConvColor, 
00091                                  UINT FillType)
00092 {
00093   ULONG x, y;
00094   ULONG BrushColor;
00095   FLOODINFO flood = {0, NULL, NULL};
00096 
00097   BrushColor = Brush->iSolidColor;
00098   x = Origin->x;
00099   y = Origin->y;
00100 
00101   if (FillType == FLOODFILLBORDER)
00102   {
00103     /* Check if the start pixel has the border color */
00104     if (DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) == ConvColor)
00105     {
00106       return FALSE;
00107     }
00108 
00109     if (initFlood(&flood, DstRect) == FALSE)
00110     {
00111       return FALSE;
00112     }
00113     addItemFlood(&flood, x, y, DstSurf, DstRect, ConvColor, FALSE);
00114     while (flood.floodLen != 0) 
00115     {
00116       x = flood.floodStart->x;
00117       y = flood.floodStart->y;
00118       removeItemFlood(&flood);
00119 
00120       DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_PutPixel(DstSurf, x, y, BrushColor);
00121       if (flood.floodStart - 4 < flood.floodData)
00122       {   
00123         DPRINT1("Can't finish flooding!\n");
00124         finalizeFlood(&flood);
00125         return FALSE;
00126       }
00127       addItemFlood(&flood, x, y + 1, DstSurf, DstRect, ConvColor, FALSE);
00128       addItemFlood(&flood, x, y - 1, DstSurf, DstRect, ConvColor, FALSE);
00129       addItemFlood(&flood, x + 1, y, DstSurf, DstRect, ConvColor, FALSE);
00130       addItemFlood(&flood, x - 1, y, DstSurf, DstRect, ConvColor, FALSE);
00131     }
00132     finalizeFlood(&flood);
00133   }
00134   else if (FillType == FLOODFILLSURFACE)
00135   {
00136     /* Check if the start pixel has the surface color */
00137     if (DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_GetPixel(DstSurf, x, y) != ConvColor)
00138     {
00139       return FALSE;
00140     }
00141 
00142     if (initFlood(&flood, DstRect) == FALSE)
00143     {
00144       return FALSE;
00145     }
00146     addItemFlood(&flood, x, y, DstSurf, DstRect, ConvColor, TRUE);
00147     while (flood.floodLen != 0) 
00148     {
00149       x = flood.floodStart->x;
00150       y = flood.floodStart->y;
00151       removeItemFlood(&flood);
00152 
00153       DibFunctionsForBitmapFormat[DstSurf->iBitmapFormat].DIB_PutPixel(DstSurf, x, y, BrushColor);
00154       if (flood.floodStart - 4 < flood.floodData)
00155       {
00156         DPRINT1("Can't finish flooding!\n");
00157         finalizeFlood(&flood);
00158         return FALSE;
00159       }
00160       addItemFlood(&flood, x, y + 1, DstSurf, DstRect, ConvColor, TRUE);
00161       addItemFlood(&flood, x, y - 1, DstSurf, DstRect, ConvColor, TRUE);
00162       addItemFlood(&flood, x + 1, y, DstSurf, DstRect, ConvColor, TRUE);
00163       addItemFlood(&flood, x - 1, y, DstSurf, DstRect, ConvColor, TRUE);
00164     }
00165     finalizeFlood(&flood);
00166   }
00167   else
00168   {
00169     DPRINT1("Unsupported FloodFill type!\n");
00170     return FALSE;
00171   }
00172   return TRUE;
00173 }

Generated on Sat May 26 2012 04:36:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.