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)"));
87 wxDELETE(m_pBitmapMask
);
88 } // end of wxBitmapRefData::Free
90 // ----------------------------------------------------------------------------
92 // ----------------------------------------------------------------------------
94 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const
96 return new wxBitmapRefData(*static_cast<const wxBitmapRefData
*>(data
));
99 // this function should be called from all wxBitmap ctors
100 void wxBitmap::Init()
104 // True for all bitmaps created from bits, wxImages, Xpms
106 } // end of wxBitmap::Init
108 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
110 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
111 POINTERINFO SIconInfo
;
113 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
115 wxLogLastError(wxT("WinQueryPointerInfo"));
118 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
120 m_refData
= pRefData
;
122 int nWidth
= rIcon
.GetWidth();
123 int nHeight
= rIcon
.GetHeight();
125 pRefData
->m_nWidth
= nWidth
;
126 pRefData
->m_nHeight
= nHeight
;
127 pRefData
->m_nDepth
= wxDisplayDepth();
129 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
131 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
133 pMask
->SetMaskBitmap(GetHBITMAP());
137 } // end of wxBitmap::CopyFromIconOrCursor
139 bool wxBitmap::CopyFromCursor(
140 const wxCursor
& rCursor
147 return(CopyFromIconOrCursor(rCursor
));
148 } // end of wxBitmap::CopyFromCursor
150 bool wxBitmap::CopyFromIcon(
159 return CopyFromIconOrCursor(rIcon
);
160 } // end of wxBitmap::CopyFromIcon
162 wxBitmap::~wxBitmap()
164 } // end of wxBitmap::~wxBitmap
175 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
176 BITMAPINFOHEADER2 vHeader
;
180 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
181 SIZEL vSize
= {0, 0};
184 wxASSERT(vHabmain
!= NULL
);
186 m_refData
= pRefData
;
188 pRefData
->m_nWidth
= nWidth
;
189 pRefData
->m_nHeight
= nHeight
;
190 pRefData
->m_nDepth
= nDepth
;
191 pRefData
->m_nNumColors
= 0;
192 pRefData
->m_pSelectedInto
= NULL
;
194 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
195 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
198 wxLogLastError(wxT("GpiCreatePS Failure"));
204 // We assume that it is in XBM format which is not quite the same as
205 // the format CreateBitmap() wants because the order of bytes in the
208 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
209 const size_t nPadding
= nBytesPerLine
% 2;
210 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
211 const char* pzSrc
= zBits
;
215 pzData
= (char *)malloc(nLen
);
217 char* pzDst
= pzData
;
219 for (nRows
= 0; nRows
< nHeight
; nRows
++)
221 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
223 unsigned char ucVal
= *pzSrc
++;
224 unsigned char ucReversed
= 0;
227 for (nBits
= 0; nBits
< 8; nBits
++)
230 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
233 *pzDst
++ = ucReversed
;
242 // Bits should already be in Windows standard format
244 pzData
= (char *)zBits
; // const_cast is harmless
248 nDepth
= 24; // MAX supported in PM
249 memset(&vHeader
, '\0', 16);
251 vHeader
.cx
= (USHORT
)nWidth
;
252 vHeader
.cy
= (USHORT
)nHeight
;
253 vHeader
.cPlanes
= 1L;
254 vHeader
.cBitCount
= (USHORT
)nDepth
;
255 vHeader
.usReserved
= 0;
257 memset(&vInfo
, '\0', 16);
259 vInfo
.cx
= (USHORT
)nWidth
;
260 vInfo
.cy
= (USHORT
)nHeight
;
262 vInfo
.cBitCount
= (USHORT
)nDepth
;
264 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
268 wxLogLastError(wxT("CreateBitmap"));
272 SetHBITMAP((WXHBITMAP
)hBmp
);
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::LoadFile(const wxString
& filename
, wxBitmapType type
)
389 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
393 m_refData
= new wxBitmapRefData
;
395 return handler
->LoadFile(this, filename
, type
, -1, -1);
398 else // no bitmap handler found
401 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
403 *this = wxBitmap(image
);
408 #endif // wxUSE_IMAGE
413 bool wxBitmap::LoadFile(
420 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
426 m_refData
= new wxBitmapRefData
;
428 return(pHandler
->LoadFile( this
439 } // end of wxBitmap::LoadFile
441 bool wxBitmap::Create(
451 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
457 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
462 m_refData
= new wxBitmapRefData
;
464 return(pHandler
->Create( this
471 } // end of wxBitmap::Create
473 bool wxBitmap::SaveFile(
474 const wxString
& rFilename
476 , const wxPalette
* pPalette
479 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
485 return pHandler
->SaveFile( this
493 // FIXME what about palette? shouldn't we use it?
494 wxImage vImage
= ConvertToImage();
499 return(vImage
.SaveFile( rFilename
503 } // end of wxBitmap::SaveFile
506 // ----------------------------------------------------------------------------
507 // wxImage-wxBitmap conversion
508 // ----------------------------------------------------------------------------
510 bool wxBitmap::CreateFromImage (
511 const wxImage
& rImage
515 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
516 m_refData
= new wxBitmapRefData();
518 int nSizeLimit
= 1024 * 768 * 3;
519 int nWidth
= rImage
.GetWidth();
520 int nBmpHeight
= rImage
.GetHeight();
521 int nBytePerLine
= nWidth
* 3;
522 int nSizeDWORD
= sizeof(DWORD
);
523 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
526 if (nLineBoundary
> 0)
528 nPadding
= nSizeDWORD
- nLineBoundary
;
529 nBytePerLine
+= nPadding
;
533 // Calc the number of DIBs and heights of DIBs
537 int nHeight
= nSizeLimit
/ nBytePerLine
;
539 if (nHeight
>= nBmpHeight
)
540 nHeight
= nBmpHeight
;
543 nNumDIB
= nBmpHeight
/ nHeight
;
544 nHRemain
= nBmpHeight
% nHeight
;
550 // Set bitmap parameters
552 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
554 SetHeight(nBmpHeight
);
560 nDepth
= wxDisplayDepth();
565 // Copy the palette from the source image
567 SetPalette(rImage
.GetPalette());
568 #endif // wxUSE_PALETTE
571 // Create a DIB header
573 BITMAPINFOHEADER2 vHeader
;
577 // Fill in the DIB header
579 memset(&vHeader
, '\0', 16);
581 vHeader
.cx
= (ULONG
)nWidth
;
582 vHeader
.cy
= (ULONG
)nHeight
;
583 vHeader
.cPlanes
= 1L;
584 vHeader
.cBitCount
= 24;
587 // Memory for DIB data
589 unsigned char* pucBits
;
591 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
594 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
597 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
600 // Create and set the device-dependent bitmap
602 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
603 SIZEL vSize
= {0, 0};
604 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
605 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
607 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
612 memset(&vInfo
, '\0', 16);
614 vInfo
.cx
= (ULONG
)nWidth
;
615 vInfo
.cy
= (ULONG
)nHeight
;
617 vInfo
.cBitCount
= 24; // Set to desired count going in
619 hBmp
= ::GpiCreateBitmap( hPS
626 HPAL hOldPalette
= NULLHANDLE
;
627 if (rImage
.GetPalette().Ok())
629 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
631 #endif // wxUSE_PALETTE
634 // Copy image data into DIB data and then into DDB (in a loop)
636 unsigned char* pData
= rImage
.GetData();
641 unsigned char* ptdata
= pData
;
642 unsigned char* ptbits
;
644 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
649 vError
= ::WinGetLastError(vHabmain
);
650 sError
= wxPMErrorToStr(vError
);
652 for (n
= 0; n
< nNumDIB
; n
++)
654 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
657 // Redefine height and size of the (possibly) last smaller DIB
658 // memory is not reallocated
661 vHeader
.cy
= (DWORD
)(nHeight
);
662 vHeader
.cbImage
= nBytePerLine
* nHeight
;
665 for (j
= 0; j
< nHeight
; j
++)
667 for (i
= 0; i
< nWidth
; i
++)
669 *(ptbits
++) = *(ptdata
+ 2);
670 *(ptbits
++) = *(ptdata
+ 1);
671 *(ptbits
++) = *(ptdata
);
674 for (i
= 0; i
< nPadding
; i
++)
679 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
680 // in combination with setting the bits into the selected bitmap
682 if ((lScans
= ::GpiSetBitmapBits( hPS
683 ,0 // Start at the bottom
684 ,(LONG
)nHeight
// One line per scan
692 vError
= ::WinGetLastError(vHabmain
);
693 sError
= wxPMErrorToStr(vError
);
695 hPSScreen
= ::GpiCreatePS( vHabmain
698 ,PU_PELS
| GPIA_ASSOC
701 POINTL vPoint
[4] = { {0, nOrigin
},
703 {0, 0}, {nWidth
, nHeight
}
707 ::GpiBitBlt( hPSScreen
714 ::GpiDestroyPS(hPSScreen
);
717 SetHBITMAP((WXHBITMAP
)hBmp
);
720 ::GpiSelectPalette(hPS
, hOldPalette
);
721 #endif // wxUSE_PALETTE
724 // Similarly, created an mono-bitmap for the possible mask
726 if (rImage
.HasMask())
730 vHeader
.cy
= nHeight
;
732 vHeader
.cBitCount
= 24;
733 hBmp
= ::GpiCreateBitmap( hPS
739 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
741 nHeight
= nBmpHeight
;
743 nHeight
= nSizeLimit
/ nBytePerLine
;
744 vHeader
.cy
= (DWORD
)(nHeight
);
747 unsigned char cRed
= rImage
.GetMaskRed();
748 unsigned char cGreen
= rImage
.GetMaskGreen();
749 unsigned char cBlue
= rImage
.GetMaskBlue();
750 unsigned char cZero
= 0;
751 unsigned char cOne
= 255;
754 for (n
= 0; n
< nNumDIB
; n
++)
756 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
759 // Redefine height and size of the (possibly) last smaller DIB
760 // memory is not reallocated
763 vHeader
.cy
= (DWORD
)(nHeight
);
764 vHeader
.cbImage
= nBytePerLine
* nHeight
;
767 for (int j
= 0; j
< nHeight
; j
++)
769 for (i
= 0; i
< nWidth
; i
++)
771 unsigned char cRedImage
= (*(ptdata
++)) ;
772 unsigned char cGreenImage
= (*(ptdata
++)) ;
773 unsigned char cBlueImage
= (*(ptdata
++)) ;
775 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
788 for (i
= 0; i
< nPadding
; i
++)
791 lScans
= ::GpiSetBitmapBits( hPS
792 ,0 // Start at the bottom
793 ,(LONG
)nHeight
// One line per scan
797 hPSScreen
= ::GpiCreatePS( vHabmain
800 ,PU_PELS
| GPIA_ASSOC
802 POINTL vPoint2
[4] = { {0, nOrigin
},
804 {0, 0}, {nWidth
, nHeight
}
806 ::GpiBitBlt( hPSScreen
813 ::GpiDestroyPS(hPSScreen
);
818 // Create a wxMask object
820 wxMask
* pMask
= new wxMask();
822 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
824 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
828 // Free allocated resources
830 ::GpiSetBitmap(hPS
, NULLHANDLE
);
832 ::DevCloseDC(hDCScreen
);
836 } // end of wxBitmap::CreateFromImage
838 wxImage
wxBitmap::ConvertToImage() const
843 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
846 // Create an wxImage object
848 int nWidth
= GetWidth();
849 int nHeight
= GetHeight();
852 int nBytePerLine
= nWidth
* 3;
853 int nSizeDWORD
= sizeof(DWORD
);
854 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
856 unsigned char* pData
;
857 unsigned char* lpBits
;
859 BITMAPINFOHEADER2 vDIBh
;
860 BITMAPINFO2 vDIBInfo
;
864 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
865 SIZEL vSizlPage
= {0,0};
866 HDC hDCMem
= NULLHANDLE
;
868 vImage
.Create( nWidth
871 pData
= vImage
.GetData();
874 wxFAIL_MSG( wxT("could not allocate data for image") );
877 if(nLineBoundary
> 0)
879 nPadding
= nSizeDWORD
- nLineBoundary
;
880 nBytePerLine
+= nPadding
;
882 wxDisplaySize( &nDevWidth
886 // Create and fill a DIB header
888 memset(&vDIBh
, '\0', 16);
893 vDIBh
.cBitCount
= 24;
895 memset(&vDIBInfo
, '\0', 16);
897 vDIBInfo
.cx
= nWidth
;
898 vDIBInfo
.cy
= nHeight
;
899 vDIBInfo
.cPlanes
= 1;
900 vDIBInfo
.cBitCount
= 24;
902 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
905 wxFAIL_MSG(wxT("could not allocate data for DIB"));
909 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
910 hBitmap
= (HBITMAP
)GetHBITMAP();
913 // May already be selected into a PS
915 pDC
= GetSelectedInto();
916 const wxPMDCImpl
*impl
;
918 (impl
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl
)) != NULL
)
920 hPSMem
= impl
->GetHPS();
924 hDCMem
= ::DevOpenDC( vHabmain
931 hPSMem
= ::GpiCreatePS( vHabmain
934 ,PU_PELS
| GPIA_ASSOC
937 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
942 vError
= ::WinGetLastError(vHabmain
);
943 sError
= wxPMErrorToStr(vError
);
947 // Copy data from the device-dependent bitmap to the DIB
949 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
959 vError
= ::WinGetLastError(vHabmain
);
960 sError
= wxPMErrorToStr(vError
);
964 // Copy DIB data into the wxImage object
968 unsigned char* ptdata
= pData
;
969 unsigned char* ptbits
= lpBits
;
971 for (i
= 0; i
< nHeight
; i
++)
973 for (j
= 0; j
< nWidth
; j
++)
975 *(ptdata
++) = *(ptbits
+2);
976 *(ptdata
++) = *(ptbits
+1);
977 *(ptdata
++) = *(ptbits
);
982 if ((pDC
= GetSelectedInto()) == NULL
)
984 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
985 ::GpiDestroyPS(hPSMem
);
986 ::DevCloseDC(hDCMem
);
990 // Similarly, set data according to the possible mask bitmap
992 if (GetMask() && GetMask()->GetMaskBitmap())
994 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
997 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
999 HDC hMemDC
= ::DevOpenDC( vHabmain
1003 ,(PDEVOPENDATA
)&vDop
1006 HPS hMemPS
= ::GpiCreatePS( vHabmain
1009 ,PU_PELS
| GPIA_ASSOC
1011 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1012 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1013 ::GpiSetBitmap(hMemPS
, hBitmap
);
1014 ::GpiQueryBitmapBits( hPSMem
1020 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1021 ::GpiDestroyPS(hMemPS
);
1022 ::DevCloseDC(hMemDC
);
1025 // Background color set to RGB(16,16,16) in consistent with wxGTK
1027 unsigned char ucRed
= 16;
1028 unsigned char ucGreen
= 16;
1029 unsigned char ucBlue
= 16;
1033 for (i
= 0; i
< nHeight
; i
++)
1035 for (j
= 0; j
< nWidth
; j
++)
1041 *(ptdata
++) = ucRed
;
1042 *(ptdata
++) = ucGreen
;
1043 *(ptdata
++) = ucBlue
;
1049 vImage
.SetMaskColour( ucRed
1053 vImage
.SetMask(true);
1057 vImage
.SetMask(false);
1061 // Free allocated resources
1065 } // end of wxBitmap::ConvertToImage
1067 // ----------------------------------------------------------------------------
1068 // sub bitmap extraction
1069 // ----------------------------------------------------------------------------
1071 wxBitmap
wxBitmap::GetSubBitmap(
1075 wxCHECK_MSG( Ok() &&
1076 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1077 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1078 (rRect
.y
+ rRect
.height
<= GetHeight()),
1079 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1081 wxBitmap
vRet( rRect
.width
1085 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1091 SIZEL vSize
= {0, 0};
1092 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1093 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1094 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1095 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1096 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1097 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1099 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1102 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1103 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1113 // Copy mask if there is one
1117 BITMAPINFOHEADER2 vBmih
;
1119 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1120 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1121 vBmih
.cx
= rRect
.width
;
1122 vBmih
.cy
= rRect
.height
;
1124 vBmih
.cBitCount
= 24;
1126 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1133 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1134 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1136 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1137 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1146 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1147 vRet
.SetMask(pMask
);
1150 ::GpiSetBitmap(hPSSrc
, NULL
);
1151 ::GpiSetBitmap(hPSDst
, NULL
);
1152 ::GpiDestroyPS(hPSSrc
);
1153 ::GpiDestroyPS(hPSDst
);
1154 ::DevCloseDC(hDCSrc
);
1155 ::DevCloseDC(hDCDst
);
1157 } // end of wxBitmap::GetSubBitmap
1159 // ----------------------------------------------------------------------------
1160 // wxBitmap accessors
1161 // ----------------------------------------------------------------------------
1163 void wxBitmap::SetQuality(
1169 GetBitmapData()->m_nQuality
= nQ
;
1170 } // end of wxBitmap::SetQuality
1172 void wxBitmap::SetPalette(
1173 const wxPalette
& rPalette
1178 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1179 } // end of wxBitmap::SetPalette
1181 void wxBitmap::SetMask(
1187 GetBitmapData()->m_pBitmapMask
= pMask
;
1188 } // end of wxBitmap::SetMask
1190 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1193 } // end of wxBitmap::GetBitmapForDC
1195 // ----------------------------------------------------------------------------
1197 // ----------------------------------------------------------------------------
1202 } // end of wxMask::wxMask
1204 wxMask::wxMask(const wxMask
& tocopy
)
1206 m_hMaskBitmap
= wxCopyBmp(tocopy
.m_hMaskBitmap
);
1207 } // end of wxMask::wxMask
1209 // Construct a mask from a bitmap and a colour indicating
1210 // the transparent area
1212 const wxBitmap
& rBitmap
1213 , const wxColour
& rColour
1220 } // end of wxMask::wxMask
1222 // Construct a mask from a bitmap and a palette index indicating
1223 // the transparent area
1225 const wxBitmap
& rBitmap
1233 } // end of wxMask::wxMask
1235 // Construct a mask from a mono bitmap (copies the bitmap).
1237 const wxBitmap
& rBitmap
1242 } // end of wxMask::wxMask
1247 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1248 } // end of wxMask::~wxMask
1250 // Create a mask from a mono bitmap (copies the bitmap).
1251 bool wxMask::Create(
1252 const wxBitmap
& rBitmap
1255 BITMAPINFOHEADER2 vBmih
;
1256 SIZEL vSize
= {0, 0};
1257 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1258 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1259 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1260 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1261 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1262 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1263 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1268 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1271 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1276 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1277 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1278 vBmih
.cx
= rBitmap
.GetWidth();
1279 vBmih
.cy
= rBitmap
.GetHeight();
1281 vBmih
.cBitCount
= 24;
1283 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1290 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1291 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1300 ::GpiDestroyPS(hPSSrc
);
1301 ::GpiDestroyPS(hPSDst
);
1302 ::DevCloseDC(hDCSrc
);
1303 ::DevCloseDC(hDCDst
);
1305 } // end of wxMask::Create
1307 // Create a mask from a bitmap and a palette index indicating
1308 // the transparent area
1309 bool wxMask::Create(
1310 const wxBitmap
& rBitmap
1316 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1319 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1322 unsigned char cGreen
;
1323 unsigned char cBlue
;
1325 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1331 wxColour
vTransparentColour( cRed
1336 return (Create( rBitmap
1342 } // end of wxMask::Create
1344 // Create a mask from a bitmap and a colour indicating
1345 // the transparent area
1346 bool wxMask::Create(
1347 const wxBitmap
& rBitmap
1348 , const wxColour
& rColour
1352 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1356 BITMAPINFOHEADER2 vBmih
;
1357 SIZEL vSize
= {0, 0};
1358 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1359 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1360 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1361 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1362 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1366 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1375 // Scan the bitmap for the transparent colour and set
1376 // the corresponding pixels in the mask to BLACK and
1377 // the rest to WHITE
1380 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1381 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1382 vBmih
.cx
= rBitmap
.GetWidth();
1383 vBmih
.cy
= rBitmap
.GetHeight();
1385 vBmih
.cBitCount
= 1;
1387 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1394 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1395 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1398 // This is not very efficient, but I can't think
1399 // of a better way of doing it
1401 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1403 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1405 POINTL vPt
= {w
, h
};
1406 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1407 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1410 // Doesn't make sense to continue
1416 if (vCol
== vMaskColour
)
1418 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1419 ::GpiSetPel(hPSDst
, &vPt
);
1423 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1424 ::GpiSetPel(hPSDst
, &vPt
);
1428 ::GpiSetBitmap(hPSSrc
, NULL
);
1429 ::GpiSetBitmap(hPSDst
, NULL
);
1430 ::GpiDestroyPS(hPSSrc
);
1431 ::GpiDestroyPS(hPSDst
);
1432 ::DevCloseDC(hDCSrc
);
1433 ::DevCloseDC(hDCDst
);
1435 } // end of wxMask::Create
1437 // ----------------------------------------------------------------------------
1439 // ----------------------------------------------------------------------------
1441 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1448 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1452 return(pBitmap
? Create( pBitmap
1461 bool wxBitmapHandler::Load(
1464 , wxBitmapType lFlags
1469 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1473 return(pBitmap
? LoadFile( pBitmap
1481 bool wxBitmapHandler::Save(
1482 const wxGDIImage
* pImage
1483 , const wxString
& rName
1484 , wxBitmapType lType
1487 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1491 return(pBitmap
? SaveFile( pBitmap
1497 bool wxBitmapHandler::Create(
1498 wxBitmap
* WXUNUSED(pBitmap
)
1499 , const void* WXUNUSED(pData
)
1500 , wxBitmapType
WXUNUSED(lType
)
1501 , int WXUNUSED(nWidth
)
1502 , int WXUNUSED(nHeight
)
1503 , int WXUNUSED(nDepth
)
1509 bool wxBitmapHandler::LoadFile(
1510 wxBitmap
* WXUNUSED(pBitmap
)
1512 , wxBitmapType
WXUNUSED(lType
)
1513 , int WXUNUSED(nDesiredWidth
)
1514 , int WXUNUSED(nDesiredHeight
)
1520 bool wxBitmapHandler::LoadFile(
1521 wxBitmap
* WXUNUSED(pBitmap
)
1522 , const wxString
& WXUNUSED(rName
)
1523 , wxBitmapType
WXUNUSED(lType
)
1524 , int WXUNUSED(nDesiredWidth
)
1525 , int WXUNUSED(nDesiredHeight
)
1531 bool wxBitmapHandler::SaveFile(
1532 wxBitmap
* WXUNUSED(pBitmap
)
1533 , const wxString
& WXUNUSED(rName
)
1534 , wxBitmapType
WXUNUSED(nType
)
1535 , const wxPalette
* WXUNUSED(pPalette
)
1541 // ----------------------------------------------------------------------------
1542 // Utility functions
1543 // ----------------------------------------------------------------------------
1544 HBITMAP
wxInvertMask(
1550 HBITMAP hBmpInvMask
= 0;
1552 wxCHECK_MSG( hBmpMask
, 0, wxT("invalid bitmap in wxInvertMask") );
1555 // Get width/height from the bitmap if not given
1557 if (!nWidth
|| !nHeight
)
1559 BITMAPINFOHEADER2 vBmhdr
;
1561 ::GpiQueryBitmapInfoHeader( hBmpMask
1564 nWidth
= (int)vBmhdr
.cx
;
1565 nHeight
= (int)vBmhdr
.cy
;
1568 BITMAPINFOHEADER2 vBmih
;
1569 SIZEL vSize
= {0, 0};
1570 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1571 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1572 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1573 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1574 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1575 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1576 {0, 0}, {nWidth
, nHeight
}
1579 memset(&vBmih
, '\0', 16);
1584 vBmih
.cBitCount
= 24;
1586 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1593 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1594 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1604 ::GpiDestroyPS(hPSSrc
);
1605 ::GpiDestroyPS(hPSDst
);
1606 ::DevCloseDC(hDCSrc
);
1607 ::DevCloseDC(hDCDst
);
1610 } // end of WxWinGdi_InvertMask
1612 HBITMAP
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight
)
1614 wxCHECK_MSG( hBmp
, 0, wxT("invalid bitmap in wxCopyBmp") );
1617 // Get width/height from the bitmap if not given
1619 if (!nWidth
|| !nHeight
)
1621 BITMAPINFOHEADER2 vBmhdr
;
1624 ::GpiQueryBitmapInfoHeader( hBmp
,
1626 nWidth
= (int)vBmhdr
.cx
;
1627 nHeight
= (int)vBmhdr
.cy
;
1630 BITMAPINFOHEADER2 vBmih
;
1631 SIZEL vSize
= {0, 0};
1632 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1633 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1637 (PDEVOPENDATA
)&vDop
,
1639 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1643 (PDEVOPENDATA
)&vDop
,
1645 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1648 PU_PELS
| GPIA_ASSOC
);
1649 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1652 PU_PELS
| GPIA_ASSOC
);
1653 POINTL vPoint
[4] = { {0, nHeight
},
1656 {nWidth
, nHeight
} };
1660 vPoint
[1].y
= nHeight
;
1662 memset(&vBmih
, '\0', 16);
1667 vBmih
.cBitCount
= 24;
1669 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1675 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1676 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1678 ::GpiBitBlt( hPSDst
,
1685 ::GpiDestroyPS(hPSSrc
);
1686 ::GpiDestroyPS(hPSDst
);
1687 ::DevCloseDC(hDCSrc
);
1688 ::DevCloseDC(hDCDst
);
1691 } // end of wxFlipBmp