1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
31 #include "wx/os2/private.h"
34 //#include "wx/msw/dib.h"
36 #include "wx/xpmdecod.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 wxBitmapRefData::wxBitmapRefData()
58 m_pSelectedInto
= NULL
;
61 m_hBitmap
= (WXHBITMAP
) NULL
;
62 } // end of wxBitmapRefData::wxBitmapRefData
64 void wxBitmapRefData::Free()
66 if ( m_pSelectedInto
)
68 wxLogLastError("GpiDeleteBitmap(hbitmap)");
72 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
74 wxLogLastError("GpiDeleteBitmap(hbitmap)");
80 } // end of wxBitmapRefData::Free
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 // this function should be called from all wxBitmap ctors
91 // True for all bitmaps created from bits, wxImages, Xpms
93 } // end of wxBitmap::Init
95 bool wxBitmap::CopyFromIconOrCursor(
96 const wxGDIImage
& rIcon
99 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
100 POINTERINFO SIconInfo
;
102 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
104 wxLogLastError(wxT("WinQueryPointerInfo"));
107 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
109 m_refData
= pRefData
;
111 int nWidth
= rIcon
.GetWidth();
112 int nHeight
= rIcon
.GetHeight();
114 pRefData
->m_nWidth
= nWidth
;
115 pRefData
->m_nHeight
= nHeight
;
116 pRefData
->m_nDepth
= wxDisplayDepth();
118 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
120 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
122 pMask
->SetMaskBitmap(GetHBITMAP());
126 } // end of wxBitmap::CopyFromIconOrCursor
128 bool wxBitmap::CopyFromCursor(
129 const wxCursor
& rCursor
136 return(CopyFromIconOrCursor(rCursor
));
137 } // end of wxBitmap::CopyFromCursor
139 bool wxBitmap::CopyFromIcon(
148 return CopyFromIconOrCursor(rIcon
);
149 } // end of wxBitmap::CopyFromIcon
151 wxBitmap::~wxBitmap()
153 } // end of wxBitmap::~wxBitmap
164 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
165 BITMAPINFOHEADER2 vHeader
;
169 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
170 SIZEL vSize
= {0, 0};
173 wxASSERT(vHabmain
!= NULL
);
175 m_refData
= pRefData
;
177 pRefData
->m_nWidth
= nWidth
;
178 pRefData
->m_nHeight
= nHeight
;
179 pRefData
->m_nDepth
= nDepth
;
180 pRefData
->m_nNumColors
= 0;
181 pRefData
->m_pSelectedInto
= NULL
;
183 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
184 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
187 wxLogLastError("GpiCreatePS Failure");
193 // We assume that it is in XBM format which is not quite the same as
194 // the format CreateBitmap() wants because the order of bytes in the
197 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
198 const size_t nPadding
= nBytesPerLine
% 2;
199 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
200 const char* pzSrc
= zBits
;
204 pzData
= (char *)malloc(nLen
);
206 char* pzDst
= pzData
;
208 for (nRows
= 0; nRows
< nHeight
; nRows
++)
210 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
212 unsigned char ucVal
= *pzSrc
++;
213 unsigned char ucReversed
= 0;
216 for (nBits
= 0; nBits
< 8; nBits
++)
219 ucReversed
|= (ucVal
& 0x01);
222 *pzDst
++ = ucReversed
;
231 // Bits should already be in Windows standard format
233 pzData
= (char *)zBits
; // const_cast is harmless
237 nDepth
= 24; // MAX supported in PM
238 memset(&vHeader
, '\0', 16);
240 vHeader
.cx
= (USHORT
)nWidth
;
241 vHeader
.cy
= (USHORT
)nHeight
;
242 vHeader
.cPlanes
= 1L;
243 vHeader
.cBitCount
= nDepth
;
244 vHeader
.usReserved
= 0;
246 memset(&vInfo
, '\0', 16);
248 vInfo
.cx
= (USHORT
)nWidth
;
249 vInfo
.cy
= (USHORT
)nHeight
;
251 vInfo
.cBitCount
= nDepth
;
253 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
257 wxLogLastError("CreateBitmap");
261 SetHBITMAP((WXHBITMAP
)hBmp
);
262 } // end of wxBitmap::wxBitmap
275 } // end of wxBitmap::wxBitmap
293 } // end of wxBitmap::wxBitmap
296 const wxString
& rFilename
304 } // end of wxBitmap::wxBitmap
306 bool wxBitmap::Create(
313 BITMAPINFOHEADER2 vHeader
;
315 wxASSERT(vHabmain
!= NULL
);
317 m_refData
= new wxBitmapRefData
;
318 GetBitmapData()->m_nWidth
= nW
;
319 GetBitmapData()->m_nHeight
= nH
;
320 GetBitmapData()->m_nDepth
= nD
;
323 // Xpms and bitmaps from other images can also be mono's, but only
324 // mono's need help changing their colors with MemDC changes
328 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
329 SIZEL vSize
= {0, 0};
330 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
331 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
335 memset(&vHeader
, '\0', 16);
340 vHeader
.cBitCount
= 24; //nD;
342 hBmp
= ::GpiCreateBitmap( hPS
357 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
358 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
359 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
364 memset(&vHeader
, '\0', 16);
369 vHeader
.cBitCount
= lBitCount
;
371 hBmp
= ::GpiCreateBitmap( hPSScreen
378 GetBitmapData()->m_nDepth
= wxDisplayDepth();
379 ::WinReleasePS(hPSScreen
);
381 SetHBITMAP((WXHBITMAP
)hBmp
);
383 #if WXWIN_COMPATIBILITY_2
384 GetBitmapData()->m_bOk
= hBmp
!= 0;
385 #endif // WXWIN_COMPATIBILITY_2
388 } // end of wxBitmap::Create
390 bool wxBitmap::CreateFromXpm(
394 #if wxUSE_IMAGE && wxUSE_XPM
397 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
399 wxXPMDecoder vDecoder
;
400 wxImage vImg
= vDecoder
.ReadData(ppData
);
402 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
404 *this = wxBitmap(vImg
);
409 } // end of wxBitmap::CreateFromXpm
411 bool wxBitmap::LoadFile(
412 const wxString
& rFilename
416 HPS hPs
= NULLHANDLE
;
420 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
426 m_refData
= new wxBitmapRefData
;
428 return(pHandler
->LoadFile( this
440 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
443 *this = wxBitmap(vImage
);
447 } // end of wxBitmap::LoadFile
449 bool wxBitmap::Create(
459 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
465 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
466 "type %d defined."), lType
);
471 m_refData
= new wxBitmapRefData
;
473 return(pHandler
->Create( this
480 } // end of wxBitmap::Create
482 bool wxBitmap::SaveFile(
483 const wxString
& rFilename
485 , const wxPalette
* pPalette
488 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
494 return pHandler
->SaveFile( this
502 // FIXME what about palette? shouldn't we use it?
503 wxImage vImage
= ConvertToImage();
508 return(vImage
.SaveFile( rFilename
512 } // end of wxBitmap::SaveFile
515 // ----------------------------------------------------------------------------
516 // wxImage-wxBitmap convertion
517 // ----------------------------------------------------------------------------
519 bool wxBitmap::CreateFromImage (
520 const wxImage
& rImage
524 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
525 m_refData
= new wxBitmapRefData();
527 int nSizeLimit
= 1024 * 768 * 3;
528 int nWidth
= rImage
.GetWidth();
529 int nBmpHeight
= rImage
.GetHeight();
530 int nBytePerLine
= nWidth
* 3;
531 int nSizeDWORD
= sizeof(DWORD
);
532 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
535 if (nLineBoundary
> 0)
537 nPadding
= nSizeDWORD
- nLineBoundary
;
538 nBytePerLine
+= nPadding
;
542 // Calc the number of DIBs and heights of DIBs
546 int nHeight
= nSizeLimit
/ nBytePerLine
;
548 if (nHeight
>= nBmpHeight
)
549 nHeight
= nBmpHeight
;
552 nNumDIB
= nBmpHeight
/ nHeight
;
553 nHRemain
= nBmpHeight
% nHeight
;
559 // Set bitmap parameters
561 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
563 SetHeight(nBmpHeight
);
569 nDepth
= wxDisplayDepth();
574 // Copy the palette from the source image
576 SetPalette(rImage
.GetPalette());
577 #endif // wxUSE_PALETTE
580 // Create a DIB header
582 BITMAPINFOHEADER2 vHeader
;
586 // Fill in the DIB header
588 memset(&vHeader
, '\0', 16);
590 vHeader
.cx
= (ULONG
)nWidth
;
591 vHeader
.cy
= (ULONG
)nHeight
;
592 vHeader
.cPlanes
= 1L;
593 vHeader
.cBitCount
= 24;
596 // Memory for DIB data
598 unsigned char* pucBits
;
600 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
603 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
606 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
609 // Create and set the device-dependent bitmap
611 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
612 SIZEL vSize
= {0, 0};
613 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
614 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
616 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
621 memset(&vInfo
, '\0', 16);
623 vInfo
.cx
= (ULONG
)nWidth
;
624 vInfo
.cy
= (ULONG
)nHeight
;
626 vInfo
.cBitCount
= 24; // Set to desired count going in
628 hBmp
= ::GpiCreateBitmap( hPS
635 HPAL hOldPalette
= NULLHANDLE
;
636 if (rImage
.GetPalette().Ok())
638 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
640 #endif // wxUSE_PALETTE
643 // Copy image data into DIB data and then into DDB (in a loop)
645 unsigned char* pData
= rImage
.GetData();
650 unsigned char* ptdata
= pData
;
651 unsigned char* ptbits
;
653 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
658 vError
= ::WinGetLastError(vHabmain
);
659 sError
= wxPMErrorToStr(vError
);
661 for (n
= 0; n
< nNumDIB
; n
++)
663 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
666 // Redefine height and size of the (possibly) last smaller DIB
667 // memory is not reallocated
670 vHeader
.cy
= (DWORD
)(nHeight
);
671 vHeader
.cbImage
= nBytePerLine
* nHeight
;
674 for (j
= 0; j
< nHeight
; j
++)
676 for (i
= 0; i
< nWidth
; i
++)
678 *(ptbits
++) = *(ptdata
+ 2);
679 *(ptbits
++) = *(ptdata
+ 1);
680 *(ptbits
++) = *(ptdata
);
683 for (i
= 0; i
< nPadding
; i
++)
688 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
689 // in combination with setting the bits into the selected bitmap
691 if ((lScans
= ::GpiSetBitmapBits( hPS
692 ,0 // Start at the bottom
693 ,(LONG
)nHeight
// One line per scan
701 vError
= ::WinGetLastError(vHabmain
);
702 sError
= wxPMErrorToStr(vError
);
704 hPSScreen
= ::GpiCreatePS( vHabmain
707 ,PU_PELS
| GPIA_ASSOC
710 POINTL vPoint
[4] = { 0, nOrigin
,
712 0, 0, nWidth
, nHeight
716 ::GpiBitBlt( hPSScreen
723 ::GpiDestroyPS(hPSScreen
);
726 SetHBITMAP((WXHBITMAP
)hBmp
);
729 ::GpiSelectPalette(hPS
, hOldPalette
);
730 #endif // wxUSE_PALETTE
733 // Similarly, created an mono-bitmap for the possible mask
735 if (rImage
.HasMask())
739 vHeader
.cy
= nHeight
;
741 vHeader
.cBitCount
= 24;
742 hBmp
= ::GpiCreateBitmap( hPS
748 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
750 nHeight
= nBmpHeight
;
752 nHeight
= nSizeLimit
/ nBytePerLine
;
753 vHeader
.cy
= (DWORD
)(nHeight
);
756 unsigned char cRed
= rImage
.GetMaskRed();
757 unsigned char cGreen
= rImage
.GetMaskGreen();
758 unsigned char cBlue
= rImage
.GetMaskBlue();
759 unsigned char cZero
= 0;
760 unsigned char cOne
= 255;
763 for (n
= 0; n
< nNumDIB
; n
++)
765 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
768 // Redefine height and size of the (possibly) last smaller DIB
769 // memory is not reallocated
772 vHeader
.cy
= (DWORD
)(nHeight
);
773 vHeader
.cbImage
= nBytePerLine
* nHeight
;
776 for (int j
= 0; j
< nHeight
; j
++)
778 for (i
= 0; i
< nWidth
; i
++)
780 unsigned char cRedImage
= (*(ptdata
++)) ;
781 unsigned char cGreenImage
= (*(ptdata
++)) ;
782 unsigned char cBlueImage
= (*(ptdata
++)) ;
784 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
797 for (i
= 0; i
< nPadding
; i
++)
800 lScans
= ::GpiSetBitmapBits( hPS
801 ,0 // Start at the bottom
802 ,(LONG
)nHeight
// One line per scan
806 hPSScreen
= ::GpiCreatePS( vHabmain
809 ,PU_PELS
| GPIA_ASSOC
811 POINTL vPoint2
[4] = { 0, nOrigin
,
813 0, 0, nWidth
, nHeight
815 ::GpiBitBlt( hPSScreen
822 ::GpiDestroyPS(hPSScreen
);
827 // Create a wxMask object
829 wxMask
* pMask
= new wxMask();
831 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
833 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
837 // Free allocated resources
839 ::GpiSetBitmap(hPS
, NULLHANDLE
);
841 ::DevCloseDC(hDCScreen
);
845 } // end of wxBitmap::CreateFromImage
847 wxImage
wxBitmap::ConvertToImage() const
852 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
855 // Create an wxImage object
857 int nWidth
= GetWidth();
858 int nHeight
= GetHeight();
861 int nBytePerLine
= nWidth
* 3;
862 int nSizeDWORD
= sizeof(DWORD
);
863 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
865 unsigned char* pData
;
866 unsigned char* lpBits
;
868 BITMAPINFOHEADER2 vDIBh
;
869 BITMAPINFO2 vDIBInfo
;
874 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
875 SIZEL vSizlPage
= {0,0};
878 vImage
.Create( nWidth
881 pData
= vImage
.GetData();
884 wxFAIL_MSG( wxT("could not allocate data for image") );
887 if(nLineBoundary
> 0)
889 nPadding
= nSizeDWORD
- nLineBoundary
;
890 nBytePerLine
+= nPadding
;
892 wxDisplaySize( &nDevWidth
896 // Create and fill a DIB header
898 memset(&vDIBh
, '\0', 16);
903 vDIBh
.cBitCount
= 24;
905 memset(&vDIBInfo
, '\0', 16);
907 vDIBInfo
.cx
= nWidth
;
908 vDIBInfo
.cy
= nHeight
;
909 vDIBInfo
.cPlanes
= 1;
910 vDIBInfo
.cBitCount
= 24;
912 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
915 wxFAIL_MSG(wxT("could not allocate data for DIB"));
919 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
920 hBitmap
= (HBITMAP
)GetHBITMAP();
923 // May already be selected into a PS
925 if ((pDC
= GetSelectedInto()) != NULL
)
927 hPSMem
= pDC
->GetHPS();
931 hDCMem
= ::DevOpenDC( vHabmain
938 hPSMem
= ::GpiCreatePS( vHabmain
941 ,PU_PELS
| GPIA_ASSOC
944 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
949 vError
= ::WinGetLastError(vHabmain
);
950 sError
= wxPMErrorToStr(vError
);
954 // Copy data from the device-dependent bitmap to the DIB
956 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
966 vError
= ::WinGetLastError(vHabmain
);
967 sError
= wxPMErrorToStr(vError
);
971 // Copy DIB data into the wxImage object
975 unsigned char* ptdata
= pData
;
976 unsigned char* ptbits
= lpBits
;
978 for (i
= 0; i
< nHeight
; i
++)
980 for (j
= 0; j
< nWidth
; j
++)
982 *(ptdata
++) = *(ptbits
+2);
983 *(ptdata
++) = *(ptbits
+1);
984 *(ptdata
++) = *(ptbits
);
989 if ((pDC
= GetSelectedInto()) == NULL
)
991 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
992 ::GpiDestroyPS(hPSMem
);
993 ::DevCloseDC(hDCMem
);
997 // Similarly, set data according to the possible mask bitmap
999 if (GetMask() && GetMask()->GetMaskBitmap())
1001 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1004 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1006 HDC hMemDC
= ::DevOpenDC( vHabmain
1010 ,(PDEVOPENDATA
)&vDop
1013 HPS hMemPS
= ::GpiCreatePS( vHabmain
1016 ,PU_PELS
| GPIA_ASSOC
1018 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1019 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1020 ::GpiSetBitmap(hMemPS
, hBitmap
);
1021 ::GpiQueryBitmapBits( hPSMem
1027 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1028 ::GpiDestroyPS(hMemPS
);
1029 ::DevCloseDC(hMemDC
);
1032 // Background color set to RGB(16,16,16) in consistent with wxGTK
1034 unsigned char ucRed
= 16;
1035 unsigned char ucGreen
= 16;
1036 unsigned char ucBlue
= 16;
1040 for (i
= 0; i
< nHeight
; i
++)
1042 for (j
= 0; j
< nWidth
; j
++)
1048 *(ptdata
++) = ucRed
;
1049 *(ptdata
++) = ucGreen
;
1050 *(ptdata
++) = ucBlue
;
1056 vImage
.SetMaskColour( ucRed
1060 vImage
.SetMask(TRUE
);
1064 vImage
.SetMask(FALSE
);
1068 // Free allocated resources
1072 } // end of wxBitmap::ConvertToImage
1074 // ----------------------------------------------------------------------------
1075 // sub bitmap extraction
1076 // ----------------------------------------------------------------------------
1078 wxBitmap
wxBitmap::GetSubBitmap(
1082 wxCHECK_MSG( Ok() &&
1083 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1084 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1085 (rRect
.y
+ rRect
.height
<= GetHeight()),
1086 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1088 wxBitmap
vRet( rRect
.width
1092 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1098 SIZEL vSize
= {0, 0};
1099 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1100 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1101 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1102 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1103 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1104 POINTL vPoint
[4] = { 0, 0, rRect
.width
, rRect
.height
,
1106 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
1109 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1110 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1120 // Copy mask if there is one
1124 BITMAPINFOHEADER2 vBmih
;
1126 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1127 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1128 vBmih
.cx
= rRect
.width
;
1129 vBmih
.cy
= rRect
.height
;
1131 vBmih
.cBitCount
= 24;
1133 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1140 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1141 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1143 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1144 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1153 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1154 vRet
.SetMask(pMask
);
1157 ::GpiSetBitmap(hPSSrc
, NULL
);
1158 ::GpiSetBitmap(hPSDst
, NULL
);
1159 ::GpiDestroyPS(hPSSrc
);
1160 ::GpiDestroyPS(hPSDst
);
1161 ::DevCloseDC(hDCSrc
);
1162 ::DevCloseDC(hDCDst
);
1164 } // end of wxBitmap::GetSubBitmap
1166 // ----------------------------------------------------------------------------
1167 // wxBitmap accessors
1168 // ----------------------------------------------------------------------------
1170 void wxBitmap::SetQuality(
1176 GetBitmapData()->m_nQuality
= nQ
;
1177 } // end of wxBitmap::SetQuality
1179 #if WXWIN_COMPATIBILITY_2
1180 void wxBitmap::SetOk(
1186 GetBitmapData()->m_bOk
= bOk
;
1187 } // end of wxBitmap::SetOk
1188 #endif // WXWIN_COMPATIBILITY_2
1190 void wxBitmap::SetPalette(
1191 const wxPalette
& rPalette
1196 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1197 } // end of wxBitmap::SetPalette
1199 void wxBitmap::SetMask(
1205 GetBitmapData()->m_pBitmapMask
= pMask
;
1206 } // end of wxBitmap::SetMask
1208 wxBitmap
wxBitmap::GetBitmapForDC(
1213 } // end of wxBitmap::GetBitmapForDC
1215 // ----------------------------------------------------------------------------
1217 // ----------------------------------------------------------------------------
1222 } // end of wxMask::wxMask
1224 // Construct a mask from a bitmap and a colour indicating
1225 // the transparent area
1227 const wxBitmap
& rBitmap
1228 , const wxColour
& rColour
1235 } // end of wxMask::wxMask
1237 // Construct a mask from a bitmap and a palette index indicating
1238 // the transparent area
1240 const wxBitmap
& rBitmap
1248 } // end of wxMask::wxMask
1250 // Construct a mask from a mono bitmap (copies the bitmap).
1252 const wxBitmap
& rBitmap
1257 } // end of wxMask::wxMask
1262 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1263 } // end of wxMask::~wxMask
1265 // Create a mask from a mono bitmap (copies the bitmap).
1266 bool wxMask::Create(
1267 const wxBitmap
& rBitmap
1270 BITMAPINFOHEADER2 vBmih
;
1271 SIZEL vSize
= {0, 0};
1272 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1273 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1274 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1275 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1276 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1277 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1278 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1283 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1286 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1291 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1292 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1293 vBmih
.cx
= rBitmap
.GetWidth();
1294 vBmih
.cy
= rBitmap
.GetHeight();
1296 vBmih
.cBitCount
= 24;
1298 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1305 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1306 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1315 ::GpiDestroyPS(hPSSrc
);
1316 ::GpiDestroyPS(hPSDst
);
1317 ::DevCloseDC(hDCSrc
);
1318 ::DevCloseDC(hDCDst
);
1320 } // end of wxMask::Create
1322 // Create a mask from a bitmap and a palette index indicating
1323 // the transparent area
1324 bool wxMask::Create(
1325 const wxBitmap
& rBitmap
1331 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1334 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1337 unsigned char cGreen
;
1338 unsigned char cBlue
;
1340 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1346 wxColour
vTransparentColour( cRed
1351 return (Create( rBitmap
1357 } // end of wxMask::Create
1359 // Create a mask from a bitmap and a colour indicating
1360 // the transparent area
1361 bool wxMask::Create(
1362 const wxBitmap
& rBitmap
1363 , const wxColour
& rColour
1367 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1371 BITMAPINFOHEADER2 vBmih
;
1372 SIZEL vSize
= {0, 0};
1373 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1374 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1375 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1376 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1377 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1378 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1379 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1384 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1393 // Scan the bitmap for the transparent colour and set
1394 // the corresponding pixels in the mask to BLACK and
1395 // the rest to WHITE
1398 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1399 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1400 vBmih
.cx
= rBitmap
.GetWidth();
1401 vBmih
.cy
= rBitmap
.GetHeight();
1403 vBmih
.cBitCount
= 1;
1405 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1412 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1413 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1416 // This is not very efficient, but I can't think
1417 // of a better way of doing it
1419 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1421 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1423 POINTL vPt
= {w
, h
};
1424 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1425 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1428 // Doesn't make sense to continue
1434 if (vCol
== vMaskColour
)
1436 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1437 ::GpiSetPel(hPSDst
, &vPt
);
1441 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1442 ::GpiSetPel(hPSDst
, &vPt
);
1446 ::GpiSetBitmap(hPSSrc
, NULL
);
1447 ::GpiSetBitmap(hPSDst
, NULL
);
1448 ::GpiDestroyPS(hPSSrc
);
1449 ::GpiDestroyPS(hPSDst
);
1450 ::DevCloseDC(hDCSrc
);
1451 ::DevCloseDC(hDCDst
);
1453 } // end of wxMask::Create
1455 // ----------------------------------------------------------------------------
1457 // ----------------------------------------------------------------------------
1459 bool wxBitmapHandler::Create(
1468 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1472 return(pBitmap
? Create( pBitmap
1480 bool wxBitmapHandler::Load(
1482 , const wxString
& rName
1489 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1493 return(pBitmap
? LoadFile( pBitmap
1502 bool wxBitmapHandler::Save(
1504 , const wxString
& rName
1508 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1512 return(pBitmap
? SaveFile( pBitmap
1518 bool wxBitmapHandler::Create(
1519 wxBitmap
* WXUNUSED(pBitmap
)
1520 , void* WXUNUSED(pData
)
1521 , long WXUNUSED(lType
)
1522 , int WXUNUSED(nWidth
)
1523 , int WXUNUSED(nHeight
)
1524 , int WXUNUSED(nDepth
)
1530 bool wxBitmapHandler::LoadFile(
1531 wxBitmap
* WXUNUSED(pBitmap
)
1532 , const wxString
& WXUNUSED(rName
)
1534 , long WXUNUSED(lType
)
1535 , int WXUNUSED(nDesiredWidth
)
1536 , int WXUNUSED(nDesiredHeight
)
1542 bool wxBitmapHandler::SaveFile(
1543 wxBitmap
* WXUNUSED(pBitmap
)
1544 , const wxString
& WXUNUSED(rName
)
1545 , int WXUNUSED(nType
)
1546 , const wxPalette
* WXUNUSED(pPalette
)
1552 // ----------------------------------------------------------------------------
1553 // Utility functions
1554 // ----------------------------------------------------------------------------
1555 HBITMAP
wxInvertMask(
1561 HBITMAP hBmpInvMask
= 0;
1563 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1566 // Get width/height from the bitmap if not given
1568 if (!nWidth
|| !nHeight
)
1570 BITMAPINFOHEADER2 vBmhdr
;
1572 ::GpiQueryBitmapInfoHeader( hBmpMask
1575 nWidth
= (int)vBmhdr
.cx
;
1576 nHeight
= (int)vBmhdr
.cy
;
1579 BITMAPINFOHEADER2 vBmih
;
1580 SIZEL vSize
= {0, 0};
1581 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1582 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1583 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1584 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1585 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1586 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1587 0, 0, nWidth
, nHeight
1590 memset(&vBmih
, '\0', 16);
1595 vBmih
.cBitCount
= 24;
1597 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1604 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1605 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1615 ::GpiDestroyPS(hPSSrc
);
1616 ::GpiDestroyPS(hPSDst
);
1617 ::DevCloseDC(hDCSrc
);
1618 ::DevCloseDC(hDCDst
);
1621 } // end of WxWinGdi_InvertMask