1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/bitmap.cpp
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
14 #include "wx/bitmap.h"
22 #include "wx/palette.h"
23 #include "wx/dcmemory.h"
29 #include "wx/os2/dc.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 m_hBitmap
= wxCopyBmp(tocopy
.m_hBitmap
);
73 void wxBitmapRefData::Free()
75 if ( m_pSelectedInto
)
77 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
81 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
83 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
86 wxDELETE(m_pBitmapMask
);
87 } // end of wxBitmapRefData::Free
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const
95 return new wxBitmapRefData(*static_cast<const wxBitmapRefData
*>(data
));
98 // this function should be called from all wxBitmap ctors
103 // True for all bitmaps created from bits, wxImages, Xpms
105 } // end of wxBitmap::Init
107 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
109 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
110 POINTERINFO SIconInfo
;
112 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
114 wxLogLastError(wxT("WinQueryPointerInfo"));
117 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
119 m_refData
= pRefData
;
121 int nWidth
= rIcon
.GetWidth();
122 int nHeight
= rIcon
.GetHeight();
124 pRefData
->m_nWidth
= nWidth
;
125 pRefData
->m_nHeight
= nHeight
;
126 pRefData
->m_nDepth
= wxDisplayDepth();
128 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
130 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
132 pMask
->SetMaskBitmap(GetHBITMAP());
136 } // end of wxBitmap::CopyFromIconOrCursor
138 bool wxBitmap::CopyFromCursor(
139 const wxCursor
& rCursor
146 return(CopyFromIconOrCursor(rCursor
));
147 } // end of wxBitmap::CopyFromCursor
149 bool wxBitmap::CopyFromIcon(
158 return CopyFromIconOrCursor(rIcon
);
159 } // end of wxBitmap::CopyFromIcon
161 wxBitmap::~wxBitmap()
163 } // end of wxBitmap::~wxBitmap
174 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
175 BITMAPINFOHEADER2 vHeader
;
179 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
180 SIZEL vSize
= {0, 0};
183 wxASSERT(vHabmain
!= NULL
);
185 m_refData
= pRefData
;
187 pRefData
->m_nWidth
= nWidth
;
188 pRefData
->m_nHeight
= nHeight
;
189 pRefData
->m_nDepth
= nDepth
;
190 pRefData
->m_nNumColors
= 0;
191 pRefData
->m_pSelectedInto
= NULL
;
193 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
194 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
197 wxLogLastError(wxT("GpiCreatePS Failure"));
203 // We assume that it is in XBM format which is not quite the same as
204 // the format CreateBitmap() wants because the order of bytes in the
207 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
208 const size_t nPadding
= nBytesPerLine
% 2;
209 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
210 const char* pzSrc
= zBits
;
214 pzData
= (char *)malloc(nLen
);
216 char* pzDst
= pzData
;
218 for (nRows
= 0; nRows
< nHeight
; nRows
++)
220 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
222 unsigned char ucVal
= *pzSrc
++;
223 unsigned char ucReversed
= 0;
226 for (nBits
= 0; nBits
< 8; nBits
++)
229 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
232 *pzDst
++ = ucReversed
;
241 // Bits should already be in Windows standard format
243 pzData
= (char *)zBits
; // const_cast is harmless
247 nDepth
= 24; // MAX supported in PM
248 memset(&vHeader
, '\0', 16);
250 vHeader
.cx
= (USHORT
)nWidth
;
251 vHeader
.cy
= (USHORT
)nHeight
;
252 vHeader
.cPlanes
= 1L;
253 vHeader
.cBitCount
= (USHORT
)nDepth
;
254 vHeader
.usReserved
= 0;
256 memset(&vInfo
, '\0', 16);
258 vInfo
.cx
= (USHORT
)nWidth
;
259 vInfo
.cy
= (USHORT
)nHeight
;
261 vInfo
.cBitCount
= (USHORT
)nDepth
;
263 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
267 wxLogLastError(wxT("CreateBitmap"));
271 SetHBITMAP((WXHBITMAP
)hBmp
);
272 } // end of wxBitmap::wxBitmap
290 } // end of wxBitmap::wxBitmap
302 } // end of wxBitmap::wxBitmap
304 bool wxBitmap::Create(
311 BITMAPINFOHEADER2 vHeader
;
313 wxASSERT(vHabmain
!= NULL
);
315 m_refData
= new wxBitmapRefData
;
316 GetBitmapData()->m_nWidth
= nW
;
317 GetBitmapData()->m_nHeight
= nH
;
318 GetBitmapData()->m_nDepth
= nD
;
321 // Xpms and bitmaps from other images can also be mono's, but only
322 // mono's need help changing their colors with MemDC changes
326 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
327 SIZEL vSize
= {0, 0};
328 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
329 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
333 memset(&vHeader
, '\0', 16);
338 vHeader
.cBitCount
= 24; //nD;
340 hBmp
= ::GpiCreateBitmap( hPS
355 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
356 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
357 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
362 memset(&vHeader
, '\0', 16);
367 vHeader
.cBitCount
= (USHORT
)lBitCount
;
369 hBmp
= ::GpiCreateBitmap( hPSScreen
376 GetBitmapData()->m_nDepth
= wxDisplayDepth();
377 ::WinReleasePS(hPSScreen
);
379 SetHBITMAP((WXHBITMAP
)hBmp
);
382 } // end of wxBitmap::Create
384 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
)
388 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
392 m_refData
= new wxBitmapRefData
;
394 return handler
->LoadFile(this, filename
, type
, -1, -1);
397 else // no bitmap handler found
400 if ( image
.LoadFile( filename
, type
) && image
.IsOk() )
402 *this = wxBitmap(image
);
407 #endif // wxUSE_IMAGE
412 bool wxBitmap::LoadFile(
419 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
425 m_refData
= new wxBitmapRefData
;
427 return(pHandler
->LoadFile( this
438 } // end of wxBitmap::LoadFile
440 bool wxBitmap::Create(
450 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
456 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld 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 conversion
507 // ----------------------------------------------------------------------------
509 bool wxBitmap::CreateFromImage (
510 const wxImage
& rImage
514 wxCHECK_MSG(rImage
.IsOk(), false, wxT("invalid image"));
515 m_refData
= new wxBitmapRefData();
517 int nSizeLimit
= 1024 * 768 * 3;
518 int nWidth
= rImage
.GetWidth();
519 int nBmpHeight
= rImage
.GetHeight();
520 int nBytePerLine
= nWidth
* 3;
521 int nSizeDWORD
= sizeof(DWORD
);
522 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
525 if (nLineBoundary
> 0)
527 nPadding
= nSizeDWORD
- nLineBoundary
;
528 nBytePerLine
+= nPadding
;
532 // Calc the number of DIBs and heights of DIBs
536 int nHeight
= nSizeLimit
/ nBytePerLine
;
538 if (nHeight
>= nBmpHeight
)
539 nHeight
= nBmpHeight
;
542 nNumDIB
= nBmpHeight
/ nHeight
;
543 nHRemain
= nBmpHeight
% nHeight
;
549 // Set bitmap parameters
551 wxCHECK_MSG(rImage
.IsOk(), false, wxT("invalid image"));
553 SetHeight(nBmpHeight
);
559 nDepth
= wxDisplayDepth();
564 // Copy the palette from the source image
566 SetPalette(rImage
.GetPalette());
567 #endif // wxUSE_PALETTE
570 // Create a DIB header
572 BITMAPINFOHEADER2 vHeader
;
576 // Fill in the DIB header
578 memset(&vHeader
, '\0', 16);
580 vHeader
.cx
= (ULONG
)nWidth
;
581 vHeader
.cy
= (ULONG
)nHeight
;
582 vHeader
.cPlanes
= 1L;
583 vHeader
.cBitCount
= 24;
586 // Memory for DIB data
588 unsigned char* pucBits
;
590 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
593 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
596 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
599 // Create and set the device-dependent bitmap
601 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
602 SIZEL vSize
= {0, 0};
603 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
604 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
606 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
611 memset(&vInfo
, '\0', 16);
613 vInfo
.cx
= (ULONG
)nWidth
;
614 vInfo
.cy
= (ULONG
)nHeight
;
616 vInfo
.cBitCount
= 24; // Set to desired count going in
618 hBmp
= ::GpiCreateBitmap( hPS
625 HPAL hOldPalette
= NULLHANDLE
;
626 if (rImage
.GetPalette().IsOk())
628 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
630 #endif // wxUSE_PALETTE
633 // Copy image data into DIB data and then into DDB (in a loop)
635 unsigned char* pData
= rImage
.GetData();
640 unsigned char* ptdata
= pData
;
641 unsigned char* ptbits
;
643 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
648 vError
= ::WinGetLastError(vHabmain
);
649 sError
= wxPMErrorToStr(vError
);
651 for (n
= 0; n
< nNumDIB
; n
++)
653 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
656 // Redefine height and size of the (possibly) last smaller DIB
657 // memory is not reallocated
660 vHeader
.cy
= (DWORD
)(nHeight
);
661 vHeader
.cbImage
= nBytePerLine
* nHeight
;
664 for (j
= 0; j
< nHeight
; j
++)
666 for (i
= 0; i
< nWidth
; i
++)
668 *(ptbits
++) = *(ptdata
+ 2);
669 *(ptbits
++) = *(ptdata
+ 1);
670 *(ptbits
++) = *(ptdata
);
673 for (i
= 0; i
< nPadding
; i
++)
678 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
679 // in combination with setting the bits into the selected bitmap
681 if ((lScans
= ::GpiSetBitmapBits( hPS
682 ,0 // Start at the bottom
683 ,(LONG
)nHeight
// One line per scan
691 vError
= ::WinGetLastError(vHabmain
);
692 sError
= wxPMErrorToStr(vError
);
694 hPSScreen
= ::GpiCreatePS( vHabmain
697 ,PU_PELS
| GPIA_ASSOC
700 POINTL vPoint
[4] = { {0, nOrigin
},
702 {0, 0}, {nWidth
, nHeight
}
706 ::GpiBitBlt( hPSScreen
713 ::GpiDestroyPS(hPSScreen
);
716 SetHBITMAP((WXHBITMAP
)hBmp
);
719 ::GpiSelectPalette(hPS
, hOldPalette
);
720 #endif // wxUSE_PALETTE
723 // Similarly, created an mono-bitmap for the possible mask
725 if (rImage
.HasMask())
729 vHeader
.cy
= nHeight
;
731 vHeader
.cBitCount
= 24;
732 hBmp
= ::GpiCreateBitmap( hPS
738 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
740 nHeight
= nBmpHeight
;
742 nHeight
= nSizeLimit
/ nBytePerLine
;
743 vHeader
.cy
= (DWORD
)(nHeight
);
746 unsigned char cRed
= rImage
.GetMaskRed();
747 unsigned char cGreen
= rImage
.GetMaskGreen();
748 unsigned char cBlue
= rImage
.GetMaskBlue();
749 unsigned char cZero
= 0;
750 unsigned char cOne
= 255;
753 for (n
= 0; n
< nNumDIB
; n
++)
755 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
758 // Redefine height and size of the (possibly) last smaller DIB
759 // memory is not reallocated
762 vHeader
.cy
= (DWORD
)(nHeight
);
763 vHeader
.cbImage
= nBytePerLine
* nHeight
;
766 for (int j
= 0; j
< nHeight
; j
++)
768 for (i
= 0; i
< nWidth
; i
++)
770 unsigned char cRedImage
= (*(ptdata
++)) ;
771 unsigned char cGreenImage
= (*(ptdata
++)) ;
772 unsigned char cBlueImage
= (*(ptdata
++)) ;
774 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
787 for (i
= 0; i
< nPadding
; i
++)
790 lScans
= ::GpiSetBitmapBits( hPS
791 ,0 // Start at the bottom
792 ,(LONG
)nHeight
// One line per scan
796 hPSScreen
= ::GpiCreatePS( vHabmain
799 ,PU_PELS
| GPIA_ASSOC
801 POINTL vPoint2
[4] = { {0, nOrigin
},
803 {0, 0}, {nWidth
, nHeight
}
805 ::GpiBitBlt( hPSScreen
812 ::GpiDestroyPS(hPSScreen
);
817 // Create a wxMask object
819 wxMask
* pMask
= new wxMask();
821 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
823 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
827 // Free allocated resources
829 ::GpiSetBitmap(hPS
, NULLHANDLE
);
831 ::DevCloseDC(hDCScreen
);
835 } // end of wxBitmap::CreateFromImage
837 wxImage
wxBitmap::ConvertToImage() const
842 wxCHECK_MSG( IsOk(), wxNullImage
, wxT("invalid bitmap") );
845 // Create an wxImage object
847 int nWidth
= GetWidth();
848 int nHeight
= GetHeight();
851 int nBytePerLine
= nWidth
* 3;
852 int nSizeDWORD
= sizeof(DWORD
);
853 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
855 unsigned char* pData
;
856 unsigned char* lpBits
;
858 BITMAPINFOHEADER2 vDIBh
;
859 BITMAPINFO2 vDIBInfo
;
863 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
864 SIZEL vSizlPage
= {0,0};
865 HDC hDCMem
= NULLHANDLE
;
867 vImage
.Create( nWidth
870 pData
= vImage
.GetData();
873 wxFAIL_MSG( wxT("could not allocate data for image") );
876 if(nLineBoundary
> 0)
878 nPadding
= nSizeDWORD
- nLineBoundary
;
879 nBytePerLine
+= nPadding
;
881 wxDisplaySize( &nDevWidth
885 // Create and fill a DIB header
887 memset(&vDIBh
, '\0', 16);
892 vDIBh
.cBitCount
= 24;
894 memset(&vDIBInfo
, '\0', 16);
896 vDIBInfo
.cx
= nWidth
;
897 vDIBInfo
.cy
= nHeight
;
898 vDIBInfo
.cPlanes
= 1;
899 vDIBInfo
.cBitCount
= 24;
901 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
904 wxFAIL_MSG(wxT("could not allocate data for DIB"));
908 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
909 hBitmap
= (HBITMAP
)GetHBITMAP();
912 // May already be selected into a PS
914 pDC
= GetSelectedInto();
915 const wxPMDCImpl
*impl
;
917 (impl
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl
)) != NULL
)
919 hPSMem
= impl
->GetHPS();
923 hDCMem
= ::DevOpenDC( vHabmain
930 hPSMem
= ::GpiCreatePS( vHabmain
933 ,PU_PELS
| GPIA_ASSOC
936 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
941 vError
= ::WinGetLastError(vHabmain
);
942 sError
= wxPMErrorToStr(vError
);
946 // Copy data from the device-dependent bitmap to the DIB
948 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
958 vError
= ::WinGetLastError(vHabmain
);
959 sError
= wxPMErrorToStr(vError
);
963 // Copy DIB data into the wxImage object
967 unsigned char* ptdata
= pData
;
968 unsigned char* ptbits
= lpBits
;
970 for (i
= 0; i
< nHeight
; i
++)
972 for (j
= 0; j
< nWidth
; j
++)
974 *(ptdata
++) = *(ptbits
+2);
975 *(ptdata
++) = *(ptbits
+1);
976 *(ptdata
++) = *(ptbits
);
981 if ((pDC
= GetSelectedInto()) == NULL
)
983 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
984 ::GpiDestroyPS(hPSMem
);
985 ::DevCloseDC(hDCMem
);
989 // Similarly, set data according to the possible mask bitmap
991 if (GetMask() && GetMask()->GetMaskBitmap())
993 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
996 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
998 HDC hMemDC
= ::DevOpenDC( vHabmain
1002 ,(PDEVOPENDATA
)&vDop
1005 HPS hMemPS
= ::GpiCreatePS( vHabmain
1008 ,PU_PELS
| GPIA_ASSOC
1010 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1011 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1012 ::GpiSetBitmap(hMemPS
, hBitmap
);
1013 ::GpiQueryBitmapBits( hPSMem
1019 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1020 ::GpiDestroyPS(hMemPS
);
1021 ::DevCloseDC(hMemDC
);
1024 // Background color set to RGB(16,16,16) in consistent with wxGTK
1026 unsigned char ucRed
= 16;
1027 unsigned char ucGreen
= 16;
1028 unsigned char ucBlue
= 16;
1032 for (i
= 0; i
< nHeight
; i
++)
1034 for (j
= 0; j
< nWidth
; j
++)
1040 *(ptdata
++) = ucRed
;
1041 *(ptdata
++) = ucGreen
;
1042 *(ptdata
++) = ucBlue
;
1048 vImage
.SetMaskColour( ucRed
1052 vImage
.SetMask(true);
1056 vImage
.SetMask(false);
1060 // Free allocated resources
1064 } // end of wxBitmap::ConvertToImage
1066 // ----------------------------------------------------------------------------
1067 // sub bitmap extraction
1068 // ----------------------------------------------------------------------------
1070 wxBitmap
wxBitmap::GetSubBitmap(
1074 wxCHECK_MSG( IsOk() &&
1075 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1076 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1077 (rRect
.y
+ rRect
.height
<= GetHeight()),
1078 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1080 wxBitmap
vRet( rRect
.width
1084 wxASSERT_MSG( vRet
.IsOk(), wxT("GetSubBitmap error") );
1090 SIZEL vSize
= {0, 0};
1091 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1092 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1093 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1094 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1095 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1096 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1098 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1101 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1102 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1112 // Copy mask if there is one
1116 BITMAPINFOHEADER2 vBmih
;
1118 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1119 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1120 vBmih
.cx
= rRect
.width
;
1121 vBmih
.cy
= rRect
.height
;
1123 vBmih
.cBitCount
= 24;
1125 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1132 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1133 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1135 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1136 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1145 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1146 vRet
.SetMask(pMask
);
1149 ::GpiSetBitmap(hPSSrc
, NULL
);
1150 ::GpiSetBitmap(hPSDst
, NULL
);
1151 ::GpiDestroyPS(hPSSrc
);
1152 ::GpiDestroyPS(hPSDst
);
1153 ::DevCloseDC(hDCSrc
);
1154 ::DevCloseDC(hDCDst
);
1156 } // end of wxBitmap::GetSubBitmap
1158 // ----------------------------------------------------------------------------
1159 // wxBitmap accessors
1160 // ----------------------------------------------------------------------------
1162 void wxBitmap::SetQuality(
1168 GetBitmapData()->m_nQuality
= nQ
;
1169 } // end of wxBitmap::SetQuality
1171 void wxBitmap::SetPalette(
1172 const wxPalette
& rPalette
1177 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1178 } // end of wxBitmap::SetPalette
1180 void wxBitmap::SetMask(
1186 GetBitmapData()->m_pBitmapMask
= pMask
;
1187 } // end of wxBitmap::SetMask
1189 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1192 } // end of wxBitmap::GetBitmapForDC
1194 // ----------------------------------------------------------------------------
1196 // ----------------------------------------------------------------------------
1201 } // end of wxMask::wxMask
1203 wxMask::wxMask(const wxMask
& tocopy
)
1205 m_hMaskBitmap
= wxCopyBmp(tocopy
.m_hMaskBitmap
);
1206 } // end of wxMask::wxMask
1208 // Construct a mask from a bitmap and a colour indicating
1209 // the transparent area
1211 const wxBitmap
& rBitmap
1212 , const wxColour
& rColour
1219 } // end of wxMask::wxMask
1221 // Construct a mask from a bitmap and a palette index indicating
1222 // the transparent area
1224 const wxBitmap
& rBitmap
1232 } // end of wxMask::wxMask
1234 // Construct a mask from a mono bitmap (copies the bitmap).
1236 const wxBitmap
& rBitmap
1241 } // end of wxMask::wxMask
1246 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1247 } // end of wxMask::~wxMask
1249 // Create a mask from a mono bitmap (copies the bitmap).
1250 bool wxMask::Create(
1251 const wxBitmap
& rBitmap
1254 BITMAPINFOHEADER2 vBmih
;
1255 SIZEL vSize
= {0, 0};
1256 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1257 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1258 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1259 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1260 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1261 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1262 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1267 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1270 if (!rBitmap
.IsOk() || rBitmap
.GetDepth() != 1)
1275 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1276 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1277 vBmih
.cx
= rBitmap
.GetWidth();
1278 vBmih
.cy
= rBitmap
.GetHeight();
1280 vBmih
.cBitCount
= 24;
1282 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1289 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1290 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1299 ::GpiDestroyPS(hPSSrc
);
1300 ::GpiDestroyPS(hPSDst
);
1301 ::DevCloseDC(hDCSrc
);
1302 ::DevCloseDC(hDCDst
);
1304 } // end of wxMask::Create
1306 // Create a mask from a bitmap and a palette index indicating
1307 // the transparent area
1308 bool wxMask::Create(
1309 const wxBitmap
& rBitmap
1315 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1318 if (rBitmap
.IsOk() && rBitmap
.GetPalette()->IsOk())
1321 unsigned char cGreen
;
1322 unsigned char cBlue
;
1324 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1330 wxColour
vTransparentColour( cRed
1335 return (Create( rBitmap
1341 } // end of wxMask::Create
1343 // Create a mask from a bitmap and a colour indicating
1344 // the transparent area
1345 bool wxMask::Create(
1346 const wxBitmap
& rBitmap
1347 , const wxColour
& rColour
1351 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1355 BITMAPINFOHEADER2 vBmih
;
1356 SIZEL vSize
= {0, 0};
1357 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1358 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1359 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1360 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1361 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1365 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1368 if (!rBitmap
.IsOk())
1374 // Scan the bitmap for the transparent colour and set
1375 // the corresponding pixels in the mask to BLACK and
1376 // the rest to WHITE
1379 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1380 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1381 vBmih
.cx
= rBitmap
.GetWidth();
1382 vBmih
.cy
= rBitmap
.GetHeight();
1384 vBmih
.cBitCount
= 1;
1386 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1393 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1394 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1397 // This is not very efficient, but I can't think
1398 // of a better way of doing it
1400 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1402 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1404 POINTL vPt
= {w
, h
};
1405 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1406 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1409 // Doesn't make sense to continue
1415 if (vCol
== vMaskColour
)
1417 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1418 ::GpiSetPel(hPSDst
, &vPt
);
1422 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1423 ::GpiSetPel(hPSDst
, &vPt
);
1427 ::GpiSetBitmap(hPSSrc
, NULL
);
1428 ::GpiSetBitmap(hPSDst
, NULL
);
1429 ::GpiDestroyPS(hPSSrc
);
1430 ::GpiDestroyPS(hPSDst
);
1431 ::DevCloseDC(hDCSrc
);
1432 ::DevCloseDC(hDCDst
);
1434 } // end of wxMask::Create
1436 // ----------------------------------------------------------------------------
1438 // ----------------------------------------------------------------------------
1440 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1447 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1451 return(pBitmap
? Create( pBitmap
1460 bool wxBitmapHandler::Load(
1463 , wxBitmapType lFlags
1468 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1472 return(pBitmap
? LoadFile( pBitmap
1480 bool wxBitmapHandler::Save(
1481 const wxGDIImage
* pImage
1482 , const wxString
& rName
1483 , wxBitmapType lType
1486 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1490 return(pBitmap
? SaveFile( pBitmap
1496 bool wxBitmapHandler::Create(
1497 wxBitmap
* WXUNUSED(pBitmap
)
1498 , const void* WXUNUSED(pData
)
1499 , wxBitmapType
WXUNUSED(lType
)
1500 , int WXUNUSED(nWidth
)
1501 , int WXUNUSED(nHeight
)
1502 , int WXUNUSED(nDepth
)
1508 bool wxBitmapHandler::LoadFile(
1509 wxBitmap
* WXUNUSED(pBitmap
)
1511 , wxBitmapType
WXUNUSED(lType
)
1512 , int WXUNUSED(nDesiredWidth
)
1513 , int WXUNUSED(nDesiredHeight
)
1519 bool wxBitmapHandler::LoadFile(
1520 wxBitmap
* WXUNUSED(pBitmap
)
1521 , const wxString
& WXUNUSED(rName
)
1522 , wxBitmapType
WXUNUSED(lType
)
1523 , int WXUNUSED(nDesiredWidth
)
1524 , int WXUNUSED(nDesiredHeight
)
1530 bool wxBitmapHandler::SaveFile(
1531 wxBitmap
* WXUNUSED(pBitmap
)
1532 , const wxString
& WXUNUSED(rName
)
1533 , wxBitmapType
WXUNUSED(nType
)
1534 , const wxPalette
* WXUNUSED(pPalette
)
1540 // ----------------------------------------------------------------------------
1541 // Utility functions
1542 // ----------------------------------------------------------------------------
1543 HBITMAP
wxInvertMask(
1549 HBITMAP hBmpInvMask
= 0;
1551 wxCHECK_MSG( hBmpMask
, 0, wxT("invalid bitmap in wxInvertMask") );
1554 // Get width/height from the bitmap if not given
1556 if (!nWidth
|| !nHeight
)
1558 BITMAPINFOHEADER2 vBmhdr
;
1560 ::GpiQueryBitmapInfoHeader( hBmpMask
1563 nWidth
= (int)vBmhdr
.cx
;
1564 nHeight
= (int)vBmhdr
.cy
;
1567 BITMAPINFOHEADER2 vBmih
;
1568 SIZEL vSize
= {0, 0};
1569 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1570 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1571 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1572 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1573 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1574 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1575 {0, 0}, {nWidth
, nHeight
}
1578 memset(&vBmih
, '\0', 16);
1583 vBmih
.cBitCount
= 24;
1585 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1592 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1593 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1603 ::GpiDestroyPS(hPSSrc
);
1604 ::GpiDestroyPS(hPSDst
);
1605 ::DevCloseDC(hDCSrc
);
1606 ::DevCloseDC(hDCDst
);
1609 } // end of WxWinGdi_InvertMask
1611 HBITMAP
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight
)
1613 wxCHECK_MSG( hBmp
, 0, wxT("invalid bitmap in wxCopyBmp") );
1616 // Get width/height from the bitmap if not given
1618 if (!nWidth
|| !nHeight
)
1620 BITMAPINFOHEADER2 vBmhdr
;
1623 ::GpiQueryBitmapInfoHeader( hBmp
,
1625 nWidth
= (int)vBmhdr
.cx
;
1626 nHeight
= (int)vBmhdr
.cy
;
1629 BITMAPINFOHEADER2 vBmih
;
1630 SIZEL vSize
= {0, 0};
1631 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1632 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1636 (PDEVOPENDATA
)&vDop
,
1638 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1642 (PDEVOPENDATA
)&vDop
,
1644 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1647 PU_PELS
| GPIA_ASSOC
);
1648 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1651 PU_PELS
| GPIA_ASSOC
);
1652 POINTL vPoint
[4] = { {0, nHeight
},
1655 {nWidth
, nHeight
} };
1659 vPoint
[1].y
= nHeight
;
1661 memset(&vBmih
, '\0', 16);
1666 vBmih
.cBitCount
= 24;
1668 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1674 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1675 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1677 ::GpiBitBlt( hPSDst
,
1684 ::GpiDestroyPS(hPSSrc
);
1685 ::GpiDestroyPS(hPSDst
);
1686 ::DevCloseDC(hDCSrc
);
1687 ::DevCloseDC(hDCDst
);
1690 } // end of wxFlipBmp