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