/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/imagfill.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/imagfill.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 8800 byte(s)
committing r3113 initial commit again...
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/common/imagfill.cpp
3     // Purpose: FloodFill for wxImage
4     // Author: Julian Smart
5     // RCS-ID: $Id: imagfill.cpp 39957 2006-07-03 19:02:54Z ABX $
6     // Copyright: (c) Julian Smart
7     // Licence: wxWindows licence
8     /////////////////////////////////////////////////////////////////////////////
9    
10    
11     // For compilers that support precompilation, includes "wx.h".
12     #include "wx/wxprec.h"
13    
14     #ifdef __BORLANDC__
15     #pragma hdrstop
16     #endif
17    
18     #if wxUSE_IMAGE && !defined(__WXMSW__)
19     // we have no use for this code in wxMSW...
20    
21     #ifndef WX_PRECOMP
22     #include "wx/brush.h"
23     #include "wx/dc.h"
24     #include "wx/dcmemory.h"
25     #include "wx/image.h"
26     #endif
27    
28     // DoFloodFill
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)
32    
33     static bool LINKAGEMODE MatchPixel(wxImage *img, int x, int y, int w, int h, const wxColour& c)
34     {
35     if ((x<0)||(x>=w)||(y<0)||(y>=h)) return false;
36    
37     unsigned char r = img->GetRed(x,y);
38     unsigned char g = img->GetGreen(x,y);
39     unsigned char b = img->GetBlue(x,y);
40     return c.Red() == r && c.Green() == g && c.Blue() == b ;
41     }
42    
43     static bool LINKAGEMODE MatchBoundaryPixel(wxImage *img, int x, int y, int w, int h, const wxColour & fill, const wxColour& bound)
44     {
45     if ((x<0)||(x>=w)||(y<0)||(y>=h)) return true;
46    
47     unsigned char r = img->GetRed(x,y);
48     unsigned char g = img->GetGreen(x,y);
49     unsigned char b = img->GetBlue(x,y);
50     if ( fill.Red() == r && fill.Green() == g && fill.Blue() == b )
51     return true;
52     if ( bound.Red() == r && bound.Green() == g && bound.Blue() == b )
53     return true;
54     return false;
55     }
56    
57    
58     static void LINKAGEMODE
59     wxImageFloodFill(wxImage *image,
60     wxCoord x, wxCoord y, const wxBrush & fillBrush,
61     const wxColour& testColour, int style,
62     int WXUNUSED(LogicalFunction))
63     {
64     /* A diamond flood-fill using a circular queue system.
65     Each pixel surrounding the current pixel is added to
66     the queue if it meets the criteria, then is retrieved in
67     its turn. Code originally based on http://www.drawit.co.nz/Developers.htm,
68     with explicit permission to use this for wxWidgets granted by Andrew Empson
69     (no copyright claimed)
70     */
71    
72     int width = image->GetWidth();
73     int height = image->GetHeight();
74    
75     //Draw using a pen made from the current brush colour
76     //Potentially allows us to use patterned flood fills in future code
77     wxColour fillColour = fillBrush.GetColour();
78     unsigned char r = fillColour.Red();
79     unsigned char g = fillColour.Green();
80     unsigned char b = fillColour.Blue();
81    
82     //initial test :
83     if (style == wxFLOOD_SURFACE)
84     {
85     //if wxFLOOD_SURFACE, if fill colour is same as required, we don't do anything
86     if ( image->GetRed(x,y) != r
87     || image->GetGreen(x,y) != g
88     || image->GetBlue (x,y) != b )
89     {
90     //prepare memory for queue
91     //queue save, start, read
92     size_t *qs, *qst, *qr;
93    
94     //queue size (physical)
95     long qSz= height * width * 2;
96     qst = new size_t [qSz];
97    
98     //temporary x and y locations
99     int xt, yt;
100    
101     for (int i=0; i < qSz; i++)
102     qst[i] = 0;
103    
104     // start queue
105     qs=qr=qst;
106     *qs=xt=x;
107     qs++;
108     *qs=yt=y;
109     qs++;
110    
111     image->SetRGB(xt,yt,r,g,b);
112    
113     //Main queue loop
114     while(qr!=qs)
115     {
116     //Add new members to queue
117     //Above current pixel
118     if(MatchPixel(image,xt,yt-1,width,height,testColour))
119     {
120     *qs=xt;
121     qs++;
122     *qs=yt-1;
123     qs++;
124     image->SetRGB(xt,yt-1,r,g,b);
125    
126     //Loop back to beginning of queue
127     if(qs>=(qst+qSz)) qs=qst;
128     }
129    
130     //Below current pixel
131     if(MatchPixel(image,xt,yt+1,width,height,testColour))
132     {
133     *qs=xt;
134     qs++;
135     *qs=yt+1;
136     qs++;
137     image->SetRGB(xt,yt+1,r,g,b);
138     if(qs>=(qst+qSz)) qs=qst;
139     }
140    
141     //Left of current pixel
142     if(MatchPixel(image,xt-1,yt,width,height,testColour))
143     {
144     *qs=xt-1;
145     qs++;
146     *qs=yt;
147     qs++;
148     image->SetRGB(xt-1,yt,r,g,b);
149     if(qs>=(qst+qSz)) qs=qst;
150     }
151    
152     //Right of current pixel
153     if(MatchPixel(image,xt+1,yt,width,height,testColour))
154     {
155     *qs=xt+1;
156     qs++;
157     *qs=yt;
158     qs++;
159     image->SetRGB(xt+1,yt,r,g,b);
160     if(qs>=(qst+qSz)) qs=qst;
161     }
162    
163     //Retrieve current queue member
164     qr+=2;
165    
166     //Loop back to the beginning
167     if(qr>=(qst+qSz)) qr=qst;
168     xt=*qr;
169     yt=*(qr+1);
170    
171     //Go Back to beginning of loop
172     }
173    
174     delete[] qst;
175     }
176     }
177     else
178     {
179     //style is wxFLOOD_BORDER
180     // fill up to testColor border - if already testColour don't do anything
181     if ( image->GetRed(x,y) != testColour.Red()
182     || image->GetGreen(x,y) != testColour.Green()
183     || image->GetBlue(x,y) != testColour.Blue() )
184     {
185     //prepare memory for queue
186     //queue save, start, read
187     size_t *qs, *qst, *qr;
188    
189     //queue size (physical)
190     long qSz= height * width * 2;
191     qst = new size_t [qSz];
192    
193     //temporary x and y locations
194     int xt, yt;
195    
196     for (int i=0; i < qSz; i++)
197     qst[i] = 0;
198    
199     // start queue
200     qs=qr=qst;
201     *qs=xt=x;
202     qs++;
203     *qs=yt=y;
204     qs++;
205    
206     image->SetRGB(xt,yt,r,g,b);
207    
208     //Main queue loop
209     while (qr!=qs)
210     {
211     //Add new members to queue
212     //Above current pixel
213     if(!MatchBoundaryPixel(image,xt,yt-1,width,height,fillColour,testColour))
214     {
215     *qs=xt;
216     qs++;
217     *qs=yt-1;
218     qs++;
219     image->SetRGB(xt,yt-1,r,g,b);
220    
221     //Loop back to beginning of queue
222     if(qs>=(qst+qSz)) qs=qst;
223     }
224    
225     //Below current pixel
226     if(!MatchBoundaryPixel(image,xt,yt+1,width,height,fillColour,testColour))
227     {
228     *qs=xt;
229     qs++;
230     *qs=yt+1;
231     qs++;
232     image->SetRGB(xt,yt+1,r,g,b);
233     if(qs>=(qst+qSz)) qs=qst;
234     }
235    
236     //Left of current pixel
237     if(!MatchBoundaryPixel(image,xt-1,yt,width,height,fillColour,testColour))
238     {
239     *qs=xt-1;
240     qs++;
241     *qs=yt;
242     qs++;
243     image->SetRGB(xt-1,yt,r,g,b);
244     if(qs>=(qst+qSz)) qs=qst;
245     }
246    
247     //Right of current pixel
248     if(!MatchBoundaryPixel(image,xt+1,yt,width,height,fillColour,testColour))
249     {
250     *qs=xt+1;
251     qs++;
252     *qs=yt;
253     qs++;
254     image->SetRGB(xt+1,yt,r,g,b);
255     if(qs>=(qst+qSz)) qs=qst;
256     }
257    
258     //Retrieve current queue member
259     qr+=2;
260    
261     //Loop back to the beginning
262     if(qr>=(qst+qSz)) qr=qst;
263     xt=*qr;
264     yt=*(qr+1);
265    
266     //Go Back to beginning of loop
267     }
268    
269     delete[] qst;
270     }
271     }
272     //all done,
273     }
274    
275    
276     bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
277     const wxColour& col, int style)
278     {
279     if (dc->GetBrush().GetStyle() == wxTRANSPARENT)
280     return true;
281    
282     int height = 0;
283     int width = 0;
284     dc->GetSize(&width, &height);
285    
286     //it would be nice to fail if we don't get a sensible size...
287     wxCHECK_MSG(width >= 1 && height >= 1, false,
288     wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
289    
290     //this is much faster than doing the individual pixels
291     wxMemoryDC memdc;
292     wxBitmap bitmap(width, height);
293     memdc.SelectObject(bitmap);
294     memdc.Blit(0, 0, width, height, dc, 0, 0);
295     memdc.SelectObject(wxNullBitmap);
296    
297     wxImage image = bitmap.ConvertToImage();
298     wxImageFloodFill(&image, x,y, dc->GetBrush(), col, style,
299     dc->GetLogicalFunction());
300     bitmap = wxBitmap(image);
301     memdc.SelectObject(bitmap);
302     dc->Blit(0, 0, width, height, &memdc, 0, 0);
303     memdc.SelectObject(wxNullBitmap);
304    
305     return true;
306     }
307    
308     #endif // wxUSE_IMAGE

  ViewVC Help
Powered by ViewVC 1.1.22