X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/df875e593f9ec4b2eb08d632e17caddf10b61ac8..e487524e492809638b7e335937c41fd432458a54:/src/gtk1/bitmap.cpp diff --git a/src/gtk1/bitmap.cpp b/src/gtk1/bitmap.cpp index 011930fbd1..f92b146377 100644 --- a/src/gtk1/bitmap.cpp +++ b/src/gtk1/bitmap.cpp @@ -16,6 +16,7 @@ #include "wx/filefn.h" #include "gdk/gdkprivate.h" #include "gdk/gdkx.h" +#include "wx/image.h" //----------------------------------------------------------------------------- // wxMask @@ -117,6 +118,29 @@ wxBitmap::wxBitmap( int width, int height, int depth ) if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); } +wxBitmap::wxBitmap( const char **bits ) +{ + wxCHECK_RET( bits != NULL, "invalid bitmap data" ) + + m_refData = new wxBitmapRefData(); + + GdkBitmap *mask = (GdkBitmap*) NULL; + GdkWindow *parent = (GdkWindow*) &gdk_root_parent; + + M_BMPDATA->m_pixmap = gdk_pixmap_create_from_xpm_d( parent, &mask, NULL, (gchar **) bits ); + + if (mask) + { + M_BMPDATA->m_mask = new wxMask(); + M_BMPDATA->m_mask->m_bitmap = mask; + } + + gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) ); + + M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth; // ? + if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); +} + wxBitmap::wxBitmap( char **bits ) { wxCHECK_RET( bits != NULL, "invalid bitmap data" ) @@ -128,6 +152,8 @@ wxBitmap::wxBitmap( char **bits ) M_BMPDATA->m_pixmap = gdk_pixmap_create_from_xpm_d( parent, &mask, NULL, (gchar **) bits ); + wxCHECK_RET( M_BMPDATA->m_pixmap, "couldn't create pixmap" ); + if (mask) { M_BMPDATA->m_mask = new wxMask(); @@ -137,7 +163,6 @@ wxBitmap::wxBitmap( char **bits ) gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) ); M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth; // ? - if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); } @@ -173,6 +198,8 @@ wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth M_BMPDATA->m_height = height; M_BMPDATA->m_bpp = 1; + wxCHECK_RET( M_BMPDATA->m_bitmap, "couldn't create bitmap" ); + if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); } @@ -205,82 +232,35 @@ bool wxBitmap::Ok(void) const int wxBitmap::GetHeight(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return -1; - } + wxCHECK_MSG( Ok(), -1, "invalid bitmap" ); return M_BMPDATA->m_height; } int wxBitmap::GetWidth(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return -1; - } + wxCHECK_MSG( Ok(), -1, "invalid bitmap" ); return M_BMPDATA->m_width; } int wxBitmap::GetDepth(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return -1; - } + wxCHECK_MSG( Ok(), -1, "invalid bitmap" ); return M_BMPDATA->m_bpp; } -void wxBitmap::SetHeight( int height ) -{ - if (!Ok()) return; - - wxFAIL_MSG( "wxBitmap::SetHeight not implemented" ); - - M_BMPDATA->m_height = height; -} - -void wxBitmap::SetWidth( int width ) -{ - if (!Ok()) return; - - wxFAIL_MSG( "wxBitmap::SetWidth not implemented" ); - - M_BMPDATA->m_width = width; -} - -void wxBitmap::SetDepth( int depth ) -{ - if (!Ok()) return; - - wxFAIL_MSG( "wxBitmap::SetDepth not implemented" ); - - M_BMPDATA->m_bpp = depth; -} - wxMask *wxBitmap::GetMask(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return (wxMask *) NULL; - } + wxCHECK_MSG( Ok(), (wxMask *) NULL, "invalid bitmap" ); return M_BMPDATA->m_mask; } void wxBitmap::SetMask( wxMask *mask ) { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return; - } + wxCHECK_RET( Ok(), "invalid bitmap" ); if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask; @@ -289,15 +269,11 @@ void wxBitmap::SetMask( wxMask *mask ) bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(palette) ) { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return FALSE; - } + wxCHECK_MSG( Ok(), FALSE, "invalid bitmap" ); if (type == wxBITMAP_TYPE_PNG) { - wxImage image = ConvertToImage(); + wxImage image( *this ); if (image.Ok()) return image.SaveFile( name, type ); } @@ -332,13 +308,13 @@ bool wxBitmap::LoadFile( const wxString &name, int type ) { wxImage image; image.LoadFile( name, type ); - if (image.Ok()) *this = wxBitmap( image ); + if (image.Ok()) *this = image.ConvertToBitmap(); } else if (type == wxBITMAP_TYPE_BMP) { wxImage image; image.LoadFile( name, type ); - if (image.Ok()) *this = wxBitmap( image ); + if (image.Ok()) *this = image.ConvertToBitmap(); } else return FALSE; @@ -349,79 +325,105 @@ bool wxBitmap::LoadFile( const wxString &name, int type ) wxPalette *wxBitmap::GetPalette(void) const { if (!Ok()) return (wxPalette *) NULL; + return M_BMPDATA->m_palette; } +void wxBitmap::SetHeight( int height ) +{ + if (!m_refData) m_refData = new wxBitmapRefData(); + + M_BMPDATA->m_height = height; +} + +void wxBitmap::SetWidth( int width ) +{ + if (!m_refData) m_refData = new wxBitmapRefData(); + + M_BMPDATA->m_width = width; +} + +void wxBitmap::SetDepth( int depth ) +{ + if (!m_refData) m_refData = new wxBitmapRefData(); + + M_BMPDATA->m_bpp = depth; +} + +void wxBitmap::SetPixmap( GdkPixmap *pixmap ) +{ + if (!m_refData) m_refData = new wxBitmapRefData(); + + M_BMPDATA->m_pixmap = pixmap; +} + GdkPixmap *wxBitmap::GetPixmap(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return (GdkPixmap *) NULL; - } + wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, "invalid bitmap" ); return M_BMPDATA->m_pixmap; } GdkBitmap *wxBitmap::GetBitmap(void) const { - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return (GdkBitmap *) NULL; - } + wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, "invalid bitmap" ); return M_BMPDATA->m_bitmap; } -wxBitmap::wxBitmap( const wxImage &image ) +//----------------------------------------------------------------------------- +// wxImage +//----------------------------------------------------------------------------- + +wxBitmap wxImage::ConvertToBitmap() const { - if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); - - if (!image.Ok()) return; + wxBitmap bitmap; - m_refData = new wxBitmapRefData(); + wxCHECK_MSG( Ok(), bitmap, "invalid image" ); - M_BMPDATA->m_height = image.GetHeight(); - M_BMPDATA->m_width = image.GetWidth(); - int width = image.GetWidth(); - int height = image.GetHeight(); + int width = GetWidth(); + int height = GetHeight(); + bitmap.SetHeight( height ); + bitmap.SetWidth( width ); + // Create picture GdkImage *data_image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), width, height ); - M_BMPDATA->m_pixmap = - gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, -1 ); + bitmap.SetPixmap( gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, -1 ) ); // Create mask GdkImage *mask_image = (GdkImage*) NULL; - if (image.HasMask()) + if (HasMask()) { unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height ); mask_image = gdk_image_new_bitmap( gdk_visual_get_system(), mask_data, width, height ); - M_BMPDATA->m_mask = new wxMask(); - M_BMPDATA->m_mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 ); + wxMask *mask = new wxMask(); + mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 ); + + bitmap.SetMask( mask ); } // Retrieve depth - M_BMPDATA->m_bpp = data_image->depth; - - int render_depth = 8; - if (M_BMPDATA->m_bpp > 8) render_depth = M_BMPDATA->m_bpp; - + GdkVisual *visual = gdk_window_get_visual( bitmap.GetPixmap() ); + if (visual == NULL) visual = gdk_window_get_visual( (GdkWindow*) &gdk_root_parent ); + int bpp = visual->depth; + if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15; + if (bpp < 8) bpp = 8; + // Render enum byte_order { RGB, RBG, BRG, BGR, GRB, GBR }; byte_order b_o = RGB; - if (render_depth >= 24) + if (bpp >= 24) { GdkVisual *visual = gdk_visual_get_system(); if ((visual->red_mask > visual->green_mask) && (visual->green_mask > visual->blue_mask)) b_o = RGB; @@ -432,11 +434,11 @@ wxBitmap::wxBitmap( const wxImage &image ) else if ((visual->green_mask > visual->blue_mask) && (visual->blue_mask > visual->red_mask)) b_o = GBR; } - int r_mask = image.GetMaskRed(); - int g_mask = image.GetMaskGreen(); - int b_mask = image.GetMaskBlue(); + int r_mask = GetMaskRed(); + int g_mask = GetMaskGreen(); + int b_mask = GetMaskBlue(); - unsigned char* data = image.GetData(); + unsigned char* data = GetData(); int index = 0; for (int y = 0; y < height; y++) @@ -450,7 +452,7 @@ wxBitmap::wxBitmap( const wxImage &image ) int b = data[index]; index++; - if (image.HasMask()) + if (HasMask()) { if ((r == r_mask) && (b == b_mask) && (g == g_mask)) gdk_image_put_pixel( mask_image, x, y, 1 ); @@ -458,7 +460,7 @@ wxBitmap::wxBitmap( const wxImage &image ) gdk_image_put_pixel( mask_image, x, y, 0 ); } - switch (render_depth) + switch (bpp) { case 8: { @@ -514,53 +516,69 @@ wxBitmap::wxBitmap( const wxImage &image ) // Blit picture - GdkGC *data_gc = gdk_gc_new( M_BMPDATA->m_pixmap ); + GdkGC *data_gc = gdk_gc_new( bitmap.GetPixmap() ); - gdk_draw_image( M_BMPDATA->m_pixmap, data_gc, data_image, 0, 0, 0, 0, width, height ); + gdk_draw_image( bitmap.GetPixmap(), data_gc, data_image, 0, 0, 0, 0, width, height ); gdk_image_destroy( data_image ); gdk_gc_unref( data_gc ); // Blit mask - if (image.HasMask()) + if (HasMask()) { - GdkGC *mask_gc = gdk_gc_new( M_BMPDATA->m_mask->m_bitmap ); + GdkGC *mask_gc = gdk_gc_new( bitmap.GetMask()->GetBitmap() ); - gdk_draw_image( M_BMPDATA->m_mask->m_bitmap, mask_gc, mask_image, 0, 0, 0, 0, width, height ); + gdk_draw_image( bitmap.GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height ); gdk_image_destroy( mask_image ); gdk_gc_unref( mask_gc ); } + + return bitmap; } -wxImage wxBitmap::ConvertToImage() const +wxImage::wxImage( const wxBitmap &bitmap ) { - wxImage image; - - if (!Ok()) - { - wxFAIL_MSG( "invalid bitmap" ); - return image; - } - - GdkImage *gdk_image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height ); + wxCHECK_RET( bitmap.Ok(), "invalid bitmap" ); - if (!gdk_image) return image; + GdkImage *gdk_image = gdk_image_get( bitmap.GetPixmap(), + 0, 0, + bitmap.GetWidth(), bitmap.GetHeight() ); + + wxCHECK_RET( gdk_image, "couldn't create image" ); - image.Create( M_BMPDATA->m_width, M_BMPDATA->m_height ); - char unsigned *data = image.GetData(); + Create( bitmap.GetWidth(), bitmap.GetHeight() ); + char unsigned *data = GetData(); + + if (!data) + { + gdk_image_destroy( gdk_image ); + wxFAIL_MSG( "couldn't create image" ); + return; + } + + GdkImage *gdk_image_mask = (GdkImage*) NULL; + if (bitmap.GetMask()) + { + gdk_image_mask = gdk_image_get( bitmap.GetMask()->GetBitmap(), + 0, 0, + bitmap.GetWidth(), bitmap.GetHeight() ); - GdkVisual *visual = gdk_window_get_visual( M_BMPDATA->m_pixmap ); + SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable + } + + GdkVisual *visual = gdk_window_get_visual( bitmap.GetPixmap() ); if (visual == NULL) visual = gdk_window_get_visual( (GdkWindow*) &gdk_root_parent ); int bpp = visual->depth; - + if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15; + GdkColormap *cmap = gtk_widget_get_default_colormap(); long pos = 0; - for (int j = 0; j < M_BMPDATA->m_height; j++) + for (int j = 0; j < bitmap.GetHeight(); j++) { - for (int i = 0; i < M_BMPDATA->m_width; i++) + for (int i = 0; i < bitmap.GetWidth(); i++) { int pixel = gdk_image_get_pixel( gdk_image, i, j ); if (bpp <= 8) @@ -585,13 +603,23 @@ wxImage wxBitmap::ConvertToImage() const data[pos+2] = pixel & 0xff; } + if (gdk_image_mask) + { + int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j ); + if (mask_pixel == 0) + { + data[pos] = 16; + data[pos+1] = 16; + data[pos+2] = 16; + } + } + pos += 3; } } gdk_image_destroy( gdk_image ); - - return image; + if (gdk_image_mask) gdk_image_destroy( gdk_image_mask ); }