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