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/dc.h"
31 #include "wx/os2/private.h"
33 #include "wx/xpmdecod.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
40 IMPLEMENT_DYNAMIC_CLASS(wxMask
, 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)"));
91 } // end of wxBitmapRefData::Free
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const
99 return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData
*, data
));
102 // this function should be called from all wxBitmap ctors
103 void wxBitmap::Init()
107 // True for all bitmaps created from bits, wxImages, Xpms
109 } // end of wxBitmap::Init
111 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
113 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
114 POINTERINFO SIconInfo
;
116 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
118 wxLogLastError(wxT("WinQueryPointerInfo"));
121 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
123 m_refData
= pRefData
;
125 int nWidth
= rIcon
.GetWidth();
126 int nHeight
= rIcon
.GetHeight();
128 pRefData
->m_nWidth
= nWidth
;
129 pRefData
->m_nHeight
= nHeight
;
130 pRefData
->m_nDepth
= wxDisplayDepth();
132 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
134 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
136 pMask
->SetMaskBitmap(GetHBITMAP());
140 } // end of wxBitmap::CopyFromIconOrCursor
142 bool wxBitmap::CopyFromCursor(
143 const wxCursor
& rCursor
150 return(CopyFromIconOrCursor(rCursor
));
151 } // end of wxBitmap::CopyFromCursor
153 bool wxBitmap::CopyFromIcon(
162 return CopyFromIconOrCursor(rIcon
);
163 } // end of wxBitmap::CopyFromIcon
165 wxBitmap::~wxBitmap()
167 } // end of wxBitmap::~wxBitmap
178 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
179 BITMAPINFOHEADER2 vHeader
;
183 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
184 SIZEL vSize
= {0, 0};
187 wxASSERT(vHabmain
!= NULL
);
189 m_refData
= pRefData
;
191 pRefData
->m_nWidth
= nWidth
;
192 pRefData
->m_nHeight
= nHeight
;
193 pRefData
->m_nDepth
= nDepth
;
194 pRefData
->m_nNumColors
= 0;
195 pRefData
->m_pSelectedInto
= NULL
;
197 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
198 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
201 wxLogLastError(wxT("GpiCreatePS Failure"));
207 // We assume that it is in XBM format which is not quite the same as
208 // the format CreateBitmap() wants because the order of bytes in the
211 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
212 const size_t nPadding
= nBytesPerLine
% 2;
213 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
214 const char* pzSrc
= zBits
;
218 pzData
= (char *)malloc(nLen
);
220 char* pzDst
= pzData
;
222 for (nRows
= 0; nRows
< nHeight
; nRows
++)
224 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
226 unsigned char ucVal
= *pzSrc
++;
227 unsigned char ucReversed
= 0;
230 for (nBits
= 0; nBits
< 8; nBits
++)
233 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
236 *pzDst
++ = ucReversed
;
245 // Bits should already be in Windows standard format
247 pzData
= (char *)zBits
; // const_cast is harmless
251 nDepth
= 24; // MAX supported in PM
252 memset(&vHeader
, '\0', 16);
254 vHeader
.cx
= (USHORT
)nWidth
;
255 vHeader
.cy
= (USHORT
)nHeight
;
256 vHeader
.cPlanes
= 1L;
257 vHeader
.cBitCount
= (USHORT
)nDepth
;
258 vHeader
.usReserved
= 0;
260 memset(&vInfo
, '\0', 16);
262 vInfo
.cx
= (USHORT
)nWidth
;
263 vInfo
.cy
= (USHORT
)nHeight
;
265 vInfo
.cBitCount
= (USHORT
)nDepth
;
267 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
271 wxLogLastError(wxT("CreateBitmap"));
275 SetHBITMAP((WXHBITMAP
)hBmp
);
276 } // end of wxBitmap::wxBitmap
289 } // end of wxBitmap::wxBitmap
307 } // end of wxBitmap::wxBitmap
319 } // end of wxBitmap::wxBitmap
321 bool wxBitmap::Create(
328 BITMAPINFOHEADER2 vHeader
;
330 wxASSERT(vHabmain
!= NULL
);
332 m_refData
= new wxBitmapRefData
;
333 GetBitmapData()->m_nWidth
= nW
;
334 GetBitmapData()->m_nHeight
= nH
;
335 GetBitmapData()->m_nDepth
= nD
;
338 // Xpms and bitmaps from other images can also be mono's, but only
339 // mono's need help changing their colors with MemDC changes
343 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
344 SIZEL vSize
= {0, 0};
345 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
346 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
350 memset(&vHeader
, '\0', 16);
355 vHeader
.cBitCount
= 24; //nD;
357 hBmp
= ::GpiCreateBitmap( hPS
372 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
373 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
374 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
379 memset(&vHeader
, '\0', 16);
384 vHeader
.cBitCount
= (USHORT
)lBitCount
;
386 hBmp
= ::GpiCreateBitmap( hPSScreen
393 GetBitmapData()->m_nDepth
= wxDisplayDepth();
394 ::WinReleasePS(hPSScreen
);
396 SetHBITMAP((WXHBITMAP
)hBmp
);
399 } // end of wxBitmap::Create
401 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
405 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
409 m_refData
= new wxBitmapRefData
;
411 return handler
->LoadFile(this, filename
, type
, -1, -1);
414 else // no bitmap handler found
417 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
419 *this = wxBitmap(image
);
424 #endif // wxUSE_IMAGE
429 bool wxBitmap::LoadFile(
436 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
442 m_refData
= new wxBitmapRefData
;
444 return(pHandler
->LoadFile( this
455 } // end of wxBitmap::LoadFile
457 bool wxBitmap::Create(
467 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
473 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
478 m_refData
= new wxBitmapRefData
;
480 return(pHandler
->Create( this
487 } // end of wxBitmap::Create
489 bool wxBitmap::SaveFile(
490 const wxString
& rFilename
492 , const wxPalette
* pPalette
495 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
501 return pHandler
->SaveFile( this
509 // FIXME what about palette? shouldn't we use it?
510 wxImage vImage
= ConvertToImage();
515 return(vImage
.SaveFile( rFilename
519 } // end of wxBitmap::SaveFile
522 // ----------------------------------------------------------------------------
523 // wxImage-wxBitmap conversion
524 // ----------------------------------------------------------------------------
526 bool wxBitmap::CreateFromImage (
527 const wxImage
& rImage
531 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
532 m_refData
= new wxBitmapRefData();
534 int nSizeLimit
= 1024 * 768 * 3;
535 int nWidth
= rImage
.GetWidth();
536 int nBmpHeight
= rImage
.GetHeight();
537 int nBytePerLine
= nWidth
* 3;
538 int nSizeDWORD
= sizeof(DWORD
);
539 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
542 if (nLineBoundary
> 0)
544 nPadding
= nSizeDWORD
- nLineBoundary
;
545 nBytePerLine
+= nPadding
;
549 // Calc the number of DIBs and heights of DIBs
553 int nHeight
= nSizeLimit
/ nBytePerLine
;
555 if (nHeight
>= nBmpHeight
)
556 nHeight
= nBmpHeight
;
559 nNumDIB
= nBmpHeight
/ nHeight
;
560 nHRemain
= nBmpHeight
% nHeight
;
566 // Set bitmap parameters
568 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
570 SetHeight(nBmpHeight
);
576 nDepth
= wxDisplayDepth();
581 // Copy the palette from the source image
583 SetPalette(rImage
.GetPalette());
584 #endif // wxUSE_PALETTE
587 // Create a DIB header
589 BITMAPINFOHEADER2 vHeader
;
593 // Fill in the DIB header
595 memset(&vHeader
, '\0', 16);
597 vHeader
.cx
= (ULONG
)nWidth
;
598 vHeader
.cy
= (ULONG
)nHeight
;
599 vHeader
.cPlanes
= 1L;
600 vHeader
.cBitCount
= 24;
603 // Memory for DIB data
605 unsigned char* pucBits
;
607 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
610 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
613 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
616 // Create and set the device-dependent bitmap
618 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
619 SIZEL vSize
= {0, 0};
620 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
621 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
623 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
628 memset(&vInfo
, '\0', 16);
630 vInfo
.cx
= (ULONG
)nWidth
;
631 vInfo
.cy
= (ULONG
)nHeight
;
633 vInfo
.cBitCount
= 24; // Set to desired count going in
635 hBmp
= ::GpiCreateBitmap( hPS
642 HPAL hOldPalette
= NULLHANDLE
;
643 if (rImage
.GetPalette().Ok())
645 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
647 #endif // wxUSE_PALETTE
650 // Copy image data into DIB data and then into DDB (in a loop)
652 unsigned char* pData
= rImage
.GetData();
657 unsigned char* ptdata
= pData
;
658 unsigned char* ptbits
;
660 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
665 vError
= ::WinGetLastError(vHabmain
);
666 sError
= wxPMErrorToStr(vError
);
668 for (n
= 0; n
< nNumDIB
; n
++)
670 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
673 // Redefine height and size of the (possibly) last smaller DIB
674 // memory is not reallocated
677 vHeader
.cy
= (DWORD
)(nHeight
);
678 vHeader
.cbImage
= nBytePerLine
* nHeight
;
681 for (j
= 0; j
< nHeight
; j
++)
683 for (i
= 0; i
< nWidth
; i
++)
685 *(ptbits
++) = *(ptdata
+ 2);
686 *(ptbits
++) = *(ptdata
+ 1);
687 *(ptbits
++) = *(ptdata
);
690 for (i
= 0; i
< nPadding
; i
++)
695 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
696 // in combination with setting the bits into the selected bitmap
698 if ((lScans
= ::GpiSetBitmapBits( hPS
699 ,0 // Start at the bottom
700 ,(LONG
)nHeight
// One line per scan
708 vError
= ::WinGetLastError(vHabmain
);
709 sError
= wxPMErrorToStr(vError
);
711 hPSScreen
= ::GpiCreatePS( vHabmain
714 ,PU_PELS
| GPIA_ASSOC
717 POINTL vPoint
[4] = { {0, nOrigin
},
719 {0, 0}, {nWidth
, nHeight
}
723 ::GpiBitBlt( hPSScreen
730 ::GpiDestroyPS(hPSScreen
);
733 SetHBITMAP((WXHBITMAP
)hBmp
);
736 ::GpiSelectPalette(hPS
, hOldPalette
);
737 #endif // wxUSE_PALETTE
740 // Similarly, created an mono-bitmap for the possible mask
742 if (rImage
.HasMask())
746 vHeader
.cy
= nHeight
;
748 vHeader
.cBitCount
= 24;
749 hBmp
= ::GpiCreateBitmap( hPS
755 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
757 nHeight
= nBmpHeight
;
759 nHeight
= nSizeLimit
/ nBytePerLine
;
760 vHeader
.cy
= (DWORD
)(nHeight
);
763 unsigned char cRed
= rImage
.GetMaskRed();
764 unsigned char cGreen
= rImage
.GetMaskGreen();
765 unsigned char cBlue
= rImage
.GetMaskBlue();
766 unsigned char cZero
= 0;
767 unsigned char cOne
= 255;
770 for (n
= 0; n
< nNumDIB
; n
++)
772 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
775 // Redefine height and size of the (possibly) last smaller DIB
776 // memory is not reallocated
779 vHeader
.cy
= (DWORD
)(nHeight
);
780 vHeader
.cbImage
= nBytePerLine
* nHeight
;
783 for (int j
= 0; j
< nHeight
; j
++)
785 for (i
= 0; i
< nWidth
; i
++)
787 unsigned char cRedImage
= (*(ptdata
++)) ;
788 unsigned char cGreenImage
= (*(ptdata
++)) ;
789 unsigned char cBlueImage
= (*(ptdata
++)) ;
791 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
804 for (i
= 0; i
< nPadding
; i
++)
807 lScans
= ::GpiSetBitmapBits( hPS
808 ,0 // Start at the bottom
809 ,(LONG
)nHeight
// One line per scan
813 hPSScreen
= ::GpiCreatePS( vHabmain
816 ,PU_PELS
| GPIA_ASSOC
818 POINTL vPoint2
[4] = { {0, nOrigin
},
820 {0, 0}, {nWidth
, nHeight
}
822 ::GpiBitBlt( hPSScreen
829 ::GpiDestroyPS(hPSScreen
);
834 // Create a wxMask object
836 wxMask
* pMask
= new wxMask();
838 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
840 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
844 // Free allocated resources
846 ::GpiSetBitmap(hPS
, NULLHANDLE
);
848 ::DevCloseDC(hDCScreen
);
852 } // end of wxBitmap::CreateFromImage
854 wxImage
wxBitmap::ConvertToImage() const
859 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
862 // Create an wxImage object
864 int nWidth
= GetWidth();
865 int nHeight
= GetHeight();
868 int nBytePerLine
= nWidth
* 3;
869 int nSizeDWORD
= sizeof(DWORD
);
870 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
872 unsigned char* pData
;
873 unsigned char* lpBits
;
875 BITMAPINFOHEADER2 vDIBh
;
876 BITMAPINFO2 vDIBInfo
;
880 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
881 SIZEL vSizlPage
= {0,0};
882 HDC hDCMem
= NULLHANDLE
;
884 vImage
.Create( nWidth
887 pData
= vImage
.GetData();
890 wxFAIL_MSG( wxT("could not allocate data for image") );
893 if(nLineBoundary
> 0)
895 nPadding
= nSizeDWORD
- nLineBoundary
;
896 nBytePerLine
+= nPadding
;
898 wxDisplaySize( &nDevWidth
902 // Create and fill a DIB header
904 memset(&vDIBh
, '\0', 16);
909 vDIBh
.cBitCount
= 24;
911 memset(&vDIBInfo
, '\0', 16);
913 vDIBInfo
.cx
= nWidth
;
914 vDIBInfo
.cy
= nHeight
;
915 vDIBInfo
.cPlanes
= 1;
916 vDIBInfo
.cBitCount
= 24;
918 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
921 wxFAIL_MSG(wxT("could not allocate data for DIB"));
925 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
926 hBitmap
= (HBITMAP
)GetHBITMAP();
929 // May already be selected into a PS
931 pDC
= GetSelectedInto();
932 const wxPMDCImpl
*impl
;
934 (impl
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl
)) != NULL
)
936 hPSMem
= impl
->GetHPS();
940 hDCMem
= ::DevOpenDC( vHabmain
947 hPSMem
= ::GpiCreatePS( vHabmain
950 ,PU_PELS
| GPIA_ASSOC
953 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
958 vError
= ::WinGetLastError(vHabmain
);
959 sError
= wxPMErrorToStr(vError
);
963 // Copy data from the device-dependent bitmap to the DIB
965 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
975 vError
= ::WinGetLastError(vHabmain
);
976 sError
= wxPMErrorToStr(vError
);
980 // Copy DIB data into the wxImage object
984 unsigned char* ptdata
= pData
;
985 unsigned char* ptbits
= lpBits
;
987 for (i
= 0; i
< nHeight
; i
++)
989 for (j
= 0; j
< nWidth
; j
++)
991 *(ptdata
++) = *(ptbits
+2);
992 *(ptdata
++) = *(ptbits
+1);
993 *(ptdata
++) = *(ptbits
);
998 if ((pDC
= GetSelectedInto()) == NULL
)
1000 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
1001 ::GpiDestroyPS(hPSMem
);
1002 ::DevCloseDC(hDCMem
);
1006 // Similarly, set data according to the possible mask bitmap
1008 if (GetMask() && GetMask()->GetMaskBitmap())
1010 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1013 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1015 HDC hMemDC
= ::DevOpenDC( vHabmain
1019 ,(PDEVOPENDATA
)&vDop
1022 HPS hMemPS
= ::GpiCreatePS( vHabmain
1025 ,PU_PELS
| GPIA_ASSOC
1027 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1028 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1029 ::GpiSetBitmap(hMemPS
, hBitmap
);
1030 ::GpiQueryBitmapBits( hPSMem
1036 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1037 ::GpiDestroyPS(hMemPS
);
1038 ::DevCloseDC(hMemDC
);
1041 // Background color set to RGB(16,16,16) in consistent with wxGTK
1043 unsigned char ucRed
= 16;
1044 unsigned char ucGreen
= 16;
1045 unsigned char ucBlue
= 16;
1049 for (i
= 0; i
< nHeight
; i
++)
1051 for (j
= 0; j
< nWidth
; j
++)
1057 *(ptdata
++) = ucRed
;
1058 *(ptdata
++) = ucGreen
;
1059 *(ptdata
++) = ucBlue
;
1065 vImage
.SetMaskColour( ucRed
1069 vImage
.SetMask(true);
1073 vImage
.SetMask(false);
1077 // Free allocated resources
1081 } // end of wxBitmap::ConvertToImage
1083 // ----------------------------------------------------------------------------
1084 // sub bitmap extraction
1085 // ----------------------------------------------------------------------------
1087 wxBitmap
wxBitmap::GetSubBitmap(
1091 wxCHECK_MSG( Ok() &&
1092 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1093 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1094 (rRect
.y
+ rRect
.height
<= GetHeight()),
1095 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1097 wxBitmap
vRet( rRect
.width
1101 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1107 SIZEL vSize
= {0, 0};
1108 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1109 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1110 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1111 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1112 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1113 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1115 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1118 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1119 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1129 // Copy mask if there is one
1133 BITMAPINFOHEADER2 vBmih
;
1135 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1136 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1137 vBmih
.cx
= rRect
.width
;
1138 vBmih
.cy
= rRect
.height
;
1140 vBmih
.cBitCount
= 24;
1142 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1149 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1150 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1152 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1153 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1162 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1163 vRet
.SetMask(pMask
);
1166 ::GpiSetBitmap(hPSSrc
, NULL
);
1167 ::GpiSetBitmap(hPSDst
, NULL
);
1168 ::GpiDestroyPS(hPSSrc
);
1169 ::GpiDestroyPS(hPSDst
);
1170 ::DevCloseDC(hDCSrc
);
1171 ::DevCloseDC(hDCDst
);
1173 } // end of wxBitmap::GetSubBitmap
1175 // ----------------------------------------------------------------------------
1176 // wxBitmap accessors
1177 // ----------------------------------------------------------------------------
1179 void wxBitmap::SetQuality(
1185 GetBitmapData()->m_nQuality
= nQ
;
1186 } // end of wxBitmap::SetQuality
1188 void wxBitmap::SetPalette(
1189 const wxPalette
& rPalette
1194 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1195 } // end of wxBitmap::SetPalette
1197 void wxBitmap::SetMask(
1203 GetBitmapData()->m_pBitmapMask
= pMask
;
1204 } // end of wxBitmap::SetMask
1206 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1209 } // end of wxBitmap::GetBitmapForDC
1211 // ----------------------------------------------------------------------------
1213 // ----------------------------------------------------------------------------
1218 } // end of wxMask::wxMask
1220 wxMask::wxMask(const wxMask
& tocopy
)
1222 m_hMaskBitmap
= wxCopyBmp(tocopy
.m_hMaskBitmap
);
1223 } // end of wxMask::wxMask
1225 // Construct a mask from a bitmap and a colour indicating
1226 // the transparent area
1228 const wxBitmap
& rBitmap
1229 , const wxColour
& rColour
1236 } // end of wxMask::wxMask
1238 // Construct a mask from a bitmap and a palette index indicating
1239 // the transparent area
1241 const wxBitmap
& rBitmap
1249 } // end of wxMask::wxMask
1251 // Construct a mask from a mono bitmap (copies the bitmap).
1253 const wxBitmap
& rBitmap
1258 } // end of wxMask::wxMask
1263 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1264 } // end of wxMask::~wxMask
1266 // Create a mask from a mono bitmap (copies the bitmap).
1267 bool wxMask::Create(
1268 const wxBitmap
& rBitmap
1271 BITMAPINFOHEADER2 vBmih
;
1272 SIZEL vSize
= {0, 0};
1273 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1274 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1275 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1276 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1277 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1278 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1279 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1284 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1287 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1292 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1293 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1294 vBmih
.cx
= rBitmap
.GetWidth();
1295 vBmih
.cy
= rBitmap
.GetHeight();
1297 vBmih
.cBitCount
= 24;
1299 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1306 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1307 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1316 ::GpiDestroyPS(hPSSrc
);
1317 ::GpiDestroyPS(hPSDst
);
1318 ::DevCloseDC(hDCSrc
);
1319 ::DevCloseDC(hDCDst
);
1321 } // end of wxMask::Create
1323 // Create a mask from a bitmap and a palette index indicating
1324 // the transparent area
1325 bool wxMask::Create(
1326 const wxBitmap
& rBitmap
1332 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1335 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1338 unsigned char cGreen
;
1339 unsigned char cBlue
;
1341 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1347 wxColour
vTransparentColour( cRed
1352 return (Create( rBitmap
1358 } // end of wxMask::Create
1360 // Create a mask from a bitmap and a colour indicating
1361 // the transparent area
1362 bool wxMask::Create(
1363 const wxBitmap
& rBitmap
1364 , const wxColour
& rColour
1368 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1372 BITMAPINFOHEADER2 vBmih
;
1373 SIZEL vSize
= {0, 0};
1374 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1375 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1376 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1377 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1378 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1382 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1391 // Scan the bitmap for the transparent colour and set
1392 // the corresponding pixels in the mask to BLACK and
1393 // the rest to WHITE
1396 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1397 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1398 vBmih
.cx
= rBitmap
.GetWidth();
1399 vBmih
.cy
= rBitmap
.GetHeight();
1401 vBmih
.cBitCount
= 1;
1403 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1410 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1411 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1414 // This is not very efficient, but I can't think
1415 // of a better way of doing it
1417 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1419 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1421 POINTL vPt
= {w
, h
};
1422 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1423 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1426 // Doesn't make sense to continue
1432 if (vCol
== vMaskColour
)
1434 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1435 ::GpiSetPel(hPSDst
, &vPt
);
1439 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1440 ::GpiSetPel(hPSDst
, &vPt
);
1444 ::GpiSetBitmap(hPSSrc
, NULL
);
1445 ::GpiSetBitmap(hPSDst
, NULL
);
1446 ::GpiDestroyPS(hPSSrc
);
1447 ::GpiDestroyPS(hPSDst
);
1448 ::DevCloseDC(hDCSrc
);
1449 ::DevCloseDC(hDCDst
);
1451 } // end of wxMask::Create
1453 // ----------------------------------------------------------------------------
1455 // ----------------------------------------------------------------------------
1457 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1459 wxBitmapType
WXUNUSED(lFlags
),
1464 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1468 return(pBitmap
? Create( pBitmap
1476 bool wxBitmapHandler::Load(
1479 , wxBitmapType lFlags
1484 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1488 return(pBitmap
? LoadFile( pBitmap
1496 bool wxBitmapHandler::Save(
1498 , const wxString
& rName
1502 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1506 return(pBitmap
? SaveFile( pBitmap
1512 bool wxBitmapHandler::Create(
1513 wxBitmap
* WXUNUSED(pBitmap
)
1514 , const void* WXUNUSED(pData
)
1515 , wxBitmapType
WXUNUSED(lType
)
1516 , int WXUNUSED(nWidth
)
1517 , int WXUNUSED(nHeight
)
1518 , int WXUNUSED(nDepth
)
1524 bool wxBitmapHandler::LoadFile(
1525 wxBitmap
* WXUNUSED(pBitmap
)
1527 , wxBitmapType
WXUNUSED(lType
)
1528 , int WXUNUSED(nDesiredWidth
)
1529 , int WXUNUSED(nDesiredHeight
)
1535 bool wxBitmapHandler::LoadFile(
1536 wxBitmap
* WXUNUSED(pBitmap
)
1537 , const wxString
& WXUNUSED(rName
)
1538 , wxBitmapType
WXUNUSED(lType
)
1539 , int WXUNUSED(nDesiredWidth
)
1540 , int WXUNUSED(nDesiredHeight
)
1546 bool wxBitmapHandler::SaveFile(
1547 wxBitmap
* WXUNUSED(pBitmap
)
1548 , const wxString
& WXUNUSED(rName
)
1549 , wxBitmapType
WXUNUSED(nType
)
1550 , const wxPalette
* WXUNUSED(pPalette
)
1556 // ----------------------------------------------------------------------------
1557 // Utility functions
1558 // ----------------------------------------------------------------------------
1559 HBITMAP
wxInvertMask(
1565 HBITMAP hBmpInvMask
= 0;
1567 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1570 // Get width/height from the bitmap if not given
1572 if (!nWidth
|| !nHeight
)
1574 BITMAPINFOHEADER2 vBmhdr
;
1576 ::GpiQueryBitmapInfoHeader( hBmpMask
1579 nWidth
= (int)vBmhdr
.cx
;
1580 nHeight
= (int)vBmhdr
.cy
;
1583 BITMAPINFOHEADER2 vBmih
;
1584 SIZEL vSize
= {0, 0};
1585 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1586 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1587 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1588 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1589 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1590 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1591 {0, 0}, {nWidth
, nHeight
}
1594 memset(&vBmih
, '\0', 16);
1599 vBmih
.cBitCount
= 24;
1601 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1608 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1609 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1619 ::GpiDestroyPS(hPSSrc
);
1620 ::GpiDestroyPS(hPSDst
);
1621 ::DevCloseDC(hDCSrc
);
1622 ::DevCloseDC(hDCDst
);
1625 } // end of WxWinGdi_InvertMask
1627 HBITMAP
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight
)
1629 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxCopyBmp") );
1632 // Get width/height from the bitmap if not given
1634 if (!nWidth
|| !nHeight
)
1636 BITMAPINFOHEADER2 vBmhdr
;
1639 ::GpiQueryBitmapInfoHeader( hBmp
,
1641 nWidth
= (int)vBmhdr
.cx
;
1642 nHeight
= (int)vBmhdr
.cy
;
1645 BITMAPINFOHEADER2 vBmih
;
1646 SIZEL vSize
= {0, 0};
1647 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1648 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1652 (PDEVOPENDATA
)&vDop
,
1654 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1658 (PDEVOPENDATA
)&vDop
,
1660 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1663 PU_PELS
| GPIA_ASSOC
);
1664 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1667 PU_PELS
| GPIA_ASSOC
);
1668 POINTL vPoint
[4] = { {0, nHeight
},
1671 {nWidth
, nHeight
} };
1675 vPoint
[1].y
= 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