]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/bitmap.cpp
Removed usage of GdkImlib
[wxWidgets.git] / src / gtk / 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 "gdk/gdkprivate.h"
17 #include "gdk/gdkx.h"
18
19 //-----------------------------------------------------------------------------
20 // wxMask
21 //-----------------------------------------------------------------------------
22
23 IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
24
25 wxMask::wxMask(void)
26 {
27 m_bitmap = (GdkBitmap *) NULL;
28 }
29
30 wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), const wxColour& WXUNUSED(colour) )
31 {
32 }
33
34 wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), int WXUNUSED(paletteIndex) )
35 {
36 }
37
38 wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap) )
39 {
40 }
41
42 wxMask::~wxMask(void)
43 {
44 if (m_bitmap) gdk_bitmap_unref( m_bitmap );
45 }
46
47 GdkBitmap *wxMask::GetBitmap(void) const
48 {
49 return m_bitmap;
50 }
51
52 //-----------------------------------------------------------------------------
53 // wxBitmap
54 //-----------------------------------------------------------------------------
55
56 class wxBitmapRefData: public wxObjectRefData
57 {
58 public:
59
60 wxBitmapRefData(void);
61 ~wxBitmapRefData(void);
62
63 GdkPixmap *m_pixmap;
64 GdkBitmap *m_bitmap;
65 wxMask *m_mask;
66 int m_width;
67 int m_height;
68 int m_bpp;
69 wxPalette *m_palette;
70 };
71
72 wxBitmapRefData::wxBitmapRefData(void)
73 {
74 m_pixmap = (GdkPixmap *) NULL;
75 m_bitmap = (GdkBitmap *) NULL;
76 m_mask = (wxMask *) NULL;
77 m_width = 0;
78 m_height = 0;
79 m_bpp = 0;
80 m_palette = (wxPalette *) NULL;
81 }
82
83 wxBitmapRefData::~wxBitmapRefData(void)
84 {
85 if (m_pixmap) gdk_pixmap_unref( m_pixmap );
86 if (m_bitmap) gdk_bitmap_unref( m_bitmap );
87 if (m_mask) delete m_mask;
88 if (m_palette) delete m_palette;
89 }
90
91 //-----------------------------------------------------------------------------
92
93 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
94
95 IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxGDIObject)
96
97 wxBitmap::wxBitmap(void)
98 {
99 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
100 }
101
102 wxBitmap::wxBitmap( int width, int height, int depth )
103 {
104 m_refData = new wxBitmapRefData();
105 M_BMPDATA->m_mask = (wxMask *) NULL;
106 M_BMPDATA->m_pixmap =
107 gdk_pixmap_new( (GdkWindow*) &gdk_root_parent, width, height, depth );
108 M_BMPDATA->m_width = width;
109 M_BMPDATA->m_height = height;
110 M_BMPDATA->m_bpp = depth;
111
112 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
113 }
114
115 wxBitmap::wxBitmap( char **bits )
116 {
117 m_refData = new wxBitmapRefData();
118
119 GdkBitmap *mask = NULL;
120
121 M_BMPDATA->m_pixmap =
122 gdk_pixmap_create_from_xpm_d( (GdkWindow*) &gdk_root_parent, &mask, NULL, (gchar **) bits );
123
124 if (mask)
125 {
126 M_BMPDATA->m_mask = new wxMask();
127 M_BMPDATA->m_mask->m_bitmap = mask;
128 }
129
130 gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
131
132 M_BMPDATA->m_bpp = 24; // ?
133
134 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
135 }
136
137 wxBitmap::wxBitmap( const wxBitmap& bmp )
138 {
139 Ref( bmp );
140
141 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
142 }
143
144 wxBitmap::wxBitmap( const wxBitmap* bmp )
145 {
146 if (bmp) Ref( *bmp );
147
148 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
149 }
150
151 wxBitmap::wxBitmap( const wxString &filename, int type )
152 {
153 LoadFile( filename, type );
154
155 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
156 }
157
158 wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth))
159 {
160 m_refData = new wxBitmapRefData();
161
162 M_BMPDATA->m_mask = (wxMask *) NULL;
163 M_BMPDATA->m_bitmap =
164 gdk_bitmap_create_from_data( (GdkWindow*) &gdk_root_parent, (gchar *) bits, width, height );
165 M_BMPDATA->m_width = width;
166 M_BMPDATA->m_height = height;
167 M_BMPDATA->m_bpp = 1;
168
169 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
170 }
171
172 wxBitmap::~wxBitmap(void)
173 {
174 if (wxTheBitmapList) wxTheBitmapList->DeleteObject(this);
175 }
176
177 wxBitmap& wxBitmap::operator = ( const wxBitmap& bmp )
178 {
179 if (*this == bmp) return (*this);
180 Ref( bmp );
181 return *this;
182 }
183
184 bool wxBitmap::operator == ( const wxBitmap& bmp )
185 {
186 return m_refData == bmp.m_refData;
187 }
188
189 bool wxBitmap::operator != ( const wxBitmap& bmp )
190 {
191 return m_refData != bmp.m_refData;
192 }
193
194 bool wxBitmap::Ok(void) const
195 {
196 return (m_refData != NULL);
197 }
198
199 int wxBitmap::GetHeight(void) const
200 {
201 if (!Ok())
202 {
203 wxFAIL_MSG( "invalid bitmap" );
204 return -1;
205 }
206
207 return M_BMPDATA->m_height;
208 }
209
210 int wxBitmap::GetWidth(void) const
211 {
212 if (!Ok())
213 {
214 wxFAIL_MSG( "invalid bitmap" );
215 return -1;
216 }
217
218 return M_BMPDATA->m_width;
219 }
220
221 int wxBitmap::GetDepth(void) const
222 {
223 if (!Ok())
224 {
225 wxFAIL_MSG( "invalid bitmap" );
226 return -1;
227 }
228
229 return M_BMPDATA->m_bpp;
230 }
231
232 void wxBitmap::SetHeight( int height )
233 {
234 if (!Ok()) return;
235
236 wxFAIL_MSG( "wxBitmap::SetHeight not implemented" );
237
238 M_BMPDATA->m_height = height;
239 }
240
241 void wxBitmap::SetWidth( int width )
242 {
243 if (!Ok()) return;
244
245 wxFAIL_MSG( "wxBitmap::SetWidth not implemented" );
246
247 M_BMPDATA->m_width = width;
248 }
249
250 void wxBitmap::SetDepth( int depth )
251 {
252 if (!Ok()) return;
253
254 wxFAIL_MSG( "wxBitmap::SetDepth not implemented" );
255
256 M_BMPDATA->m_bpp = depth;
257 }
258
259 wxMask *wxBitmap::GetMask(void) const
260 {
261 if (!Ok())
262 {
263 wxFAIL_MSG( "invalid bitmap" );
264 return (wxMask *) NULL;
265 }
266
267 return M_BMPDATA->m_mask;
268 }
269
270 void wxBitmap::SetMask( wxMask *mask )
271 {
272 if (!Ok())
273 {
274 wxFAIL_MSG( "invalid bitmap" );
275 return;
276 }
277
278 if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
279
280 M_BMPDATA->m_mask = mask;
281 }
282
283 bool wxBitmap::SaveFile( const wxString &WXUNUSED(name), int WXUNUSED(type),
284 wxPalette *WXUNUSED(palette) )
285 {
286 if (!Ok())
287 {
288 wxFAIL_MSG( "invalid bitmap" );
289 return FALSE;
290 }
291
292 return FALSE;
293 }
294
295 bool wxBitmap::LoadFile( const wxString &WXUNUSED(name), int WXUNUSED(type) )
296 {
297 if (!Ok())
298 {
299 wxFAIL_MSG( "invalid bitmap" );
300 return FALSE;
301 }
302
303 return FALSE;
304 }
305
306 wxPalette *wxBitmap::GetPalette(void) const
307 {
308 if (!Ok()) return (wxPalette *) NULL;
309 return M_BMPDATA->m_palette;
310 }
311
312 GdkPixmap *wxBitmap::GetPixmap(void) const
313 {
314 if (!Ok())
315 {
316 wxFAIL_MSG( "invalid bitmap" );
317 return (GdkPixmap *) NULL;
318 }
319
320 return M_BMPDATA->m_pixmap;
321 }
322
323 GdkBitmap *wxBitmap::GetBitmap(void) const
324 {
325 if (!Ok())
326 {
327 wxFAIL_MSG( "invalid bitmap" );
328 return (GdkBitmap *) NULL;
329 }
330
331 return M_BMPDATA->m_bitmap;
332 }
333
334 wxBitmap::wxBitmap( const wxImage &image )
335 {
336 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
337
338 if (!image.Ok()) return;
339
340 m_refData = new wxBitmapRefData();
341
342 M_BMPDATA->m_height = image.GetHeight();
343 M_BMPDATA->m_width = image.GetWidth();
344 int width = image.GetWidth();
345 int height = image.GetHeight();
346
347 // Create picture
348
349 GdkImage *data_image =
350 gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), width, height );
351
352 M_BMPDATA->m_pixmap =
353 gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, -1 );
354
355 // Create mask
356
357 GdkImage *mask_image = (GdkImage*) NULL;
358
359 if (image.HasMask())
360 {
361 unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height );
362
363 mask_image = gdk_image_new_bitmap( gdk_visual_get_system(), mask_data, width, height );
364
365 M_BMPDATA->m_mask = new wxMask();
366 M_BMPDATA->m_mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 );
367 }
368
369 // Retrieve depth
370
371 M_BMPDATA->m_bpp = data_image->depth;
372
373 int render_depth = 8;
374 if (M_BMPDATA->m_bpp > 8) render_depth = M_BMPDATA->m_bpp;
375
376 // Render
377
378 int r_mask = image.GetMaskRed();
379 int g_mask = image.GetMaskGreen();
380 int b_mask = image.GetMaskBlue();
381
382 unsigned char* data = image.GetData();
383
384 int index = 0;
385 for (int y = 0; y < height; y++)
386 for (int x = 0; x < width; x++)
387 {
388 int r = data[index];
389 index++;
390 int g = data[index];
391 index++;
392 int b = data[index];
393 index++;
394
395 if (image.HasMask())
396 {
397 if ((r == r_mask) && (b = b_mask) && (g = g_mask))
398 gdk_image_put_pixel( mask_image, x, y, 0 );
399 else
400 gdk_image_put_pixel( mask_image, x, y, 1 );
401 }
402
403 switch (render_depth)
404 {
405 case 8:
406 {
407 GdkColormap *cmap = gtk_widget_get_default_colormap();
408 GdkColor *colors = cmap->colors;
409 int max = 3 * (65536);
410 int index = -1;
411
412 for (int i = 0; i < cmap->size; i++)
413 {
414 int rdiff = (r << 8) - colors[i].red;
415 int gdiff = (g << 8) - colors[i].green;
416 int bdiff = (b << 8) - colors[i].blue;
417 int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
418 if (sum < max) { index = i; max = sum; }
419 }
420
421 gdk_image_put_pixel( data_image, x, y, index );
422
423 break;
424 }
425 case 15:
426 {
427 guint32 pixel = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
428 gdk_image_put_pixel( data_image, x, y, pixel );
429 break;
430 }
431 case 16:
432 {
433 guint32 pixel = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
434 gdk_image_put_pixel( data_image, x, y, pixel );
435 break;
436 }
437 case 24:
438 {
439 break;
440 }
441 case 32:
442 {
443 break;
444 }
445 default: break;
446 }
447 }
448
449 // Blit picture
450
451 GdkGC *data_gc = gdk_gc_new( M_BMPDATA->m_pixmap );
452
453 gdk_draw_image( M_BMPDATA->m_pixmap, data_gc, data_image, 0, 0, 0, 0, width, height );
454
455 gdk_image_destroy( data_image );
456 gdk_gc_unref( data_gc );
457
458 // Blit mask
459
460 if (image.HasMask())
461 {
462 GdkGC *mask_gc = gdk_gc_new( M_BMPDATA->m_mask->m_bitmap );
463
464 gdk_draw_image( M_BMPDATA->m_mask->m_bitmap, mask_gc, mask_image, 0, 0, 0, 0, width, height );
465
466 gdk_image_destroy( mask_image );
467 gdk_gc_unref( mask_gc );
468 }
469
470 }
471
472 wxImage wxBitmap::ConvertToImage() const
473 {
474 wxImage image;
475
476 if (!Ok())
477 {
478 wxFAIL_MSG( "invalid bitmap" );
479 return image;
480 }
481
482 GdkImage *gdk_image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height );
483
484 if (!gdk_image) return image;
485
486 image.Create( M_BMPDATA->m_width, M_BMPDATA->m_height );
487 char unsigned *data = image.GetData();
488
489 int bpp = gdk_image->bpp;
490 GdkColormap *cmap = gtk_widget_get_default_colormap();
491
492 long pos = 0;
493 for (int j = 0; j < M_BMPDATA->m_height; j++)
494 {
495 for (int i = 0; i < M_BMPDATA->m_width; i++)
496 {
497 int pixel = gdk_image_get_pixel( gdk_image, i, j );
498 if (bpp <= 8)
499 {
500 data[pos] = cmap->colors[pixel].red >> 8;
501 data[pos+1] = cmap->colors[pixel].green >> 8;
502 data[pos+2] = cmap->colors[pixel].blue >> 8;
503 } else if (bpp == 15)
504 {
505 data[pos] = (pixel >> 7) & 0xf8;
506 data[pos+1] = (pixel >> 3) & 0xf8;
507 data[pos+2] = (pixel << 3) & 0xf8;
508 } else if (bpp == 16)
509 {
510 data[pos] = (pixel >> 8) & 0xf8;
511 data[pos+1] = (pixel >> 3) & 0xfc;
512 data[pos+2] = (pixel << 3) & 0xf8;
513 } else
514 {
515 data[pos] = (pixel >> 16) & 0xff;
516 data[pos+1] = (pixel >> 8) & 0xff;
517 data[pos+2] = pixel & 0xff;
518 }
519
520 pos += 3;
521 }
522 }
523
524 gdk_image_destroy( gdk_image );
525
526 return image;
527 }
528
529
530