]> git.saurik.com Git - wxWidgets.git/blame - src/os2/bitmap.cpp
cleaned up the checkbox creation code (~70 lines of code became 3)
[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"
1c344e89 36#include "wx/xpmdecod.h"
3b9e3455 37
d88de032
DW
38// ----------------------------------------------------------------------------
39// macros
40// ----------------------------------------------------------------------------
41
0e320a79
DW
42IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
43IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
3b9e3455
DW
44
45IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
0e320a79 46
3b9e3455
DW
47// ============================================================================
48// implementation
49// ============================================================================
50
51// ----------------------------------------------------------------------------
52// wxBitmapRefData
53// ----------------------------------------------------------------------------
54
0e320a79
DW
55wxBitmapRefData::wxBitmapRefData()
56{
3b9e3455
DW
57 m_nQuality = 0;
58 m_pSelectedInto = NULL;
59 m_nNumColors = 0;
60 m_pBitmapMask = NULL;
341366c6
DW
61 m_hBitmap = (WXHBITMAP) NULL;
62} // end of wxBitmapRefData::wxBitmapRefData
0e320a79 63
3b9e3455 64void wxBitmapRefData::Free()
0e320a79 65{
3b9e3455
DW
66 wxASSERT_MSG( !m_pSelectedInto,
67 wxT("deleting bitmap still selected into wxMemoryDC") );
0e320a79 68
3b9e3455
DW
69 if (m_hBitmap)
70 {
3437f881 71 if (!::GpiDeleteBitmap((HBITMAP)m_hBitmap))
3b9e3455
DW
72 {
73 wxLogLastError("GpiDeleteBitmap(hbitmap)");
74 }
75 }
76
77 delete m_pBitmapMask;
78 m_pBitmapMask = NULL;
341366c6 79} // end of wxBitmapRefData::Free
0e320a79 80
3b9e3455
DW
81// ----------------------------------------------------------------------------
82// wxBitmap creation
83// ----------------------------------------------------------------------------
0e320a79 84
3b9e3455
DW
85// this function should be called from all wxBitmap ctors
86void wxBitmap::Init()
0e320a79 87{
6f38c86f 88} // end of wxBitmap::Init
0e320a79 89
3b9e3455
DW
90bool wxBitmap::CopyFromIconOrCursor(
91 const wxGDIImage& rIcon
92)
d88de032 93{
6f38c86f
DW
94 HPOINTER hIcon = (HPOINTER)rIcon.GetHandle();
95 POINTERINFO SIconInfo;
96
97 if (!::WinQueryPointerInfo(hIcon, &SIconInfo))
98 {
99 wxLogLastError(wxT("WinQueryPointerInfo"));
100 return FALSE;
101 }
3b9e3455 102 wxBitmapRefData* pRefData = new wxBitmapRefData;
d88de032 103
3b9e3455 104 m_refData = pRefData;
d88de032 105
6f38c86f
DW
106 int nWidth = rIcon.GetWidth();
107 int nHeight = rIcon.GetHeight();
d88de032 108
6f38c86f
DW
109 pRefData->m_nWidth = nWidth;
110 pRefData->m_nHeight = nHeight;
111 pRefData->m_nDepth = wxDisplayDepth();
d88de032 112
6f38c86f
DW
113 pRefData->m_hBitmap = (WXHBITMAP)SIconInfo.hbmColor;
114
115 //
116 // No mask in the Info struct in OS/2
117 //
3b9e3455 118 return(TRUE);
6f38c86f 119} // end of wxBitmap::CopyFromIconOrCursor
0e320a79 120
3b9e3455
DW
121bool wxBitmap::CopyFromCursor(
122 const wxCursor& rCursor
123)
d88de032 124{
3b9e3455 125 UnRef();
d88de032 126
3b9e3455
DW
127 if (!rCursor.Ok())
128 return(FALSE);
43543d98 129 return(CopyFromIconOrCursor(rCursor));
6f38c86f 130} // end of wxBitmap::CopyFromCursor
d88de032 131
3b9e3455
DW
132bool wxBitmap::CopyFromIcon(
133 const wxIcon& rIcon
134)
0e320a79 135{
3b9e3455 136 UnRef();
0e320a79 137
3b9e3455
DW
138 if (!rIcon.Ok())
139 return(FALSE);
0e320a79 140
43543d98 141 return CopyFromIconOrCursor(rIcon);
6f38c86f 142} // end of wxBitmap::CopyFromIcon
0e320a79 143
3b9e3455 144wxBitmap::~wxBitmap()
d88de032 145{
6f38c86f 146} // end of wxBitmap::~wxBitmap
d88de032 147
3b9e3455
DW
148wxBitmap::wxBitmap(
149 const char zBits[]
3437f881
DW
150, int nWidth
151, int nHeight
152, int nDepth
3b9e3455
DW
153)
154{
155 Init();
156
157 wxBitmapRefData* pRefData = new wxBitmapRefData;
158 BITMAPINFOHEADER2 vHeader;
159 BITMAPINFO2 vInfo;
160 HDC hDc;
161 HPS hPs;
43543d98 162 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3b9e3455 163 SIZEL vSize = {0, 0};
3437f881 164 char* pzData;
3b9e3455 165
43543d98 166 wxASSERT(vHabmain != NULL);
3b9e3455 167
3437f881 168 m_refData = pRefData;
3b9e3455 169
3437f881
DW
170 pRefData->m_nWidth = nWidth;
171 pRefData->m_nHeight = nHeight;
172 pRefData->m_nDepth = nDepth;
173 pRefData->m_nNumColors = 0;
174 pRefData->m_pSelectedInto = NULL;
3b9e3455 175
3437f881 176 hDc = ::DevOpenDC(vHabmain, OD_MEMORY, (PSZ)"*", 1L, (PDEVOPENDATA)&vDop, 0L);
43543d98 177 hPs = ::GpiCreatePS(vHabmain, hDc, &vSize, GPIA_ASSOC | PU_PELS);
4f72fe4f 178 if (hPs == 0)
3b9e3455
DW
179 {
180 wxLogLastError("GpiCreatePS Failure");
181 }
0e320a79 182
3437f881
DW
183 if (nDepth == 1)
184 {
185 //
186 // We assume that it is in XBM format which is not quite the same as
187 // the format CreateBitmap() wants because the order of bytes in the
188 // line is inversed!
189 //
190 const size_t nBytesPerLine = (nWidth + 7) / 8;
191 const size_t nPadding = nBytesPerLine % 2;
192 const size_t nLen = nHeight * (nPadding + nBytesPerLine);
193 const char* pzSrc = zBits;
194 int nRows;
195 size_t nCols;
196
197 pzData = (char *)malloc(nLen);
198
199 char* pzDst = pzData;
200
201 for (nRows = 0; nRows < nHeight; nRows++)
202 {
203 for (nCols = 0; nCols < nBytesPerLine; nCols++)
204 {
205 unsigned char ucVal = *pzSrc++;
206 unsigned char ucReversed = 0;
207 int nBits;
0e320a79 208
3437f881
DW
209 for (nBits = 0; nBits < 8; nBits++)
210 {
211 ucReversed <<= 1;
212 ucReversed |= (ucVal & 0x01);
213 ucVal >>= 1;
214 }
215 *pzDst++ = ucReversed;
216 }
217 if (nPadding)
218 *pzDst++ = 0;
219 }
220 }
221 else
222 {
223 //
224 // Bits should already be in Windows standard format
225 //
226 pzData = (char *)zBits; // const_cast is harmless
227 }
228
229 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
230 vHeader.cbFix = sizeof(vHeader);
231 vHeader.cx = (USHORT)nWidth;
232 vHeader.cy = (USHORT)nHeight;
233 vHeader.cPlanes = 1L;
234 vHeader.cBitCount = nDepth;
235 vHeader.usReserved = 0;
236 vHeader.ulCompression = BCA_UNCOMP;
237 vHeader.usRecording = BRA_BOTTOMUP;
238 vHeader.usRendering = BRH_NOTHALFTONED;
239 vHeader.ulColorEncoding = BCE_RGB;
240 vHeader.ulIdentifier = 0;
241
242 memset(&vInfo, '\0', sizeof(BITMAPINFO2));
243 vInfo.cbFix = sizeof(vInfo);
244 vInfo.cx = (USHORT)nWidth;
245 vInfo.cy = (USHORT)nHeight;
246 vInfo.cPlanes = 1L;
247 vInfo.cBitCount = nDepth;
248 vInfo.usReserved = 0;
249 vInfo.ulCompression = BCA_UNCOMP;
250 vInfo.usRecording = BRA_BOTTOMUP;
251 vInfo.usRendering = BRH_NOTHALFTONED;
252 vInfo.ulColorEncoding = BCE_RGB;
253 vInfo.ulIdentifier = 0;
254
255 HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, CBM_INIT, (PBYTE)pzData, &vInfo);
0e320a79 256
43543d98 257 if (!hBmp)
3b9e3455
DW
258 {
259 wxLogLastError("CreateBitmap");
260 }
3437f881 261 ::WinReleasePS(hPs);
43543d98 262 SetHBITMAP((WXHBITMAP)hBmp);
6f38c86f 263} // end of wxBitmap::wxBitmap
0e320a79 264
3b9e3455
DW
265wxBitmap::wxBitmap(
266 int nW
267, int nH
268, int nD
269)
270{
271 Init();
272
273 (void)Create( nW
274 ,nH
275 ,nD
276 );
6f38c86f 277} // end of wxBitmap::wxBitmap
3b9e3455
DW
278
279wxBitmap::wxBitmap(
280 void* pData
281, long lType
282, int nWidth
283, int nHeight
284, int nDepth
285)
286{
287 Init();
288
289 (void)Create( pData
290 ,lType
291 ,nWidth
292 ,nHeight
293 ,nDepth
294 );
6f38c86f 295} // end of wxBitmap::wxBitmap
3b9e3455
DW
296
297wxBitmap::wxBitmap(
298 const wxString& rFilename
299, long lType
300)
301{
302 Init();
303
304 LoadFile( rFilename
305 ,(int)lType
306 );
6f38c86f 307} // end of wxBitmap::wxBitmap
3b9e3455
DW
308
309bool wxBitmap::Create(
310 int nW
311, int nH
312, int nD
313)
314{
315 HBITMAP hBmp;
316 BITMAPINFOHEADER2 vHeader;
3b9e3455 317
43543d98 318 wxASSERT(vHabmain != NULL);
0e320a79 319 UnRef();
0e320a79 320 m_refData = new wxBitmapRefData;
43543d98
DW
321 GetBitmapData()->m_nWidth = nW;
322 GetBitmapData()->m_nHeight = nH;
323 GetBitmapData()->m_nDepth = nD;
0e320a79 324
3b9e3455
DW
325 if (nD > 0)
326 {
6f38c86f
DW
327 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
328 SIZEL vSize = {0, 0};
329 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
330 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
331
332 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
333 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
334 vHeader.cx = nW;
335 vHeader.cy = nH;
336 vHeader.cPlanes = 1;
337 vHeader.cBitCount = nD;
338
339 hBmp = ::GpiCreateBitmap( hPS
340 ,&vHeader
341 ,0L
342 ,NULL
343 ,NULL
344 );
345 ::GpiDestroyPS(hPS);
346 ::DevCloseDC(hDC);
3b9e3455
DW
347 }
348 else
349 {
6f38c86f
DW
350 HPS hPSScreen;
351 HDC hDCScreen;
352 LONG lBitCount;
353
354 hPSScreen = ::WinGetScreenPS(HWND_DESKTOP);
355 hDCScreen = ::GpiQueryDevice(hPSScreen);
356 ::DevQueryCaps(hDCScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
357
358 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
359 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
360 vHeader.cx = nW;
361 vHeader.cy = nH;
362 vHeader.cPlanes = 1;
363 vHeader.cBitCount = lBitCount;
364
365 hBmp = ::GpiCreateBitmap( hPSScreen
366 ,&vHeader
367 ,0L
368 ,NULL
369 ,NULL
370 );
4f72fe4f 371
43543d98 372 GetBitmapData()->m_nDepth = wxDisplayDepth();
6f38c86f 373 ::WinReleasePS(hPSScreen);
3b9e3455 374 }
4f72fe4f 375 SetHBITMAP((WXHBITMAP)hBmp);
0e320a79 376
3b9e3455 377#if WXWIN_COMPATIBILITY_2
4f72fe4f 378 GetBitmapData()->m_bOk = hBmp != 0;
3b9e3455
DW
379#endif // WXWIN_COMPATIBILITY_2
380
381 return Ok();
6f38c86f 382} // end of wxBitmap::Create
0e320a79 383
1c344e89
DW
384bool wxBitmap::CreateFromXpm(
385 const char** ppData
386)
387{
388#if wxUSE_IMAGE && wxUSE_XPM
389 Init();
390
391 wxCHECK_MSG(ppData != NULL, FALSE, wxT("invalid bitmap data"))
392
393 wxXPMDecoder vDecoder;
394 wxImage vImg = vDecoder.ReadData(ppData);
395
396 wxCHECK_MSG(vImg.Ok(), FALSE, wxT("invalid bitmap data"))
397
398 *this = wxBitmap(vImg);
399 return TRUE;
400#else
401 return FALSE;
402#endif
403} // end of wxBitmap::CreateFromXpm
404
4f72fe4f
DW
405bool wxBitmap::LoadFile(
406 const wxString& rFilename
407, long lType
408)
0e320a79 409{
4e0f4f97 410 HPS hPs = NULLHANDLE;
8ea3f821 411
0e320a79
DW
412 UnRef();
413
4f72fe4f
DW
414 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
415 ,wxBitmapHandler
416 );
0e320a79 417
4f72fe4f 418 if (pHandler)
3b9e3455
DW
419 {
420 m_refData = new wxBitmapRefData;
0e320a79 421
4f72fe4f
DW
422 return(pHandler->LoadFile( this
423 ,rFilename
8ea3f821 424 ,hPs
4f72fe4f
DW
425 ,lType
426 , -1
427 , -1
43543d98 428 ));
0e320a79 429 }
3b9e3455
DW
430 else
431 {
4f72fe4f 432 wxImage vImage;
0e320a79 433
43543d98 434 if (!vImage.LoadFile(rFilename, lType) || !vImage.Ok() )
4f72fe4f 435 return(FALSE);
3b9e3455 436
f95255e2 437 *this = wxBitmap(vImage);
4f72fe4f
DW
438
439 return(TRUE);
3b9e3455 440 }
6f38c86f 441} // end of wxBitmap::LoadFile
0e320a79 442
4f72fe4f
DW
443bool wxBitmap::Create(
444 void* pData
445, long lType
446, int nWidth
447, int nHeight
448, int nDepth
449)
0e320a79
DW
450{
451 UnRef();
452
4f72fe4f
DW
453 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
454 ,wxBitmapHandler
455 );
0e320a79 456
4f72fe4f 457 if (!pHandler)
3b9e3455
DW
458 {
459 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
43543d98 460 "type %d defined."), lType);
0e320a79 461
4f72fe4f 462 return(FALSE);
0e320a79
DW
463 }
464
3b9e3455
DW
465 m_refData = new wxBitmapRefData;
466
43543d98
DW
467 return(pHandler->Create( this
468 ,pData
469 ,lType
470 ,nWidth
471 ,nHeight
472 ,nDepth
473 ));
6f38c86f 474} // end of wxBitmap::Create
0e320a79 475
58b16424 476bool wxBitmap::SaveFile(
4f72fe4f
DW
477 const wxString& rFilename
478, int lType
479, const wxPalette* pPalette
480)
0e320a79 481{
4f72fe4f
DW
482 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
483 ,wxBitmapHandler
484 );
0e320a79 485
4f72fe4f 486 if (pHandler)
3b9e3455 487 {
4f72fe4f
DW
488 return pHandler->SaveFile( this
489 ,rFilename
490 ,lType
491 ,pPalette
492 );
3b9e3455
DW
493 }
494 else
495 {
496 // FIXME what about palette? shouldn't we use it?
f95255e2 497 wxImage vImage = ConvertToImage();
4f72fe4f
DW
498
499 if (!vImage.Ok())
500 return(FALSE);
0e320a79 501
4f72fe4f
DW
502 return(vImage.SaveFile( rFilename
503 ,lType
504 ));
3b9e3455 505 }
6f38c86f
DW
506} // end of wxBitmap::SaveFile
507
fec19ea9
VS
508
509// ----------------------------------------------------------------------------
510// wxImage-wxBitmap convertion
511// ----------------------------------------------------------------------------
512
3437f881
DW
513bool wxBitmap::CreateFromImage (
514 const wxImage& rImage
515, int nDepth
516)
fec19ea9 517{
3437f881
DW
518 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
519
520 int nSizeLimit = 1024 * 768 * 3;
521 int nWidth = GetWidth();
522 int nBmpHeight = GetHeight();
523 int nBytePerLine = nWidth * 3;
524 int nSizeDWORD = sizeof(DWORD);
525 int nLineBoundary = nBytePerLine % nSizeDWORD;
526 int nPadding = 0;
527
528 if (nLineBoundary > 0)
fec19ea9 529 {
3437f881
DW
530 nPadding = nSizeDWORD - nLineBoundary;
531 nBytePerLine += nPadding;
fec19ea9 532 }
3437f881
DW
533
534 //
535 // Calc the number of DIBs and heights of DIBs
536 //
537 int nNumDIB = 1;
538 int nHRemain = 0;
539 int nHeight = nSizeLimit / nBytePerLine;
540
541 if (nHeight >= nBmpHeight)
542 nHeight = nBmpHeight;
fec19ea9
VS
543 else
544 {
3437f881
DW
545 nNumDIB = nBmpHeight / nHeight;
546 nHRemain = nBmpHeight % nHeight;
547 if (nHRemain > 0)
548 nNumDIB++;
fec19ea9
VS
549 }
550
3437f881
DW
551 //
552 // Set bitmap parameters
553 //
554 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
555 SetWidth(nWidth);
556 SetHeight(nBmpHeight);
557 if (nDepth == -1)
558 nDepth = wxDisplayDepth();
559 SetDepth(nDepth);
560
561#if wxUSE_PALETTE
562 //
563 // Copy the palette from the source image
564 //
565 SetPalette(rImage.GetPalette());
566#endif // wxUSE_PALETTE
567
568 //
569 // Create a DIB header
570 //
571 BITMAPINFOHEADER2 vHeader;
572
573 //
fec19ea9 574 // Fill in the DIB header
3437f881
DW
575 //
576 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
577 vHeader.cbFix = sizeof(vHeader);
578 vHeader.cx = (USHORT)nWidth;
579 vHeader.cy = (USHORT)nHeight;
580 vHeader.cPlanes = 1L;
581 vHeader.cBitCount = 24;
582 vHeader.ulCompression = BCA_UNCOMP;
583 vHeader.cbImage = nBytePerLine * nHeight;
584 vHeader.cclrUsed = 0;
585
586 //
fec19ea9 587 // These seem not really needed for our purpose here.
3437f881
DW
588 //
589 vHeader.cxResolution = 0;
590 vHeader.cyResolution = 0;
591 vHeader.cclrImportant = 0;
592 vHeader.usUnits = BRU_METRIC;
593 vHeader.usReserved = 0;
594 vHeader.cSize1 = 0;
595 vHeader.cSize2 = 0;
596 vHeader.usRecording = BRA_BOTTOMUP;
597 vHeader.usRendering = BRH_NOTHALFTONED;
598 vHeader.ulColorEncoding = BCE_RGB;
599 vHeader.ulIdentifier = 0;
600
601 //
602 // Memory for DIB data
603 //
604 unsigned char* pucBits;
605
606 pucBits = (unsigned char *)malloc(vHeader.cbImage);
607 if(!pucBits)
608 {
609 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
610 return FALSE;
611 }
612
613 //
614 // Create and set the device-dependent bitmap
615 //
616 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
617 SIZEL vSize = {0, 0};
618 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
619 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
620 HBITMAP hBmp;
621 HBITMAP hBmpOld;
622
623 hBmp = ::GpiCreateBitmap( hPS
624 ,&vHeader
625 ,0L
626 ,NULL
627 ,NULL
628 );
629 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
630#if wxUSE_PALETTE
631 HPAL hOldPalette = NULLHANDLE;
632 if (rImage.GetPalette().Ok())
fec19ea9 633 {
3437f881 634 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
fec19ea9 635 }
3437f881 636#endif // wxUSE_PALETTE
fec19ea9 637
3437f881
DW
638 //
639 // Copy image data into DIB data and then into DDB (in a loop)
640 //
641 unsigned char* pData = rImage.GetData();
642 int i;
643 int j;
644 int n;
645 int nOrigin = 0;
646 unsigned char* ptdata = pData;
647 unsigned char* ptbits;
648
649 for (n = 0; n < nNumDIB; n++)
fec19ea9 650 {
3437f881 651 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
fec19ea9 652 {
3437f881
DW
653 //
654 // Redefine height and size of the (possibly) last smaller DIB
fec19ea9 655 // memory is not reallocated
3437f881
DW
656 //
657 nHeight = nHRemain;
658 vHeader.cy = (DWORD)(nHeight);
659 vHeader.cbImage = nBytePerLine * nHeight;
fec19ea9 660 }
3437f881
DW
661 ptbits = pucBits;
662 for (j = 0; j < nHeight; j++)
fec19ea9 663 {
3437f881 664 for (i = 0; i < nWidth; i++)
fec19ea9 665 {
3437f881
DW
666 *(ptbits++) = *(ptdata + 2);
667 *(ptbits++) = *(ptdata + 1);
668 *(ptbits++) = *(ptdata);
fec19ea9
VS
669 ptdata += 3;
670 }
3437f881
DW
671 for (i = 0; i < nPadding; i++)
672 *(ptbits++) = 0;
fec19ea9 673 }
3437f881
DW
674
675 //
676 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
677 //
678 POINTL vPoint[4] = { 0, nOrigin,
679 nWidth, nHeight,
680 0, 0, nWidth, nHeight
681 };
682
683 ::GpiBitBlt( hPS
684 ,hPS
685 ,4
686 ,vPoint
687 ,ROP_SRCCOPY
688 ,BBO_IGNORE
689 );
690 nOrigin += nHeight;
fec19ea9 691 }
3437f881
DW
692 SetHBITMAP((WXHBITMAP)hBmp);
693#if wxUSE_PALETTE
694 if (hOldPalette)
695 ::GpiSelectPalette(hPS, hOldPalette);
696#endif // wxUSE_PALETTE
fec19ea9 697
3437f881
DW
698 //
699 // Similarly, created an mono-bitmap for the possible mask
700 //
701 if (rImage.HasMask())
fec19ea9 702 {
3437f881
DW
703 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
704 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
705 vHeader.cx = nWidth;
706 vHeader.cy = nHeight;
707 vHeader.cPlanes = 1;
708 vHeader.cBitCount = 1;
709 hBmp = ::GpiCreateBitmap( hPS
710 ,&vHeader
711 ,0L
712 ,NULL
713 ,NULL
714 );
715 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
716 if (nNumDIB == 1)
717 nHeight = nBmpHeight;
718 else
719 nHeight = nSizeLimit / nBytePerLine;
720 vHeader.cy = (DWORD)(nHeight);
721 vHeader.cbImage = nBytePerLine * nHeight;
722 nOrigin = 0;
723
724 unsigned char cRed = rImage.GetMaskRed();
725 unsigned char cGreen = rImage.GetMaskGreen();
726 unsigned char cBlue = rImage.GetMaskBlue();
727 unsigned char cZero = 0;
728 unsigned char cOne = 255;
729
730 ptdata = pData;
731 for (n = 0; n < nNumDIB; n++)
fec19ea9 732 {
3437f881 733 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
fec19ea9 734 {
3437f881
DW
735 //
736 // Redefine height and size of the (possibly) last smaller DIB
fec19ea9 737 // memory is not reallocated
3437f881
DW
738 //
739 nHeight = nHRemain;
740 vHeader.cy = (DWORD)(nHeight);
741 vHeader.cbImage = nBytePerLine * nHeight;
fec19ea9 742 }
3437f881
DW
743 ptbits = pucBits;
744 for (int j = 0; j < nHeight; j++)
fec19ea9 745 {
3437f881 746 for (i = 0; i < nWidth; i++)
fec19ea9 747 {
3437f881 748 if ((*(ptdata++) != cRed) || (*(ptdata++) != cGreen) || (*(ptdata++) != cBlue))
fec19ea9 749 {
3437f881
DW
750 *(ptbits++) = cOne;
751 *(ptbits++) = cOne;
752 *(ptbits++) = cOne;
fec19ea9
VS
753 }
754 else
755 {
3437f881
DW
756 *(ptbits++) = cZero;
757 *(ptbits++) = cZero;
758 *(ptbits++) = cZero;
fec19ea9
VS
759 }
760 }
3437f881
DW
761 for (i = 0; i < nPadding; i++)
762 *(ptbits++) = cZero;
fec19ea9 763 }
3437f881
DW
764 POINTL vPoint[4] = { 0, nOrigin,
765 nWidth, nHeight,
766 0, 0, nWidth, nHeight
767 };
768
769 ::GpiBitBlt( hPS
770 ,hPS
771 ,4
772 ,vPoint
773 ,ROP_SRCCOPY
774 ,BBO_IGNORE
775 );
776 nOrigin += nHeight;
fec19ea9 777 }
fec19ea9 778
3437f881
DW
779 //
780 // Create a wxMask object
781 //
782 wxMask* pMask = new wxMask();
fec19ea9 783
3437f881
DW
784 pMask->SetMaskBitmap((WXHBITMAP)hBmp);
785 SetMask(pMask);
786 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
787 }
fec19ea9 788
3437f881
DW
789 //
790 // Free allocated resources
791 //
792 ::GpiSetBitmap(hPS, NULLHANDLE);
793 ::GpiDestroyPS(hPS);
794 ::DevCloseDC(hDC);
795 free(pucBits);
fec19ea9 796 return TRUE;
3437f881 797} // end of wxBitmap::CreateFromImage
fec19ea9
VS
798
799wxImage wxBitmap::ConvertToImage() const
800{
3437f881 801 wxImage vImage;
1c344e89 802
fec19ea9
VS
803 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
804
3437f881
DW
805 //
806 // Create an wxImage object
807 //
808 int nWidth = GetWidth();
809 int nHeight = GetHeight();
810 int nDevWidth;
811 int nDevHeight;
812 int nBytePerLine = nWidth * 3;
813 int nSizeDWORD = sizeof(DWORD);
814 int nLineBoundary = nBytePerLine % nSizeDWORD;
815 int nPadding = 0;
816 unsigned char* pData;
817 unsigned char* lpBits;
818 long lScans;
819 BITMAPINFOHEADER2 vDIBh;
820 BITMAPINFO2 vDIBInfo;
821 HDC hDCMem;
822 PSZ pszData[4] = { "Display", NULL, NULL, NULL };
823 HPS hPSMem;
824 HPS hPS;
825 SIZEL vSizlPage = {0,0};
826 HBITMAP hBitmap;
827
828 vImage.Create( nWidth
829 ,nHeight
830 );
831 pData = vImage.GetData();
832 if(!pData)
fec19ea9
VS
833 {
834 wxFAIL_MSG( wxT("could not allocate data for image") );
835 return wxNullImage;
836 }
3437f881 837 if(nLineBoundary > 0)
fec19ea9 838 {
3437f881
DW
839 nPadding = nSizeDWORD - nLineBoundary;
840 nBytePerLine += nPadding;
fec19ea9 841 }
3437f881
DW
842 wxDisplaySize( &nDevWidth
843 ,&nDevHeight
844 );
845 //
846 // Create and fill a DIB header
847 //
848 memset(&vDIBh, '\0', sizeof(BITMAPINFOHEADER2));
849 vDIBh.cbFix = sizeof(BITMAPINFOHEADER2);
850 vDIBh.cx = nWidth;
851 vDIBh.cy = nHeight;
852 vDIBh.cPlanes = 1;
853 vDIBh.cbImage = nBytePerLine * nHeight;
854 vDIBh.cBitCount = 24;
855
856 memset(&vDIBInfo, '\0', sizeof(BITMAPINFO2));
857 vDIBInfo.cbFix = sizeof(BITMAPINFO2);
858 vDIBInfo.cPlanes = 1;
859 vDIBInfo.cBitCount = 24;
860 vDIBInfo.ulCompression = BCA_UNCOMP;
861 vDIBInfo.usReserved = 0;
862 vDIBInfo.usRecording = BRA_BOTTOMUP;
863 vDIBInfo.usRendering = BRH_NOTHALFTONED;
864 vDIBInfo.ulColorEncoding = BCE_RGB;
865 vDIBInfo.ulIdentifier = 0;
866
867 lpBits = (unsigned char *)malloc(vDIBh.cbImage);
868 if (!lpBits)
fec19ea9 869 {
3437f881
DW
870 wxFAIL_MSG(wxT("could not allocate data for DIB"));
871 free(pData);
872 return wxNullImage;
fec19ea9
VS
873 }
874
3437f881
DW
875 //
876 // Copy data from the device-dependent bitmap to the DIB
877 //
878 hDCMem = ::DevOpenDC( vHabmain
879 ,OD_MEMORY
880 ,"*"
881 ,4
882 ,(PDEVOPENDATA)pszData
883 ,NULLHANDLE
884 );
885 hPSMem = ::GpiCreatePS( vHabmain
886 ,hDCMem
887 ,&vSizlPage
888 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
889 );
890 hBitmap = ::GpiCreateBitmap( hPSMem
891 ,&vDIBh
892 ,0L
893 ,NULL
894 ,NULL
895 );
896 lScans = ::GpiQueryBitmapBits( hPSMem
897 ,0L
898 ,(LONG)nHeight
899 ,(PBYTE)lpBits
900 ,&vDIBInfo
901 );
902
903 //
904 // Copy DIB data into the wxImage object
905 //
906 int i;
907 int j;
908 unsigned char* ptdata = pData;
909 unsigned char* ptbits = lpBits;
910
911 for (i = 0; i < nHeight; i++)
fec19ea9 912 {
3437f881 913 for (j = 0; j < nWidth; j++)
fec19ea9
VS
914 {
915 *(ptdata++) = *(ptbits+2);
916 *(ptdata++) = *(ptbits+1);
917 *(ptdata++) = *(ptbits );
918 ptbits += 3;
919 }
3437f881 920 ptbits += nPadding;
fec19ea9
VS
921 }
922
3437f881
DW
923 //
924 // Similarly, set data according to the possible mask bitmap
925 //
926 if (GetMask() && GetMask()->GetMaskBitmap())
fec19ea9 927 {
3437f881
DW
928 hBitmap = (HBITMAP)GetMask()->GetMaskBitmap();
929
930 //
931 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
932 //
933 HDC hMemDC = ::DevOpenDC( vHabmain
934 ,OD_MEMORY
935 ,"*"
936 ,4
937 ,(PDEVOPENDATA)pszData
938 ,NULLHANDLE
939 );
940 HPS hMemPS = ::GpiCreatePS( vHabmain
941 ,hMemDC
942 ,&vSizlPage
943 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
944 );
945 ::GpiSetColor(hMemPS, OS2RGB(0, 0, 0));
946 ::GpiSetBackColor(hMemPS, OS2RGB(255, 255, 255) );
947 ::GpiQueryBitmapBits( hPSMem
948 ,0L
949 ,(LONG)nHeight
950 ,(PBYTE)lpBits
951 ,&vDIBInfo
952 );
953 ::GpiDestroyPS(hMemPS);
954 ::DevCloseDC(hMemDC);
955
956 //
957 // Background color set to RGB(16,16,16) in consistent with wxGTK
958 //
959 unsigned char ucRed = 16;
960 unsigned char ucGreen = 16;
961 unsigned char ucBlue = 16;
962
963 ptdata = pData;
fec19ea9 964 ptbits = lpBits;
3437f881 965 for (i = 0; i < nHeight; i++)
fec19ea9 966 {
3437f881 967 for (j = 0; j < nWidth; j++)
fec19ea9 968 {
3437f881 969 if (*ptbits != 0)
fec19ea9
VS
970 ptdata += 3;
971 else
972 {
3437f881
DW
973 *(ptdata++) = ucRed;
974 *(ptdata++) = ucGreen;
975 *(ptdata++) = ucBlue;
fec19ea9
VS
976 }
977 ptbits += 3;
978 }
3437f881 979 ptbits += nPadding;
fec19ea9 980 }
3437f881
DW
981 vImage.SetMaskColour( ucRed
982 ,ucGreen
983 ,ucBlue
984 );
985 vImage.SetMask(TRUE);
fec19ea9
VS
986 }
987 else
988 {
3437f881 989 vImage.SetMask(FALSE);
fec19ea9 990 }
fec19ea9 991
3437f881
DW
992 //
993 // Free allocated resources
994 //
995 ::GpiDestroyPS(hPSMem);
996 ::DevCloseDC(hDCMem);
997 free(lpBits);
998 return vImage;
999} // end of wxBitmap::ConvertToImage
fec19ea9 1000
6f38c86f
DW
1001// ----------------------------------------------------------------------------
1002// sub bitmap extraction
1003// ----------------------------------------------------------------------------
1004
1005wxBitmap wxBitmap::GetSubBitmap(
1006 const wxRect& rRect
1007) const
1008{
1009 wxCHECK_MSG( Ok() &&
1010 (rRect.x >= 0) && (rRect.y >= 0) &&
1011 (rRect.x + rRect.width <= GetWidth()) &&
1012 (rRect.y + rRect.height <= GetHeight()),
1013 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
1014
1015 wxBitmap vRet( rRect.width
1016 ,rRect.height
1017 ,GetDepth()
1018 );
1019 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
1020
1021
1022 //
1023 // Copy bitmap data
1024 //
1025 SIZEL vSize = {0, 0};
1026 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1027 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1028 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1029 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1030 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1031 POINTL vPoint[4] = { rRect.x, rRect.y,
1032 rRect.x + rRect.width, rRect.y + rRect.height,
1033 0, 0, GetWidth(), GetHeight()
1034 };
1035
1036 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1037 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1038 ::GpiBitBlt( hPSDst
1039 ,hPSSrc
1040 ,4L
1041 ,vPoint
1042 ,ROP_SRCCOPY
1043 ,BBO_IGNORE
1044 );
1045
1046 //
1047 // Copy mask if there is one
1048 //
1049 if (GetMask())
1050 {
1051 BITMAPINFOHEADER2 vBmih;
1052
1053 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1054 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1055 vBmih.cx = rRect.width;
1056 vBmih.cy = rRect.height;
1057 vBmih.cPlanes = 1;
1058 vBmih.cBitCount = 1;
1059
1060 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
1061 ,&vBmih
1062 ,0L
1063 ,NULL
1064 ,NULL
1065 );
1066
1067 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1068 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1069
1070 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
1071 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
1072 ::GpiBitBlt( hPSDst
1073 ,hPSSrc
1074 ,4L
1075 ,vPoint
1076 ,ROP_SRCCOPY
1077 ,BBO_IGNORE
1078 );
1079
1080 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
1081 vRet.SetMask(pMask);
1082 }
1083
1084 ::GpiSetBitmap(hPSSrc, NULL);
1085 ::GpiSetBitmap(hPSDst, NULL);
1086 ::GpiDestroyPS(hPSSrc);
1087 ::GpiDestroyPS(hPSDst);
1088 ::DevCloseDC(hDCSrc);
1089 ::DevCloseDC(hDCDst);
1090 return vRet;
1091} // end of wxBitmap::GetSubBitmap
0e320a79 1092
3b9e3455
DW
1093// ----------------------------------------------------------------------------
1094// wxBitmap accessors
1095// ----------------------------------------------------------------------------
0e320a79 1096
4f72fe4f
DW
1097void wxBitmap::SetQuality(
1098 int nQ
1099)
0e320a79 1100{
3b9e3455 1101 EnsureHasData();
0e320a79 1102
4f72fe4f 1103 GetBitmapData()->m_nQuality = nQ;
6f38c86f 1104} // end of wxBitmap::SetQuality
0e320a79 1105
3b9e3455 1106#if WXWIN_COMPATIBILITY_2
4f72fe4f
DW
1107void wxBitmap::SetOk(
1108 bool bOk
1109)
0e320a79 1110{
3b9e3455 1111 EnsureHasData();
0e320a79 1112
4f72fe4f 1113 GetBitmapData()->m_bOk = bOk;
6f38c86f 1114} // end of wxBitmap::SetOk
3b9e3455 1115#endif // WXWIN_COMPATIBILITY_2
0e320a79 1116
4f72fe4f
DW
1117void wxBitmap::SetPalette(
1118 const wxPalette& rPalette
1119)
0e320a79 1120{
3b9e3455 1121 EnsureHasData();
0e320a79 1122
4f72fe4f 1123 GetBitmapData()->m_vBitmapPalette = rPalette;
6f38c86f 1124} // end of wxBitmap::SetPalette
0e320a79 1125
4f72fe4f
DW
1126void wxBitmap::SetMask(
1127 wxMask* pMask
1128)
0e320a79 1129{
3b9e3455 1130 EnsureHasData();
0e320a79 1131
4f72fe4f 1132 GetBitmapData()->m_pBitmapMask = pMask;
6f38c86f 1133} // end of wxBitmap::SetMask
0e320a79 1134
4f72fe4f
DW
1135wxBitmap wxBitmap::GetBitmapForDC(
1136 wxDC& rDc
1137) const
d88de032 1138{
3437f881 1139 return(*this);
6f38c86f 1140} // end of wxBitmap::GetBitmapForDC
d88de032 1141
3b9e3455
DW
1142// ----------------------------------------------------------------------------
1143// wxMask
1144// ----------------------------------------------------------------------------
0e320a79
DW
1145
1146wxMask::wxMask()
1147{
4f72fe4f 1148 m_hMaskBitmap = 0;
6f38c86f 1149} // end of wxMask::wxMask
0e320a79
DW
1150
1151// Construct a mask from a bitmap and a colour indicating
1152// the transparent area
4f72fe4f
DW
1153wxMask::wxMask(
1154 const wxBitmap& rBitmap
1155, const wxColour& rColour
1156)
0e320a79 1157{
4f72fe4f
DW
1158 m_hMaskBitmap = 0;
1159 Create( rBitmap
1160 ,rColour
1161 );
6f38c86f 1162} // end of wxMask::wxMask
0e320a79
DW
1163
1164// Construct a mask from a bitmap and a palette index indicating
1165// the transparent area
4f72fe4f
DW
1166wxMask::wxMask(
1167 const wxBitmap& rBitmap
1168, int nPaletteIndex
1169)
0e320a79 1170{
4f72fe4f
DW
1171 m_hMaskBitmap = 0;
1172 Create( rBitmap
1173 ,nPaletteIndex
1174 );
6f38c86f 1175} // end of wxMask::wxMask
0e320a79
DW
1176
1177// Construct a mask from a mono bitmap (copies the bitmap).
4f72fe4f
DW
1178wxMask::wxMask(
1179 const wxBitmap& rBitmap
1180)
0e320a79 1181{
4f72fe4f
DW
1182 m_hMaskBitmap = 0;
1183 Create(rBitmap);
6f38c86f 1184} // end of wxMask::wxMask
0e320a79
DW
1185
1186wxMask::~wxMask()
1187{
4f72fe4f
DW
1188 if (m_hMaskBitmap)
1189 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
6f38c86f 1190} // end of wxMask::~wxMask
0e320a79
DW
1191
1192// Create a mask from a mono bitmap (copies the bitmap).
58b16424
DW
1193bool wxMask::Create(
1194 const wxBitmap& rBitmap
1195)
0e320a79 1196{
6f38c86f 1197 BITMAPINFOHEADER2 vBmih;
58b16424 1198 SIZEL vSize = {0, 0};
6f38c86f
DW
1199 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1200 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1201 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1202 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1203 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1204 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1205 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1206 };
58b16424
DW
1207
1208 if (m_hMaskBitmap)
3b9e3455 1209 {
58b16424
DW
1210 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1211 m_hMaskBitmap = 0;
3b9e3455 1212 }
58b16424 1213 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
3b9e3455 1214 {
58b16424 1215 return(FALSE);
3b9e3455 1216 }
6f38c86f
DW
1217
1218 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1219 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1220 vBmih.cx = rBitmap.GetWidth();
1221 vBmih.cy = rBitmap.GetHeight();
1222 vBmih.cPlanes = 1;
1223 vBmih.cBitCount = 1;
1224
1225 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1226 ,&vBmih
1227 ,0L
1228 ,NULL
1229 ,NULL
1230 );
1231
1232 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1233 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1234 ::GpiBitBlt( hPSDst
1235 ,hPSSrc
1236 ,4L
1237 ,vPoint
1238 ,ROP_SRCCOPY
1239 ,BBO_IGNORE
1240 );
1241
1242 ::GpiDestroyPS(hPSSrc);
1243 ::GpiDestroyPS(hPSDst);
1244 ::DevCloseDC(hDCSrc);
1245 ::DevCloseDC(hDCDst);
58b16424 1246 return(TRUE);
6f38c86f 1247} // end of wxMask::Create
0e320a79
DW
1248
1249// Create a mask from a bitmap and a palette index indicating
1250// the transparent area
58b16424
DW
1251bool wxMask::Create(
1252 const wxBitmap& rBitmap
1253, int nPaletteIndex
1254)
0e320a79 1255{
58b16424 1256 if (m_hMaskBitmap)
3b9e3455 1257 {
58b16424
DW
1258 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1259 m_hMaskBitmap = 0;
3b9e3455 1260 }
58b16424 1261 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
3b9e3455 1262 {
43543d98
DW
1263 unsigned char cRed;
1264 unsigned char cGreen;
1265 unsigned char cBlue;
1266
58b16424 1267 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
43543d98
DW
1268 ,&cRed
1269 ,&cGreen
1270 ,&cBlue
58b16424 1271 ))
3b9e3455 1272 {
43543d98
DW
1273 wxColour vTransparentColour( cRed
1274 ,cGreen
1275 ,cBlue
58b16424
DW
1276 );
1277
1278 return (Create( rBitmap
1279 ,vTransparentColour
1280 ));
3b9e3455
DW
1281 }
1282 }
58b16424 1283 return(FALSE);
6f38c86f 1284} // end of wxMask::Create
0e320a79
DW
1285
1286// Create a mask from a bitmap and a colour indicating
1287// the transparent area
58b16424
DW
1288bool wxMask::Create(
1289 const wxBitmap& rBitmap
1290, const wxColour& rColour
1291)
0e320a79 1292{
6f38c86f
DW
1293 bool bOk = TRUE;
1294 COLORREF vMaskColour = OS2RGB( rColour.Red()
1295 ,rColour.Green()
1296 ,rColour.Blue()
1297 );
1298 BITMAPINFOHEADER2 vBmih;
58b16424 1299 SIZEL vSize = {0, 0};
6f38c86f
DW
1300 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1301 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1302 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1303 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1304 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1305 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1306 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1307 };
58b16424
DW
1308
1309 if (m_hMaskBitmap)
3b9e3455 1310 {
58b16424
DW
1311 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1312 m_hMaskBitmap = 0;
3b9e3455 1313 }
58b16424 1314 if (!rBitmap.Ok())
3b9e3455 1315 {
58b16424 1316 return(FALSE);
3b9e3455
DW
1317 }
1318
6f38c86f
DW
1319 //
1320 // Scan the bitmap for the transparent colour and set
3b9e3455
DW
1321 // the corresponding pixels in the mask to BLACK and
1322 // the rest to WHITE
6f38c86f
DW
1323 //
1324
1325 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1326 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1327 vBmih.cx = rBitmap.GetWidth();
1328 vBmih.cy = rBitmap.GetHeight();
1329 vBmih.cPlanes = 1;
1330 vBmih.cBitCount = 1;
1331
1332 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1333 ,&vBmih
1334 ,0L
1335 ,NULL
1336 ,NULL
1337 );
1338
1339 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1340 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1341
1342 //
1343 // This is not very efficient, but I can't think
3b9e3455 1344 // of a better way of doing it
6f38c86f 1345 //
58b16424 1346 for (int w = 0; w < rBitmap.GetWidth(); w++)
3b9e3455 1347 {
58b16424 1348 for (int h = 0; h < rBitmap.GetHeight(); h++)
3b9e3455 1349 {
6f38c86f
DW
1350 POINTL vPt = {w, h};
1351 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1352 if (vCol == (COLORREF)CLR_NOINDEX)
1353 {
1354 //
1355 // Doesn't make sense to continue
1356 //
1357 bOk = FALSE;
1358 break;
1359 }
58b16424 1360
6f38c86f 1361 if (vCol == vMaskColour)
3b9e3455 1362 {
6f38c86f
DW
1363 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1364 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1365 }
1366 else
1367 {
6f38c86f
DW
1368 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1369 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1370 }
1371 }
1372 }
6f38c86f
DW
1373 ::GpiSetBitmap(hPSSrc, NULL);
1374 ::GpiSetBitmap(hPSDst, NULL);
1375 ::GpiDestroyPS(hPSSrc);
1376 ::GpiDestroyPS(hPSDst);
1377 ::DevCloseDC(hDCSrc);
1378 ::DevCloseDC(hDCDst);
58b16424 1379 return(TRUE);
6f38c86f 1380} // end of wxMask::Create
0e320a79 1381
3b9e3455
DW
1382// ----------------------------------------------------------------------------
1383// wxBitmapHandler
1384// ----------------------------------------------------------------------------
0e320a79 1385
58b16424
DW
1386bool wxBitmapHandler::Create(
1387 wxGDIImage* pImage
1388, void* pData
1389, long lFlags
1390, int nWidth
1391, int nHeight
1392, int nDepth
1393)
3b9e3455 1394{
58b16424
DW
1395 wxBitmap* pBitmap = wxDynamicCast( pImage
1396 ,wxBitmap
1397 );
3b9e3455 1398
58b16424
DW
1399 return(pBitmap ? Create( pBitmap
1400 ,pData
1401 ,nWidth
1402 ,nHeight
1403 ,nDepth
1404 ) : FALSE);
3b9e3455
DW
1405}
1406
58b16424
DW
1407bool wxBitmapHandler::Load(
1408 wxGDIImage* pImage
1409, const wxString& rName
8ea3f821 1410, HPS hPs
58b16424
DW
1411, long lFlags
1412, int nWidth
1413, int nHeight
1414)
3b9e3455 1415{
43543d98
DW
1416 wxBitmap* pBitmap = wxDynamicCast( pImage
1417 ,wxBitmap
1418 );
3b9e3455 1419
58b16424
DW
1420 return(pBitmap ? LoadFile( pBitmap
1421 ,rName
8ea3f821 1422 ,hPs
58b16424
DW
1423 ,lFlags
1424 ,nWidth
1425 ,nHeight
1426 ) : FALSE);
3b9e3455
DW
1427}
1428
58b16424
DW
1429bool wxBitmapHandler::Save(
1430 wxGDIImage* pImage
1431, const wxString& rName
1432, int lType
1433)
0e320a79 1434{
58b16424
DW
1435 wxBitmap* pBitmap = wxDynamicCast( pImage
1436 ,wxBitmap
1437 );
0e320a79 1438
58b16424
DW
1439 return(pBitmap ? SaveFile( pBitmap
1440 ,rName
1441 ,lType
1442 ) : FALSE);
0e320a79
DW
1443}
1444
58b16424
DW
1445bool wxBitmapHandler::Create(
1446 wxBitmap* WXUNUSED(pBitmap)
1447, void* WXUNUSED(pData)
1448, long WXUNUSED(lType)
1449, int WXUNUSED(nWidth)
1450, int WXUNUSED(nHeight)
1451, int WXUNUSED(nDepth)
1452)
0e320a79 1453{
58b16424 1454 return(FALSE);
0e320a79
DW
1455}
1456
58b16424
DW
1457bool wxBitmapHandler::LoadFile(
1458 wxBitmap* WXUNUSED(pBitmap)
1459, const wxString& WXUNUSED(rName)
8ea3f821 1460, HPS WXUNUSED(hPs)
58b16424
DW
1461, long WXUNUSED(lType)
1462, int WXUNUSED(nDesiredWidth)
1463, int WXUNUSED(nDesiredHeight)
1464)
0e320a79 1465{
43543d98 1466 return(FALSE);
0e320a79
DW
1467}
1468
58b16424
DW
1469bool wxBitmapHandler::SaveFile(
1470 wxBitmap* WXUNUSED(pBitmap)
1471, const wxString& WXUNUSED(rName)
1472, int WXUNUSED(nType)
1473, const wxPalette* WXUNUSED(pPalette)
1474)
0e320a79 1475{
58b16424 1476 return(FALSE);
0e320a79 1477}
ce44c50e 1478
020a1653
DW
1479// ----------------------------------------------------------------------------
1480// Utility functions
1481// ----------------------------------------------------------------------------
1482HBITMAP wxInvertMask(
1483 HBITMAP hBmpMask
1484, int nWidth
1485, int nHeight
1486)
1487{
1488 HBITMAP hBmpInvMask = 0;
1489
1490 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1491
1492 //
1493 // Get width/height from the bitmap if not given
1494 //
1495 if (!nWidth || !nHeight)
1496 {
1497 BITMAPINFOHEADER2 vBmhdr;
1498
1499 ::GpiQueryBitmapInfoHeader( hBmpMask
1500 ,&vBmhdr
1501 );
1502 nWidth = (int)vBmhdr.cx;
e464c180 1503 nHeight = (int)vBmhdr.cy;
020a1653
DW
1504 }
1505
1506 BITMAPINFOHEADER2 vBmih;
1507 SIZEL vSize = {0, 0};
1508 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
e464c180
DW
1509 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1510 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1511 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1512 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1513 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1514 0, 0, nWidth, nHeight
020a1653
DW
1515 };
1516
e464c180 1517 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
020a1653 1518 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
e464c180
DW
1519 vBmih.cx = nWidth;
1520 vBmih.cy = nHeight;
020a1653
DW
1521 vBmih.cPlanes = 1;
1522 vBmih.cBitCount = 1;
1523
1524 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1525 ,&vBmih
1526 ,0L
1527 ,NULL
1528 ,NULL
1529 );
1530
1531 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1532 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1533
1534 ::GpiBitBlt( hPSDst
1535 ,hPSSrc
1536 ,4L
e464c180 1537 ,vPoint
8e8d8eef 1538 ,ROP_SRCINVERT
020a1653
DW
1539 ,BBO_IGNORE
1540 );
1541
1542 ::GpiDestroyPS(hPSSrc);
1543 ::GpiDestroyPS(hPSDst);
1544 ::DevCloseDC(hDCSrc);
e464c180 1545 ::DevCloseDC(hDCDst);
020a1653
DW
1546
1547 return hBmpInvMask;
1548} // end of WxWinGdi_InvertMask
3437f881 1549