1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
18 #include "wx/palette.h"
19 #include "wx/bitmap.h"
22 #include "wx/control.h"
23 #include "wx/dcmemory.h"
28 #pragma message disable nosimpint
31 #pragma message enable nosimpint
34 #include "wx/x11/private.h"
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 wxBitmapRefData::wxBitmapRefData()
55 m_pixmap
= (WXPixmap
) 0;
56 m_display
= (WXDisplay
*) 0;
58 m_freePixmap
= TRUE
; //TODO: necessary?
59 m_freeColors
= (unsigned long*) 0;
60 m_freeColorsCount
= 0;
63 wxBitmapRefData::~wxBitmapRefData()
65 if (m_pixmap
&& m_freePixmap
)
66 XFreePixmap ((Display
*) m_display
, (Pixmap
) m_pixmap
);
70 int screen
= DefaultScreen((Display
*) m_display
);
71 Colormap cmp
= DefaultColormap((Display
*) m_display
,screen
);
73 for(llp
= 0;llp
< m_freeColorsCount
;llp
++)
74 XFreeColors((Display
*) m_display
, cmp
, &m_freeColors
[llp
], 1, 0L);
83 wxList
wxBitmap::sm_handlers
;
85 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
96 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
98 m_refData
= new wxBitmapRefData
;
100 (void) Create((void*) bits
, wxBITMAP_TYPE_XBM_DATA
, width
, height
, depth
);
103 wxBitmap::wxBitmap(int w
, int h
, int d
)
105 (void)Create(w
, h
, d
);
108 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
110 (void) Create(data
, type
, width
, height
, depth
);
113 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
115 LoadFile(filename
, (int)type
);
118 bool wxBitmap::Create(int w
, int h
, int d
)
122 m_refData
= new wxBitmapRefData
;
125 d
= wxDisplayDepth();
127 M_BITMAPDATA
->m_width
= w
;
128 M_BITMAPDATA
->m_height
= h
;
129 M_BITMAPDATA
->m_depth
= d
;
130 M_BITMAPDATA
->m_freePixmap
= TRUE
;
132 Display
*dpy
= (Display
*) wxGetDisplay();
134 M_BITMAPDATA
->m_display
= dpy
; /* MATTHEW: [4] Remember the display */
136 M_BITMAPDATA
->m_pixmap
= (WXPixmap
) XCreatePixmap (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
139 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_pixmap
!= (WXPixmap
) 0) ;
140 return M_BITMAPDATA
->m_ok
;
143 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
147 m_refData
= new wxBitmapRefData
;
149 wxBitmapHandler
*handler
= FindHandler(type
);
151 if ( handler
== NULL
) {
153 if (!image
.LoadFile( filename
, type
)) return FALSE
;
156 *this = image
.ConvertToBitmap();
162 return handler
->LoadFile(this, filename
, type
, -1, -1);
165 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
169 m_refData
= new wxBitmapRefData
;
171 wxBitmapHandler
*handler
= FindHandler(type
);
173 if ( handler
== NULL
) {
174 wxLogWarning("no data bitmap handler for type %d defined.", type
);
179 return handler
->Create(this, data
, type
, width
, height
, depth
);
182 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
184 wxBitmapHandler
*handler
= FindHandler(type
);
186 if ( handler
== NULL
) { // try wxImage
187 wxImage
image( *this );
188 if (image
.Ok()) return image
.SaveFile( filename
, type
);
192 return handler
->SaveFile(this, filename
, type
, palette
);
195 void wxBitmap::SetWidth(int w
)
198 m_refData
= new wxBitmapRefData
;
200 M_BITMAPDATA
->m_width
= w
;
203 void wxBitmap::SetHeight(int h
)
206 m_refData
= new wxBitmapRefData
;
208 M_BITMAPDATA
->m_height
= h
;
211 void wxBitmap::SetDepth(int d
)
214 m_refData
= new wxBitmapRefData
;
216 M_BITMAPDATA
->m_depth
= d
;
219 void wxBitmap::SetQuality(int q
)
222 m_refData
= new wxBitmapRefData
;
224 M_BITMAPDATA
->m_quality
= q
;
227 void wxBitmap::SetOk(bool isOk
)
230 m_refData
= new wxBitmapRefData
;
232 M_BITMAPDATA
->m_ok
= isOk
;
235 void wxBitmap::SetPalette(const wxPalette
& palette
)
238 m_refData
= new wxBitmapRefData
;
240 M_BITMAPDATA
->m_bitmapPalette
= palette
;
243 void wxBitmap::SetMask(wxMask
*mask
)
246 m_refData
= new wxBitmapRefData
;
248 M_BITMAPDATA
->m_bitmapMask
= mask
;
251 wxBitmap
wxBitmap::GetSubBitmap( const wxRect
& rect
) const
254 (rect
.x
>= 0) && (rect
.y
>= 0) &&
255 (rect
.x
+rect
.width
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height
<= M_BMPDATA
->m_height
),
256 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
258 wxBitmap
ret( rect
.width
, rect
.height
, 0 );
259 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
261 // The remaining still TODO
265 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
267 sm_handlers
.Append(handler
);
270 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
272 sm_handlers
.Insert(handler
);
275 bool wxBitmap::RemoveHandler(const wxString
& name
)
277 wxBitmapHandler
*handler
= FindHandler(name
);
280 sm_handlers
.DeleteObject(handler
);
287 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
289 wxNode
*node
= sm_handlers
.First();
292 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
293 if ( handler
->GetName() == name
)
300 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
302 wxNode
*node
= sm_handlers
.First();
305 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
306 if ( handler
->GetExtension() == extension
&&
307 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
314 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
316 wxNode
*node
= sm_handlers
.First();
319 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
320 if (handler
->GetType() == bitmapType
)
333 m_pixmap
= (WXPixmap
) 0;
336 // Construct a mask from a bitmap and a colour indicating
337 // the transparent area
338 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
340 m_pixmap
= (WXPixmap
) 0;
342 Create(bitmap
, colour
);
345 // Construct a mask from a bitmap and a palette index indicating
346 // the transparent area
347 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
349 m_pixmap
= (WXPixmap
) 0;
351 Create(bitmap
, paletteIndex
);
354 // Construct a mask from a mono bitmap (copies the bitmap).
355 wxMask::wxMask(const wxBitmap
& bitmap
)
357 m_pixmap
= (WXPixmap
) 0;
364 // TODO: this may be the wrong display
366 XFreePixmap ((Display
*) wxGetDisplay(), (Pixmap
) m_pixmap
);
369 // Create a mask from a mono bitmap (copies the bitmap).
370 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
))
376 // Create a mask from a bitmap and a palette index indicating
377 // the transparent area
378 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), int WXUNUSED(paletteIndex
))
384 // Create a mask from a bitmap and a colour indicating
385 // the transparent area
386 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), const wxColour
& WXUNUSED(colour
))
396 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
398 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
),
399 int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
404 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
405 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
410 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
),
411 const wxPalette
*WXUNUSED(palette
))
420 class WXDLLEXPORT wxXBMFileHandler
: public wxBitmapHandler
422 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler
)
424 inline wxXBMFileHandler()
428 m_type
= wxBITMAP_TYPE_XBM
;
431 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
432 int desiredWidth
, int desiredHeight
);
434 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler
, wxBitmapHandler
)
436 bool wxXBMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
437 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
439 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
445 Display
*dpy
= (Display
*) wxGetDisplay();
446 M_BITMAPDATA
->m_display
= (WXDisplay
*) dpy
;
448 int value
= XReadBitmapFile (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
449 (char*) (const char*) name
, &w
, &h
, &pixmap
, &hotX
, &hotY
);
450 M_BITMAPHANDLERDATA
->m_width
= w
;
451 M_BITMAPHANDLERDATA
->m_height
= h
;
452 M_BITMAPHANDLERDATA
->m_depth
= 1;
453 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
455 if ((value
== BitmapFileInvalid
) ||
456 (value
== BitmapOpenFailed
) ||
457 (value
== BitmapNoMemory
))
459 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
460 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) 0;
463 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
465 return M_BITMAPHANDLERDATA
->m_ok
;
468 class WXDLLEXPORT wxXBMDataHandler
: public wxBitmapHandler
470 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler
)
472 inline wxXBMDataHandler()
476 m_type
= wxBITMAP_TYPE_XBM_DATA
;
479 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
481 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler
, wxBitmapHandler
)
483 bool wxXBMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
484 int width
, int height
, int WXUNUSED(depth
))
486 M_BITMAPHANDLERDATA
->m_width
= width
;
487 M_BITMAPHANDLERDATA
->m_height
= height
;
488 M_BITMAPHANDLERDATA
->m_depth
= 1;
489 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
491 Display
*dpy
= (Display
*) wxGetDisplay();
492 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
494 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) XCreateBitmapFromData (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)), (char*) data
, width
, height
);
495 M_BITMAPHANDLERDATA
->m_ok
= (M_BITMAPHANDLERDATA
->m_pixmap
!= (WXPixmap
) 0) ;
500 void wxBitmap::CleanUpHandlers()
502 wxNode
*node
= sm_handlers
.First();
505 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
506 wxNode
*next
= node
->Next();
513 void wxBitmap::InitStandardHandlers()
515 // Initialize all standard bitmap or derived class handlers here.
516 AddHandler(new wxXBMFileHandler
);
517 AddHandler(new wxXBMDataHandler
);
519 // XPM will be handled by wxImage
522 // Creates a bitmap with transparent areas drawn in
524 wxBitmap
wxCreateMaskedBitmap(const wxBitmap
& bitmap
, wxColour
& colour
)
526 wxBitmap
newBitmap(bitmap
.GetWidth(),
531 srcDC
.SelectObject(bitmap
);
532 destDC
.SelectObject(newBitmap
);
534 wxBrush
brush(colour
, wxSOLID
);
535 destDC
.SetOptimization(FALSE
);
536 destDC
.SetBackground(brush
);
538 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);
543 //-----------------------------------------------------------------------------
544 // wxImage conversion routines
545 //-----------------------------------------------------------------------------
549 Date: Wed, 05 Jan 2000 11:45:40 +0100
550 From: Frits Boel <boel@niob.knaw.nl>
551 To: julian.smart@ukonline.co.uk
552 Subject: Patch for Motif ConvertToBitmap
556 I've been working on a wxWin application for image processing. From the
557 beginning, I was surprised by the (lack of) speed of ConvertToBitmap,
558 till I looked in the source code of image.cpp. I saw that converting a
559 wxImage to a bitmap with 8-bit pixels is done with comparing every pixel
560 to the 256 colors of the palet. A very time-consuming piece of code!
562 Because I wanted a faster application, I've made a 'patch' for this. In
563 short: every pixel of the image is compared to a sorted list with
564 colors. If the color is found in the list, the palette entry is
565 returned; if the color is not found, the color palette is searched and
566 then the palette entry is returned and the color added to the sorted
569 Maybe there is another method for this, namely changing the palette
570 itself (if the colors are known, as is the case with tiffs with a
571 colormap). I did not look at this, maybe someone else did?
573 The code of the patch is attached, have a look on it, and maybe you will
574 ship it with the next release of wxMotif?
579 Software engineer at Hubrecht Laboratory, The Netherlands.
586 wxSearchColor( void );
587 wxSearchColor( int size
, XColor
*colors
);
588 ~wxSearchColor( void );
590 int SearchColor( int r
, int g
, int b
);
592 int AddColor( unsigned int value
, int pos
);
603 wxSearchColor::wxSearchColor( void )
606 colors
= (XColor
*) NULL
;
607 color
= (unsigned int *) NULL
;
614 wxSearchColor::wxSearchColor( int size_
, XColor
*colors_
)
619 color
= new unsigned int[size
];
620 entry
= new int [size
];
622 for (i
= 0; i
< size
; i
++ ) {
626 bottom
= top
= ( size
>> 1 );
629 wxSearchColor::~wxSearchColor( void )
631 if ( color
) delete color
;
632 if ( entry
) delete entry
;
635 int wxSearchColor::SearchColor( int r
, int g
, int b
)
637 unsigned int value
= ( ( ( r
* 256 ) + g
) * 256 ) + b
;
642 while ( begin
<= end
) {
644 middle
= ( begin
+ end
) >> 1;
646 if ( value
== color
[middle
] ) {
647 return( entry
[middle
] );
648 } else if ( value
< color
[middle
] ) {
656 return AddColor( value
, middle
);
659 int wxSearchColor::AddColor( unsigned int value
, int pos
)
663 int max
= 3 * (65536);
664 for ( i
= 0; i
< 256; i
++ ) {
665 int rdiff
= ((value
>> 8) & 0xFF00 ) - colors
[i
].red
;
666 int gdiff
= ((value
) & 0xFF00 ) - colors
[i
].green
;
667 int bdiff
= ((value
<< 8) & 0xFF00 ) - colors
[i
].blue
;
668 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
669 if (sum
< max
) { pixel
= i
; max
= sum
; }
672 if ( entry
[pos
] < 0 ) {
675 } else if ( value
< color
[pos
] ) {
678 for ( i
= bottom
; i
< pos
; i
++ ) {
679 color
[i
-1] = color
[i
];
680 entry
[i
-1] = entry
[i
];
683 color
[pos
-1] = value
;
684 entry
[pos
-1] = pixel
;
685 } else if ( top
< size
-1 ) {
686 for ( i
= top
; i
>= pos
; i
-- ) {
687 color
[i
+1] = color
[i
];
688 entry
[i
+1] = entry
[i
];
697 if ( top
< size
-1 ) {
698 for ( i
= top
; i
> pos
; i
-- ) {
699 color
[i
+1] = color
[i
];
700 entry
[i
+1] = entry
[i
];
703 color
[pos
+1] = value
;
704 entry
[pos
+1] = pixel
;
705 } else if ( bottom
> 0 ) {
706 for ( i
= bottom
; i
< pos
; i
++ ) {
707 color
[i
-1] = color
[i
];
708 entry
[i
-1] = entry
[i
];
721 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth
)
723 wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") )
724 wxCHECK_MSG( depth
== -1, FALSE
, wxT("invalid bitmap depth") )
726 m_refData
= new wxBitmapRefData();
728 int width
= image
.GetWidth();
729 int height
= image
.GetHeight();
734 Display
*dpy
= (Display
*) wxGetDisplay();
735 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
736 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
740 XImage
*data_image
= XCreateImage( dpy
, vis
, bpp
, ZPixmap
, 0, 0, width
, height
, 32, 0 );
741 data_image
->data
= (char*) malloc( data_image
->bytes_per_line
* data_image
->height
);
743 Create( width
, height
, bpp
);
747 XImage
*mask_image
= (XImage
*) NULL
;
750 mask_image
= XCreateImage( dpy
, vis
, 1, ZPixmap
, 0, 0, width
, height
, 32, 0 );
751 mask_image
->data
= (char*) malloc( mask_image
->bytes_per_line
* mask_image
->height
);
754 // Retrieve depth info
756 XVisualInfo vinfo_template
;
759 vinfo_template
.visual
= vis
;
760 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
761 vinfo_template
.depth
= bpp
;
764 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
766 wxCHECK_MSG( vi
, FALSE
, wxT("no visual") );
770 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
771 if (bpp
< 8) bpp
= 8;
775 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
776 byte_order b_o
= RGB
;
780 if ((vi
->red_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->blue_mask
)) b_o
= RGB
;
781 else if ((vi
->red_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->green_mask
)) b_o
= RGB
;
782 else if ((vi
->blue_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->green_mask
)) b_o
= BRG
;
783 else if ((vi
->blue_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->red_mask
)) b_o
= BGR
;
784 else if ((vi
->green_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->blue_mask
)) b_o
= GRB
;
785 else if ((vi
->green_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->red_mask
)) b_o
= GBR
;
788 int r_mask
= image
.GetMaskRed();
789 int g_mask
= image
.GetMaskGreen();
790 int b_mask
= image
.GetMaskBlue();
795 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap( dpy
);
797 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
798 XQueryColors( dpy
, cmap
, colors
, 256 );
801 wxSearchColor
scolor( 256, colors
);
802 unsigned char* data
= image
.GetData();
804 bool hasMask
= image
.HasMask();
807 for (int y
= 0; y
< height
; y
++)
809 for (int x
= 0; x
< width
; x
++)
820 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
821 XPutPixel( mask_image
, x
, y
, 0 );
823 XPutPixel( mask_image
, x
, y
, 1 );
830 #if 0 // Old, slower code
833 if (wxTheApp->m_colorCube)
835 pixel = wxTheApp->m_colorCube
836 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
841 int max
= 3 * (65536);
842 for (int i
= 0; i
< 256; i
++)
844 int rdiff
= (r
<< 8) - colors
[i
].red
;
845 int gdiff
= (g
<< 8) - colors
[i
].green
;
846 int bdiff
= (b
<< 8) - colors
[i
].blue
;
847 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
848 if (sum
< max
) { pixel
= i
; max
= sum
; }
855 // And this is all to get the 'right' color...
856 int pixel
= scolor
.SearchColor( r
, g
, b
);
857 XPutPixel( data_image
, x
, y
, pixel
);
862 int pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
863 XPutPixel( data_image
, x
, y
, pixel
);
868 int pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
869 XPutPixel( data_image
, x
, y
, pixel
);
878 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
879 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
880 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
881 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
882 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
883 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
885 XPutPixel( data_image
, x
, y
, pixel
);
895 gcvalues
.foreground
= BlackPixel( dpy
, DefaultScreen( dpy
) );
896 GC gc
= XCreateGC( dpy
, RootWindow ( dpy
, DefaultScreen(dpy
) ), GCForeground
, &gcvalues
);
897 XPutImage( dpy
, (Drawable
)GetPixmap(), gc
, data_image
, 0, 0, 0, 0, width
, height
);
899 XDestroyImage( data_image
);
905 wxBitmap
maskBitmap(width
, height
, 1);
907 GC gcMask
= XCreateGC( dpy
, (Pixmap
) maskBitmap
.GetPixmap(), 0, (XGCValues
*)NULL
);
908 XPutImage( dpy
, (Drawable
)maskBitmap
.GetPixmap(), gcMask
, mask_image
, 0, 0, 0, 0, width
, height
);
910 XDestroyImage( mask_image
);
911 XFreeGC( dpy
, gcMask
);
913 wxMask
* mask
= new wxMask
;
914 mask
->SetPixmap(maskBitmap
.GetPixmap());
918 maskBitmap
.SetPixmapNull();
925 wxImage
wxBitmap::ConvertToImage() const
929 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
931 Display
*dpy
= (Display
*) wxGetDisplay();
932 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
933 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
935 XImage
*ximage
= XGetImage( dpy
,
936 (Drawable
)GetPixmap(),
938 GetWidth(), GetHeight(),
939 AllPlanes
, ZPixmap
);
941 wxCHECK_MSG( ximage
, wxNullImage
, wxT("couldn't create image") );
943 image
.Create( GetWidth(), GetHeight() );
944 char unsigned *data
= image
.GetData();
948 XDestroyImage( ximage
);
949 wxFAIL_MSG( wxT("couldn't create image") );
954 GdkImage *gdk_image_mask = (GdkImage*) NULL;
957 gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
959 GetWidth(), GetHeight() );
961 image.SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
965 // Retrieve depth info
967 XVisualInfo vinfo_template
;
970 vinfo_template
.visual
= vis
;
971 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
972 vinfo_template
.depth
= bpp
;
975 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
977 wxCHECK_MSG( vi
, wxNullImage
, wxT("no visual") );
979 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
986 Colormap cmap
= (Colormap
)wxTheApp
->GetMainColormap( dpy
);
988 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
989 XQueryColors( dpy
, cmap
, colors
, 256 );
993 for (int j
= 0; j
< GetHeight(); j
++)
995 for (int i
= 0; i
< GetWidth(); i
++)
997 int pixel
= XGetPixel( ximage
, i
, j
);
1000 data
[pos
] = colors
[pixel
].red
>> 8;
1001 data
[pos
+1] = colors
[pixel
].green
>> 8;
1002 data
[pos
+2] = colors
[pixel
].blue
>> 8;
1003 } else if (bpp
== 15)
1005 data
[pos
] = (pixel
>> 7) & 0xf8;
1006 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1007 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1008 } else if (bpp
== 16)
1010 data
[pos
] = (pixel
>> 8) & 0xf8;
1011 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1012 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1015 data
[pos
] = (pixel
>> 16) & 0xff;
1016 data
[pos
+1] = (pixel
>> 8) & 0xff;
1017 data
[pos
+2] = pixel
& 0xff;
1023 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1024 if (mask_pixel == 0)
1037 XDestroyImage( ximage
);
1039 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
1045 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)