Latest Updates
[wxWidgets.git] / src / os2 / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: David Webster
5 // Modified by:
6 // Created: 08/08/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include <stdio.h>
17
18 #include "wx/list.h"
19 #include "wx/utils.h"
20 #include "wx/app.h"
21 #include "wx/palette.h"
22 #include "wx/dcmemory.h"
23 #include "wx/bitmap.h"
24 #include "wx/icon.h"
25 #endif
26
27 #include "wx/os2/private.h"
28 #include "wx/log.h"
29
30 // ----------------------------------------------------------------------------
31 // macros
32 // ----------------------------------------------------------------------------
33
34 #if !USE_SHARED_LIBRARIES
35 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
36 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
37 #endif
38
39 wxBitmapRefData::wxBitmapRefData()
40 {
41 m_ok = FALSE;
42 m_width = 0;
43 m_height = 0;
44 m_depth = 0;
45 m_quality = 0;
46 m_hBitmap = 0 ;
47 m_selectedInto = NULL;
48 m_numColors = 0;
49 m_bitmapMask = NULL;
50 }
51
52 wxBitmapRefData::~wxBitmapRefData()
53 {
54 if (m_selectedInto)
55 {
56 wxChar buf[200];
57 wxSprintf(buf, wxT("Bitmap was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) m_selectedInto);
58 wxFatalError(buf);
59 }
60 if (m_hBitmap)
61 {
62 // TODO: DeleteObject((HBITMAP) m_hBitmap);
63 }
64 m_hBitmap = 0 ;
65
66 if (m_bitmapMask)
67 delete m_bitmapMask;
68 m_bitmapMask = NULL;
69 }
70
71 wxList wxBitmap::sm_handlers;
72
73 wxBitmap::wxBitmap()
74 {
75 m_refData = NULL;
76
77 if ( wxTheBitmapList )
78 wxTheBitmapList->AddBitmap(this);
79 }
80
81 wxBitmap::wxBitmap(const wxBitmap& bitmap)
82 {
83 // TODO:
84 /*
85 wxIcon *icon = wxDynamicCast(&bitmap, wxIcon);
86 if ( icon )
87 {
88 HDC hdc = ::CreateCompatibleDC(NULL); // screen DC
89 HBITMAP hbitmap = ::CreateCompatibleBitmap(hdc,
90 icon->GetWidth(),
91 icon->GetHeight());
92 ::SelectObject(hdc, hbitmap);
93 ::DrawIcon(hdc, 0, 0, (HICON)icon->GetHICON());
94
95 ::DeleteDC(hdc);
96
97 SetHBITMAP((WXHBITMAP)hbitmap);
98 }
99 else
100 {
101 Ref(bitmap);
102 }
103
104 if ( wxTheBitmapList )
105 wxTheBitmapList->AddBitmap(this);
106 */
107 }
108
109 wxBitmap::~wxBitmap()
110 {
111 if (wxTheBitmapList)
112 wxTheBitmapList->DeleteObject(this);
113 }
114
115 bool wxBitmap::FreeResource(bool WXUNUSED(force))
116 {
117 if ( !M_BITMAPDATA )
118 return FALSE;
119
120 if (M_BITMAPDATA->m_selectedInto)
121 {
122 wxChar buf[200];
123 wxSprintf(buf, wxT("Bitmap %lX was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) this, (unsigned long) M_BITMAPDATA->m_selectedInto);
124 wxFatalError(buf);
125 }
126 if (M_BITMAPDATA->m_hBitmap)
127 {
128 // TODO: DeleteObject((HBITMAP) M_BITMAPDATA->m_hBitmap);
129 }
130 M_BITMAPDATA->m_hBitmap = 0 ;
131
132 /*
133 if (M_BITMAPDATA->m_bitmapPalette)
134 delete M_BITMAPDATA->m_bitmapPalette;
135
136 M_BITMAPDATA->m_bitmapPalette = NULL ;
137 */
138
139 return TRUE;
140 }
141
142
143 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
144 {
145 m_refData = new wxBitmapRefData;
146
147 M_BITMAPDATA->m_width = the_width ;
148 M_BITMAPDATA->m_height = the_height ;
149 M_BITMAPDATA->m_depth = no_bits ;
150 M_BITMAPDATA->m_numColors = 0;
151
152 /* TODO: create the bitmap from data */
153
154 if ( wxTheBitmapList )
155 wxTheBitmapList->AddBitmap(this);
156 }
157
158 // Create from XPM data
159 wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
160 {
161 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
162 }
163
164 wxBitmap::wxBitmap(int w, int h, int d)
165 {
166 (void)Create(w, h, d);
167
168 if ( wxTheBitmapList )
169 wxTheBitmapList->AddBitmap(this);
170 }
171
172 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
173 {
174 (void) Create(data, type, width, height, depth);
175
176 if ( wxTheBitmapList )
177 wxTheBitmapList->AddBitmap(this);
178 }
179
180 wxBitmap::wxBitmap(const wxString& filename, long type)
181 {
182 LoadFile(filename, (int)type);
183
184 if ( wxTheBitmapList )
185 wxTheBitmapList->AddBitmap(this);
186 }
187
188 bool wxBitmap::Create(int w, int h, int d)
189 {
190 UnRef();
191
192 m_refData = new wxBitmapRefData;
193
194 M_BITMAPDATA->m_width = w;
195 M_BITMAPDATA->m_height = h;
196 M_BITMAPDATA->m_depth = d;
197
198 /* TODO: create new bitmap */
199
200 return M_BITMAPDATA->m_ok;
201 }
202
203 bool wxBitmap::LoadFile(const wxString& filename, long type)
204 {
205 UnRef();
206
207 m_refData = new wxBitmapRefData;
208
209 wxBitmapHandler *handler = FindHandler(type);
210
211 if ( handler == NULL ) {
212 wxLogWarning("no bitmap handler for type %d defined.", type);
213
214 return FALSE;
215 }
216
217 return handler->LoadFile(this, filename, type, -1, -1);
218 }
219
220 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
221 {
222 UnRef();
223
224 m_refData = new wxBitmapRefData;
225
226 wxBitmapHandler *handler = FindHandler(type);
227
228 if ( handler == NULL ) {
229 wxLogWarning("no bitmap handler for type %d defined.", type);
230
231 return FALSE;
232 }
233
234 return handler->Create(this, data, type, width, height, depth);
235 }
236
237 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
238 {
239 wxBitmapHandler *handler = FindHandler(type);
240
241 if ( handler == NULL ) {
242 wxLogWarning("no bitmap handler for type %d defined.", type);
243
244 return FALSE;
245 }
246
247 return handler->SaveFile(this, filename, type, palette);
248 }
249
250 void wxBitmap::SetWidth(int w)
251 {
252 if (!M_BITMAPDATA)
253 m_refData = new wxBitmapRefData;
254
255 M_BITMAPDATA->m_width = w;
256 }
257
258 void wxBitmap::SetHeight(int h)
259 {
260 if (!M_BITMAPDATA)
261 m_refData = new wxBitmapRefData;
262
263 M_BITMAPDATA->m_height = h;
264 }
265
266 void wxBitmap::SetDepth(int d)
267 {
268 if (!M_BITMAPDATA)
269 m_refData = new wxBitmapRefData;
270
271 M_BITMAPDATA->m_depth = d;
272 }
273
274 void wxBitmap::SetQuality(int q)
275 {
276 if (!M_BITMAPDATA)
277 m_refData = new wxBitmapRefData;
278
279 M_BITMAPDATA->m_quality = q;
280 }
281
282 void wxBitmap::SetOk(bool isOk)
283 {
284 if (!M_BITMAPDATA)
285 m_refData = new wxBitmapRefData;
286
287 M_BITMAPDATA->m_ok = isOk;
288 }
289
290 void wxBitmap::SetPalette(const wxPalette& palette)
291 {
292 if (!M_BITMAPDATA)
293 m_refData = new wxBitmapRefData;
294
295 M_BITMAPDATA->m_bitmapPalette = palette ;
296 }
297
298 void wxBitmap::SetMask(wxMask *mask)
299 {
300 if (!M_BITMAPDATA)
301 m_refData = new wxBitmapRefData;
302
303 M_BITMAPDATA->m_bitmapMask = mask ;
304 }
305
306 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
307 {
308 if (!M_BITMAPDATA)
309 m_refData = new wxBitmapRefData;
310
311 M_BITMAPDATA->m_hBitmap = bmp;
312 }
313
314 void wxBitmap::AddHandler(wxBitmapHandler *handler)
315 {
316 sm_handlers.Append(handler);
317 }
318
319 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
320 {
321 sm_handlers.Insert(handler);
322 }
323
324 bool wxBitmap::RemoveHandler(const wxString& name)
325 {
326 wxBitmapHandler *handler = FindHandler(name);
327 if ( handler )
328 {
329 sm_handlers.DeleteObject(handler);
330 return TRUE;
331 }
332 else
333 return FALSE;
334 }
335
336 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
337 {
338 wxNode *node = sm_handlers.First();
339 while ( node )
340 {
341 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
342 if ( handler->GetName() == name )
343 return handler;
344 node = node->Next();
345 }
346 return NULL;
347 }
348
349 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
350 {
351 wxNode *node = sm_handlers.First();
352 while ( node )
353 {
354 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
355 if ( handler->GetExtension() == extension &&
356 (bitmapType == -1 || handler->GetType() == bitmapType) )
357 return handler;
358 node = node->Next();
359 }
360 return NULL;
361 }
362
363 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
364 {
365 wxNode *node = sm_handlers.First();
366 while ( node )
367 {
368 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
369 if (handler->GetType() == bitmapType)
370 return handler;
371 node = node->Next();
372 }
373 return NULL;
374 }
375
376 // Creates a bitmap that matches the device context, from
377 // an arbitray bitmap. At present, the original bitmap must have an
378 // associated palette. TODO: use a default palette if no palette exists.
379 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
380 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
381 {
382 wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
383 // TODO:
384 /*
385 wxMemoryDC memDC;
386 HPALETTE hPal = (HPALETTE) NULL;
387 LPBITMAPINFO lpDib;
388 void *lpBits = (void*) NULL;
389
390
391 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
392
393 tmpBitmap.SetPalette(this->GetPalette());
394 memDC.SelectObject(tmpBitmap);
395 memDC.SetPalette(this->GetPalette());
396
397 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
398
399 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
400 {
401 tmpBitmap.SetPalette(* this->GetPalette());
402 memDC.SelectObject(tmpBitmap);
403 memDC.SetPalette(* this->GetPalette());
404 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
405 }
406 else
407 {
408 hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);
409 wxPalette palette;
410 palette.SetHPALETTE( (WXHPALETTE)hPal );
411 tmpBitmap.SetPalette( palette );
412 memDC.SelectObject(tmpBitmap);
413 memDC.SetPalette( palette );
414 }
415
416 // set the height negative because in a DIB the order of the lines is reversed
417 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib);
418
419 lpBits = malloc(lpDib->bmiHeader.biSizeImage);
420
421 ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits);
422
423 ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
424 0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS);
425
426 free(lpBits);
427
428 freeDIB(lpDib);
429 */
430 return (tmpBitmap);
431 }
432
433 /*
434 * wxMask
435 */
436
437 wxMask::wxMask()
438 {
439 m_maskBitmap = 0;
440 }
441
442 // Construct a mask from a bitmap and a colour indicating
443 // the transparent area
444 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
445 {
446 m_maskBitmap = 0;
447 Create(bitmap, colour);
448 }
449
450 // Construct a mask from a bitmap and a palette index indicating
451 // the transparent area
452 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
453 {
454 m_maskBitmap = 0;
455 Create(bitmap, paletteIndex);
456 }
457
458 // Construct a mask from a mono bitmap (copies the bitmap).
459 wxMask::wxMask(const wxBitmap& bitmap)
460 {
461 m_maskBitmap = 0;
462 Create(bitmap);
463 }
464
465 wxMask::~wxMask()
466 {
467 // TODO: delete mask bitmap
468 }
469
470 // Create a mask from a mono bitmap (copies the bitmap).
471 bool wxMask::Create(const wxBitmap& bitmap)
472 {
473 // TODO
474 return FALSE;
475 }
476
477 // Create a mask from a bitmap and a palette index indicating
478 // the transparent area
479 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
480 {
481 // TODO
482 return FALSE;
483 }
484
485 // Create a mask from a bitmap and a colour indicating
486 // the transparent area
487 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
488 {
489 // TODO
490 return FALSE;
491 }
492
493 /*
494 * wxBitmapHandler
495 */
496
497 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
498
499 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
500 {
501 return FALSE;
502 }
503
504 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
505 int desiredWidth, int desiredHeight)
506 {
507 return FALSE;
508 }
509
510 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
511 {
512 return FALSE;
513 }
514
515 /*
516 * Standard handlers
517 */
518
519 /* TODO: bitmap handlers, a bit like this:
520 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
521 {
522 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
523 public:
524 inline wxBMPResourceHandler()
525 {
526 m_name = "Windows bitmap resource";
527 m_extension = "";
528 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
529 };
530
531 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
532 int desiredWidth, int desiredHeight);
533 };
534 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
535 */
536
537 void wxBitmap::CleanUpHandlers()
538 {
539 wxNode *node = sm_handlers.First();
540 while ( node )
541 {
542 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
543 wxNode *next = node->Next();
544 delete handler;
545 delete node;
546 node = next;
547 }
548 }
549
550 void wxBitmap::InitStandardHandlers()
551 {
552 /* TODO: initialize all standard bitmap or derive class handlers here.
553 AddHandler(new wxBMPResourceHandler);
554 AddHandler(new wxBMPFileHandler);
555 AddHandler(new wxXPMFileHandler);
556 AddHandler(new wxXPMDataHandler);
557 AddHandler(new wxICOResourceHandler);
558 AddHandler(new wxICOFileHandler);
559 */
560 }
561