]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/_bitmap.i
try to deal more gracefully (than simply not showing anything at all) with invalid...
[wxWidgets.git] / wxPython / src / _bitmap.i
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
15 %{
16 #include <wx/rawbmp.h>
17 %}
18
19 //---------------------------------------------------------------------------
20
21 %{
22 #include <wx/image.h>
23
24 static char** ConvertListOfStrings(PyObject* listOfStrings) {
25 char** cArray = NULL;
26 int count;
27
28 if (!PyList_Check(listOfStrings)) {
29 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
30 return NULL;
31 }
32 count = PyList_Size(listOfStrings);
33 cArray = new char*[count];
34
35 for(int x=0; x<count; x++) {
36 // TODO: Need some validation and error checking here
37 cArray[x] = PyString_AsString(PyList_GET_ITEM(listOfStrings, x));
38 }
39 return cArray;
40 }
41
42 %}
43
44 //---------------------------------------------------------------------------
45
46 // TODO: When the API stabalizes and is available on other platforms, add
47 // wrappers for the new wxBitmap, wxRawBitmap, wxDIB stuff...
48
49 DocStr(wxBitmap,
50 "The wx.Bitmap class encapsulates the concept of a platform-dependent
51 bitmap. It can be either monochrome or colour, and either loaded from
52 a file or created dynamically. A bitmap can be selected into a memory
53 device context (instance of `wx.MemoryDC`). This enables the bitmap to
54 be copied to a window or memory device context using `wx.DC.Blit`, or
55 to be used as a drawing surface.", "
56
57 The BMP and XMP image file formats are supported on all platforms by
58 wx.Bitmap. Other formats are automatically loaded by `wx.Image` and
59 converted to a wx.Bitmap, so any image file format supported by
60 `wx.Image` can be used.
61
62 :todo: Add wrappers and support for raw bitmap data access. Can this
63 be be put into Python without losing the speed benefits of the
64 teplates and iterators in rawbmp.h?
65
66 :todo: Find a way to do very efficient PIL Image <--> wx.Bitmap
67 converstions.
68
69 :see: `wx.EmptyBitmap`, `wx.BitmapFromIcon`, `wx.BitmapFromImage`,
70 `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, `wx.BitmapFromBuffer`,
71 `wx.BitmapFromBufferRGBA`, `wx.Image`
72 ");
73
74
75 MustHaveApp(wxBitmap);
76
77 class wxBitmap : public wxGDIObject
78 {
79 public:
80 DocCtorStr(
81 wxBitmap(const wxString& name, wxBitmapType type=wxBITMAP_TYPE_ANY),
82 "Loads a bitmap from a file.",
83 "
84 :param name: Name of the file to load the bitmap from.
85 :param type: The type of image to expect. Can be one of the following
86 constants (assuming that the neccessary `wx.Image` handlers are
87 loaded):
88
89 * wx.BITMAP_TYPE_ANY
90 * wx.BITMAP_TYPE_BMP
91 * wx.BITMAP_TYPE_ICO
92 * wx.BITMAP_TYPE_CUR
93 * wx.BITMAP_TYPE_XBM
94 * wx.BITMAP_TYPE_XPM
95 * wx.BITMAP_TYPE_TIF
96 * wx.BITMAP_TYPE_GIF
97 * wx.BITMAP_TYPE_PNG
98 * wx.BITMAP_TYPE_JPEG
99 * wx.BITMAP_TYPE_PNM
100 * wx.BITMAP_TYPE_PCX
101 * wx.BITMAP_TYPE_PICT
102 * wx.BITMAP_TYPE_ICON
103 * wx.BITMAP_TYPE_ANI
104 * wx.BITMAP_TYPE_IFF
105
106 :see: Alternate constructors `wx.EmptyBitmap`, `wx.BitmapFromIcon`,
107 `wx.BitmapFromImage`, `wx.BitmapFromXPMData`,
108 `wx.BitmapFromBits`
109 ");
110
111 ~wxBitmap();
112
113 DocCtorStrName(
114 wxBitmap(int width, int height, int depth=-1),
115 "Creates a new bitmap of the given size. A depth of -1 indicates the
116 depth of the current screen or visual. Some platforms only support 1
117 for monochrome and -1 for the current display depth.", "",
118 EmptyBitmap);
119
120 DocCtorStrName(
121 wxBitmap(const wxIcon& icon),
122 "Create a new bitmap from a `wx.Icon` object.", "",
123 BitmapFromIcon);
124
125 DocCtorStrName(
126 wxBitmap(const wxImage& image, int depth=-1),
127 "Creates bitmap object from a `wx.Image`. This has to be done to
128 actually display a `wx.Image` as you cannot draw an image directly on
129 a window. The resulting bitmap will use the provided colour depth (or
130 that of the current screen colour depth if depth is -1) which entails
131 that a colour reduction may have to take place.", "",
132 BitmapFromImage);
133
134
135 %extend {
136 %RenameDocCtor(
137 BitmapFromXPMData,
138 "Construct a Bitmap from a list of strings formatted as XPM data.", "",
139 wxBitmap(PyObject* listOfStrings))
140 {
141 char** cArray = NULL;
142 wxBitmap* bmp;
143
144 cArray = ConvertListOfStrings(listOfStrings);
145 if (! cArray)
146 return NULL;
147 bmp = new wxBitmap(cArray);
148 delete [] cArray;
149 return bmp;
150 }
151
152
153 %RenameDocCtor(
154 BitmapFromBits,
155 "Creates a bitmap from an array of bits. You should only use this
156 function for monochrome bitmaps (depth 1) in portable programs: in
157 this case the bits parameter should contain an XBM image. For other
158 bit depths, the behaviour is platform dependent.", "",
159 wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
160 {
161 char* buf;
162 Py_ssize_t length;
163 PyString_AsStringAndSize(bits, &buf, &length);
164 return new wxBitmap(buf, width, height, depth);
165 }
166 }
167
168
169 // wxGDIImage methods
170 #ifdef __WXMSW__
171 long GetHandle();
172 %extend {
173 void SetHandle(long handle) { self->SetHandle((WXHANDLE)handle); }
174 }
175 #endif
176
177 bool Ok();
178
179 DocDeclStr(
180 int , GetWidth(),
181 "Gets the width of the bitmap in pixels.", "");
182
183
184 DocDeclStr(
185 int , GetHeight(),
186 "Gets the height of the bitmap in pixels.", "");
187
188
189 DocDeclStr(
190 int , GetDepth(),
191 "Gets the colour depth of the bitmap. A value of 1 indicates a
192 monochrome bitmap.", "");
193
194
195
196 %extend {
197 DocStr(GetSize, "Get the size of the bitmap.", "");
198 wxSize GetSize() {
199 wxSize size(self->GetWidth(), self->GetHeight());
200 return size;
201 }
202 }
203
204
205 DocDeclStr(
206 virtual wxImage , ConvertToImage() const,
207 "Creates a platform-independent image from a platform-dependent
208 bitmap. This preserves mask information so that bitmaps and images can
209 be converted back and forth without loss in that respect.", "");
210
211
212
213 DocDeclStr(
214 virtual wxMask* , GetMask() const,
215 "Gets the associated mask (if any) which may have been loaded from a
216 file or explpicitly set for the bitmap.
217
218 :see: `SetMask`, `wx.Mask`
219 ", "");
220
221 // MSW only? wxBitmap GetMaskBitmap() const;
222
223 %disownarg(wxMask*);
224 DocDeclStr(
225 virtual void , SetMask(wxMask* mask),
226 "Sets the mask for this bitmap.
227
228 :see: `GetMask`, `wx.Mask`
229 ", "");
230 %cleardisown(wxMask*);
231
232 %extend {
233 DocStr(SetMaskColour,
234 "Create a Mask based on a specified colour in the Bitmap.", "");
235 void SetMaskColour(const wxColour& colour) {
236 wxMask *mask = new wxMask(*self, colour);
237 self->SetMask(mask);
238 }
239 }
240
241
242 DocDeclStr(
243 virtual wxBitmap , GetSubBitmap(const wxRect& rect) const,
244 "Returns a sub-bitmap of the current one as long as the rect belongs
245 entirely to the bitmap. This function preserves bit depth and mask
246 information.", "");
247
248
249 DocDeclStr(
250 virtual bool , SaveFile(const wxString &name, wxBitmapType type,
251 wxPalette *palette = NULL),
252 "Saves a bitmap in the named file. See `__init__` for a description of
253 the ``type`` parameter.", "");
254
255
256 DocDeclStr(
257 virtual bool , LoadFile(const wxString &name, wxBitmapType type),
258 "Loads a bitmap from a file. See `__init__` for a description of the
259 ``type`` parameter.", "");
260
261
262
263 virtual wxPalette *GetPalette() const;
264 #ifdef __WXMSW__
265 virtual void SetPalette(const wxPalette& palette);
266 #endif
267
268
269 virtual bool CopyFromIcon(const wxIcon& icon);
270
271 DocDeclStr(
272 virtual void , SetHeight(int height),
273 "Set the height property (does not affect the existing bitmap data).", "");
274
275
276 DocDeclStr(
277 virtual void , SetWidth(int width),
278 "Set the width property (does not affect the existing bitmap data).", "");
279
280
281 DocDeclStr(
282 virtual void , SetDepth(int depth),
283 "Set the depth property (does not affect the existing bitmap data).", "");
284
285
286 %extend {
287 DocStr(SetSize, "Set the bitmap size (does not affect the existing bitmap data).", "");
288 void SetSize(const wxSize& size) {
289 self->SetWidth(size.x);
290 self->SetHeight(size.y);
291 }
292 }
293
294 #ifdef __WXMSW__
295 bool CopyFromCursor(const wxCursor& cursor);
296
297 // WXWIN_COMPATIBILITY_2_4
298 #if 0
299 int GetQuality();
300 void SetQuality(int q);
301 %pythoncode { GetQuality = wx._deprecated(GetQuality) }
302 %pythoncode { SetQuality = wx._deprecated(SetQuality) }
303 #endif
304 #endif
305
306 %pythoncode { def __nonzero__(self): return self.Ok() }
307
308 %extend {
309 bool __eq__(const wxBitmap* other) { return other ? (*self == *other) : false; }
310 bool __ne__(const wxBitmap* other) { return other ? (*self != *other) : true; }
311 }
312 };
313
314
315 //---------------------------------------------------------------------------
316 // Factory functions for creating wxBitmaps from Python buffer objects. They
317 // use the Abstract Pixel API to be able to set RGB and A bytes directly into
318 // the wxBitmap's pixel buffer.
319
320 %{
321 // See http://tinyurl.com/e5adr for what premultiplying alpha means. It
322 // appears to me that the other platforms are already doing it, so I'll just
323 // automatically do it for wxMSW here.
324 #ifdef __WXMSW__
325 #define wxPy_premultiply(p, a) ((p) * (a) / 256)
326 #else
327 #define wxPy_premultiply(p, a) (p)
328 #endif
329 %}
330
331
332 %newobject _BitmapFromBufferAlpha;
333 %newobject _BitmapFromBuffer;
334 %inline %{
335 wxBitmap* _BitmapFromBufferAlpha(int width, int height,
336 buffer data, int DATASIZE,
337 buffer alpha, int ALPHASIZE)
338 {
339 if (DATASIZE != width*height*3) {
340 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
341 return NULL;
342 }
343
344 if (ALPHASIZE != width*height) {
345 wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
346 return NULL;
347 }
348
349 wxBitmap* bmp = new wxBitmap(width, height, 32);
350 wxAlphaPixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height));
351 if (! pixels) {
352 // raise an exception...
353 wxPyErr_SetString(PyExc_RuntimeError,
354 "Failed to gain raw access to bitmap data.");
355 return NULL;
356 }
357
358 pixels.UseAlpha();
359 wxAlphaPixelData::Iterator p(pixels);
360 for (int y=0; y<height; y++) {
361 wxAlphaPixelData::Iterator rowStart = p;
362 for (int x=0; x<width; x++) {
363 byte a = *(alpha++);
364 p.Red() = wxPy_premultiply(*(data++), a);
365 p.Green() = wxPy_premultiply(*(data++), a);
366 p.Blue() = wxPy_premultiply(*(data++), a);
367 p.Alpha() = a;
368 ++p;
369 }
370 p = rowStart;
371 p.OffsetY(pixels, 1);
372 }
373 return bmp;
374 }
375
376 wxBitmap* _BitmapFromBuffer(int width, int height, buffer data, int DATASIZE)
377 {
378 if (DATASIZE != width*height*3) {
379 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
380 return NULL;
381 }
382
383 wxBitmap* bmp = new wxBitmap(width, height, 24);
384 wxNativePixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height));
385 if (! pixels) {
386 // raise an exception...
387 wxPyErr_SetString(PyExc_RuntimeError,
388 "Failed to gain raw access to bitmap data.");
389 return NULL;
390 }
391
392 wxNativePixelData::Iterator p(pixels);
393 for (int y=0; y<height; y++) {
394 wxNativePixelData::Iterator rowStart = p;
395 for (int x=0; x<width; x++) {
396 p.Red() = *(data++);
397 p.Green() = *(data++);
398 p.Blue() = *(data++);
399 ++p;
400 }
401 p = rowStart;
402 p.OffsetY(pixels, 1);
403 }
404 return bmp;
405 }
406 %}
407
408
409 %pythoncode {
410 def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
411 """
412 Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
413 parameter must be a Python object that implements the buffer interface, or
414 is convertable to a buffer object, such as a string, array, etc. The
415 dataBuffer object is expected to contain a series of RGB bytes and be
416 width*height*3 bytes long. A buffer object can optionally be supplied for
417 the image's alpha channel data, and it is expected to be width*height
418 bytes long. On Windows the RGB values are 'premultiplied' by the alpha
419 values. (The other platforms appear to already be premultiplying the
420 alpha.)
421
422 Unlike `wx.ImageFromBuffer` the bitmap created with this function does not
423 share the memory buffer with the buffer object. This is because the
424 native pixel buffer format varies on different platforms, and so instead
425 an efficient as possible copy of the data is made from the buffer objects
426 to the bitmap's native pixel buffer. For direct access to a bitmap's
427 pixel buffer see `wx.NativePixelData` and `wx.AlphaPixelData`.
428
429 :see: `wx.Bitmap`, `wx.BitmapFromBufferRGBA`, `wx.NativePixelData`,
430 `wx.AlphaPixelData`, `wx.ImageFromBuffer`
431 """
432 if not isinstance(dataBuffer, buffer):
433 dataBuffer = buffer(dataBuffer)
434 if alphaBuffer is not None and not isinstance(alphaBuffer, buffer):
435 alphaBuffer = buffer(alphaBuffer)
436 if alphaBuffer is not None:
437 return _gdi_._BitmapFromBufferAlpha(width, height, dataBuffer, alphaBuffer)
438 else:
439 return _gdi_._BitmapFromBuffer(width, height, dataBuffer)
440 }
441
442
443
444 %newobject _BitmapFromBufferRGBA;
445 %inline %{
446 wxBitmap* _BitmapFromBufferRGBA(int width, int height, buffer data, int DATASIZE)
447 {
448 if (DATASIZE != width*height*4) {
449 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
450 return NULL;
451 }
452
453 wxBitmap* bmp = new wxBitmap(width, height, 32);
454 wxAlphaPixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height));
455 if (! pixels) {
456 // raise an exception...
457 wxPyErr_SetString(PyExc_RuntimeError,
458 "Failed to gain raw access to bitmap data.");
459 return NULL;
460 }
461
462 pixels.UseAlpha();
463 wxAlphaPixelData::Iterator p(pixels);
464 for (int y=0; y<height; y++) {
465 wxAlphaPixelData::Iterator rowStart = p;
466 for (int x=0; x<width; x++) {
467 byte a = data[3];
468 p.Red() = wxPy_premultiply(*(data++), a);
469 p.Green() = wxPy_premultiply(*(data++), a);
470 p.Blue() = wxPy_premultiply(*(data++), a);
471 p.Alpha() = a; data++;
472 ++p;
473 }
474 p = rowStart;
475 p.OffsetY(pixels, 1);
476 }
477 return bmp;
478 }
479 %}
480
481 %pythoncode {
482 def BitmapFromBufferRGBA(width, height, dataBuffer):
483 """
484 Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
485 parameter must be a Python object that implements the buffer interface, or
486 is convertable to a buffer object, such as a string, array, etc. The
487 dataBuffer object is expected to contain a series of RGBA bytes (red,
488 green, blue and alpha) and be width*height*4 bytes long. On Windows the
489 RGB values are 'premultiplied' by the alpha values. (The other platforms
490 appear to already be premultiplying the alpha.)
491
492 Unlike `wx.ImageFromBuffer` the bitmap created with this function does not
493 share the memory buffer with the buffer object. This is because the
494 native pixel buffer format varies on different platforms, and so instead
495 an efficient as possible copy of the data is made from the buffer object
496 to the bitmap's native pixel buffer. For direct access to a bitmap's
497 pixel buffer see `wx.NativePixelData` and `wx.AlphaPixelData`.
498
499 :see: `wx.Bitmap`, `wx.BitmapFromBuffer`, `wx.NativePixelData`,
500 `wx.AlphaPixelData`, `wx.ImageFromBuffer`
501 """
502 if not isinstance(dataBuffer, buffer):
503 dataBuffer = buffer(dataBuffer)
504 return _gdi_._BitmapFromBufferRGBA(width, height, dataBuffer)
505 }
506
507
508 //---------------------------------------------------------------------------
509
510 DocStr(wxMask,
511 "This class encapsulates a monochrome mask bitmap, where the masked
512 area is black and the unmasked area is white. When associated with a
513 bitmap and drawn in a device context, the unmasked area of the bitmap
514 will be drawn, and the masked area will not be drawn.
515
516 A mask may be associated with a `wx.Bitmap`. It is used in
517 `wx.DC.DrawBitmap` or `wx.DC.Blit` when the source device context is a
518 `wx.MemoryDC` with a `wx.Bitmap` selected into it that contains a
519 mask.", "");
520
521 MustHaveApp(wxMask);
522
523 class wxMask : public wxObject {
524 public:
525
526 DocStr(wxMask,
527 "Constructs a mask from a `wx.Bitmap` and a `wx.Colour` in that bitmap
528 that indicates the transparent portions of the mask. In other words,
529 the pixels in ``bitmap`` that match ``colour`` will be the transparent
530 portions of the mask. If no ``colour`` or an invalid ``colour`` is
531 passed then BLACK is used.
532
533 :see: `wx.Bitmap`, `wx.Colour`", "");
534
535 %extend {
536 wxMask(const wxBitmap& bitmap, const wxColour& colour = wxNullColour) {
537 if ( !colour.Ok() )
538 return new wxMask(bitmap, *wxBLACK);
539 else
540 return new wxMask(bitmap, colour);
541 }
542 }
543
544 ~wxMask();
545 };
546
547 %pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") }
548
549 //---------------------------------------------------------------------------
550 //---------------------------------------------------------------------------