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
231 nDepth
= 24; // MAX supported in PM
232 memset(&vHeader
, '\0', 16);
234 vHeader
.cx
= (USHORT
)nWidth
;
235 vHeader
.cy
= (USHORT
)nHeight
;
236 vHeader
.cPlanes
= 1L;
237 vHeader
.cBitCount
= nDepth
;
238 vHeader
.usReserved
= 0;
240 memset(&vInfo
, '\0', 16);
242 vInfo
.cx
= (USHORT
)nWidth
;
243 vInfo
.cy
= (USHORT
)nHeight
;
245 vInfo
.cBitCount
= nDepth
;
247 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
251 wxLogLastError("CreateBitmap");
255 SetHBITMAP((WXHBITMAP
)hBmp
);
256 } // end of wxBitmap::wxBitmap
270 } // end of wxBitmap::wxBitmap
288 } // end of wxBitmap::wxBitmap
291 const wxString
& rFilename
300 } // end of wxBitmap::wxBitmap
302 bool wxBitmap::Create(
309 BITMAPINFOHEADER2 vHeader
;
311 wxASSERT(vHabmain
!= NULL
);
313 m_refData
= new wxBitmapRefData
;
314 GetBitmapData()->m_nWidth
= nW
;
315 GetBitmapData()->m_nHeight
= nH
;
316 GetBitmapData()->m_nDepth
= nD
;
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
);
325 memset(&vHeader
, '\0', 16);
330 vHeader
.cBitCount
= nD
;
332 hBmp
= ::GpiCreateBitmap( hPS
347 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
348 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
349 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
354 memset(&vHeader
, '\0', 16);
359 vHeader
.cBitCount
= lBitCount
;
361 hBmp
= ::GpiCreateBitmap( hPSScreen
368 GetBitmapData()->m_nDepth
= wxDisplayDepth();
369 ::WinReleasePS(hPSScreen
);
371 SetHBITMAP((WXHBITMAP
)hBmp
);
373 #if WXWIN_COMPATIBILITY_2
374 GetBitmapData()->m_bOk
= hBmp
!= 0;
375 #endif // WXWIN_COMPATIBILITY_2
378 } // end of wxBitmap::Create
380 bool wxBitmap::CreateFromXpm(
384 #if wxUSE_IMAGE && wxUSE_XPM
387 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
389 wxXPMDecoder vDecoder
;
390 wxImage vImg
= vDecoder
.ReadData(ppData
);
392 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
394 *this = wxBitmap(vImg
);
399 } // end of wxBitmap::CreateFromXpm
401 bool wxBitmap::LoadFile(
402 const wxString
& rFilename
406 HPS hPs
= NULLHANDLE
;
410 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
416 m_refData
= new wxBitmapRefData
;
418 return(pHandler
->LoadFile( this
430 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
433 *this = wxBitmap(vImage
);
437 } // end of wxBitmap::LoadFile
439 bool wxBitmap::Create(
449 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
455 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
456 "type %d defined."), lType
);
461 m_refData
= new wxBitmapRefData
;
463 return(pHandler
->Create( this
470 } // end of wxBitmap::Create
472 bool wxBitmap::SaveFile(
473 const wxString
& rFilename
475 , const wxPalette
* pPalette
478 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
484 return pHandler
->SaveFile( this
492 // FIXME what about palette? shouldn't we use it?
493 wxImage vImage
= ConvertToImage();
498 return(vImage
.SaveFile( rFilename
502 } // end of wxBitmap::SaveFile
505 // ----------------------------------------------------------------------------
506 // wxImage-wxBitmap convertion
507 // ----------------------------------------------------------------------------
509 bool wxBitmap::CreateFromImage (
510 const wxImage
& rImage
514 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
515 m_refData
= new wxBitmapRefData();
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
;
526 if (nLineBoundary
> 0)
528 nPadding
= nSizeDWORD
- nLineBoundary
;
529 nBytePerLine
+= nPadding
;
533 // Calc the number of DIBs and heights of DIBs
537 int nHeight
= nSizeLimit
/ nBytePerLine
;
539 if (nHeight
>= nBmpHeight
)
540 nHeight
= nBmpHeight
;
543 nNumDIB
= nBmpHeight
/ nHeight
;
544 nHRemain
= nBmpHeight
% nHeight
;
550 // Set bitmap parameters
552 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
554 SetHeight(nBmpHeight
);
556 nDepth
= wxDisplayDepth();
561 // Copy the palette from the source image
563 SetPalette(rImage
.GetPalette());
564 #endif // wxUSE_PALETTE
567 // Create a DIB header
569 BITMAPINFOHEADER2 vHeader
;
571 LONG alFormats
[24]; // Max formats OS/2 PM supports
575 // Fill in the DIB header
577 memset(&vHeader
, '\0', 16);
579 vHeader
.cx
= (ULONG
)nWidth
;
580 vHeader
.cy
= (ULONG
)nHeight
;
581 vHeader
.cPlanes
= 1L;
582 vHeader
.cBitCount
= 24;
585 // Memory for DIB data
587 unsigned char* pucBits
;
589 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
592 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
597 // Create and set the device-dependent bitmap
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
);
604 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
609 ::GpiQueryDeviceBitmapFormats(hPS
, 24, alFormats
);
610 ulBitcount
= alFormats
[1]; // the best one for the device
612 ulBitcount
= 24; // MAX bits supported by PM
613 memset(&vInfo
, '\0', 16);
615 vInfo
.cx
= (ULONG
)nWidth
;
616 vInfo
.cy
= (ULONG
)nHeight
;
618 vInfo
.cBitCount
= ulBitcount
;
620 hBmp
= ::GpiCreateBitmap( hPS
626 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
628 HPAL hOldPalette
= NULLHANDLE
;
629 if (rImage
.GetPalette().Ok())
631 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
633 #endif // wxUSE_PALETTE
636 // Copy image data into DIB data and then into DDB (in a loop)
638 unsigned char* pData
= rImage
.GetData();
643 unsigned char* ptdata
= pData
;
644 unsigned char* ptbits
;
646 for (n
= 0; n
< nNumDIB
; n
++)
648 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
651 // Redefine height and size of the (possibly) last smaller DIB
652 // memory is not reallocated
655 vHeader
.cy
= (DWORD
)(nHeight
);
656 vHeader
.cbImage
= nBytePerLine
* nHeight
;
659 for (j
= 0; j
< nHeight
; j
++)
661 for (i
= 0; i
< nWidth
; i
++)
663 *(ptbits
++) = *(ptdata
+ 2);
664 *(ptbits
++) = *(ptdata
+ 1);
665 *(ptbits
++) = *(ptdata
);
668 for (i
= 0; i
< nPadding
; i
++)
673 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
674 // in combination with setting the bits into the selected bitmap
676 if ((lScans
= ::GpiSetBitmapBits( hPS
677 ,0 // Start at the bottom
678 ,(LONG
)nHeight
// One line per scan
686 vError
= ::WinGetLastError(vHabmain
);
687 sError
= wxPMErrorToStr(vError
);
690 hPSScreen
= ::GpiCreatePS( vHabmain
693 ,PU_PELS
| GPIA_ASSOC
696 POINTL vPoint
[4] = { 0, nOrigin
,
698 0, 0, nWidth
, nHeight
702 ::GpiBitBlt( hPSScreen
709 ::GpiDestroyPS(hPSScreen
);
712 SetHBITMAP((WXHBITMAP
)hBmp
);
715 ::GpiSelectPalette(hPS
, hOldPalette
);
716 #endif // wxUSE_PALETTE
719 // Similarly, created an mono-bitmap for the possible mask
721 if (rImage
.HasMask())
725 vHeader
.cy
= nHeight
;
727 vHeader
.cBitCount
= 24;
728 hBmp
= ::GpiCreateBitmap( hPS
734 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
736 nHeight
= nBmpHeight
;
738 nHeight
= nSizeLimit
/ nBytePerLine
;
739 vHeader
.cy
= (DWORD
)(nHeight
);
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;
749 for (n
= 0; n
< nNumDIB
; n
++)
751 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
754 // Redefine height and size of the (possibly) last smaller DIB
755 // memory is not reallocated
758 vHeader
.cy
= (DWORD
)(nHeight
);
761 for (int j
= 0; j
< nHeight
; j
++)
763 for (i
= 0; i
< nWidth
; i
++)
765 if ((*(ptdata
++) != cRed
) || (*(ptdata
++) != cGreen
) || (*(ptdata
++) != cBlue
))
778 for (i
= 0; i
< nPadding
; i
++)
781 lScans
= ::GpiSetBitmapBits( hPS
782 ,0 // Start at the bottom
783 ,(LONG
)nHeight
// One line per scan
787 hPSScreen
= ::GpiCreatePS( vHabmain
790 ,PU_PELS
| GPIA_ASSOC
792 POINTL vPoint2
[4] = { 0, nOrigin
,
794 0, 0, nWidth
, nHeight
796 ::GpiBitBlt( hPSScreen
803 ::GpiDestroyPS(hPSScreen
);
808 // Create a wxMask object
810 wxMask
* pMask
= new wxMask();
812 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
814 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
818 // Free allocated resources
820 ::GpiSetBitmap(hPS
, NULLHANDLE
);
822 ::DevCloseDC(hDCScreen
);
826 } // end of wxBitmap::CreateFromImage
828 wxImage
wxBitmap::ConvertToImage() const
833 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
836 // Create an wxImage object
838 int nWidth
= GetWidth();
839 int nHeight
= GetHeight();
842 int nBytePerLine
= nWidth
* 3;
843 int nSizeDWORD
= sizeof(DWORD
);
844 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
846 unsigned char* pData
;
847 unsigned char* lpBits
;
849 BITMAPINFOHEADER2 vDIBh
;
850 BITMAPINFO2 vDIBInfo
;
855 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
856 SIZEL vSizlPage
= {0,0};
858 LONG alFormats
[24]; // 24 is MAX formats supported
861 ::GpiQueryDeviceBitmapFormats(hPS
, 24, alFormats
);
862 ulBitcount
= alFormats
[1]; // the best one
863 if (ulBitcount
> 24) // PM supports a max of 24
865 vImage
.Create( nWidth
868 pData
= vImage
.GetData();
871 wxFAIL_MSG( wxT("could not allocate data for image") );
874 if(nLineBoundary
> 0)
876 nPadding
= nSizeDWORD
- nLineBoundary
;
877 nBytePerLine
+= nPadding
;
879 wxDisplaySize( &nDevWidth
883 // Create and fill a DIB header
885 memset(&vDIBh
, '\0', 16);
890 vDIBh
.cBitCount
= 24;
892 memset(&vDIBInfo
, '\0', 16);
894 vDIBInfo
.cx
= nWidth
;
895 vDIBInfo
.cy
= nHeight
;
896 vDIBInfo
.cPlanes
= 1;
897 vDIBInfo
.cBitCount
= ulBitcount
;
899 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
902 wxFAIL_MSG(wxT("could not allocate data for DIB"));
908 // May already be selected into a PS
910 if ((pDC
= GetSelectedInto()) != NULL
)
912 hPSMem
= pDC
->GetHPS();
916 hDCMem
= ::DevOpenDC( vHabmain
923 hPSMem
= ::GpiCreatePS( vHabmain
926 ,PU_PELS
| GPIA_ASSOC
928 hBitmap
= (HBITMAP
)GetHBITMAP();
929 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
934 vError
= ::WinGetLastError(vHabmain
);
935 sError
= wxPMErrorToStr(vError
);
940 // Copy data from the device-dependent bitmap to the DIB
942 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
952 vError
= ::WinGetLastError(vHabmain
);
953 sError
= wxPMErrorToStr(vError
);
957 // Copy DIB data into the wxImage object
961 unsigned char* ptdata
= pData
;
962 unsigned char* ptbits
= lpBits
;
964 for (i
= 0; i
< nHeight
; i
++)
966 for (j
= 0; j
< nWidth
; j
++)
968 *(ptdata
++) = *(ptbits
+2);
969 *(ptdata
++) = *(ptbits
+1);
970 *(ptdata
++) = *(ptbits
);
975 if ((pDC
= GetSelectedInto()) == NULL
)
977 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
978 ::GpiDestroyPS(hPSMem
);
979 ::DevCloseDC(hDCMem
);
983 // Similarly, set data according to the possible mask bitmap
985 if (GetMask() && GetMask()->GetMaskBitmap())
987 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
990 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
992 HDC hMemDC
= ::DevOpenDC( vHabmain
999 HPS hMemPS
= ::GpiCreatePS( vHabmain
1002 ,PU_PELS
| GPIA_ASSOC
1004 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1005 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1006 ::GpiSetBitmap(hMemPS
, hBitmap
);
1007 ::GpiQueryBitmapBits( hPSMem
1013 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1014 ::GpiDestroyPS(hMemPS
);
1015 ::DevCloseDC(hMemDC
);
1018 // Background color set to RGB(16,16,16) in consistent with wxGTK
1020 unsigned char ucRed
= 16;
1021 unsigned char ucGreen
= 16;
1022 unsigned char ucBlue
= 16;
1026 for (i
= 0; i
< nHeight
; i
++)
1028 for (j
= 0; j
< nWidth
; j
++)
1034 *(ptdata
++) = ucRed
;
1035 *(ptdata
++) = ucGreen
;
1036 *(ptdata
++) = ucBlue
;
1042 vImage
.SetMaskColour( ucRed
1046 vImage
.SetMask(TRUE
);
1050 vImage
.SetMask(FALSE
);
1054 // Free allocated resources
1058 } // end of wxBitmap::ConvertToImage
1060 // ----------------------------------------------------------------------------
1061 // sub bitmap extraction
1062 // ----------------------------------------------------------------------------
1064 wxBitmap
wxBitmap::GetSubBitmap(
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") );
1074 wxBitmap
vRet( rRect
.width
1078 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
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
,
1092 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
1095 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1096 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1106 // Copy mask if there is one
1110 BITMAPINFOHEADER2 vBmih
;
1112 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1113 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1114 vBmih
.cx
= rRect
.width
;
1115 vBmih
.cy
= rRect
.height
;
1117 vBmih
.cBitCount
= 1;
1119 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1126 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1127 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1129 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1130 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1139 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1140 vRet
.SetMask(pMask
);
1143 ::GpiSetBitmap(hPSSrc
, NULL
);
1144 ::GpiSetBitmap(hPSDst
, NULL
);
1145 ::GpiDestroyPS(hPSSrc
);
1146 ::GpiDestroyPS(hPSDst
);
1147 ::DevCloseDC(hDCSrc
);
1148 ::DevCloseDC(hDCDst
);
1150 } // end of wxBitmap::GetSubBitmap
1152 // ----------------------------------------------------------------------------
1153 // wxBitmap accessors
1154 // ----------------------------------------------------------------------------
1156 void wxBitmap::SetQuality(
1162 GetBitmapData()->m_nQuality
= nQ
;
1163 } // end of wxBitmap::SetQuality
1165 #if WXWIN_COMPATIBILITY_2
1166 void wxBitmap::SetOk(
1172 GetBitmapData()->m_bOk
= bOk
;
1173 } // end of wxBitmap::SetOk
1174 #endif // WXWIN_COMPATIBILITY_2
1176 void wxBitmap::SetPalette(
1177 const wxPalette
& rPalette
1182 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1183 } // end of wxBitmap::SetPalette
1185 void wxBitmap::SetMask(
1191 GetBitmapData()->m_pBitmapMask
= pMask
;
1192 } // end of wxBitmap::SetMask
1194 wxBitmap
wxBitmap::GetBitmapForDC(
1199 } // end of wxBitmap::GetBitmapForDC
1201 // ----------------------------------------------------------------------------
1203 // ----------------------------------------------------------------------------
1208 } // end of wxMask::wxMask
1210 // Construct a mask from a bitmap and a colour indicating
1211 // the transparent area
1213 const wxBitmap
& rBitmap
1214 , const wxColour
& rColour
1221 } // end of wxMask::wxMask
1223 // Construct a mask from a bitmap and a palette index indicating
1224 // the transparent area
1226 const wxBitmap
& rBitmap
1234 } // end of wxMask::wxMask
1236 // Construct a mask from a mono bitmap (copies the bitmap).
1238 const wxBitmap
& rBitmap
1243 } // end of wxMask::wxMask
1248 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1249 } // end of wxMask::~wxMask
1251 // Create a mask from a mono bitmap (copies the bitmap).
1252 bool wxMask::Create(
1253 const wxBitmap
& rBitmap
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()
1269 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1272 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1277 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1278 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1279 vBmih
.cx
= rBitmap
.GetWidth();
1280 vBmih
.cy
= rBitmap
.GetHeight();
1282 vBmih
.cBitCount
= 1;
1284 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1291 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1292 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1301 ::GpiDestroyPS(hPSSrc
);
1302 ::GpiDestroyPS(hPSDst
);
1303 ::DevCloseDC(hDCSrc
);
1304 ::DevCloseDC(hDCDst
);
1306 } // end of wxMask::Create
1308 // Create a mask from a bitmap and a palette index indicating
1309 // the transparent area
1310 bool wxMask::Create(
1311 const wxBitmap
& rBitmap
1317 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1320 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1323 unsigned char cGreen
;
1324 unsigned char cBlue
;
1326 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1332 wxColour
vTransparentColour( cRed
1337 return (Create( rBitmap
1343 } // end of wxMask::Create
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
1353 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
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()
1370 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
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
1384 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1385 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1386 vBmih
.cx
= rBitmap
.GetWidth();
1387 vBmih
.cy
= rBitmap
.GetHeight();
1389 vBmih
.cBitCount
= 1;
1391 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1398 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1399 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1402 // This is not very efficient, but I can't think
1403 // of a better way of doing it
1405 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1407 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1409 POINTL vPt
= {w
, h
};
1410 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1411 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1414 // Doesn't make sense to continue
1420 if (vCol
== vMaskColour
)
1422 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1423 ::GpiSetPel(hPSDst
, &vPt
);
1427 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1428 ::GpiSetPel(hPSDst
, &vPt
);
1432 ::GpiSetBitmap(hPSSrc
, NULL
);
1433 ::GpiSetBitmap(hPSDst
, NULL
);
1434 ::GpiDestroyPS(hPSSrc
);
1435 ::GpiDestroyPS(hPSDst
);
1436 ::DevCloseDC(hDCSrc
);
1437 ::DevCloseDC(hDCDst
);
1439 } // end of wxMask::Create
1441 // ----------------------------------------------------------------------------
1443 // ----------------------------------------------------------------------------
1445 bool wxBitmapHandler::Create(
1454 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1458 return(pBitmap
? Create( pBitmap
1466 bool wxBitmapHandler::Load(
1468 , const wxString
& rName
1475 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1479 return(pBitmap
? LoadFile( pBitmap
1488 bool wxBitmapHandler::Save(
1490 , const wxString
& rName
1494 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1498 return(pBitmap
? SaveFile( pBitmap
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
)
1516 bool wxBitmapHandler::LoadFile(
1517 wxBitmap
* WXUNUSED(pBitmap
)
1518 , const wxString
& WXUNUSED(rName
)
1520 , long WXUNUSED(lType
)
1521 , int WXUNUSED(nDesiredWidth
)
1522 , int WXUNUSED(nDesiredHeight
)
1528 bool wxBitmapHandler::SaveFile(
1529 wxBitmap
* WXUNUSED(pBitmap
)
1530 , const wxString
& WXUNUSED(rName
)
1531 , int WXUNUSED(nType
)
1532 , const wxPalette
* WXUNUSED(pPalette
)
1538 // ----------------------------------------------------------------------------
1539 // Utility functions
1540 // ----------------------------------------------------------------------------
1541 HBITMAP
wxInvertMask(
1547 HBITMAP hBmpInvMask
= 0;
1549 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1552 // Get width/height from the bitmap if not given
1554 if (!nWidth
|| !nHeight
)
1556 BITMAPINFOHEADER2 vBmhdr
;
1558 ::GpiQueryBitmapInfoHeader( hBmpMask
1561 nWidth
= (int)vBmhdr
.cx
;
1562 nHeight
= (int)vBmhdr
.cy
;
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
1576 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1577 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1581 vBmih
.cBitCount
= 1;
1583 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1590 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1591 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1601 ::GpiDestroyPS(hPSSrc
);
1602 ::GpiDestroyPS(hPSDst
);
1603 ::DevCloseDC(hDCSrc
);
1604 ::DevCloseDC(hDCDst
);
1607 } // end of WxWinGdi_InvertMask