X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/777dffec694eae7231e4133e5dc6bbca78045f29..f27895d28959ea2d8ddf4c2c5b5ad3958bcaadb4:/wxPython/src/_bitmap.i diff --git a/wxPython/src/_bitmap.i b/wxPython/src/_bitmap.i index 2f018e31e9..1316e7cd35 100644 --- a/wxPython/src/_bitmap.i +++ b/wxPython/src/_bitmap.i @@ -17,11 +17,28 @@ %} -// Turn off the aquisition of the Global Interpreter Lock for this file +// Turn off the aquisition of the Global Interpreter Lock for the classes and +// functions in this file %threadWrapperOff //--------------------------------------------------------------------------- +%{ +// See http://tinyurl.com/e5adr for what premultiplying alpha means. It +// appears to me that the other platforms are already doing it, so I'll just +// automatically do it for wxMSW here. +#ifdef __WXMSW__ +#define wxPy_premultiply(p, a) ((p) * (a) / 0xff) +#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p)) +#else +#define wxPy_premultiply(p, a) (p) +#define wxPy_unpremultiply(p, a) (p) +#endif +%} + +//--------------------------------------------------------------------------- + + %{ #include @@ -108,8 +125,8 @@ public: * wx.BITMAP_TYPE_IFF :see: Alternate constructors `wx.EmptyBitmap`, `wx.BitmapFromIcon`, - `wx.BitmapFromImage`, `wx.BitmapFromXPMData`, - `wx.BitmapFromBits` + `wx.BitmapFromImage`, `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, + `wx.BitmapFromBuffer`, `wx.BitmapFromBufferRGBA`, "); ~wxBitmap(); @@ -178,8 +195,9 @@ bit depths, the behaviour is platform dependent.", "", } #endif - bool Ok(); - + bool IsOk(); + %pythoncode { Ok = IsOk } + DocDeclStr( int , GetWidth(), "Gets the width of the bitmap in pixels.", ""); @@ -213,7 +231,6 @@ bitmap. This preserves mask information so that bitmaps and images can be converted back and forth without loss in that respect.", ""); - DocDeclStr( virtual wxMask* , GetMask() const, "Gets the associated mask (if any) which may have been loaded from a @@ -297,22 +314,97 @@ the ``type`` parameter.", ""); #ifdef __WXMSW__ bool CopyFromCursor(const wxCursor& cursor); - -// WXWIN_COMPATIBILITY_2_4 - #if 0 - int GetQuality(); - void SetQuality(int q); - %pythoncode { GetQuality = wx._deprecated(GetQuality) } - %pythoncode { SetQuality = wx._deprecated(SetQuality) } - #endif #endif - %pythoncode { def __nonzero__(self): return self.Ok() } + %extend { + DocStr(CopyFromBuffer, + "Copy data from a RGB buffer object to replace the bitmap pixel data. +See `wxBitmapFromBuffer` for more details.", ""); + void CopyFromBuffer(buffer data, int DATASIZE) + { + int height=self->GetHeight(); + int width=self->GetWidth(); + + if (DATASIZE != width * height * 3) { + wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size."); + } + wxNativePixelData pixData(*self, wxPoint(0,0), wxSize(width, height)); + if (! pixData) { + // raise an exception... + wxPyErr_SetString(PyExc_RuntimeError, + "Failed to gain raw access to bitmap data."); + return; + } + + wxNativePixelData::Iterator p(pixData); + for (int y=0; yGetHeight(); + int width=self->GetWidth(); + + if (DATASIZE != width * height * 4) { + wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size."); + } + wxAlphaPixelData pixData(*self, wxPoint(0,0), wxSize(width, height)); + if (! pixData) { + // raise an exception... + wxPyErr_SetString(PyExc_RuntimeError, + "Failed to gain raw access to bitmap data."); + return; + } + + pixData.UseAlpha(); + wxAlphaPixelData::Iterator p(pixData); + for (int y=0; yIsSameAs(*other) : false; } + bool __ne__(const wxBitmap* other) { return other ? !self->IsSameAs(*other) : true; } } + + %property(Depth, GetDepth, SetDepth, doc="See `GetDepth` and `SetDepth`"); + %property(Height, GetHeight, SetHeight, doc="See `GetHeight` and `SetHeight`"); + %property(Mask, GetMask, SetMask, doc="See `GetMask` and `SetMask`"); + %property(Palette, GetPalette, doc="See `GetPalette`"); + %property(Size, GetSize, SetSize, doc="See `GetSize` and `SetSize`"); + %property(SubBitmap, GetSubBitmap, doc="See `GetSubBitmap`"); + %property(Width, GetWidth, SetWidth, doc="See `GetWidth` and `SetWidth`"); + }; @@ -321,17 +413,6 @@ the ``type`` parameter.", ""); // use the Abstract Pixel API to be able to set RGB and A bytes directly into // the wxBitmap's pixel buffer. -%{ -// See http://tinyurl.com/e5adr for what premultiplying alpha means. It -// appears to me that the other platforms are already doing it, so I'll just -// automatically do it for wxMSW here. -#ifdef __WXMSW__ -#define wxPy_premultiply(p, a) ((p) * (a) / 256) -#else -#define wxPy_premultiply(p, a) (p) -#endif -%} - %newobject _BitmapFromBufferAlpha; %newobject _BitmapFromBuffer; @@ -351,16 +432,16 @@ the ``type`` parameter.", ""); } wxBitmap* bmp = new wxBitmap(width, height, 32); - wxAlphaPixelData pixels(*bmp, wxPoint(0,0), wxSize(width,height)); - if (! pixels) { + wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height)); + if (! pixData) { // raise an exception... wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data."); return NULL; } - pixels.UseAlpha(); - wxAlphaPixelData::Iterator p(pixels); + pixData.UseAlpha(); + wxAlphaPixelData::Iterator p(pixData); for (int y=0; yoperator bool(); } } - PixelData##_Iterator GetPixels() const; - void UseAlpha(); + %pythoncode { + def __iter__(self): + """ + Create and return an iterator object for this pixel data + object. (It's really a generator but I won't tell if you + don't tell.) + """ + width = self.GetWidth() + height = self.GetHeight() + pixels = self.GetPixels() + + # This class is a facade over the pixels object (using the one + # in the enclosing scope) that only allows Get() and Set() to + # be called. + class PixelFacade(object): + def Get(self): + return pixels.Get() + def Set(self, *args, **kw): + return pixels.Set(*args, **kw) + def __str__(self): + return str(self.Get()) + def __repr__(self): + return 'pixel(%d,%d): %s' % (x,y,self.Get()) + X = property(lambda self: x) + Y = property(lambda self: y) + + pf = PixelFacade() + for y in xrange(height): + for x in xrange(width): + # We always generate the same pf instance, but it + # accesses the pixels object which we use to iterate + # over the pixel buffer. + yield pf + pixels.nextPixel() + pixels.MoveTo(self, 0, y) + } + + %property(Pixels, GetPixels, doc="See `GetPixels`"); }; -class PixelData##_Iterator + +class PixelData##_Accessor { public: - %nokwargs PixelData##_Iterator; + %nokwargs PixelData##_Accessor; - PixelData##_Iterator(PixelData& data); - PixelData##_Iterator(wxBitmap& bmp, PixelData& data); - PixelData##_Iterator(); + PixelData##_Accessor(PixelData& data); + PixelData##_Accessor(wxBitmap& bmp, PixelData& data); + PixelData##_Accessor(); - ~PixelData##_Iterator(); + ~PixelData##_Accessor(); void Reset(const PixelData& data); bool IsOk() const; %extend { - // PixelData##_Iterator& nextPixel() { return ++(*self); } + // PixelData##_Accessor& nextPixel() { return ++(*self); } void nextPixel() { ++(*self); } } @@ -579,34 +703,44 @@ public: void OffsetY(const PixelData& data, int y); void MoveTo(const PixelData& data, int x, int y); - %extend { - byte _get_Red() { return self->Red(); } - byte _get_Green() { return self->Green(); } - byte _get_Blue() { return self->Blue(); } - - void _set_Red(byte val) { self->Red() = val; } - void _set_Green(byte val) { self->Green() = val; } - void _set_Blue(byte val) { self->Blue() = val; } - } - - %pythoncode { - Red = property(_get_Red, _set_Red) - Green = property(_get_Green, _set_Green) - Blue = property(_get_Blue, _set_Blue) - } - +// NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha +// functions because I can't hide the premultiplying needed on wxMSW +// if only the individual components are wrapped, plus it would mean 3 +// or 4 trips per pixel from Python to C++ instead of just one. +// Instead I've added the Set and Get functions and put the +// premultiplying in there. + +// %extend { +// byte _get_Red() { return self->Red(); } +// byte _get_Green() { return self->Green(); } +// byte _get_Blue() { return self->Blue(); } + +// void _set_Red(byte val) { self->Red() = val; } +// void _set_Green(byte val) { self->Green() = val; } +// void _set_Blue(byte val) { self->Blue() = val; } +// } + +// %pythoncode { +// Red = property(_get_Red, _set_Red) +// Green = property(_get_Green, _set_Green) +// Blue = property(_get_Blue, _set_Blue) +// } }; %enddef +%pythonAppend wxAlphaPixelData::wxAlphaPixelData "self.UseAlpha()" + +// Make the classes PIXELDATA(wxNativePixelData) PIXELDATA(wxAlphaPixelData) // Add in a few things that are different between the wxNativePixelData and -// wxAlphaPixelData iterators and so are not included in our macro... +// wxAlphaPixelData and the iterator classes and so are not included in our +// macro... -%extend wxNativePixelData_Iterator { +%extend wxNativePixelData_Accessor { void Set(byte red, byte green, byte blue) { self->Red() = red; self->Green() = green; @@ -622,31 +756,37 @@ PIXELDATA(wxAlphaPixelData) } } -%extend wxAlphaPixelData_Iterator { - byte _get_Alpha() { return self->Alpha(); } - void _set_Alpha(byte val) { self->Alpha() = val; } +%extend wxAlphaPixelData_Accessor { +// byte _get_Alpha() { return self->Alpha(); } +// void _set_Alpha(byte val) { self->Alpha() = val; } - %pythoncode { - Alpha = property(_get_Alpha, _set_Alpha) - } +// %pythoncode { +// Alpha = property(_get_Alpha, _set_Alpha) +// } void Set(byte red, byte green, byte blue, byte alpha) { - self->Red() = red; - self->Green() = green; - self->Blue() = blue; + self->Red() = wxPy_premultiply(red, alpha); + self->Green() = wxPy_premultiply(green, alpha); + self->Blue() = wxPy_premultiply(blue, alpha); self->Alpha() = alpha; } PyObject* Get() { PyObject* rv = PyTuple_New(4); - PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red())); - PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green())); - PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue())); - PyTuple_SetItem(rv, 3, PyInt_FromLong(self->Alpha())); + int red = self->Red(); + int green = self->Green(); + int blue = self->Blue(); + int alpha = self->Alpha(); + + PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red, alpha) )); + PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) )); + PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue, alpha) )); + PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha )); return rv; } } + //--------------------------------------------------------------------------- DocStr(wxMask, @@ -676,7 +816,7 @@ passed then BLACK is used. %extend { wxMask(const wxBitmap& bitmap, const wxColour& colour = wxNullColour) { - if ( !colour.Ok() ) + if ( !colour.IsOk() ) return new wxMask(bitmap, *wxBLACK); else return new wxMask(bitmap, colour); @@ -690,4 +830,6 @@ passed then BLACK is used. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- + +// Turn GIL acquisition back on. %threadWrapperOn