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