cleaned up the mess caused by FloodFill patch

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15011 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2002-04-07 23:07:17 +00:00
parent 17483066d2
commit 3a0a5ada86
6 changed files with 114 additions and 198 deletions

View File

@@ -7,8 +7,6 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#endif
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -17,12 +15,17 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#if wxUSE_IMAGE #include "wx/defs.h"
#if wxUSE_IMAGE && !defined(__WXMSW__)
// we have no use for this code in wxMSW...
#include "wx/image.h" #include "wx/image.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/brush.h" #include "wx/brush.h"
#include "wx/dc.h"
#include "wx/dcmemory.h"
#endif #endif
// DoFloodFill // DoFloodFill
@@ -30,40 +33,44 @@
// a color different from the start pixel is reached (wxFLOOD_SURFACE) // a color different from the start pixel is reached (wxFLOOD_SURFACE)
// or fill color is reached (wxFLOOD_BORDER) // or fill color is reached (wxFLOOD_BORDER)
bool wxImage::MatchPixel(int x, int y, int w, int h, const wxColour & c) static LINKAGEMODE bool MatchPixel(wxImage *img, int x, int y, int w, int h, const wxColour& c)
{ {
if ((x<0)||(x>=w)||(y<0)||(y>=h)) return FALSE; if ((x<0)||(x>=w)||(y<0)||(y>=h)) return FALSE;
unsigned char r = GetRed(x,y); unsigned char r = img->GetRed(x,y);
unsigned char g = GetGreen(x,y); unsigned char g = img->GetGreen(x,y);
unsigned char b = GetBlue(x,y); unsigned char b = img->GetBlue(x,y);
return c.Red() == r && c.Green() == g && c.Blue() == b ; return c.Red() == r && c.Green() == g && c.Blue() == b ;
} }
bool wxImage::MatchBoundaryPixel(int x, int y, int w, int h, const wxColour & fill, const wxColour & bound) static LINKAGEMODE bool MatchBoundaryPixel(wxImage *img, int x, int y, int w, int h, const wxColour & fill, const wxColour& bound)
{ {
if ((x<0)||(x>=w)||(y<0)||(y>=h)) return TRUE; if ((x<0)||(x>=w)||(y<0)||(y>=h)) return TRUE;
unsigned char r = GetRed(x,y); unsigned char r = img->GetRed(x,y);
unsigned char g = GetGreen(x,y); unsigned char g = img->GetGreen(x,y);
unsigned char b = GetBlue(x,y); unsigned char b = img->GetBlue(x,y);
if ( fill.Red() == r && fill.Green() == g && fill.Blue() == b ) return TRUE; if ( fill.Red() == r && fill.Green() == g && fill.Blue() == b )
if ( bound.Red() == r && bound.Green() == g && bound.Blue() == b ) return TRUE; return TRUE;
if ( bound.Red() == r && bound.Green() == g && bound.Blue() == b )
return TRUE;
return FALSE; return FALSE;
} }
void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush, static LINKAGEMODE
const wxColour& testColour, int style /*=wxFLOOD_SURFACE */, void wxImageFloodFill(wxImage *image,
int LogicalFunction /*= wxCOPY, currently unused */) wxCoord x, wxCoord y, const wxBrush & fillBrush,
const wxColour& testColour, int style,
int LogicalFunction)
{ {
/* A diamond flood-fill using a circular queue system. /* A diamond flood-fill using a circular queue system.
Each pixel surrounding the current pixel is added to Each pixel surrounding the current pixel is added to
the queue if it meets the criteria, then is retrieved in the queue if it meets the criteria, then is retrieved in
its turn. Code originally based on http://www.drawit.co.nz/Developers.htm */ its turn. Code originally based on http://www.drawit.co.nz/Developers.htm */
int width = GetWidth(); int width = image->GetWidth();
int height = GetHeight(); int height = image->GetHeight();
//Draw using a pen made from the current brush colour //Draw using a pen made from the current brush colour
//Potentially allows us to use patterned flood fills in future code //Potentially allows us to use patterned flood fills in future code
@@ -76,9 +83,9 @@ void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush,
if (style == wxFLOOD_SURFACE) if (style == wxFLOOD_SURFACE)
{ {
//if wxFLOOD_SURFACE, if fill colour is same as required, we don't do anything //if wxFLOOD_SURFACE, if fill colour is same as required, we don't do anything
if ( GetRed(x,y) != r if ( image->GetRed(x,y) != r
|| GetGreen(x,y) != g || image->GetGreen(x,y) != g
|| GetBlue (x,y) != b ) || image->GetBlue (x,y) != b )
{ {
//prepare memory for queue //prepare memory for queue
//queue save, start, read //queue save, start, read
@@ -101,55 +108,55 @@ void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush,
*qs=yt=y; *qs=yt=y;
qs++; qs++;
SetRGB(xt,yt,r,g,b); image->SetRGB(xt,yt,r,g,b);
//Main queue loop //Main queue loop
while(qr!=qs) while(qr!=qs)
{ {
//Add new members to queue //Add new members to queue
//Above current pixel //Above current pixel
if(MatchPixel(xt,yt-1,width,height,testColour)) if(MatchPixel(image,xt,yt-1,width,height,testColour))
{ {
*qs=xt; *qs=xt;
qs++; qs++;
*qs=yt-1; *qs=yt-1;
qs++; qs++;
SetRGB(xt,yt-1,r,g,b); image->SetRGB(xt,yt-1,r,g,b);
//Loop back to beginning of queue //Loop back to beginning of queue
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Below current pixel //Below current pixel
if(MatchPixel(xt,yt+1,width,height,testColour)) if(MatchPixel(image,xt,yt+1,width,height,testColour))
{ {
*qs=xt; *qs=xt;
qs++; qs++;
*qs=yt+1; *qs=yt+1;
qs++; qs++;
SetRGB(xt,yt+1,r,g,b); image->SetRGB(xt,yt+1,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Left of current pixel //Left of current pixel
if(MatchPixel(xt-1,yt,width,height,testColour)) if(MatchPixel(image,xt-1,yt,width,height,testColour))
{ {
*qs=xt-1; *qs=xt-1;
qs++; qs++;
*qs=yt; *qs=yt;
qs++; qs++;
SetRGB(xt-1,yt,r,g,b); image->SetRGB(xt-1,yt,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Right of current pixel //Right of current pixel
if(MatchPixel(xt+1,yt,width,height,testColour)) if(MatchPixel(image,xt+1,yt,width,height,testColour))
{ {
*qs=xt+1; *qs=xt+1;
qs++; qs++;
*qs=yt; *qs=yt;
qs++; qs++;
SetRGB(xt+1,yt,r,g,b); image->SetRGB(xt+1,yt,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
@@ -171,9 +178,9 @@ void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush,
{ {
//style is wxFLOOD_BORDER //style is wxFLOOD_BORDER
// fill up to testColor border - if already testColour don't do anything // fill up to testColor border - if already testColour don't do anything
if ( GetRed(x,y) != testColour.Red() if ( image->GetRed(x,y) != testColour.Red()
|| GetGreen(x,y) != testColour.Green() || image->GetGreen(x,y) != testColour.Green()
|| GetBlue(x,y) != testColour.Blue() ) || image->GetBlue(x,y) != testColour.Blue() )
{ {
//prepare memory for queue //prepare memory for queue
//queue save, start, read //queue save, start, read
@@ -196,55 +203,55 @@ void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush,
*qs=yt=y; *qs=yt=y;
qs++; qs++;
SetRGB(xt,yt,r,g,b); image->SetRGB(xt,yt,r,g,b);
//Main queue loop //Main queue loop
while (qr!=qs) while (qr!=qs)
{ {
//Add new members to queue //Add new members to queue
//Above current pixel //Above current pixel
if(!MatchBoundaryPixel(xt,yt-1,width,height,fillColour,testColour)) if(!MatchBoundaryPixel(image,xt,yt-1,width,height,fillColour,testColour))
{ {
*qs=xt; *qs=xt;
qs++; qs++;
*qs=yt-1; *qs=yt-1;
qs++; qs++;
SetRGB(xt,yt-1,r,g,b); image->SetRGB(xt,yt-1,r,g,b);
//Loop back to beginning of queue //Loop back to beginning of queue
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Below current pixel //Below current pixel
if(!MatchBoundaryPixel(xt,yt+1,width,height,fillColour,testColour)) if(!MatchBoundaryPixel(image,xt,yt+1,width,height,fillColour,testColour))
{ {
*qs=xt; *qs=xt;
qs++; qs++;
*qs=yt+1; *qs=yt+1;
qs++; qs++;
SetRGB(xt,yt+1,r,g,b); image->SetRGB(xt,yt+1,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Left of current pixel //Left of current pixel
if(!MatchBoundaryPixel(xt-1,yt,width,height,fillColour,testColour)) if(!MatchBoundaryPixel(image,xt-1,yt,width,height,fillColour,testColour))
{ {
*qs=xt-1; *qs=xt-1;
qs++; qs++;
*qs=yt; *qs=yt;
qs++; qs++;
SetRGB(xt-1,yt,r,g,b); image->SetRGB(xt-1,yt,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
//Right of current pixel //Right of current pixel
if(!MatchBoundaryPixel(xt+1,yt,width,height,fillColour,testColour)) if(!MatchBoundaryPixel(image,xt+1,yt,width,height,fillColour,testColour))
{ {
*qs=xt+1; *qs=xt+1;
qs++; qs++;
*qs=yt; *qs=yt;
qs++; qs++;
SetRGB(xt+1,yt,r,g,b); image->SetRGB(xt+1,yt,r,g,b);
if(qs>=(qst+qSz)) qs=qst; if(qs>=(qst+qSz)) qs=qst;
} }
@@ -265,5 +272,35 @@ void wxImage::DoFloodFill (wxCoord x, wxCoord y, const wxBrush & fillBrush,
//all done, //all done,
} }
void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
const wxColour& col, int style)
{
if (dc->GetBrush().GetStyle() == wxTRANSPARENT)
return;
int height = 0;
int width = 0;
dc->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
wxCHECK_RET(width >= 1 && height >= 1, wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
//this is much faster than doing the individual pixels
wxMemoryDC memdc;
wxBitmap bitmap(width, height);
memdc.SelectObject(bitmap);
memdc.Blit(0, 0, width, height, dc, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image = bitmap.ConvertToImage();
wxImageFloodFill(&image, x,y, dc->GetBrush(), col, style,
dc->GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
dc->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
}
#endif // wxUSE_IMAGE #endif // wxUSE_IMAGE

View File

@@ -649,40 +649,15 @@ void wxDC::SetLogicalFunction( int function )
m_macPenInstalled = false ; m_macPenInstalled = false ;
} }
void wxDC::DoFloodFill( wxCoord x, wxCoord y, const wxColour& col, extern void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
int style ) const wxColour & col, int style);
{
if (GetBrush().GetStyle() == wxTRANSPARENT)
{
wxLogDebug(wxT("In FloodFill, Current Brush is transparent, no filling done"));
return ;
}
int height = 0;
int width = 0;
this->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
if (width < 1 || height < 1)
{
wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
return ;
}
//this is much faster than doing the individual pixels void wxDC::DoFloodFill(wxCoord x, wxCoord y,
wxMemoryDC memdc; const wxColour& col, int style)
wxBitmap bitmap(width, height); {
memdc.SelectObject(bitmap); wxDoFloodFill(this, x, y, col, style);
memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image = bitmap.ConvertToImage() ;
image.DoFloodFill (x,y, GetBrush(), col, style, GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
this->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
} }
bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
{ {
wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") ); wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") );

View File

@@ -649,40 +649,15 @@ void wxDC::SetLogicalFunction( int function )
m_macPenInstalled = false ; m_macPenInstalled = false ;
} }
void wxDC::DoFloodFill( wxCoord x, wxCoord y, const wxColour& col, extern void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
int style ) const wxColour & col, int style);
{
if (GetBrush().GetStyle() == wxTRANSPARENT)
{
wxLogDebug(wxT("In FloodFill, Current Brush is transparent, no filling done"));
return ;
}
int height = 0;
int width = 0;
this->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
if (width < 1 || height < 1)
{
wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
return ;
}
//this is much faster than doing the individual pixels void wxDC::DoFloodFill(wxCoord x, wxCoord y,
wxMemoryDC memdc; const wxColour& col, int style)
wxBitmap bitmap(width, height); {
memdc.SelectObject(bitmap); wxDoFloodFill(this, x, y, col, style);
memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image = bitmap.ConvertToImage() ;
image.DoFloodFill (x,y, GetBrush(), col, style, GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
this->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
} }
bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
{ {
wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") ); wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") );

View File

@@ -332,36 +332,13 @@ void wxDC::Clear()
} }
} }
void wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) extern void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
{ const wxColour & col, int style);
if (GetBrush().GetStyle() == wxTRANSPARENT)
{
wxLogDebug(wxT("In FloodFill, Current Brush is transparent, no filling done"));
return ;
}
int height = 0;
int width = 0;
this->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
if (width < 1 || height < 1)
{
wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
return ;
}
//this is much faster than doing the individual pixels void wxDC::DoFloodFill(wxCoord x, wxCoord y,
wxMemoryDC memdc; const wxColour& col, int style)
wxBitmap bitmap(width, height); {
memdc.SelectObject(bitmap); wxDoFloodFill(this, x, y, col, style);
memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image(bitmap);
image.DoFloodFill (x,y, GetBrush(), col, style, GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
this->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
} }
bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const

View File

@@ -231,37 +231,13 @@ wxWindowDC::~wxWindowDC()
m_userRegion = (WXRegion) 0; m_userRegion = (WXRegion) 0;
} }
void wxWindowDC::DoFloodFill( wxCoord x1, wxCoord y1, extern void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
const wxColour & col, int style);
void wxWindowDC::DoFloodFill(wxCoord x, wxCoord y,
const wxColour& col, int style) const wxColour& col, int style)
{ {
if (GetBrush().GetStyle() == wxTRANSPARENT) wxDoFloodFill(this, x, y, col, style);
{
wxLogDebug(wxT("In FloodFill, current brush is transparent, no filling done"));
return ;
}
int height = 0;
int width = 0;
this->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
if (width < 1 || height < 1)
{
wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
return ;
}
//this is much faster than doing the individual pixels
wxMemoryDC memdc;
wxBitmap bitmap(width, height);
memdc.SelectObject(bitmap);
memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image(bitmap);
image.DoFloodFill (x1,y1, GetBrush(), col, style, GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
this->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
} }
bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const

View File

@@ -313,37 +313,13 @@ void wxWindowDC::DoGetSize( int* width, int* height ) const
m_owner->GetSize(width, height); m_owner->GetSize(width, height);
} }
extern void wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
const wxColour & col, int style);
void wxWindowDC::DoFloodFill(wxCoord x, wxCoord y, void wxWindowDC::DoFloodFill(wxCoord x, wxCoord y,
const wxColour& col, int style) const wxColour& col, int style)
{ {
if (GetBrush().GetStyle() == wxTRANSPARENT) wxDoFloodFill(this, x, y, col, style);
{
wxLogDebug(wxT("In FloodFill, current brush is transparent, no filling done"));
return ;
}
int height = 0;
int width = 0;
this->GetSize(&width, &height);
//it would be nice to fail if we don't get a sensible size...
if (width < 1 || height < 1)
{
wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
return ;
}
//this is much faster than doing the individual pixels
wxMemoryDC memdc;
wxBitmap bitmap(width, height);
memdc.SelectObject(bitmap);
memdc.Blit(0, 0, width, height, (wxDC*) this, 0, 0);
memdc.SelectObject(wxNullBitmap);
wxImage image(bitmap);
image.DoFloodFill (x,y, GetBrush(), col, style, GetLogicalFunction());
bitmap = wxBitmap(image);
memdc.SelectObject(bitmap);
this->Blit(0, 0, width, height, &memdc, 0, 0);
memdc.SelectObject(wxNullBitmap);
} }
bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const