]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/bitmap.cpp
In wxApp::OnIdle() check to see if there is not a current menubar and if
[wxWidgets.git] / src / gtk / bitmap.cpp
index 9fda483abaf5b402f1a6c50f8a598587b79d9d51..a7e059c40c8bef06ca3960270feaa5485d3506b4 100644 (file)
 #include "wx/dcmemory.h"
 #include "wx/app.h"
 
+#ifdef __WXGTK20__
+    // need this to get gdk_image_new_bitmap()
+    #define GDK_ENABLE_BROKEN
+#endif
+
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 
-#if (GTK_MINOR_VERSION > 0)
-#include <gdk/gdkrgb.h>
-#endif
+#ifdef __WXGTK20__
+    #include <gdk/gdkimage.h>
+#else // GTK+ 1.2
+    #include <gdk/gdkrgb.h>
+#endif // GTK+ 2.0/1.2
 
 extern void gdk_wx_draw_bitmap     (GdkDrawable  *drawable,
                           GdkGC               *gc,
@@ -89,7 +96,7 @@ bool wxMask::Create( const wxBitmap& bitmap,
         m_bitmap = (GdkBitmap*) NULL;
     }
 
-    wxImage image( bitmap );
+    wxImage image = bitmap.ConvertToImage();
     if (!image.Ok()) return FALSE;
 
     m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, image.GetWidth(), image.GetHeight(), 1 );
@@ -111,23 +118,29 @@ bool wxMask::Create( const wxBitmap& bitmap,
     unsigned char green = colour.Green();
     unsigned char blue = colour.Blue();
 
-    GdkVisual *visual = gdk_window_get_visual( wxGetRootWindow()->window );
-    wxASSERT( visual );
+    GdkVisual *visual = wxTheApp->GetGdkVisual();
 
     int bpp = visual->depth;
-    if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15;
+    if ((bpp == 16) && (visual->red_mask != 0xf800))
+        bpp = 15;
     if (bpp == 15)
     {
         red = red & 0xf8;
         green = green & 0xf8;
         blue = blue & 0xf8;
     }
-    if (bpp == 16)
+    else if (bpp == 16)
     {
         red = red & 0xf8;
         green = green & 0xfc;
         blue = blue & 0xf8;
     }
+    else if (bpp == 12)
+    {
+        red = red & 0xf0;
+        green = green & 0xf0;
+        blue = blue & 0xf0;
+    }
 
     color.red = 0;
     color.green = 0;
@@ -268,8 +281,7 @@ bool wxBitmap::Create( int width, int height, int depth )
 
     wxCHECK_MSG( (width > 0) && (height > 0), FALSE, wxT("invalid bitmap size") )
 
-    GdkVisual *visual = gdk_window_get_visual( wxGetRootWindow()->window );
-    wxASSERT( visual );
+    GdkVisual *visual = wxTheApp->GetGdkVisual();
 
     if (depth == -1) depth = visual->depth;
 
@@ -296,10 +308,11 @@ bool wxBitmap::Create( int width, int height, int depth )
 
 bool wxBitmap::CreateFromXpm( const char **bits )
 {
+    UnRef();
+
     wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
 
-    GdkVisual *visual = gdk_window_get_visual( wxGetRootWindow()->window );
-    wxASSERT( visual );
+    GdkVisual *visual = wxTheApp->GetGdkVisual();
 
     m_refData = new wxBitmapRefData();
 
@@ -317,20 +330,22 @@ bool wxBitmap::CreateFromXpm( const char **bits )
 
     gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
 
-    M_BMPDATA->m_bpp = visual->depth;  // ?
+    M_BMPDATA->m_bpp = visual->depth;  // Can we get a different depth from create_from_xpm_d() ?
 
     return TRUE;
 }
 
 bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 {
+    UnRef();
+
     wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
     wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") )
 
     m_refData = new wxBitmapRefData();
 
     // ------
-    // convertion to mono bitmap:
+    // conversion to mono bitmap:
     // ------
     if (depth == 1)
     {
@@ -344,8 +359,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 
         SetDepth( 1 );
 
-        GdkVisual *visual = gdk_window_get_visual( wxGetRootWindow()->window );
-        wxASSERT( visual );
+        GdkVisual *visual = wxTheApp->GetGdkVisual();
 
         // Create picture image
 
@@ -427,7 +441,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
     }
 
     // ------
-    // convertion to colour bitmap:
+    // conversion to colour bitmap:
     // ------
     else
     {
@@ -439,29 +453,25 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 
         SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
 
-        // Retrieve depth, using XVisualInfo from app, if set
-        GdkVisual *visual;
-        if (wxTheApp->m_glVisualInfo)
-        {
-            visual = gdkx_visual_get( ((XVisualInfo *) wxTheApp->m_glVisualInfo)->visualid );
-        }
-        else
-        {
-            visual = gdk_window_get_visual( wxGetRootWindow()->window );
-        }
-        wxASSERT( visual );
+        GdkVisual *visual = wxTheApp->GetGdkVisual();
 
         int bpp = visual->depth;
 
         SetDepth( bpp );
 
-        if ((bpp == 16) && (visual->red_mask != 0xf800)) bpp = 15;
-        if (bpp < 8) bpp = 8;
+        if ((bpp == 16) && (visual->red_mask != 0xf800))
+            bpp = 15;
+        else if (bpp < 8)
+            bpp = 8;
 
-        // We handle 8-bit bitmaps ourselves using the colour cube, 12-bit 
+        // We handle 8-bit bitmaps ourselves using the colour cube, 12-bit
         // visuals are not supported by GDK so we do these ourselves, too.
         // 15-bit and 16-bit should actually work and 24-bit certainly does.
+#ifdef __sgi
+        if (!image.HasMask() && (bpp > 16))
+#else
         if (!image.HasMask() && (bpp > 12))
+#endif
         {
             static bool s_hasInitialized = FALSE;
 
@@ -514,7 +524,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
         if (bpp > 8)
         {
             if ((visual->red_mask > visual->green_mask) && (visual->green_mask > visual->blue_mask))      b_o = RGB;
-            else if ((visual->red_mask > visual->blue_mask) && (visual->blue_mask > visual->green_mask))  b_o = RGB;
+            else if ((visual->red_mask > visual->blue_mask) && (visual->blue_mask > visual->green_mask))  b_o = RBG;
             else if ((visual->blue_mask > visual->red_mask) && (visual->red_mask > visual->green_mask))   b_o = BRG;
             else if ((visual->blue_mask > visual->green_mask) && (visual->green_mask > visual->red_mask)) b_o = BGR;
             else if ((visual->green_mask > visual->red_mask) && (visual->red_mask > visual->blue_mask))   b_o = GRB;
@@ -561,7 +571,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
                             GdkColormap *cmap = gtk_widget_get_default_colormap();
                             GdkColor *colors = cmap->colors;
                             int max = 3 * (65536);
-    
+
                             for (int i = 0; i < cmap->size; i++)
                             {
                                 int rdiff = (r << 8) - colors[i].red;
@@ -571,9 +581,9 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
                                 if (sum < max) { pixel = i; max = sum; }
                             }
                         }
-    
+
                         gdk_image_put_pixel( data_image, x, y, pixel );
-    
+
                         break;
                     }
                     case 12:  // SGI only
@@ -613,12 +623,12 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
                         guint32 pixel = 0;
                         switch (b_o)
                         {
-                            case RGB: pixel = ((r & 0xf8) << 7) | ((g & 0xfc) << 2) | ((b & 0xf8) >> 3); break;
-                            case RBG: pixel = ((r & 0xf8) << 7) | ((b & 0xfc) << 2) | ((g & 0xf8) >> 3); break;
-                            case GRB: pixel = ((g & 0xf8) << 7) | ((r & 0xfc) << 2) | ((b & 0xf8) >> 3); break;
-                            case GBR: pixel = ((g & 0xf8) << 7) | ((b & 0xfc) << 2) | ((r & 0xf8) >> 3); break;
-                            case BRG: pixel = ((b & 0xf8) << 7) | ((r & 0xfc) << 2) | ((g & 0xf8) >> 3); break;
-                            case BGR: pixel = ((b & 0xf8) << 7) | ((g & 0xfc) << 2) | ((r & 0xf8) >> 3); break;
+                            case RGB: pixel = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3); break;
+                            case RBG: pixel = ((r & 0xf8) << 8) | ((b & 0xfc) << 3) | ((g & 0xf8) >> 3); break;
+                            case GRB: pixel = ((g & 0xf8) << 8) | ((r & 0xfc) << 3) | ((b & 0xf8) >> 3); break;
+                            case GBR: pixel = ((g & 0xf8) << 8) | ((b & 0xfc) << 3) | ((r & 0xf8) >> 3); break;
+                            case BRG: pixel = ((b & 0xf8) << 8) | ((r & 0xfc) << 3) | ((g & 0xf8) >> 3); break;
+                            case BGR: pixel = ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3); break;
                         }
                         gdk_image_put_pixel( data_image, x, y, pixel );
                         break;
@@ -670,6 +680,13 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
 
 wxImage wxBitmap::ConvertToImage() const
 {
+    // the colour used as transparent one in wxImage and the one it is replaced
+    // with when it really occurs in the bitmap
+    static const int MASK_RED = 1;
+    static const int MASK_GREEN = 2;
+    static const int MASK_BLUE = 3;
+    static const int MASK_BLUE_REPLACEMENT = 2;
+
     wxImage image;
 
     wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
@@ -678,15 +695,16 @@ wxImage wxBitmap::ConvertToImage() const
     if (GetPixmap())
     {
         gdk_image = gdk_image_get( GetPixmap(),
-            0, 0,
-            GetWidth(), GetHeight() );
-    } else
-    if (GetBitmap())
+                                   0, 0,
+                                   GetWidth(), GetHeight() );
+    }
+    else if (GetBitmap())
     {
         gdk_image = gdk_image_get( GetBitmap(),
-            0, 0,
-            GetWidth(), GetHeight() );
-    } else
+                                   0, 0,
+                                   GetWidth(), GetHeight() );
+    }
+    else
     {
         wxFAIL_MSG( wxT("Ill-formed bitmap") );
     }
@@ -707,10 +725,10 @@ wxImage wxBitmap::ConvertToImage() const
     if (GetMask())
     {
         gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
-            0, 0,
-            GetWidth(), GetHeight() );
+                                        0, 0,
+                                        GetWidth(), GetHeight() );
 
-        image.SetMaskColour( 16, 16, 16 );  // anything unlikely and dividable
+        image.SetMaskColour( MASK_RED, MASK_GREEN, MASK_BLUE );
     }
 
     int bpp = -1;
@@ -725,10 +743,12 @@ wxImage wxBitmap::ConvertToImage() const
     if (GetPixmap())
     {
         GdkVisual *visual = gdk_window_get_visual( GetPixmap() );
+        if (visual == NULL)
+            visual = wxTheApp->GetGdkVisual();
 
-        if (visual == NULL) visual = gdk_window_get_visual( wxGetRootWindow()->window );
         bpp = visual->depth;
-        if (bpp == 16) bpp = visual->red_prec + visual->green_prec + visual->blue_prec;
+        if (bpp == 16)
+            bpp = visual->red_prec + visual->green_prec + visual->blue_prec;
         red_shift_right = visual->red_shift;
         red_shift_left = 8-visual->red_prec;
         green_shift_right = visual->green_shift;
@@ -789,9 +809,15 @@ wxImage wxBitmap::ConvertToImage() const
                 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;
+                    data[pos] = MASK_RED;
+                    data[pos+1] = MASK_GREEN;
+                    data[pos+2] = MASK_BLUE;
+                }
+                else if ( data[pos] == MASK_RED &&
+                            data[pos+1] == MASK_GREEN &&
+                                data[pos+2] == MASK_BLUE )
+                {
+                    data[pos+2] = MASK_BLUE_REPLACEMENT;
                 }
             }
 
@@ -806,6 +832,7 @@ wxImage wxBitmap::ConvertToImage() const
 }
 
 wxBitmap::wxBitmap( const wxBitmap& bmp )
+    : wxGDIObject()
 {
     Ref( bmp );
 }
@@ -943,7 +970,7 @@ bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(pal
 
     // Try to save the bitmap via wxImage handlers:
     {
-        wxImage image( *this );
+        wxImage image = ConvertToImage();
         if (image.Ok()) return image.SaveFile( name, type );
     }
 
@@ -956,8 +983,7 @@ bool wxBitmap::LoadFile( const wxString &name, int type )
 
     if (!wxFileExists(name)) return FALSE;
 
-    GdkVisual *visual = gdk_window_get_visual( wxGetRootWindow()->window );
-    wxASSERT( visual );
+    GdkVisual *visual = wxTheApp->GetGdkVisual();
 
     if (type == wxBITMAP_TYPE_XPM)
     {
@@ -981,7 +1007,8 @@ bool wxBitmap::LoadFile( const wxString &name, int type )
     {
         wxImage image;
         if (!image.LoadFile( name, type )) return FALSE;
-        if (image.Ok()) *this = image.ConvertToBitmap();
+        if (image.Ok())
+            *this = wxBitmap(image);
         else return FALSE;
     }