]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imagfill.cpp
f199f0a4e825e46fe36cd5a93d6e83a6ef71107d
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: FloodFill for wxImage
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
27 // Fills with the colour extracted from fillBrush, starting at x,y until either
28 // a color different from the start pixel is reached (wxFLOOD_SURFACE)
29 // or fill color is reached (wxFLOOD_BORDER)
31 bool wxImage::MatchPixel(int x
, int y
, int w
, int h
, const wxColour
& c
)
33 if ((x
<0)||(x
>=w
)||(y
<0)||(y
>=h
)) return false;
35 unsigned char r
= GetRed(x
,y
);
36 unsigned char g
= GetGreen(x
,y
);
37 unsigned char b
= GetBlue(x
,y
);
38 return c
.Red() == r
&& c
.Green() == g
&& c
.Blue() == b
;
41 bool wxImage::MatchBoundaryPixel(int x
, int y
, int w
, int h
, const wxColour
& fill
, const wxColour
& bound
)
43 if ((x
<0)||(x
>=w
)||(y
<0)||(y
>=h
)) return TRUE
;
45 unsigned char r
= GetRed(x
,y
);
46 unsigned char g
= GetGreen(x
,y
);
47 unsigned char b
= GetBlue(x
,y
);
48 if ( fill
.Red() == r
&& fill
.Green() == g
&& fill
.Blue() == b
) return TRUE
;
49 if ( bound
.Red() == r
&& bound
.Green() == g
&& bound
.Blue() == b
) return TRUE
;
54 void wxImage::DoFloodFill (wxCoord x
, wxCoord y
, const wxBrush
& fillBrush
,
55 const wxColour
& testColour
, int style
/*=wxFLOOD_SURFACE */,
56 int LogicalFunction
/*= wxCOPY, currently unused */)
58 /* A diamond flood-fill using a circular queue system.
59 Each pixel surrounding the current pixel is added to
60 the queue if it meets the criteria, then is retrieved in
61 its turn. Code originally based on http://www.drawit.co.nz/Developers.htm */
63 int width
= GetWidth();
64 int height
= GetHeight();
66 //Draw using a pen made from the current brush colour
67 //Potentially allows us to use patterned flood fills in future code
68 wxColour fillColour
= fillBrush
.GetColour();
69 unsigned char r
= fillColour
.Red();
70 unsigned char g
= fillColour
.Green();
71 unsigned char b
= fillColour
.Blue();
74 if (style
== wxFLOOD_SURFACE
)
76 //if wxFLOOD_SURFACE, if fill colour is same as required, we don't do anything
79 || GetBlue (x
,y
) != b
)
81 //prepare memory for queue
82 //queue save, start, read
83 size_t *qs
, *qst
, *qr
;
85 //queue size (physical)
86 long qSz
= height
* width
* 2;
87 qst
= new size_t [qSz
];
89 //temporary x and y locations
92 for (int i
=0; i
< qSz
; i
++)
107 //Add new members to queue
108 //Above current pixel
109 if(MatchPixel(xt
,yt
-1,width
,height
,testColour
))
115 SetRGB(xt
,yt
-1,r
,g
,b
);
117 //Loop back to beginning of queue
118 if(qs
>=(qst
+qSz
)) qs
=qst
;
121 //Below current pixel
122 if(MatchPixel(xt
,yt
+1,width
,height
,testColour
))
128 SetRGB(xt
,yt
+1,r
,g
,b
);
129 if(qs
>=(qst
+qSz
)) qs
=qst
;
132 //Left of current pixel
133 if(MatchPixel(xt
-1,yt
,width
,height
,testColour
))
139 SetRGB(xt
-1,yt
,r
,g
,b
);
140 if(qs
>=(qst
+qSz
)) qs
=qst
;
143 //Right of current pixel
144 if(MatchPixel(xt
+1,yt
,width
,height
,testColour
))
150 SetRGB(xt
+1,yt
,r
,g
,b
);
151 if(qs
>=(qst
+qSz
)) qs
=qst
;
154 //Retrieve current queue member
157 //Loop back to the beginning
158 if(qr
>=(qst
+qSz
)) qr
=qst
;
162 //Go Back to beginning of loop
170 //style is wxFLOOD_BORDER
171 // fill up to testColor border - if already testColour don't do anything
172 if ( GetRed(x
,y
) != testColour
.Red()
173 || GetGreen(x
,y
) != testColour
.Green()
174 || GetBlue(x
,y
) != testColour
.Blue() )
176 //prepare memory for queue
177 //queue save, start, read
178 size_t *qs
, *qst
, *qr
;
180 //queue size (physical)
181 long qSz
= height
* width
* 2;
182 qst
= new size_t [qSz
];
184 //temporary x and y locations
187 for (int i
=0; i
< qSz
; i
++)
202 //Add new members to queue
203 //Above current pixel
204 if(!MatchBoundaryPixel(xt
,yt
-1,width
,height
,fillColour
,testColour
))
210 SetRGB(xt
,yt
-1,r
,g
,b
);
212 //Loop back to beginning of queue
213 if(qs
>=(qst
+qSz
)) qs
=qst
;
216 //Below current pixel
217 if(!MatchBoundaryPixel(xt
,yt
+1,width
,height
,fillColour
,testColour
))
223 SetRGB(xt
,yt
+1,r
,g
,b
);
224 if(qs
>=(qst
+qSz
)) qs
=qst
;
227 //Left of current pixel
228 if(!MatchBoundaryPixel(xt
-1,yt
,width
,height
,fillColour
,testColour
))
234 SetRGB(xt
-1,yt
,r
,g
,b
);
235 if(qs
>=(qst
+qSz
)) qs
=qst
;
238 //Right of current pixel
239 if(!MatchBoundaryPixel(xt
+1,yt
,width
,height
,fillColour
,testColour
))
245 SetRGB(xt
+1,yt
,r
,g
,b
);
246 if(qs
>=(qst
+qSz
)) qs
=qst
;
249 //Retrieve current queue member
252 //Loop back to the beginning
253 if(qr
>=(qst
+qSz
)) qr
=qst
;
257 //Go Back to beginning of loop
266 #endif // wxUSE_IMAGE