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