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