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