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