1 /////////////////////////////////////////////////////////////////////////////
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"
21 #include "wx/palette.h"
22 #include "wx/dcmemory.h"
23 #include "wx/bitmap.h"
27 #include "wx/os2/private.h"
30 //#include "wx/msw/dib.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 void wxBitmapRefData::Free()
62 if ( m_pSelectedInto
)
64 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
68 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
70 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
78 } // end of wxBitmapRefData::Free
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // this function should be called from all wxBitmap ctors
89 // True for all bitmaps created from bits, wxImages, Xpms
91 } // end of wxBitmap::Init
93 bool wxBitmap::CopyFromIconOrCursor(
94 const wxGDIImage
& rIcon
97 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
98 POINTERINFO SIconInfo
;
100 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
102 wxLogLastError(wxT("WinQueryPointerInfo"));
105 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
107 m_refData
= pRefData
;
109 int nWidth
= rIcon
.GetWidth();
110 int nHeight
= rIcon
.GetHeight();
112 pRefData
->m_nWidth
= nWidth
;
113 pRefData
->m_nHeight
= nHeight
;
114 pRefData
->m_nDepth
= wxDisplayDepth();
116 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
118 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
120 pMask
->SetMaskBitmap(GetHBITMAP());
124 } // end of wxBitmap::CopyFromIconOrCursor
126 bool wxBitmap::CopyFromCursor(
127 const wxCursor
& rCursor
134 return(CopyFromIconOrCursor(rCursor
));
135 } // end of wxBitmap::CopyFromCursor
137 bool wxBitmap::CopyFromIcon(
146 return CopyFromIconOrCursor(rIcon
);
147 } // end of wxBitmap::CopyFromIcon
149 wxBitmap::~wxBitmap()
151 } // end of wxBitmap::~wxBitmap
162 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
163 BITMAPINFOHEADER2 vHeader
;
167 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
168 SIZEL vSize
= {0, 0};
171 wxASSERT(vHabmain
!= NULL
);
173 m_refData
= pRefData
;
175 pRefData
->m_nWidth
= nWidth
;
176 pRefData
->m_nHeight
= nHeight
;
177 pRefData
->m_nDepth
= nDepth
;
178 pRefData
->m_nNumColors
= 0;
179 pRefData
->m_pSelectedInto
= NULL
;
181 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
182 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
185 wxLogLastError(wxT("GpiCreatePS Failure"));
191 // We assume that it is in XBM format which is not quite the same as
192 // the format CreateBitmap() wants because the order of bytes in the
195 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
196 const size_t nPadding
= nBytesPerLine
% 2;
197 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
198 const char* pzSrc
= zBits
;
202 pzData
= (char *)malloc(nLen
);
204 char* pzDst
= pzData
;
206 for (nRows
= 0; nRows
< nHeight
; nRows
++)
208 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
210 unsigned char ucVal
= *pzSrc
++;
211 unsigned char ucReversed
= 0;
214 for (nBits
= 0; nBits
< 8; nBits
++)
217 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
220 *pzDst
++ = ucReversed
;
229 // Bits should already be in Windows standard format
231 pzData
= (char *)zBits
; // const_cast is harmless
235 nDepth
= 24; // MAX supported in PM
236 memset(&vHeader
, '\0', 16);
238 vHeader
.cx
= (USHORT
)nWidth
;
239 vHeader
.cy
= (USHORT
)nHeight
;
240 vHeader
.cPlanes
= 1L;
241 vHeader
.cBitCount
= (USHORT
)nDepth
;
242 vHeader
.usReserved
= 0;
244 memset(&vInfo
, '\0', 16);
246 vInfo
.cx
= (USHORT
)nWidth
;
247 vInfo
.cy
= (USHORT
)nHeight
;
249 vInfo
.cBitCount
= (USHORT
)nDepth
;
251 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
255 wxLogLastError(wxT("CreateBitmap"));
259 SetHBITMAP((WXHBITMAP
)hBmp
);
260 } // end of wxBitmap::wxBitmap
273 } // end of wxBitmap::wxBitmap
291 } // end of wxBitmap::wxBitmap
303 } // end of wxBitmap::wxBitmap
305 bool wxBitmap::Create(
312 BITMAPINFOHEADER2 vHeader
;
314 wxASSERT(vHabmain
!= NULL
);
316 m_refData
= new wxBitmapRefData
;
317 GetBitmapData()->m_nWidth
= nW
;
318 GetBitmapData()->m_nHeight
= nH
;
319 GetBitmapData()->m_nDepth
= nD
;
322 // Xpms and bitmaps from other images can also be mono's, but only
323 // mono's need help changing their colors with MemDC changes
327 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
328 SIZEL vSize
= {0, 0};
329 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
330 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
334 memset(&vHeader
, '\0', 16);
339 vHeader
.cBitCount
= 24; //nD;
341 hBmp
= ::GpiCreateBitmap( hPS
356 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
357 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
358 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
363 memset(&vHeader
, '\0', 16);
368 vHeader
.cBitCount
= (USHORT
)lBitCount
;
370 hBmp
= ::GpiCreateBitmap( hPSScreen
377 GetBitmapData()->m_nDepth
= wxDisplayDepth();
378 ::WinReleasePS(hPSScreen
);
380 SetHBITMAP((WXHBITMAP
)hBmp
);
383 } // end of wxBitmap::Create
385 bool wxBitmap::CreateFromXpm(
389 #if wxUSE_IMAGE && wxUSE_XPM
392 wxCHECK_MSG(ppData
!= NULL
, false, wxT("invalid bitmap data"))
394 wxXPMDecoder vDecoder
;
395 wxImage vImg
= vDecoder
.ReadData(ppData
);
397 wxCHECK_MSG(vImg
.Ok(), false, wxT("invalid bitmap data"))
399 *this = wxBitmap(vImg
);
404 } // end of wxBitmap::CreateFromXpm
406 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
410 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
414 m_refData
= new wxBitmapRefData
;
416 return handler
->LoadFile(this, filename
, type
, -1, -1);
419 else // no bitmap handler found
422 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
424 *this = wxBitmap(image
);
429 #endif // wxUSE_IMAGE
434 bool wxBitmap::LoadFile(
441 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
447 m_refData
= new wxBitmapRefData
;
449 return(pHandler
->LoadFile( this
460 } // end of wxBitmap::LoadFile
462 bool wxBitmap::Create(
472 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
478 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
483 m_refData
= new wxBitmapRefData
;
485 return(pHandler
->Create( this
492 } // end of wxBitmap::Create
494 bool wxBitmap::SaveFile(
495 const wxString
& rFilename
497 , const wxPalette
* pPalette
500 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
506 return pHandler
->SaveFile( this
514 // FIXME what about palette? shouldn't we use it?
515 wxImage vImage
= ConvertToImage();
520 return(vImage
.SaveFile( rFilename
524 } // end of wxBitmap::SaveFile
527 // ----------------------------------------------------------------------------
528 // wxImage-wxBitmap conversion
529 // ----------------------------------------------------------------------------
531 bool wxBitmap::CreateFromImage (
532 const wxImage
& rImage
536 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
537 m_refData
= new wxBitmapRefData();
539 int nSizeLimit
= 1024 * 768 * 3;
540 int nWidth
= rImage
.GetWidth();
541 int nBmpHeight
= rImage
.GetHeight();
542 int nBytePerLine
= nWidth
* 3;
543 int nSizeDWORD
= sizeof(DWORD
);
544 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
547 if (nLineBoundary
> 0)
549 nPadding
= nSizeDWORD
- nLineBoundary
;
550 nBytePerLine
+= nPadding
;
554 // Calc the number of DIBs and heights of DIBs
558 int nHeight
= nSizeLimit
/ nBytePerLine
;
560 if (nHeight
>= nBmpHeight
)
561 nHeight
= nBmpHeight
;
564 nNumDIB
= nBmpHeight
/ nHeight
;
565 nHRemain
= nBmpHeight
% nHeight
;
571 // Set bitmap parameters
573 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
575 SetHeight(nBmpHeight
);
581 nDepth
= wxDisplayDepth();
586 // Copy the palette from the source image
588 SetPalette(rImage
.GetPalette());
589 #endif // wxUSE_PALETTE
592 // Create a DIB header
594 BITMAPINFOHEADER2 vHeader
;
598 // Fill in the DIB header
600 memset(&vHeader
, '\0', 16);
602 vHeader
.cx
= (ULONG
)nWidth
;
603 vHeader
.cy
= (ULONG
)nHeight
;
604 vHeader
.cPlanes
= 1L;
605 vHeader
.cBitCount
= 24;
608 // Memory for DIB data
610 unsigned char* pucBits
;
612 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
615 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
618 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
621 // Create and set the device-dependent bitmap
623 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
624 SIZEL vSize
= {0, 0};
625 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
626 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
628 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
633 memset(&vInfo
, '\0', 16);
635 vInfo
.cx
= (ULONG
)nWidth
;
636 vInfo
.cy
= (ULONG
)nHeight
;
638 vInfo
.cBitCount
= 24; // Set to desired count going in
640 hBmp
= ::GpiCreateBitmap( hPS
647 HPAL hOldPalette
= NULLHANDLE
;
648 if (rImage
.GetPalette().Ok())
650 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
652 #endif // wxUSE_PALETTE
655 // Copy image data into DIB data and then into DDB (in a loop)
657 unsigned char* pData
= rImage
.GetData();
662 unsigned char* ptdata
= pData
;
663 unsigned char* ptbits
;
665 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
670 vError
= ::WinGetLastError(vHabmain
);
671 sError
= wxPMErrorToStr(vError
);
673 for (n
= 0; n
< nNumDIB
; n
++)
675 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
678 // Redefine height and size of the (possibly) last smaller DIB
679 // memory is not reallocated
682 vHeader
.cy
= (DWORD
)(nHeight
);
683 vHeader
.cbImage
= nBytePerLine
* nHeight
;
686 for (j
= 0; j
< nHeight
; j
++)
688 for (i
= 0; i
< nWidth
; i
++)
690 *(ptbits
++) = *(ptdata
+ 2);
691 *(ptbits
++) = *(ptdata
+ 1);
692 *(ptbits
++) = *(ptdata
);
695 for (i
= 0; i
< nPadding
; i
++)
700 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
701 // in combination with setting the bits into the selected bitmap
703 if ((lScans
= ::GpiSetBitmapBits( hPS
704 ,0 // Start at the bottom
705 ,(LONG
)nHeight
// One line per scan
713 vError
= ::WinGetLastError(vHabmain
);
714 sError
= wxPMErrorToStr(vError
);
716 hPSScreen
= ::GpiCreatePS( vHabmain
719 ,PU_PELS
| GPIA_ASSOC
722 POINTL vPoint
[4] = { {0, nOrigin
},
724 {0, 0}, {nWidth
, nHeight
}
728 ::GpiBitBlt( hPSScreen
735 ::GpiDestroyPS(hPSScreen
);
738 SetHBITMAP((WXHBITMAP
)hBmp
);
741 ::GpiSelectPalette(hPS
, hOldPalette
);
742 #endif // wxUSE_PALETTE
745 // Similarly, created an mono-bitmap for the possible mask
747 if (rImage
.HasMask())
751 vHeader
.cy
= nHeight
;
753 vHeader
.cBitCount
= 24;
754 hBmp
= ::GpiCreateBitmap( hPS
760 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
762 nHeight
= nBmpHeight
;
764 nHeight
= nSizeLimit
/ nBytePerLine
;
765 vHeader
.cy
= (DWORD
)(nHeight
);
768 unsigned char cRed
= rImage
.GetMaskRed();
769 unsigned char cGreen
= rImage
.GetMaskGreen();
770 unsigned char cBlue
= rImage
.GetMaskBlue();
771 unsigned char cZero
= 0;
772 unsigned char cOne
= 255;
775 for (n
= 0; n
< nNumDIB
; n
++)
777 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
780 // Redefine height and size of the (possibly) last smaller DIB
781 // memory is not reallocated
784 vHeader
.cy
= (DWORD
)(nHeight
);
785 vHeader
.cbImage
= nBytePerLine
* nHeight
;
788 for (int j
= 0; j
< nHeight
; j
++)
790 for (i
= 0; i
< nWidth
; i
++)
792 unsigned char cRedImage
= (*(ptdata
++)) ;
793 unsigned char cGreenImage
= (*(ptdata
++)) ;
794 unsigned char cBlueImage
= (*(ptdata
++)) ;
796 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
809 for (i
= 0; i
< nPadding
; i
++)
812 lScans
= ::GpiSetBitmapBits( hPS
813 ,0 // Start at the bottom
814 ,(LONG
)nHeight
// One line per scan
818 hPSScreen
= ::GpiCreatePS( vHabmain
821 ,PU_PELS
| GPIA_ASSOC
823 POINTL vPoint2
[4] = { {0, nOrigin
},
825 {0, 0}, {nWidth
, nHeight
}
827 ::GpiBitBlt( hPSScreen
834 ::GpiDestroyPS(hPSScreen
);
839 // Create a wxMask object
841 wxMask
* pMask
= new wxMask();
843 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
845 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
849 // Free allocated resources
851 ::GpiSetBitmap(hPS
, NULLHANDLE
);
853 ::DevCloseDC(hDCScreen
);
857 } // end of wxBitmap::CreateFromImage
859 wxImage
wxBitmap::ConvertToImage() const
864 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
867 // Create an wxImage object
869 int nWidth
= GetWidth();
870 int nHeight
= GetHeight();
873 int nBytePerLine
= nWidth
* 3;
874 int nSizeDWORD
= sizeof(DWORD
);
875 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
877 unsigned char* pData
;
878 unsigned char* lpBits
;
880 BITMAPINFOHEADER2 vDIBh
;
881 BITMAPINFO2 vDIBInfo
;
885 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
886 SIZEL vSizlPage
= {0,0};
887 HDC hDCMem
= NULLHANDLE
;
889 vImage
.Create( nWidth
892 pData
= vImage
.GetData();
895 wxFAIL_MSG( wxT("could not allocate data for image") );
898 if(nLineBoundary
> 0)
900 nPadding
= nSizeDWORD
- nLineBoundary
;
901 nBytePerLine
+= nPadding
;
903 wxDisplaySize( &nDevWidth
907 // Create and fill a DIB header
909 memset(&vDIBh
, '\0', 16);
914 vDIBh
.cBitCount
= 24;
916 memset(&vDIBInfo
, '\0', 16);
918 vDIBInfo
.cx
= nWidth
;
919 vDIBInfo
.cy
= nHeight
;
920 vDIBInfo
.cPlanes
= 1;
921 vDIBInfo
.cBitCount
= 24;
923 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
926 wxFAIL_MSG(wxT("could not allocate data for DIB"));
930 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
931 hBitmap
= (HBITMAP
)GetHBITMAP();
934 // May already be selected into a PS
936 if ((pDC
= GetSelectedInto()) != NULL
)
938 hPSMem
= pDC
->GetHPS();
942 hDCMem
= ::DevOpenDC( vHabmain
949 hPSMem
= ::GpiCreatePS( vHabmain
952 ,PU_PELS
| GPIA_ASSOC
955 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
960 vError
= ::WinGetLastError(vHabmain
);
961 sError
= wxPMErrorToStr(vError
);
965 // Copy data from the device-dependent bitmap to the DIB
967 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
977 vError
= ::WinGetLastError(vHabmain
);
978 sError
= wxPMErrorToStr(vError
);
982 // Copy DIB data into the wxImage object
986 unsigned char* ptdata
= pData
;
987 unsigned char* ptbits
= lpBits
;
989 for (i
= 0; i
< nHeight
; i
++)
991 for (j
= 0; j
< nWidth
; j
++)
993 *(ptdata
++) = *(ptbits
+2);
994 *(ptdata
++) = *(ptbits
+1);
995 *(ptdata
++) = *(ptbits
);
1000 if ((pDC
= GetSelectedInto()) == NULL
)
1002 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
1003 ::GpiDestroyPS(hPSMem
);
1004 ::DevCloseDC(hDCMem
);
1008 // Similarly, set data according to the possible mask bitmap
1010 if (GetMask() && GetMask()->GetMaskBitmap())
1012 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1015 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1017 HDC hMemDC
= ::DevOpenDC( vHabmain
1021 ,(PDEVOPENDATA
)&vDop
1024 HPS hMemPS
= ::GpiCreatePS( vHabmain
1027 ,PU_PELS
| GPIA_ASSOC
1029 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1030 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1031 ::GpiSetBitmap(hMemPS
, hBitmap
);
1032 ::GpiQueryBitmapBits( hPSMem
1038 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1039 ::GpiDestroyPS(hMemPS
);
1040 ::DevCloseDC(hMemDC
);
1043 // Background color set to RGB(16,16,16) in consistent with wxGTK
1045 unsigned char ucRed
= 16;
1046 unsigned char ucGreen
= 16;
1047 unsigned char ucBlue
= 16;
1051 for (i
= 0; i
< nHeight
; i
++)
1053 for (j
= 0; j
< nWidth
; j
++)
1059 *(ptdata
++) = ucRed
;
1060 *(ptdata
++) = ucGreen
;
1061 *(ptdata
++) = ucBlue
;
1067 vImage
.SetMaskColour( ucRed
1071 vImage
.SetMask(true);
1075 vImage
.SetMask(false);
1079 // Free allocated resources
1083 } // end of wxBitmap::ConvertToImage
1085 // ----------------------------------------------------------------------------
1086 // sub bitmap extraction
1087 // ----------------------------------------------------------------------------
1089 wxBitmap
wxBitmap::GetSubBitmap(
1093 wxCHECK_MSG( Ok() &&
1094 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1095 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1096 (rRect
.y
+ rRect
.height
<= GetHeight()),
1097 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1099 wxBitmap
vRet( rRect
.width
1103 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1109 SIZEL vSize
= {0, 0};
1110 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1111 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1112 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1113 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1114 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1115 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1117 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1120 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1121 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1131 // Copy mask if there is one
1135 BITMAPINFOHEADER2 vBmih
;
1137 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1138 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1139 vBmih
.cx
= rRect
.width
;
1140 vBmih
.cy
= rRect
.height
;
1142 vBmih
.cBitCount
= 24;
1144 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1151 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1152 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1154 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1155 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1164 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1165 vRet
.SetMask(pMask
);
1168 ::GpiSetBitmap(hPSSrc
, NULL
);
1169 ::GpiSetBitmap(hPSDst
, NULL
);
1170 ::GpiDestroyPS(hPSSrc
);
1171 ::GpiDestroyPS(hPSDst
);
1172 ::DevCloseDC(hDCSrc
);
1173 ::DevCloseDC(hDCDst
);
1175 } // end of wxBitmap::GetSubBitmap
1177 // ----------------------------------------------------------------------------
1178 // wxBitmap accessors
1179 // ----------------------------------------------------------------------------
1181 void wxBitmap::SetQuality(
1187 GetBitmapData()->m_nQuality
= nQ
;
1188 } // end of wxBitmap::SetQuality
1190 void wxBitmap::SetPalette(
1191 const wxPalette
& rPalette
1196 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1197 } // end of wxBitmap::SetPalette
1199 void wxBitmap::SetMask(
1205 GetBitmapData()->m_pBitmapMask
= pMask
;
1206 } // end of wxBitmap::SetMask
1208 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1211 } // end of wxBitmap::GetBitmapForDC
1213 // ----------------------------------------------------------------------------
1215 // ----------------------------------------------------------------------------
1220 } // end of wxMask::wxMask
1222 // Construct a mask from a bitmap and a colour indicating
1223 // the transparent area
1225 const wxBitmap
& rBitmap
1226 , const wxColour
& rColour
1233 } // end of wxMask::wxMask
1235 // Construct a mask from a bitmap and a palette index indicating
1236 // the transparent area
1238 const wxBitmap
& rBitmap
1246 } // end of wxMask::wxMask
1248 // Construct a mask from a mono bitmap (copies the bitmap).
1250 const wxBitmap
& rBitmap
1255 } // end of wxMask::wxMask
1260 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1261 } // end of wxMask::~wxMask
1263 // Create a mask from a mono bitmap (copies the bitmap).
1264 bool wxMask::Create(
1265 const wxBitmap
& rBitmap
1268 BITMAPINFOHEADER2 vBmih
;
1269 SIZEL vSize
= {0, 0};
1270 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1271 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1272 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1273 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1274 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1275 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1276 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1281 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1284 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1289 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1290 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1291 vBmih
.cx
= rBitmap
.GetWidth();
1292 vBmih
.cy
= rBitmap
.GetHeight();
1294 vBmih
.cBitCount
= 24;
1296 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1303 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1304 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1313 ::GpiDestroyPS(hPSSrc
);
1314 ::GpiDestroyPS(hPSDst
);
1315 ::DevCloseDC(hDCSrc
);
1316 ::DevCloseDC(hDCDst
);
1318 } // end of wxMask::Create
1320 // Create a mask from a bitmap and a palette index indicating
1321 // the transparent area
1322 bool wxMask::Create(
1323 const wxBitmap
& rBitmap
1329 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1332 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1335 unsigned char cGreen
;
1336 unsigned char cBlue
;
1338 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1344 wxColour
vTransparentColour( cRed
1349 return (Create( rBitmap
1355 } // end of wxMask::Create
1357 // Create a mask from a bitmap and a colour indicating
1358 // the transparent area
1359 bool wxMask::Create(
1360 const wxBitmap
& rBitmap
1361 , const wxColour
& rColour
1365 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1369 BITMAPINFOHEADER2 vBmih
;
1370 SIZEL vSize
= {0, 0};
1371 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1372 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1373 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1374 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1375 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1379 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1388 // Scan the bitmap for the transparent colour and set
1389 // the corresponding pixels in the mask to BLACK and
1390 // the rest to WHITE
1393 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1394 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1395 vBmih
.cx
= rBitmap
.GetWidth();
1396 vBmih
.cy
= rBitmap
.GetHeight();
1398 vBmih
.cBitCount
= 1;
1400 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1407 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1408 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1411 // This is not very efficient, but I can't think
1412 // of a better way of doing it
1414 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1416 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1418 POINTL vPt
= {w
, h
};
1419 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1420 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1423 // Doesn't make sense to continue
1429 if (vCol
== vMaskColour
)
1431 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1432 ::GpiSetPel(hPSDst
, &vPt
);
1436 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1437 ::GpiSetPel(hPSDst
, &vPt
);
1441 ::GpiSetBitmap(hPSSrc
, NULL
);
1442 ::GpiSetBitmap(hPSDst
, NULL
);
1443 ::GpiDestroyPS(hPSSrc
);
1444 ::GpiDestroyPS(hPSDst
);
1445 ::DevCloseDC(hDCSrc
);
1446 ::DevCloseDC(hDCDst
);
1448 } // end of wxMask::Create
1450 // ----------------------------------------------------------------------------
1452 // ----------------------------------------------------------------------------
1454 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1456 long WXUNUSED(lFlags
),
1461 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1465 return(pBitmap
? Create( pBitmap
1473 bool wxBitmapHandler::Load(
1481 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1485 return(pBitmap
? LoadFile( pBitmap
1493 bool wxBitmapHandler::Save(
1495 , const wxString
& rName
1499 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1503 return(pBitmap
? SaveFile( pBitmap
1509 bool wxBitmapHandler::Create(
1510 wxBitmap
* WXUNUSED(pBitmap
)
1511 , void* WXUNUSED(pData
)
1512 , long WXUNUSED(lType
)
1513 , int WXUNUSED(nWidth
)
1514 , int WXUNUSED(nHeight
)
1515 , int WXUNUSED(nDepth
)
1521 bool wxBitmapHandler::LoadFile(
1522 wxBitmap
* WXUNUSED(pBitmap
)
1524 , long WXUNUSED(lType
)
1525 , int WXUNUSED(nDesiredWidth
)
1526 , int WXUNUSED(nDesiredHeight
)
1532 bool wxBitmapHandler::LoadFile(
1533 wxBitmap
* WXUNUSED(pBitmap
)
1534 , const wxString
& WXUNUSED(rName
)
1535 , long WXUNUSED(lType
)
1536 , int WXUNUSED(nDesiredWidth
)
1537 , int WXUNUSED(nDesiredHeight
)
1543 bool wxBitmapHandler::SaveFile(
1544 wxBitmap
* WXUNUSED(pBitmap
)
1545 , const wxString
& WXUNUSED(rName
)
1546 , int WXUNUSED(nType
)
1547 , const wxPalette
* WXUNUSED(pPalette
)
1553 // ----------------------------------------------------------------------------
1554 // Utility functions
1555 // ----------------------------------------------------------------------------
1556 HBITMAP
wxInvertMask(
1562 HBITMAP hBmpInvMask
= 0;
1564 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1567 // Get width/height from the bitmap if not given
1569 if (!nWidth
|| !nHeight
)
1571 BITMAPINFOHEADER2 vBmhdr
;
1573 ::GpiQueryBitmapInfoHeader( hBmpMask
1576 nWidth
= (int)vBmhdr
.cx
;
1577 nHeight
= (int)vBmhdr
.cy
;
1580 BITMAPINFOHEADER2 vBmih
;
1581 SIZEL vSize
= {0, 0};
1582 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1583 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1584 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1585 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1586 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1587 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1588 {0, 0}, {nWidth
, nHeight
}
1591 memset(&vBmih
, '\0', 16);
1596 vBmih
.cBitCount
= 24;
1598 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1605 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1606 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1616 ::GpiDestroyPS(hPSSrc
);
1617 ::GpiDestroyPS(hPSDst
);
1618 ::DevCloseDC(hDCSrc
);
1619 ::DevCloseDC(hDCDst
);
1622 } // end of WxWinGdi_InvertMask
1624 HBITMAP
wxFlipBmp( HBITMAP hBmp
, int nWidth
, int nHeight
)
1626 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxFlipBmp") );
1629 // Get width/height from the bitmap if not given
1631 if (!nWidth
|| !nHeight
)
1633 BITMAPINFOHEADER2 vBmhdr
;
1636 ::GpiQueryBitmapInfoHeader( hBmp
,
1638 nWidth
= (int)vBmhdr
.cx
;
1639 nHeight
= (int)vBmhdr
.cy
;
1642 BITMAPINFOHEADER2 vBmih
;
1643 SIZEL vSize
= {0, 0};
1644 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1645 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1649 (PDEVOPENDATA
)&vDop
,
1651 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1655 (PDEVOPENDATA
)&vDop
,
1657 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1660 PU_PELS
| GPIA_ASSOC
);
1661 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1664 PU_PELS
| GPIA_ASSOC
);
1665 POINTL vPoint
[4] = { {0, nHeight
},
1668 {nWidth
, nHeight
} };
1670 memset(&vBmih
, '\0', 16);
1675 vBmih
.cBitCount
= 24;
1677 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1683 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1684 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1686 ::GpiBitBlt( hPSDst
,
1693 ::GpiDestroyPS(hPSSrc
);
1694 ::GpiDestroyPS(hPSDst
);
1695 ::DevCloseDC(hDCSrc
);
1696 ::DevCloseDC(hDCDst
);
1699 } // end of wxFlipBmp