]> git.saurik.com Git - wxWidgets.git/blame - src/os2/bitmap.cpp
More GTK+ 1.3.1 fixes
[wxWidgets.git] / src / os2 / bitmap.cpp
CommitLineData
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
aa213887
SN
12#ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14#endif
15
d88de032
DW
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifndef WX_PRECOMP
20 #include <stdio.h>
21
22 #include "wx/list.h"
23 #include "wx/utils.h"
24 #include "wx/app.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
28 #include "wx/icon.h"
0e320a79
DW
29#endif
30
d88de032 31#include "wx/os2/private.h"
0e320a79
DW
32#include "wx/log.h"
33
3b9e3455
DW
34//#include "wx/msw/dib.h"
35#include "wx/image.h"
36
d88de032
DW
37// ----------------------------------------------------------------------------
38// macros
39// ----------------------------------------------------------------------------
40
0e320a79
DW
41IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
42IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
3b9e3455
DW
43
44IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
0e320a79 45
3b9e3455
DW
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
51// wxBitmapRefData
52// ----------------------------------------------------------------------------
53
0e320a79
DW
54wxBitmapRefData::wxBitmapRefData()
55{
3b9e3455
DW
56 m_nQuality = 0;
57 m_pSelectedInto = NULL;
58 m_nNumColors = 0;
59 m_pBitmapMask = NULL;
341366c6
DW
60 m_hBitmap = (WXHBITMAP) NULL;
61} // end of wxBitmapRefData::wxBitmapRefData
0e320a79 62
3b9e3455 63void wxBitmapRefData::Free()
0e320a79 64{
3b9e3455
DW
65 wxASSERT_MSG( !m_pSelectedInto,
66 wxT("deleting bitmap still selected into wxMemoryDC") );
0e320a79 67
3b9e3455
DW
68 if (m_hBitmap)
69 {
70 if ( !::GpiDeleteBitmap((HBITMAP)m_hBitmap) )
71 {
72 wxLogLastError("GpiDeleteBitmap(hbitmap)");
73 }
74 }
75
76 delete m_pBitmapMask;
77 m_pBitmapMask = NULL;
341366c6 78} // end of wxBitmapRefData::Free
0e320a79 79
3b9e3455
DW
80// ----------------------------------------------------------------------------
81// wxBitmap creation
82// ----------------------------------------------------------------------------
0e320a79 83
3b9e3455
DW
84// this function should be called from all wxBitmap ctors
85void wxBitmap::Init()
0e320a79 86{
3b9e3455 87 // m_refData = NULL; done in the base class ctor
0e320a79 88
3b9e3455 89 if (wxTheBitmapList)
0e320a79 90 wxTheBitmapList->AddBitmap(this);
6f38c86f 91} // end of wxBitmap::Init
0e320a79 92
3b9e3455
DW
93bool wxBitmap::CopyFromIconOrCursor(
94 const wxGDIImage& rIcon
95)
d88de032 96{
6f38c86f
DW
97 HPOINTER hIcon = (HPOINTER)rIcon.GetHandle();
98 POINTERINFO SIconInfo;
99
100 if (!::WinQueryPointerInfo(hIcon, &SIconInfo))
101 {
102 wxLogLastError(wxT("WinQueryPointerInfo"));
103 return FALSE;
104 }
3b9e3455 105 wxBitmapRefData* pRefData = new wxBitmapRefData;
d88de032 106
3b9e3455 107 m_refData = pRefData;
d88de032 108
6f38c86f
DW
109 int nWidth = rIcon.GetWidth();
110 int nHeight = rIcon.GetHeight();
d88de032 111
6f38c86f
DW
112 pRefData->m_nWidth = nWidth;
113 pRefData->m_nHeight = nHeight;
114 pRefData->m_nDepth = wxDisplayDepth();
d88de032 115
6f38c86f
DW
116 pRefData->m_hBitmap = (WXHBITMAP)SIconInfo.hbmColor;
117
118 //
119 // No mask in the Info struct in OS/2
120 //
3b9e3455 121 return(TRUE);
6f38c86f 122} // end of wxBitmap::CopyFromIconOrCursor
0e320a79 123
3b9e3455
DW
124bool wxBitmap::CopyFromCursor(
125 const wxCursor& rCursor
126)
d88de032 127{
3b9e3455 128 UnRef();
d88de032 129
3b9e3455
DW
130 if (!rCursor.Ok())
131 return(FALSE);
43543d98 132 return(CopyFromIconOrCursor(rCursor));
6f38c86f 133} // end of wxBitmap::CopyFromCursor
d88de032 134
3b9e3455
DW
135bool wxBitmap::CopyFromIcon(
136 const wxIcon& rIcon
137)
0e320a79 138{
3b9e3455 139 UnRef();
0e320a79 140
3b9e3455
DW
141 if (!rIcon.Ok())
142 return(FALSE);
0e320a79 143
43543d98 144 return CopyFromIconOrCursor(rIcon);
6f38c86f 145} // end of wxBitmap::CopyFromIcon
0e320a79 146
3b9e3455 147wxBitmap::~wxBitmap()
d88de032 148{
3b9e3455
DW
149 if (wxTheBitmapList)
150 wxTheBitmapList->DeleteObject(this);
6f38c86f 151} // end of wxBitmap::~wxBitmap
d88de032 152
3b9e3455
DW
153wxBitmap::wxBitmap(
154 const char zBits[]
155, int nTheWidth
156, int nTheHeight
157, int nNoBits
158)
159{
160 Init();
161
162 wxBitmapRefData* pRefData = new wxBitmapRefData;
163 BITMAPINFOHEADER2 vHeader;
164 BITMAPINFO2 vInfo;
165 HDC hDc;
166 HPS hPs;
43543d98 167 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3b9e3455
DW
168 SIZEL vSize = {0, 0};
169
43543d98 170 wxASSERT(vHabmain != NULL);
3b9e3455
DW
171
172 hDc = ::DevOpenDC(vHabmain, OD_MEMORY, (PSZ)"*", 1L, (PDEVOPENDATA)&vDop, 0L);
173
174 vHeader.cbFix = sizeof(vHeader);
175 vHeader.cx = (USHORT)nTheWidth;
176 vHeader.cy = (USHORT)nTheHeight;
177 vHeader.cPlanes = 1L;
178 vHeader.cBitCount = nNoBits;
179 vHeader.ulCompression = BCA_UNCOMP;
180 vHeader.cxResolution = 0;
181 vHeader.cyResolution = 0;
182 vHeader.cclrUsed = 0;
183 vHeader.cclrImportant = 0;
184 vHeader.usUnits = BRU_METRIC;
185 vHeader.usRecording = BRA_BOTTOMUP;
186 vHeader.usRendering = BRH_NOTHALFTONED;
187 vHeader.cSize1 = 0;
188 vHeader.cSize2 = 0;
189 vHeader.ulColorEncoding = 0;
190 vHeader.ulIdentifier = 0;
191
43543d98 192 hPs = ::GpiCreatePS(vHabmain, hDc, &vSize, GPIA_ASSOC | PU_PELS);
4f72fe4f 193 if (hPs == 0)
3b9e3455
DW
194 {
195 wxLogLastError("GpiCreatePS Failure");
196 }
0e320a79 197
3b9e3455 198 m_refData = pRefData;
0e320a79 199
43543d98
DW
200 pRefData->m_nWidth = nTheWidth;
201 pRefData->m_nHeight = nTheHeight;
202 pRefData->m_nDepth = nNoBits;
203 pRefData->m_nNumColors = 0;
204 pRefData->m_pSelectedInto = NULL;
0e320a79 205
3b9e3455 206 HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, 0L, NULL, &vInfo);
43543d98 207 if (!hBmp)
3b9e3455
DW
208 {
209 wxLogLastError("CreateBitmap");
210 }
43543d98 211 SetHBITMAP((WXHBITMAP)hBmp);
6f38c86f 212} // end of wxBitmap::wxBitmap
0e320a79 213
6f38c86f 214//
3b9e3455 215// Create from XPM data
6f38c86f 216//
3b9e3455
DW
217wxBitmap::wxBitmap(
218 char** ppData
6f38c86f
DW
219)
220{
221 Init();
222
223 (void)Create( (void *)ppData
224 ,wxBITMAP_TYPE_XPM_DATA
225 ,0
226 ,0
227 ,0
228 );
229} // end of wxBitmap::wxBitmap
230
231wxBitmap::wxBitmap(
232 const char** ppData
233)
3b9e3455
DW
234{
235 Init();
236
43543d98 237 (void)Create( (void *)ppData
3b9e3455
DW
238 ,wxBITMAP_TYPE_XPM_DATA
239 ,0
240 ,0
241 ,0
242 );
6f38c86f 243} // end of wxBitmap::wxBitmap
3b9e3455
DW
244
245wxBitmap::wxBitmap(
246 int nW
247, int nH
248, int nD
249)
250{
251 Init();
252
253 (void)Create( nW
254 ,nH
255 ,nD
256 );
6f38c86f 257} // end of wxBitmap::wxBitmap
3b9e3455
DW
258
259wxBitmap::wxBitmap(
260 void* pData
261, long lType
262, int nWidth
263, int nHeight
264, int nDepth
265)
266{
267 Init();
268
269 (void)Create( pData
270 ,lType
271 ,nWidth
272 ,nHeight
273 ,nDepth
274 );
6f38c86f 275} // end of wxBitmap::wxBitmap
3b9e3455
DW
276
277wxBitmap::wxBitmap(
278 const wxString& rFilename
279, long lType
280)
281{
282 Init();
283
284 LoadFile( rFilename
285 ,(int)lType
286 );
6f38c86f 287} // end of wxBitmap::wxBitmap
3b9e3455
DW
288
289bool wxBitmap::Create(
290 int nW
291, int nH
292, int nD
293)
294{
295 HBITMAP hBmp;
296 BITMAPINFOHEADER2 vHeader;
3b9e3455 297
43543d98 298 wxASSERT(vHabmain != NULL);
0e320a79 299 UnRef();
0e320a79 300 m_refData = new wxBitmapRefData;
43543d98
DW
301 GetBitmapData()->m_nWidth = nW;
302 GetBitmapData()->m_nHeight = nH;
303 GetBitmapData()->m_nDepth = nD;
0e320a79 304
3b9e3455
DW
305 if (nD > 0)
306 {
6f38c86f
DW
307 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
308 SIZEL vSize = {0, 0};
309 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
310 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
311
312 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
313 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
314 vHeader.cx = nW;
315 vHeader.cy = nH;
316 vHeader.cPlanes = 1;
317 vHeader.cBitCount = nD;
318
319 hBmp = ::GpiCreateBitmap( hPS
320 ,&vHeader
321 ,0L
322 ,NULL
323 ,NULL
324 );
325 ::GpiDestroyPS(hPS);
326 ::DevCloseDC(hDC);
3b9e3455
DW
327 }
328 else
329 {
6f38c86f
DW
330 HPS hPSScreen;
331 HDC hDCScreen;
332 LONG lBitCount;
333
334 hPSScreen = ::WinGetScreenPS(HWND_DESKTOP);
335 hDCScreen = ::GpiQueryDevice(hPSScreen);
336 ::DevQueryCaps(hDCScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
337
338 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
339 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
340 vHeader.cx = nW;
341 vHeader.cy = nH;
342 vHeader.cPlanes = 1;
343 vHeader.cBitCount = lBitCount;
344
345 hBmp = ::GpiCreateBitmap( hPSScreen
346 ,&vHeader
347 ,0L
348 ,NULL
349 ,NULL
350 );
4f72fe4f 351
43543d98 352 GetBitmapData()->m_nDepth = wxDisplayDepth();
6f38c86f 353 ::WinReleasePS(hPSScreen);
3b9e3455 354 }
4f72fe4f 355 SetHBITMAP((WXHBITMAP)hBmp);
0e320a79 356
3b9e3455 357#if WXWIN_COMPATIBILITY_2
4f72fe4f 358 GetBitmapData()->m_bOk = hBmp != 0;
3b9e3455
DW
359#endif // WXWIN_COMPATIBILITY_2
360
361 return Ok();
6f38c86f 362} // end of wxBitmap::Create
0e320a79 363
4f72fe4f
DW
364bool wxBitmap::LoadFile(
365 const wxString& rFilename
366, long lType
367)
0e320a79 368{
4e0f4f97 369 HPS hPs = NULLHANDLE;
8ea3f821 370
0e320a79
DW
371 UnRef();
372
4f72fe4f
DW
373 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
374 ,wxBitmapHandler
375 );
0e320a79 376
4f72fe4f 377 if (pHandler)
3b9e3455
DW
378 {
379 m_refData = new wxBitmapRefData;
0e320a79 380
4f72fe4f
DW
381 return(pHandler->LoadFile( this
382 ,rFilename
8ea3f821 383 ,hPs
4f72fe4f
DW
384 ,lType
385 , -1
386 , -1
43543d98 387 ));
0e320a79 388 }
3b9e3455
DW
389 else
390 {
4f72fe4f 391 wxImage vImage;
0e320a79 392
43543d98 393 if (!vImage.LoadFile(rFilename, lType) || !vImage.Ok() )
4f72fe4f 394 return(FALSE);
3b9e3455 395
4f72fe4f
DW
396 *this = vImage.ConvertToBitmap();
397
398 return(TRUE);
3b9e3455 399 }
6f38c86f 400} // end of wxBitmap::LoadFile
0e320a79 401
4f72fe4f
DW
402bool wxBitmap::Create(
403 void* pData
404, long lType
405, int nWidth
406, int nHeight
407, int nDepth
408)
0e320a79
DW
409{
410 UnRef();
411
4f72fe4f
DW
412 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
413 ,wxBitmapHandler
414 );
0e320a79 415
4f72fe4f 416 if (!pHandler)
3b9e3455
DW
417 {
418 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
43543d98 419 "type %d defined."), lType);
0e320a79 420
4f72fe4f 421 return(FALSE);
0e320a79
DW
422 }
423
3b9e3455
DW
424 m_refData = new wxBitmapRefData;
425
43543d98
DW
426 return(pHandler->Create( this
427 ,pData
428 ,lType
429 ,nWidth
430 ,nHeight
431 ,nDepth
432 ));
6f38c86f 433} // end of wxBitmap::Create
0e320a79 434
58b16424 435bool wxBitmap::SaveFile(
4f72fe4f
DW
436 const wxString& rFilename
437, int lType
438, const wxPalette* pPalette
439)
0e320a79 440{
4f72fe4f
DW
441 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
442 ,wxBitmapHandler
443 );
0e320a79 444
4f72fe4f 445 if (pHandler)
3b9e3455 446 {
4f72fe4f
DW
447 return pHandler->SaveFile( this
448 ,rFilename
449 ,lType
450 ,pPalette
451 );
3b9e3455
DW
452 }
453 else
454 {
455 // FIXME what about palette? shouldn't we use it?
4f72fe4f
DW
456 wxImage vImage(*this);
457
458 if (!vImage.Ok())
459 return(FALSE);
0e320a79 460
4f72fe4f
DW
461 return(vImage.SaveFile( rFilename
462 ,lType
463 ));
3b9e3455 464 }
6f38c86f
DW
465} // end of wxBitmap::SaveFile
466
467// ----------------------------------------------------------------------------
468// sub bitmap extraction
469// ----------------------------------------------------------------------------
470
471wxBitmap wxBitmap::GetSubBitmap(
472 const wxRect& rRect
473) const
474{
475 wxCHECK_MSG( Ok() &&
476 (rRect.x >= 0) && (rRect.y >= 0) &&
477 (rRect.x + rRect.width <= GetWidth()) &&
478 (rRect.y + rRect.height <= GetHeight()),
479 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
480
481 wxBitmap vRet( rRect.width
482 ,rRect.height
483 ,GetDepth()
484 );
485 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
486
487
488 //
489 // Copy bitmap data
490 //
491 SIZEL vSize = {0, 0};
492 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
493 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
494 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
495 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
496 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
497 POINTL vPoint[4] = { rRect.x, rRect.y,
498 rRect.x + rRect.width, rRect.y + rRect.height,
499 0, 0, GetWidth(), GetHeight()
500 };
501
502 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
503 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
504 ::GpiBitBlt( hPSDst
505 ,hPSSrc
506 ,4L
507 ,vPoint
508 ,ROP_SRCCOPY
509 ,BBO_IGNORE
510 );
511
512 //
513 // Copy mask if there is one
514 //
515 if (GetMask())
516 {
517 BITMAPINFOHEADER2 vBmih;
518
519 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
520 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
521 vBmih.cx = rRect.width;
522 vBmih.cy = rRect.height;
523 vBmih.cPlanes = 1;
524 vBmih.cBitCount = 1;
525
526 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
527 ,&vBmih
528 ,0L
529 ,NULL
530 ,NULL
531 );
532
533 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
534 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
535
536 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
537 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
538 ::GpiBitBlt( hPSDst
539 ,hPSSrc
540 ,4L
541 ,vPoint
542 ,ROP_SRCCOPY
543 ,BBO_IGNORE
544 );
545
546 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
547 vRet.SetMask(pMask);
548 }
549
550 ::GpiSetBitmap(hPSSrc, NULL);
551 ::GpiSetBitmap(hPSDst, NULL);
552 ::GpiDestroyPS(hPSSrc);
553 ::GpiDestroyPS(hPSDst);
554 ::DevCloseDC(hDCSrc);
555 ::DevCloseDC(hDCDst);
556 return vRet;
557} // end of wxBitmap::GetSubBitmap
0e320a79 558
3b9e3455
DW
559// ----------------------------------------------------------------------------
560// wxBitmap accessors
561// ----------------------------------------------------------------------------
0e320a79 562
4f72fe4f
DW
563void wxBitmap::SetQuality(
564 int nQ
565)
0e320a79 566{
3b9e3455 567 EnsureHasData();
0e320a79 568
4f72fe4f 569 GetBitmapData()->m_nQuality = nQ;
6f38c86f 570} // end of wxBitmap::SetQuality
0e320a79 571
3b9e3455 572#if WXWIN_COMPATIBILITY_2
4f72fe4f
DW
573void wxBitmap::SetOk(
574 bool bOk
575)
0e320a79 576{
3b9e3455 577 EnsureHasData();
0e320a79 578
4f72fe4f 579 GetBitmapData()->m_bOk = bOk;
6f38c86f 580} // end of wxBitmap::SetOk
3b9e3455 581#endif // WXWIN_COMPATIBILITY_2
0e320a79 582
4f72fe4f
DW
583void wxBitmap::SetPalette(
584 const wxPalette& rPalette
585)
0e320a79 586{
3b9e3455 587 EnsureHasData();
0e320a79 588
4f72fe4f 589 GetBitmapData()->m_vBitmapPalette = rPalette;
6f38c86f 590} // end of wxBitmap::SetPalette
0e320a79 591
4f72fe4f
DW
592void wxBitmap::SetMask(
593 wxMask* pMask
594)
0e320a79 595{
3b9e3455 596 EnsureHasData();
0e320a79 597
4f72fe4f 598 GetBitmapData()->m_pBitmapMask = pMask;
6f38c86f 599} // end of wxBitmap::SetMask
0e320a79 600
6f38c86f 601//
4f72fe4f 602// Will try something for OS/2 but not really sure how close
58b16424 603// to the msw intent this is.
6f38c86f 604//
4f72fe4f
DW
605wxBitmap wxBitmap::GetBitmapForDC(
606 wxDC& rDc
607) const
d88de032 608{
4f72fe4f
DW
609 wxMemoryDC vMemDC;
610 wxBitmap vTmpBitmap( this->GetWidth()
611 ,this->GetHeight()
612 ,rDc.GetDepth()
613 );
43543d98 614 WXHBITMAP vOldBitmap;
4f72fe4f
DW
615 HPS hMemoryPS;
616 HPS hPs;
617 POINTL vPoint[4];
43543d98 618 SIZEL vSize = {0,0};
d88de032 619
43543d98
DW
620 hMemoryPS = ::GpiCreatePS(vHabmain, (HDC)vMemDC.GetHDC(), &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
621 hPs = ::GpiCreatePS(vHabmain, (HDC)rDc.GetHDC(), &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
d88de032 622
4f72fe4f 623 // TODO: Set the points
3b9e3455 624
43543d98
DW
625 vOldBitmap = (WXHBITMAP)::GpiSetBitmap(hPs, (HBITMAP)vTmpBitmap.GetHBITMAP());
626 ::GpiBitBlt(hPs, hMemoryPS, 4L, vPoint, ROP_SRCCOPY, BBO_IGNORE);
58b16424
DW
627
628 return(vTmpBitmap);
6f38c86f 629} // end of wxBitmap::GetBitmapForDC
d88de032 630
3b9e3455
DW
631// ----------------------------------------------------------------------------
632// wxMask
633// ----------------------------------------------------------------------------
0e320a79
DW
634
635wxMask::wxMask()
636{
4f72fe4f 637 m_hMaskBitmap = 0;
6f38c86f 638} // end of wxMask::wxMask
0e320a79
DW
639
640// Construct a mask from a bitmap and a colour indicating
641// the transparent area
4f72fe4f
DW
642wxMask::wxMask(
643 const wxBitmap& rBitmap
644, const wxColour& rColour
645)
0e320a79 646{
4f72fe4f
DW
647 m_hMaskBitmap = 0;
648 Create( rBitmap
649 ,rColour
650 );
6f38c86f 651} // end of wxMask::wxMask
0e320a79
DW
652
653// Construct a mask from a bitmap and a palette index indicating
654// the transparent area
4f72fe4f
DW
655wxMask::wxMask(
656 const wxBitmap& rBitmap
657, int nPaletteIndex
658)
0e320a79 659{
4f72fe4f
DW
660 m_hMaskBitmap = 0;
661 Create( rBitmap
662 ,nPaletteIndex
663 );
6f38c86f 664} // end of wxMask::wxMask
0e320a79
DW
665
666// Construct a mask from a mono bitmap (copies the bitmap).
4f72fe4f
DW
667wxMask::wxMask(
668 const wxBitmap& rBitmap
669)
0e320a79 670{
4f72fe4f
DW
671 m_hMaskBitmap = 0;
672 Create(rBitmap);
6f38c86f 673} // end of wxMask::wxMask
0e320a79
DW
674
675wxMask::~wxMask()
676{
4f72fe4f
DW
677 if (m_hMaskBitmap)
678 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
6f38c86f 679} // end of wxMask::~wxMask
0e320a79
DW
680
681// Create a mask from a mono bitmap (copies the bitmap).
58b16424
DW
682bool wxMask::Create(
683 const wxBitmap& rBitmap
684)
0e320a79 685{
6f38c86f 686 BITMAPINFOHEADER2 vBmih;
58b16424 687 SIZEL vSize = {0, 0};
6f38c86f
DW
688 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
689 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
690 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
691 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
692 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
693 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
694 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
695 };
58b16424
DW
696
697 if (m_hMaskBitmap)
3b9e3455 698 {
58b16424
DW
699 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
700 m_hMaskBitmap = 0;
3b9e3455 701 }
58b16424 702 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
3b9e3455 703 {
58b16424 704 return(FALSE);
3b9e3455 705 }
6f38c86f
DW
706
707 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
708 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
709 vBmih.cx = rBitmap.GetWidth();
710 vBmih.cy = rBitmap.GetHeight();
711 vBmih.cPlanes = 1;
712 vBmih.cBitCount = 1;
713
714 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
715 ,&vBmih
716 ,0L
717 ,NULL
718 ,NULL
719 );
720
721 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
722 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
723 ::GpiBitBlt( hPSDst
724 ,hPSSrc
725 ,4L
726 ,vPoint
727 ,ROP_SRCCOPY
728 ,BBO_IGNORE
729 );
730
731 ::GpiDestroyPS(hPSSrc);
732 ::GpiDestroyPS(hPSDst);
733 ::DevCloseDC(hDCSrc);
734 ::DevCloseDC(hDCDst);
58b16424 735 return(TRUE);
6f38c86f 736} // end of wxMask::Create
0e320a79
DW
737
738// Create a mask from a bitmap and a palette index indicating
739// the transparent area
58b16424
DW
740bool wxMask::Create(
741 const wxBitmap& rBitmap
742, int nPaletteIndex
743)
0e320a79 744{
58b16424 745 if (m_hMaskBitmap)
3b9e3455 746 {
58b16424
DW
747 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
748 m_hMaskBitmap = 0;
3b9e3455 749 }
58b16424 750 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
3b9e3455 751 {
43543d98
DW
752 unsigned char cRed;
753 unsigned char cGreen;
754 unsigned char cBlue;
755
58b16424 756 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
43543d98
DW
757 ,&cRed
758 ,&cGreen
759 ,&cBlue
58b16424 760 ))
3b9e3455 761 {
43543d98
DW
762 wxColour vTransparentColour( cRed
763 ,cGreen
764 ,cBlue
58b16424
DW
765 );
766
767 return (Create( rBitmap
768 ,vTransparentColour
769 ));
3b9e3455
DW
770 }
771 }
58b16424 772 return(FALSE);
6f38c86f 773} // end of wxMask::Create
0e320a79
DW
774
775// Create a mask from a bitmap and a colour indicating
776// the transparent area
58b16424
DW
777bool wxMask::Create(
778 const wxBitmap& rBitmap
779, const wxColour& rColour
780)
0e320a79 781{
6f38c86f
DW
782 bool bOk = TRUE;
783 COLORREF vMaskColour = OS2RGB( rColour.Red()
784 ,rColour.Green()
785 ,rColour.Blue()
786 );
787 BITMAPINFOHEADER2 vBmih;
58b16424 788 SIZEL vSize = {0, 0};
6f38c86f
DW
789 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
790 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
791 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
792 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
793 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
794 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
795 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
796 };
58b16424
DW
797
798 if (m_hMaskBitmap)
3b9e3455 799 {
58b16424
DW
800 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
801 m_hMaskBitmap = 0;
3b9e3455 802 }
58b16424 803 if (!rBitmap.Ok())
3b9e3455 804 {
58b16424 805 return(FALSE);
3b9e3455
DW
806 }
807
6f38c86f
DW
808 //
809 // Scan the bitmap for the transparent colour and set
3b9e3455
DW
810 // the corresponding pixels in the mask to BLACK and
811 // the rest to WHITE
6f38c86f
DW
812 //
813
814 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
815 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
816 vBmih.cx = rBitmap.GetWidth();
817 vBmih.cy = rBitmap.GetHeight();
818 vBmih.cPlanes = 1;
819 vBmih.cBitCount = 1;
820
821 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
822 ,&vBmih
823 ,0L
824 ,NULL
825 ,NULL
826 );
827
828 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
829 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
830
831 //
832 // This is not very efficient, but I can't think
3b9e3455 833 // of a better way of doing it
6f38c86f 834 //
58b16424 835 for (int w = 0; w < rBitmap.GetWidth(); w++)
3b9e3455 836 {
58b16424 837 for (int h = 0; h < rBitmap.GetHeight(); h++)
3b9e3455 838 {
6f38c86f
DW
839 POINTL vPt = {w, h};
840 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
841 if (vCol == (COLORREF)CLR_NOINDEX)
842 {
843 //
844 // Doesn't make sense to continue
845 //
846 bOk = FALSE;
847 break;
848 }
58b16424 849
6f38c86f 850 if (vCol == vMaskColour)
3b9e3455 851 {
6f38c86f
DW
852 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
853 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
854 }
855 else
856 {
6f38c86f
DW
857 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
858 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
859 }
860 }
861 }
6f38c86f
DW
862 ::GpiSetBitmap(hPSSrc, NULL);
863 ::GpiSetBitmap(hPSDst, NULL);
864 ::GpiDestroyPS(hPSSrc);
865 ::GpiDestroyPS(hPSDst);
866 ::DevCloseDC(hDCSrc);
867 ::DevCloseDC(hDCDst);
58b16424 868 return(TRUE);
6f38c86f 869} // end of wxMask::Create
0e320a79 870
3b9e3455
DW
871// ----------------------------------------------------------------------------
872// wxBitmapHandler
873// ----------------------------------------------------------------------------
0e320a79 874
58b16424
DW
875bool wxBitmapHandler::Create(
876 wxGDIImage* pImage
877, void* pData
878, long lFlags
879, int nWidth
880, int nHeight
881, int nDepth
882)
3b9e3455 883{
58b16424
DW
884 wxBitmap* pBitmap = wxDynamicCast( pImage
885 ,wxBitmap
886 );
3b9e3455 887
58b16424
DW
888 return(pBitmap ? Create( pBitmap
889 ,pData
890 ,nWidth
891 ,nHeight
892 ,nDepth
893 ) : FALSE);
3b9e3455
DW
894}
895
58b16424
DW
896bool wxBitmapHandler::Load(
897 wxGDIImage* pImage
898, const wxString& rName
8ea3f821 899, HPS hPs
58b16424
DW
900, long lFlags
901, int nWidth
902, int nHeight
903)
3b9e3455 904{
43543d98
DW
905 wxBitmap* pBitmap = wxDynamicCast( pImage
906 ,wxBitmap
907 );
3b9e3455 908
58b16424
DW
909 return(pBitmap ? LoadFile( pBitmap
910 ,rName
8ea3f821 911 ,hPs
58b16424
DW
912 ,lFlags
913 ,nWidth
914 ,nHeight
915 ) : FALSE);
3b9e3455
DW
916}
917
58b16424
DW
918bool wxBitmapHandler::Save(
919 wxGDIImage* pImage
920, const wxString& rName
921, int lType
922)
0e320a79 923{
58b16424
DW
924 wxBitmap* pBitmap = wxDynamicCast( pImage
925 ,wxBitmap
926 );
0e320a79 927
58b16424
DW
928 return(pBitmap ? SaveFile( pBitmap
929 ,rName
930 ,lType
931 ) : FALSE);
0e320a79
DW
932}
933
58b16424
DW
934bool wxBitmapHandler::Create(
935 wxBitmap* WXUNUSED(pBitmap)
936, void* WXUNUSED(pData)
937, long WXUNUSED(lType)
938, int WXUNUSED(nWidth)
939, int WXUNUSED(nHeight)
940, int WXUNUSED(nDepth)
941)
0e320a79 942{
58b16424 943 return(FALSE);
0e320a79
DW
944}
945
58b16424
DW
946bool wxBitmapHandler::LoadFile(
947 wxBitmap* WXUNUSED(pBitmap)
948, const wxString& WXUNUSED(rName)
8ea3f821 949, HPS WXUNUSED(hPs)
58b16424
DW
950, long WXUNUSED(lType)
951, int WXUNUSED(nDesiredWidth)
952, int WXUNUSED(nDesiredHeight)
953)
0e320a79 954{
43543d98 955 return(FALSE);
0e320a79
DW
956}
957
58b16424
DW
958bool wxBitmapHandler::SaveFile(
959 wxBitmap* WXUNUSED(pBitmap)
960, const wxString& WXUNUSED(rName)
961, int WXUNUSED(nType)
962, const wxPalette* WXUNUSED(pPalette)
963)
0e320a79 964{
58b16424 965 return(FALSE);
0e320a79 966}
ce44c50e 967
020a1653
DW
968// ----------------------------------------------------------------------------
969// Utility functions
970// ----------------------------------------------------------------------------
971HBITMAP wxInvertMask(
972 HBITMAP hBmpMask
973, int nWidth
974, int nHeight
975)
976{
977 HBITMAP hBmpInvMask = 0;
978
979 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
980
981 //
982 // Get width/height from the bitmap if not given
983 //
984 if (!nWidth || !nHeight)
985 {
986 BITMAPINFOHEADER2 vBmhdr;
987
988 ::GpiQueryBitmapInfoHeader( hBmpMask
989 ,&vBmhdr
990 );
991 nWidth = (int)vBmhdr.cx;
e464c180 992 nHeight = (int)vBmhdr.cy;
020a1653
DW
993 }
994
995 BITMAPINFOHEADER2 vBmih;
996 SIZEL vSize = {0, 0};
997 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
e464c180
DW
998 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
999 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1000 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1001 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1002 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1003 0, 0, nWidth, nHeight
020a1653
DW
1004 };
1005
e464c180 1006 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
020a1653 1007 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
e464c180
DW
1008 vBmih.cx = nWidth;
1009 vBmih.cy = nHeight;
020a1653
DW
1010 vBmih.cPlanes = 1;
1011 vBmih.cBitCount = 1;
1012
1013 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1014 ,&vBmih
1015 ,0L
1016 ,NULL
1017 ,NULL
1018 );
1019
1020 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1021 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1022
1023 ::GpiBitBlt( hPSDst
1024 ,hPSSrc
1025 ,4L
e464c180 1026 ,vPoint
020a1653
DW
1027 ,ROP_SRCCOPY
1028 ,BBO_IGNORE
1029 );
1030
1031 ::GpiDestroyPS(hPSSrc);
1032 ::GpiDestroyPS(hPSDst);
1033 ::DevCloseDC(hDCSrc);
e464c180 1034 ::DevCloseDC(hDCDst);
020a1653
DW
1035
1036 return hBmpInvMask;
1037} // end of WxWinGdi_InvertMask