X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/feac79373c7965db3869c352ed0a4f297b41222b..caa2490c0fb8053b1d416117a9619695d75af9e4:/src/gtk1/bitmap.cpp diff --git a/src/gtk1/bitmap.cpp b/src/gtk1/bitmap.cpp index 036f237c89..df7af69140 100644 --- a/src/gtk1/bitmap.cpp +++ b/src/gtk1/bitmap.cpp @@ -16,13 +16,14 @@ #include "wx/defs.h" -#include "wx/palette.h" #include "wx/bitmap.h" +#include "wx/palette.h" #include "wx/icon.h" #include "wx/filefn.h" #include "wx/image.h" #include "wx/dcmemory.h" #include "wx/app.h" +#include "wx/rawbmp.h" #ifdef __WXGTK20__ // need this to get gdk_image_new_bitmap() @@ -39,7 +40,7 @@ #include #endif // GTK+ 2.0/1.2 -#include +#include "wx/math.h" extern void gdk_wx_draw_bitmap (GdkDrawable *drawable, GdkGC *gc, @@ -306,7 +307,7 @@ bool wxBitmap::Create( int width, int height, int depth ) if (depth == -1) depth = visual->depth; - wxCHECK_MSG( (depth == visual->depth) || (depth == 1), FALSE, + wxCHECK_MSG( (depth == visual->depth) || (depth == 1) || (depth == 32), FALSE, wxT("invalid bitmap depth") ) m_refData = new wxBitmapRefData(); @@ -318,6 +319,14 @@ bool wxBitmap::Create( int width, int height, int depth ) M_BMPDATA->m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ); M_BMPDATA->m_bpp = 1; } +#ifdef __WXGTK20__ + else if (depth == 32) + { + M_BMPDATA->m_pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, true, + 8, width, height); + M_BMPDATA->m_bpp = 32; + } +#endif else { M_BMPDATA->m_pixmap = gdk_pixmap_new( wxGetRootWindow()->window, width, height, depth ); @@ -376,9 +385,10 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight, bmp.SetWidth(width); bmp.SetHeight(height); bmp.SetDepth(GetDepth()); - bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE/*has_alpha*/, + bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, + gdk_pixbuf_get_has_alpha(GetPixbuf()), 8, width, height)); - gdk_pixbuf_scale(M_BMPDATA->m_pixbuf, bmp.GetPixbuf(), + gdk_pixbuf_scale(GetPixbuf(), bmp.GetPixbuf(), 0, 0, width, height, clipx, clipy, (double)newx/GetWidth(), (double)newy/GetHeight(), @@ -935,6 +945,7 @@ bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image) if (!pixbuf) return false; + wxASSERT( image.HasAlpha() ); // for now wxASSERT( gdk_pixbuf_get_n_channels(pixbuf) == 4 ); wxASSERT( gdk_pixbuf_get_width(pixbuf) == width ); wxASSERT( gdk_pixbuf_get_height(pixbuf) == height ); @@ -951,7 +962,6 @@ bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image) int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width; - for (int y = 0; y < height; y++, out += rowinc) { for (int x = 0; x < width; x++, alpha++, out += 4, in += 3) @@ -1152,12 +1162,12 @@ wxImage wxBitmap::ConvertToImage() const } wxBitmap::wxBitmap( const wxBitmap& bmp ) - : wxGDIObject() + : wxBitmapBase() { Ref( bmp ); } -wxBitmap::wxBitmap( const wxString &filename, int type ) +wxBitmap::wxBitmap( const wxString &filename, wxBitmapType type ) { LoadFile( filename, type ); } @@ -1274,10 +1284,10 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const if (HasPixbuf()) { GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, - TRUE/*has_alpha*/, + gdk_pixbuf_get_has_alpha(GetPixbuf()), 8, GetWidth(), GetHeight()); ret.SetPixbuf(pixbuf); - gdk_pixbuf_copy_area(M_BMPDATA->m_pixbuf, + gdk_pixbuf_copy_area(GetPixbuf(), rect.x, rect.y, rect.width, rect.height, pixbuf, 0, 0); } @@ -1323,7 +1333,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const return ret; } -bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(palette) ) +bool wxBitmap::SaveFile( const wxString &name, wxBitmapType type, const wxPalette *WXUNUSED(palette) ) const { wxCHECK_MSG( Ok(), FALSE, wxT("invalid bitmap") ); @@ -1336,7 +1346,7 @@ bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(pal return FALSE; } -bool wxBitmap::LoadFile( const wxString &name, int type ) +bool wxBitmap::LoadFile( const wxString &name, wxBitmapType type ) { UnRef(); @@ -1389,6 +1399,11 @@ wxPalette *wxBitmap::GetPalette() const return M_BMPDATA->m_palette; } +void wxBitmap::SetPalette(const wxPalette& WXUNUSED(palette)) +{ + // TODO +} + void wxBitmap::SetHeight( int height ) { if (!m_refData) @@ -1419,6 +1434,9 @@ void wxBitmap::SetPixmap( GdkPixmap *pixmap ) m_refData = new wxBitmapRefData(); M_BMPDATA->m_pixmap = pixmap; +#ifdef __WXGTK20__ + PurgeOtherRepresentations(Pixmap); +#endif } void wxBitmap::SetBitmap( GdkPixmap *bitmap ) @@ -1427,6 +1445,9 @@ void wxBitmap::SetBitmap( GdkPixmap *bitmap ) m_refData = new wxBitmapRefData(); M_BMPDATA->m_bitmap = bitmap; +#ifdef __WXGTK20__ + PurgeOtherRepresentations(Pixmap); +#endif } GdkPixmap *wxBitmap::GetPixmap() const @@ -1437,9 +1458,11 @@ GdkPixmap *wxBitmap::GetPixmap() const // create the pixmap on the fly if we use Pixbuf representation: if (HasPixbuf() && !HasPixmap()) { + delete M_BMPDATA->m_mask; + M_BMPDATA->m_mask = new wxMask(); gdk_pixbuf_render_pixmap_and_mask(M_BMPDATA->m_pixbuf, &M_BMPDATA->m_pixmap, - NULL /*mask*/, + &M_BMPDATA->m_mask->m_bitmap, 128 /*threshold*/); } #endif // __WXGTK20__ @@ -1466,6 +1489,48 @@ GdkPixbuf *wxBitmap::GetPixbuf() const { wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + if (HasPixmap() && !HasPixbuf()) + { + int width = GetWidth(); + int height = GetHeight(); + + GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, + GetMask() != NULL, + 8, width, height); + M_BMPDATA->m_pixbuf = + gdk_pixbuf_get_from_drawable(pixbuf, M_BMPDATA->m_pixmap, NULL, + 0, 0, 0, 0, width, height); + + // apply the mask to created pixbuf: + if (M_BMPDATA->m_pixbuf && M_BMPDATA->m_mask) + { + GdkPixbuf *pmask = + gdk_pixbuf_get_from_drawable(NULL, + M_BMPDATA->m_mask->GetBitmap(), + NULL, + 0, 0, 0, 0, width, height); + if (pmask) + { + guchar *bmp = gdk_pixbuf_get_pixels(pixbuf); + guchar *mask = gdk_pixbuf_get_pixels(pmask); + int bmprowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width; + int maskrowinc = gdk_pixbuf_get_rowstride(pmask) - 3 * width; + + for (int y = 0; y < height; + y++, bmp += bmprowinc, mask += maskrowinc) + { + for (int x = 0; x < width; x++, bmp += 4, mask += 3) + { + if (mask[0] == 0 /*black pixel*/) + bmp[3] = 0; + } + } + + gdk_pixbuf_unref(pmask); + } + } + } + return M_BMPDATA->m_pixbuf; } @@ -1482,6 +1547,7 @@ void wxBitmap::SetPixbuf( GdkPixbuf *pixbuf ) m_refData = new wxBitmapRefData(); M_BMPDATA->m_pixbuf = pixbuf; + PurgeOtherRepresentations(Pixbuf); } void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep) @@ -1499,3 +1565,84 @@ void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep) } #endif // __WXGTK20__ + +void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp) +{ +#ifdef __WXGTK20__ + if (bpp != 32) + return NULL; + + GdkPixbuf *pixbuf = GetPixbuf(); + if (!pixbuf) + return NULL; + +#if 0 + if (gdk_pixbuf_get_has_alpha( pixbuf )) + wxPrintf( wxT("Has alpha\n") ); + else + wxPrintf( wxT("No alpha.\n") ); +#endif + + data.m_height = gdk_pixbuf_get_height( pixbuf ); + data.m_width = gdk_pixbuf_get_width( pixbuf ); + data.m_stride = gdk_pixbuf_get_rowstride( pixbuf ); + + return gdk_pixbuf_get_pixels( pixbuf ); +#else + return NULL; +#endif +} + +void wxBitmap::UngetRawData(wxPixelDataBase& data) +{ +} + + +bool wxBitmap::HasAlpha() const +{ +#ifdef __WXGTK20__ + return HasPixbuf(); +#else + return false; +#endif +} + +void wxBitmap::UseAlpha() +{ +#ifdef __WXGTK20__ + GetPixbuf(); +#endif +} + +//----------------------------------------------------------------------------- +// wxBitmapHandler +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler,wxBitmapHandlerBase) + +wxBitmapHandler::~wxBitmapHandler() +{ +} + +bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) +{ + return FALSE; +} + +bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, + int desiredWidth, int desiredHeight) +{ + return FALSE; +} + +bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette) +{ + return FALSE; +} + +/* static */ void wxBitmap::InitStandardHandlers() +{ + // TODO: Insert handler based on GdkPixbufs handler later +} + +