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