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