]>
Commit | Line | Data |
---|---|---|
0e320a79 DW |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: bitmap.cpp | |
3 | // Purpose: wxBitmap | |
f0a56ab0 | 4 | // Author: David Webster |
0e320a79 | 5 | // Modified by: |
f0a56ab0 | 6 | // Created: 08/08/99 |
0e320a79 | 7 | // RCS-ID: $Id$ |
f0a56ab0 | 8 | // Copyright: (c) David Webster |
0e320a79 DW |
9 | // Licence: wxWindows licence |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
d88de032 DW |
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" | |
0e320a79 DW |
25 | #endif |
26 | ||
d88de032 | 27 | #include "wx/os2/private.h" |
0e320a79 DW |
28 | #include "wx/log.h" |
29 | ||
d88de032 DW |
30 | // ---------------------------------------------------------------------------- |
31 | // macros | |
32 | // ---------------------------------------------------------------------------- | |
33 | ||
0e320a79 DW |
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; | |
d88de032 DW |
46 | m_hBitmap = 0 ; |
47 | m_selectedInto = NULL; | |
0e320a79 DW |
48 | m_numColors = 0; |
49 | m_bitmapMask = NULL; | |
50 | } | |
51 | ||
52 | wxBitmapRefData::~wxBitmapRefData() | |
53 | { | |
d88de032 DW |
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 ; | |
0e320a79 DW |
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 | ||
d88de032 DW |
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 | ||
0e320a79 DW |
109 | wxBitmap::~wxBitmap() |
110 | { | |
111 | if (wxTheBitmapList) | |
112 | wxTheBitmapList->DeleteObject(this); | |
113 | } | |
114 | ||
d88de032 DW |
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 | ||
0e320a79 DW |
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 | ||
d88de032 DW |
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 | ||
0e320a79 DW |
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 | ||
0e320a79 DW |
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 | ||
d88de032 DW |
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 | ||
0e320a79 DW |
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 | ||
d88de032 DW |
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 | ||
0e320a79 DW |
433 | /* |
434 | * wxMask | |
435 | */ | |
436 | ||
437 | wxMask::wxMask() | |
438 | { | |
0e320a79 | 439 | m_maskBitmap = 0; |
0e320a79 DW |
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 | { | |
0e320a79 | 446 | m_maskBitmap = 0; |
0e320a79 DW |
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 | { | |
0e320a79 | 454 | m_maskBitmap = 0; |
0e320a79 DW |
455 | Create(bitmap, paletteIndex); |
456 | } | |
457 | ||
458 | // Construct a mask from a mono bitmap (copies the bitmap). | |
459 | wxMask::wxMask(const wxBitmap& bitmap) | |
460 | { | |
0e320a79 | 461 | m_maskBitmap = 0; |
0e320a79 DW |
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 | } | |
ce44c50e | 561 |