1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/bitmap.cpp
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #include "wx/bitmap.h"
23 #include "wx/palette.h"
24 #include "wx/dcmemory.h"
30 #include "wx/os2/private.h"
32 #include "wx/xpmdecod.h"
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
39 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 wxBitmapRefData::wxBitmapRefData()
54 m_pSelectedInto
= NULL
;
57 m_hBitmap
= (WXHBITMAP
) NULL
;
58 } // end of wxBitmapRefData::wxBitmapRefData
60 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData
&tocopy
)
62 m_nQuality
= tocopy
.m_nQuality
;
63 m_pSelectedInto
= NULL
; // don't copy this
64 m_nNumColors
= tocopy
.m_nNumColors
;
67 if (tocopy
.m_pBitmapMask
)
68 m_pBitmapMask
= new wxMask(*tocopy
.m_pBitmapMask
);
70 // TODO: how to copy an HBITMAP?
71 m_hBitmap
= tocopy
.m_hBitmap
;
74 void wxBitmapRefData::Free()
76 if ( m_pSelectedInto
)
78 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
82 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
84 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
92 } // end of wxBitmapRefData::Free
94 // ----------------------------------------------------------------------------
96 // ----------------------------------------------------------------------------
98 wxObjectRefData
* wxBitmap::CreateRefData() const
100 return new wxBitmapRefData
;
103 wxObjectRefData
* wxBitmap::CloneRefData(const wxObjectRefData
* data
) const
105 return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData
*, data
));
108 // this function should be called from all wxBitmap ctors
109 void wxBitmap::Init()
113 // True for all bitmaps created from bits, wxImages, Xpms
115 } // end of wxBitmap::Init
117 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
119 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
120 POINTERINFO SIconInfo
;
122 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
124 wxLogLastError(wxT("WinQueryPointerInfo"));
127 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
129 m_refData
= pRefData
;
131 int nWidth
= rIcon
.GetWidth();
132 int nHeight
= rIcon
.GetHeight();
134 pRefData
->m_nWidth
= nWidth
;
135 pRefData
->m_nHeight
= nHeight
;
136 pRefData
->m_nDepth
= wxDisplayDepth();
138 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
140 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
142 pMask
->SetMaskBitmap(GetHBITMAP());
146 } // end of wxBitmap::CopyFromIconOrCursor
148 bool wxBitmap::CopyFromCursor(
149 const wxCursor
& rCursor
156 return(CopyFromIconOrCursor(rCursor
));
157 } // end of wxBitmap::CopyFromCursor
159 bool wxBitmap::CopyFromIcon(
168 return CopyFromIconOrCursor(rIcon
);
169 } // end of wxBitmap::CopyFromIcon
171 wxBitmap::~wxBitmap()
173 } // end of wxBitmap::~wxBitmap
184 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
185 BITMAPINFOHEADER2 vHeader
;
189 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
190 SIZEL vSize
= {0, 0};
193 wxASSERT(vHabmain
!= NULL
);
195 m_refData
= pRefData
;
197 pRefData
->m_nWidth
= nWidth
;
198 pRefData
->m_nHeight
= nHeight
;
199 pRefData
->m_nDepth
= nDepth
;
200 pRefData
->m_nNumColors
= 0;
201 pRefData
->m_pSelectedInto
= NULL
;
203 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
204 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
207 wxLogLastError(wxT("GpiCreatePS Failure"));
213 // We assume that it is in XBM format which is not quite the same as
214 // the format CreateBitmap() wants because the order of bytes in the
217 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
218 const size_t nPadding
= nBytesPerLine
% 2;
219 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
220 const char* pzSrc
= zBits
;
224 pzData
= (char *)malloc(nLen
);
226 char* pzDst
= pzData
;
228 for (nRows
= 0; nRows
< nHeight
; nRows
++)
230 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
232 unsigned char ucVal
= *pzSrc
++;
233 unsigned char ucReversed
= 0;
236 for (nBits
= 0; nBits
< 8; nBits
++)
239 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
242 *pzDst
++ = ucReversed
;
251 // Bits should already be in Windows standard format
253 pzData
= (char *)zBits
; // const_cast is harmless
257 nDepth
= 24; // MAX supported in PM
258 memset(&vHeader
, '\0', 16);
260 vHeader
.cx
= (USHORT
)nWidth
;
261 vHeader
.cy
= (USHORT
)nHeight
;
262 vHeader
.cPlanes
= 1L;
263 vHeader
.cBitCount
= (USHORT
)nDepth
;
264 vHeader
.usReserved
= 0;
266 memset(&vInfo
, '\0', 16);
268 vInfo
.cx
= (USHORT
)nWidth
;
269 vInfo
.cy
= (USHORT
)nHeight
;
271 vInfo
.cBitCount
= (USHORT
)nDepth
;
273 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
277 wxLogLastError(wxT("CreateBitmap"));
281 SetHBITMAP((WXHBITMAP
)hBmp
);
282 } // end of wxBitmap::wxBitmap
295 } // end of wxBitmap::wxBitmap
313 } // end of wxBitmap::wxBitmap
325 } // end of wxBitmap::wxBitmap
327 bool wxBitmap::Create(
334 BITMAPINFOHEADER2 vHeader
;
336 wxASSERT(vHabmain
!= NULL
);
338 m_refData
= new wxBitmapRefData
;
339 GetBitmapData()->m_nWidth
= nW
;
340 GetBitmapData()->m_nHeight
= nH
;
341 GetBitmapData()->m_nDepth
= nD
;
344 // Xpms and bitmaps from other images can also be mono's, but only
345 // mono's need help changing their colors with MemDC changes
349 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
350 SIZEL vSize
= {0, 0};
351 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
352 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
356 memset(&vHeader
, '\0', 16);
361 vHeader
.cBitCount
= 24; //nD;
363 hBmp
= ::GpiCreateBitmap( hPS
378 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
379 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
380 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
385 memset(&vHeader
, '\0', 16);
390 vHeader
.cBitCount
= (USHORT
)lBitCount
;
392 hBmp
= ::GpiCreateBitmap( hPSScreen
399 GetBitmapData()->m_nDepth
= wxDisplayDepth();
400 ::WinReleasePS(hPSScreen
);
402 SetHBITMAP((WXHBITMAP
)hBmp
);
405 } // end of wxBitmap::Create
407 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
411 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
415 m_refData
= new wxBitmapRefData
;
417 return handler
->LoadFile(this, filename
, type
, -1, -1);
420 else // no bitmap handler found
423 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
425 *this = wxBitmap(image
);
430 #endif // wxUSE_IMAGE
435 bool wxBitmap::LoadFile(
442 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
448 m_refData
= new wxBitmapRefData
;
450 return(pHandler
->LoadFile( this
461 } // end of wxBitmap::LoadFile
463 bool wxBitmap::Create(
473 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
479 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
484 m_refData
= new wxBitmapRefData
;
486 return(pHandler
->Create( this
493 } // end of wxBitmap::Create
495 bool wxBitmap::SaveFile(
496 const wxString
& rFilename
498 , const wxPalette
* pPalette
501 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
507 return pHandler
->SaveFile( this
515 // FIXME what about palette? shouldn't we use it?
516 wxImage vImage
= ConvertToImage();
521 return(vImage
.SaveFile( rFilename
525 } // end of wxBitmap::SaveFile
528 // ----------------------------------------------------------------------------
529 // wxImage-wxBitmap conversion
530 // ----------------------------------------------------------------------------
532 bool wxBitmap::CreateFromImage (
533 const wxImage
& rImage
537 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
538 m_refData
= new wxBitmapRefData();
540 int nSizeLimit
= 1024 * 768 * 3;
541 int nWidth
= rImage
.GetWidth();
542 int nBmpHeight
= rImage
.GetHeight();
543 int nBytePerLine
= nWidth
* 3;
544 int nSizeDWORD
= sizeof(DWORD
);
545 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
548 if (nLineBoundary
> 0)
550 nPadding
= nSizeDWORD
- nLineBoundary
;
551 nBytePerLine
+= nPadding
;
555 // Calc the number of DIBs and heights of DIBs
559 int nHeight
= nSizeLimit
/ nBytePerLine
;
561 if (nHeight
>= nBmpHeight
)
562 nHeight
= nBmpHeight
;
565 nNumDIB
= nBmpHeight
/ nHeight
;
566 nHRemain
= nBmpHeight
% nHeight
;
572 // Set bitmap parameters
574 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
576 SetHeight(nBmpHeight
);
582 nDepth
= wxDisplayDepth();
587 // Copy the palette from the source image
589 SetPalette(rImage
.GetPalette());
590 #endif // wxUSE_PALETTE
593 // Create a DIB header
595 BITMAPINFOHEADER2 vHeader
;
599 // Fill in the DIB header
601 memset(&vHeader
, '\0', 16);
603 vHeader
.cx
= (ULONG
)nWidth
;
604 vHeader
.cy
= (ULONG
)nHeight
;
605 vHeader
.cPlanes
= 1L;
606 vHeader
.cBitCount
= 24;
609 // Memory for DIB data
611 unsigned char* pucBits
;
613 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
616 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
619 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
622 // Create and set the device-dependent bitmap
624 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
625 SIZEL vSize
= {0, 0};
626 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
627 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
629 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
634 memset(&vInfo
, '\0', 16);
636 vInfo
.cx
= (ULONG
)nWidth
;
637 vInfo
.cy
= (ULONG
)nHeight
;
639 vInfo
.cBitCount
= 24; // Set to desired count going in
641 hBmp
= ::GpiCreateBitmap( hPS
648 HPAL hOldPalette
= NULLHANDLE
;
649 if (rImage
.GetPalette().Ok())
651 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
653 #endif // wxUSE_PALETTE
656 // Copy image data into DIB data and then into DDB (in a loop)
658 unsigned char* pData
= rImage
.GetData();
663 unsigned char* ptdata
= pData
;
664 unsigned char* ptbits
;
666 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
671 vError
= ::WinGetLastError(vHabmain
);
672 sError
= wxPMErrorToStr(vError
);
674 for (n
= 0; n
< nNumDIB
; n
++)
676 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
679 // Redefine height and size of the (possibly) last smaller DIB
680 // memory is not reallocated
683 vHeader
.cy
= (DWORD
)(nHeight
);
684 vHeader
.cbImage
= nBytePerLine
* nHeight
;
687 for (j
= 0; j
< nHeight
; j
++)
689 for (i
= 0; i
< nWidth
; i
++)
691 *(ptbits
++) = *(ptdata
+ 2);
692 *(ptbits
++) = *(ptdata
+ 1);
693 *(ptbits
++) = *(ptdata
);
696 for (i
= 0; i
< nPadding
; i
++)
701 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
702 // in combination with setting the bits into the selected bitmap
704 if ((lScans
= ::GpiSetBitmapBits( hPS
705 ,0 // Start at the bottom
706 ,(LONG
)nHeight
// One line per scan
714 vError
= ::WinGetLastError(vHabmain
);
715 sError
= wxPMErrorToStr(vError
);
717 hPSScreen
= ::GpiCreatePS( vHabmain
720 ,PU_PELS
| GPIA_ASSOC
723 POINTL vPoint
[4] = { {0, nOrigin
},
725 {0, 0}, {nWidth
, nHeight
}
729 ::GpiBitBlt( hPSScreen
736 ::GpiDestroyPS(hPSScreen
);
739 SetHBITMAP((WXHBITMAP
)hBmp
);
742 ::GpiSelectPalette(hPS
, hOldPalette
);
743 #endif // wxUSE_PALETTE
746 // Similarly, created an mono-bitmap for the possible mask
748 if (rImage
.HasMask())
752 vHeader
.cy
= nHeight
;
754 vHeader
.cBitCount
= 24;
755 hBmp
= ::GpiCreateBitmap( hPS
761 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
763 nHeight
= nBmpHeight
;
765 nHeight
= nSizeLimit
/ nBytePerLine
;
766 vHeader
.cy
= (DWORD
)(nHeight
);
769 unsigned char cRed
= rImage
.GetMaskRed();
770 unsigned char cGreen
= rImage
.GetMaskGreen();
771 unsigned char cBlue
= rImage
.GetMaskBlue();
772 unsigned char cZero
= 0;
773 unsigned char cOne
= 255;
776 for (n
= 0; n
< nNumDIB
; n
++)
778 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
781 // Redefine height and size of the (possibly) last smaller DIB
782 // memory is not reallocated
785 vHeader
.cy
= (DWORD
)(nHeight
);
786 vHeader
.cbImage
= nBytePerLine
* nHeight
;
789 for (int j
= 0; j
< nHeight
; j
++)
791 for (i
= 0; i
< nWidth
; i
++)
793 unsigned char cRedImage
= (*(ptdata
++)) ;
794 unsigned char cGreenImage
= (*(ptdata
++)) ;
795 unsigned char cBlueImage
= (*(ptdata
++)) ;
797 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
810 for (i
= 0; i
< nPadding
; i
++)
813 lScans
= ::GpiSetBitmapBits( hPS
814 ,0 // Start at the bottom
815 ,(LONG
)nHeight
// One line per scan
819 hPSScreen
= ::GpiCreatePS( vHabmain
822 ,PU_PELS
| GPIA_ASSOC
824 POINTL vPoint2
[4] = { {0, nOrigin
},
826 {0, 0}, {nWidth
, nHeight
}
828 ::GpiBitBlt( hPSScreen
835 ::GpiDestroyPS(hPSScreen
);
840 // Create a wxMask object
842 wxMask
* pMask
= new wxMask();
844 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
846 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
850 // Free allocated resources
852 ::GpiSetBitmap(hPS
, NULLHANDLE
);
854 ::DevCloseDC(hDCScreen
);
858 } // end of wxBitmap::CreateFromImage
860 wxImage
wxBitmap::ConvertToImage() const
865 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
868 // Create an wxImage object
870 int nWidth
= GetWidth();
871 int nHeight
= GetHeight();
874 int nBytePerLine
= nWidth
* 3;
875 int nSizeDWORD
= sizeof(DWORD
);
876 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
878 unsigned char* pData
;
879 unsigned char* lpBits
;
881 BITMAPINFOHEADER2 vDIBh
;
882 BITMAPINFO2 vDIBInfo
;
886 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
887 SIZEL vSizlPage
= {0,0};
888 HDC hDCMem
= NULLHANDLE
;
890 vImage
.Create( nWidth
893 pData
= vImage
.GetData();
896 wxFAIL_MSG( wxT("could not allocate data for image") );
899 if(nLineBoundary
> 0)
901 nPadding
= nSizeDWORD
- nLineBoundary
;
902 nBytePerLine
+= nPadding
;
904 wxDisplaySize( &nDevWidth
908 // Create and fill a DIB header
910 memset(&vDIBh
, '\0', 16);
915 vDIBh
.cBitCount
= 24;
917 memset(&vDIBInfo
, '\0', 16);
919 vDIBInfo
.cx
= nWidth
;
920 vDIBInfo
.cy
= nHeight
;
921 vDIBInfo
.cPlanes
= 1;
922 vDIBInfo
.cBitCount
= 24;
924 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
927 wxFAIL_MSG(wxT("could not allocate data for DIB"));
931 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
932 hBitmap
= (HBITMAP
)GetHBITMAP();
935 // May already be selected into a PS
937 if ((pDC
= GetSelectedInto()) != NULL
)
939 hPSMem
= pDC
->GetHPS();
943 hDCMem
= ::DevOpenDC( vHabmain
950 hPSMem
= ::GpiCreatePS( vHabmain
953 ,PU_PELS
| GPIA_ASSOC
956 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
961 vError
= ::WinGetLastError(vHabmain
);
962 sError
= wxPMErrorToStr(vError
);
966 // Copy data from the device-dependent bitmap to the DIB
968 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
978 vError
= ::WinGetLastError(vHabmain
);
979 sError
= wxPMErrorToStr(vError
);
983 // Copy DIB data into the wxImage object
987 unsigned char* ptdata
= pData
;
988 unsigned char* ptbits
= lpBits
;
990 for (i
= 0; i
< nHeight
; i
++)
992 for (j
= 0; j
< nWidth
; j
++)
994 *(ptdata
++) = *(ptbits
+2);
995 *(ptdata
++) = *(ptbits
+1);
996 *(ptdata
++) = *(ptbits
);
1001 if ((pDC
= GetSelectedInto()) == NULL
)
1003 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
1004 ::GpiDestroyPS(hPSMem
);
1005 ::DevCloseDC(hDCMem
);
1009 // Similarly, set data according to the possible mask bitmap
1011 if (GetMask() && GetMask()->GetMaskBitmap())
1013 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1016 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1018 HDC hMemDC
= ::DevOpenDC( vHabmain
1022 ,(PDEVOPENDATA
)&vDop
1025 HPS hMemPS
= ::GpiCreatePS( vHabmain
1028 ,PU_PELS
| GPIA_ASSOC
1030 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1031 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1032 ::GpiSetBitmap(hMemPS
, hBitmap
);
1033 ::GpiQueryBitmapBits( hPSMem
1039 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1040 ::GpiDestroyPS(hMemPS
);
1041 ::DevCloseDC(hMemDC
);
1044 // Background color set to RGB(16,16,16) in consistent with wxGTK
1046 unsigned char ucRed
= 16;
1047 unsigned char ucGreen
= 16;
1048 unsigned char ucBlue
= 16;
1052 for (i
= 0; i
< nHeight
; i
++)
1054 for (j
= 0; j
< nWidth
; j
++)
1060 *(ptdata
++) = ucRed
;
1061 *(ptdata
++) = ucGreen
;
1062 *(ptdata
++) = ucBlue
;
1068 vImage
.SetMaskColour( ucRed
1072 vImage
.SetMask(true);
1076 vImage
.SetMask(false);
1080 // Free allocated resources
1084 } // end of wxBitmap::ConvertToImage
1086 // ----------------------------------------------------------------------------
1087 // sub bitmap extraction
1088 // ----------------------------------------------------------------------------
1090 wxBitmap
wxBitmap::GetSubBitmap(
1094 wxCHECK_MSG( Ok() &&
1095 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1096 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1097 (rRect
.y
+ rRect
.height
<= GetHeight()),
1098 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1100 wxBitmap
vRet( rRect
.width
1104 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1110 SIZEL vSize
= {0, 0};
1111 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1112 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1113 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1114 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1115 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1116 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1118 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1121 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1122 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1132 // Copy mask if there is one
1136 BITMAPINFOHEADER2 vBmih
;
1138 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1139 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1140 vBmih
.cx
= rRect
.width
;
1141 vBmih
.cy
= rRect
.height
;
1143 vBmih
.cBitCount
= 24;
1145 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1152 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1153 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1155 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1156 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1165 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1166 vRet
.SetMask(pMask
);
1169 ::GpiSetBitmap(hPSSrc
, NULL
);
1170 ::GpiSetBitmap(hPSDst
, NULL
);
1171 ::GpiDestroyPS(hPSSrc
);
1172 ::GpiDestroyPS(hPSDst
);
1173 ::DevCloseDC(hDCSrc
);
1174 ::DevCloseDC(hDCDst
);
1176 } // end of wxBitmap::GetSubBitmap
1178 // ----------------------------------------------------------------------------
1179 // wxBitmap accessors
1180 // ----------------------------------------------------------------------------
1182 void wxBitmap::SetQuality(
1188 GetBitmapData()->m_nQuality
= nQ
;
1189 } // end of wxBitmap::SetQuality
1191 void wxBitmap::SetPalette(
1192 const wxPalette
& rPalette
1197 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1198 } // end of wxBitmap::SetPalette
1200 void wxBitmap::SetMask(
1206 GetBitmapData()->m_pBitmapMask
= pMask
;
1207 } // end of wxBitmap::SetMask
1209 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1212 } // end of wxBitmap::GetBitmapForDC
1214 // ----------------------------------------------------------------------------
1216 // ----------------------------------------------------------------------------
1221 } // end of wxMask::wxMask
1223 wxMask::wxMask(const wxMask
& tocopy
)
1225 // TODO: how to copy a WXHBITMAP?
1226 m_hMaskBitmap
= tocopy
.m_hMaskBitmap
;
1227 } // end of wxMask::wxMask
1229 // Construct a mask from a bitmap and a colour indicating
1230 // the transparent area
1232 const wxBitmap
& rBitmap
1233 , const wxColour
& rColour
1240 } // end of wxMask::wxMask
1242 // Construct a mask from a bitmap and a palette index indicating
1243 // the transparent area
1245 const wxBitmap
& rBitmap
1253 } // end of wxMask::wxMask
1255 // Construct a mask from a mono bitmap (copies the bitmap).
1257 const wxBitmap
& rBitmap
1262 } // end of wxMask::wxMask
1267 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1268 } // end of wxMask::~wxMask
1270 // Create a mask from a mono bitmap (copies the bitmap).
1271 bool wxMask::Create(
1272 const wxBitmap
& rBitmap
1275 BITMAPINFOHEADER2 vBmih
;
1276 SIZEL vSize
= {0, 0};
1277 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1278 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1279 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1280 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1281 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1282 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1283 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1288 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1291 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1296 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1297 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1298 vBmih
.cx
= rBitmap
.GetWidth();
1299 vBmih
.cy
= rBitmap
.GetHeight();
1301 vBmih
.cBitCount
= 24;
1303 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1310 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1311 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1320 ::GpiDestroyPS(hPSSrc
);
1321 ::GpiDestroyPS(hPSDst
);
1322 ::DevCloseDC(hDCSrc
);
1323 ::DevCloseDC(hDCDst
);
1325 } // end of wxMask::Create
1327 // Create a mask from a bitmap and a palette index indicating
1328 // the transparent area
1329 bool wxMask::Create(
1330 const wxBitmap
& rBitmap
1336 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1339 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1342 unsigned char cGreen
;
1343 unsigned char cBlue
;
1345 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1351 wxColour
vTransparentColour( cRed
1356 return (Create( rBitmap
1362 } // end of wxMask::Create
1364 // Create a mask from a bitmap and a colour indicating
1365 // the transparent area
1366 bool wxMask::Create(
1367 const wxBitmap
& rBitmap
1368 , const wxColour
& rColour
1372 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1376 BITMAPINFOHEADER2 vBmih
;
1377 SIZEL vSize
= {0, 0};
1378 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1379 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1380 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1381 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1382 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1386 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1395 // Scan the bitmap for the transparent colour and set
1396 // the corresponding pixels in the mask to BLACK and
1397 // the rest to WHITE
1400 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1401 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1402 vBmih
.cx
= rBitmap
.GetWidth();
1403 vBmih
.cy
= rBitmap
.GetHeight();
1405 vBmih
.cBitCount
= 1;
1407 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1414 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1415 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1418 // This is not very efficient, but I can't think
1419 // of a better way of doing it
1421 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1423 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1425 POINTL vPt
= {w
, h
};
1426 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1427 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1430 // Doesn't make sense to continue
1436 if (vCol
== vMaskColour
)
1438 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1439 ::GpiSetPel(hPSDst
, &vPt
);
1443 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1444 ::GpiSetPel(hPSDst
, &vPt
);
1448 ::GpiSetBitmap(hPSSrc
, NULL
);
1449 ::GpiSetBitmap(hPSDst
, NULL
);
1450 ::GpiDestroyPS(hPSSrc
);
1451 ::GpiDestroyPS(hPSDst
);
1452 ::DevCloseDC(hDCSrc
);
1453 ::DevCloseDC(hDCDst
);
1455 } // end of wxMask::Create
1457 // ----------------------------------------------------------------------------
1459 // ----------------------------------------------------------------------------
1461 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1463 long WXUNUSED(lFlags
),
1468 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1472 return(pBitmap
? Create( pBitmap
1480 bool wxBitmapHandler::Load(
1488 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1492 return(pBitmap
? LoadFile( pBitmap
1500 bool wxBitmapHandler::Save(
1502 , const wxString
& rName
1506 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1510 return(pBitmap
? SaveFile( pBitmap
1516 bool wxBitmapHandler::Create(
1517 wxBitmap
* WXUNUSED(pBitmap
)
1518 , const void* WXUNUSED(pData
)
1519 , long WXUNUSED(lType
)
1520 , int WXUNUSED(nWidth
)
1521 , int WXUNUSED(nHeight
)
1522 , int WXUNUSED(nDepth
)
1528 bool wxBitmapHandler::LoadFile(
1529 wxBitmap
* WXUNUSED(pBitmap
)
1531 , long WXUNUSED(lType
)
1532 , int WXUNUSED(nDesiredWidth
)
1533 , int WXUNUSED(nDesiredHeight
)
1539 bool wxBitmapHandler::LoadFile(
1540 wxBitmap
* WXUNUSED(pBitmap
)
1541 , const wxString
& WXUNUSED(rName
)
1542 , long WXUNUSED(lType
)
1543 , int WXUNUSED(nDesiredWidth
)
1544 , int WXUNUSED(nDesiredHeight
)
1550 bool wxBitmapHandler::SaveFile(
1551 wxBitmap
* WXUNUSED(pBitmap
)
1552 , const wxString
& WXUNUSED(rName
)
1553 , int WXUNUSED(nType
)
1554 , const wxPalette
* WXUNUSED(pPalette
)
1560 // ----------------------------------------------------------------------------
1561 // Utility functions
1562 // ----------------------------------------------------------------------------
1563 HBITMAP
wxInvertMask(
1569 HBITMAP hBmpInvMask
= 0;
1571 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1574 // Get width/height from the bitmap if not given
1576 if (!nWidth
|| !nHeight
)
1578 BITMAPINFOHEADER2 vBmhdr
;
1580 ::GpiQueryBitmapInfoHeader( hBmpMask
1583 nWidth
= (int)vBmhdr
.cx
;
1584 nHeight
= (int)vBmhdr
.cy
;
1587 BITMAPINFOHEADER2 vBmih
;
1588 SIZEL vSize
= {0, 0};
1589 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1590 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1591 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1592 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1593 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1594 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1595 {0, 0}, {nWidth
, nHeight
}
1598 memset(&vBmih
, '\0', 16);
1603 vBmih
.cBitCount
= 24;
1605 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1612 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1613 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1623 ::GpiDestroyPS(hPSSrc
);
1624 ::GpiDestroyPS(hPSDst
);
1625 ::DevCloseDC(hDCSrc
);
1626 ::DevCloseDC(hDCDst
);
1629 } // end of WxWinGdi_InvertMask
1631 HBITMAP
wxFlipBmp( HBITMAP hBmp
, int nWidth
, int nHeight
)
1633 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxFlipBmp") );
1636 // Get width/height from the bitmap if not given
1638 if (!nWidth
|| !nHeight
)
1640 BITMAPINFOHEADER2 vBmhdr
;
1643 ::GpiQueryBitmapInfoHeader( hBmp
,
1645 nWidth
= (int)vBmhdr
.cx
;
1646 nHeight
= (int)vBmhdr
.cy
;
1649 BITMAPINFOHEADER2 vBmih
;
1650 SIZEL vSize
= {0, 0};
1651 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1652 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1656 (PDEVOPENDATA
)&vDop
,
1658 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1662 (PDEVOPENDATA
)&vDop
,
1664 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1667 PU_PELS
| GPIA_ASSOC
);
1668 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1671 PU_PELS
| GPIA_ASSOC
);
1672 POINTL vPoint
[4] = { {0, nHeight
},
1675 {nWidth
, nHeight
} };
1677 memset(&vBmih
, '\0', 16);
1682 vBmih
.cBitCount
= 24;
1684 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1690 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1691 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1693 ::GpiBitBlt( hPSDst
,
1700 ::GpiDestroyPS(hPSSrc
);
1701 ::GpiDestroyPS(hPSDst
);
1702 ::DevCloseDC(hDCSrc
);
1703 ::DevCloseDC(hDCDst
);
1706 } // end of wxFlipBmp