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