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