]> git.saurik.com Git - wxWidgets.git/blob - src/os2/bitmap.cpp
A few tweaks and cleanups
[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 m_refData = new wxBitmapRefData();
520
521 int nSizeLimit = 1024 * 768 * 3;
522 int nWidth = rImage.GetWidth();
523 int nBmpHeight = rImage.GetHeight();
524 int nBytePerLine = nWidth * 3;
525 int nSizeDWORD = sizeof(DWORD);
526 int nLineBoundary = nBytePerLine % nSizeDWORD;
527 int nPadding = 0;
528
529 if (nLineBoundary > 0)
530 {
531 nPadding = nSizeDWORD - nLineBoundary;
532 nBytePerLine += nPadding;
533 }
534
535 //
536 // Calc the number of DIBs and heights of DIBs
537 //
538 int nNumDIB = 1;
539 int nHRemain = 0;
540 int nHeight = nSizeLimit / nBytePerLine;
541
542 if (nHeight >= nBmpHeight)
543 nHeight = nBmpHeight;
544 else
545 {
546 nNumDIB = nBmpHeight / nHeight;
547 nHRemain = nBmpHeight % nHeight;
548 if (nHRemain > 0)
549 nNumDIB++;
550 }
551
552 //
553 // Set bitmap parameters
554 //
555 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
556 SetWidth(nWidth);
557 SetHeight(nBmpHeight);
558 if (nDepth == -1)
559 nDepth = wxDisplayDepth();
560 SetDepth(nDepth);
561
562 #if wxUSE_PALETTE
563 //
564 // Copy the palette from the source image
565 //
566 SetPalette(rImage.GetPalette());
567 #endif // wxUSE_PALETTE
568
569 //
570 // Create a DIB header
571 //
572 BITMAPINFOHEADER2 vHeader;
573
574 //
575 // Fill in the DIB header
576 //
577 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
578 vHeader.cbFix = sizeof(vHeader);
579 vHeader.cx = (USHORT)nWidth;
580 vHeader.cy = (USHORT)nHeight;
581 vHeader.cPlanes = 1L;
582 vHeader.cBitCount = 24;
583 vHeader.ulCompression = BCA_UNCOMP;
584 vHeader.cbImage = nBytePerLine * nHeight;
585 vHeader.cclrUsed = 0;
586
587 //
588 // These seem not really needed for our purpose here.
589 //
590 vHeader.cxResolution = 0;
591 vHeader.cyResolution = 0;
592 vHeader.cclrImportant = 0;
593 vHeader.usUnits = BRU_METRIC;
594 vHeader.usReserved = 0;
595 vHeader.cSize1 = 0;
596 vHeader.cSize2 = 0;
597 vHeader.usRecording = BRA_BOTTOMUP;
598 vHeader.usRendering = BRH_NOTHALFTONED;
599 vHeader.ulColorEncoding = BCE_RGB;
600 vHeader.ulIdentifier = 0;
601
602 //
603 // Memory for DIB data
604 //
605 unsigned char* pucBits;
606
607 pucBits = (unsigned char *)malloc(vHeader.cbImage);
608 if(!pucBits)
609 {
610 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
611 return FALSE;
612 }
613
614 //
615 // Create and set the device-dependent bitmap
616 //
617 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
618 SIZEL vSize = {0, 0};
619 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
620 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
621 HBITMAP hBmp;
622 HBITMAP hBmpOld;
623
624 hBmp = ::GpiCreateBitmap( hPS
625 ,&vHeader
626 ,0L
627 ,NULL
628 ,NULL
629 );
630 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
631 #if wxUSE_PALETTE
632 HPAL hOldPalette = NULLHANDLE;
633 if (rImage.GetPalette().Ok())
634 {
635 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
636 }
637 #endif // wxUSE_PALETTE
638
639 //
640 // Copy image data into DIB data and then into DDB (in a loop)
641 //
642 unsigned char* pData = rImage.GetData();
643 int i;
644 int j;
645 int n;
646 int nOrigin = 0;
647 unsigned char* ptdata = pData;
648 unsigned char* ptbits;
649
650 for (n = 0; n < nNumDIB; n++)
651 {
652 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
653 {
654 //
655 // Redefine height and size of the (possibly) last smaller DIB
656 // memory is not reallocated
657 //
658 nHeight = nHRemain;
659 vHeader.cy = (DWORD)(nHeight);
660 vHeader.cbImage = nBytePerLine * nHeight;
661 }
662 ptbits = pucBits;
663 for (j = 0; j < nHeight; j++)
664 {
665 for (i = 0; i < nWidth; i++)
666 {
667 *(ptbits++) = *(ptdata + 2);
668 *(ptbits++) = *(ptdata + 1);
669 *(ptbits++) = *(ptdata);
670 ptdata += 3;
671 }
672 for (i = 0; i < nPadding; i++)
673 *(ptbits++) = 0;
674 }
675
676 //
677 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
678 //
679 POINTL vPoint[4] = { 0, nOrigin,
680 nWidth, nHeight,
681 0, 0, nWidth, nHeight
682 };
683
684 ::GpiBitBlt( hPS
685 ,hPS
686 ,4
687 ,vPoint
688 ,ROP_SRCCOPY
689 ,BBO_IGNORE
690 );
691 nOrigin += nHeight;
692 }
693 SetHBITMAP((WXHBITMAP)hBmp);
694 #if wxUSE_PALETTE
695 if (hOldPalette)
696 ::GpiSelectPalette(hPS, hOldPalette);
697 #endif // wxUSE_PALETTE
698
699 //
700 // Similarly, created an mono-bitmap for the possible mask
701 //
702 if (rImage.HasMask())
703 {
704 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
705 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
706 vHeader.cx = nWidth;
707 vHeader.cy = nHeight;
708 vHeader.cPlanes = 1;
709 vHeader.cBitCount = 1;
710 hBmp = ::GpiCreateBitmap( hPS
711 ,&vHeader
712 ,0L
713 ,NULL
714 ,NULL
715 );
716 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
717 if (nNumDIB == 1)
718 nHeight = nBmpHeight;
719 else
720 nHeight = nSizeLimit / nBytePerLine;
721 vHeader.cy = (DWORD)(nHeight);
722 vHeader.cbImage = nBytePerLine * nHeight;
723 nOrigin = 0;
724
725 unsigned char cRed = rImage.GetMaskRed();
726 unsigned char cGreen = rImage.GetMaskGreen();
727 unsigned char cBlue = rImage.GetMaskBlue();
728 unsigned char cZero = 0;
729 unsigned char cOne = 255;
730
731 ptdata = pData;
732 for (n = 0; n < nNumDIB; n++)
733 {
734 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
735 {
736 //
737 // Redefine height and size of the (possibly) last smaller DIB
738 // memory is not reallocated
739 //
740 nHeight = nHRemain;
741 vHeader.cy = (DWORD)(nHeight);
742 vHeader.cbImage = nBytePerLine * nHeight;
743 }
744 ptbits = pucBits;
745 for (int j = 0; j < nHeight; j++)
746 {
747 for (i = 0; i < nWidth; i++)
748 {
749 if ((*(ptdata++) != cRed) || (*(ptdata++) != cGreen) || (*(ptdata++) != cBlue))
750 {
751 *(ptbits++) = cOne;
752 *(ptbits++) = cOne;
753 *(ptbits++) = cOne;
754 }
755 else
756 {
757 *(ptbits++) = cZero;
758 *(ptbits++) = cZero;
759 *(ptbits++) = cZero;
760 }
761 }
762 for (i = 0; i < nPadding; i++)
763 *(ptbits++) = cZero;
764 }
765 POINTL vPoint[4] = { 0, nOrigin,
766 nWidth, nHeight,
767 0, 0, nWidth, nHeight
768 };
769
770 ::GpiBitBlt( hPS
771 ,hPS
772 ,4
773 ,vPoint
774 ,ROP_SRCCOPY
775 ,BBO_IGNORE
776 );
777 nOrigin += nHeight;
778 }
779
780 //
781 // Create a wxMask object
782 //
783 wxMask* pMask = new wxMask();
784
785 pMask->SetMaskBitmap((WXHBITMAP)hBmp);
786 SetMask(pMask);
787 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
788 }
789
790 //
791 // Free allocated resources
792 //
793 ::GpiSetBitmap(hPS, NULLHANDLE);
794 ::GpiDestroyPS(hPS);
795 ::DevCloseDC(hDC);
796 free(pucBits);
797 return TRUE;
798 } // end of wxBitmap::CreateFromImage
799
800 wxImage wxBitmap::ConvertToImage() const
801 {
802 wxImage vImage;
803
804 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
805
806 //
807 // Create an wxImage object
808 //
809 int nWidth = GetWidth();
810 int nHeight = GetHeight();
811 int nDevWidth;
812 int nDevHeight;
813 int nBytePerLine = nWidth * 3;
814 int nSizeDWORD = sizeof(DWORD);
815 int nLineBoundary = nBytePerLine % nSizeDWORD;
816 int nPadding = 0;
817 unsigned char* pData;
818 unsigned char* lpBits;
819 long lScans;
820 BITMAPINFOHEADER2 vDIBh;
821 BITMAPINFO2 vDIBInfo;
822 HDC hDCMem;
823 PSZ pszData[4] = { "Display", NULL, NULL, NULL };
824 HPS hPSMem;
825 HPS hPS;
826 SIZEL vSizlPage = {0,0};
827 HBITMAP hBitmap;
828
829 vImage.Create( nWidth
830 ,nHeight
831 );
832 pData = vImage.GetData();
833 if(!pData)
834 {
835 wxFAIL_MSG( wxT("could not allocate data for image") );
836 return wxNullImage;
837 }
838 if(nLineBoundary > 0)
839 {
840 nPadding = nSizeDWORD - nLineBoundary;
841 nBytePerLine += nPadding;
842 }
843 wxDisplaySize( &nDevWidth
844 ,&nDevHeight
845 );
846 //
847 // Create and fill a DIB header
848 //
849 memset(&vDIBh, '\0', sizeof(BITMAPINFOHEADER2));
850 vDIBh.cbFix = sizeof(BITMAPINFOHEADER2);
851 vDIBh.cx = nWidth;
852 vDIBh.cy = nHeight;
853 vDIBh.cPlanes = 1;
854 vDIBh.cbImage = nBytePerLine * nHeight;
855 vDIBh.cBitCount = 24;
856
857 memset(&vDIBInfo, '\0', sizeof(BITMAPINFO2));
858 vDIBInfo.cbFix = sizeof(BITMAPINFO2);
859 vDIBInfo.cPlanes = 1;
860 vDIBInfo.cBitCount = 24;
861 vDIBInfo.ulCompression = BCA_UNCOMP;
862 vDIBInfo.usReserved = 0;
863 vDIBInfo.usRecording = BRA_BOTTOMUP;
864 vDIBInfo.usRendering = BRH_NOTHALFTONED;
865 vDIBInfo.ulColorEncoding = BCE_RGB;
866 vDIBInfo.ulIdentifier = 0;
867
868 lpBits = (unsigned char *)malloc(vDIBh.cbImage);
869 if (!lpBits)
870 {
871 wxFAIL_MSG(wxT("could not allocate data for DIB"));
872 free(pData);
873 return wxNullImage;
874 }
875
876 //
877 // Copy data from the device-dependent bitmap to the DIB
878 //
879 hDCMem = ::DevOpenDC( vHabmain
880 ,OD_MEMORY
881 ,"*"
882 ,4
883 ,(PDEVOPENDATA)pszData
884 ,NULLHANDLE
885 );
886 hPSMem = ::GpiCreatePS( vHabmain
887 ,hDCMem
888 ,&vSizlPage
889 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
890 );
891 hBitmap = ::GpiCreateBitmap( hPSMem
892 ,&vDIBh
893 ,0L
894 ,NULL
895 ,NULL
896 );
897 lScans = ::GpiQueryBitmapBits( hPSMem
898 ,0L
899 ,(LONG)nHeight
900 ,(PBYTE)lpBits
901 ,&vDIBInfo
902 );
903
904 //
905 // Copy DIB data into the wxImage object
906 //
907 int i;
908 int j;
909 unsigned char* ptdata = pData;
910 unsigned char* ptbits = lpBits;
911
912 for (i = 0; i < nHeight; i++)
913 {
914 for (j = 0; j < nWidth; j++)
915 {
916 *(ptdata++) = *(ptbits+2);
917 *(ptdata++) = *(ptbits+1);
918 *(ptdata++) = *(ptbits );
919 ptbits += 3;
920 }
921 ptbits += nPadding;
922 }
923
924 //
925 // Similarly, set data according to the possible mask bitmap
926 //
927 if (GetMask() && GetMask()->GetMaskBitmap())
928 {
929 hBitmap = (HBITMAP)GetMask()->GetMaskBitmap();
930
931 //
932 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
933 //
934 HDC hMemDC = ::DevOpenDC( vHabmain
935 ,OD_MEMORY
936 ,"*"
937 ,4
938 ,(PDEVOPENDATA)pszData
939 ,NULLHANDLE
940 );
941 HPS hMemPS = ::GpiCreatePS( vHabmain
942 ,hMemDC
943 ,&vSizlPage
944 ,PU_PELS | GPIA_ASSOC | GPIT_MICRO
945 );
946 ::GpiSetColor(hMemPS, OS2RGB(0, 0, 0));
947 ::GpiSetBackColor(hMemPS, OS2RGB(255, 255, 255) );
948 ::GpiQueryBitmapBits( hPSMem
949 ,0L
950 ,(LONG)nHeight
951 ,(PBYTE)lpBits
952 ,&vDIBInfo
953 );
954 ::GpiDestroyPS(hMemPS);
955 ::DevCloseDC(hMemDC);
956
957 //
958 // Background color set to RGB(16,16,16) in consistent with wxGTK
959 //
960 unsigned char ucRed = 16;
961 unsigned char ucGreen = 16;
962 unsigned char ucBlue = 16;
963
964 ptdata = pData;
965 ptbits = lpBits;
966 for (i = 0; i < nHeight; i++)
967 {
968 for (j = 0; j < nWidth; j++)
969 {
970 if (*ptbits != 0)
971 ptdata += 3;
972 else
973 {
974 *(ptdata++) = ucRed;
975 *(ptdata++) = ucGreen;
976 *(ptdata++) = ucBlue;
977 }
978 ptbits += 3;
979 }
980 ptbits += nPadding;
981 }
982 vImage.SetMaskColour( ucRed
983 ,ucGreen
984 ,ucBlue
985 );
986 vImage.SetMask(TRUE);
987 }
988 else
989 {
990 vImage.SetMask(FALSE);
991 }
992
993 //
994 // Free allocated resources
995 //
996 ::GpiDestroyPS(hPSMem);
997 ::DevCloseDC(hDCMem);
998 free(lpBits);
999 return vImage;
1000 } // end of wxBitmap::ConvertToImage
1001
1002 // ----------------------------------------------------------------------------
1003 // sub bitmap extraction
1004 // ----------------------------------------------------------------------------
1005
1006 wxBitmap wxBitmap::GetSubBitmap(
1007 const wxRect& rRect
1008 ) const
1009 {
1010 wxCHECK_MSG( Ok() &&
1011 (rRect.x >= 0) && (rRect.y >= 0) &&
1012 (rRect.x + rRect.width <= GetWidth()) &&
1013 (rRect.y + rRect.height <= GetHeight()),
1014 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
1015
1016 wxBitmap vRet( rRect.width
1017 ,rRect.height
1018 ,GetDepth()
1019 );
1020 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
1021
1022
1023 //
1024 // Copy bitmap data
1025 //
1026 SIZEL vSize = {0, 0};
1027 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1028 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1029 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1030 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1031 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1032 POINTL vPoint[4] = { rRect.x, rRect.y,
1033 rRect.x + rRect.width, rRect.y + rRect.height,
1034 0, 0, GetWidth(), GetHeight()
1035 };
1036
1037 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1038 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1039 ::GpiBitBlt( hPSDst
1040 ,hPSSrc
1041 ,4L
1042 ,vPoint
1043 ,ROP_SRCCOPY
1044 ,BBO_IGNORE
1045 );
1046
1047 //
1048 // Copy mask if there is one
1049 //
1050 if (GetMask())
1051 {
1052 BITMAPINFOHEADER2 vBmih;
1053
1054 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1055 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1056 vBmih.cx = rRect.width;
1057 vBmih.cy = rRect.height;
1058 vBmih.cPlanes = 1;
1059 vBmih.cBitCount = 1;
1060
1061 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
1062 ,&vBmih
1063 ,0L
1064 ,NULL
1065 ,NULL
1066 );
1067
1068 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1069 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1070
1071 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
1072 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
1073 ::GpiBitBlt( hPSDst
1074 ,hPSSrc
1075 ,4L
1076 ,vPoint
1077 ,ROP_SRCCOPY
1078 ,BBO_IGNORE
1079 );
1080
1081 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
1082 vRet.SetMask(pMask);
1083 }
1084
1085 ::GpiSetBitmap(hPSSrc, NULL);
1086 ::GpiSetBitmap(hPSDst, NULL);
1087 ::GpiDestroyPS(hPSSrc);
1088 ::GpiDestroyPS(hPSDst);
1089 ::DevCloseDC(hDCSrc);
1090 ::DevCloseDC(hDCDst);
1091 return vRet;
1092 } // end of wxBitmap::GetSubBitmap
1093
1094 // ----------------------------------------------------------------------------
1095 // wxBitmap accessors
1096 // ----------------------------------------------------------------------------
1097
1098 void wxBitmap::SetQuality(
1099 int nQ
1100 )
1101 {
1102 EnsureHasData();
1103
1104 GetBitmapData()->m_nQuality = nQ;
1105 } // end of wxBitmap::SetQuality
1106
1107 #if WXWIN_COMPATIBILITY_2
1108 void wxBitmap::SetOk(
1109 bool bOk
1110 )
1111 {
1112 EnsureHasData();
1113
1114 GetBitmapData()->m_bOk = bOk;
1115 } // end of wxBitmap::SetOk
1116 #endif // WXWIN_COMPATIBILITY_2
1117
1118 void wxBitmap::SetPalette(
1119 const wxPalette& rPalette
1120 )
1121 {
1122 EnsureHasData();
1123
1124 GetBitmapData()->m_vBitmapPalette = rPalette;
1125 } // end of wxBitmap::SetPalette
1126
1127 void wxBitmap::SetMask(
1128 wxMask* pMask
1129 )
1130 {
1131 EnsureHasData();
1132
1133 GetBitmapData()->m_pBitmapMask = pMask;
1134 } // end of wxBitmap::SetMask
1135
1136 wxBitmap wxBitmap::GetBitmapForDC(
1137 wxDC& rDc
1138 ) const
1139 {
1140 return(*this);
1141 } // end of wxBitmap::GetBitmapForDC
1142
1143 // ----------------------------------------------------------------------------
1144 // wxMask
1145 // ----------------------------------------------------------------------------
1146
1147 wxMask::wxMask()
1148 {
1149 m_hMaskBitmap = 0;
1150 } // end of wxMask::wxMask
1151
1152 // Construct a mask from a bitmap and a colour indicating
1153 // the transparent area
1154 wxMask::wxMask(
1155 const wxBitmap& rBitmap
1156 , const wxColour& rColour
1157 )
1158 {
1159 m_hMaskBitmap = 0;
1160 Create( rBitmap
1161 ,rColour
1162 );
1163 } // end of wxMask::wxMask
1164
1165 // Construct a mask from a bitmap and a palette index indicating
1166 // the transparent area
1167 wxMask::wxMask(
1168 const wxBitmap& rBitmap
1169 , int nPaletteIndex
1170 )
1171 {
1172 m_hMaskBitmap = 0;
1173 Create( rBitmap
1174 ,nPaletteIndex
1175 );
1176 } // end of wxMask::wxMask
1177
1178 // Construct a mask from a mono bitmap (copies the bitmap).
1179 wxMask::wxMask(
1180 const wxBitmap& rBitmap
1181 )
1182 {
1183 m_hMaskBitmap = 0;
1184 Create(rBitmap);
1185 } // end of wxMask::wxMask
1186
1187 wxMask::~wxMask()
1188 {
1189 if (m_hMaskBitmap)
1190 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
1191 } // end of wxMask::~wxMask
1192
1193 // Create a mask from a mono bitmap (copies the bitmap).
1194 bool wxMask::Create(
1195 const wxBitmap& rBitmap
1196 )
1197 {
1198 BITMAPINFOHEADER2 vBmih;
1199 SIZEL vSize = {0, 0};
1200 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1201 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1202 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1203 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1204 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1205 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1206 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1207 };
1208
1209 if (m_hMaskBitmap)
1210 {
1211 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1212 m_hMaskBitmap = 0;
1213 }
1214 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
1215 {
1216 return(FALSE);
1217 }
1218
1219 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1220 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1221 vBmih.cx = rBitmap.GetWidth();
1222 vBmih.cy = rBitmap.GetHeight();
1223 vBmih.cPlanes = 1;
1224 vBmih.cBitCount = 1;
1225
1226 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1227 ,&vBmih
1228 ,0L
1229 ,NULL
1230 ,NULL
1231 );
1232
1233 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1234 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1235 ::GpiBitBlt( hPSDst
1236 ,hPSSrc
1237 ,4L
1238 ,vPoint
1239 ,ROP_SRCCOPY
1240 ,BBO_IGNORE
1241 );
1242
1243 ::GpiDestroyPS(hPSSrc);
1244 ::GpiDestroyPS(hPSDst);
1245 ::DevCloseDC(hDCSrc);
1246 ::DevCloseDC(hDCDst);
1247 return(TRUE);
1248 } // end of wxMask::Create
1249
1250 // Create a mask from a bitmap and a palette index indicating
1251 // the transparent area
1252 bool wxMask::Create(
1253 const wxBitmap& rBitmap
1254 , int nPaletteIndex
1255 )
1256 {
1257 if (m_hMaskBitmap)
1258 {
1259 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1260 m_hMaskBitmap = 0;
1261 }
1262 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
1263 {
1264 unsigned char cRed;
1265 unsigned char cGreen;
1266 unsigned char cBlue;
1267
1268 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
1269 ,&cRed
1270 ,&cGreen
1271 ,&cBlue
1272 ))
1273 {
1274 wxColour vTransparentColour( cRed
1275 ,cGreen
1276 ,cBlue
1277 );
1278
1279 return (Create( rBitmap
1280 ,vTransparentColour
1281 ));
1282 }
1283 }
1284 return(FALSE);
1285 } // end of wxMask::Create
1286
1287 // Create a mask from a bitmap and a colour indicating
1288 // the transparent area
1289 bool wxMask::Create(
1290 const wxBitmap& rBitmap
1291 , const wxColour& rColour
1292 )
1293 {
1294 bool bOk = TRUE;
1295 COLORREF vMaskColour = OS2RGB( rColour.Red()
1296 ,rColour.Green()
1297 ,rColour.Blue()
1298 );
1299 BITMAPINFOHEADER2 vBmih;
1300 SIZEL vSize = {0, 0};
1301 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1302 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1303 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1304 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1305 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1306 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1307 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1308 };
1309
1310 if (m_hMaskBitmap)
1311 {
1312 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1313 m_hMaskBitmap = 0;
1314 }
1315 if (!rBitmap.Ok())
1316 {
1317 return(FALSE);
1318 }
1319
1320 //
1321 // Scan the bitmap for the transparent colour and set
1322 // the corresponding pixels in the mask to BLACK and
1323 // the rest to WHITE
1324 //
1325
1326 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1327 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1328 vBmih.cx = rBitmap.GetWidth();
1329 vBmih.cy = rBitmap.GetHeight();
1330 vBmih.cPlanes = 1;
1331 vBmih.cBitCount = 1;
1332
1333 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1334 ,&vBmih
1335 ,0L
1336 ,NULL
1337 ,NULL
1338 );
1339
1340 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1341 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1342
1343 //
1344 // This is not very efficient, but I can't think
1345 // of a better way of doing it
1346 //
1347 for (int w = 0; w < rBitmap.GetWidth(); w++)
1348 {
1349 for (int h = 0; h < rBitmap.GetHeight(); h++)
1350 {
1351 POINTL vPt = {w, h};
1352 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1353 if (vCol == (COLORREF)CLR_NOINDEX)
1354 {
1355 //
1356 // Doesn't make sense to continue
1357 //
1358 bOk = FALSE;
1359 break;
1360 }
1361
1362 if (vCol == vMaskColour)
1363 {
1364 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1365 ::GpiSetPel(hPSDst, &vPt);
1366 }
1367 else
1368 {
1369 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1370 ::GpiSetPel(hPSDst, &vPt);
1371 }
1372 }
1373 }
1374 ::GpiSetBitmap(hPSSrc, NULL);
1375 ::GpiSetBitmap(hPSDst, NULL);
1376 ::GpiDestroyPS(hPSSrc);
1377 ::GpiDestroyPS(hPSDst);
1378 ::DevCloseDC(hDCSrc);
1379 ::DevCloseDC(hDCDst);
1380 return(TRUE);
1381 } // end of wxMask::Create
1382
1383 // ----------------------------------------------------------------------------
1384 // wxBitmapHandler
1385 // ----------------------------------------------------------------------------
1386
1387 bool wxBitmapHandler::Create(
1388 wxGDIImage* pImage
1389 , void* pData
1390 , long lFlags
1391 , int nWidth
1392 , int nHeight
1393 , int nDepth
1394 )
1395 {
1396 wxBitmap* pBitmap = wxDynamicCast( pImage
1397 ,wxBitmap
1398 );
1399
1400 return(pBitmap ? Create( pBitmap
1401 ,pData
1402 ,nWidth
1403 ,nHeight
1404 ,nDepth
1405 ) : FALSE);
1406 }
1407
1408 bool wxBitmapHandler::Load(
1409 wxGDIImage* pImage
1410 , const wxString& rName
1411 , HPS hPs
1412 , long lFlags
1413 , int nWidth
1414 , int nHeight
1415 )
1416 {
1417 wxBitmap* pBitmap = wxDynamicCast( pImage
1418 ,wxBitmap
1419 );
1420
1421 return(pBitmap ? LoadFile( pBitmap
1422 ,rName
1423 ,hPs
1424 ,lFlags
1425 ,nWidth
1426 ,nHeight
1427 ) : FALSE);
1428 }
1429
1430 bool wxBitmapHandler::Save(
1431 wxGDIImage* pImage
1432 , const wxString& rName
1433 , int lType
1434 )
1435 {
1436 wxBitmap* pBitmap = wxDynamicCast( pImage
1437 ,wxBitmap
1438 );
1439
1440 return(pBitmap ? SaveFile( pBitmap
1441 ,rName
1442 ,lType
1443 ) : FALSE);
1444 }
1445
1446 bool wxBitmapHandler::Create(
1447 wxBitmap* WXUNUSED(pBitmap)
1448 , void* WXUNUSED(pData)
1449 , long WXUNUSED(lType)
1450 , int WXUNUSED(nWidth)
1451 , int WXUNUSED(nHeight)
1452 , int WXUNUSED(nDepth)
1453 )
1454 {
1455 return(FALSE);
1456 }
1457
1458 bool wxBitmapHandler::LoadFile(
1459 wxBitmap* WXUNUSED(pBitmap)
1460 , const wxString& WXUNUSED(rName)
1461 , HPS WXUNUSED(hPs)
1462 , long WXUNUSED(lType)
1463 , int WXUNUSED(nDesiredWidth)
1464 , int WXUNUSED(nDesiredHeight)
1465 )
1466 {
1467 return(FALSE);
1468 }
1469
1470 bool wxBitmapHandler::SaveFile(
1471 wxBitmap* WXUNUSED(pBitmap)
1472 , const wxString& WXUNUSED(rName)
1473 , int WXUNUSED(nType)
1474 , const wxPalette* WXUNUSED(pPalette)
1475 )
1476 {
1477 return(FALSE);
1478 }
1479
1480 // ----------------------------------------------------------------------------
1481 // Utility functions
1482 // ----------------------------------------------------------------------------
1483 HBITMAP wxInvertMask(
1484 HBITMAP hBmpMask
1485 , int nWidth
1486 , int nHeight
1487 )
1488 {
1489 HBITMAP hBmpInvMask = 0;
1490
1491 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1492
1493 //
1494 // Get width/height from the bitmap if not given
1495 //
1496 if (!nWidth || !nHeight)
1497 {
1498 BITMAPINFOHEADER2 vBmhdr;
1499
1500 ::GpiQueryBitmapInfoHeader( hBmpMask
1501 ,&vBmhdr
1502 );
1503 nWidth = (int)vBmhdr.cx;
1504 nHeight = (int)vBmhdr.cy;
1505 }
1506
1507 BITMAPINFOHEADER2 vBmih;
1508 SIZEL vSize = {0, 0};
1509 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1510 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1511 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1512 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1513 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1514 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1515 0, 0, nWidth, nHeight
1516 };
1517
1518 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1519 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1520 vBmih.cx = nWidth;
1521 vBmih.cy = nHeight;
1522 vBmih.cPlanes = 1;
1523 vBmih.cBitCount = 1;
1524
1525 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1526 ,&vBmih
1527 ,0L
1528 ,NULL
1529 ,NULL
1530 );
1531
1532 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1533 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1534
1535 ::GpiBitBlt( hPSDst
1536 ,hPSSrc
1537 ,4L
1538 ,vPoint
1539 ,ROP_SRCINVERT
1540 ,BBO_IGNORE
1541 );
1542
1543 ::GpiDestroyPS(hPSSrc);
1544 ::GpiDestroyPS(hPSDst);
1545 ::DevCloseDC(hDCSrc);
1546 ::DevCloseDC(hDCDst);
1547
1548 return hBmpInvMask;
1549 } // end of WxWinGdi_InvertMask
1550