]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imagfill.cpp
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"
29 // Fills with the colour extracted from fillBrush, starting at x,y until either
30 // a color different from the start pixel is reached (wxFLOOD_SURFACE)
31 // or fill color is reached (wxFLOOD_BORDER)
33 bool wxImage::MatchPixel(int x
, int y
, int w
, int h
, const wxColour
& c
)
35 if ((x
<0)||(x
>=w
)||(y
<0)||(y
>=h
)) return false;
37 unsigned char r
= GetRed(x
,y
);
38 unsigned char g
= GetGreen(x
,y
);
39 unsigned char b
= GetBlue(x
,y
);
40 return c
.Red() == r
&& c
.Green() == g
&& c
.Blue() == b
;
43 bool wxImage::MatchBoundaryPixel(int x
, int y
, int w
, int h
, const wxColour
& fill
, const wxColour
& bound
)
45 if ((x
<0)||(x
>=w
)||(y
<0)||(y
>=h
)) return TRUE
;
47 unsigned char r
= GetRed(x
,y
);
48 unsigned char g
= GetGreen(x
,y
);
49 unsigned char b
= GetBlue(x
,y
);
50 if ( fill
.Red() == r
&& fill
.Green() == g
&& fill
.Blue() == b
) return TRUE
;
51 if ( bound
.Red() == r
&& bound
.Green() == g
&& bound
.Blue() == b
) return TRUE
;
56 void wxImage::DoFloodFill (wxCoord x
, wxCoord y
, const wxBrush
& fillBrush
,
57 const wxColour
& testColour
, int style
/*=wxFLOOD_SURFACE */,
58 int LogicalFunction
/*= wxCOPY, currently unused */)
60 /* A diamond flood-fill using a circular queue system.
61 Each pixel surrounding the current pixel is added to
62 the queue if it meets the criteria, then is retrieved in
63 its turn. Code originally based on http://www.drawit.co.nz/Developers.htm */
65 int width
= GetWidth();
66 int height
= GetHeight();
68 //Draw using a pen made from the current brush colour
69 //Potentially allows us to use patterned flood fills in future code
70 wxColour fillColour
= fillBrush
.GetColour();
71 unsigned char r
= fillColour
.Red();
72 unsigned char g
= fillColour
.Green();
73 unsigned char b
= fillColour
.Blue();
76 if (style
== wxFLOOD_SURFACE
)
78 //if wxFLOOD_SURFACE, if fill colour is same as required, we don't do anything
81 || GetBlue (x
,y
) != b
)
83 //prepare memory for queue
84 //queue save, start, read
85 size_t *qs
, *qst
, *qr
;
87 //queue size (physical)
88 long qSz
= height
* width
* 2;
89 qst
= new size_t [qSz
];
91 //temporary x and y locations
94 for (int i
=0; i
< qSz
; i
++)
109 //Add new members to queue
110 //Above current pixel
111 if(MatchPixel(xt
,yt
-1,width
,height
,testColour
))
117 SetRGB(xt
,yt
-1,r
,g
,b
);
119 //Loop back to beginning of queue
120 if(qs
>=(qst
+qSz
)) qs
=qst
;
123 //Below current pixel
124 if(MatchPixel(xt
,yt
+1,width
,height
,testColour
))
130 SetRGB(xt
,yt
+1,r
,g
,b
);
131 if(qs
>=(qst
+qSz
)) qs
=qst
;
134 //Left of current pixel
135 if(MatchPixel(xt
-1,yt
,width
,height
,testColour
))
141 SetRGB(xt
-1,yt
,r
,g
,b
);
142 if(qs
>=(qst
+qSz
)) qs
=qst
;
145 //Right of current pixel
146 if(MatchPixel(xt
+1,yt
,width
,height
,testColour
))
152 SetRGB(xt
+1,yt
,r
,g
,b
);
153 if(qs
>=(qst
+qSz
)) qs
=qst
;
156 //Retrieve current queue member
159 //Loop back to the beginning
160 if(qr
>=(qst
+qSz
)) qr
=qst
;
164 //Go Back to beginning of loop
172 //style is wxFLOOD_BORDER
173 // fill up to testColor border - if already testColour don't do anything
174 if ( GetRed(x
,y
) != testColour
.Red()
175 || GetGreen(x
,y
) != testColour
.Green()
176 || GetBlue(x
,y
) != testColour
.Blue() )
178 //prepare memory for queue
179 //queue save, start, read
180 size_t *qs
, *qst
, *qr
;
182 //queue size (physical)
183 long qSz
= height
* width
* 2;
184 qst
= new size_t [qSz
];
186 //temporary x and y locations
189 for (int i
=0; i
< qSz
; i
++)
204 //Add new members to queue
205 //Above current pixel
206 if(!MatchBoundaryPixel(xt
,yt
-1,width
,height
,fillColour
,testColour
))
212 SetRGB(xt
,yt
-1,r
,g
,b
);
214 //Loop back to beginning of queue
215 if(qs
>=(qst
+qSz
)) qs
=qst
;
218 //Below current pixel
219 if(!MatchBoundaryPixel(xt
,yt
+1,width
,height
,fillColour
,testColour
))
225 SetRGB(xt
,yt
+1,r
,g
,b
);
226 if(qs
>=(qst
+qSz
)) qs
=qst
;
229 //Left of current pixel
230 if(!MatchBoundaryPixel(xt
-1,yt
,width
,height
,fillColour
,testColour
))
236 SetRGB(xt
-1,yt
,r
,g
,b
);
237 if(qs
>=(qst
+qSz
)) qs
=qst
;
240 //Right of current pixel
241 if(!MatchBoundaryPixel(xt
+1,yt
,width
,height
,fillColour
,testColour
))
247 SetRGB(xt
+1,yt
,r
,g
,b
);
248 if(qs
>=(qst
+qSz
)) qs
=qst
;
251 //Retrieve current queue member
254 //Loop back to the beginning
255 if(qr
>=(qst
+qSz
)) qr
=qst
;
259 //Go Back to beginning of loop
268 #endif // wxUSE_IMAGE