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
)
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
44 // ============================================================================
46 // ============================================================================
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 wxBitmapRefData::wxBitmapRefData()
55 m_pSelectedInto
= NULL
;
58 m_hBitmap
= (WXHBITMAP
) NULL
;
59 } // end of wxBitmapRefData::wxBitmapRefData
61 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData
&tocopy
)
63 m_nQuality
= tocopy
.m_nQuality
;
64 m_pSelectedInto
= NULL
; // don't copy this
65 m_nNumColors
= tocopy
.m_nNumColors
;
68 if (tocopy
.m_pBitmapMask
)
69 m_pBitmapMask
= new wxMask(*tocopy
.m_pBitmapMask
);
71 m_hBitmap
= wxCopyBmp(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 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const
100 return new wxBitmapRefData(*static_cast<const wxBitmapRefData
*>(data
));
103 // this function should be called from all wxBitmap ctors
104 void wxBitmap::Init()
108 // True for all bitmaps created from bits, wxImages, Xpms
110 } // end of wxBitmap::Init
112 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
114 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
115 POINTERINFO SIconInfo
;
117 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
119 wxLogLastError(wxT("WinQueryPointerInfo"));
122 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
124 m_refData
= pRefData
;
126 int nWidth
= rIcon
.GetWidth();
127 int nHeight
= rIcon
.GetHeight();
129 pRefData
->m_nWidth
= nWidth
;
130 pRefData
->m_nHeight
= nHeight
;
131 pRefData
->m_nDepth
= wxDisplayDepth();
133 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
135 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
137 pMask
->SetMaskBitmap(GetHBITMAP());
141 } // end of wxBitmap::CopyFromIconOrCursor
143 bool wxBitmap::CopyFromCursor(
144 const wxCursor
& rCursor
151 return(CopyFromIconOrCursor(rCursor
));
152 } // end of wxBitmap::CopyFromCursor
154 bool wxBitmap::CopyFromIcon(
163 return CopyFromIconOrCursor(rIcon
);
164 } // end of wxBitmap::CopyFromIcon
166 wxBitmap::~wxBitmap()
168 } // end of wxBitmap::~wxBitmap
179 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
180 BITMAPINFOHEADER2 vHeader
;
184 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
185 SIZEL vSize
= {0, 0};
188 wxASSERT(vHabmain
!= NULL
);
190 m_refData
= pRefData
;
192 pRefData
->m_nWidth
= nWidth
;
193 pRefData
->m_nHeight
= nHeight
;
194 pRefData
->m_nDepth
= nDepth
;
195 pRefData
->m_nNumColors
= 0;
196 pRefData
->m_pSelectedInto
= NULL
;
198 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
199 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
202 wxLogLastError(wxT("GpiCreatePS Failure"));
208 // We assume that it is in XBM format which is not quite the same as
209 // the format CreateBitmap() wants because the order of bytes in the
212 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
213 const size_t nPadding
= nBytesPerLine
% 2;
214 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
215 const char* pzSrc
= zBits
;
219 pzData
= (char *)malloc(nLen
);
221 char* pzDst
= pzData
;
223 for (nRows
= 0; nRows
< nHeight
; nRows
++)
225 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
227 unsigned char ucVal
= *pzSrc
++;
228 unsigned char ucReversed
= 0;
231 for (nBits
= 0; nBits
< 8; nBits
++)
234 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
237 *pzDst
++ = ucReversed
;
246 // Bits should already be in Windows standard format
248 pzData
= (char *)zBits
; // const_cast is harmless
252 nDepth
= 24; // MAX supported in PM
253 memset(&vHeader
, '\0', 16);
255 vHeader
.cx
= (USHORT
)nWidth
;
256 vHeader
.cy
= (USHORT
)nHeight
;
257 vHeader
.cPlanes
= 1L;
258 vHeader
.cBitCount
= (USHORT
)nDepth
;
259 vHeader
.usReserved
= 0;
261 memset(&vInfo
, '\0', 16);
263 vInfo
.cx
= (USHORT
)nWidth
;
264 vInfo
.cy
= (USHORT
)nHeight
;
266 vInfo
.cBitCount
= (USHORT
)nDepth
;
268 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
272 wxLogLastError(wxT("CreateBitmap"));
276 SetHBITMAP((WXHBITMAP
)hBmp
);
277 } // end of wxBitmap::wxBitmap
290 } // end of wxBitmap::wxBitmap
308 } // end of wxBitmap::wxBitmap
320 } // end of wxBitmap::wxBitmap
322 bool wxBitmap::Create(
329 BITMAPINFOHEADER2 vHeader
;
331 wxASSERT(vHabmain
!= NULL
);
333 m_refData
= new wxBitmapRefData
;
334 GetBitmapData()->m_nWidth
= nW
;
335 GetBitmapData()->m_nHeight
= nH
;
336 GetBitmapData()->m_nDepth
= nD
;
339 // Xpms and bitmaps from other images can also be mono's, but only
340 // mono's need help changing their colors with MemDC changes
344 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
345 SIZEL vSize
= {0, 0};
346 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
347 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
351 memset(&vHeader
, '\0', 16);
356 vHeader
.cBitCount
= 24; //nD;
358 hBmp
= ::GpiCreateBitmap( hPS
373 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
374 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
375 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
380 memset(&vHeader
, '\0', 16);
385 vHeader
.cBitCount
= (USHORT
)lBitCount
;
387 hBmp
= ::GpiCreateBitmap( hPSScreen
394 GetBitmapData()->m_nDepth
= wxDisplayDepth();
395 ::WinReleasePS(hPSScreen
);
397 SetHBITMAP((WXHBITMAP
)hBmp
);
400 } // end of wxBitmap::Create
402 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
)
406 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
410 m_refData
= new wxBitmapRefData
;
412 return handler
->LoadFile(this, filename
, type
, -1, -1);
415 else // no bitmap handler found
418 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
420 *this = wxBitmap(image
);
425 #endif // wxUSE_IMAGE
430 bool wxBitmap::LoadFile(
437 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
443 m_refData
= new wxBitmapRefData
;
445 return(pHandler
->LoadFile( this
456 } // end of wxBitmap::LoadFile
458 bool wxBitmap::Create(
468 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
474 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
479 m_refData
= new wxBitmapRefData
;
481 return(pHandler
->Create( this
488 } // end of wxBitmap::Create
490 bool wxBitmap::SaveFile(
491 const wxString
& rFilename
493 , const wxPalette
* pPalette
496 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
502 return pHandler
->SaveFile( this
510 // FIXME what about palette? shouldn't we use it?
511 wxImage vImage
= ConvertToImage();
516 return(vImage
.SaveFile( rFilename
520 } // end of wxBitmap::SaveFile
523 // ----------------------------------------------------------------------------
524 // wxImage-wxBitmap conversion
525 // ----------------------------------------------------------------------------
527 bool wxBitmap::CreateFromImage (
528 const wxImage
& rImage
532 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
533 m_refData
= new wxBitmapRefData();
535 int nSizeLimit
= 1024 * 768 * 3;
536 int nWidth
= rImage
.GetWidth();
537 int nBmpHeight
= rImage
.GetHeight();
538 int nBytePerLine
= nWidth
* 3;
539 int nSizeDWORD
= sizeof(DWORD
);
540 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
543 if (nLineBoundary
> 0)
545 nPadding
= nSizeDWORD
- nLineBoundary
;
546 nBytePerLine
+= nPadding
;
550 // Calc the number of DIBs and heights of DIBs
554 int nHeight
= nSizeLimit
/ nBytePerLine
;
556 if (nHeight
>= nBmpHeight
)
557 nHeight
= nBmpHeight
;
560 nNumDIB
= nBmpHeight
/ nHeight
;
561 nHRemain
= nBmpHeight
% nHeight
;
567 // Set bitmap parameters
569 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
571 SetHeight(nBmpHeight
);
577 nDepth
= wxDisplayDepth();
582 // Copy the palette from the source image
584 SetPalette(rImage
.GetPalette());
585 #endif // wxUSE_PALETTE
588 // Create a DIB header
590 BITMAPINFOHEADER2 vHeader
;
594 // Fill in the DIB header
596 memset(&vHeader
, '\0', 16);
598 vHeader
.cx
= (ULONG
)nWidth
;
599 vHeader
.cy
= (ULONG
)nHeight
;
600 vHeader
.cPlanes
= 1L;
601 vHeader
.cBitCount
= 24;
604 // Memory for DIB data
606 unsigned char* pucBits
;
608 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
611 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
614 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
617 // Create and set the device-dependent bitmap
619 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
620 SIZEL vSize
= {0, 0};
621 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
622 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
624 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
629 memset(&vInfo
, '\0', 16);
631 vInfo
.cx
= (ULONG
)nWidth
;
632 vInfo
.cy
= (ULONG
)nHeight
;
634 vInfo
.cBitCount
= 24; // Set to desired count going in
636 hBmp
= ::GpiCreateBitmap( hPS
643 HPAL hOldPalette
= NULLHANDLE
;
644 if (rImage
.GetPalette().Ok())
646 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
648 #endif // wxUSE_PALETTE
651 // Copy image data into DIB data and then into DDB (in a loop)
653 unsigned char* pData
= rImage
.GetData();
658 unsigned char* ptdata
= pData
;
659 unsigned char* ptbits
;
661 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
666 vError
= ::WinGetLastError(vHabmain
);
667 sError
= wxPMErrorToStr(vError
);
669 for (n
= 0; n
< nNumDIB
; n
++)
671 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
674 // Redefine height and size of the (possibly) last smaller DIB
675 // memory is not reallocated
678 vHeader
.cy
= (DWORD
)(nHeight
);
679 vHeader
.cbImage
= nBytePerLine
* nHeight
;
682 for (j
= 0; j
< nHeight
; j
++)
684 for (i
= 0; i
< nWidth
; i
++)
686 *(ptbits
++) = *(ptdata
+ 2);
687 *(ptbits
++) = *(ptdata
+ 1);
688 *(ptbits
++) = *(ptdata
);
691 for (i
= 0; i
< nPadding
; i
++)
696 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
697 // in combination with setting the bits into the selected bitmap
699 if ((lScans
= ::GpiSetBitmapBits( hPS
700 ,0 // Start at the bottom
701 ,(LONG
)nHeight
// One line per scan
709 vError
= ::WinGetLastError(vHabmain
);
710 sError
= wxPMErrorToStr(vError
);
712 hPSScreen
= ::GpiCreatePS( vHabmain
715 ,PU_PELS
| GPIA_ASSOC
718 POINTL vPoint
[4] = { {0, nOrigin
},
720 {0, 0}, {nWidth
, nHeight
}
724 ::GpiBitBlt( hPSScreen
731 ::GpiDestroyPS(hPSScreen
);
734 SetHBITMAP((WXHBITMAP
)hBmp
);
737 ::GpiSelectPalette(hPS
, hOldPalette
);
738 #endif // wxUSE_PALETTE
741 // Similarly, created an mono-bitmap for the possible mask
743 if (rImage
.HasMask())
747 vHeader
.cy
= nHeight
;
749 vHeader
.cBitCount
= 24;
750 hBmp
= ::GpiCreateBitmap( hPS
756 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
758 nHeight
= nBmpHeight
;
760 nHeight
= nSizeLimit
/ nBytePerLine
;
761 vHeader
.cy
= (DWORD
)(nHeight
);
764 unsigned char cRed
= rImage
.GetMaskRed();
765 unsigned char cGreen
= rImage
.GetMaskGreen();
766 unsigned char cBlue
= rImage
.GetMaskBlue();
767 unsigned char cZero
= 0;
768 unsigned char cOne
= 255;
771 for (n
= 0; n
< nNumDIB
; n
++)
773 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
776 // Redefine height and size of the (possibly) last smaller DIB
777 // memory is not reallocated
780 vHeader
.cy
= (DWORD
)(nHeight
);
781 vHeader
.cbImage
= nBytePerLine
* nHeight
;
784 for (int j
= 0; j
< nHeight
; j
++)
786 for (i
= 0; i
< nWidth
; i
++)
788 unsigned char cRedImage
= (*(ptdata
++)) ;
789 unsigned char cGreenImage
= (*(ptdata
++)) ;
790 unsigned char cBlueImage
= (*(ptdata
++)) ;
792 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
805 for (i
= 0; i
< nPadding
; i
++)
808 lScans
= ::GpiSetBitmapBits( hPS
809 ,0 // Start at the bottom
810 ,(LONG
)nHeight
// One line per scan
814 hPSScreen
= ::GpiCreatePS( vHabmain
817 ,PU_PELS
| GPIA_ASSOC
819 POINTL vPoint2
[4] = { {0, nOrigin
},
821 {0, 0}, {nWidth
, nHeight
}
823 ::GpiBitBlt( hPSScreen
830 ::GpiDestroyPS(hPSScreen
);
835 // Create a wxMask object
837 wxMask
* pMask
= new wxMask();
839 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
841 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
845 // Free allocated resources
847 ::GpiSetBitmap(hPS
, NULLHANDLE
);
849 ::DevCloseDC(hDCScreen
);
853 } // end of wxBitmap::CreateFromImage
855 wxImage
wxBitmap::ConvertToImage() const
860 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
863 // Create an wxImage object
865 int nWidth
= GetWidth();
866 int nHeight
= GetHeight();
869 int nBytePerLine
= nWidth
* 3;
870 int nSizeDWORD
= sizeof(DWORD
);
871 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
873 unsigned char* pData
;
874 unsigned char* lpBits
;
876 BITMAPINFOHEADER2 vDIBh
;
877 BITMAPINFO2 vDIBInfo
;
881 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
882 SIZEL vSizlPage
= {0,0};
883 HDC hDCMem
= NULLHANDLE
;
885 vImage
.Create( nWidth
888 pData
= vImage
.GetData();
891 wxFAIL_MSG( wxT("could not allocate data for image") );
894 if(nLineBoundary
> 0)
896 nPadding
= nSizeDWORD
- nLineBoundary
;
897 nBytePerLine
+= nPadding
;
899 wxDisplaySize( &nDevWidth
903 // Create and fill a DIB header
905 memset(&vDIBh
, '\0', 16);
910 vDIBh
.cBitCount
= 24;
912 memset(&vDIBInfo
, '\0', 16);
914 vDIBInfo
.cx
= nWidth
;
915 vDIBInfo
.cy
= nHeight
;
916 vDIBInfo
.cPlanes
= 1;
917 vDIBInfo
.cBitCount
= 24;
919 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
922 wxFAIL_MSG(wxT("could not allocate data for DIB"));
926 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
927 hBitmap
= (HBITMAP
)GetHBITMAP();
930 // May already be selected into a PS
932 pDC
= GetSelectedInto();
933 const wxPMDCImpl
*impl
;
935 (impl
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl
)) != NULL
)
937 hPSMem
= impl
->GetHPS();
941 hDCMem
= ::DevOpenDC( vHabmain
948 hPSMem
= ::GpiCreatePS( vHabmain
951 ,PU_PELS
| GPIA_ASSOC
954 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
959 vError
= ::WinGetLastError(vHabmain
);
960 sError
= wxPMErrorToStr(vError
);
964 // Copy data from the device-dependent bitmap to the DIB
966 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
976 vError
= ::WinGetLastError(vHabmain
);
977 sError
= wxPMErrorToStr(vError
);
981 // Copy DIB data into the wxImage object
985 unsigned char* ptdata
= pData
;
986 unsigned char* ptbits
= lpBits
;
988 for (i
= 0; i
< nHeight
; i
++)
990 for (j
= 0; j
< nWidth
; j
++)
992 *(ptdata
++) = *(ptbits
+2);
993 *(ptdata
++) = *(ptbits
+1);
994 *(ptdata
++) = *(ptbits
);
999 if ((pDC
= GetSelectedInto()) == NULL
)
1001 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
1002 ::GpiDestroyPS(hPSMem
);
1003 ::DevCloseDC(hDCMem
);
1007 // Similarly, set data according to the possible mask bitmap
1009 if (GetMask() && GetMask()->GetMaskBitmap())
1011 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1014 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1016 HDC hMemDC
= ::DevOpenDC( vHabmain
1020 ,(PDEVOPENDATA
)&vDop
1023 HPS hMemPS
= ::GpiCreatePS( vHabmain
1026 ,PU_PELS
| GPIA_ASSOC
1028 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1029 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1030 ::GpiSetBitmap(hMemPS
, hBitmap
);
1031 ::GpiQueryBitmapBits( hPSMem
1037 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1038 ::GpiDestroyPS(hMemPS
);
1039 ::DevCloseDC(hMemDC
);
1042 // Background color set to RGB(16,16,16) in consistent with wxGTK
1044 unsigned char ucRed
= 16;
1045 unsigned char ucGreen
= 16;
1046 unsigned char ucBlue
= 16;
1050 for (i
= 0; i
< nHeight
; i
++)
1052 for (j
= 0; j
< nWidth
; j
++)
1058 *(ptdata
++) = ucRed
;
1059 *(ptdata
++) = ucGreen
;
1060 *(ptdata
++) = ucBlue
;
1066 vImage
.SetMaskColour( ucRed
1070 vImage
.SetMask(true);
1074 vImage
.SetMask(false);
1078 // Free allocated resources
1082 } // end of wxBitmap::ConvertToImage
1084 // ----------------------------------------------------------------------------
1085 // sub bitmap extraction
1086 // ----------------------------------------------------------------------------
1088 wxBitmap
wxBitmap::GetSubBitmap(
1092 wxCHECK_MSG( Ok() &&
1093 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1094 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1095 (rRect
.y
+ rRect
.height
<= GetHeight()),
1096 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1098 wxBitmap
vRet( rRect
.width
1102 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1108 SIZEL vSize
= {0, 0};
1109 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1110 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1111 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1112 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1113 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1114 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1116 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1119 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1120 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1130 // Copy mask if there is one
1134 BITMAPINFOHEADER2 vBmih
;
1136 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1137 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1138 vBmih
.cx
= rRect
.width
;
1139 vBmih
.cy
= rRect
.height
;
1141 vBmih
.cBitCount
= 24;
1143 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1150 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1151 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1153 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1154 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1163 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1164 vRet
.SetMask(pMask
);
1167 ::GpiSetBitmap(hPSSrc
, NULL
);
1168 ::GpiSetBitmap(hPSDst
, NULL
);
1169 ::GpiDestroyPS(hPSSrc
);
1170 ::GpiDestroyPS(hPSDst
);
1171 ::DevCloseDC(hDCSrc
);
1172 ::DevCloseDC(hDCDst
);
1174 } // end of wxBitmap::GetSubBitmap
1176 // ----------------------------------------------------------------------------
1177 // wxBitmap accessors
1178 // ----------------------------------------------------------------------------
1180 void wxBitmap::SetQuality(
1186 GetBitmapData()->m_nQuality
= nQ
;
1187 } // end of wxBitmap::SetQuality
1189 void wxBitmap::SetPalette(
1190 const wxPalette
& rPalette
1195 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1196 } // end of wxBitmap::SetPalette
1198 void wxBitmap::SetMask(
1204 GetBitmapData()->m_pBitmapMask
= pMask
;
1205 } // end of wxBitmap::SetMask
1207 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1210 } // end of wxBitmap::GetBitmapForDC
1212 // ----------------------------------------------------------------------------
1214 // ----------------------------------------------------------------------------
1219 } // end of wxMask::wxMask
1221 wxMask::wxMask(const wxMask
& tocopy
)
1223 m_hMaskBitmap
= wxCopyBmp(tocopy
.m_hMaskBitmap
);
1224 } // end of wxMask::wxMask
1226 // Construct a mask from a bitmap and a colour indicating
1227 // the transparent area
1229 const wxBitmap
& rBitmap
1230 , const wxColour
& rColour
1237 } // end of wxMask::wxMask
1239 // Construct a mask from a bitmap and a palette index indicating
1240 // the transparent area
1242 const wxBitmap
& rBitmap
1250 } // end of wxMask::wxMask
1252 // Construct a mask from a mono bitmap (copies the bitmap).
1254 const wxBitmap
& rBitmap
1259 } // end of wxMask::wxMask
1264 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1265 } // end of wxMask::~wxMask
1267 // Create a mask from a mono bitmap (copies the bitmap).
1268 bool wxMask::Create(
1269 const wxBitmap
& rBitmap
1272 BITMAPINFOHEADER2 vBmih
;
1273 SIZEL vSize
= {0, 0};
1274 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1275 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1276 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1277 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1278 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1279 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1280 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1285 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1288 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1293 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1294 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1295 vBmih
.cx
= rBitmap
.GetWidth();
1296 vBmih
.cy
= rBitmap
.GetHeight();
1298 vBmih
.cBitCount
= 24;
1300 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1307 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1308 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1317 ::GpiDestroyPS(hPSSrc
);
1318 ::GpiDestroyPS(hPSDst
);
1319 ::DevCloseDC(hDCSrc
);
1320 ::DevCloseDC(hDCDst
);
1322 } // end of wxMask::Create
1324 // Create a mask from a bitmap and a palette index indicating
1325 // the transparent area
1326 bool wxMask::Create(
1327 const wxBitmap
& rBitmap
1333 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1336 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1339 unsigned char cGreen
;
1340 unsigned char cBlue
;
1342 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1348 wxColour
vTransparentColour( cRed
1353 return (Create( rBitmap
1359 } // end of wxMask::Create
1361 // Create a mask from a bitmap and a colour indicating
1362 // the transparent area
1363 bool wxMask::Create(
1364 const wxBitmap
& rBitmap
1365 , const wxColour
& rColour
1369 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1373 BITMAPINFOHEADER2 vBmih
;
1374 SIZEL vSize
= {0, 0};
1375 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1376 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1377 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1378 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1379 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1383 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1392 // Scan the bitmap for the transparent colour and set
1393 // the corresponding pixels in the mask to BLACK and
1394 // the rest to WHITE
1397 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1398 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1399 vBmih
.cx
= rBitmap
.GetWidth();
1400 vBmih
.cy
= rBitmap
.GetHeight();
1402 vBmih
.cBitCount
= 1;
1404 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1411 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1412 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1415 // This is not very efficient, but I can't think
1416 // of a better way of doing it
1418 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1420 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1422 POINTL vPt
= {w
, h
};
1423 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1424 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1427 // Doesn't make sense to continue
1433 if (vCol
== vMaskColour
)
1435 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1436 ::GpiSetPel(hPSDst
, &vPt
);
1440 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1441 ::GpiSetPel(hPSDst
, &vPt
);
1445 ::GpiSetBitmap(hPSSrc
, NULL
);
1446 ::GpiSetBitmap(hPSDst
, NULL
);
1447 ::GpiDestroyPS(hPSSrc
);
1448 ::GpiDestroyPS(hPSDst
);
1449 ::DevCloseDC(hDCSrc
);
1450 ::DevCloseDC(hDCDst
);
1452 } // end of wxMask::Create
1454 // ----------------------------------------------------------------------------
1456 // ----------------------------------------------------------------------------
1458 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1465 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1469 return(pBitmap
? Create( pBitmap
1478 bool wxBitmapHandler::Load(
1481 , wxBitmapType lFlags
1486 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1490 return(pBitmap
? LoadFile( pBitmap
1498 bool wxBitmapHandler::Save(
1499 const wxGDIImage
* pImage
1500 , const wxString
& rName
1501 , wxBitmapType lType
1504 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1508 return(pBitmap
? SaveFile( pBitmap
1514 bool wxBitmapHandler::Create(
1515 wxBitmap
* WXUNUSED(pBitmap
)
1516 , const void* WXUNUSED(pData
)
1517 , wxBitmapType
WXUNUSED(lType
)
1518 , int WXUNUSED(nWidth
)
1519 , int WXUNUSED(nHeight
)
1520 , int WXUNUSED(nDepth
)
1526 bool wxBitmapHandler::LoadFile(
1527 wxBitmap
* WXUNUSED(pBitmap
)
1529 , wxBitmapType
WXUNUSED(lType
)
1530 , int WXUNUSED(nDesiredWidth
)
1531 , int WXUNUSED(nDesiredHeight
)
1537 bool wxBitmapHandler::LoadFile(
1538 wxBitmap
* WXUNUSED(pBitmap
)
1539 , const wxString
& WXUNUSED(rName
)
1540 , wxBitmapType
WXUNUSED(lType
)
1541 , int WXUNUSED(nDesiredWidth
)
1542 , int WXUNUSED(nDesiredHeight
)
1548 bool wxBitmapHandler::SaveFile(
1549 wxBitmap
* WXUNUSED(pBitmap
)
1550 , const wxString
& WXUNUSED(rName
)
1551 , wxBitmapType
WXUNUSED(nType
)
1552 , const wxPalette
* WXUNUSED(pPalette
)
1558 // ----------------------------------------------------------------------------
1559 // Utility functions
1560 // ----------------------------------------------------------------------------
1561 HBITMAP
wxInvertMask(
1567 HBITMAP hBmpInvMask
= 0;
1569 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1572 // Get width/height from the bitmap if not given
1574 if (!nWidth
|| !nHeight
)
1576 BITMAPINFOHEADER2 vBmhdr
;
1578 ::GpiQueryBitmapInfoHeader( hBmpMask
1581 nWidth
= (int)vBmhdr
.cx
;
1582 nHeight
= (int)vBmhdr
.cy
;
1585 BITMAPINFOHEADER2 vBmih
;
1586 SIZEL vSize
= {0, 0};
1587 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1588 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1589 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1590 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1591 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1592 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1593 {0, 0}, {nWidth
, nHeight
}
1596 memset(&vBmih
, '\0', 16);
1601 vBmih
.cBitCount
= 24;
1603 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1610 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1611 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1621 ::GpiDestroyPS(hPSSrc
);
1622 ::GpiDestroyPS(hPSDst
);
1623 ::DevCloseDC(hDCSrc
);
1624 ::DevCloseDC(hDCDst
);
1627 } // end of WxWinGdi_InvertMask
1629 HBITMAP
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight
)
1631 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxCopyBmp") );
1634 // Get width/height from the bitmap if not given
1636 if (!nWidth
|| !nHeight
)
1638 BITMAPINFOHEADER2 vBmhdr
;
1641 ::GpiQueryBitmapInfoHeader( hBmp
,
1643 nWidth
= (int)vBmhdr
.cx
;
1644 nHeight
= (int)vBmhdr
.cy
;
1647 BITMAPINFOHEADER2 vBmih
;
1648 SIZEL vSize
= {0, 0};
1649 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1650 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1654 (PDEVOPENDATA
)&vDop
,
1656 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1660 (PDEVOPENDATA
)&vDop
,
1662 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1665 PU_PELS
| GPIA_ASSOC
);
1666 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1669 PU_PELS
| GPIA_ASSOC
);
1670 POINTL vPoint
[4] = { {0, nHeight
},
1673 {nWidth
, nHeight
} };
1677 vPoint
[1].y
= nHeight
;
1679 memset(&vBmih
, '\0', 16);
1684 vBmih
.cBitCount
= 24;
1686 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1692 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1693 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1695 ::GpiBitBlt( hPSDst
,
1702 ::GpiDestroyPS(hPSSrc
);
1703 ::GpiDestroyPS(hPSDst
);
1704 ::DevCloseDC(hDCSrc
);
1705 ::DevCloseDC(hDCDst
);
1708 } // end of wxFlipBmp