]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_bitmap.i
fixed wxString iterators linked list corruption
[wxWidgets.git] / wxPython / src / _bitmap.i
CommitLineData
d14a1e28
RD
1/////////////////////////////////////////////////////////////////////////////
2// Name: _bitmap.i
3// Purpose: SWIG interface for wxBitmap and wxMask
4//
5// Author: Robin Dunn
6//
7// Created: 7-July-1997
8// RCS-ID: $Id$
9// Copyright: (c) 2003 by Total Control Software
10// Licence: wxWindows license
11/////////////////////////////////////////////////////////////////////////////
12
13// Not a %module
14
238ba802
RD
15%{
16#include <wx/rawbmp.h>
17%}
d14a1e28 18
777dffec 19
0f82eb02
RD
20// Turn off the aquisition of the Global Interpreter Lock for the classes and
21// functions in this file
777dffec
RD
22%threadWrapperOff
23
d14a1e28
RD
24//---------------------------------------------------------------------------
25
8f514ab4
RD
26%{
27// See http://tinyurl.com/e5adr for what premultiplying alpha means. It
28// appears to me that the other platforms are already doing it, so I'll just
29// automatically do it for wxMSW here.
30#ifdef __WXMSW__
31#define wxPy_premultiply(p, a) ((p) * (a) / 0xff)
32#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p))
33#else
34#define wxPy_premultiply(p, a) (p)
35#define wxPy_unpremultiply(p, a) (p)
36#endif
37%}
38
39//---------------------------------------------------------------------------
40
41
d14a1e28
RD
42%{
43#include <wx/image.h>
44
45 static char** ConvertListOfStrings(PyObject* listOfStrings) {
46 char** cArray = NULL;
47 int count;
48
49 if (!PyList_Check(listOfStrings)) {
50 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
51 return NULL;
52 }
53 count = PyList_Size(listOfStrings);
54 cArray = new char*[count];
55
56 for(int x=0; x<count; x++) {
57 // TODO: Need some validation and error checking here
58 cArray[x] = PyString_AsString(PyList_GET_ITEM(listOfStrings, x));
59 }
60 return cArray;
61 }
62
63%}
64
65//---------------------------------------------------------------------------
66
67// TODO: When the API stabalizes and is available on other platforms, add
68// wrappers for the new wxBitmap, wxRawBitmap, wxDIB stuff...
69
dce2bd22
RD
70DocStr(wxBitmap,
71"The wx.Bitmap class encapsulates the concept of a platform-dependent
72bitmap. It can be either monochrome or colour, and either loaded from
73a file or created dynamically. A bitmap can be selected into a memory
74device context (instance of `wx.MemoryDC`). This enables the bitmap to
75be copied to a window or memory device context using `wx.DC.Blit`, or
d07d2bc9 76to be used as a drawing surface.", "
dce2bd22
RD
77
78The BMP and XMP image file formats are supported on all platforms by
79wx.Bitmap. Other formats are automatically loaded by `wx.Image` and
80converted to a wx.Bitmap, so any image file format supported by
81`wx.Image` can be used.
82
83:todo: Add wrappers and support for raw bitmap data access. Can this
84 be be put into Python without losing the speed benefits of the
85 teplates and iterators in rawbmp.h?
86
87:todo: Find a way to do very efficient PIL Image <--> wx.Bitmap
88 converstions.
238ba802
RD
89
90:see: `wx.EmptyBitmap`, `wx.BitmapFromIcon`, `wx.BitmapFromImage`,
91 `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, `wx.BitmapFromBuffer`,
92 `wx.BitmapFromBufferRGBA`, `wx.Image`
dce2bd22
RD
93");
94
d14a1e28 95
ab1f7d2a
RD
96MustHaveApp(wxBitmap);
97
d14a1e28
RD
98class wxBitmap : public wxGDIObject
99{
100public:
1e0c8722
RD
101 DocCtorStr(
102 wxBitmap(const wxString& name, wxBitmapType type=wxBITMAP_TYPE_ANY),
d07d2bc9
RD
103 "Loads a bitmap from a file.",
104 "
105 :param name: Name of the file to load the bitmap from.
106 :param type: The type of image to expect. Can be one of the following
107 constants (assuming that the neccessary `wx.Image` handlers are
108 loaded):
dce2bd22
RD
109
110 * wx.BITMAP_TYPE_ANY
111 * wx.BITMAP_TYPE_BMP
112 * wx.BITMAP_TYPE_ICO
113 * wx.BITMAP_TYPE_CUR
114 * wx.BITMAP_TYPE_XBM
115 * wx.BITMAP_TYPE_XPM
116 * wx.BITMAP_TYPE_TIF
117 * wx.BITMAP_TYPE_GIF
118 * wx.BITMAP_TYPE_PNG
119 * wx.BITMAP_TYPE_JPEG
120 * wx.BITMAP_TYPE_PNM
121 * wx.BITMAP_TYPE_PCX
122 * wx.BITMAP_TYPE_PICT
123 * wx.BITMAP_TYPE_ICON
124 * wx.BITMAP_TYPE_ANI
125 * wx.BITMAP_TYPE_IFF
126
127:see: Alternate constructors `wx.EmptyBitmap`, `wx.BitmapFromIcon`,
8423bd78
RD
128 `wx.BitmapFromImage`, `wx.BitmapFromXPMData`, `wx.BitmapFromBits`,
129 `wx.BitmapFromBuffer`, `wx.BitmapFromBufferRGBA`,
dce2bd22 130");
1e0c8722 131
d14a1e28
RD
132 ~wxBitmap();
133
dce2bd22
RD
134 DocCtorStrName(
135 wxBitmap(int width, int height, int depth=-1),
136 "Creates a new bitmap of the given size. A depth of -1 indicates the
137depth of the current screen or visual. Some platforms only support 1
9c383901 138for monochrome and -1 for the current display depth.", "",
dce2bd22 139 EmptyBitmap);
1e0c8722
RD
140
141 DocCtorStrName(
142 wxBitmap(const wxIcon& icon),
d07d2bc9 143 "Create a new bitmap from a `wx.Icon` object.", "",
1e0c8722
RD
144 BitmapFromIcon);
145
146 DocCtorStrName(
147 wxBitmap(const wxImage& image, int depth=-1),
dce2bd22
RD
148 "Creates bitmap object from a `wx.Image`. This has to be done to
149actually display a `wx.Image` as you cannot draw an image directly on
150a window. The resulting bitmap will use the provided colour depth (or
151that of the current screen colour depth if depth is -1) which entails
d07d2bc9 152that a colour reduction may have to take place.", "",
1e0c8722
RD
153 BitmapFromImage);
154
155
d14a1e28 156 %extend {
238ba802
RD
157 %RenameDocCtor(
158 BitmapFromXPMData,
159 "Construct a Bitmap from a list of strings formatted as XPM data.", "",
160 wxBitmap(PyObject* listOfStrings))
161 {
162 char** cArray = NULL;
163 wxBitmap* bmp;
164
165 cArray = ConvertListOfStrings(listOfStrings);
166 if (! cArray)
167 return NULL;
168 bmp = new wxBitmap(cArray);
169 delete [] cArray;
170 return bmp;
171 }
172
173
174 %RenameDocCtor(
175 BitmapFromBits,
176 "Creates a bitmap from an array of bits. You should only use this
dce2bd22
RD
177function for monochrome bitmaps (depth 1) in portable programs: in
178this case the bits parameter should contain an XBM image. For other
238ba802
RD
179bit depths, the behaviour is platform dependent.", "",
180 wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
181 {
182 char* buf;
183 Py_ssize_t length;
184 PyString_AsStringAndSize(bits, &buf, &length);
185 return new wxBitmap(buf, width, height, depth);
186 }
d14a1e28
RD
187 }
188
189
d14a1e28
RD
190 // wxGDIImage methods
191#ifdef __WXMSW__
192 long GetHandle();
a0c956e8
RD
193 %extend {
194 void SetHandle(long handle) { self->SetHandle((WXHANDLE)handle); }
195 }
d14a1e28
RD
196#endif
197
6c2dd16f
RD
198 bool IsOk();
199 %pythoncode { Ok = IsOk }
200
dce2bd22
RD
201 DocDeclStr(
202 int , GetWidth(),
d07d2bc9 203 "Gets the width of the bitmap in pixels.", "");
dce2bd22 204
1e0c8722 205
dce2bd22
RD
206 DocDeclStr(
207 int , GetHeight(),
d07d2bc9 208 "Gets the height of the bitmap in pixels.", "");
dce2bd22 209
1e0c8722 210
dce2bd22
RD
211 DocDeclStr(
212 int , GetDepth(),
213 "Gets the colour depth of the bitmap. A value of 1 indicates a
d07d2bc9 214monochrome bitmap.", "");
dce2bd22 215
d14a1e28 216
ba938c3d
RD
217
218 %extend {
d07d2bc9 219 DocStr(GetSize, "Get the size of the bitmap.", "");
ba938c3d
RD
220 wxSize GetSize() {
221 wxSize size(self->GetWidth(), self->GetHeight());
222 return size;
223 }
224 }
225
226
dce2bd22
RD
227 DocDeclStr(
228 virtual wxImage , ConvertToImage() const,
229 "Creates a platform-independent image from a platform-dependent
230bitmap. This preserves mask information so that bitmaps and images can
d07d2bc9 231be converted back and forth without loss in that respect.", "");
dce2bd22
RD
232
233
234 DocDeclStr(
235 virtual wxMask* , GetMask() const,
236 "Gets the associated mask (if any) which may have been loaded from a
237file or explpicitly set for the bitmap.
238
239:see: `SetMask`, `wx.Mask`
d07d2bc9 240", "");
c1acc129
RD
241
242 // MSW only? wxBitmap GetMaskBitmap() const;
dce2bd22 243
c5633576 244 %disownarg(wxMask*);
dce2bd22
RD
245 DocDeclStr(
246 virtual void , SetMask(wxMask* mask),
247 "Sets the mask for this bitmap.
248
249:see: `GetMask`, `wx.Mask`
d07d2bc9 250", "");
c5633576 251 %cleardisown(wxMask*);
1e0c8722 252
d14a1e28 253 %extend {
1e0c8722 254 DocStr(SetMaskColour,
d07d2bc9 255 "Create a Mask based on a specified colour in the Bitmap.", "");
d14a1e28
RD
256 void SetMaskColour(const wxColour& colour) {
257 wxMask *mask = new wxMask(*self, colour);
258 self->SetMask(mask);
259 }
260 }
d14a1e28 261
d14a1e28 262
dce2bd22
RD
263 DocDeclStr(
264 virtual wxBitmap , GetSubBitmap(const wxRect& rect) const,
265 "Returns a sub-bitmap of the current one as long as the rect belongs
266entirely to the bitmap. This function preserves bit depth and mask
d07d2bc9 267information.", "");
dce2bd22
RD
268
269
270 DocDeclStr(
271 virtual bool , SaveFile(const wxString &name, wxBitmapType type,
272 wxPalette *palette = NULL),
273 "Saves a bitmap in the named file. See `__init__` for a description of
d07d2bc9 274the ``type`` parameter.", "");
dce2bd22 275
1e0c8722 276
dce2bd22
RD
277 DocDeclStr(
278 virtual bool , LoadFile(const wxString &name, wxBitmapType type),
279 "Loads a bitmap from a file. See `__init__` for a description of the
d07d2bc9 280``type`` parameter.", "");
dce2bd22 281
d14a1e28
RD
282
283
d14a1e28 284 virtual wxPalette *GetPalette() const;
7aada1e0 285#ifdef __WXMSW__
d14a1e28
RD
286 virtual void SetPalette(const wxPalette& palette);
287#endif
288
d14a1e28 289
1e0c8722
RD
290 virtual bool CopyFromIcon(const wxIcon& icon);
291
dce2bd22
RD
292 DocDeclStr(
293 virtual void , SetHeight(int height),
d07d2bc9 294 "Set the height property (does not affect the existing bitmap data).", "");
dce2bd22
RD
295
296
297 DocDeclStr(
298 virtual void , SetWidth(int width),
d07d2bc9 299 "Set the width property (does not affect the existing bitmap data).", "");
1e0c8722 300
1e0c8722 301
dce2bd22
RD
302 DocDeclStr(
303 virtual void , SetDepth(int depth),
d07d2bc9 304 "Set the depth property (does not affect the existing bitmap data).", "");
dce2bd22 305
d14a1e28 306
ba938c3d 307 %extend {
d07d2bc9 308 DocStr(SetSize, "Set the bitmap size (does not affect the existing bitmap data).", "");
ba938c3d
RD
309 void SetSize(const wxSize& size) {
310 self->SetWidth(size.x);
311 self->SetHeight(size.y);
312 }
313 }
1e0c8722 314
d14a1e28
RD
315#ifdef __WXMSW__
316 bool CopyFromCursor(const wxCursor& cursor);
d14a1e28
RD
317#endif
318
8f514ab4
RD
319 %extend {
320 DocStr(CopyFromBuffer,
321 "Copy data from a RGB buffer object to replace the bitmap pixel data.
cbfc9df6 322See `wx.BitmapFromBuffer` for more details.", "");
8f514ab4
RD
323 void CopyFromBuffer(buffer data, int DATASIZE)
324 {
325 int height=self->GetHeight();
326 int width=self->GetWidth();
327
328 if (DATASIZE != width * height * 3) {
329 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
330 }
331 wxNativePixelData pixData(*self, wxPoint(0,0), wxSize(width, height));
332 if (! pixData) {
333 // raise an exception...
334 wxPyErr_SetString(PyExc_RuntimeError,
335 "Failed to gain raw access to bitmap data.");
336 return;
337 }
338
339 wxNativePixelData::Iterator p(pixData);
340 for (int y=0; y<height; y++) {
341 wxNativePixelData::Iterator rowStart = p;
342 for (int x=0; x<width; x++) {
343 p.Red() = *(data++);
344 p.Green() = *(data++);
345 p.Blue() = *(data++);
346 ++p;
347 }
348 p = rowStart;
349 p.OffsetY(pixData, 1);
350 }
351 }
352
353 DocStr(CopyFromBufferRGBA,
354 "Copy data from a RGBA buffer object to replace the bitmap pixel data.
cbfc9df6 355See `wx.BitmapFromBufferRGBA` for more details.", "");
8f514ab4
RD
356 void CopyFromBufferRGBA(buffer data, int DATASIZE)
357 {
358 int height=self->GetHeight();
359 int width=self->GetWidth();
360
361 if (DATASIZE != width * height * 4) {
362 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
363 }
364 wxAlphaPixelData pixData(*self, wxPoint(0,0), wxSize(width, height));
365 if (! pixData) {
366 // raise an exception...
367 wxPyErr_SetString(PyExc_RuntimeError,
368 "Failed to gain raw access to bitmap data.");
369 return;
370 }
371
372 pixData.UseAlpha();
373 wxAlphaPixelData::Iterator p(pixData);
374 for (int y=0; y<height; y++) {
375 wxAlphaPixelData::Iterator rowStart = p;
376 for (int x=0; x<width; x++) {
377 byte a = data[3];
378 p.Red() = wxPy_premultiply(*(data++), a);
379 p.Green() = wxPy_premultiply(*(data++), a);
380 p.Blue() = wxPy_premultiply(*(data++), a);
381 p.Alpha() = a; data++;
382 ++p;
383 }
384 p = rowStart;
385 p.OffsetY(pixData, 1);
386 }
387 }
388 }
389
390
6c2dd16f 391 %pythoncode { def __nonzero__(self): return self.IsOk() }
b403cd65 392
8f514ab4
RD
393 // TODO: Should these just be removed since the C++ operators are
394 // gone? Or is using IsSameAs for wxPython ok?
b403cd65 395 %extend {
8f514ab4
RD
396 bool __eq__(const wxBitmap* other) { return other ? self->IsSameAs(*other) : false; }
397 bool __ne__(const wxBitmap* other) { return other ? !self->IsSameAs(*other) : true; }
b403cd65 398 }
0eae5d09
RD
399
400 %property(Depth, GetDepth, SetDepth, doc="See `GetDepth` and `SetDepth`");
401 %property(Height, GetHeight, SetHeight, doc="See `GetHeight` and `SetHeight`");
402 %property(Mask, GetMask, SetMask, doc="See `GetMask` and `SetMask`");
403 %property(Palette, GetPalette, doc="See `GetPalette`");
404 %property(Size, GetSize, SetSize, doc="See `GetSize` and `SetSize`");
405 %property(SubBitmap, GetSubBitmap, doc="See `GetSubBitmap`");
406 %property(Width, GetWidth, SetWidth, doc="See `GetWidth` and `SetWidth`");
407
d14a1e28
RD
408};
409
410
238ba802
RD
411//---------------------------------------------------------------------------
412// Factory functions for creating wxBitmaps from Python buffer objects. They
413// use the Abstract Pixel API to be able to set RGB and A bytes directly into
414// the wxBitmap's pixel buffer.
415
1d1972fc 416
238ba802
RD
417%newobject _BitmapFromBufferAlpha;
418%newobject _BitmapFromBuffer;
419%inline %{
420 wxBitmap* _BitmapFromBufferAlpha(int width, int height,
421 buffer data, int DATASIZE,
422 buffer alpha, int ALPHASIZE)
423 {
424 if (DATASIZE != width*height*3) {
425 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
426 return NULL;
427 }
428
429 if (ALPHASIZE != width*height) {
430 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
431 return NULL;
432 }
433
434 wxBitmap* bmp = new wxBitmap(width, height, 32);
c4caf81d
RD
435 wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
436 if (! pixData) {
238ba802
RD
437 // raise an exception...
438 wxPyErr_SetString(PyExc_RuntimeError,
439 "Failed to gain raw access to bitmap data.");
440 return NULL;
441 }
442
c4caf81d
RD
443 pixData.UseAlpha();
444 wxAlphaPixelData::Iterator p(pixData);
238ba802
RD
445 for (int y=0; y<height; y++) {
446 wxAlphaPixelData::Iterator rowStart = p;
447 for (int x=0; x<width; x++) {
1d1972fc
RD
448 byte a = *(alpha++);
449 p.Red() = wxPy_premultiply(*(data++), a);
450 p.Green() = wxPy_premultiply(*(data++), a);
451 p.Blue() = wxPy_premultiply(*(data++), a);
452 p.Alpha() = a;
238ba802
RD
453 ++p;
454 }
455 p = rowStart;
c4caf81d 456 p.OffsetY(pixData, 1);
238ba802
RD
457 }
458 return bmp;
459 }
460
461 wxBitmap* _BitmapFromBuffer(int width, int height, buffer data, int DATASIZE)
462 {
463 if (DATASIZE != width*height*3) {
464 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
465 return NULL;
466 }
467
468 wxBitmap* bmp = new wxBitmap(width, height, 24);
c4caf81d
RD
469 wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
470 if (! pixData) {
238ba802
RD
471 // raise an exception...
472 wxPyErr_SetString(PyExc_RuntimeError,
473 "Failed to gain raw access to bitmap data.");
474 return NULL;
475 }
476
c4caf81d 477 wxNativePixelData::Iterator p(pixData);
238ba802
RD
478 for (int y=0; y<height; y++) {
479 wxNativePixelData::Iterator rowStart = p;
480 for (int x=0; x<width; x++) {
481 p.Red() = *(data++);
482 p.Green() = *(data++);
483 p.Blue() = *(data++);
484 ++p;
485 }
486 p = rowStart;
c4caf81d 487 p.OffsetY(pixData, 1);
238ba802
RD
488 }
489 return bmp;
490 }
491%}
492
493
494%pythoncode {
495def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
496 """
497 Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
bf64693b
RD
498 parameter must be a Python object that implements the buffer
499 interface, such as a string, array, etc. The dataBuffer object is
500 expected to contain a series of RGB bytes and be width*height*3
501 bytes long. A buffer object can optionally be supplied for the
502 image's alpha channel data, and it is expected to be width*height
503 bytes long. On Windows the RGB values are 'premultiplied' by the
504 alpha values. (The other platforms do the multiplication
505 themselves.)
506
507 Unlike `wx.ImageFromBuffer` the bitmap created with this function
508 does not share the memory buffer with the buffer object. This is
509 because the native pixel buffer format varies on different
510 platforms, and so instead an efficient as possible copy of the
511 data is made from the buffer objects to the bitmap's native pixel
512 buffer. For direct access to a bitmap's pixel buffer see
513 `wx.NativePixelData` and `wx.AlphaPixelData`.
238ba802
RD
514
515 :see: `wx.Bitmap`, `wx.BitmapFromBufferRGBA`, `wx.NativePixelData`,
516 `wx.AlphaPixelData`, `wx.ImageFromBuffer`
517 """
238ba802
RD
518 if alphaBuffer is not None:
519 return _gdi_._BitmapFromBufferAlpha(width, height, dataBuffer, alphaBuffer)
520 else:
521 return _gdi_._BitmapFromBuffer(width, height, dataBuffer)
522}
523
524
525
526%newobject _BitmapFromBufferRGBA;
527%inline %{
777dffec 528 wxBitmap* _BitmapFromBufferRGBA(int width, int height, buffer data, int DATASIZE)
238ba802
RD
529 {
530 if (DATASIZE != width*height*4) {
531 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
532 return NULL;
533 }
534
535 wxBitmap* bmp = new wxBitmap(width, height, 32);
c4caf81d
RD
536 wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
537 if (! pixData) {
238ba802
RD
538 // raise an exception...
539 wxPyErr_SetString(PyExc_RuntimeError,
540 "Failed to gain raw access to bitmap data.");
541 return NULL;
542 }
777dffec 543
c4caf81d
RD
544 pixData.UseAlpha();
545 wxAlphaPixelData::Iterator p(pixData);
238ba802
RD
546 for (int y=0; y<height; y++) {
547 wxAlphaPixelData::Iterator rowStart = p;
548 for (int x=0; x<width; x++) {
1d1972fc
RD
549 byte a = data[3];
550 p.Red() = wxPy_premultiply(*(data++), a);
551 p.Green() = wxPy_premultiply(*(data++), a);
552 p.Blue() = wxPy_premultiply(*(data++), a);
553 p.Alpha() = a; data++;
238ba802
RD
554 ++p;
555 }
556 p = rowStart;
c4caf81d 557 p.OffsetY(pixData, 1);
238ba802
RD
558 }
559 return bmp;
560 }
561%}
562
563%pythoncode {
564def BitmapFromBufferRGBA(width, height, dataBuffer):
565 """
566 Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
bf64693b
RD
567 parameter must be a Python object that implements the buffer
568 interface, such as a string, array, etc. The dataBuffer object is
569 expected to contain a series of RGBA bytes (red, green, blue and
570 alpha) and be width*height*4 bytes long. On Windows the RGB
571 values are 'premultiplied' by the alpha values. (The other
572 platforms do the multiplication themselves.)
573
574 Unlike `wx.ImageFromBuffer` the bitmap created with this function
575 does not share the memory buffer with the buffer object. This is
576 because the native pixel buffer format varies on different
577 platforms, and so instead an efficient as possible copy of the
578 data is made from the buffer object to the bitmap's native pixel
579 buffer. For direct access to a bitmap's pixel buffer see
580 `wx.NativePixelData` and `wx.AlphaPixelData`.
238ba802
RD
581
582 :see: `wx.Bitmap`, `wx.BitmapFromBuffer`, `wx.NativePixelData`,
583 `wx.AlphaPixelData`, `wx.ImageFromBuffer`
584 """
238ba802
RD
585 return _gdi_._BitmapFromBufferRGBA(width, height, dataBuffer)
586}
587
588
777dffec
RD
589//---------------------------------------------------------------------------
590
591class wxPixelDataBase
592{
593public:
594 // origin of the rectangular region we represent
595 wxPoint GetOrigin() const { return m_ptOrigin; }
596
597 // width and height of the region we represent
598 int GetWidth() const { return m_width; }
599 int GetHeight() const { return m_height; }
600
601 wxSize GetSize() const { return wxSize(m_width, m_height); }
602
603 // the distance between two rows
604 int GetRowStride() const { return m_stride; }
605
7012bb9f
RD
606 %property(Height, GetHeight, doc="See `GetHeight`");
607 %property(Origin, GetOrigin, doc="See `GetOrigin`");
608 %property(RowStride, GetRowStride, doc="See `GetRowStride`");
609 %property(Size, GetSize, doc="See `GetSize`");
610 %property(Width, GetWidth, doc="See `GetWidth`");
777dffec
RD
611};
612
613
97c7d01d
RD
614// Both wxNativePixelData and wxAlphaPixelData have the same interface, so
615// make a macro to declare them both.
777dffec
RD
616
617%define PIXELDATA(PixelData)
618%{
97c7d01d 619 typedef PixelData##::Iterator PixelData##_Accessor;
777dffec 620%}
97c7d01d 621class PixelData##_Accessor;
777dffec
RD
622class PixelData : public wxPixelDataBase
623{
624public:
625 %nokwargs PixelData;
626
627 PixelData(wxBitmap& bmp);
628 PixelData(wxBitmap& bmp, const wxRect& rect);
629 PixelData(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz);
630
631 ~PixelData();
632
97c7d01d
RD
633 PixelData##_Accessor GetPixels() const;
634 void UseAlpha();
635
777dffec
RD
636 %extend {
637 bool __nonzero__() { return self->operator bool(); }
638 }
639
97c7d01d
RD
640 %pythoncode {
641 def __iter__(self):
97c7d01d 642 """
9bcdb631
RD
643 Create and return an iterator object for this pixel data
644 object. (It's really a generator but I won't tell if you
645 don't tell.)
97c7d01d 646 """
9bcdb631
RD
647 width = self.GetWidth()
648 height = self.GetHeight()
649 pixels = self.GetPixels()
650
651 # This class is a facade over the pixels object (using the one
652 # in the enclosing scope) that only allows Get() and Set() to
653 # be called.
654 class PixelFacade(object):
97c7d01d 655 def Get(self):
9bcdb631
RD
656 return pixels.Get()
657 def Set(self, *args, **kw):
658 return pixels.Set(*args, **kw)
659 def __str__(self):
660 return str(self.Get())
661 def __repr__(self):
662 return 'pixel(%d,%d): %s' % (x,y,self.Get())
663 X = property(lambda self: x)
664 Y = property(lambda self: y)
665
666 pf = PixelFacade()
667 for y in xrange(height):
668 for x in xrange(width):
669 # We always generate the same pf instance, but it
670 # accesses the pixels object which we use to iterate
671 # over the pixel buffer.
672 yield pf
673 pixels.nextPixel()
674 pixels.MoveTo(self, 0, y)
97c7d01d 675 }
0eae5d09
RD
676
677 %property(Pixels, GetPixels, doc="See `GetPixels`");
777dffec
RD
678};
679
680
c4caf81d 681
97c7d01d 682class PixelData##_Accessor
777dffec
RD
683{
684public:
97c7d01d 685 %nokwargs PixelData##_Accessor;
777dffec 686
97c7d01d
RD
687 PixelData##_Accessor(PixelData& data);
688 PixelData##_Accessor(wxBitmap& bmp, PixelData& data);
689 PixelData##_Accessor();
777dffec 690
97c7d01d 691 ~PixelData##_Accessor();
777dffec
RD
692
693 void Reset(const PixelData& data);
694 bool IsOk() const;
695
696 %extend {
97c7d01d 697 // PixelData##_Accessor& nextPixel() { return ++(*self); }
777dffec
RD
698 void nextPixel() { ++(*self); }
699 }
700
701 void Offset(const PixelData& data, int x, int y);
702 void OffsetX(const PixelData& data, int x);
703 void OffsetY(const PixelData& data, int y);
704 void MoveTo(const PixelData& data, int x, int y);
705
9bcdb631
RD
706// NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha
707// functions because I can't hide the premultiplying needed on wxMSW
708// if only the individual components are wrapped, plus it would mean 3
709// or 4 trips per pixel from Python to C++ instead of just one.
710// Instead I've added the Set and Get functions and put the
711// premultiplying in there.
c4caf81d
RD
712
713// %extend {
714// byte _get_Red() { return self->Red(); }
715// byte _get_Green() { return self->Green(); }
716// byte _get_Blue() { return self->Blue(); }
717
718// void _set_Red(byte val) { self->Red() = val; }
719// void _set_Green(byte val) { self->Green() = val; }
720// void _set_Blue(byte val) { self->Blue() = val; }
721// }
722
723// %pythoncode {
724// Red = property(_get_Red, _set_Red)
725// Green = property(_get_Green, _set_Green)
726// Blue = property(_get_Blue, _set_Blue)
727// }
777dffec
RD
728};
729%enddef
730
731
97c7d01d
RD
732%pythonAppend wxAlphaPixelData::wxAlphaPixelData "self.UseAlpha()"
733
734// Make the classes
777dffec
RD
735PIXELDATA(wxNativePixelData)
736PIXELDATA(wxAlphaPixelData)
737
738
739// Add in a few things that are different between the wxNativePixelData and
97c7d01d
RD
740// wxAlphaPixelData and the iterator classes and so are not included in our
741// macro...
777dffec 742
97c7d01d 743%extend wxNativePixelData_Accessor {
777dffec
RD
744 void Set(byte red, byte green, byte blue) {
745 self->Red() = red;
746 self->Green() = green;
747 self->Blue() = blue;
748 }
749
750 PyObject* Get() {
751 PyObject* rv = PyTuple_New(3);
752 PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red()));
753 PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green()));
754 PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue()));
755 return rv;
756 }
757}
758
97c7d01d 759%extend wxAlphaPixelData_Accessor {
c4caf81d
RD
760// byte _get_Alpha() { return self->Alpha(); }
761// void _set_Alpha(byte val) { self->Alpha() = val; }
777dffec 762
c4caf81d
RD
763// %pythoncode {
764// Alpha = property(_get_Alpha, _set_Alpha)
765// }
777dffec
RD
766
767 void Set(byte red, byte green, byte blue, byte alpha) {
c4caf81d
RD
768 self->Red() = wxPy_premultiply(red, alpha);
769 self->Green() = wxPy_premultiply(green, alpha);
770 self->Blue() = wxPy_premultiply(blue, alpha);
777dffec
RD
771 self->Alpha() = alpha;
772 }
773
774 PyObject* Get() {
775 PyObject* rv = PyTuple_New(4);
c4caf81d
RD
776 int red = self->Red();
777 int green = self->Green();
778 int blue = self->Blue();
779 int alpha = self->Alpha();
780
781 PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red, alpha) ));
782 PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
783 PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue, alpha) ));
784 PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha ));
777dffec
RD
785 return rv;
786 }
787}
788
97c7d01d 789
d14a1e28
RD
790//---------------------------------------------------------------------------
791
1e0c8722 792DocStr(wxMask,
dce2bd22
RD
793"This class encapsulates a monochrome mask bitmap, where the masked
794area is black and the unmasked area is white. When associated with a
795bitmap and drawn in a device context, the unmasked area of the bitmap
796will be drawn, and the masked area will not be drawn.
797
798A mask may be associated with a `wx.Bitmap`. It is used in
799`wx.DC.DrawBitmap` or `wx.DC.Blit` when the source device context is a
800`wx.MemoryDC` with a `wx.Bitmap` selected into it that contains a
d07d2bc9 801mask.", "");
1e0c8722 802
ab1f7d2a
RD
803MustHaveApp(wxMask);
804
d14a1e28
RD
805class wxMask : public wxObject {
806public:
1e0c8722 807
0482c494 808 DocStr(wxMask,
dce2bd22
RD
809 "Constructs a mask from a `wx.Bitmap` and a `wx.Colour` in that bitmap
810that indicates the transparent portions of the mask. In other words,
811the pixels in ``bitmap`` that match ``colour`` will be the transparent
812portions of the mask. If no ``colour`` or an invalid ``colour`` is
813passed then BLACK is used.
814
d07d2bc9 815:see: `wx.Bitmap`, `wx.Colour`", "");
0482c494
RD
816
817 %extend {
818 wxMask(const wxBitmap& bitmap, const wxColour& colour = wxNullColour) {
6c2dd16f 819 if ( !colour.IsOk() )
0482c494
RD
820 return new wxMask(bitmap, *wxBLACK);
821 else
822 return new wxMask(bitmap, colour);
823 }
824 }
d14a1e28 825
c5633576 826 ~wxMask();
d14a1e28
RD
827};
828
dce2bd22 829%pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") }
0482c494 830
d14a1e28
RD
831//---------------------------------------------------------------------------
832//---------------------------------------------------------------------------
0f82eb02
RD
833
834// Turn GIL acquisition back on.
777dffec 835%threadWrapperOn