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
);
535 wxBrush
brush(colour
, wxSOLID
);
536 destDC
.SetOptimization(FALSE
);
537 destDC
.SetBackground(brush
);
539 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);
545 //-----------------------------------------------------------------------------
546 // wxImage conversion routines
547 //-----------------------------------------------------------------------------
551 Date: Wed, 05 Jan 2000 11:45:40 +0100
552 From: Frits Boel <boel@niob.knaw.nl>
553 To: julian.smart@ukonline.co.uk
554 Subject: Patch for Motif ConvertToBitmap
558 I've been working on a wxWin application for image processing. From the
559 beginning, I was surprised by the (lack of) speed of ConvertToBitmap,
560 till I looked in the source code of image.cpp. I saw that converting a
561 wxImage to a bitmap with 8-bit pixels is done with comparing every pixel
562 to the 256 colors of the palet. A very time-consuming piece of code!
564 Because I wanted a faster application, I've made a 'patch' for this. In
565 short: every pixel of the image is compared to a sorted list with
566 colors. If the color is found in the list, the palette entry is
567 returned; if the color is not found, the color palette is searched and
568 then the palette entry is returned and the color added to the sorted
571 Maybe there is another method for this, namely changing the palette
572 itself (if the colors are known, as is the case with tiffs with a
573 colormap). I did not look at this, maybe someone else did?
575 The code of the patch is attached, have a look on it, and maybe you will
576 ship it with the next release of wxMotif?
581 Software engineer at Hubrecht Laboratory, The Netherlands.
588 wxSearchColor( void );
589 wxSearchColor( int size
, XColor
*colors
);
590 ~wxSearchColor( void );
592 int SearchColor( int r
, int g
, int b
);
594 int AddColor( unsigned int value
, int pos
);
605 wxSearchColor::wxSearchColor( void )
608 colors
= (XColor
*) NULL
;
609 color
= (unsigned int *) NULL
;
616 wxSearchColor::wxSearchColor( int size_
, XColor
*colors_
)
621 color
= new unsigned int[size
];
622 entry
= new int [size
];
624 for (i
= 0; i
< size
; i
++ ) {
628 bottom
= top
= ( size
>> 1 );
631 wxSearchColor::~wxSearchColor( void )
633 if ( color
) delete color
;
634 if ( entry
) delete entry
;
637 int wxSearchColor::SearchColor( int r
, int g
, int b
)
639 unsigned int value
= ( ( ( r
* 256 ) + g
) * 256 ) + b
;
644 while ( begin
<= end
) {
646 middle
= ( begin
+ end
) >> 1;
648 if ( value
== color
[middle
] ) {
649 return( entry
[middle
] );
650 } else if ( value
< color
[middle
] ) {
658 return AddColor( value
, middle
);
661 int wxSearchColor::AddColor( unsigned int value
, int pos
)
665 int max
= 3 * (65536);
666 for ( i
= 0; i
< 256; i
++ ) {
667 int rdiff
= ((value
>> 8) & 0xFF00 ) - colors
[i
].red
;
668 int gdiff
= ((value
) & 0xFF00 ) - colors
[i
].green
;
669 int bdiff
= ((value
<< 8) & 0xFF00 ) - colors
[i
].blue
;
670 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
671 if (sum
< max
) { pixel
= i
; max
= sum
; }
674 if ( entry
[pos
] < 0 ) {
677 } else if ( value
< color
[pos
] ) {
680 for ( i
= bottom
; i
< pos
; i
++ ) {
681 color
[i
-1] = color
[i
];
682 entry
[i
-1] = entry
[i
];
685 color
[pos
-1] = value
;
686 entry
[pos
-1] = pixel
;
687 } else if ( top
< size
-1 ) {
688 for ( i
= top
; i
>= pos
; i
-- ) {
689 color
[i
+1] = color
[i
];
690 entry
[i
+1] = entry
[i
];
699 if ( top
< size
-1 ) {
700 for ( i
= top
; i
> pos
; i
-- ) {
701 color
[i
+1] = color
[i
];
702 entry
[i
+1] = entry
[i
];
705 color
[pos
+1] = value
;
706 entry
[pos
+1] = pixel
;
707 } else if ( bottom
> 0 ) {
708 for ( i
= bottom
; i
< pos
; i
++ ) {
709 color
[i
-1] = color
[i
];
710 entry
[i
-1] = entry
[i
];
723 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth
)
725 wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") )
726 wxCHECK_MSG( depth
== -1, FALSE
, wxT("invalid bitmap depth") )
728 m_refData
= new wxBitmapRefData();
730 int width
= image
.GetWidth();
731 int height
= image
.GetHeight();
736 Display
*dpy
= (Display
*) wxGetDisplay();
737 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
738 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
742 XImage
*data_image
= XCreateImage( dpy
, vis
, bpp
, ZPixmap
, 0, 0, width
, height
, 32, 0 );
743 data_image
->data
= (char*) malloc( data_image
->bytes_per_line
* data_image
->height
);
745 Create( width
, height
, bpp
);
749 XImage
*mask_image
= (XImage
*) NULL
;
752 mask_image
= XCreateImage( dpy
, vis
, 1, ZPixmap
, 0, 0, width
, height
, 32, 0 );
753 mask_image
->data
= (char*) malloc( mask_image
->bytes_per_line
* mask_image
->height
);
756 // Retrieve depth info
758 XVisualInfo vinfo_template
;
761 vinfo_template
.visual
= vis
;
762 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
763 vinfo_template
.depth
= bpp
;
766 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
768 wxCHECK_MSG( vi
, FALSE
, wxT("no visual") );
772 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
773 if (bpp
< 8) bpp
= 8;
777 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
778 byte_order b_o
= RGB
;
782 if ((vi
->red_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->blue_mask
)) b_o
= RGB
;
783 else if ((vi
->red_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->green_mask
)) b_o
= RGB
;
784 else if ((vi
->blue_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->green_mask
)) b_o
= BRG
;
785 else if ((vi
->blue_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->red_mask
)) b_o
= BGR
;
786 else if ((vi
->green_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->blue_mask
)) b_o
= GRB
;
787 else if ((vi
->green_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->red_mask
)) b_o
= GBR
;
790 int r_mask
= image
.GetMaskRed();
791 int g_mask
= image
.GetMaskGreen();
792 int b_mask
= image
.GetMaskBlue();
797 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap( dpy
);
799 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
800 XQueryColors( dpy
, cmap
, colors
, 256 );
803 wxSearchColor
scolor( 256, colors
);
804 unsigned char* data
= image
.GetData();
806 bool hasMask
= image
.HasMask();
809 for (int y
= 0; y
< height
; y
++)
811 for (int x
= 0; x
< width
; x
++)
822 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
823 XPutPixel( mask_image
, x
, y
, 0 );
825 XPutPixel( mask_image
, x
, y
, 1 );
832 #if 0 // Old, slower code
835 if (wxTheApp->m_colorCube)
837 pixel = wxTheApp->m_colorCube
838 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
843 int max
= 3 * (65536);
844 for (int i
= 0; i
< 256; i
++)
846 int rdiff
= (r
<< 8) - colors
[i
].red
;
847 int gdiff
= (g
<< 8) - colors
[i
].green
;
848 int bdiff
= (b
<< 8) - colors
[i
].blue
;
849 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
850 if (sum
< max
) { pixel
= i
; max
= sum
; }
857 // And this is all to get the 'right' color...
858 int pixel
= scolor
.SearchColor( r
, g
, b
);
859 XPutPixel( data_image
, x
, y
, pixel
);
864 int pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
865 XPutPixel( data_image
, x
, y
, pixel
);
870 int pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
871 XPutPixel( data_image
, x
, y
, pixel
);
880 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
881 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
882 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
883 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
884 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
885 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
887 XPutPixel( data_image
, x
, y
, pixel
);
897 gcvalues
.foreground
= BlackPixel( dpy
, DefaultScreen( dpy
) );
898 GC gc
= XCreateGC( dpy
, RootWindow ( dpy
, DefaultScreen(dpy
) ), GCForeground
, &gcvalues
);
899 XPutImage( dpy
, (Drawable
)GetPixmap(), gc
, data_image
, 0, 0, 0, 0, width
, height
);
901 XDestroyImage( data_image
);
907 wxBitmap
maskBitmap(width
, height
, 1);
909 GC gcMask
= XCreateGC( dpy
, (Pixmap
) maskBitmap
.GetPixmap(), 0, (XGCValues
*)NULL
);
910 XPutImage( dpy
, (Drawable
)maskBitmap
.GetPixmap(), gcMask
, mask_image
, 0, 0, 0, 0, width
, height
);
912 XDestroyImage( mask_image
);
913 XFreeGC( dpy
, gcMask
);
915 wxMask
* mask
= new wxMask
;
916 mask
->SetPixmap(maskBitmap
.GetPixmap());
920 maskBitmap
.SetPixmapNull();
927 wxImage
wxBitmap::ConvertToImage() const
931 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
933 Display
*dpy
= (Display
*) wxGetDisplay();
934 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
935 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
937 XImage
*ximage
= XGetImage( dpy
,
938 (Drawable
)GetPixmap(),
940 GetWidth(), GetHeight(),
941 AllPlanes
, ZPixmap
);
943 wxCHECK_MSG( ximage
, wxNullImage
, wxT("couldn't create image") );
945 image
.Create( GetWidth(), GetHeight() );
946 char unsigned *data
= image
.GetData();
950 XDestroyImage( ximage
);
951 wxFAIL_MSG( wxT("couldn't create image") );
956 GdkImage *gdk_image_mask = (GdkImage*) NULL;
959 gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
961 GetWidth(), GetHeight() );
963 image.SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
967 // Retrieve depth info
969 XVisualInfo vinfo_template
;
972 vinfo_template
.visual
= vis
;
973 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
974 vinfo_template
.depth
= bpp
;
977 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
979 wxCHECK_MSG( vi
, wxNullImage
, wxT("no visual") );
981 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
988 Colormap cmap
= (Colormap
)wxTheApp
->GetMainColormap( dpy
);
990 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
991 XQueryColors( dpy
, cmap
, colors
, 256 );
995 for (int j
= 0; j
< GetHeight(); j
++)
997 for (int i
= 0; i
< GetWidth(); i
++)
999 int pixel
= XGetPixel( ximage
, i
, j
);
1002 data
[pos
] = colors
[pixel
].red
>> 8;
1003 data
[pos
+1] = colors
[pixel
].green
>> 8;
1004 data
[pos
+2] = colors
[pixel
].blue
>> 8;
1005 } else if (bpp
== 15)
1007 data
[pos
] = (pixel
>> 7) & 0xf8;
1008 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1009 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1010 } else if (bpp
== 16)
1012 data
[pos
] = (pixel
>> 8) & 0xf8;
1013 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1014 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1017 data
[pos
] = (pixel
>> 16) & 0xff;
1018 data
[pos
+1] = (pixel
>> 8) & 0xff;
1019 data
[pos
+2] = pixel
& 0xff;
1025 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1026 if (mask_pixel == 0)
1039 XDestroyImage( ximage
);
1041 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
1047 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
1049 wxBitmap
* bitmap
= (wxBitmap
*) & icon
;