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