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 if ( m_pSelectedInto
)
68 wxLogLastError("GpiDeleteBitmap(hbitmap)");
72 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
74 wxLogLastError("GpiDeleteBitmap(hbitmap)");
82 } // end of wxBitmapRefData::Free
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 // this function should be called from all wxBitmap ctors
93 // True for all bitmaps created from bits, wxImages, Xpms
95 } // end of wxBitmap::Init
97 bool wxBitmap::CopyFromIconOrCursor(
98 const wxGDIImage
& rIcon
101 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
102 POINTERINFO SIconInfo
;
104 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
106 wxLogLastError(wxT("WinQueryPointerInfo"));
109 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
111 m_refData
= pRefData
;
113 int nWidth
= rIcon
.GetWidth();
114 int nHeight
= rIcon
.GetHeight();
116 pRefData
->m_nWidth
= nWidth
;
117 pRefData
->m_nHeight
= nHeight
;
118 pRefData
->m_nDepth
= wxDisplayDepth();
120 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
122 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
124 pMask
->SetMaskBitmap(GetHBITMAP());
128 } // end of wxBitmap::CopyFromIconOrCursor
130 bool wxBitmap::CopyFromCursor(
131 const wxCursor
& rCursor
138 return(CopyFromIconOrCursor(rCursor
));
139 } // end of wxBitmap::CopyFromCursor
141 bool wxBitmap::CopyFromIcon(
150 return CopyFromIconOrCursor(rIcon
);
151 } // end of wxBitmap::CopyFromIcon
153 wxBitmap::~wxBitmap()
155 } // end of wxBitmap::~wxBitmap
166 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
167 BITMAPINFOHEADER2 vHeader
;
171 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
172 SIZEL vSize
= {0, 0};
175 wxASSERT(vHabmain
!= NULL
);
177 m_refData
= pRefData
;
179 pRefData
->m_nWidth
= nWidth
;
180 pRefData
->m_nHeight
= nHeight
;
181 pRefData
->m_nDepth
= nDepth
;
182 pRefData
->m_nNumColors
= 0;
183 pRefData
->m_pSelectedInto
= NULL
;
185 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
186 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
189 wxLogLastError("GpiCreatePS Failure");
195 // We assume that it is in XBM format which is not quite the same as
196 // the format CreateBitmap() wants because the order of bytes in the
199 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
200 const size_t nPadding
= nBytesPerLine
% 2;
201 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
202 const char* pzSrc
= zBits
;
206 pzData
= (char *)malloc(nLen
);
208 char* pzDst
= pzData
;
210 for (nRows
= 0; nRows
< nHeight
; nRows
++)
212 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
214 unsigned char ucVal
= *pzSrc
++;
215 unsigned char ucReversed
= 0;
218 for (nBits
= 0; nBits
< 8; nBits
++)
221 ucReversed
|= (ucVal
& 0x01);
224 *pzDst
++ = ucReversed
;
233 // Bits should already be in Windows standard format
235 pzData
= (char *)zBits
; // const_cast is harmless
239 nDepth
= 24; // MAX supported in PM
240 memset(&vHeader
, '\0', 16);
242 vHeader
.cx
= (USHORT
)nWidth
;
243 vHeader
.cy
= (USHORT
)nHeight
;
244 vHeader
.cPlanes
= 1L;
245 vHeader
.cBitCount
= nDepth
;
246 vHeader
.usReserved
= 0;
248 memset(&vInfo
, '\0', 16);
250 vInfo
.cx
= (USHORT
)nWidth
;
251 vInfo
.cy
= (USHORT
)nHeight
;
253 vInfo
.cBitCount
= nDepth
;
255 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
259 wxLogLastError("CreateBitmap");
263 SetHBITMAP((WXHBITMAP
)hBmp
);
264 } // end of wxBitmap::wxBitmap
277 } // end of wxBitmap::wxBitmap
295 } // end of wxBitmap::wxBitmap
298 const wxString
& rFilename
306 } // end of wxBitmap::wxBitmap
308 bool wxBitmap::Create(
315 BITMAPINFOHEADER2 vHeader
;
317 wxASSERT(vHabmain
!= NULL
);
319 m_refData
= new wxBitmapRefData
;
320 GetBitmapData()->m_nWidth
= nW
;
321 GetBitmapData()->m_nHeight
= nH
;
322 GetBitmapData()->m_nDepth
= nD
;
325 // Xpms and bitmaps from other images can also be mono's, but only
326 // mono's need help changing their colors with MemDC changes
330 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
331 SIZEL vSize
= {0, 0};
332 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
333 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
337 memset(&vHeader
, '\0', 16);
342 vHeader
.cBitCount
= 24; //nD;
344 hBmp
= ::GpiCreateBitmap( hPS
359 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
360 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
361 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
366 memset(&vHeader
, '\0', 16);
371 vHeader
.cBitCount
= lBitCount
;
373 hBmp
= ::GpiCreateBitmap( hPSScreen
380 GetBitmapData()->m_nDepth
= wxDisplayDepth();
381 ::WinReleasePS(hPSScreen
);
383 SetHBITMAP((WXHBITMAP
)hBmp
);
385 #if WXWIN_COMPATIBILITY_2
386 GetBitmapData()->m_bOk
= hBmp
!= 0;
387 #endif // WXWIN_COMPATIBILITY_2
390 } // end of wxBitmap::Create
392 bool wxBitmap::CreateFromXpm(
396 #if wxUSE_IMAGE && wxUSE_XPM
399 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
401 wxXPMDecoder vDecoder
;
402 wxImage vImg
= vDecoder
.ReadData(ppData
);
404 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
406 *this = wxBitmap(vImg
);
411 } // end of wxBitmap::CreateFromXpm
413 bool wxBitmap::LoadFile(
414 const wxString
& rFilename
418 HPS hPs
= NULLHANDLE
;
422 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
428 m_refData
= new wxBitmapRefData
;
430 return(pHandler
->LoadFile( this
442 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
445 *this = wxBitmap(vImage
);
449 } // end of wxBitmap::LoadFile
451 bool wxBitmap::Create(
461 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
467 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
468 "type %d defined."), lType
);
473 m_refData
= new wxBitmapRefData
;
475 return(pHandler
->Create( this
482 } // end of wxBitmap::Create
484 bool wxBitmap::SaveFile(
485 const wxString
& rFilename
487 , const wxPalette
* pPalette
490 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
496 return pHandler
->SaveFile( this
504 // FIXME what about palette? shouldn't we use it?
505 wxImage vImage
= ConvertToImage();
510 return(vImage
.SaveFile( rFilename
514 } // end of wxBitmap::SaveFile
517 // ----------------------------------------------------------------------------
518 // wxImage-wxBitmap convertion
519 // ----------------------------------------------------------------------------
521 bool wxBitmap::CreateFromImage (
522 const wxImage
& rImage
526 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
527 m_refData
= new wxBitmapRefData();
529 int nSizeLimit
= 1024 * 768 * 3;
530 int nWidth
= rImage
.GetWidth();
531 int nBmpHeight
= rImage
.GetHeight();
532 int nBytePerLine
= nWidth
* 3;
533 int nSizeDWORD
= sizeof(DWORD
);
534 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
537 if (nLineBoundary
> 0)
539 nPadding
= nSizeDWORD
- nLineBoundary
;
540 nBytePerLine
+= nPadding
;
544 // Calc the number of DIBs and heights of DIBs
548 int nHeight
= nSizeLimit
/ nBytePerLine
;
550 if (nHeight
>= nBmpHeight
)
551 nHeight
= nBmpHeight
;
554 nNumDIB
= nBmpHeight
/ nHeight
;
555 nHRemain
= nBmpHeight
% nHeight
;
561 // Set bitmap parameters
563 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
565 SetHeight(nBmpHeight
);
571 nDepth
= wxDisplayDepth();
576 // Copy the palette from the source image
578 SetPalette(rImage
.GetPalette());
579 #endif // wxUSE_PALETTE
582 // Create a DIB header
584 BITMAPINFOHEADER2 vHeader
;
588 // Fill in the DIB header
590 memset(&vHeader
, '\0', 16);
592 vHeader
.cx
= (ULONG
)nWidth
;
593 vHeader
.cy
= (ULONG
)nHeight
;
594 vHeader
.cPlanes
= 1L;
595 vHeader
.cBitCount
= 24;
598 // Memory for DIB data
600 unsigned char* pucBits
;
602 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
605 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
608 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
611 // Create and set the device-dependent bitmap
613 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
614 SIZEL vSize
= {0, 0};
615 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
616 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
618 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
623 memset(&vInfo
, '\0', 16);
625 vInfo
.cx
= (ULONG
)nWidth
;
626 vInfo
.cy
= (ULONG
)nHeight
;
628 vInfo
.cBitCount
= 24; // Set to desired count going in
630 hBmp
= ::GpiCreateBitmap( hPS
637 HPAL hOldPalette
= NULLHANDLE
;
638 if (rImage
.GetPalette().Ok())
640 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
642 #endif // wxUSE_PALETTE
645 // Copy image data into DIB data and then into DDB (in a loop)
647 unsigned char* pData
= rImage
.GetData();
652 unsigned char* ptdata
= pData
;
653 unsigned char* ptbits
;
655 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
660 vError
= ::WinGetLastError(vHabmain
);
661 sError
= wxPMErrorToStr(vError
);
663 for (n
= 0; n
< nNumDIB
; n
++)
665 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
668 // Redefine height and size of the (possibly) last smaller DIB
669 // memory is not reallocated
672 vHeader
.cy
= (DWORD
)(nHeight
);
673 vHeader
.cbImage
= nBytePerLine
* nHeight
;
676 for (j
= 0; j
< nHeight
; j
++)
678 for (i
= 0; i
< nWidth
; i
++)
680 *(ptbits
++) = *(ptdata
+ 2);
681 *(ptbits
++) = *(ptdata
+ 1);
682 *(ptbits
++) = *(ptdata
);
685 for (i
= 0; i
< nPadding
; i
++)
690 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
691 // in combination with setting the bits into the selected bitmap
693 if ((lScans
= ::GpiSetBitmapBits( hPS
694 ,0 // Start at the bottom
695 ,(LONG
)nHeight
// One line per scan
703 vError
= ::WinGetLastError(vHabmain
);
704 sError
= wxPMErrorToStr(vError
);
706 hPSScreen
= ::GpiCreatePS( vHabmain
709 ,PU_PELS
| GPIA_ASSOC
712 POINTL vPoint
[4] = { 0, nOrigin
,
714 0, 0, nWidth
, nHeight
718 ::GpiBitBlt( hPSScreen
725 ::GpiDestroyPS(hPSScreen
);
728 SetHBITMAP((WXHBITMAP
)hBmp
);
731 ::GpiSelectPalette(hPS
, hOldPalette
);
732 #endif // wxUSE_PALETTE
735 // Similarly, created an mono-bitmap for the possible mask
737 if (rImage
.HasMask())
741 vHeader
.cy
= nHeight
;
743 vHeader
.cBitCount
= 24;
744 hBmp
= ::GpiCreateBitmap( hPS
750 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
752 nHeight
= nBmpHeight
;
754 nHeight
= nSizeLimit
/ nBytePerLine
;
755 vHeader
.cy
= (DWORD
)(nHeight
);
758 unsigned char cRed
= rImage
.GetMaskRed();
759 unsigned char cGreen
= rImage
.GetMaskGreen();
760 unsigned char cBlue
= rImage
.GetMaskBlue();
761 unsigned char cZero
= 0;
762 unsigned char cOne
= 255;
765 for (n
= 0; n
< nNumDIB
; n
++)
767 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
770 // Redefine height and size of the (possibly) last smaller DIB
771 // memory is not reallocated
774 vHeader
.cy
= (DWORD
)(nHeight
);
775 vHeader
.cbImage
= nBytePerLine
* nHeight
;
778 for (int j
= 0; j
< nHeight
; j
++)
780 for (i
= 0; i
< nWidth
; i
++)
782 unsigned char cRedImage
= (*(ptdata
++)) ;
783 unsigned char cGreenImage
= (*(ptdata
++)) ;
784 unsigned char cBlueImage
= (*(ptdata
++)) ;
786 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
799 for (i
= 0; i
< nPadding
; i
++)
802 lScans
= ::GpiSetBitmapBits( hPS
803 ,0 // Start at the bottom
804 ,(LONG
)nHeight
// One line per scan
808 hPSScreen
= ::GpiCreatePS( vHabmain
811 ,PU_PELS
| GPIA_ASSOC
813 POINTL vPoint2
[4] = { 0, nOrigin
,
815 0, 0, nWidth
, nHeight
817 ::GpiBitBlt( hPSScreen
824 ::GpiDestroyPS(hPSScreen
);
829 // Create a wxMask object
831 wxMask
* pMask
= new wxMask();
833 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
835 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
839 // Free allocated resources
841 ::GpiSetBitmap(hPS
, NULLHANDLE
);
843 ::DevCloseDC(hDCScreen
);
847 } // end of wxBitmap::CreateFromImage
849 wxImage
wxBitmap::ConvertToImage() const
854 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
857 // Create an wxImage object
859 int nWidth
= GetWidth();
860 int nHeight
= GetHeight();
863 int nBytePerLine
= nWidth
* 3;
864 int nSizeDWORD
= sizeof(DWORD
);
865 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
867 unsigned char* pData
;
868 unsigned char* lpBits
;
870 BITMAPINFOHEADER2 vDIBh
;
871 BITMAPINFO2 vDIBInfo
;
876 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
877 SIZEL vSizlPage
= {0,0};
880 vImage
.Create( nWidth
883 pData
= vImage
.GetData();
886 wxFAIL_MSG( wxT("could not allocate data for image") );
889 if(nLineBoundary
> 0)
891 nPadding
= nSizeDWORD
- nLineBoundary
;
892 nBytePerLine
+= nPadding
;
894 wxDisplaySize( &nDevWidth
898 // Create and fill a DIB header
900 memset(&vDIBh
, '\0', 16);
905 vDIBh
.cBitCount
= 24;
907 memset(&vDIBInfo
, '\0', 16);
909 vDIBInfo
.cx
= nWidth
;
910 vDIBInfo
.cy
= nHeight
;
911 vDIBInfo
.cPlanes
= 1;
912 vDIBInfo
.cBitCount
= 24;
914 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
917 wxFAIL_MSG(wxT("could not allocate data for DIB"));
921 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
922 hBitmap
= (HBITMAP
)GetHBITMAP();
925 // May already be selected into a PS
927 if ((pDC
= GetSelectedInto()) != NULL
)
929 hPSMem
= pDC
->GetHPS();
933 hDCMem
= ::DevOpenDC( vHabmain
940 hPSMem
= ::GpiCreatePS( vHabmain
943 ,PU_PELS
| GPIA_ASSOC
946 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
951 vError
= ::WinGetLastError(vHabmain
);
952 sError
= wxPMErrorToStr(vError
);
956 // Copy data from the device-dependent bitmap to the DIB
958 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
968 vError
= ::WinGetLastError(vHabmain
);
969 sError
= wxPMErrorToStr(vError
);
973 // Copy DIB data into the wxImage object
977 unsigned char* ptdata
= pData
;
978 unsigned char* ptbits
= lpBits
;
980 for (i
= 0; i
< nHeight
; i
++)
982 for (j
= 0; j
< nWidth
; j
++)
984 *(ptdata
++) = *(ptbits
+2);
985 *(ptdata
++) = *(ptbits
+1);
986 *(ptdata
++) = *(ptbits
);
991 if ((pDC
= GetSelectedInto()) == NULL
)
993 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
994 ::GpiDestroyPS(hPSMem
);
995 ::DevCloseDC(hDCMem
);
999 // Similarly, set data according to the possible mask bitmap
1001 if (GetMask() && GetMask()->GetMaskBitmap())
1003 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1006 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1008 HDC hMemDC
= ::DevOpenDC( vHabmain
1012 ,(PDEVOPENDATA
)&vDop
1015 HPS hMemPS
= ::GpiCreatePS( vHabmain
1018 ,PU_PELS
| GPIA_ASSOC
1020 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1021 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1022 ::GpiSetBitmap(hMemPS
, hBitmap
);
1023 ::GpiQueryBitmapBits( hPSMem
1029 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1030 ::GpiDestroyPS(hMemPS
);
1031 ::DevCloseDC(hMemDC
);
1034 // Background color set to RGB(16,16,16) in consistent with wxGTK
1036 unsigned char ucRed
= 16;
1037 unsigned char ucGreen
= 16;
1038 unsigned char ucBlue
= 16;
1042 for (i
= 0; i
< nHeight
; i
++)
1044 for (j
= 0; j
< nWidth
; j
++)
1050 *(ptdata
++) = ucRed
;
1051 *(ptdata
++) = ucGreen
;
1052 *(ptdata
++) = ucBlue
;
1058 vImage
.SetMaskColour( ucRed
1062 vImage
.SetMask(TRUE
);
1066 vImage
.SetMask(FALSE
);
1070 // Free allocated resources
1074 } // end of wxBitmap::ConvertToImage
1076 // ----------------------------------------------------------------------------
1077 // sub bitmap extraction
1078 // ----------------------------------------------------------------------------
1080 wxBitmap
wxBitmap::GetSubBitmap(
1084 wxCHECK_MSG( Ok() &&
1085 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1086 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1087 (rRect
.y
+ rRect
.height
<= GetHeight()),
1088 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1090 wxBitmap
vRet( rRect
.width
1094 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1100 SIZEL vSize
= {0, 0};
1101 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1102 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1103 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1104 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1105 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1106 POINTL vPoint
[4] = { 0, 0, rRect
.width
, rRect
.height
,
1108 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
1111 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1112 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1122 // Copy mask if there is one
1126 BITMAPINFOHEADER2 vBmih
;
1128 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1129 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1130 vBmih
.cx
= rRect
.width
;
1131 vBmih
.cy
= rRect
.height
;
1133 vBmih
.cBitCount
= 24;
1135 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1142 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1143 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1145 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1146 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1155 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1156 vRet
.SetMask(pMask
);
1159 ::GpiSetBitmap(hPSSrc
, NULL
);
1160 ::GpiSetBitmap(hPSDst
, NULL
);
1161 ::GpiDestroyPS(hPSSrc
);
1162 ::GpiDestroyPS(hPSDst
);
1163 ::DevCloseDC(hDCSrc
);
1164 ::DevCloseDC(hDCDst
);
1166 } // end of wxBitmap::GetSubBitmap
1168 // ----------------------------------------------------------------------------
1169 // wxBitmap accessors
1170 // ----------------------------------------------------------------------------
1172 void wxBitmap::SetQuality(
1178 GetBitmapData()->m_nQuality
= nQ
;
1179 } // end of wxBitmap::SetQuality
1181 #if WXWIN_COMPATIBILITY_2
1182 void wxBitmap::SetOk(
1188 GetBitmapData()->m_bOk
= bOk
;
1189 } // end of wxBitmap::SetOk
1190 #endif // WXWIN_COMPATIBILITY_2
1192 void wxBitmap::SetPalette(
1193 const wxPalette
& rPalette
1198 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1199 } // end of wxBitmap::SetPalette
1201 void wxBitmap::SetMask(
1207 GetBitmapData()->m_pBitmapMask
= pMask
;
1208 } // end of wxBitmap::SetMask
1210 wxBitmap
wxBitmap::GetBitmapForDC(
1215 } // end of wxBitmap::GetBitmapForDC
1217 // ----------------------------------------------------------------------------
1219 // ----------------------------------------------------------------------------
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
);
1380 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1381 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1386 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1395 // Scan the bitmap for the transparent colour and set
1396 // the corresponding pixels in the mask to BLACK and
1397 // the rest to WHITE
1400 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1401 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1402 vBmih
.cx
= rBitmap
.GetWidth();
1403 vBmih
.cy
= rBitmap
.GetHeight();
1405 vBmih
.cBitCount
= 1;
1407 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1414 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1415 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1418 // This is not very efficient, but I can't think
1419 // of a better way of doing it
1421 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1423 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1425 POINTL vPt
= {w
, h
};
1426 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1427 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1430 // Doesn't make sense to continue
1436 if (vCol
== vMaskColour
)
1438 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1439 ::GpiSetPel(hPSDst
, &vPt
);
1443 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1444 ::GpiSetPel(hPSDst
, &vPt
);
1448 ::GpiSetBitmap(hPSSrc
, NULL
);
1449 ::GpiSetBitmap(hPSDst
, NULL
);
1450 ::GpiDestroyPS(hPSSrc
);
1451 ::GpiDestroyPS(hPSDst
);
1452 ::DevCloseDC(hDCSrc
);
1453 ::DevCloseDC(hDCDst
);
1455 } // end of wxMask::Create
1457 // ----------------------------------------------------------------------------
1459 // ----------------------------------------------------------------------------
1461 bool wxBitmapHandler::Create(
1470 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1474 return(pBitmap
? Create( pBitmap
1482 bool wxBitmapHandler::Load(
1484 , const wxString
& rName
1491 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1495 return(pBitmap
? LoadFile( pBitmap
1504 bool wxBitmapHandler::Save(
1506 , const wxString
& rName
1510 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1514 return(pBitmap
? SaveFile( pBitmap
1520 bool wxBitmapHandler::Create(
1521 wxBitmap
* WXUNUSED(pBitmap
)
1522 , void* WXUNUSED(pData
)
1523 , long WXUNUSED(lType
)
1524 , int WXUNUSED(nWidth
)
1525 , int WXUNUSED(nHeight
)
1526 , int WXUNUSED(nDepth
)
1532 bool wxBitmapHandler::LoadFile(
1533 wxBitmap
* WXUNUSED(pBitmap
)
1534 , const wxString
& WXUNUSED(rName
)
1536 , long WXUNUSED(lType
)
1537 , int WXUNUSED(nDesiredWidth
)
1538 , int WXUNUSED(nDesiredHeight
)
1544 bool wxBitmapHandler::SaveFile(
1545 wxBitmap
* WXUNUSED(pBitmap
)
1546 , const wxString
& WXUNUSED(rName
)
1547 , int WXUNUSED(nType
)
1548 , const wxPalette
* WXUNUSED(pPalette
)
1554 // ----------------------------------------------------------------------------
1555 // Utility functions
1556 // ----------------------------------------------------------------------------
1557 HBITMAP
wxInvertMask(
1563 HBITMAP hBmpInvMask
= 0;
1565 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1568 // Get width/height from the bitmap if not given
1570 if (!nWidth
|| !nHeight
)
1572 BITMAPINFOHEADER2 vBmhdr
;
1574 ::GpiQueryBitmapInfoHeader( hBmpMask
1577 nWidth
= (int)vBmhdr
.cx
;
1578 nHeight
= (int)vBmhdr
.cy
;
1581 BITMAPINFOHEADER2 vBmih
;
1582 SIZEL vSize
= {0, 0};
1583 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1584 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1585 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1586 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1587 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1588 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1589 0, 0, nWidth
, nHeight
1592 memset(&vBmih
, '\0', 16);
1597 vBmih
.cBitCount
= 24;
1599 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1606 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1607 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1617 ::GpiDestroyPS(hPSSrc
);
1618 ::GpiDestroyPS(hPSDst
);
1619 ::DevCloseDC(hDCSrc
);
1620 ::DevCloseDC(hDCDst
);
1623 } // end of WxWinGdi_InvertMask