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