Audacity  2.2.2
ImageRoll.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ImageRoll.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//****************************************************************//*******************************************************************/
96 
97 #include "../Audacity.h"
98 #include "ImageRoll.h"
99 
100 #include <wx/wx.h>
101 #include <wx/bitmap.h>
102 #include <wx/dcmemory.h>
103 #include <wx/image.h>
104 
105 // static
106 ImageArray ImageRoll::SplitH(const wxImage &src, wxColour magicColor)
107 {
108  ImageArray result;
109 
110  int width = src.GetWidth();
111  int height = src.GetHeight();
112  unsigned char *data = src.GetData();
113  unsigned char *ptr = data;
114  unsigned char magicRed = magicColor.Red();
115  unsigned char magicGreen = magicColor.Green();
116  unsigned char magicBlue = magicColor.Blue();
117  bool cur, prev;
118  int i, j, start;
119 
120  // Sanity check...
121  if (width<=0 || height<=0 || data==NULL)
122  return result;
123 
124  prev = false;
125  start = 0;
126  for(i=0; i<width+1; i++) {
127  if (i < width) {
128  unsigned char *ptr2 = ptr;
129  cur = true;
130  for(j=0; j<height && cur; j++) {
131  if (!(ptr2[0] == magicRed &&
132  ptr2[1] == magicGreen &&
133  ptr2[2] == magicBlue))
134  cur = false;
135  ptr2 += 3 * width;
136  }
137  }
138  else
139  cur = !prev;
140 
141  if ((cur && !prev)) {
142  wxRect subRect(start, 0, i-start, height);
143  wxImage subImage;
144  if (subRect.width > 0)
145  subImage = src.GetSubImage(subRect);
146  else
147  subImage = wxImage(subRect.width, subRect.height);
148  result.push_back(subImage);
149  }
150  else if (!cur && prev) {
151  start = i;
152  }
153 
154  prev = cur;
155  ptr += 3;
156  }
157 
158  return result;
159 }
160 
161 // static
162 ImageArray ImageRoll::SplitV(const wxImage &src, wxColour magicColor)
163 {
164  ImageArray result;
165  int width = src.GetWidth();
166  int height = src.GetHeight();
167  unsigned char *data = src.GetData();
168  unsigned char *ptr = data;
169  unsigned char magicRed = magicColor.Red();
170  unsigned char magicGreen = magicColor.Green();
171  unsigned char magicBlue = magicColor.Blue();
172  bool cur, prev;
173  int i, j, start;
174 
175  // Sanity check...
176  if (width<=0 || height<=0 || data==NULL)
177  return result;
178 
179  prev = false;
180  start = 0;
181  for(i=0; i<height+1; i++) {
182  if (i < height) {
183  unsigned char *ptr2 = ptr;
184  cur = true;
185  for(j=0; j<width && cur; j++) {
186  if (!(ptr2[0] == magicRed &&
187  ptr2[1] == magicGreen &&
188  ptr2[2] == magicBlue))
189  cur = false;
190  ptr2 += 3;
191  }
192  }
193  else
194  cur = !prev;
195 
196  if ((cur && !prev)) {
197  wxRect subRect(0, start, width, i-start);
198  wxImage subImage;
199  if (subRect.width > 0)
200  subImage = src.GetSubImage(subRect);
201  else
202  subImage = wxImage(subRect.width, subRect.height);
203  result.push_back(subImage);
204  }
205  else if (!cur && prev) {
206  start = i;
207  }
208 
209  prev = cur;
210  ptr += 3*width;
211  }
212 
213  return result;
214 }
215 
216 void ImageRoll::Init(RollType type, const wxImage &src, wxColour magicColor)
217 {
218  ImageArray images;
219  int i;
220 
221  mType = type;
222 
223  switch(mType) {
224  case HorizontalRoll:
225  images = SplitH(src, magicColor);
226 
227  mMinSize.x = 0;
228  mMinSize.y = src.GetHeight();
229  mMaxSize.x = 9999;
230  mMaxSize.y = src.GetHeight();
231 
232  for(i = 0; i < (int)images.size(); i++) {
233  if (images[i].Ok()) {
234  mPieces.push_back(wxBitmap(images[i]));
235  mMinSize.x += mPieces[i].GetWidth();
236  }
237  else
238  mPieces.push_back(wxBitmap());
239  }
240  break;
241 
242  case VerticalRoll:
243  images = SplitV(src, magicColor);
244 
245  mMinSize.x = src.GetWidth();
246  mMinSize.y = 0;
247  mMaxSize.x = src.GetWidth();
248  mMaxSize.y = 9999;
249 
250  for(i = 0; i < (int)images.size(); i++) {
251  if (images[i].Ok()) {
252  mPieces.push_back(wxBitmap(images[i]));
253  mMinSize.y += mPieces[i].GetHeight();
254  }
255  else
256  mPieces.push_back(wxBitmap());
257  }
258  break;
259 
260  case FixedImage:
261  mPieces.push_back(wxBitmap(src));
262  mMinSize.x = src.GetWidth();
263  mMinSize.y = src.GetHeight();
264  mMaxSize.x = src.GetWidth();
265  mMaxSize.y = src.GetHeight();
266  break;
267 
268  /* Adding these shuts up some GCC warnings. It is functionally what was
269  * implict here before - Richard */
270  case Uninitialized:
271  break;
272 
273  case Frame:
274  break;
275 
276  } // switch
277 }
278 
280 {
282 }
283 
284 ImageRoll::ImageRoll(RollType type, const wxImage &src, wxColour magicColor)
285 {
286  Init(type, src, magicColor);
287 }
288 
289 ImageRoll::ImageRoll(const wxImage &src)
290 {
291  Init(FixedImage, src, *wxWHITE);
292 }
293 
294 bool ImageRoll::Ok() const
295 {
296  return (mType != Uninitialized);
297 }
298 
299 void ImageRoll::DrawBitmap(wxDC &dc, wxBitmap &bitmap,
300  int x, int y, wxRasterOperationMode logicalFunc)
301 {
302  if (logicalFunc == wxCOPY)
303  dc.DrawBitmap(bitmap, x, y);
304  else {
305  wxMemoryDC memDC;
306  memDC.SelectObject(bitmap);
307  dc.Blit(x, y, bitmap.GetWidth(), bitmap.GetHeight(),
308  &memDC, 0, 0, logicalFunc);
309  }
310 }
311 
312 void ImageRoll::Draw(wxDC &dc, wxRect rect, wxRasterOperationMode WXUNUSED(logicalFunc))
313 {
314  int width = rect.width;
315  int height = rect.height;
316  int num = (int)mPieces.size();
317  int i, j;
318 
319  switch(mType) {
320  case HorizontalRoll: {
321  // The pieces alternate fixed, rolling, fixed, rolling...
322 
323  int fixedWidth = 0;
324  for(i=0; i<num; i+=2)
325  fixedWidth += (mPieces[i].Ok() ? mPieces[i].GetWidth() : 0);
326 
327  int rollingSpace = width - fixedWidth;
328  int numRolling = num / 2;
329  int x = 0;
330 
331  for(i=0; i<num; i++) {
332  int w = (mPieces[i].Ok() ? mPieces[i].GetWidth() : 0);
333 
334  if (i%2==0) {
335  // fixed
336 
337  if (mPieces[i].Ok())
338  DrawBitmap(dc, mPieces[i], rect.x + x, rect.y);
339  x += w;
340  }
341  else {
342  // rolling
343 
344  int space =
345  ((1+(i/2))*rollingSpace / numRolling) -
346  ((i/2)*rollingSpace / numRolling);
347 
348  j = 0;
349  while(j < space) {
350  if (mPieces[i].Ok())
351  DrawBitmap(dc, mPieces[i], rect.x + x + j, rect.y);
352  j += w;
353  }
354 
355  x += space;
356  }
357  }
358  } break; // case HorizontalRoll
359 
360  case VerticalRoll: {
361  // The pieces alternate fixed, rolling, fixed, rolling...
362 
363  int fixedHeight = 0;
364  for(i=0; i<num; i+=2)
365  fixedHeight += (mPieces[i].Ok() ? mPieces[i].GetHeight() : 0);
366 
367  int rollingSpace = height - fixedHeight;
368  int numRolling = num / 2;
369  int y = 0;
370 
371  for(i=0; i<num; i++) {
372  int h = (mPieces[i].Ok() ? mPieces[i].GetHeight() : 0);
373 
374  if (i%2==0) {
375  // fixed
376 
377  if (mPieces[i].Ok())
378  DrawBitmap(dc, mPieces[i], rect.x, rect.y + y);
379  y += h;
380  }
381  else {
382  // rolling
383 
384  int space =
385  ((1+(i/2))*rollingSpace / numRolling) -
386  ((i/2)*rollingSpace / numRolling);
387 
388  j = 0;
389  while(j < space) {
390  if (mPieces[i].Ok())
391  DrawBitmap(dc, mPieces[i], rect.x, rect.y + y + j);
392  j += h;
393  }
394 
395  y += space;
396  }
397  }
398  } break; // case VerticalRoll
399 
400  case FixedImage:
401  DrawBitmap(dc, mPieces[0], rect.x, rect.y);
402  break;
403  /* the other possible cases don't really make sense, but not having them
404  * listed gives a GCC warning */
405  case Uninitialized:
406  break;
407 
408  case Frame:
409  break;
410 
411  } // switch
412 }
413 
414 BEGIN_EVENT_TABLE(ImageRollPanel, wxPanelWrapper)
415  EVT_PAINT(ImageRollPanel::OnPaint)
416  EVT_SIZE(ImageRollPanel::OnSize)
418 
420 
421 ImageRollPanel::ImageRollPanel(wxWindow *parent,
422  wxWindowID id,
423  //ImageRoll &imgRoll,
424  const wxPoint& pos,
425  const wxSize& size,
426  long style):
427  wxPanelWrapper(parent, id, pos, size, style),
428  //mImageRoll(imgRoll),
429  mLogicalFunction(wxCOPY)
430 {
431 // SetSizeHints(mImageRoll.GetMinSize(),
432 // mImageRoll.GetMaxSize());
433 }
434 
436 {
437  mLogicalFunction = func;
438 }
439 
440 void ImageRollPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
441 {
442  wxPaintDC dc(this);
443 
444 // mImageRoll.Draw(dc, GetClientRect(), mLogicalFunction);
445 }
446 
447 void ImageRollPanel::OnSize(wxSizeEvent & WXUNUSED(event))
448 {
449  Refresh(false);
450 }
wxSize mMaxSize
Definition: ImageRoll.h:66
void SetLogicalFunction(wxRasterOperationMode func)
Definition: ImageRoll.cpp:435
void OnPaint(wxPaintEvent &evt)
Definition: ImageRoll.cpp:440
wxRasterOperationMode mLogicalFunction
Definition: ImageRoll.h:91
bool Ok() const
Definition: ImageRoll.cpp:294
std::vector< wxBitmap > mPieces
Definition: ImageRoll.h:64
std::vector< wxImage > ImageArray
Definition: ImageRoll.h:27
static ImageArray SplitH(const wxImage &src, wxColour magicColor)
Definition: ImageRoll.cpp:106
A wxPanel which displays an ImageRoll.
Definition: ImageRoll.h:71
static ImageArray SplitV(const wxImage &src, wxColour magicColor)
Definition: ImageRoll.cpp:162
IMPLEMENT_CLASS(ControlToolBar, ToolBar)
RollType mType
Definition: ImageRoll.h:62
void OnSize(wxSizeEvent &evt)
Definition: ImageRoll.cpp:447
wxSize mMinSize
Definition: ImageRoll.h:65
void Draw(wxDC &dc, wxRect rect, wxRasterOperationMode logicalFunc=wxCOPY)
Definition: ImageRoll.cpp:312
#define wxRasterOperationMode
Definition: ImageRoll.h:23
void Init(RollType type, const wxImage &src, wxColour magicColor)
Definition: ImageRoll.cpp:216
END_EVENT_TABLE()
void DrawBitmap(wxDC &dc, wxBitmap &bitmap, int x, int y, wxRasterOperationMode logicalFunc=wxCOPY)
Definition: ImageRoll.cpp:299