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
89 } // end of wxBitmap::Init
91 bool wxBitmap::CopyFromIconOrCursor(
92 const wxGDIImage
& rIcon
95 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
96 POINTERINFO SIconInfo
;
98 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
100 wxLogLastError(wxT("WinQueryPointerInfo"));
103 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
105 m_refData
= pRefData
;
107 int nWidth
= rIcon
.GetWidth();
108 int nHeight
= rIcon
.GetHeight();
110 pRefData
->m_nWidth
= nWidth
;
111 pRefData
->m_nHeight
= nHeight
;
112 pRefData
->m_nDepth
= wxDisplayDepth();
114 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
117 // No mask in the Info struct in OS/2
120 } // end of wxBitmap::CopyFromIconOrCursor
122 bool wxBitmap::CopyFromCursor(
123 const wxCursor
& rCursor
130 return(CopyFromIconOrCursor(rCursor
));
131 } // end of wxBitmap::CopyFromCursor
133 bool wxBitmap::CopyFromIcon(
142 return CopyFromIconOrCursor(rIcon
);
143 } // end of wxBitmap::CopyFromIcon
145 wxBitmap::~wxBitmap()
147 } // end of wxBitmap::~wxBitmap
158 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
159 BITMAPINFOHEADER2 vHeader
;
163 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
164 SIZEL vSize
= {0, 0};
167 wxASSERT(vHabmain
!= NULL
);
169 m_refData
= pRefData
;
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
;
177 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
178 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
181 wxLogLastError("GpiCreatePS Failure");
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
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
;
198 pzData
= (char *)malloc(nLen
);
200 char* pzDst
= pzData
;
202 for (nRows
= 0; nRows
< nHeight
; nRows
++)
204 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
206 unsigned char ucVal
= *pzSrc
++;
207 unsigned char ucReversed
= 0;
210 for (nBits
= 0; nBits
< 8; nBits
++)
213 ucReversed
|= (ucVal
& 0x01);
216 *pzDst
++ = ucReversed
;
225 // Bits should already be in Windows standard format
227 pzData
= (char *)zBits
; // const_cast is harmless
230 memset(&vHeader
, '\0', 16);
232 vHeader
.cx
= (USHORT
)nWidth
;
233 vHeader
.cy
= (USHORT
)nHeight
;
234 vHeader
.cPlanes
= 1L;
235 vHeader
.cBitCount
= nDepth
;
236 vHeader
.usReserved
= 0;
238 memset(&vInfo
, '\0', 16);
240 vInfo
.cx
= (USHORT
)nWidth
;
241 vInfo
.cy
= (USHORT
)nHeight
;
243 vInfo
.cBitCount
= nDepth
;
245 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
249 wxLogLastError("CreateBitmap");
253 SetHBITMAP((WXHBITMAP
)hBmp
);
254 } // end of wxBitmap::wxBitmap
268 } // end of wxBitmap::wxBitmap
286 } // end of wxBitmap::wxBitmap
289 const wxString
& rFilename
298 } // end of wxBitmap::wxBitmap
300 bool wxBitmap::Create(
307 BITMAPINFOHEADER2 vHeader
;
309 wxASSERT(vHabmain
!= NULL
);
311 m_refData
= new wxBitmapRefData
;
312 GetBitmapData()->m_nWidth
= nW
;
313 GetBitmapData()->m_nHeight
= nH
;
314 GetBitmapData()->m_nDepth
= nD
;
318 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
319 SIZEL vSize
= {0, 0};
320 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
321 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
323 memset(&vHeader
, '\0', 16);
328 vHeader
.cBitCount
= nD
;
330 hBmp
= ::GpiCreateBitmap( hPS
345 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
346 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
347 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
349 memset(&vHeader
, '\0', 16);
354 vHeader
.cBitCount
= lBitCount
;
356 hBmp
= ::GpiCreateBitmap( hPSScreen
363 GetBitmapData()->m_nDepth
= wxDisplayDepth();
364 ::WinReleasePS(hPSScreen
);
366 SetHBITMAP((WXHBITMAP
)hBmp
);
368 #if WXWIN_COMPATIBILITY_2
369 GetBitmapData()->m_bOk
= hBmp
!= 0;
370 #endif // WXWIN_COMPATIBILITY_2
373 } // end of wxBitmap::Create
375 bool wxBitmap::CreateFromXpm(
379 #if wxUSE_IMAGE && wxUSE_XPM
382 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
384 wxXPMDecoder vDecoder
;
385 wxImage vImg
= vDecoder
.ReadData(ppData
);
387 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
389 *this = wxBitmap(vImg
);
394 } // end of wxBitmap::CreateFromXpm
396 bool wxBitmap::LoadFile(
397 const wxString
& rFilename
401 HPS hPs
= NULLHANDLE
;
405 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
411 m_refData
= new wxBitmapRefData
;
413 return(pHandler
->LoadFile( this
425 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
428 *this = wxBitmap(vImage
);
432 } // end of wxBitmap::LoadFile
434 bool wxBitmap::Create(
444 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
450 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
451 "type %d defined."), lType
);
456 m_refData
= new wxBitmapRefData
;
458 return(pHandler
->Create( this
465 } // end of wxBitmap::Create
467 bool wxBitmap::SaveFile(
468 const wxString
& rFilename
470 , const wxPalette
* pPalette
473 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
479 return pHandler
->SaveFile( this
487 // FIXME what about palette? shouldn't we use it?
488 wxImage vImage
= ConvertToImage();
493 return(vImage
.SaveFile( rFilename
497 } // end of wxBitmap::SaveFile
500 // ----------------------------------------------------------------------------
501 // wxImage-wxBitmap convertion
502 // ----------------------------------------------------------------------------
504 bool wxBitmap::CreateFromImage (
505 const wxImage
& rImage
509 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
510 m_refData
= new wxBitmapRefData();
513 int nSizeLimit
= 1024 * 768 * 3;
514 int nWidth
= rImage
.GetWidth();
515 int nBmpHeight
= rImage
.GetHeight();
516 int nBytePerLine
= nWidth
* 3;
517 int nSizeDWORD
= sizeof(DWORD
);
518 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
521 if (nLineBoundary
> 0)
523 nPadding
= nSizeDWORD
- nLineBoundary
;
524 nBytePerLine
+= nPadding
;
528 // Calc the number of DIBs and heights of DIBs
532 int nHeight
= nSizeLimit
/ nBytePerLine
;
534 if (nHeight
>= nBmpHeight
)
535 nHeight
= nBmpHeight
;
538 nNumDIB
= nBmpHeight
/ nHeight
;
539 nHRemain
= nBmpHeight
% nHeight
;
545 // Set bitmap parameters
547 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
549 SetHeight(nBmpHeight
);
551 nDepth
= 16; // wxDisplayDepth();
556 // Copy the palette from the source image
558 SetPalette(rImage
.GetPalette());
559 #endif // wxUSE_PALETTE
562 // Create a DIB header
564 BITMAPINFOHEADER2 vHeader
;
568 // Fill in the DIB header
570 memset(&vHeader
, '\0', 16);
572 vHeader
.cx
= (ULONG
)nWidth
;
573 vHeader
.cy
= (ULONG
)nHeight
;
574 vHeader
.cPlanes
= 1L;
575 vHeader
.cBitCount
= 24;
577 memset(&vInfo
, '\0', 16);
579 vInfo
.cx
= (ULONG
)nWidth
;
580 vInfo
.cy
= (ULONG
)nHeight
;
582 vInfo
.cBitCount
= 24;
584 // Memory for DIB data
586 unsigned char* pucBits
;
588 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
591 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
596 // Create and set the device-dependent bitmap
598 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
599 SIZEL vSize
= {0, 0};
600 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
601 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
603 HDC hDCScreen
= ::WinOpenWindowDC(HWND_DESKTOP
);
608 hBmp
= ::GpiCreateBitmap( hPS
614 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
616 HPAL hOldPalette
= NULLHANDLE
;
617 if (rImage
.GetPalette().Ok())
619 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
621 #endif // wxUSE_PALETTE
624 // Copy image data into DIB data and then into DDB (in a loop)
626 unsigned char* pData
= rImage
.GetData();
631 unsigned char* ptdata
= pData
;
632 unsigned char* ptbits
;
634 for (n
= 0; n
< nNumDIB
; n
++)
636 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
639 // Redefine height and size of the (possibly) last smaller DIB
640 // memory is not reallocated
643 vHeader
.cy
= (DWORD
)(nHeight
);
644 vHeader
.cbImage
= nBytePerLine
* nHeight
;
647 for (j
= 0; j
< nHeight
; j
++)
649 for (i
= 0; i
< nWidth
; i
++)
651 *(ptbits
++) = *(ptdata
+ 2);
652 *(ptbits
++) = *(ptdata
+ 1);
653 *(ptbits
++) = *(ptdata
);
656 for (i
= 0; i
< nPadding
; i
++)
661 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
662 // in combination with setting the bits into the selected bitmap
664 if ((lScans
= ::GpiSetBitmapBits( hPS
665 ,0 // Start at the bottom
666 ,(LONG
)nHeight
// One line per scan
674 vError
= ::WinGetLastError(vHabmain
);
675 sError
= wxPMErrorToStr(vError
);
678 hPSScreen
= ::GpiCreatePS( vHabmain
681 ,PU_PELS
| GPIA_ASSOC
684 POINTL vPoint
[4] = { 0, nOrigin
,
686 0, 0, nWidth
, nHeight
690 ::GpiBitBlt( hPSScreen
697 ::GpiDestroyPS(hPSScreen
);
700 SetHBITMAP((WXHBITMAP
)hBmp
);
703 ::GpiSelectPalette(hPS
, hOldPalette
);
704 #endif // wxUSE_PALETTE
707 // Similarly, created an mono-bitmap for the possible mask
709 if (rImage
.HasMask())
711 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
713 vHeader
.cy
= nHeight
;
715 vHeader
.cBitCount
= 1;
716 hBmp
= ::GpiCreateBitmap( hPS
722 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
724 nHeight
= nBmpHeight
;
726 nHeight
= nSizeLimit
/ nBytePerLine
;
727 vHeader
.cy
= (DWORD
)(nHeight
);
728 vHeader
.cbImage
= nBytePerLine
* nHeight
;
731 unsigned char cRed
= rImage
.GetMaskRed();
732 unsigned char cGreen
= rImage
.GetMaskGreen();
733 unsigned char cBlue
= rImage
.GetMaskBlue();
734 unsigned char cZero
= 0;
735 unsigned char cOne
= 255;
738 for (n
= 0; n
< nNumDIB
; n
++)
740 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
743 // Redefine height and size of the (possibly) last smaller DIB
744 // memory is not reallocated
747 vHeader
.cy
= (DWORD
)(nHeight
);
748 vHeader
.cbImage
= nBytePerLine
* nHeight
;
751 for (int j
= 0; j
< nHeight
; j
++)
753 for (i
= 0; i
< nWidth
; i
++)
755 if ((*(ptdata
++) != cRed
) || (*(ptdata
++) != cGreen
) || (*(ptdata
++) != cBlue
))
768 for (i
= 0; i
< nPadding
; i
++)
771 lScans
= ::GpiSetBitmapBits( hPS
772 ,0 // Start at the bottom
773 ,(LONG
)nHeight
// One line per scan
777 hPSScreen
= ::GpiCreatePS( vHabmain
780 ,PU_PELS
| GPIA_ASSOC
782 POINTL vPoint2
[4] = { 0, nOrigin
,
784 0, 0, nWidth
, nHeight
786 ::GpiBitBlt( hPSScreen
793 ::GpiDestroyPS(hPSScreen
);
798 // Create a wxMask object
800 wxMask
* pMask
= new wxMask();
802 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
804 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
808 // Free allocated resources
810 ::GpiSetBitmap(hPS
, NULLHANDLE
);
815 } // end of wxBitmap::CreateFromImage
817 wxImage
wxBitmap::ConvertToImage() const
821 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
824 // Create an wxImage object
826 int nWidth
= GetWidth();
827 int nHeight
= GetHeight();
830 int nBytePerLine
= nWidth
* 3;
831 int nSizeDWORD
= sizeof(DWORD
);
832 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
834 unsigned char* pData
;
835 unsigned char* lpBits
;
837 BITMAPINFOHEADER2 vDIBh
;
838 BITMAPINFO2 vDIBInfo
;
840 PSZ pszData
[4] = { "Display", NULL
, NULL
, NULL
};
843 SIZEL vSizlPage
= {0,0};
846 vImage
.Create( nWidth
849 pData
= vImage
.GetData();
852 wxFAIL_MSG( wxT("could not allocate data for image") );
855 if(nLineBoundary
> 0)
857 nPadding
= nSizeDWORD
- nLineBoundary
;
858 nBytePerLine
+= nPadding
;
860 wxDisplaySize( &nDevWidth
864 // Create and fill a DIB header
866 memset(&vDIBh
, '\0', 16);
871 vDIBh
.cBitCount
= 24;
873 memset(&vDIBInfo
, '\0', 16);
875 vDIBInfo
.cx
= nWidth
;
876 vDIBInfo
.cy
= nHeight
;
877 vDIBInfo
.cPlanes
= 1;
878 vDIBInfo
.cBitCount
= 24;
880 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
883 wxFAIL_MSG(wxT("could not allocate data for DIB"));
889 // Copy data from the device-dependent bitmap to the DIB
891 hDCMem
= ::DevOpenDC( vHabmain
895 ,(PDEVOPENDATA
)pszData
898 hPSMem
= ::GpiCreatePS( vHabmain
901 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
903 hBitmap
= ::GpiCreateBitmap( hPSMem
909 ::GpiSetBitmap(hPSMem
, hBitmap
);
910 lScans
= ::GpiQueryBitmapBits( hPSMem
918 // Copy DIB data into the wxImage object
922 unsigned char* ptdata
= pData
;
923 unsigned char* ptbits
= lpBits
;
925 for (i
= 0; i
< nHeight
; i
++)
927 for (j
= 0; j
< nWidth
; j
++)
929 *(ptdata
++) = *(ptbits
+2);
930 *(ptdata
++) = *(ptbits
+1);
931 *(ptdata
++) = *(ptbits
);
936 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
939 // Similarly, set data according to the possible mask bitmap
941 if (GetMask() && GetMask()->GetMaskBitmap())
943 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
946 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
948 HDC hMemDC
= ::DevOpenDC( vHabmain
952 ,(PDEVOPENDATA
)pszData
955 HPS hMemPS
= ::GpiCreatePS( vHabmain
958 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
960 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
961 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
962 ::GpiSetBitmap(hMemPS
, hBitmap
);
963 ::GpiQueryBitmapBits( hPSMem
969 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
970 ::GpiDestroyPS(hMemPS
);
971 ::DevCloseDC(hMemDC
);
974 // Background color set to RGB(16,16,16) in consistent with wxGTK
976 unsigned char ucRed
= 16;
977 unsigned char ucGreen
= 16;
978 unsigned char ucBlue
= 16;
982 for (i
= 0; i
< nHeight
; i
++)
984 for (j
= 0; j
< nWidth
; j
++)
991 *(ptdata
++) = ucGreen
;
992 *(ptdata
++) = ucBlue
;
998 vImage
.SetMaskColour( ucRed
1002 vImage
.SetMask(TRUE
);
1006 vImage
.SetMask(FALSE
);
1010 // Free allocated resources
1012 ::GpiDestroyPS(hPSMem
);
1013 ::DevCloseDC(hDCMem
);
1016 } // end of wxBitmap::ConvertToImage
1018 // ----------------------------------------------------------------------------
1019 // sub bitmap extraction
1020 // ----------------------------------------------------------------------------
1022 wxBitmap
wxBitmap::GetSubBitmap(
1026 wxCHECK_MSG( Ok() &&
1027 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1028 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1029 (rRect
.y
+ rRect
.height
<= GetHeight()),
1030 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1032 wxBitmap
vRet( rRect
.width
1036 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1042 SIZEL vSize
= {0, 0};
1043 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1044 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1045 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1046 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1047 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1048 POINTL vPoint
[4] = { 0, 0, rRect
.width
, rRect
.height
,
1050 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
1053 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1054 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1064 // Copy mask if there is one
1068 BITMAPINFOHEADER2 vBmih
;
1070 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1071 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1072 vBmih
.cx
= rRect
.width
;
1073 vBmih
.cy
= rRect
.height
;
1075 vBmih
.cBitCount
= 1;
1077 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1084 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1085 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1087 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1088 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1097 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1098 vRet
.SetMask(pMask
);
1101 ::GpiSetBitmap(hPSSrc
, NULL
);
1102 ::GpiSetBitmap(hPSDst
, NULL
);
1103 ::GpiDestroyPS(hPSSrc
);
1104 ::GpiDestroyPS(hPSDst
);
1105 ::DevCloseDC(hDCSrc
);
1106 ::DevCloseDC(hDCDst
);
1108 } // end of wxBitmap::GetSubBitmap
1110 // ----------------------------------------------------------------------------
1111 // wxBitmap accessors
1112 // ----------------------------------------------------------------------------
1114 void wxBitmap::SetQuality(
1120 GetBitmapData()->m_nQuality
= nQ
;
1121 } // end of wxBitmap::SetQuality
1123 #if WXWIN_COMPATIBILITY_2
1124 void wxBitmap::SetOk(
1130 GetBitmapData()->m_bOk
= bOk
;
1131 } // end of wxBitmap::SetOk
1132 #endif // WXWIN_COMPATIBILITY_2
1134 void wxBitmap::SetPalette(
1135 const wxPalette
& rPalette
1140 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1141 } // end of wxBitmap::SetPalette
1143 void wxBitmap::SetMask(
1149 GetBitmapData()->m_pBitmapMask
= pMask
;
1150 } // end of wxBitmap::SetMask
1152 wxBitmap
wxBitmap::GetBitmapForDC(
1157 } // end of wxBitmap::GetBitmapForDC
1159 // ----------------------------------------------------------------------------
1161 // ----------------------------------------------------------------------------
1166 } // end of wxMask::wxMask
1168 // Construct a mask from a bitmap and a colour indicating
1169 // the transparent area
1171 const wxBitmap
& rBitmap
1172 , const wxColour
& rColour
1179 } // end of wxMask::wxMask
1181 // Construct a mask from a bitmap and a palette index indicating
1182 // the transparent area
1184 const wxBitmap
& rBitmap
1192 } // end of wxMask::wxMask
1194 // Construct a mask from a mono bitmap (copies the bitmap).
1196 const wxBitmap
& rBitmap
1201 } // end of wxMask::wxMask
1206 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1207 } // end of wxMask::~wxMask
1209 // Create a mask from a mono bitmap (copies the bitmap).
1210 bool wxMask::Create(
1211 const wxBitmap
& rBitmap
1214 BITMAPINFOHEADER2 vBmih
;
1215 SIZEL vSize
= {0, 0};
1216 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1217 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1218 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1219 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1220 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1221 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1222 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1227 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1230 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1235 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1236 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1237 vBmih
.cx
= rBitmap
.GetWidth();
1238 vBmih
.cy
= rBitmap
.GetHeight();
1240 vBmih
.cBitCount
= 1;
1242 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1249 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1250 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1259 ::GpiDestroyPS(hPSSrc
);
1260 ::GpiDestroyPS(hPSDst
);
1261 ::DevCloseDC(hDCSrc
);
1262 ::DevCloseDC(hDCDst
);
1264 } // end of wxMask::Create
1266 // Create a mask from a bitmap and a palette index indicating
1267 // the transparent area
1268 bool wxMask::Create(
1269 const wxBitmap
& rBitmap
1275 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1278 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1281 unsigned char cGreen
;
1282 unsigned char cBlue
;
1284 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1290 wxColour
vTransparentColour( cRed
1295 return (Create( rBitmap
1301 } // end of wxMask::Create
1303 // Create a mask from a bitmap and a colour indicating
1304 // the transparent area
1305 bool wxMask::Create(
1306 const wxBitmap
& rBitmap
1307 , const wxColour
& rColour
1311 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1315 BITMAPINFOHEADER2 vBmih
;
1316 SIZEL vSize
= {0, 0};
1317 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1318 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1319 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1320 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1321 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1322 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1323 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1328 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1337 // Scan the bitmap for the transparent colour and set
1338 // the corresponding pixels in the mask to BLACK and
1339 // the rest to WHITE
1342 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1343 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1344 vBmih
.cx
= rBitmap
.GetWidth();
1345 vBmih
.cy
= rBitmap
.GetHeight();
1347 vBmih
.cBitCount
= 1;
1349 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1356 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1357 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1360 // This is not very efficient, but I can't think
1361 // of a better way of doing it
1363 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1365 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1367 POINTL vPt
= {w
, h
};
1368 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1369 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1372 // Doesn't make sense to continue
1378 if (vCol
== vMaskColour
)
1380 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1381 ::GpiSetPel(hPSDst
, &vPt
);
1385 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1386 ::GpiSetPel(hPSDst
, &vPt
);
1390 ::GpiSetBitmap(hPSSrc
, NULL
);
1391 ::GpiSetBitmap(hPSDst
, NULL
);
1392 ::GpiDestroyPS(hPSSrc
);
1393 ::GpiDestroyPS(hPSDst
);
1394 ::DevCloseDC(hDCSrc
);
1395 ::DevCloseDC(hDCDst
);
1397 } // end of wxMask::Create
1399 // ----------------------------------------------------------------------------
1401 // ----------------------------------------------------------------------------
1403 bool wxBitmapHandler::Create(
1412 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1416 return(pBitmap
? Create( pBitmap
1424 bool wxBitmapHandler::Load(
1426 , const wxString
& rName
1433 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1437 return(pBitmap
? LoadFile( pBitmap
1446 bool wxBitmapHandler::Save(
1448 , const wxString
& rName
1452 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1456 return(pBitmap
? SaveFile( pBitmap
1462 bool wxBitmapHandler::Create(
1463 wxBitmap
* WXUNUSED(pBitmap
)
1464 , void* WXUNUSED(pData
)
1465 , long WXUNUSED(lType
)
1466 , int WXUNUSED(nWidth
)
1467 , int WXUNUSED(nHeight
)
1468 , int WXUNUSED(nDepth
)
1474 bool wxBitmapHandler::LoadFile(
1475 wxBitmap
* WXUNUSED(pBitmap
)
1476 , const wxString
& WXUNUSED(rName
)
1478 , long WXUNUSED(lType
)
1479 , int WXUNUSED(nDesiredWidth
)
1480 , int WXUNUSED(nDesiredHeight
)
1486 bool wxBitmapHandler::SaveFile(
1487 wxBitmap
* WXUNUSED(pBitmap
)
1488 , const wxString
& WXUNUSED(rName
)
1489 , int WXUNUSED(nType
)
1490 , const wxPalette
* WXUNUSED(pPalette
)
1496 // ----------------------------------------------------------------------------
1497 // Utility functions
1498 // ----------------------------------------------------------------------------
1499 HBITMAP
wxInvertMask(
1505 HBITMAP hBmpInvMask
= 0;
1507 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1510 // Get width/height from the bitmap if not given
1512 if (!nWidth
|| !nHeight
)
1514 BITMAPINFOHEADER2 vBmhdr
;
1516 ::GpiQueryBitmapInfoHeader( hBmpMask
1519 nWidth
= (int)vBmhdr
.cx
;
1520 nHeight
= (int)vBmhdr
.cy
;
1523 BITMAPINFOHEADER2 vBmih
;
1524 SIZEL vSize
= {0, 0};
1525 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1526 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1527 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1528 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1529 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1530 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1531 0, 0, nWidth
, nHeight
1534 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1535 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1539 vBmih
.cBitCount
= 1;
1541 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1548 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1549 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1559 ::GpiDestroyPS(hPSSrc
);
1560 ::GpiDestroyPS(hPSDst
);
1561 ::DevCloseDC(hDCSrc
);
1562 ::DevCloseDC(hDCDst
);
1565 } // end of WxWinGdi_InvertMask