]> git.saurik.com Git - wxWidgets.git/blame - src/os2/bitmap.cpp
don't try to remove -g flag from CFLAGS, it is not necessary and doesn't work correct...
[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 518 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
a086de98 519 m_refData = new wxBitmapRefData();
3437f881
DW
520
521 int nSizeLimit = 1024 * 768 * 3;
a086de98
DW
522 int nWidth = rImage.GetWidth();
523 int nBmpHeight = rImage.GetHeight();
3437f881
DW
524 int nBytePerLine = nWidth * 3;
525 int nSizeDWORD = sizeof(DWORD);
526 int nLineBoundary = nBytePerLine % nSizeDWORD;
527 int nPadding = 0;
528
529 if (nLineBoundary > 0)
fec19ea9 530 {
3437f881
DW
531 nPadding = nSizeDWORD - nLineBoundary;
532 nBytePerLine += nPadding;
fec19ea9 533 }
3437f881
DW
534
535 //
536 // Calc the number of DIBs and heights of DIBs
537 //
538 int nNumDIB = 1;
539 int nHRemain = 0;
540 int nHeight = nSizeLimit / nBytePerLine;
541
542 if (nHeight >= nBmpHeight)
543 nHeight = nBmpHeight;
fec19ea9
VS
544 else
545 {
3437f881
DW
546 nNumDIB = nBmpHeight / nHeight;
547 nHRemain = nBmpHeight % nHeight;
548 if (nHRemain > 0)
549 nNumDIB++;
fec19ea9
VS
550 }
551
3437f881
DW
552 //
553 // Set bitmap parameters
554 //
555 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
556 SetWidth(nWidth);
557 SetHeight(nBmpHeight);
558 if (nDepth == -1)
559 nDepth = wxDisplayDepth();
560 SetDepth(nDepth);
561
562#if wxUSE_PALETTE
563 //
564 // Copy the palette from the source image
565 //
566 SetPalette(rImage.GetPalette());
567#endif // wxUSE_PALETTE
568
569 //
570 // Create a DIB header
571 //
572 BITMAPINFOHEADER2 vHeader;
573
574 //
fec19ea9 575 // Fill in the DIB header
3437f881
DW
576 //
577 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
578 vHeader.cbFix = sizeof(vHeader);
579 vHeader.cx = (USHORT)nWidth;
580 vHeader.cy = (USHORT)nHeight;
581 vHeader.cPlanes = 1L;
582 vHeader.cBitCount = 24;
583 vHeader.ulCompression = BCA_UNCOMP;
584 vHeader.cbImage = nBytePerLine * nHeight;
585 vHeader.cclrUsed = 0;
586
587 //
fec19ea9 588 // These seem not really needed for our purpose here.
3437f881
DW
589 //
590 vHeader.cxResolution = 0;
591 vHeader.cyResolution = 0;
592 vHeader.cclrImportant = 0;
593 vHeader.usUnits = BRU_METRIC;
594 vHeader.usReserved = 0;
595 vHeader.cSize1 = 0;
596 vHeader.cSize2 = 0;
597 vHeader.usRecording = BRA_BOTTOMUP;
598 vHeader.usRendering = BRH_NOTHALFTONED;
599 vHeader.ulColorEncoding = BCE_RGB;
600 vHeader.ulIdentifier = 0;
601
602 //
603 // Memory for DIB data
604 //
605 unsigned char* pucBits;
606
607 pucBits = (unsigned char *)malloc(vHeader.cbImage);
608 if(!pucBits)
609 {
610 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
611 return FALSE;
612 }
613
614 //
615 // Create and set the device-dependent bitmap
616 //
617 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
618 SIZEL vSize = {0, 0};
619 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
620 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
621 HBITMAP hBmp;
622 HBITMAP hBmpOld;
623
624 hBmp = ::GpiCreateBitmap( hPS
625 ,&vHeader
626 ,0L
627 ,NULL
628 ,NULL
629 );
630 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
631#if wxUSE_PALETTE
632 HPAL hOldPalette = NULLHANDLE;
633 if (rImage.GetPalette().Ok())
fec19ea9 634 {
3437f881 635 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
fec19ea9 636 }
3437f881 637#endif // wxUSE_PALETTE
fec19ea9 638
3437f881
DW
639 //
640 // Copy image data into DIB data and then into DDB (in a loop)
641 //
642 unsigned char* pData = rImage.GetData();
643 int i;
644 int j;
645 int n;
646 int nOrigin = 0;
647 unsigned char* ptdata = pData;
648 unsigned char* ptbits;
649
650 for (n = 0; n < nNumDIB; n++)
fec19ea9 651 {
3437f881 652 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
fec19ea9 653 {
3437f881
DW
654 //
655 // Redefine height and size of the (possibly) last smaller DIB
fec19ea9 656 // memory is not reallocated
3437f881
DW
657 //
658 nHeight = nHRemain;
659 vHeader.cy = (DWORD)(nHeight);
660 vHeader.cbImage = nBytePerLine * nHeight;
fec19ea9 661 }
3437f881
DW
662 ptbits = pucBits;
663 for (j = 0; j < nHeight; j++)
fec19ea9 664 {
3437f881 665 for (i = 0; i < nWidth; i++)
fec19ea9 666 {
3437f881
DW
667 *(ptbits++) = *(ptdata + 2);
668 *(ptbits++) = *(ptdata + 1);
669 *(ptbits++) = *(ptdata);
fec19ea9
VS
670 ptdata += 3;
671 }
3437f881
DW
672 for (i = 0; i < nPadding; i++)
673 *(ptbits++) = 0;
fec19ea9 674 }
3437f881
DW
675
676 //
677 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
678 //
679 POINTL vPoint[4] = { 0, nOrigin,
680 nWidth, nHeight,
681 0, 0, nWidth, nHeight
682 };
683
684 ::GpiBitBlt( hPS
685 ,hPS
686 ,4
687 ,vPoint
688 ,ROP_SRCCOPY
689 ,BBO_IGNORE
690 );
691 nOrigin += nHeight;
fec19ea9 692 }
3437f881
DW
693 SetHBITMAP((WXHBITMAP)hBmp);
694#if wxUSE_PALETTE
695 if (hOldPalette)
696 ::GpiSelectPalette(hPS, hOldPalette);
697#endif // wxUSE_PALETTE
fec19ea9 698
3437f881
DW
699 //
700 // Similarly, created an mono-bitmap for the possible mask
701 //
702 if (rImage.HasMask())
fec19ea9 703 {
3437f881
DW
704 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
705 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
706 vHeader.cx = nWidth;
707 vHeader.cy = nHeight;
708 vHeader.cPlanes = 1;
709 vHeader.cBitCount = 1;
710 hBmp = ::GpiCreateBitmap( hPS
711 ,&vHeader
712 ,0L
713 ,NULL
714 ,NULL
715 );
716 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
717 if (nNumDIB == 1)
718 nHeight = nBmpHeight;
719 else
720 nHeight = nSizeLimit / nBytePerLine;
721 vHeader.cy = (DWORD)(nHeight);
722 vHeader.cbImage = nBytePerLine * nHeight;
723 nOrigin = 0;
724
725 unsigned char cRed = rImage.GetMaskRed();
726 unsigned char cGreen = rImage.GetMaskGreen();
727 unsigned char cBlue = rImage.GetMaskBlue();
728 unsigned char cZero = 0;
729 unsigned char cOne = 255;
730
731 ptdata = pData;
732 for (n = 0; n < nNumDIB; n++)
fec19ea9 733 {
3437f881 734 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
fec19ea9 735 {
3437f881
DW
736 //
737 // Redefine height and size of the (possibly) last smaller DIB
fec19ea9 738 // memory is not reallocated
3437f881
DW
739 //
740 nHeight = nHRemain;
741 vHeader.cy = (DWORD)(nHeight);
742 vHeader.cbImage = nBytePerLine * nHeight;
fec19ea9 743 }
3437f881
DW
744 ptbits = pucBits;
745 for (int j = 0; j < nHeight; j++)
fec19ea9 746 {
3437f881 747 for (i = 0; i < nWidth; i++)
fec19ea9 748 {
3437f881 749 if ((*(ptdata++) != cRed) || (*(ptdata++) != cGreen) || (*(ptdata++) != cBlue))
fec19ea9 750 {
3437f881
DW
751 *(ptbits++) = cOne;
752 *(ptbits++) = cOne;
753 *(ptbits++) = cOne;
fec19ea9
VS
754 }
755 else
756 {
3437f881
DW
757 *(ptbits++) = cZero;
758 *(ptbits++) = cZero;
759 *(ptbits++) = cZero;
fec19ea9
VS
760 }
761 }
3437f881
DW
762 for (i = 0; i < nPadding; i++)
763 *(ptbits++) = cZero;
fec19ea9 764 }
3437f881
DW
765 POINTL vPoint[4] = { 0, nOrigin,
766 nWidth, nHeight,
767 0, 0, nWidth, nHeight
768 };
769
770 ::GpiBitBlt( hPS
771 ,hPS
772 ,4
773 ,vPoint
774 ,ROP_SRCCOPY
775 ,BBO_IGNORE
776 );
777 nOrigin += nHeight;
fec19ea9 778 }
fec19ea9 779
3437f881
DW
780 //
781 // Create a wxMask object
782 //
783 wxMask* pMask = new wxMask();
fec19ea9 784
3437f881
DW
785 pMask->SetMaskBitmap((WXHBITMAP)hBmp);
786 SetMask(pMask);
787 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
788 }
fec19ea9 789
3437f881
DW
790 //
791 // Free allocated resources
792 //
793 ::GpiSetBitmap(hPS, NULLHANDLE);
794 ::GpiDestroyPS(hPS);
795 ::DevCloseDC(hDC);
796 free(pucBits);
fec19ea9 797 return TRUE;
3437f881 798} // end of wxBitmap::CreateFromImage
fec19ea9
VS
799
800wxImage wxBitmap::ConvertToImage() const
801{
3437f881 802 wxImage vImage;
1c344e89 803
fec19ea9
VS
804 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
805
3437f881
DW
806 //
807 // Create an wxImage object
808 //
809 int nWidth = GetWidth();
810 int nHeight = GetHeight();
811 int nDevWidth;
812 int nDevHeight;
813 int nBytePerLine = nWidth * 3;
814 int nSizeDWORD = sizeof(DWORD);
815 int nLineBoundary = nBytePerLine % nSizeDWORD;
816 int nPadding = 0;
817 unsigned char* pData;
818 unsigned char* lpBits;
819 long lScans;
820 BITMAPINFOHEADER2 vDIBh;
821 BITMAPINFO2 vDIBInfo;
822 HDC hDCMem;
823 PSZ pszData[4] = { "Display", NULL, NULL, NULL };
824 HPS hPSMem;
825 HPS hPS;
826 SIZEL vSizlPage = {0,0};
827 HBITMAP hBitmap;
828
829 vImage.Create( nWidth
830 ,nHeight
831 );
832 pData = vImage.GetData();
833 if(!pData)
fec19ea9
VS
834 {
835 wxFAIL_MSG( wxT("could not allocate data for image") );
836 return wxNullImage;
837 }
3437f881 838 if(nLineBoundary > 0)
fec19ea9 839 {
3437f881
DW
840 nPadding = nSizeDWORD - nLineBoundary;
841 nBytePerLine += nPadding;
fec19ea9 842 }
3437f881
DW
843 wxDisplaySize( &nDevWidth
844 ,&nDevHeight
845 );
846 //
847 // Create and fill a DIB header
848 //
849 memset(&vDIBh, '\0', sizeof(BITMAPINFOHEADER2));
850 vDIBh.cbFix = sizeof(BITMAPINFOHEADER2);
851 vDIBh.cx = nWidth;
852 vDIBh.cy = nHeight;
853 vDIBh.cPlanes = 1;
854 vDIBh.cbImage = nBytePerLine * nHeight;
855 vDIBh.cBitCount = 24;
856
857 memset(&vDIBInfo, '\0', sizeof(BITMAPINFO2));
858 vDIBInfo.cbFix = sizeof(BITMAPINFO2);
859 vDIBInfo.cPlanes = 1;
860 vDIBInfo.cBitCount = 24;
861 vDIBInfo.ulCompression = BCA_UNCOMP;
862 vDIBInfo.usReserved = 0;
863 vDIBInfo.usRecording = BRA_BOTTOMUP;
864 vDIBInfo.usRendering = BRH_NOTHALFTONED;
865 vDIBInfo.ulColorEncoding = BCE_RGB;
866 vDIBInfo.ulIdentifier = 0;
867
868 lpBits = (unsigned char *)malloc(vDIBh.cbImage);
869 if (!lpBits)
fec19ea9 870 {
3437f881
DW
871 wxFAIL_MSG(wxT("could not allocate data for DIB"));
872 free(pData);
873 return wxNullImage;
fec19ea9
VS
874 }
875
3437f881
DW
876 //
877 // Copy data from the device-dependent bitmap to the DIB
878 //
879 hDCMem = ::DevOpenDC( vHabmain
880 ,OD_MEMORY
881 ,"*"
882 ,4
883 ,(PDEVOPENDATA)pszData
884 ,NULLHANDLE
885 );
886 hPSMem = ::GpiCreatePS( vHabmain
887 ,hDCMem
888 ,&vSizlPage
889 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
890 );
891 hBitmap = ::GpiCreateBitmap( hPSMem
892 ,&vDIBh
893 ,0L
894 ,NULL
895 ,NULL
896 );
897 lScans = ::GpiQueryBitmapBits( hPSMem
898 ,0L
899 ,(LONG)nHeight
900 ,(PBYTE)lpBits
901 ,&vDIBInfo
902 );
903
904 //
905 // Copy DIB data into the wxImage object
906 //
907 int i;
908 int j;
909 unsigned char* ptdata = pData;
910 unsigned char* ptbits = lpBits;
911
912 for (i = 0; i < nHeight; i++)
fec19ea9 913 {
3437f881 914 for (j = 0; j < nWidth; j++)
fec19ea9
VS
915 {
916 *(ptdata++) = *(ptbits+2);
917 *(ptdata++) = *(ptbits+1);
918 *(ptdata++) = *(ptbits );
919 ptbits += 3;
920 }
3437f881 921 ptbits += nPadding;
fec19ea9
VS
922 }
923
3437f881
DW
924 //
925 // Similarly, set data according to the possible mask bitmap
926 //
927 if (GetMask() && GetMask()->GetMaskBitmap())
fec19ea9 928 {
3437f881
DW
929 hBitmap = (HBITMAP)GetMask()->GetMaskBitmap();
930
931 //
932 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
933 //
934 HDC hMemDC = ::DevOpenDC( vHabmain
935 ,OD_MEMORY
936 ,"*"
937 ,4
938 ,(PDEVOPENDATA)pszData
939 ,NULLHANDLE
940 );
941 HPS hMemPS = ::GpiCreatePS( vHabmain
942 ,hMemDC
943 ,&vSizlPage
944 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
945 );
946 ::GpiSetColor(hMemPS, OS2RGB(0, 0, 0));
947 ::GpiSetBackColor(hMemPS, OS2RGB(255, 255, 255) );
948 ::GpiQueryBitmapBits( hPSMem
949 ,0L
950 ,(LONG)nHeight
951 ,(PBYTE)lpBits
952 ,&vDIBInfo
953 );
954 ::GpiDestroyPS(hMemPS);
955 ::DevCloseDC(hMemDC);
956
957 //
958 // Background color set to RGB(16,16,16) in consistent with wxGTK
959 //
960 unsigned char ucRed = 16;
961 unsigned char ucGreen = 16;
962 unsigned char ucBlue = 16;
963
964 ptdata = pData;
fec19ea9 965 ptbits = lpBits;
3437f881 966 for (i = 0; i < nHeight; i++)
fec19ea9 967 {
3437f881 968 for (j = 0; j < nWidth; j++)
fec19ea9 969 {
3437f881 970 if (*ptbits != 0)
fec19ea9
VS
971 ptdata += 3;
972 else
973 {
3437f881
DW
974 *(ptdata++) = ucRed;
975 *(ptdata++) = ucGreen;
976 *(ptdata++) = ucBlue;
fec19ea9
VS
977 }
978 ptbits += 3;
979 }
3437f881 980 ptbits += nPadding;
fec19ea9 981 }
3437f881
DW
982 vImage.SetMaskColour( ucRed
983 ,ucGreen
984 ,ucBlue
985 );
986 vImage.SetMask(TRUE);
fec19ea9
VS
987 }
988 else
989 {
3437f881 990 vImage.SetMask(FALSE);
fec19ea9 991 }
fec19ea9 992
3437f881
DW
993 //
994 // Free allocated resources
995 //
996 ::GpiDestroyPS(hPSMem);
997 ::DevCloseDC(hDCMem);
998 free(lpBits);
999 return vImage;
1000} // end of wxBitmap::ConvertToImage
fec19ea9 1001
6f38c86f
DW
1002// ----------------------------------------------------------------------------
1003// sub bitmap extraction
1004// ----------------------------------------------------------------------------
1005
1006wxBitmap wxBitmap::GetSubBitmap(
1007 const wxRect& rRect
1008) const
1009{
1010 wxCHECK_MSG( Ok() &&
1011 (rRect.x >= 0) && (rRect.y >= 0) &&
1012 (rRect.x + rRect.width <= GetWidth()) &&
1013 (rRect.y + rRect.height <= GetHeight()),
1014 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
1015
1016 wxBitmap vRet( rRect.width
1017 ,rRect.height
1018 ,GetDepth()
1019 );
1020 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
1021
1022
1023 //
1024 // Copy bitmap data
1025 //
1026 SIZEL vSize = {0, 0};
1027 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1028 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1029 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1030 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1031 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1032 POINTL vPoint[4] = { rRect.x, rRect.y,
1033 rRect.x + rRect.width, rRect.y + rRect.height,
1034 0, 0, GetWidth(), GetHeight()
1035 };
1036
1037 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1038 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1039 ::GpiBitBlt( hPSDst
1040 ,hPSSrc
1041 ,4L
1042 ,vPoint
1043 ,ROP_SRCCOPY
1044 ,BBO_IGNORE
1045 );
1046
1047 //
1048 // Copy mask if there is one
1049 //
1050 if (GetMask())
1051 {
1052 BITMAPINFOHEADER2 vBmih;
1053
1054 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1055 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1056 vBmih.cx = rRect.width;
1057 vBmih.cy = rRect.height;
1058 vBmih.cPlanes = 1;
1059 vBmih.cBitCount = 1;
1060
1061 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
1062 ,&vBmih
1063 ,0L
1064 ,NULL
1065 ,NULL
1066 );
1067
1068 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1069 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1070
1071 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
1072 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
1073 ::GpiBitBlt( hPSDst
1074 ,hPSSrc
1075 ,4L
1076 ,vPoint
1077 ,ROP_SRCCOPY
1078 ,BBO_IGNORE
1079 );
1080
1081 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
1082 vRet.SetMask(pMask);
1083 }
1084
1085 ::GpiSetBitmap(hPSSrc, NULL);
1086 ::GpiSetBitmap(hPSDst, NULL);
1087 ::GpiDestroyPS(hPSSrc);
1088 ::GpiDestroyPS(hPSDst);
1089 ::DevCloseDC(hDCSrc);
1090 ::DevCloseDC(hDCDst);
1091 return vRet;
1092} // end of wxBitmap::GetSubBitmap
0e320a79 1093
3b9e3455
DW
1094// ----------------------------------------------------------------------------
1095// wxBitmap accessors
1096// ----------------------------------------------------------------------------
0e320a79 1097
4f72fe4f
DW
1098void wxBitmap::SetQuality(
1099 int nQ
1100)
0e320a79 1101{
3b9e3455 1102 EnsureHasData();
0e320a79 1103
4f72fe4f 1104 GetBitmapData()->m_nQuality = nQ;
6f38c86f 1105} // end of wxBitmap::SetQuality
0e320a79 1106
3b9e3455 1107#if WXWIN_COMPATIBILITY_2
4f72fe4f
DW
1108void wxBitmap::SetOk(
1109 bool bOk
1110)
0e320a79 1111{
3b9e3455 1112 EnsureHasData();
0e320a79 1113
4f72fe4f 1114 GetBitmapData()->m_bOk = bOk;
6f38c86f 1115} // end of wxBitmap::SetOk
3b9e3455 1116#endif // WXWIN_COMPATIBILITY_2
0e320a79 1117
4f72fe4f
DW
1118void wxBitmap::SetPalette(
1119 const wxPalette& rPalette
1120)
0e320a79 1121{
3b9e3455 1122 EnsureHasData();
0e320a79 1123
4f72fe4f 1124 GetBitmapData()->m_vBitmapPalette = rPalette;
6f38c86f 1125} // end of wxBitmap::SetPalette
0e320a79 1126
4f72fe4f
DW
1127void wxBitmap::SetMask(
1128 wxMask* pMask
1129)
0e320a79 1130{
3b9e3455 1131 EnsureHasData();
0e320a79 1132
4f72fe4f 1133 GetBitmapData()->m_pBitmapMask = pMask;
6f38c86f 1134} // end of wxBitmap::SetMask
0e320a79 1135
4f72fe4f
DW
1136wxBitmap wxBitmap::GetBitmapForDC(
1137 wxDC& rDc
1138) const
d88de032 1139{
3437f881 1140 return(*this);
6f38c86f 1141} // end of wxBitmap::GetBitmapForDC
d88de032 1142
3b9e3455
DW
1143// ----------------------------------------------------------------------------
1144// wxMask
1145// ----------------------------------------------------------------------------
0e320a79
DW
1146
1147wxMask::wxMask()
1148{
4f72fe4f 1149 m_hMaskBitmap = 0;
6f38c86f 1150} // end of wxMask::wxMask
0e320a79
DW
1151
1152// Construct a mask from a bitmap and a colour indicating
1153// the transparent area
4f72fe4f
DW
1154wxMask::wxMask(
1155 const wxBitmap& rBitmap
1156, const wxColour& rColour
1157)
0e320a79 1158{
4f72fe4f
DW
1159 m_hMaskBitmap = 0;
1160 Create( rBitmap
1161 ,rColour
1162 );
6f38c86f 1163} // end of wxMask::wxMask
0e320a79
DW
1164
1165// Construct a mask from a bitmap and a palette index indicating
1166// the transparent area
4f72fe4f
DW
1167wxMask::wxMask(
1168 const wxBitmap& rBitmap
1169, int nPaletteIndex
1170)
0e320a79 1171{
4f72fe4f
DW
1172 m_hMaskBitmap = 0;
1173 Create( rBitmap
1174 ,nPaletteIndex
1175 );
6f38c86f 1176} // end of wxMask::wxMask
0e320a79
DW
1177
1178// Construct a mask from a mono bitmap (copies the bitmap).
4f72fe4f
DW
1179wxMask::wxMask(
1180 const wxBitmap& rBitmap
1181)
0e320a79 1182{
4f72fe4f
DW
1183 m_hMaskBitmap = 0;
1184 Create(rBitmap);
6f38c86f 1185} // end of wxMask::wxMask
0e320a79
DW
1186
1187wxMask::~wxMask()
1188{
4f72fe4f
DW
1189 if (m_hMaskBitmap)
1190 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
6f38c86f 1191} // end of wxMask::~wxMask
0e320a79
DW
1192
1193// Create a mask from a mono bitmap (copies the bitmap).
58b16424
DW
1194bool wxMask::Create(
1195 const wxBitmap& rBitmap
1196)
0e320a79 1197{
6f38c86f 1198 BITMAPINFOHEADER2 vBmih;
58b16424 1199 SIZEL vSize = {0, 0};
6f38c86f
DW
1200 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1201 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1202 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1203 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1204 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1205 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1206 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1207 };
58b16424
DW
1208
1209 if (m_hMaskBitmap)
3b9e3455 1210 {
58b16424
DW
1211 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1212 m_hMaskBitmap = 0;
3b9e3455 1213 }
58b16424 1214 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
3b9e3455 1215 {
58b16424 1216 return(FALSE);
3b9e3455 1217 }
6f38c86f
DW
1218
1219 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1220 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1221 vBmih.cx = rBitmap.GetWidth();
1222 vBmih.cy = rBitmap.GetHeight();
1223 vBmih.cPlanes = 1;
1224 vBmih.cBitCount = 1;
1225
1226 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1227 ,&vBmih
1228 ,0L
1229 ,NULL
1230 ,NULL
1231 );
1232
1233 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1234 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1235 ::GpiBitBlt( hPSDst
1236 ,hPSSrc
1237 ,4L
1238 ,vPoint
1239 ,ROP_SRCCOPY
1240 ,BBO_IGNORE
1241 );
1242
1243 ::GpiDestroyPS(hPSSrc);
1244 ::GpiDestroyPS(hPSDst);
1245 ::DevCloseDC(hDCSrc);
1246 ::DevCloseDC(hDCDst);
58b16424 1247 return(TRUE);
6f38c86f 1248} // end of wxMask::Create
0e320a79
DW
1249
1250// Create a mask from a bitmap and a palette index indicating
1251// the transparent area
58b16424
DW
1252bool wxMask::Create(
1253 const wxBitmap& rBitmap
1254, int nPaletteIndex
1255)
0e320a79 1256{
58b16424 1257 if (m_hMaskBitmap)
3b9e3455 1258 {
58b16424
DW
1259 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1260 m_hMaskBitmap = 0;
3b9e3455 1261 }
58b16424 1262 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
3b9e3455 1263 {
43543d98
DW
1264 unsigned char cRed;
1265 unsigned char cGreen;
1266 unsigned char cBlue;
1267
58b16424 1268 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
43543d98
DW
1269 ,&cRed
1270 ,&cGreen
1271 ,&cBlue
58b16424 1272 ))
3b9e3455 1273 {
43543d98
DW
1274 wxColour vTransparentColour( cRed
1275 ,cGreen
1276 ,cBlue
58b16424
DW
1277 );
1278
1279 return (Create( rBitmap
1280 ,vTransparentColour
1281 ));
3b9e3455
DW
1282 }
1283 }
58b16424 1284 return(FALSE);
6f38c86f 1285} // end of wxMask::Create
0e320a79
DW
1286
1287// Create a mask from a bitmap and a colour indicating
1288// the transparent area
58b16424
DW
1289bool wxMask::Create(
1290 const wxBitmap& rBitmap
1291, const wxColour& rColour
1292)
0e320a79 1293{
6f38c86f
DW
1294 bool bOk = TRUE;
1295 COLORREF vMaskColour = OS2RGB( rColour.Red()
1296 ,rColour.Green()
1297 ,rColour.Blue()
1298 );
1299 BITMAPINFOHEADER2 vBmih;
58b16424 1300 SIZEL vSize = {0, 0};
6f38c86f
DW
1301 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1302 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1303 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1304 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1305 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1306 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1307 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1308 };
58b16424
DW
1309
1310 if (m_hMaskBitmap)
3b9e3455 1311 {
58b16424
DW
1312 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1313 m_hMaskBitmap = 0;
3b9e3455 1314 }
58b16424 1315 if (!rBitmap.Ok())
3b9e3455 1316 {
58b16424 1317 return(FALSE);
3b9e3455
DW
1318 }
1319
6f38c86f
DW
1320 //
1321 // Scan the bitmap for the transparent colour and set
3b9e3455
DW
1322 // the corresponding pixels in the mask to BLACK and
1323 // the rest to WHITE
6f38c86f
DW
1324 //
1325
1326 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1327 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1328 vBmih.cx = rBitmap.GetWidth();
1329 vBmih.cy = rBitmap.GetHeight();
1330 vBmih.cPlanes = 1;
1331 vBmih.cBitCount = 1;
1332
1333 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1334 ,&vBmih
1335 ,0L
1336 ,NULL
1337 ,NULL
1338 );
1339
1340 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1341 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1342
1343 //
1344 // This is not very efficient, but I can't think
3b9e3455 1345 // of a better way of doing it
6f38c86f 1346 //
58b16424 1347 for (int w = 0; w < rBitmap.GetWidth(); w++)
3b9e3455 1348 {
58b16424 1349 for (int h = 0; h < rBitmap.GetHeight(); h++)
3b9e3455 1350 {
6f38c86f
DW
1351 POINTL vPt = {w, h};
1352 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1353 if (vCol == (COLORREF)CLR_NOINDEX)
1354 {
1355 //
1356 // Doesn't make sense to continue
1357 //
1358 bOk = FALSE;
1359 break;
1360 }
58b16424 1361
6f38c86f 1362 if (vCol == vMaskColour)
3b9e3455 1363 {
6f38c86f
DW
1364 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1365 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1366 }
1367 else
1368 {
6f38c86f
DW
1369 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1370 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1371 }
1372 }
1373 }
6f38c86f
DW
1374 ::GpiSetBitmap(hPSSrc, NULL);
1375 ::GpiSetBitmap(hPSDst, NULL);
1376 ::GpiDestroyPS(hPSSrc);
1377 ::GpiDestroyPS(hPSDst);
1378 ::DevCloseDC(hDCSrc);
1379 ::DevCloseDC(hDCDst);
58b16424 1380 return(TRUE);
6f38c86f 1381} // end of wxMask::Create
0e320a79 1382
3b9e3455
DW
1383// ----------------------------------------------------------------------------
1384// wxBitmapHandler
1385// ----------------------------------------------------------------------------
0e320a79 1386
58b16424
DW
1387bool wxBitmapHandler::Create(
1388 wxGDIImage* pImage
1389, void* pData
1390, long lFlags
1391, int nWidth
1392, int nHeight
1393, int nDepth
1394)
3b9e3455 1395{
58b16424
DW
1396 wxBitmap* pBitmap = wxDynamicCast( pImage
1397 ,wxBitmap
1398 );
3b9e3455 1399
58b16424
DW
1400 return(pBitmap ? Create( pBitmap
1401 ,pData
1402 ,nWidth
1403 ,nHeight
1404 ,nDepth
1405 ) : FALSE);
3b9e3455
DW
1406}
1407
58b16424
DW
1408bool wxBitmapHandler::Load(
1409 wxGDIImage* pImage
1410, const wxString& rName
8ea3f821 1411, HPS hPs
58b16424
DW
1412, long lFlags
1413, int nWidth
1414, int nHeight
1415)
3b9e3455 1416{
43543d98
DW
1417 wxBitmap* pBitmap = wxDynamicCast( pImage
1418 ,wxBitmap
1419 );
3b9e3455 1420
58b16424
DW
1421 return(pBitmap ? LoadFile( pBitmap
1422 ,rName
8ea3f821 1423 ,hPs
58b16424
DW
1424 ,lFlags
1425 ,nWidth
1426 ,nHeight
1427 ) : FALSE);
3b9e3455
DW
1428}
1429
58b16424
DW
1430bool wxBitmapHandler::Save(
1431 wxGDIImage* pImage
1432, const wxString& rName
1433, int lType
1434)
0e320a79 1435{
58b16424
DW
1436 wxBitmap* pBitmap = wxDynamicCast( pImage
1437 ,wxBitmap
1438 );
0e320a79 1439
58b16424
DW
1440 return(pBitmap ? SaveFile( pBitmap
1441 ,rName
1442 ,lType
1443 ) : FALSE);
0e320a79
DW
1444}
1445
58b16424
DW
1446bool wxBitmapHandler::Create(
1447 wxBitmap* WXUNUSED(pBitmap)
1448, void* WXUNUSED(pData)
1449, long WXUNUSED(lType)
1450, int WXUNUSED(nWidth)
1451, int WXUNUSED(nHeight)
1452, int WXUNUSED(nDepth)
1453)
0e320a79 1454{
58b16424 1455 return(FALSE);
0e320a79
DW
1456}
1457
58b16424
DW
1458bool wxBitmapHandler::LoadFile(
1459 wxBitmap* WXUNUSED(pBitmap)
1460, const wxString& WXUNUSED(rName)
8ea3f821 1461, HPS WXUNUSED(hPs)
58b16424
DW
1462, long WXUNUSED(lType)
1463, int WXUNUSED(nDesiredWidth)
1464, int WXUNUSED(nDesiredHeight)
1465)
0e320a79 1466{
43543d98 1467 return(FALSE);
0e320a79
DW
1468}
1469
58b16424
DW
1470bool wxBitmapHandler::SaveFile(
1471 wxBitmap* WXUNUSED(pBitmap)
1472, const wxString& WXUNUSED(rName)
1473, int WXUNUSED(nType)
1474, const wxPalette* WXUNUSED(pPalette)
1475)
0e320a79 1476{
58b16424 1477 return(FALSE);
0e320a79 1478}
ce44c50e 1479
020a1653
DW
1480// ----------------------------------------------------------------------------
1481// Utility functions
1482// ----------------------------------------------------------------------------
1483HBITMAP wxInvertMask(
1484 HBITMAP hBmpMask
1485, int nWidth
1486, int nHeight
1487)
1488{
1489 HBITMAP hBmpInvMask = 0;
1490
1491 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1492
1493 //
1494 // Get width/height from the bitmap if not given
1495 //
1496 if (!nWidth || !nHeight)
1497 {
1498 BITMAPINFOHEADER2 vBmhdr;
1499
1500 ::GpiQueryBitmapInfoHeader( hBmpMask
1501 ,&vBmhdr
1502 );
1503 nWidth = (int)vBmhdr.cx;
e464c180 1504 nHeight = (int)vBmhdr.cy;
020a1653
DW
1505 }
1506
1507 BITMAPINFOHEADER2 vBmih;
1508 SIZEL vSize = {0, 0};
1509 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
e464c180
DW
1510 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1511 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1512 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1513 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1514 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1515 0, 0, nWidth, nHeight
020a1653
DW
1516 };
1517
e464c180 1518 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
020a1653 1519 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
e464c180
DW
1520 vBmih.cx = nWidth;
1521 vBmih.cy = nHeight;
020a1653
DW
1522 vBmih.cPlanes = 1;
1523 vBmih.cBitCount = 1;
1524
1525 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1526 ,&vBmih
1527 ,0L
1528 ,NULL
1529 ,NULL
1530 );
1531
1532 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1533 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1534
1535 ::GpiBitBlt( hPSDst
1536 ,hPSSrc
1537 ,4L
e464c180 1538 ,vPoint
8e8d8eef 1539 ,ROP_SRCINVERT
020a1653
DW
1540 ,BBO_IGNORE
1541 );
1542
1543 ::GpiDestroyPS(hPSSrc);
1544 ::GpiDestroyPS(hPSDst);
1545 ::DevCloseDC(hDCSrc);
e464c180 1546 ::DevCloseDC(hDCDst);
020a1653
DW
1547
1548 return hBmpInvMask;
1549} // end of WxWinGdi_InvertMask
3437f881 1550