]>
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 | ||
3b9e3455 DW |
30 | //#include "wx/msw/dib.h" |
31 | #include "wx/image.h" | |
32 | ||
d88de032 DW |
33 | // ---------------------------------------------------------------------------- |
34 | // macros | |
35 | // ---------------------------------------------------------------------------- | |
36 | ||
0e320a79 DW |
37 | #if !USE_SHARED_LIBRARIES |
38 | IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) | |
39 | IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) | |
3b9e3455 DW |
40 | |
41 | IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) | |
0e320a79 DW |
42 | #endif |
43 | ||
3b9e3455 DW |
44 | // ============================================================================ |
45 | // implementation | |
46 | // ============================================================================ | |
47 | ||
48 | // ---------------------------------------------------------------------------- | |
49 | // wxBitmapRefData | |
50 | // ---------------------------------------------------------------------------- | |
51 | ||
0e320a79 DW |
52 | wxBitmapRefData::wxBitmapRefData() |
53 | { | |
3b9e3455 DW |
54 | m_nQuality = 0; |
55 | m_pSelectedInto = NULL; | |
56 | m_nNumColors = 0; | |
57 | m_pBitmapMask = NULL; | |
0e320a79 DW |
58 | } |
59 | ||
3b9e3455 | 60 | void wxBitmapRefData::Free() |
0e320a79 | 61 | { |
3b9e3455 DW |
62 | wxASSERT_MSG( !m_pSelectedInto, |
63 | wxT("deleting bitmap still selected into wxMemoryDC") ); | |
0e320a79 | 64 | |
3b9e3455 DW |
65 | if (m_hBitmap) |
66 | { | |
67 | if ( !::GpiDeleteBitmap((HBITMAP)m_hBitmap) ) | |
68 | { | |
69 | wxLogLastError("GpiDeleteBitmap(hbitmap)"); | |
70 | } | |
71 | } | |
72 | ||
73 | delete m_pBitmapMask; | |
74 | m_pBitmapMask = NULL; | |
0e320a79 DW |
75 | } |
76 | ||
3b9e3455 DW |
77 | // ---------------------------------------------------------------------------- |
78 | // wxBitmap creation | |
79 | // ---------------------------------------------------------------------------- | |
0e320a79 | 80 | |
3b9e3455 DW |
81 | // this function should be called from all wxBitmap ctors |
82 | void wxBitmap::Init() | |
0e320a79 | 83 | { |
3b9e3455 | 84 | // m_refData = NULL; done in the base class ctor |
0e320a79 | 85 | |
3b9e3455 | 86 | if (wxTheBitmapList) |
0e320a79 DW |
87 | wxTheBitmapList->AddBitmap(this); |
88 | } | |
89 | ||
3b9e3455 DW |
90 | bool wxBitmap::CopyFromIconOrCursor( |
91 | const wxGDIImage& rIcon | |
92 | ) | |
d88de032 | 93 | { |
3b9e3455 | 94 | wxBitmapRefData* pRefData = new wxBitmapRefData; |
d88de032 | 95 | |
3b9e3455 | 96 | m_refData = pRefData; |
d88de032 | 97 | |
3b9e3455 DW |
98 | refData->m_width = rIcon.GetWidth(); |
99 | refData->m_height = rIcon.GetHeight(); | |
100 | refData->m_depth = wxDisplayDepth(); | |
d88de032 | 101 | |
3b9e3455 DW |
102 | refData->m_hBitmap = (WXHBITMAP)rIcon.GetHandle(); |
103 | // no mask??? | |
104 | refData->m_bitmapMask = new wxMask(); | |
d88de032 | 105 | |
3b9e3455 DW |
106 | #if WXWIN_COMPATIBILITY_2 |
107 | refData->m_ok = TRUE; | |
108 | #endif // WXWIN_COMPATIBILITY_2 | |
109 | ||
110 | return(TRUE); | |
0e320a79 DW |
111 | } |
112 | ||
3b9e3455 DW |
113 | bool wxBitmap::CopyFromCursor( |
114 | const wxCursor& rCursor | |
115 | ) | |
d88de032 | 116 | { |
3b9e3455 | 117 | UnRef(); |
d88de032 | 118 | |
3b9e3455 DW |
119 | if (!rCursor.Ok()) |
120 | return(FALSE); | |
121 | return CopyFromIconOrCursor(wxGDIImage)rCursor); | |
d88de032 DW |
122 | } |
123 | ||
3b9e3455 DW |
124 | bool wxBitmap::CopyFromIcon( |
125 | const wxIcon& rIcon | |
126 | ) | |
0e320a79 | 127 | { |
3b9e3455 | 128 | UnRef(); |
0e320a79 | 129 | |
3b9e3455 DW |
130 | if (!rIcon.Ok()) |
131 | return(FALSE); | |
0e320a79 | 132 | |
3b9e3455 DW |
133 | #if WXWIN_COMPATIBILITY_2 |
134 | refData->m_ok = TRUE; | |
135 | #endif // WXWIN_COMPATIBILITY_2 | |
0e320a79 | 136 | |
3b9e3455 | 137 | return CopyFromIconOrCursor(icon); |
0e320a79 DW |
138 | } |
139 | ||
3b9e3455 | 140 | wxBitmap::~wxBitmap() |
d88de032 | 141 | { |
3b9e3455 DW |
142 | if (wxTheBitmapList) |
143 | wxTheBitmapList->DeleteObject(this); | |
d88de032 DW |
144 | } |
145 | ||
3b9e3455 DW |
146 | wxBitmap::wxBitmap( |
147 | const char zBits[] | |
148 | , int nTheWidth | |
149 | , int nTheHeight | |
150 | , int nNoBits | |
151 | ) | |
152 | { | |
153 | Init(); | |
154 | ||
155 | wxBitmapRefData* pRefData = new wxBitmapRefData; | |
156 | BITMAPINFOHEADER2 vHeader; | |
157 | BITMAPINFO2 vInfo; | |
158 | HDC hDc; | |
159 | HPS hPs; | |
160 | DEVOPENSTRUCT vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | |
161 | SIZEL vSize = {0, 0}; | |
162 | ||
163 | wxAssert(vHabmain != NULL); | |
164 | ||
165 | hDc = ::DevOpenDC(vHabmain, OD_MEMORY, (PSZ)"*", 1L, (PDEVOPENDATA)&vDop, 0L); | |
166 | ||
167 | vHeader.cbFix = sizeof(vHeader); | |
168 | vHeader.cx = (USHORT)nTheWidth; | |
169 | vHeader.cy = (USHORT)nTheHeight; | |
170 | vHeader.cPlanes = 1L; | |
171 | vHeader.cBitCount = nNoBits; | |
172 | vHeader.ulCompression = BCA_UNCOMP; | |
173 | vHeader.cxResolution = 0; | |
174 | vHeader.cyResolution = 0; | |
175 | vHeader.cclrUsed = 0; | |
176 | vHeader.cclrImportant = 0; | |
177 | vHeader.usUnits = BRU_METRIC; | |
178 | vHeader.usRecording = BRA_BOTTOMUP; | |
179 | vHeader.usRendering = BRH_NOTHALFTONED; | |
180 | vHeader.cSize1 = 0; | |
181 | vHeader.cSize2 = 0; | |
182 | vHeader.ulColorEncoding = 0; | |
183 | vHeader.ulIdentifier = 0; | |
184 | ||
4f72fe4f DW |
185 | hPs = ::GpiCreatePS(habMain, hdc, &vSize, GPIA_ASSOC | PU_PELS); |
186 | if (hPs == 0) | |
3b9e3455 DW |
187 | { |
188 | wxLogLastError("GpiCreatePS Failure"); | |
189 | } | |
0e320a79 | 190 | |
4f72fe4f DW |
191 | m_hDc = hDc; |
192 | m_hPs = hPs; | |
193 | ||
3b9e3455 | 194 | m_refData = pRefData; |
0e320a79 | 195 | |
3b9e3455 DW |
196 | refData->m_width = nTheWidth; |
197 | refData->m_height = nTheHeight; | |
198 | refData->m_depth = nNoBits; | |
199 | refData->m_numColors = 0; | |
200 | refData->m_selectedInto = NULL; | |
0e320a79 | 201 | |
3b9e3455 DW |
202 | HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, 0L, NULL, &vInfo); |
203 | if ( !hbmp ) | |
204 | { | |
205 | wxLogLastError("CreateBitmap"); | |
206 | } | |
207 | SetHBITMAP((WXHBITMAP)hbmp); | |
0e320a79 DW |
208 | } |
209 | ||
3b9e3455 DW |
210 | // Create from XPM data |
211 | wxBitmap::wxBitmap( | |
212 | char** ppData | |
213 | , wxControl* WXUNUSED(pAnItem)) | |
214 | { | |
215 | Init(); | |
216 | ||
217 | F (void)Create( (void *)ppData | |
218 | ,wxBITMAP_TYPE_XPM_DATA | |
219 | ,0 | |
220 | ,0 | |
221 | ,0 | |
222 | ); | |
223 | } | |
224 | ||
225 | wxBitmap::wxBitmap( | |
226 | int nW | |
227 | , int nH | |
228 | , int nD | |
229 | ) | |
230 | { | |
231 | Init(); | |
232 | ||
233 | (void)Create( nW | |
234 | ,nH | |
235 | ,nD | |
236 | ); | |
237 | } | |
238 | ||
239 | wxBitmap::wxBitmap( | |
240 | void* pData | |
241 | , long lType | |
242 | , int nWidth | |
243 | , int nHeight | |
244 | , int nDepth | |
245 | ) | |
246 | { | |
247 | Init(); | |
248 | ||
249 | (void)Create( pData | |
250 | ,lType | |
251 | ,nWidth | |
252 | ,nHeight | |
253 | ,nDepth | |
254 | ); | |
255 | } | |
256 | ||
257 | wxBitmap::wxBitmap( | |
258 | const wxString& rFilename | |
259 | , long lType | |
260 | ) | |
261 | { | |
262 | Init(); | |
263 | ||
264 | LoadFile( rFilename | |
265 | ,(int)lType | |
266 | ); | |
267 | } | |
268 | ||
269 | bool wxBitmap::Create( | |
270 | int nW | |
271 | , int nH | |
272 | , int nD | |
273 | ) | |
274 | { | |
275 | HBITMAP hBmp; | |
276 | BITMAPINFOHEADER2 vHeader; | |
277 | BITMAPINFO2 vInfo; | |
4f72fe4f DW |
278 | HPS hpsScreen; |
279 | HDC hdcScreen; | |
3b9e3455 DW |
280 | DEVOPENSTRUCT vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
281 | SIZEL vSize = {0, 0}; | |
4f72fe4f | 282 | LONG lBitCount; |
3b9e3455 DW |
283 | |
284 | wxAssert(vHabmain != NULL); | |
285 | ||
4f72fe4f DW |
286 | hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); |
287 | hdcScreen = ::GpiQueryDevice(hpsScreen); | |
288 | ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, &lBitCount); | |
3b9e3455 DW |
289 | |
290 | vHeader.cbFix = sizeof(vHeader); | |
291 | vHeader.cx = (USHORT)nW; | |
292 | vHeader.cy = (USHORT)nH; | |
293 | vHeader.cPlanes = (USHORT)nD; | |
4f72fe4f | 294 | vHeader.cBitCount = lBitCount; |
3b9e3455 DW |
295 | vHeader.ulCompression = BCA_UNCOMP; |
296 | vHeader.cxResolution = 0; | |
297 | vHeader.cyResolution = 0; | |
298 | vHeader.cclrUsed = 0; | |
299 | vHeader.cclrImportant = 0; | |
300 | vHeader.usUnits = BRU_METRIC; | |
301 | vHeader.usRecording = BRA_BOTTOMUP; | |
302 | vHeader.usRendering = BRH_NOTHALFTONED; | |
303 | vHeader.cSize1 = 0; | |
304 | vHeader.cSize2 = 0; | |
305 | vHeader.ulColorEncoding = 0; | |
306 | vHeader.ulIdentifier = 0; | |
307 | ||
0e320a79 | 308 | |
0e320a79 | 309 | UnRef(); |
0e320a79 DW |
310 | m_refData = new wxBitmapRefData; |
311 | ||
3b9e3455 DW |
312 | GetBitmapData()->m_width = nW; |
313 | GetBitmapData()->m_height = nH; | |
314 | GetBitmapData()->m_depth = nD; | |
0e320a79 | 315 | |
3b9e3455 DW |
316 | if (nD > 0) |
317 | { | |
4f72fe4f | 318 | hBmp = ::GpiCreateBitmap(hpsScreen, &vHeader, 0L, NULL, &vInfo); |
3b9e3455 DW |
319 | if (!hBmp) |
320 | { | |
321 | wxLogLastError("CreateBitmap"); | |
322 | } | |
323 | } | |
324 | else | |
325 | { | |
4f72fe4f DW |
326 | LONG lPlanes; |
327 | ||
328 | ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, &lPlanes); | |
329 | hBmp = ::GpiCreateBitmap(hpsScreen, &vHeader, 0L, NULL, &vInfo); | |
330 | if (!hBmp) | |
3b9e3455 | 331 | { |
4f72fe4f | 332 | wxLogLastError("CreateBitmap"); |
3b9e3455 | 333 | } |
3b9e3455 DW |
334 | GetBitmapData()->m_depth = wxDisplayDepth(); |
335 | } | |
4f72fe4f | 336 | SetHBITMAP((WXHBITMAP)hBmp); |
0e320a79 | 337 | |
3b9e3455 | 338 | #if WXWIN_COMPATIBILITY_2 |
4f72fe4f | 339 | GetBitmapData()->m_bOk = hBmp != 0; |
3b9e3455 DW |
340 | #endif // WXWIN_COMPATIBILITY_2 |
341 | ||
342 | return Ok(); | |
0e320a79 DW |
343 | } |
344 | ||
4f72fe4f DW |
345 | bool wxBitmap::LoadFile( |
346 | const wxString& rFilename | |
347 | , long lType | |
348 | ) | |
0e320a79 DW |
349 | { |
350 | UnRef(); | |
351 | ||
4f72fe4f DW |
352 | wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) |
353 | ,wxBitmapHandler | |
354 | ); | |
0e320a79 | 355 | |
4f72fe4f | 356 | if (pHandler) |
3b9e3455 DW |
357 | { |
358 | m_refData = new wxBitmapRefData; | |
0e320a79 | 359 | |
4f72fe4f DW |
360 | return(pHandler->LoadFile( this |
361 | ,rFilename | |
362 | ,lType | |
363 | , -1 | |
364 | , -1 | |
365 | ); | |
0e320a79 | 366 | } |
3b9e3455 DW |
367 | else |
368 | { | |
4f72fe4f | 369 | wxImage vImage; |
0e320a79 | 370 | |
4f72fe4f DW |
371 | if (!vImage.LoadFile(rFilename, lType) || !image.Ok() ) |
372 | return(FALSE); | |
3b9e3455 | 373 | |
4f72fe4f DW |
374 | *this = vImage.ConvertToBitmap(); |
375 | ||
376 | return(TRUE); | |
3b9e3455 | 377 | } |
0e320a79 DW |
378 | } |
379 | ||
4f72fe4f DW |
380 | bool wxBitmap::Create( |
381 | void* pData | |
382 | , long lType | |
383 | , int nWidth | |
384 | , int nHeight | |
385 | , int nDepth | |
386 | ) | |
0e320a79 DW |
387 | { |
388 | UnRef(); | |
389 | ||
4f72fe4f DW |
390 | wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) |
391 | ,wxBitmapHandler | |
392 | ); | |
0e320a79 | 393 | |
4f72fe4f | 394 | if (!pHandler) |
3b9e3455 DW |
395 | { |
396 | wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for " | |
397 | "type %d defined."), type); | |
0e320a79 | 398 | |
4f72fe4f | 399 | return(FALSE); |
0e320a79 DW |
400 | } |
401 | ||
3b9e3455 DW |
402 | m_refData = new wxBitmapRefData; |
403 | ||
4f72fe4f DW |
404 | return(handler->Create( this |
405 | ,pData | |
406 | ,lType | |
407 | ,nWidth | |
408 | ,nHeight | |
409 | ,nDepth | |
410 | )); | |
0e320a79 DW |
411 | } |
412 | ||
4f72fe4f DW |
413 | bool wxBitmap::SaveFile( |
414 | const wxString& rFilename | |
415 | , int lType | |
416 | , const wxPalette* pPalette | |
417 | ) | |
0e320a79 | 418 | { |
4f72fe4f DW |
419 | wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) |
420 | ,wxBitmapHandler | |
421 | ); | |
0e320a79 | 422 | |
4f72fe4f | 423 | if (pHandler) |
3b9e3455 | 424 | { |
4f72fe4f DW |
425 | return pHandler->SaveFile( this |
426 | ,rFilename | |
427 | ,lType | |
428 | ,pPalette | |
429 | ); | |
3b9e3455 DW |
430 | } |
431 | else | |
432 | { | |
433 | // FIXME what about palette? shouldn't we use it? | |
4f72fe4f DW |
434 | wxImage vImage(*this); |
435 | ||
436 | if (!vImage.Ok()) | |
437 | return(FALSE); | |
0e320a79 | 438 | |
4f72fe4f DW |
439 | return(vImage.SaveFile( rFilename |
440 | ,lType | |
441 | )); | |
3b9e3455 | 442 | } |
0e320a79 DW |
443 | } |
444 | ||
3b9e3455 DW |
445 | // ---------------------------------------------------------------------------- |
446 | // wxBitmap accessors | |
447 | // ---------------------------------------------------------------------------- | |
0e320a79 | 448 | |
4f72fe4f DW |
449 | void wxBitmap::SetQuality( |
450 | int nQ | |
451 | ) | |
0e320a79 | 452 | { |
3b9e3455 | 453 | EnsureHasData(); |
0e320a79 | 454 | |
4f72fe4f | 455 | GetBitmapData()->m_nQuality = nQ; |
0e320a79 DW |
456 | } |
457 | ||
3b9e3455 | 458 | #if WXWIN_COMPATIBILITY_2 |
4f72fe4f DW |
459 | void wxBitmap::SetOk( |
460 | bool bOk | |
461 | ) | |
0e320a79 | 462 | { |
3b9e3455 | 463 | EnsureHasData(); |
0e320a79 | 464 | |
4f72fe4f | 465 | GetBitmapData()->m_bOk = bOk; |
0e320a79 | 466 | } |
3b9e3455 | 467 | #endif // WXWIN_COMPATIBILITY_2 |
0e320a79 | 468 | |
4f72fe4f DW |
469 | void wxBitmap::SetPalette( |
470 | const wxPalette& rPalette | |
471 | ) | |
0e320a79 | 472 | { |
3b9e3455 | 473 | EnsureHasData(); |
0e320a79 | 474 | |
4f72fe4f | 475 | GetBitmapData()->m_vBitmapPalette = rPalette; |
0e320a79 DW |
476 | } |
477 | ||
4f72fe4f DW |
478 | void wxBitmap::SetMask( |
479 | wxMask* pMask | |
480 | ) | |
0e320a79 | 481 | { |
3b9e3455 | 482 | EnsureHasData(); |
0e320a79 | 483 | |
4f72fe4f | 484 | GetBitmapData()->m_pBitmapMask = pMask; |
0e320a79 DW |
485 | } |
486 | ||
4f72fe4f DW |
487 | // Will try something for OS/2 but not really sure how close |
488 | // to the msw intent this is. | |
489 | wxBitmap wxBitmap::GetBitmapForDC( | |
490 | wxDC& rDc | |
491 | ) const | |
d88de032 | 492 | { |
4f72fe4f DW |
493 | wxMemoryDC vMemDC; |
494 | wxBitmap vTmpBitmap( this->GetWidth() | |
495 | ,this->GetHeight() | |
496 | ,rDc.GetDepth() | |
497 | ); | |
498 | HPS hMemoryPS; | |
499 | HPS hPs; | |
500 | POINTL vPoint[4]; | |
501 | SIZEL vSize = {0,0} | |
d88de032 | 502 | |
4f72fe4f DW |
503 | hMemoryPS = ::GpiCreatePS(habMain, (HDC)vMemDC.m_hDc, &vSize, PU_PELS | GPIT_MICRO | GPI_ASSOC); |
504 | hPs = ::GpiCreatePS(habMain, (HDC)rDc.m_hDc, &vSize, PU_PELS | GPIT_MICRO | GPI_ASSOC); | |
d88de032 | 505 | |
4f72fe4f | 506 | // TODO: Set the points |
3b9e3455 | 507 | |
4f72fe4f DW |
508 | rDc.m_oldBitmap = (WXHBITMAP)::GpiSetBitMap(hPs, (HBITMAP)vTmpBitmap.GetHBITMAP()); |
509 | :GpiBitBlt(hPs, hMemoryPS, 4L, vPoint, &vSize, PU_PELS | GPI_ASSOC); | |
510 | ||
3b9e3455 | 511 | return tmpBitmap; |
d88de032 DW |
512 | } |
513 | ||
3b9e3455 DW |
514 | // ---------------------------------------------------------------------------- |
515 | // wxMask | |
516 | // ---------------------------------------------------------------------------- | |
0e320a79 DW |
517 | |
518 | wxMask::wxMask() | |
519 | { | |
4f72fe4f | 520 | m_hMaskBitmap = 0; |
0e320a79 DW |
521 | } |
522 | ||
523 | // Construct a mask from a bitmap and a colour indicating | |
524 | // the transparent area | |
4f72fe4f DW |
525 | wxMask::wxMask( |
526 | const wxBitmap& rBitmap | |
527 | , const wxColour& rColour | |
528 | ) | |
0e320a79 | 529 | { |
4f72fe4f DW |
530 | m_hMaskBitmap = 0; |
531 | Create( rBitmap | |
532 | ,rColour | |
533 | ); | |
0e320a79 DW |
534 | } |
535 | ||
536 | // Construct a mask from a bitmap and a palette index indicating | |
537 | // the transparent area | |
4f72fe4f DW |
538 | wxMask::wxMask( |
539 | const wxBitmap& rBitmap | |
540 | , int nPaletteIndex | |
541 | ) | |
0e320a79 | 542 | { |
4f72fe4f DW |
543 | m_hMaskBitmap = 0; |
544 | Create( rBitmap | |
545 | ,nPaletteIndex | |
546 | ); | |
0e320a79 DW |
547 | } |
548 | ||
549 | // Construct a mask from a mono bitmap (copies the bitmap). | |
4f72fe4f DW |
550 | wxMask::wxMask( |
551 | const wxBitmap& rBitmap | |
552 | ) | |
0e320a79 | 553 | { |
4f72fe4f DW |
554 | m_hMaskBitmap = 0; |
555 | Create(rBitmap); | |
0e320a79 DW |
556 | } |
557 | ||
558 | wxMask::~wxMask() | |
559 | { | |
4f72fe4f DW |
560 | if (m_hMaskBitmap) |
561 | ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap); | |
0e320a79 DW |
562 | } |
563 | ||
564 | // Create a mask from a mono bitmap (copies the bitmap). | |
565 | bool wxMask::Create(const wxBitmap& bitmap) | |
566 | { | |
3b9e3455 DW |
567 | if ( m_maskBitmap ) |
568 | { | |
569 | ::DeleteObject((HBITMAP) m_maskBitmap); | |
570 | m_maskBitmap = 0; | |
571 | } | |
572 | if (!bitmap.Ok() || bitmap.GetDepth() != 1) | |
573 | { | |
574 | return FALSE; | |
575 | } | |
576 | m_maskBitmap = (WXHBITMAP) CreateBitmap( | |
577 | bitmap.GetWidth(), | |
578 | bitmap.GetHeight(), | |
579 | 1, 1, 0 | |
580 | ); | |
581 | HDC srcDC = CreateCompatibleDC(0); | |
582 | SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP()); | |
583 | HDC destDC = CreateCompatibleDC(0); | |
584 | SelectObject(destDC, (HBITMAP) m_maskBitmap); | |
585 | BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY); | |
586 | SelectObject(srcDC, 0); | |
587 | DeleteDC(srcDC); | |
588 | SelectObject(destDC, 0); | |
589 | DeleteDC(destDC); | |
590 | return TRUE; | |
0e320a79 DW |
591 | } |
592 | ||
593 | // Create a mask from a bitmap and a palette index indicating | |
594 | // the transparent area | |
595 | bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) | |
596 | { | |
3b9e3455 DW |
597 | if ( m_maskBitmap ) |
598 | { | |
599 | ::DeleteObject((HBITMAP) m_maskBitmap); | |
600 | m_maskBitmap = 0; | |
601 | } | |
602 | if (bitmap.Ok() && bitmap.GetPalette()->Ok()) | |
603 | { | |
604 | unsigned char red, green, blue; | |
605 | if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue)) | |
606 | { | |
607 | wxColour transparentColour(red, green, blue); | |
608 | return Create(bitmap, transparentColour); | |
609 | } | |
610 | } | |
0e320a79 DW |
611 | return FALSE; |
612 | } | |
613 | ||
614 | // Create a mask from a bitmap and a colour indicating | |
615 | // the transparent area | |
616 | bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) | |
617 | { | |
3b9e3455 DW |
618 | if ( m_maskBitmap ) |
619 | { | |
620 | ::DeleteObject((HBITMAP) m_maskBitmap); | |
621 | m_maskBitmap = 0; | |
622 | } | |
623 | if (!bitmap.Ok()) | |
624 | { | |
625 | return FALSE; | |
626 | } | |
627 | ||
628 | // scan the bitmap for the transparent colour and set | |
629 | // the corresponding pixels in the mask to BLACK and | |
630 | // the rest to WHITE | |
631 | COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue()); | |
632 | m_maskBitmap = (WXHBITMAP) ::CreateBitmap( | |
633 | bitmap.GetWidth(), | |
634 | bitmap.GetHeight(), | |
635 | 1, 1, 0 | |
636 | ); | |
637 | HDC srcDC = ::CreateCompatibleDC(0); | |
638 | ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP()); | |
639 | HDC destDC = ::CreateCompatibleDC(0); | |
640 | ::SelectObject(destDC, (HBITMAP) m_maskBitmap); | |
641 | ||
642 | // this is not very efficient, but I can't think | |
643 | // of a better way of doing it | |
644 | for (int w = 0; w < bitmap.GetWidth(); w++) | |
645 | { | |
646 | for (int h = 0; h < bitmap.GetHeight(); h++) | |
647 | { | |
648 | COLORREF col = GetPixel(srcDC, w, h); | |
649 | if (col == maskColour) | |
650 | { | |
651 | ::SetPixel(destDC, w, h, RGB(0, 0, 0)); | |
652 | } | |
653 | else | |
654 | { | |
655 | ::SetPixel(destDC, w, h, RGB(255, 255, 255)); | |
656 | } | |
657 | } | |
658 | } | |
659 | ::SelectObject(srcDC, 0); | |
660 | ::DeleteDC(srcDC); | |
661 | ::SelectObject(destDC, 0); | |
662 | ::DeleteDC(destDC); | |
663 | return TRUE; | |
0e320a79 DW |
664 | } |
665 | ||
3b9e3455 DW |
666 | // ---------------------------------------------------------------------------- |
667 | // wxBitmapHandler | |
668 | // ---------------------------------------------------------------------------- | |
0e320a79 | 669 | |
3b9e3455 DW |
670 | bool wxBitmapHandler::Create(wxGDIImage *image, |
671 | void *data, | |
672 | long flags, | |
673 | int width, int height, int depth) | |
674 | { | |
675 | wxBitmap *bitmap = wxDynamicCast(image, wxBitmap); | |
0e320a79 | 676 | |
3b9e3455 DW |
677 | return bitmap ? Create(bitmap, data, width, height, depth) : FALSE; |
678 | } | |
679 | ||
680 | bool wxBitmapHandler::Load(wxGDIImage *image, | |
681 | const wxString& name, | |
682 | long flags, | |
683 | int width, int height) | |
684 | { | |
685 | wxBitmap *bitmap = wxDynamicCast(image, wxBitmap); | |
686 | ||
687 | return bitmap ? LoadFile(bitmap, name, flags, width, height) : FALSE; | |
688 | } | |
689 | ||
690 | bool wxBitmapHandler::Save(wxGDIImage *image, | |
691 | const wxString& name, | |
692 | int type) | |
693 | { | |
694 | wxBitmap *bitmap = wxDynamicCast(image, wxBitmap); | |
695 | ||
696 | return bitmap ? SaveFile(bitmap, name, type) : FALSE; | |
697 | } | |
698 | ||
699 | bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), | |
700 | void *WXUNUSED(data), | |
701 | long WXUNUSED(type), | |
702 | int WXUNUSED(width), | |
703 | int WXUNUSED(height), | |
704 | int WXUNUSED(depth)) | |
0e320a79 DW |
705 | { |
706 | return FALSE; | |
707 | } | |
708 | ||
3b9e3455 DW |
709 | bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), |
710 | const wxString& WXUNUSED(name), | |
711 | long WXUNUSED(type), | |
712 | int WXUNUSED(desiredWidth), | |
713 | int WXUNUSED(desiredHeight)) | |
0e320a79 DW |
714 | { |
715 | return FALSE; | |
716 | } | |
717 | ||
3b9e3455 DW |
718 | bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), |
719 | const wxString& WXUNUSED(name), | |
720 | int WXUNUSED(type), | |
721 | const wxPalette *WXUNUSED(palette)) | |
0e320a79 DW |
722 | { |
723 | return FALSE; | |
724 | } | |
725 | ||
3b9e3455 DW |
726 | // ---------------------------------------------------------------------------- |
727 | // DIB functions | |
728 | // ---------------------------------------------------------------------------- | |
0e320a79 | 729 | |
3b9e3455 DW |
730 | bool wxCreateDIB(long xSize, long ySize, long bitsPerPixel, |
731 | HPALETTE hPal, LPBITMAPINFO* lpDIBHeader) | |
0e320a79 | 732 | { |
3b9e3455 DW |
733 | unsigned long i, headerSize; |
734 | LPBITMAPINFO lpDIBheader = NULL; | |
735 | LPPALETTEENTRY lpPe = NULL; | |
0e320a79 | 736 | |
0e320a79 | 737 | |
3b9e3455 DW |
738 | // Allocate space for a DIB header |
739 | headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY))); | |
740 | lpDIBheader = (BITMAPINFO *) malloc(headerSize); | |
741 | lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER)); | |
742 | ||
743 | GetPaletteEntries(hPal, 0, 256, lpPe); | |
744 | ||
745 | memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER)); | |
746 | ||
747 | // Fill in the static parts of the DIB header | |
748 | lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
749 | lpDIBheader->bmiHeader.biWidth = xSize; | |
750 | lpDIBheader->bmiHeader.biHeight = ySize; | |
751 | lpDIBheader->bmiHeader.biPlanes = 1; | |
752 | ||
753 | // this value must be 1, 4, 8 or 24 so PixelDepth can only be | |
754 | lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel); | |
755 | lpDIBheader->bmiHeader.biCompression = BI_RGB; | |
756 | lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >> 3; | |
757 | lpDIBheader->bmiHeader.biClrUsed = 256; | |
758 | ||
759 | ||
760 | // Initialize the DIB palette | |
761 | for (i = 0; i < 256; i++) { | |
762 | lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags; | |
763 | lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed; | |
764 | lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen; | |
765 | lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue; | |
766 | } | |
767 | ||
768 | *lpDIBHeader = lpDIBheader; | |
769 | ||
770 | return TRUE; | |
0e320a79 DW |
771 | } |
772 | ||
3b9e3455 | 773 | void wxFreeDIB(LPBITMAPINFO lpDIBHeader) |
0e320a79 | 774 | { |
3b9e3455 | 775 | free(lpDIBHeader); |
0e320a79 | 776 | } |
ce44c50e | 777 | |
3b9e3455 | 778 |