1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
31 #include "wx/os2/private.h"
34 //#include "wx/msw/dib.h"
36 #include "wx/xpmdecod.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 wxBitmapRefData::wxBitmapRefData()
58 m_pSelectedInto
= NULL
;
61 m_hBitmap
= (WXHBITMAP
) NULL
;
62 } // end of wxBitmapRefData::wxBitmapRefData
64 void wxBitmapRefData::Free()
66 wxASSERT_MSG( !m_pSelectedInto
,
67 wxT("deleting bitmap still selected into wxMemoryDC") );
71 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
73 wxLogLastError("GpiDeleteBitmap(hbitmap)");
79 } // end of wxBitmapRefData::Free
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 // this function should be called from all wxBitmap ctors
88 } // end of wxBitmap::Init
90 bool wxBitmap::CopyFromIconOrCursor(
91 const wxGDIImage
& rIcon
94 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
95 POINTERINFO SIconInfo
;
97 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
99 wxLogLastError(wxT("WinQueryPointerInfo"));
102 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
104 m_refData
= pRefData
;
106 int nWidth
= rIcon
.GetWidth();
107 int nHeight
= rIcon
.GetHeight();
109 pRefData
->m_nWidth
= nWidth
;
110 pRefData
->m_nHeight
= nHeight
;
111 pRefData
->m_nDepth
= wxDisplayDepth();
113 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
116 // No mask in the Info struct in OS/2
119 } // end of wxBitmap::CopyFromIconOrCursor
121 bool wxBitmap::CopyFromCursor(
122 const wxCursor
& rCursor
129 return(CopyFromIconOrCursor(rCursor
));
130 } // end of wxBitmap::CopyFromCursor
132 bool wxBitmap::CopyFromIcon(
141 return CopyFromIconOrCursor(rIcon
);
142 } // end of wxBitmap::CopyFromIcon
144 wxBitmap::~wxBitmap()
146 } // end of wxBitmap::~wxBitmap
157 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
158 BITMAPINFOHEADER2 vHeader
;
162 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
163 SIZEL vSize
= {0, 0};
166 wxASSERT(vHabmain
!= NULL
);
168 m_refData
= pRefData
;
170 pRefData
->m_nWidth
= nWidth
;
171 pRefData
->m_nHeight
= nHeight
;
172 pRefData
->m_nDepth
= nDepth
;
173 pRefData
->m_nNumColors
= 0;
174 pRefData
->m_pSelectedInto
= NULL
;
176 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
177 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
180 wxLogLastError("GpiCreatePS Failure");
186 // We assume that it is in XBM format which is not quite the same as
187 // the format CreateBitmap() wants because the order of bytes in the
190 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
191 const size_t nPadding
= nBytesPerLine
% 2;
192 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
193 const char* pzSrc
= zBits
;
197 pzData
= (char *)malloc(nLen
);
199 char* pzDst
= pzData
;
201 for (nRows
= 0; nRows
< nHeight
; nRows
++)
203 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
205 unsigned char ucVal
= *pzSrc
++;
206 unsigned char ucReversed
= 0;
209 for (nBits
= 0; nBits
< 8; nBits
++)
212 ucReversed
|= (ucVal
& 0x01);
215 *pzDst
++ = ucReversed
;
224 // Bits should already be in Windows standard format
226 pzData
= (char *)zBits
; // const_cast is harmless
229 memset(&vHeader
, '\0', 16);
231 vHeader
.cx
= (USHORT
)nWidth
;
232 vHeader
.cy
= (USHORT
)nHeight
;
233 vHeader
.cPlanes
= 1L;
234 vHeader
.cBitCount
= nDepth
;
235 vHeader
.usReserved
= 0;
237 memset(&vInfo
, '\0', 16);
239 vInfo
.cx
= (USHORT
)nWidth
;
240 vInfo
.cy
= (USHORT
)nHeight
;
242 vInfo
.cBitCount
= nDepth
;
244 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
248 wxLogLastError("CreateBitmap");
252 SetHBITMAP((WXHBITMAP
)hBmp
);
253 } // end of wxBitmap::wxBitmap
267 } // end of wxBitmap::wxBitmap
285 } // end of wxBitmap::wxBitmap
288 const wxString
& rFilename
297 } // end of wxBitmap::wxBitmap
299 bool wxBitmap::Create(
306 BITMAPINFOHEADER2 vHeader
;
308 wxASSERT(vHabmain
!= NULL
);
310 m_refData
= new wxBitmapRefData
;
311 GetBitmapData()->m_nWidth
= nW
;
312 GetBitmapData()->m_nHeight
= nH
;
313 GetBitmapData()->m_nDepth
= nD
;
317 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
318 SIZEL vSize
= {0, 0};
319 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
320 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
322 memset(&vHeader
, '\0', 16);
327 vHeader
.cBitCount
= nD
;
329 hBmp
= ::GpiCreateBitmap( hPS
344 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
345 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
346 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
348 memset(&vHeader
, '\0', 16);
353 vHeader
.cBitCount
= lBitCount
;
355 hBmp
= ::GpiCreateBitmap( hPSScreen
362 GetBitmapData()->m_nDepth
= wxDisplayDepth();
363 ::WinReleasePS(hPSScreen
);
365 SetHBITMAP((WXHBITMAP
)hBmp
);
367 #if WXWIN_COMPATIBILITY_2
368 GetBitmapData()->m_bOk
= hBmp
!= 0;
369 #endif // WXWIN_COMPATIBILITY_2
372 } // end of wxBitmap::Create
374 bool wxBitmap::CreateFromXpm(
378 #if wxUSE_IMAGE && wxUSE_XPM
381 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
383 wxXPMDecoder vDecoder
;
384 wxImage vImg
= vDecoder
.ReadData(ppData
);
386 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
388 *this = wxBitmap(vImg
);
393 } // end of wxBitmap::CreateFromXpm
395 bool wxBitmap::LoadFile(
396 const wxString
& rFilename
400 HPS hPs
= NULLHANDLE
;
404 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
410 m_refData
= new wxBitmapRefData
;
412 return(pHandler
->LoadFile( this
424 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
427 *this = wxBitmap(vImage
);
431 } // end of wxBitmap::LoadFile
433 bool wxBitmap::Create(
443 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
449 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
450 "type %d defined."), lType
);
455 m_refData
= new wxBitmapRefData
;
457 return(pHandler
->Create( this
464 } // end of wxBitmap::Create
466 bool wxBitmap::SaveFile(
467 const wxString
& rFilename
469 , const wxPalette
* pPalette
472 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
478 return pHandler
->SaveFile( this
486 // FIXME what about palette? shouldn't we use it?
487 wxImage vImage
= ConvertToImage();
492 return(vImage
.SaveFile( rFilename
496 } // end of wxBitmap::SaveFile
499 // ----------------------------------------------------------------------------
500 // wxImage-wxBitmap convertion
501 // ----------------------------------------------------------------------------
503 bool wxBitmap::CreateFromImage (
504 const wxImage
& rImage
508 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
509 m_refData
= new wxBitmapRefData();
512 int nSizeLimit
= 1024 * 768 * 3;
513 int nWidth
= rImage
.GetWidth();
514 int nBmpHeight
= rImage
.GetHeight();
515 int nBytePerLine
= nWidth
* 3;
516 int nSizeDWORD
= sizeof(DWORD
);
517 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
520 if (nLineBoundary
> 0)
522 nPadding
= nSizeDWORD
- nLineBoundary
;
523 nBytePerLine
+= nPadding
;
527 // Calc the number of DIBs and heights of DIBs
531 int nHeight
= nSizeLimit
/ nBytePerLine
;
533 if (nHeight
>= nBmpHeight
)
534 nHeight
= nBmpHeight
;
537 nNumDIB
= nBmpHeight
/ nHeight
;
538 nHRemain
= nBmpHeight
% nHeight
;
544 // Set bitmap parameters
546 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
548 SetHeight(nBmpHeight
);
550 nDepth
= 16; // wxDisplayDepth();
555 // Copy the palette from the source image
557 SetPalette(rImage
.GetPalette());
558 #endif // wxUSE_PALETTE
561 // Create a DIB header
563 BITMAPINFOHEADER2 vHeader
;
567 // Fill in the DIB header
569 memset(&vHeader
, '\0', 16);
571 vHeader
.cx
= (ULONG
)nWidth
;
572 vHeader
.cy
= (ULONG
)nHeight
;
573 vHeader
.cPlanes
= 1L;
574 vHeader
.cBitCount
= 24;
576 memset(&vInfo
, '\0', 16);
578 vInfo
.cx
= (ULONG
)nWidth
;
579 vInfo
.cy
= (ULONG
)nHeight
;
581 vInfo
.cBitCount
= 24;
583 // Memory for DIB data
585 unsigned char* pucBits
;
587 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
590 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
595 // Create and set the device-dependent bitmap
597 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
598 SIZEL vSize
= {0, 0};
599 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
600 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
602 HDC hDCScreen
= ::WinOpenWindowDC(HWND_DESKTOP
);
607 hBmp
= ::GpiCreateBitmap( hPS
613 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
615 HPAL hOldPalette
= NULLHANDLE
;
616 if (rImage
.GetPalette().Ok())
618 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
620 #endif // wxUSE_PALETTE
623 // Copy image data into DIB data and then into DDB (in a loop)
625 unsigned char* pData
= rImage
.GetData();
630 unsigned char* ptdata
= pData
;
631 unsigned char* ptbits
;
633 for (n
= 0; n
< nNumDIB
; n
++)
635 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
638 // Redefine height and size of the (possibly) last smaller DIB
639 // memory is not reallocated
642 vHeader
.cy
= (DWORD
)(nHeight
);
643 vHeader
.cbImage
= nBytePerLine
* nHeight
;
646 for (j
= 0; j
< nHeight
; j
++)
648 for (i
= 0; i
< nWidth
; i
++)
650 *(ptbits
++) = *(ptdata
+ 2);
651 *(ptbits
++) = *(ptdata
+ 1);
652 *(ptbits
++) = *(ptdata
);
655 for (i
= 0; i
< nPadding
; i
++)
660 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
661 // in combination with setting the bits into the selected bitmap
663 lScans
= ::GpiSetBitmapBits( hPS
664 ,0 // Start at the bottom
665 ,(LONG
)nHeight
// One line per scan
669 hPSScreen
= ::GpiCreatePS( vHabmain
672 ,PU_PELS
| GPIA_ASSOC
675 POINTL vPoint
[4] = { 0, nOrigin
,
677 0, 0, nWidth
, nHeight
681 ::GpiBitBlt( hPSScreen
688 ::GpiDestroyPS(hPSScreen
);
691 SetHBITMAP((WXHBITMAP
)hBmp
);
694 ::GpiSelectPalette(hPS
, hOldPalette
);
695 #endif // wxUSE_PALETTE
698 // Similarly, created an mono-bitmap for the possible mask
700 if (rImage
.HasMask())
702 hBmp
= ::GpiCreateBitmap( hPS
708 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
709 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
711 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
713 vHeader
.cy
= nHeight
;
715 vHeader
.cBitCount
= 1;
716 hBmp
= ::GpiCreateBitmap( hPS
723 nHeight
= nBmpHeight
;
725 nHeight
= nSizeLimit
/ nBytePerLine
;
726 vHeader
.cy
= (DWORD
)(nHeight
);
727 vHeader
.cbImage
= nBytePerLine
* nHeight
;
730 unsigned char cRed
= rImage
.GetMaskRed();
731 unsigned char cGreen
= rImage
.GetMaskGreen();
732 unsigned char cBlue
= rImage
.GetMaskBlue();
733 unsigned char cZero
= 0;
734 unsigned char cOne
= 255;
737 for (n
= 0; n
< nNumDIB
; n
++)
739 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
742 // Redefine height and size of the (possibly) last smaller DIB
743 // memory is not reallocated
746 vHeader
.cy
= (DWORD
)(nHeight
);
747 vHeader
.cbImage
= nBytePerLine
* nHeight
;
750 for (int j
= 0; j
< nHeight
; j
++)
752 for (i
= 0; i
< nWidth
; i
++)
754 if ((*(ptdata
++) != cRed
) || (*(ptdata
++) != cGreen
) || (*(ptdata
++) != cBlue
))
767 for (i
= 0; i
< nPadding
; i
++)
770 lScans
= ::GpiSetBitmapBits( hPS
771 ,0 // Start at the bottom
772 ,(LONG
)nHeight
// One line per scan
776 hPSScreen
= ::GpiCreatePS( vHabmain
779 ,PU_PELS
| GPIA_ASSOC
781 POINTL vPoint2
[4] = { 0, nOrigin
,
783 0, 0, nWidth
, nHeight
785 ::GpiBitBlt( hPSScreen
792 ::GpiDestroyPS(hPSScreen
);
797 // Create a wxMask object
799 wxMask
* pMask
= new wxMask();
801 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
803 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
807 // Free allocated resources
809 ::GpiSetBitmap(hPS
, NULLHANDLE
);
814 } // end of wxBitmap::CreateFromImage
816 wxImage
wxBitmap::ConvertToImage() const
820 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
823 // Create an wxImage object
825 int nWidth
= GetWidth();
826 int nHeight
= GetHeight();
829 int nBytePerLine
= nWidth
* 3;
830 int nSizeDWORD
= sizeof(DWORD
);
831 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
833 unsigned char* pData
;
834 unsigned char* lpBits
;
836 BITMAPINFOHEADER2 vDIBh
;
837 BITMAPINFO2 vDIBInfo
;
839 PSZ pszData
[4] = { "Display", NULL
, NULL
, NULL
};
842 SIZEL vSizlPage
= {0,0};
845 vImage
.Create( nWidth
848 pData
= vImage
.GetData();
851 wxFAIL_MSG( wxT("could not allocate data for image") );
854 if(nLineBoundary
> 0)
856 nPadding
= nSizeDWORD
- nLineBoundary
;
857 nBytePerLine
+= nPadding
;
859 wxDisplaySize( &nDevWidth
863 // Create and fill a DIB header
865 memset(&vDIBh
, '\0', 16);
870 vDIBh
.cBitCount
= 24;
872 memset(&vDIBInfo
, '\0', 16);
874 vDIBInfo
.cx
= nWidth
;
875 vDIBInfo
.cy
= nHeight
;
876 vDIBInfo
.cPlanes
= 1;
877 vDIBInfo
.cBitCount
= 24;
879 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
882 wxFAIL_MSG(wxT("could not allocate data for DIB"));
888 // Copy data from the device-dependent bitmap to the DIB
890 hDCMem
= ::DevOpenDC( vHabmain
894 ,(PDEVOPENDATA
)pszData
897 hPSMem
= ::GpiCreatePS( vHabmain
900 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
902 hBitmap
= ::GpiCreateBitmap( hPSMem
908 lScans
= ::GpiQueryBitmapBits( hPSMem
916 // Copy DIB data into the wxImage object
920 unsigned char* ptdata
= pData
;
921 unsigned char* ptbits
= lpBits
;
923 for (i
= 0; i
< nHeight
; i
++)
925 for (j
= 0; j
< nWidth
; j
++)
927 *(ptdata
++) = *(ptbits
+2);
928 *(ptdata
++) = *(ptbits
+1);
929 *(ptdata
++) = *(ptbits
);
936 // Similarly, set data according to the possible mask bitmap
938 if (GetMask() && GetMask()->GetMaskBitmap())
940 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
943 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
945 HDC hMemDC
= ::DevOpenDC( vHabmain
949 ,(PDEVOPENDATA
)pszData
952 HPS hMemPS
= ::GpiCreatePS( vHabmain
955 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
957 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
958 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
959 ::GpiQueryBitmapBits( hPSMem
965 ::GpiDestroyPS(hMemPS
);
966 ::DevCloseDC(hMemDC
);
969 // Background color set to RGB(16,16,16) in consistent with wxGTK
971 unsigned char ucRed
= 16;
972 unsigned char ucGreen
= 16;
973 unsigned char ucBlue
= 16;
977 for (i
= 0; i
< nHeight
; i
++)
979 for (j
= 0; j
< nWidth
; j
++)
986 *(ptdata
++) = ucGreen
;
987 *(ptdata
++) = ucBlue
;
993 vImage
.SetMaskColour( ucRed
997 vImage
.SetMask(TRUE
);
1001 vImage
.SetMask(FALSE
);
1005 // Free allocated resources
1007 ::GpiDestroyPS(hPSMem
);
1008 ::DevCloseDC(hDCMem
);
1011 } // end of wxBitmap::ConvertToImage
1013 // ----------------------------------------------------------------------------
1014 // sub bitmap extraction
1015 // ----------------------------------------------------------------------------
1017 wxBitmap
wxBitmap::GetSubBitmap(
1021 wxCHECK_MSG( Ok() &&
1022 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1023 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1024 (rRect
.y
+ rRect
.height
<= GetHeight()),
1025 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1027 wxBitmap
vRet( rRect
.width
1031 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1037 SIZEL vSize
= {0, 0};
1038 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1039 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1040 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1041 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1042 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1043 POINTL vPoint
[4] = { 0, 0, rRect
.width
, rRect
.height
,
1045 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
1048 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1049 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1059 // Copy mask if there is one
1063 BITMAPINFOHEADER2 vBmih
;
1065 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1066 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1067 vBmih
.cx
= rRect
.width
;
1068 vBmih
.cy
= rRect
.height
;
1070 vBmih
.cBitCount
= 1;
1072 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1079 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1080 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1082 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1083 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1092 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1093 vRet
.SetMask(pMask
);
1096 ::GpiSetBitmap(hPSSrc
, NULL
);
1097 ::GpiSetBitmap(hPSDst
, NULL
);
1098 ::GpiDestroyPS(hPSSrc
);
1099 ::GpiDestroyPS(hPSDst
);
1100 ::DevCloseDC(hDCSrc
);
1101 ::DevCloseDC(hDCDst
);
1103 } // end of wxBitmap::GetSubBitmap
1105 // ----------------------------------------------------------------------------
1106 // wxBitmap accessors
1107 // ----------------------------------------------------------------------------
1109 void wxBitmap::SetQuality(
1115 GetBitmapData()->m_nQuality
= nQ
;
1116 } // end of wxBitmap::SetQuality
1118 #if WXWIN_COMPATIBILITY_2
1119 void wxBitmap::SetOk(
1125 GetBitmapData()->m_bOk
= bOk
;
1126 } // end of wxBitmap::SetOk
1127 #endif // WXWIN_COMPATIBILITY_2
1129 void wxBitmap::SetPalette(
1130 const wxPalette
& rPalette
1135 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1136 } // end of wxBitmap::SetPalette
1138 void wxBitmap::SetMask(
1144 GetBitmapData()->m_pBitmapMask
= pMask
;
1145 } // end of wxBitmap::SetMask
1147 wxBitmap
wxBitmap::GetBitmapForDC(
1152 } // end of wxBitmap::GetBitmapForDC
1154 // ----------------------------------------------------------------------------
1156 // ----------------------------------------------------------------------------
1161 } // end of wxMask::wxMask
1163 // Construct a mask from a bitmap and a colour indicating
1164 // the transparent area
1166 const wxBitmap
& rBitmap
1167 , const wxColour
& rColour
1174 } // end of wxMask::wxMask
1176 // Construct a mask from a bitmap and a palette index indicating
1177 // the transparent area
1179 const wxBitmap
& rBitmap
1187 } // end of wxMask::wxMask
1189 // Construct a mask from a mono bitmap (copies the bitmap).
1191 const wxBitmap
& rBitmap
1196 } // end of wxMask::wxMask
1201 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1202 } // end of wxMask::~wxMask
1204 // Create a mask from a mono bitmap (copies the bitmap).
1205 bool wxMask::Create(
1206 const wxBitmap
& rBitmap
1209 BITMAPINFOHEADER2 vBmih
;
1210 SIZEL vSize
= {0, 0};
1211 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1212 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1213 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1214 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1215 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1216 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1217 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1222 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1225 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1230 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1231 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1232 vBmih
.cx
= rBitmap
.GetWidth();
1233 vBmih
.cy
= rBitmap
.GetHeight();
1235 vBmih
.cBitCount
= 1;
1237 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1244 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1245 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1254 ::GpiDestroyPS(hPSSrc
);
1255 ::GpiDestroyPS(hPSDst
);
1256 ::DevCloseDC(hDCSrc
);
1257 ::DevCloseDC(hDCDst
);
1259 } // end of wxMask::Create
1261 // Create a mask from a bitmap and a palette index indicating
1262 // the transparent area
1263 bool wxMask::Create(
1264 const wxBitmap
& rBitmap
1270 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1273 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1276 unsigned char cGreen
;
1277 unsigned char cBlue
;
1279 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1285 wxColour
vTransparentColour( cRed
1290 return (Create( rBitmap
1296 } // end of wxMask::Create
1298 // Create a mask from a bitmap and a colour indicating
1299 // the transparent area
1300 bool wxMask::Create(
1301 const wxBitmap
& rBitmap
1302 , const wxColour
& rColour
1306 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1310 BITMAPINFOHEADER2 vBmih
;
1311 SIZEL vSize
= {0, 0};
1312 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1313 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1314 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1315 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1316 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1317 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1318 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1323 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1332 // Scan the bitmap for the transparent colour and set
1333 // the corresponding pixels in the mask to BLACK and
1334 // the rest to WHITE
1337 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1338 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1339 vBmih
.cx
= rBitmap
.GetWidth();
1340 vBmih
.cy
= rBitmap
.GetHeight();
1342 vBmih
.cBitCount
= 1;
1344 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1351 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1352 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1355 // This is not very efficient, but I can't think
1356 // of a better way of doing it
1358 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1360 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1362 POINTL vPt
= {w
, h
};
1363 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1364 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1367 // Doesn't make sense to continue
1373 if (vCol
== vMaskColour
)
1375 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1376 ::GpiSetPel(hPSDst
, &vPt
);
1380 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1381 ::GpiSetPel(hPSDst
, &vPt
);
1385 ::GpiSetBitmap(hPSSrc
, NULL
);
1386 ::GpiSetBitmap(hPSDst
, NULL
);
1387 ::GpiDestroyPS(hPSSrc
);
1388 ::GpiDestroyPS(hPSDst
);
1389 ::DevCloseDC(hDCSrc
);
1390 ::DevCloseDC(hDCDst
);
1392 } // end of wxMask::Create
1394 // ----------------------------------------------------------------------------
1396 // ----------------------------------------------------------------------------
1398 bool wxBitmapHandler::Create(
1407 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1411 return(pBitmap
? Create( pBitmap
1419 bool wxBitmapHandler::Load(
1421 , const wxString
& rName
1428 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1432 return(pBitmap
? LoadFile( pBitmap
1441 bool wxBitmapHandler::Save(
1443 , const wxString
& rName
1447 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1451 return(pBitmap
? SaveFile( pBitmap
1457 bool wxBitmapHandler::Create(
1458 wxBitmap
* WXUNUSED(pBitmap
)
1459 , void* WXUNUSED(pData
)
1460 , long WXUNUSED(lType
)
1461 , int WXUNUSED(nWidth
)
1462 , int WXUNUSED(nHeight
)
1463 , int WXUNUSED(nDepth
)
1469 bool wxBitmapHandler::LoadFile(
1470 wxBitmap
* WXUNUSED(pBitmap
)
1471 , const wxString
& WXUNUSED(rName
)
1473 , long WXUNUSED(lType
)
1474 , int WXUNUSED(nDesiredWidth
)
1475 , int WXUNUSED(nDesiredHeight
)
1481 bool wxBitmapHandler::SaveFile(
1482 wxBitmap
* WXUNUSED(pBitmap
)
1483 , const wxString
& WXUNUSED(rName
)
1484 , int WXUNUSED(nType
)
1485 , const wxPalette
* WXUNUSED(pPalette
)
1491 // ----------------------------------------------------------------------------
1492 // Utility functions
1493 // ----------------------------------------------------------------------------
1494 HBITMAP
wxInvertMask(
1500 HBITMAP hBmpInvMask
= 0;
1502 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1505 // Get width/height from the bitmap if not given
1507 if (!nWidth
|| !nHeight
)
1509 BITMAPINFOHEADER2 vBmhdr
;
1511 ::GpiQueryBitmapInfoHeader( hBmpMask
1514 nWidth
= (int)vBmhdr
.cx
;
1515 nHeight
= (int)vBmhdr
.cy
;
1518 BITMAPINFOHEADER2 vBmih
;
1519 SIZEL vSize
= {0, 0};
1520 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1521 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1522 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1523 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1524 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1525 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1526 0, 0, nWidth
, nHeight
1529 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1530 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1534 vBmih
.cBitCount
= 1;
1536 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1543 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1544 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1554 ::GpiDestroyPS(hPSSrc
);
1555 ::GpiDestroyPS(hPSDst
);
1556 ::DevCloseDC(hDCSrc
);
1557 ::DevCloseDC(hDCDst
);
1560 } // end of WxWinGdi_InvertMask