1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  11 #pragma implementation "bitmap.h" 
  14 // For compilers that support precompilation, includes "wx.h". 
  15 #include "wx/wxprec.h" 
  19 #include "wx/palette.h" 
  20 #include "wx/bitmap.h" 
  22 #include "wx/filefn.h" 
  24 #include "wx/dcmemory.h" 
  28     // need this to get gdk_image_new_bitmap() 
  29     #define GDK_ENABLE_BROKEN 
  37     #include <gdk/gdkimage.h> 
  39     #include <gdk/gdkrgb.h> 
  40 #endif // GTK+ 2.0/1.2 
  42 extern void gdk_wx_draw_bitmap     (GdkDrawable  
*drawable
, 
  52 //----------------------------------------------------------------------------- 
  54 //----------------------------------------------------------------------------- 
  56 extern GtkWidget 
*wxGetRootWindow(); 
  58 //----------------------------------------------------------------------------- 
  60 //----------------------------------------------------------------------------- 
  62 IMPLEMENT_DYNAMIC_CLASS(wxMask
,wxObject
) 
  66     m_bitmap 
= (GdkBitmap 
*) NULL
; 
  69 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
  71     m_bitmap 
= (GdkBitmap 
*) NULL
; 
  72     Create( bitmap
, colour 
); 
  75 wxMask::wxMask( const wxBitmap
& bitmap
, int paletteIndex 
) 
  77     m_bitmap 
= (GdkBitmap 
*) NULL
; 
  78     Create( bitmap
, paletteIndex 
); 
  81 wxMask::wxMask( const wxBitmap
& bitmap 
) 
  83     m_bitmap 
= (GdkBitmap 
*) NULL
; 
  90         gdk_bitmap_unref( m_bitmap 
); 
  93 bool wxMask::Create( const wxBitmap
& bitmap
, 
  94                      const wxColour
& colour 
) 
  98         gdk_bitmap_unref( m_bitmap 
); 
  99         m_bitmap 
= (GdkBitmap
*) NULL
; 
 102     wxImage image 
= bitmap
.ConvertToImage(); 
 103     if (!image
.Ok()) return FALSE
; 
 105     m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, image
.GetWidth(), image
.GetHeight(), 1 ); 
 106     GdkGC 
*gc 
= gdk_gc_new( m_bitmap 
); 
 113     gdk_gc_set_foreground( gc
, &color 
); 
 114     gdk_gc_set_fill( gc
, GDK_SOLID 
); 
 115     gdk_draw_rectangle( m_bitmap
, gc
, TRUE
, 0, 0, image
.GetWidth(), image
.GetHeight() ); 
 117     unsigned char *data 
= image
.GetData(); 
 120     unsigned char red 
= colour
.Red(); 
 121     unsigned char green 
= colour
.Green(); 
 122     unsigned char blue 
= colour
.Blue(); 
 124     GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
 126     int bpp 
= visual
->depth
; 
 127     if ((bpp 
== 16) && (visual
->red_mask 
!= 0xf800)) 
 132         green 
= green 
& 0xf8; 
 138         green 
= green 
& 0xfc; 
 144         green 
= green 
& 0xf0; 
 152     gdk_gc_set_foreground( gc
, &color 
); 
 154     for (int j 
= 0; j 
< image
.GetHeight(); j
++) 
 158         for (i 
= 0; i 
< image
.GetWidth(); i
++) 
 160             if ((data
[index
] == red
) && 
 161                 (data
[index
+1] == green
) && 
 162                 (data
[index
+2] == blue
)) 
 171                     gdk_draw_line( m_bitmap
, gc
, start_x
, j
, i
-1, j 
); 
 178             gdk_draw_line( m_bitmap
, gc
, start_x
, j
, i
, j 
); 
 186 bool wxMask::Create( const wxBitmap
& bitmap
, int paletteIndex 
) 
 189     wxPalette 
*pal 
= bitmap
.GetPalette(); 
 191     wxCHECK_MSG( pal
, FALSE
, wxT("Cannot create mask from bitmap without palette") ); 
 193     pal
->GetRGB(paletteIndex
, &r
, &g
, &b
); 
 195     return Create(bitmap
, wxColour(r
, g
, b
)); 
 198 bool wxMask::Create( const wxBitmap
& bitmap 
) 
 202         gdk_bitmap_unref( m_bitmap 
); 
 203         m_bitmap 
= (GdkBitmap
*) NULL
; 
 206     if (!bitmap
.Ok()) return FALSE
; 
 208     wxCHECK_MSG( bitmap
.GetBitmap(), FALSE
, wxT("Cannot create mask from colour bitmap") ); 
 210     m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, bitmap
.GetWidth(), bitmap
.GetHeight(), 1 ); 
 212     if (!m_bitmap
) return FALSE
; 
 214     GdkGC 
*gc 
= gdk_gc_new( m_bitmap 
); 
 216     gdk_wx_draw_bitmap( m_bitmap
, gc
, bitmap
.GetBitmap(), 0, 0, 0, 0, bitmap
.GetWidth(), bitmap
.GetHeight() ); 
 223 GdkBitmap 
*wxMask::GetBitmap() const 
 228 //----------------------------------------------------------------------------- 
 230 //----------------------------------------------------------------------------- 
 232 class wxBitmapRefData
: public wxObjectRefData
 
 244     wxPalette      
*m_palette
; 
 247 wxBitmapRefData::wxBitmapRefData() 
 249     m_pixmap 
= (GdkPixmap 
*) NULL
; 
 250     m_bitmap 
= (GdkBitmap 
*) NULL
; 
 251     m_mask 
= (wxMask 
*) NULL
; 
 255     m_palette 
= (wxPalette 
*) NULL
; 
 258 wxBitmapRefData::~wxBitmapRefData() 
 261         gdk_pixmap_unref( m_pixmap 
); 
 263         gdk_bitmap_unref( m_bitmap 
); 
 268 //----------------------------------------------------------------------------- 
 270 #define M_BMPDATA ((wxBitmapRefData *)m_refData) 
 272 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxGDIObject
) 
 278 wxBitmap::wxBitmap( int width
, int height
, int depth 
) 
 280     Create( width
, height
, depth 
); 
 283 bool wxBitmap::Create( int width
, int height
, int depth 
) 
 287     if ( width 
<= 0 || height 
<= 0 ) 
 292     GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
 295         depth 
= visual
->depth
; 
 297     wxCHECK_MSG( (depth 
== visual
->depth
) || (depth 
== 1), FALSE
, 
 298                     wxT("invalid bitmap depth") ) 
 300     m_refData 
= new wxBitmapRefData(); 
 301     M_BMPDATA
->m_mask 
= (wxMask 
*) NULL
; 
 302     M_BMPDATA
->m_width 
= width
; 
 303     M_BMPDATA
->m_height 
= height
; 
 306         M_BMPDATA
->m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 ); 
 307         M_BMPDATA
->m_bpp 
= 1; 
 311         M_BMPDATA
->m_pixmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, depth 
); 
 312         M_BMPDATA
->m_bpp 
= visual
->depth
; 
 318 bool wxBitmap::CreateFromXpm( const char **bits 
) 
 322     wxCHECK_MSG( bits 
!= NULL
, FALSE
, wxT("invalid bitmap data") ) 
 324     GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
 326     m_refData 
= new wxBitmapRefData(); 
 328     GdkBitmap 
*mask 
= (GdkBitmap
*) NULL
; 
 330     M_BMPDATA
->m_pixmap 
= gdk_pixmap_create_from_xpm_d( wxGetRootWindow()->window
, &mask
, NULL
, (gchar 
**) bits 
); 
 332     wxCHECK_MSG( M_BMPDATA
->m_pixmap
, FALSE
, wxT("couldn't create pixmap") ); 
 336         M_BMPDATA
->m_mask 
= new wxMask(); 
 337         M_BMPDATA
->m_mask
->m_bitmap 
= mask
; 
 340     gdk_window_get_size( M_BMPDATA
->m_pixmap
, &(M_BMPDATA
->m_width
), &(M_BMPDATA
->m_height
) ); 
 342     M_BMPDATA
->m_bpp 
= visual
->depth
;  // Can we get a different depth from create_from_xpm_d() ? 
 347 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth 
) 
 351     wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") ) 
 352     wxCHECK_MSG( depth 
== -1 || depth 
== 1, FALSE
, wxT("invalid bitmap depth") ) 
 354     int width 
= image
.GetWidth(); 
 355     int height 
= image
.GetHeight(); 
 357     if ( width 
<= 0 || height 
<= 0 ) 
 362     m_refData 
= new wxBitmapRefData(); 
 368     // conversion to mono bitmap: 
 372         SetBitmap( gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 ) ); 
 376         GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
 378         // Create picture image 
 380         unsigned char *data_data 
= (unsigned char*)malloc( ((width 
>> 3)+8) * height 
); 
 382         GdkImage 
*data_image 
= 
 383             gdk_image_new_bitmap( visual
, data_data
, width
, height 
); 
 387         GdkImage 
*mask_image 
= (GdkImage
*) NULL
; 
 391             unsigned char *mask_data 
= (unsigned char*)malloc( ((width 
>> 3)+8) * height 
); 
 393             mask_image 
=  gdk_image_new_bitmap( visual
, mask_data
, width
, height 
); 
 395             wxMask 
*mask 
= new wxMask(); 
 396             mask
->m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 ); 
 401         int r_mask 
= image
.GetMaskRed(); 
 402         int g_mask 
= image
.GetMaskGreen(); 
 403         int b_mask 
= image
.GetMaskBlue(); 
 405         unsigned char* data 
= image
.GetData(); 
 408         for (int y 
= 0; y 
< height
; y
++) 
 410             for (int x 
= 0; x 
< width
; x
++) 
 421                     if ((r 
== r_mask
) && (b 
== b_mask
) && (g 
== g_mask
)) 
 422                         gdk_image_put_pixel( mask_image
, x
, y
, 1 ); 
 424                         gdk_image_put_pixel( mask_image
, x
, y
, 0 ); 
 427                 if ((r 
== 255) && (b 
== 255) && (g 
== 255)) 
 428                     gdk_image_put_pixel( data_image
, x
, y
, 1 ); 
 430                     gdk_image_put_pixel( data_image
, x
, y
, 0 ); 
 437         GdkGC 
*data_gc 
= gdk_gc_new( GetBitmap() ); 
 439         gdk_draw_image( GetBitmap(), data_gc
, data_image
, 0, 0, 0, 0, width
, height 
); 
 441         gdk_image_destroy( data_image 
); 
 442         gdk_gc_unref( data_gc 
); 
 448             GdkGC 
*mask_gc 
= gdk_gc_new( GetMask()->GetBitmap() ); 
 450             gdk_draw_image( GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height 
); 
 452             gdk_image_destroy( mask_image 
); 
 453             gdk_gc_unref( mask_gc 
); 
 458     // conversion to colour bitmap: 
 462         SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, -1 ) ); 
 464         GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
 466         int bpp 
= visual
->depth
; 
 470         if ((bpp 
== 16) && (visual
->red_mask 
!= 0xf800)) 
 475         // We handle 8-bit bitmaps ourselves using the colour cube, 12-bit 
 476         // visuals are not supported by GDK so we do these ourselves, too. 
 477         // 15-bit and 16-bit should actually work and 24-bit certainly does. 
 479         if (!image
.HasMask() && (bpp 
> 16)) 
 481         if (!image
.HasMask() && (bpp 
> 12)) 
 484             static bool s_hasInitialized 
= FALSE
; 
 486             if (!s_hasInitialized
) 
 489                 s_hasInitialized 
= TRUE
; 
 492             GdkGC 
*gc 
= gdk_gc_new( GetPixmap() ); 
 494             gdk_draw_rgb_image( GetPixmap(), 
 506         // Create picture image 
 508         GdkImage 
*data_image 
= 
 509             gdk_image_new( GDK_IMAGE_FASTEST
, visual
, width
, height 
); 
 513         GdkImage 
*mask_image 
= (GdkImage
*) NULL
; 
 517             unsigned char *mask_data 
= (unsigned char*)malloc( ((width 
>> 3)+8) * height 
); 
 519             mask_image 
=  gdk_image_new_bitmap( visual
, mask_data
, width
, height 
); 
 521             wxMask 
*mask 
= new wxMask(); 
 522             mask
->m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 ); 
 529         enum byte_order 
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR 
}; 
 530         byte_order b_o 
= RGB
; 
 534             if ((visual
->red_mask 
> visual
->green_mask
) && (visual
->green_mask 
> visual
->blue_mask
))      b_o 
= RGB
; 
 535             else if ((visual
->red_mask 
> visual
->blue_mask
) && (visual
->blue_mask 
> visual
->green_mask
))  b_o 
= RBG
; 
 536             else if ((visual
->blue_mask 
> visual
->red_mask
) && (visual
->red_mask 
> visual
->green_mask
))   b_o 
= BRG
; 
 537             else if ((visual
->blue_mask 
> visual
->green_mask
) && (visual
->green_mask 
> visual
->red_mask
)) b_o 
= BGR
; 
 538             else if ((visual
->green_mask 
> visual
->red_mask
) && (visual
->red_mask 
> visual
->blue_mask
))   b_o 
= GRB
; 
 539             else if ((visual
->green_mask 
> visual
->blue_mask
) && (visual
->blue_mask 
> visual
->red_mask
))  b_o 
= GBR
; 
 542         int r_mask 
= image
.GetMaskRed(); 
 543         int g_mask 
= image
.GetMaskGreen(); 
 544         int b_mask 
= image
.GetMaskBlue(); 
 546         unsigned char* data 
= image
.GetData(); 
 549         for (int y 
= 0; y 
< height
; y
++) 
 551             for (int x 
= 0; x 
< width
; x
++) 
 562                     if ((r 
== r_mask
) && (b 
== b_mask
) && (g 
== g_mask
)) 
 563                         gdk_image_put_pixel( mask_image
, x
, y
, 1 ); 
 565                         gdk_image_put_pixel( mask_image
, x
, y
, 0 ); 
 573                         if (wxTheApp
->m_colorCube
) 
 575                             pixel 
= wxTheApp
->m_colorCube
[ ((r 
& 0xf8) << 7) + ((g 
& 0xf8) << 2) + ((b 
& 0xf8) >> 3) ]; 
 579                             GdkColormap 
*cmap 
= gtk_widget_get_default_colormap(); 
 580                             GdkColor 
*colors 
= cmap
->colors
; 
 581                             int max 
= 3 * (65536); 
 583                             for (int i 
= 0; i 
< cmap
->size
; i
++) 
 585                                 int rdiff 
= (r 
<< 8) - colors
[i
].red
; 
 586                                 int gdiff 
= (g 
<< 8) - colors
[i
].green
; 
 587                                 int bdiff 
= (b 
<< 8) - colors
[i
].blue
; 
 588                                 int sum 
= ABS (rdiff
) + ABS (gdiff
) + ABS (bdiff
); 
 589                                 if (sum 
< max
) { pixel 
= i
; max 
= sum
; } 
 593                         gdk_image_put_pixel( data_image
, x
, y
, pixel 
); 
 602                             case RGB
: pixel 
= ((r 
& 0xf0) << 4) | (g 
& 0xf0) | ((b 
& 0xf0) >> 4); break; 
 603                             case RBG
: pixel 
= ((r 
& 0xf0) << 4) | (b 
& 0xf0) | ((g 
& 0xf0) >> 4); break; 
 604                             case GRB
: pixel 
= ((g 
& 0xf0) << 4) | (r 
& 0xf0) | ((b 
& 0xf0) >> 4); break; 
 605                             case GBR
: pixel 
= ((g 
& 0xf0) << 4) | (b 
& 0xf0) | ((r 
& 0xf0) >> 4); break; 
 606                             case BRG
: pixel 
= ((b 
& 0xf0) << 4) | (r 
& 0xf0) | ((g 
& 0xf0) >> 4); break; 
 607                             case BGR
: pixel 
= ((b 
& 0xf0) << 4) | (g 
& 0xf0) | ((r 
& 0xf0) >> 4); break; 
 609                         gdk_image_put_pixel( data_image
, x
, y
, pixel 
); 
 617                             case RGB
: pixel 
= ((r 
& 0xf8) << 7) | ((g 
& 0xf8) << 2) | ((b 
& 0xf8) >> 3); break; 
 618                             case RBG
: pixel 
= ((r 
& 0xf8) << 7) | ((b 
& 0xf8) << 2) | ((g 
& 0xf8) >> 3); break; 
 619                             case GRB
: pixel 
= ((g 
& 0xf8) << 7) | ((r 
& 0xf8) << 2) | ((b 
& 0xf8) >> 3); break; 
 620                             case GBR
: pixel 
= ((g 
& 0xf8) << 7) | ((b 
& 0xf8) << 2) | ((r 
& 0xf8) >> 3); break; 
 621                             case BRG
: pixel 
= ((b 
& 0xf8) << 7) | ((r 
& 0xf8) << 2) | ((g 
& 0xf8) >> 3); break; 
 622                             case BGR
: pixel 
= ((b 
& 0xf8) << 7) | ((g 
& 0xf8) << 2) | ((r 
& 0xf8) >> 3); break; 
 624                         gdk_image_put_pixel( data_image
, x
, y
, pixel 
); 
 629                         // I actually don't know if for 16-bit displays, it is alway the green 
 630                         // component or the second component which has 6 bits. 
 634                             case RGB
: pixel 
= ((r 
& 0xf8) << 8) | ((g 
& 0xfc) << 3) | ((b 
& 0xf8) >> 3); break; 
 635                             case RBG
: pixel 
= ((r 
& 0xf8) << 8) | ((b 
& 0xfc) << 3) | ((g 
& 0xf8) >> 3); break; 
 636                             case GRB
: pixel 
= ((g 
& 0xf8) << 8) | ((r 
& 0xfc) << 3) | ((b 
& 0xf8) >> 3); break; 
 637                             case GBR
: pixel 
= ((g 
& 0xf8) << 8) | ((b 
& 0xfc) << 3) | ((r 
& 0xf8) >> 3); break; 
 638                             case BRG
: pixel 
= ((b 
& 0xf8) << 8) | ((r 
& 0xfc) << 3) | ((g 
& 0xf8) >> 3); break; 
 639                             case BGR
: pixel 
= ((b 
& 0xf8) << 8) | ((g 
& 0xfc) << 3) | ((r 
& 0xf8) >> 3); break; 
 641                         gdk_image_put_pixel( data_image
, x
, y
, pixel 
); 
 650                             case RGB
: pixel 
= (r 
<< 16) | (g 
<< 8) | b
; break; 
 651                             case RBG
: pixel 
= (r 
<< 16) | (b 
<< 8) | g
; break; 
 652                             case BRG
: pixel 
= (b 
<< 16) | (r 
<< 8) | g
; break; 
 653                             case BGR
: pixel 
= (b 
<< 16) | (g 
<< 8) | r
; break; 
 654                             case GRB
: pixel 
= (g 
<< 16) | (r 
<< 8) | b
; break; 
 655                             case GBR
: pixel 
= (g 
<< 16) | (b 
<< 8) | r
; break; 
 657                         gdk_image_put_pixel( data_image
, x
, y
, pixel 
); 
 666         GdkGC 
*data_gc 
= gdk_gc_new( GetPixmap() ); 
 668         gdk_draw_image( GetPixmap(), data_gc
, data_image
, 0, 0, 0, 0, width
, height 
); 
 670         gdk_image_destroy( data_image 
); 
 671         gdk_gc_unref( data_gc 
); 
 677             GdkGC 
*mask_gc 
= gdk_gc_new( GetMask()->GetBitmap() ); 
 679             gdk_draw_image( GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height 
); 
 681             gdk_image_destroy( mask_image 
); 
 682             gdk_gc_unref( mask_gc 
); 
 689 wxImage 
wxBitmap::ConvertToImage() const 
 691     // the colour used as transparent one in wxImage and the one it is replaced 
 692     // with when it really occurs in the bitmap 
 693     static const int MASK_RED 
= 1; 
 694     static const int MASK_GREEN 
= 2; 
 695     static const int MASK_BLUE 
= 3; 
 696     static const int MASK_BLUE_REPLACEMENT 
= 2; 
 700     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 702     GdkImage 
*gdk_image 
= (GdkImage
*) NULL
; 
 705         gdk_image 
= gdk_image_get( GetPixmap(), 
 707                                    GetWidth(), GetHeight() ); 
 709     else if (GetBitmap()) 
 711         gdk_image 
= gdk_image_get( GetBitmap(), 
 713                                    GetWidth(), GetHeight() ); 
 717         wxFAIL_MSG( wxT("Ill-formed bitmap") ); 
 720     wxCHECK_MSG( gdk_image
, wxNullImage
, wxT("couldn't create image") ); 
 722     image
.Create( GetWidth(), GetHeight() ); 
 723     char unsigned *data 
= image
.GetData(); 
 727         gdk_image_destroy( gdk_image 
); 
 728         wxFAIL_MSG( wxT("couldn't create image") ); 
 732     GdkImage 
*gdk_image_mask 
= (GdkImage
*) NULL
; 
 735         gdk_image_mask 
= gdk_image_get( GetMask()->GetBitmap(), 
 737                                         GetWidth(), GetHeight() ); 
 739         image
.SetMaskColour( MASK_RED
, MASK_GREEN
, MASK_BLUE 
); 
 743     int red_shift_right 
= 0; 
 744     int green_shift_right 
= 0; 
 745     int blue_shift_right 
= 0; 
 746     int red_shift_left 
= 0; 
 747     int green_shift_left 
= 0; 
 748     int blue_shift_left 
= 0; 
 749     bool use_shift 
= FALSE
; 
 753         GdkVisual 
*visual 
= gdk_window_get_visual( GetPixmap() ); 
 755             visual 
= wxTheApp
->GetGdkVisual(); 
 759             bpp 
= visual
->red_prec 
+ visual
->green_prec 
+ visual
->blue_prec
; 
 760         red_shift_right 
= visual
->red_shift
; 
 761         red_shift_left 
= 8-visual
->red_prec
; 
 762         green_shift_right 
= visual
->green_shift
; 
 763         green_shift_left 
= 8-visual
->green_prec
; 
 764         blue_shift_right 
= visual
->blue_shift
; 
 765         blue_shift_left 
= 8-visual
->blue_prec
; 
 767         use_shift 
= (visual
->type 
== GDK_VISUAL_TRUE_COLOR
) || (visual
->type 
== GDK_VISUAL_DIRECT_COLOR
); 
 775     GdkColormap 
*cmap 
= gtk_widget_get_default_colormap(); 
 778     for (int j 
= 0; j 
< GetHeight(); j
++) 
 780         for (int i 
= 0; i 
< GetWidth(); i
++) 
 782             wxUint32 pixel 
= gdk_image_get_pixel( gdk_image
, i
, j 
); 
 800                 data
[pos
] =   (pixel 
>> red_shift_right
)   << red_shift_left
; 
 801                 data
[pos
+1] = (pixel 
>> green_shift_right
) << green_shift_left
; 
 802                 data
[pos
+2] = (pixel 
>> blue_shift_right
)  << blue_shift_left
; 
 804             else if (cmap
->colors
) 
 806                 data
[pos
] =   cmap
->colors
[pixel
].red   
>> 8; 
 807                 data
[pos
+1] = cmap
->colors
[pixel
].green 
>> 8; 
 808                 data
[pos
+2] = cmap
->colors
[pixel
].blue  
>> 8; 
 812                 wxFAIL_MSG( wxT("Image conversion failed. Unknown visual type.") ); 
 817                 int mask_pixel 
= gdk_image_get_pixel( gdk_image_mask
, i
, j 
); 
 820                     data
[pos
] = MASK_RED
; 
 821                     data
[pos
+1] = MASK_GREEN
; 
 822                     data
[pos
+2] = MASK_BLUE
; 
 824                 else if ( data
[pos
] == MASK_RED 
&& 
 825                             data
[pos
+1] == MASK_GREEN 
&& 
 826                                 data
[pos
+2] == MASK_BLUE 
) 
 828                     data
[pos
+2] = MASK_BLUE_REPLACEMENT
; 
 836     gdk_image_destroy( gdk_image 
); 
 837     if (gdk_image_mask
) gdk_image_destroy( gdk_image_mask 
); 
 842 wxBitmap::wxBitmap( const wxBitmap
& bmp 
) 
 848 wxBitmap::wxBitmap( const wxString 
&filename
, int type 
) 
 850     LoadFile( filename
, type 
); 
 853 wxBitmap::wxBitmap( const char bits
[], int width
, int height
, int WXUNUSED(depth
)) 
 855     if ( width 
> 0 && height 
> 0 ) 
 857         m_refData 
= new wxBitmapRefData(); 
 859         M_BMPDATA
->m_mask 
= (wxMask 
*) NULL
; 
 860         M_BMPDATA
->m_bitmap 
= gdk_bitmap_create_from_data
 
 862                                 wxGetRootWindow()->window
, 
 867         M_BMPDATA
->m_width 
= width
; 
 868         M_BMPDATA
->m_height 
= height
; 
 869         M_BMPDATA
->m_bpp 
= 1; 
 871         wxASSERT_MSG( M_BMPDATA
->m_bitmap
, wxT("couldn't create bitmap") ); 
 875 wxBitmap::~wxBitmap() 
 879 wxBitmap
& wxBitmap::operator = ( const wxBitmap
& bmp 
) 
 881     if ( m_refData 
!= bmp
.m_refData 
) 
 887 bool wxBitmap::operator == ( const wxBitmap
& bmp 
) const 
 889     return m_refData 
== bmp
.m_refData
; 
 892 bool wxBitmap::operator != ( const wxBitmap
& bmp 
) const 
 894     return m_refData 
!= bmp
.m_refData
; 
 897 bool wxBitmap::Ok() const 
 899     return (m_refData 
!= NULL
); 
 902 int wxBitmap::GetHeight() const 
 904     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 906     return M_BMPDATA
->m_height
; 
 909 int wxBitmap::GetWidth() const 
 911     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 913     return M_BMPDATA
->m_width
; 
 916 int wxBitmap::GetDepth() const 
 918     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 920     return M_BMPDATA
->m_bpp
; 
 923 wxMask 
*wxBitmap::GetMask() const 
 925     wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 927     return M_BMPDATA
->m_mask
; 
 930 void wxBitmap::SetMask( wxMask 
*mask 
) 
 932     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 934     if (M_BMPDATA
->m_mask
) delete M_BMPDATA
->m_mask
; 
 936     M_BMPDATA
->m_mask 
= mask
; 
 939 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 945 wxBitmap 
wxBitmap::GetSubBitmap( const wxRect
& rect
) const 
 948                  (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 949                  (rect
.x
+rect
.width 
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height 
<= M_BMPDATA
->m_height
), 
 950                  wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 952     wxBitmap 
ret( rect
.width
, rect
.height
, M_BMPDATA
->m_bpp 
); 
 953     wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 957         GdkGC 
*gc 
= gdk_gc_new( ret
.GetPixmap() ); 
 958         gdk_draw_pixmap( ret
.GetPixmap(), gc
, GetPixmap(), rect
.x
, rect
.y
, 0, 0, rect
.width
, rect
.height 
); 
 959         gdk_gc_destroy( gc 
); 
 963         GdkGC 
*gc 
= gdk_gc_new( ret
.GetBitmap() ); 
 964         gdk_wx_draw_bitmap( ret
.GetBitmap(), gc
, GetBitmap(), rect
.x
, rect
.y
, 0, 0, rect
.width
, rect
.height 
); 
 965         gdk_gc_destroy( gc 
); 
 970         wxMask 
*mask 
= new wxMask
; 
 971         mask
->m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, rect
.width
, rect
.height
, 1 ); 
 973         GdkGC 
*gc 
= gdk_gc_new( mask
->m_bitmap 
); 
 974         gdk_wx_draw_bitmap( mask
->m_bitmap
, gc
, M_BMPDATA
->m_mask
->m_bitmap
, 0, 0, rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 975         gdk_gc_destroy( gc 
); 
 983 bool wxBitmap::SaveFile( const wxString 
&name
, int type
, wxPalette 
*WXUNUSED(palette
) ) 
 985     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") ); 
 987     // Try to save the bitmap via wxImage handlers: 
 989         wxImage image 
= ConvertToImage(); 
 990         if (image
.Ok()) return image
.SaveFile( name
, type 
); 
 996 bool wxBitmap::LoadFile( const wxString 
&name
, int type 
) 
1000     if (!wxFileExists(name
)) 
1003     GdkVisual 
*visual 
= wxTheApp
->GetGdkVisual(); 
1005     if (type 
== wxBITMAP_TYPE_XPM
) 
1007         m_refData 
= new wxBitmapRefData(); 
1009         GdkBitmap 
*mask 
= (GdkBitmap
*) NULL
; 
1011         M_BMPDATA
->m_pixmap 
= gdk_pixmap_create_from_xpm
 
1013                                 wxGetRootWindow()->window
, 
1021            M_BMPDATA
->m_mask 
= new wxMask(); 
1022            M_BMPDATA
->m_mask
->m_bitmap 
= mask
; 
1025         gdk_window_get_size( M_BMPDATA
->m_pixmap
, &(M_BMPDATA
->m_width
), &(M_BMPDATA
->m_height
) ); 
1027         M_BMPDATA
->m_bpp 
= visual
->depth
; 
1029     else // try if wxImage can load it 
1032         if ( !image
.LoadFile( name
, type 
) || !image
.Ok() ) 
1035         *this = wxBitmap(image
); 
1041 wxPalette 
*wxBitmap::GetPalette() const 
1044         return (wxPalette 
*) NULL
; 
1046     return M_BMPDATA
->m_palette
; 
1049 void wxBitmap::SetHeight( int height 
) 
1052         m_refData 
= new wxBitmapRefData(); 
1054     M_BMPDATA
->m_height 
= height
; 
1057 void wxBitmap::SetWidth( int width 
) 
1060         m_refData 
= new wxBitmapRefData(); 
1062     M_BMPDATA
->m_width 
= width
; 
1065 void wxBitmap::SetDepth( int depth 
) 
1068         m_refData 
= new wxBitmapRefData(); 
1070     M_BMPDATA
->m_bpp 
= depth
; 
1073 void wxBitmap::SetPixmap( GdkPixmap 
*pixmap 
) 
1076         m_refData 
= new wxBitmapRefData(); 
1078     M_BMPDATA
->m_pixmap 
= pixmap
; 
1081 void wxBitmap::SetBitmap( GdkPixmap 
*bitmap 
) 
1084         m_refData 
= new wxBitmapRefData(); 
1086     M_BMPDATA
->m_bitmap 
= bitmap
; 
1089 GdkPixmap 
*wxBitmap::GetPixmap() const 
1091     wxCHECK_MSG( Ok(), (GdkPixmap 
*) NULL
, wxT("invalid bitmap") ); 
1093     return M_BMPDATA
->m_pixmap
; 
1096 GdkBitmap 
*wxBitmap::GetBitmap() const 
1098     wxCHECK_MSG( Ok(), (GdkBitmap 
*) NULL
, wxT("invalid bitmap") ); 
1100     return M_BMPDATA
->m_bitmap
;