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