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
295 } // end of wxBitmap::wxBitmap
307 } // end of wxBitmap::wxBitmap
309 bool wxBitmap::Create(
316 BITMAPINFOHEADER2 vHeader
;
318 wxASSERT(vHabmain
!= NULL
);
320 m_refData
= new wxBitmapRefData
;
321 GetBitmapData()->m_nWidth
= nW
;
322 GetBitmapData()->m_nHeight
= nH
;
323 GetBitmapData()->m_nDepth
= nD
;
326 // Xpms and bitmaps from other images can also be mono's, but only
327 // mono's need help changing their colors with MemDC changes
331 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
332 SIZEL vSize
= {0, 0};
333 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
334 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
338 memset(&vHeader
, '\0', 16);
343 vHeader
.cBitCount
= 24; //nD;
345 hBmp
= ::GpiCreateBitmap( hPS
360 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
361 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
362 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
367 memset(&vHeader
, '\0', 16);
372 vHeader
.cBitCount
= (USHORT
)lBitCount
;
374 hBmp
= ::GpiCreateBitmap( hPSScreen
381 GetBitmapData()->m_nDepth
= wxDisplayDepth();
382 ::WinReleasePS(hPSScreen
);
384 SetHBITMAP((WXHBITMAP
)hBmp
);
387 } // end of wxBitmap::Create
389 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
)
393 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
397 m_refData
= new wxBitmapRefData
;
399 return handler
->LoadFile(this, filename
, type
, -1, -1);
402 else // no bitmap handler found
405 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
407 *this = wxBitmap(image
);
412 #endif // wxUSE_IMAGE
417 bool wxBitmap::LoadFile(
424 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
430 m_refData
= new wxBitmapRefData
;
432 return(pHandler
->LoadFile( this
443 } // end of wxBitmap::LoadFile
445 bool wxBitmap::Create(
455 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
461 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
466 m_refData
= new wxBitmapRefData
;
468 return(pHandler
->Create( this
475 } // end of wxBitmap::Create
477 bool wxBitmap::SaveFile(
478 const wxString
& rFilename
480 , const wxPalette
* pPalette
483 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
489 return pHandler
->SaveFile( this
497 // FIXME what about palette? shouldn't we use it?
498 wxImage vImage
= ConvertToImage();
503 return(vImage
.SaveFile( rFilename
507 } // end of wxBitmap::SaveFile
510 // ----------------------------------------------------------------------------
511 // wxImage-wxBitmap conversion
512 // ----------------------------------------------------------------------------
514 bool wxBitmap::CreateFromImage (
515 const wxImage
& rImage
519 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
520 m_refData
= new wxBitmapRefData();
522 int nSizeLimit
= 1024 * 768 * 3;
523 int nWidth
= rImage
.GetWidth();
524 int nBmpHeight
= rImage
.GetHeight();
525 int nBytePerLine
= nWidth
* 3;
526 int nSizeDWORD
= sizeof(DWORD
);
527 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
530 if (nLineBoundary
> 0)
532 nPadding
= nSizeDWORD
- nLineBoundary
;
533 nBytePerLine
+= nPadding
;
537 // Calc the number of DIBs and heights of DIBs
541 int nHeight
= nSizeLimit
/ nBytePerLine
;
543 if (nHeight
>= nBmpHeight
)
544 nHeight
= nBmpHeight
;
547 nNumDIB
= nBmpHeight
/ nHeight
;
548 nHRemain
= nBmpHeight
% nHeight
;
554 // Set bitmap parameters
556 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
558 SetHeight(nBmpHeight
);
564 nDepth
= wxDisplayDepth();
569 // Copy the palette from the source image
571 SetPalette(rImage
.GetPalette());
572 #endif // wxUSE_PALETTE
575 // Create a DIB header
577 BITMAPINFOHEADER2 vHeader
;
581 // Fill in the DIB header
583 memset(&vHeader
, '\0', 16);
585 vHeader
.cx
= (ULONG
)nWidth
;
586 vHeader
.cy
= (ULONG
)nHeight
;
587 vHeader
.cPlanes
= 1L;
588 vHeader
.cBitCount
= 24;
591 // Memory for DIB data
593 unsigned char* pucBits
;
595 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
598 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
601 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
604 // Create and set the device-dependent bitmap
606 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
607 SIZEL vSize
= {0, 0};
608 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
609 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
611 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
616 memset(&vInfo
, '\0', 16);
618 vInfo
.cx
= (ULONG
)nWidth
;
619 vInfo
.cy
= (ULONG
)nHeight
;
621 vInfo
.cBitCount
= 24; // Set to desired count going in
623 hBmp
= ::GpiCreateBitmap( hPS
630 HPAL hOldPalette
= NULLHANDLE
;
631 if (rImage
.GetPalette().Ok())
633 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
635 #endif // wxUSE_PALETTE
638 // Copy image data into DIB data and then into DDB (in a loop)
640 unsigned char* pData
= rImage
.GetData();
645 unsigned char* ptdata
= pData
;
646 unsigned char* ptbits
;
648 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
653 vError
= ::WinGetLastError(vHabmain
);
654 sError
= wxPMErrorToStr(vError
);
656 for (n
= 0; n
< nNumDIB
; n
++)
658 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
661 // Redefine height and size of the (possibly) last smaller DIB
662 // memory is not reallocated
665 vHeader
.cy
= (DWORD
)(nHeight
);
666 vHeader
.cbImage
= nBytePerLine
* nHeight
;
669 for (j
= 0; j
< nHeight
; j
++)
671 for (i
= 0; i
< nWidth
; i
++)
673 *(ptbits
++) = *(ptdata
+ 2);
674 *(ptbits
++) = *(ptdata
+ 1);
675 *(ptbits
++) = *(ptdata
);
678 for (i
= 0; i
< nPadding
; i
++)
683 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
684 // in combination with setting the bits into the selected bitmap
686 if ((lScans
= ::GpiSetBitmapBits( hPS
687 ,0 // Start at the bottom
688 ,(LONG
)nHeight
// One line per scan
696 vError
= ::WinGetLastError(vHabmain
);
697 sError
= wxPMErrorToStr(vError
);
699 hPSScreen
= ::GpiCreatePS( vHabmain
702 ,PU_PELS
| GPIA_ASSOC
705 POINTL vPoint
[4] = { {0, nOrigin
},
707 {0, 0}, {nWidth
, nHeight
}
711 ::GpiBitBlt( hPSScreen
718 ::GpiDestroyPS(hPSScreen
);
721 SetHBITMAP((WXHBITMAP
)hBmp
);
724 ::GpiSelectPalette(hPS
, hOldPalette
);
725 #endif // wxUSE_PALETTE
728 // Similarly, created an mono-bitmap for the possible mask
730 if (rImage
.HasMask())
734 vHeader
.cy
= nHeight
;
736 vHeader
.cBitCount
= 24;
737 hBmp
= ::GpiCreateBitmap( hPS
743 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
745 nHeight
= nBmpHeight
;
747 nHeight
= nSizeLimit
/ nBytePerLine
;
748 vHeader
.cy
= (DWORD
)(nHeight
);
751 unsigned char cRed
= rImage
.GetMaskRed();
752 unsigned char cGreen
= rImage
.GetMaskGreen();
753 unsigned char cBlue
= rImage
.GetMaskBlue();
754 unsigned char cZero
= 0;
755 unsigned char cOne
= 255;
758 for (n
= 0; n
< nNumDIB
; n
++)
760 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
763 // Redefine height and size of the (possibly) last smaller DIB
764 // memory is not reallocated
767 vHeader
.cy
= (DWORD
)(nHeight
);
768 vHeader
.cbImage
= nBytePerLine
* nHeight
;
771 for (int j
= 0; j
< nHeight
; j
++)
773 for (i
= 0; i
< nWidth
; i
++)
775 unsigned char cRedImage
= (*(ptdata
++)) ;
776 unsigned char cGreenImage
= (*(ptdata
++)) ;
777 unsigned char cBlueImage
= (*(ptdata
++)) ;
779 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
792 for (i
= 0; i
< nPadding
; i
++)
795 lScans
= ::GpiSetBitmapBits( hPS
796 ,0 // Start at the bottom
797 ,(LONG
)nHeight
// One line per scan
801 hPSScreen
= ::GpiCreatePS( vHabmain
804 ,PU_PELS
| GPIA_ASSOC
806 POINTL vPoint2
[4] = { {0, nOrigin
},
808 {0, 0}, {nWidth
, nHeight
}
810 ::GpiBitBlt( hPSScreen
817 ::GpiDestroyPS(hPSScreen
);
822 // Create a wxMask object
824 wxMask
* pMask
= new wxMask();
826 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
828 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
832 // Free allocated resources
834 ::GpiSetBitmap(hPS
, NULLHANDLE
);
836 ::DevCloseDC(hDCScreen
);
840 } // end of wxBitmap::CreateFromImage
842 wxImage
wxBitmap::ConvertToImage() const
847 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
850 // Create an wxImage object
852 int nWidth
= GetWidth();
853 int nHeight
= GetHeight();
856 int nBytePerLine
= nWidth
* 3;
857 int nSizeDWORD
= sizeof(DWORD
);
858 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
860 unsigned char* pData
;
861 unsigned char* lpBits
;
863 BITMAPINFOHEADER2 vDIBh
;
864 BITMAPINFO2 vDIBInfo
;
868 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
869 SIZEL vSizlPage
= {0,0};
870 HDC hDCMem
= NULLHANDLE
;
872 vImage
.Create( nWidth
875 pData
= vImage
.GetData();
878 wxFAIL_MSG( wxT("could not allocate data for image") );
881 if(nLineBoundary
> 0)
883 nPadding
= nSizeDWORD
- nLineBoundary
;
884 nBytePerLine
+= nPadding
;
886 wxDisplaySize( &nDevWidth
890 // Create and fill a DIB header
892 memset(&vDIBh
, '\0', 16);
897 vDIBh
.cBitCount
= 24;
899 memset(&vDIBInfo
, '\0', 16);
901 vDIBInfo
.cx
= nWidth
;
902 vDIBInfo
.cy
= nHeight
;
903 vDIBInfo
.cPlanes
= 1;
904 vDIBInfo
.cBitCount
= 24;
906 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
909 wxFAIL_MSG(wxT("could not allocate data for DIB"));
913 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
914 hBitmap
= (HBITMAP
)GetHBITMAP();
917 // May already be selected into a PS
919 pDC
= GetSelectedInto();
920 const wxPMDCImpl
*impl
;
922 (impl
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl
)) != NULL
)
924 hPSMem
= impl
->GetHPS();
928 hDCMem
= ::DevOpenDC( vHabmain
935 hPSMem
= ::GpiCreatePS( vHabmain
938 ,PU_PELS
| GPIA_ASSOC
941 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
946 vError
= ::WinGetLastError(vHabmain
);
947 sError
= wxPMErrorToStr(vError
);
951 // Copy data from the device-dependent bitmap to the DIB
953 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
963 vError
= ::WinGetLastError(vHabmain
);
964 sError
= wxPMErrorToStr(vError
);
968 // Copy DIB data into the wxImage object
972 unsigned char* ptdata
= pData
;
973 unsigned char* ptbits
= lpBits
;
975 for (i
= 0; i
< nHeight
; i
++)
977 for (j
= 0; j
< nWidth
; j
++)
979 *(ptdata
++) = *(ptbits
+2);
980 *(ptdata
++) = *(ptbits
+1);
981 *(ptdata
++) = *(ptbits
);
986 if ((pDC
= GetSelectedInto()) == NULL
)
988 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
989 ::GpiDestroyPS(hPSMem
);
990 ::DevCloseDC(hDCMem
);
994 // Similarly, set data according to the possible mask bitmap
996 if (GetMask() && GetMask()->GetMaskBitmap())
998 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1001 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1003 HDC hMemDC
= ::DevOpenDC( vHabmain
1007 ,(PDEVOPENDATA
)&vDop
1010 HPS hMemPS
= ::GpiCreatePS( vHabmain
1013 ,PU_PELS
| GPIA_ASSOC
1015 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1016 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1017 ::GpiSetBitmap(hMemPS
, hBitmap
);
1018 ::GpiQueryBitmapBits( hPSMem
1024 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1025 ::GpiDestroyPS(hMemPS
);
1026 ::DevCloseDC(hMemDC
);
1029 // Background color set to RGB(16,16,16) in consistent with wxGTK
1031 unsigned char ucRed
= 16;
1032 unsigned char ucGreen
= 16;
1033 unsigned char ucBlue
= 16;
1037 for (i
= 0; i
< nHeight
; i
++)
1039 for (j
= 0; j
< nWidth
; j
++)
1045 *(ptdata
++) = ucRed
;
1046 *(ptdata
++) = ucGreen
;
1047 *(ptdata
++) = ucBlue
;
1053 vImage
.SetMaskColour( ucRed
1057 vImage
.SetMask(true);
1061 vImage
.SetMask(false);
1065 // Free allocated resources
1069 } // end of wxBitmap::ConvertToImage
1071 // ----------------------------------------------------------------------------
1072 // sub bitmap extraction
1073 // ----------------------------------------------------------------------------
1075 wxBitmap
wxBitmap::GetSubBitmap(
1079 wxCHECK_MSG( Ok() &&
1080 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1081 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1082 (rRect
.y
+ rRect
.height
<= GetHeight()),
1083 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1085 wxBitmap
vRet( rRect
.width
1089 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1095 SIZEL vSize
= {0, 0};
1096 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1097 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1098 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1099 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1100 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1101 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1103 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1106 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1107 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1117 // Copy mask if there is one
1121 BITMAPINFOHEADER2 vBmih
;
1123 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1124 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1125 vBmih
.cx
= rRect
.width
;
1126 vBmih
.cy
= rRect
.height
;
1128 vBmih
.cBitCount
= 24;
1130 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1137 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1138 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1140 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1141 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1150 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1151 vRet
.SetMask(pMask
);
1154 ::GpiSetBitmap(hPSSrc
, NULL
);
1155 ::GpiSetBitmap(hPSDst
, NULL
);
1156 ::GpiDestroyPS(hPSSrc
);
1157 ::GpiDestroyPS(hPSDst
);
1158 ::DevCloseDC(hDCSrc
);
1159 ::DevCloseDC(hDCDst
);
1161 } // end of wxBitmap::GetSubBitmap
1163 // ----------------------------------------------------------------------------
1164 // wxBitmap accessors
1165 // ----------------------------------------------------------------------------
1167 void wxBitmap::SetQuality(
1173 GetBitmapData()->m_nQuality
= nQ
;
1174 } // end of wxBitmap::SetQuality
1176 void wxBitmap::SetPalette(
1177 const wxPalette
& rPalette
1182 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1183 } // end of wxBitmap::SetPalette
1185 void wxBitmap::SetMask(
1191 GetBitmapData()->m_pBitmapMask
= pMask
;
1192 } // end of wxBitmap::SetMask
1194 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1197 } // end of wxBitmap::GetBitmapForDC
1199 // ----------------------------------------------------------------------------
1201 // ----------------------------------------------------------------------------
1206 } // end of wxMask::wxMask
1208 wxMask::wxMask(const wxMask
& tocopy
)
1210 m_hMaskBitmap
= wxCopyBmp(tocopy
.m_hMaskBitmap
);
1211 } // end of wxMask::wxMask
1213 // Construct a mask from a bitmap and a colour indicating
1214 // the transparent area
1216 const wxBitmap
& rBitmap
1217 , const wxColour
& rColour
1224 } // end of wxMask::wxMask
1226 // Construct a mask from a bitmap and a palette index indicating
1227 // the transparent area
1229 const wxBitmap
& rBitmap
1237 } // end of wxMask::wxMask
1239 // Construct a mask from a mono bitmap (copies the bitmap).
1241 const wxBitmap
& rBitmap
1246 } // end of wxMask::wxMask
1251 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1252 } // end of wxMask::~wxMask
1254 // Create a mask from a mono bitmap (copies the bitmap).
1255 bool wxMask::Create(
1256 const wxBitmap
& rBitmap
1259 BITMAPINFOHEADER2 vBmih
;
1260 SIZEL vSize
= {0, 0};
1261 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1262 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1263 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1264 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1265 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1266 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1267 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1272 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1275 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1280 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1281 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1282 vBmih
.cx
= rBitmap
.GetWidth();
1283 vBmih
.cy
= rBitmap
.GetHeight();
1285 vBmih
.cBitCount
= 24;
1287 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1294 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1295 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1304 ::GpiDestroyPS(hPSSrc
);
1305 ::GpiDestroyPS(hPSDst
);
1306 ::DevCloseDC(hDCSrc
);
1307 ::DevCloseDC(hDCDst
);
1309 } // end of wxMask::Create
1311 // Create a mask from a bitmap and a palette index indicating
1312 // the transparent area
1313 bool wxMask::Create(
1314 const wxBitmap
& rBitmap
1320 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1323 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1326 unsigned char cGreen
;
1327 unsigned char cBlue
;
1329 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1335 wxColour
vTransparentColour( cRed
1340 return (Create( rBitmap
1346 } // end of wxMask::Create
1348 // Create a mask from a bitmap and a colour indicating
1349 // the transparent area
1350 bool wxMask::Create(
1351 const wxBitmap
& rBitmap
1352 , const wxColour
& rColour
1356 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1360 BITMAPINFOHEADER2 vBmih
;
1361 SIZEL vSize
= {0, 0};
1362 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1363 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1364 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1365 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1366 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1370 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1379 // Scan the bitmap for the transparent colour and set
1380 // the corresponding pixels in the mask to BLACK and
1381 // the rest to WHITE
1384 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1385 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1386 vBmih
.cx
= rBitmap
.GetWidth();
1387 vBmih
.cy
= rBitmap
.GetHeight();
1389 vBmih
.cBitCount
= 1;
1391 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1398 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1399 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1402 // This is not very efficient, but I can't think
1403 // of a better way of doing it
1405 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1407 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1409 POINTL vPt
= {w
, h
};
1410 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1411 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1414 // Doesn't make sense to continue
1420 if (vCol
== vMaskColour
)
1422 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1423 ::GpiSetPel(hPSDst
, &vPt
);
1427 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1428 ::GpiSetPel(hPSDst
, &vPt
);
1432 ::GpiSetBitmap(hPSSrc
, NULL
);
1433 ::GpiSetBitmap(hPSDst
, NULL
);
1434 ::GpiDestroyPS(hPSSrc
);
1435 ::GpiDestroyPS(hPSDst
);
1436 ::DevCloseDC(hDCSrc
);
1437 ::DevCloseDC(hDCDst
);
1439 } // end of wxMask::Create
1441 // ----------------------------------------------------------------------------
1443 // ----------------------------------------------------------------------------
1445 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1452 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1456 return(pBitmap
? Create( pBitmap
1465 bool wxBitmapHandler::Load(
1468 , wxBitmapType lFlags
1473 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1477 return(pBitmap
? LoadFile( pBitmap
1485 bool wxBitmapHandler::Save(
1486 const wxGDIImage
* pImage
1487 , const wxString
& rName
1488 , wxBitmapType lType
1491 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1495 return(pBitmap
? SaveFile( pBitmap
1501 bool wxBitmapHandler::Create(
1502 wxBitmap
* WXUNUSED(pBitmap
)
1503 , const void* WXUNUSED(pData
)
1504 , wxBitmapType
WXUNUSED(lType
)
1505 , int WXUNUSED(nWidth
)
1506 , int WXUNUSED(nHeight
)
1507 , int WXUNUSED(nDepth
)
1513 bool wxBitmapHandler::LoadFile(
1514 wxBitmap
* WXUNUSED(pBitmap
)
1516 , wxBitmapType
WXUNUSED(lType
)
1517 , int WXUNUSED(nDesiredWidth
)
1518 , int WXUNUSED(nDesiredHeight
)
1524 bool wxBitmapHandler::LoadFile(
1525 wxBitmap
* WXUNUSED(pBitmap
)
1526 , const wxString
& WXUNUSED(rName
)
1527 , wxBitmapType
WXUNUSED(lType
)
1528 , int WXUNUSED(nDesiredWidth
)
1529 , int WXUNUSED(nDesiredHeight
)
1535 bool wxBitmapHandler::SaveFile(
1536 wxBitmap
* WXUNUSED(pBitmap
)
1537 , const wxString
& WXUNUSED(rName
)
1538 , wxBitmapType
WXUNUSED(nType
)
1539 , const wxPalette
* WXUNUSED(pPalette
)
1545 // ----------------------------------------------------------------------------
1546 // Utility functions
1547 // ----------------------------------------------------------------------------
1548 HBITMAP
wxInvertMask(
1554 HBITMAP hBmpInvMask
= 0;
1556 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1559 // Get width/height from the bitmap if not given
1561 if (!nWidth
|| !nHeight
)
1563 BITMAPINFOHEADER2 vBmhdr
;
1565 ::GpiQueryBitmapInfoHeader( hBmpMask
1568 nWidth
= (int)vBmhdr
.cx
;
1569 nHeight
= (int)vBmhdr
.cy
;
1572 BITMAPINFOHEADER2 vBmih
;
1573 SIZEL vSize
= {0, 0};
1574 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1575 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1576 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1577 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1578 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1579 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1580 {0, 0}, {nWidth
, nHeight
}
1583 memset(&vBmih
, '\0', 16);
1588 vBmih
.cBitCount
= 24;
1590 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1597 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1598 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1608 ::GpiDestroyPS(hPSSrc
);
1609 ::GpiDestroyPS(hPSDst
);
1610 ::DevCloseDC(hDCSrc
);
1611 ::DevCloseDC(hDCDst
);
1614 } // end of WxWinGdi_InvertMask
1616 HBITMAP
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight
)
1618 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxCopyBmp") );
1621 // Get width/height from the bitmap if not given
1623 if (!nWidth
|| !nHeight
)
1625 BITMAPINFOHEADER2 vBmhdr
;
1628 ::GpiQueryBitmapInfoHeader( hBmp
,
1630 nWidth
= (int)vBmhdr
.cx
;
1631 nHeight
= (int)vBmhdr
.cy
;
1634 BITMAPINFOHEADER2 vBmih
;
1635 SIZEL vSize
= {0, 0};
1636 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1637 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1641 (PDEVOPENDATA
)&vDop
,
1643 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1647 (PDEVOPENDATA
)&vDop
,
1649 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1652 PU_PELS
| GPIA_ASSOC
);
1653 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1656 PU_PELS
| GPIA_ASSOC
);
1657 POINTL vPoint
[4] = { {0, nHeight
},
1660 {nWidth
, nHeight
} };
1664 vPoint
[1].y
= nHeight
;
1666 memset(&vBmih
, '\0', 16);
1671 vBmih
.cBitCount
= 24;
1673 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1679 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1680 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1682 ::GpiBitBlt( hPSDst
,
1689 ::GpiDestroyPS(hPSSrc
);
1690 ::GpiDestroyPS(hPSDst
);
1691 ::DevCloseDC(hDCSrc
);
1692 ::DevCloseDC(hDCDst
);
1695 } // end of wxFlipBmp