Minor changes.
[wxWidgets.git] / src / gtk1 / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // RCS-ID: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "bitmap.h"
12 #endif
13
14 #include "wx/bitmap.h"
15 #include "wx/icon.h"
16 #include "wx/filefn.h"
17 #include "wx/image.h"
18
19 #include <gdk/gdk.h>
20 #include <gdk/gdkprivate.h>
21 #include <gdk/gdkx.h>
22
23 //-----------------------------------------------------------------------------
24 // wxMask
25 //-----------------------------------------------------------------------------
26
27 IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
28
29 wxMask::wxMask()
30 {
31 m_bitmap = (GdkBitmap *) NULL;
32 }
33
34 wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
35 {
36 m_bitmap = (GdkBitmap *) NULL;
37 Create( bitmap, colour );
38 }
39
40 wxMask::wxMask( const wxBitmap& bitmap, int paletteIndex )
41 {
42 m_bitmap = (GdkBitmap *) NULL;
43 Create( bitmap, paletteIndex );
44 }
45
46 wxMask::wxMask( const wxBitmap& bitmap )
47 {
48 m_bitmap = (GdkBitmap *) NULL;
49 Create( bitmap );
50 }
51
52 wxMask::~wxMask()
53 {
54 if (m_bitmap)
55 gdk_bitmap_unref( m_bitmap );
56 }
57
58 bool wxMask::Create( const wxBitmap& WXUNUSED(bitmap),
59 const wxColour& WXUNUSED(colour) )
60 {
61 if (m_bitmap)
62 {
63 gdk_bitmap_unref( m_bitmap );
64 m_bitmap = (GdkBitmap*) NULL;
65 }
66
67 wxFAIL_MSG( wxT("TODO") );
68
69 return FALSE;
70 }
71
72 bool wxMask::Create( const wxBitmap& WXUNUSED(bitmap),
73 int WXUNUSED(paletteIndex) )
74 {
75 if (m_bitmap)
76 {
77 gdk_bitmap_unref( m_bitmap );
78 m_bitmap = (GdkBitmap*) NULL;
79 }
80
81 wxFAIL_MSG( wxT("not implemented") );
82
83 return FALSE;
84 }
85
86 bool wxMask::Create( const wxBitmap& bitmap )
87 {
88 if (m_bitmap)
89 {
90 gdk_bitmap_unref( m_bitmap );
91 m_bitmap = (GdkBitmap*) NULL;
92 }
93
94 if (!bitmap.Ok()) return FALSE;
95
96 wxCHECK_MSG( bitmap.GetBitmap(), FALSE, wxT("Cannot create mask from colour bitmap") );
97
98 m_bitmap = gdk_pixmap_new( (GdkWindow*) &gdk_root_parent, bitmap.GetWidth(), bitmap.GetHeight(), 1 );
99
100 if (!m_bitmap) return FALSE;
101
102 GdkGC *gc = gdk_gc_new( m_bitmap );
103
104 gdk_draw_bitmap( m_bitmap, gc, bitmap.GetBitmap(), 0, 0, 0, 0, bitmap.GetWidth(), bitmap.GetHeight() );
105
106 gdk_gc_unref( gc );
107
108 return TRUE;
109 }
110
111 GdkBitmap *wxMask::GetBitmap() const
112 {
113 return m_bitmap;
114 }
115
116 //-----------------------------------------------------------------------------
117 // wxBitmap
118 //-----------------------------------------------------------------------------
119
120 class wxBitmapRefData: public wxObjectRefData
121 {
122 public:
123 wxBitmapRefData();
124 ~wxBitmapRefData();
125
126 GdkPixmap *m_pixmap;
127 GdkBitmap *m_bitmap;
128 wxMask *m_mask;
129 int m_width;
130 int m_height;
131 int m_bpp;
132 wxPalette *m_palette;
133 };
134
135 wxBitmapRefData::wxBitmapRefData()
136 {
137 m_pixmap = (GdkPixmap *) NULL;
138 m_bitmap = (GdkBitmap *) NULL;
139 m_mask = (wxMask *) NULL;
140 m_width = 0;
141 m_height = 0;
142 m_bpp = 0;
143 m_palette = (wxPalette *) NULL;
144 }
145
146 wxBitmapRefData::~wxBitmapRefData()
147 {
148 if (m_pixmap) gdk_pixmap_unref( m_pixmap );
149 if (m_bitmap) gdk_bitmap_unref( m_bitmap );
150 if (m_mask) delete m_mask;
151 if (m_palette) delete m_palette;
152 }
153
154 //-----------------------------------------------------------------------------
155
156 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
157
158 IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxGDIObject)
159
160 wxBitmap::wxBitmap()
161 {
162 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
163 }
164
165 wxBitmap::wxBitmap( int width, int height, int depth )
166 {
167 wxCHECK_RET( (width > 0) && (height > 0), wxT("invalid bitmap size") )
168
169 GdkWindow *parent = (GdkWindow*) &gdk_root_parent;
170 if (depth == -1) depth = gdk_window_get_visual( parent )->depth;
171
172 wxCHECK_RET( (depth == gdk_window_get_visual( parent )->depth) ||
173 (depth == 1), wxT("invalid bitmap depth") )
174
175 m_refData = new wxBitmapRefData();
176 M_BMPDATA->m_mask = (wxMask *) NULL;
177 M_BMPDATA->m_width = width;
178 M_BMPDATA->m_height = height;
179 if (depth == 1)
180 {
181 M_BMPDATA->m_bitmap = gdk_pixmap_new( parent, width, height, 1 );
182 M_BMPDATA->m_bpp = 1;
183 }
184 else
185 {
186 M_BMPDATA->m_pixmap = gdk_pixmap_new( parent, width, height, depth );
187 M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth;
188 }
189
190 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
191 }
192
193 wxBitmap::wxBitmap( const char **bits )
194 {
195 wxCHECK_RET( bits != NULL, wxT("invalid bitmap data") )
196
197 m_refData = new wxBitmapRefData();
198
199 GdkBitmap *mask = (GdkBitmap*) NULL;
200 GdkWindow *parent = (GdkWindow*) &gdk_root_parent;
201
202 M_BMPDATA->m_pixmap = gdk_pixmap_create_from_xpm_d( parent, &mask, NULL, (gchar **) bits );
203
204 if (mask)
205 {
206 M_BMPDATA->m_mask = new wxMask();
207 M_BMPDATA->m_mask->m_bitmap = mask;
208 }
209
210 gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
211
212 M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth; // ?
213 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
214 }
215
216 wxBitmap::wxBitmap( char **bits )
217 {
218 wxCHECK_RET( bits != NULL, wxT("invalid bitmap data") )
219
220 m_refData = new wxBitmapRefData();
221
222 GdkBitmap *mask = (GdkBitmap*) NULL;
223 GdkWindow *parent = (GdkWindow*) &gdk_root_parent;
224
225 M_BMPDATA->m_pixmap = gdk_pixmap_create_from_xpm_d( parent, &mask, NULL, (gchar **) bits );
226
227 wxCHECK_RET( M_BMPDATA->m_pixmap, wxT("couldn't create pixmap") );
228
229 if (mask)
230 {
231 M_BMPDATA->m_mask = new wxMask();
232 M_BMPDATA->m_mask->m_bitmap = mask;
233 }
234
235 gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
236
237 M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth; // ?
238 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
239 }
240
241 wxBitmap::wxBitmap( const wxBitmap& bmp )
242 {
243 Ref( bmp );
244
245 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
246 }
247
248 wxBitmap::wxBitmap( const wxString &filename, int type )
249 {
250 LoadFile( filename, type );
251
252 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
253 }
254
255 wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth))
256 {
257 m_refData = new wxBitmapRefData();
258
259 M_BMPDATA->m_mask = (wxMask *) NULL;
260 M_BMPDATA->m_bitmap =
261 gdk_bitmap_create_from_data( (GdkWindow*) &gdk_root_parent, (gchar *) bits, width, height );
262 M_BMPDATA->m_width = width;
263 M_BMPDATA->m_height = height;
264 M_BMPDATA->m_bpp = 1;
265
266 wxCHECK_RET( M_BMPDATA->m_bitmap, wxT("couldn't create bitmap") );
267
268 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
269 }
270
271 wxBitmap::~wxBitmap()
272 {
273 if (wxTheBitmapList) wxTheBitmapList->DeleteObject(this);
274 }
275
276 wxBitmap& wxBitmap::operator = ( const wxBitmap& bmp )
277 {
278 if (*this == bmp) return (*this);
279 Ref( bmp );
280 return *this;
281 }
282
283 bool wxBitmap::operator == ( const wxBitmap& bmp )
284 {
285 return m_refData == bmp.m_refData;
286 }
287
288 bool wxBitmap::operator != ( const wxBitmap& bmp )
289 {
290 return m_refData != bmp.m_refData;
291 }
292
293 bool wxBitmap::Ok() const
294 {
295 return (m_refData != NULL);
296 }
297
298 int wxBitmap::GetHeight() const
299 {
300 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
301
302 return M_BMPDATA->m_height;
303 }
304
305 int wxBitmap::GetWidth() const
306 {
307 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
308
309 return M_BMPDATA->m_width;
310 }
311
312 int wxBitmap::GetDepth() const
313 {
314 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
315
316 return M_BMPDATA->m_bpp;
317 }
318
319 wxMask *wxBitmap::GetMask() const
320 {
321 wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
322
323 return M_BMPDATA->m_mask;
324 }
325
326 void wxBitmap::SetMask( wxMask *mask )
327 {
328 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
329
330 if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
331
332 M_BMPDATA->m_mask = mask;
333 }
334
335 bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(palette) )
336 {
337 wxCHECK_MSG( Ok(), FALSE, wxT("invalid bitmap") );
338
339 // Try to save the bitmap via wxImage handlers:
340 {
341 wxImage image( *this );
342 if (image.Ok()) return image.SaveFile( name, type );
343 }
344
345 return FALSE;
346 }
347
348 bool wxBitmap::LoadFile( const wxString &name, int type )
349 {
350 UnRef();
351
352 if (!wxFileExists(name)) return FALSE;
353
354 if (type == wxBITMAP_TYPE_XPM)
355 {
356 m_refData = new wxBitmapRefData();
357
358 GdkBitmap *mask = (GdkBitmap*) NULL;
359 GdkWindow *parent = (GdkWindow*) &gdk_root_parent;
360
361 M_BMPDATA->m_pixmap = gdk_pixmap_create_from_xpm( parent, &mask, NULL, name.fn_str() );
362
363 if (mask)
364 {
365 M_BMPDATA->m_mask = new wxMask();
366 M_BMPDATA->m_mask->m_bitmap = mask;
367 }
368
369 gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
370 M_BMPDATA->m_bpp = gdk_window_get_visual( parent )->depth;
371 }
372 else // try if wxImage can load it
373 {
374 wxImage image;
375 if (!image.LoadFile( name, type )) return FALSE;
376 if (image.Ok()) *this = image.ConvertToBitmap();
377 else return FALSE;
378 }
379
380 return TRUE;
381 }
382
383 wxPalette *wxBitmap::GetPalette() const
384 {
385 if (!Ok()) return (wxPalette *) NULL;
386
387 return M_BMPDATA->m_palette;
388 }
389
390 void wxBitmap::SetHeight( int height )
391 {
392 if (!m_refData) m_refData = new wxBitmapRefData();
393
394 M_BMPDATA->m_height = height;
395 }
396
397 void wxBitmap::SetWidth( int width )
398 {
399 if (!m_refData) m_refData = new wxBitmapRefData();
400
401 M_BMPDATA->m_width = width;
402 }
403
404 void wxBitmap::SetDepth( int depth )
405 {
406 if (!m_refData) m_refData = new wxBitmapRefData();
407
408 M_BMPDATA->m_bpp = depth;
409 }
410
411 void wxBitmap::SetPixmap( GdkPixmap *pixmap )
412 {
413 if (!m_refData) m_refData = new wxBitmapRefData();
414
415 M_BMPDATA->m_pixmap = pixmap;
416 }
417
418 GdkPixmap *wxBitmap::GetPixmap() const
419 {
420 wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, wxT("invalid bitmap") );
421
422 return M_BMPDATA->m_pixmap;
423 }
424
425 GdkBitmap *wxBitmap::GetBitmap() const
426 {
427 wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, wxT("invalid bitmap") );
428
429 return M_BMPDATA->m_bitmap;
430 }