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(wxT("GpiDeleteBitmap(hbitmap)"));
72 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
74 wxLogLastError(wxT("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(wxT("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
= (unsigned char)(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
= (USHORT
)nDepth
;
246 vHeader
.usReserved
= 0;
248 memset(&vInfo
, '\0', 16);
250 vInfo
.cx
= (USHORT
)nWidth
;
251 vInfo
.cy
= (USHORT
)nHeight
;
253 vInfo
.cBitCount
= (USHORT
)nDepth
;
255 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
259 wxLogLastError(wxT("CreateBitmap"));
263 SetHBITMAP((WXHBITMAP
)hBmp
);
264 } // end of wxBitmap::wxBitmap
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::CreateFromXpm(
393 #if wxUSE_IMAGE && wxUSE_XPM
396 wxCHECK_MSG(ppData
!= NULL
, false, wxT("invalid bitmap data"))
398 wxXPMDecoder vDecoder
;
399 wxImage vImg
= vDecoder
.ReadData(ppData
);
401 wxCHECK_MSG(vImg
.Ok(), false, wxT("invalid bitmap data"))
403 *this = wxBitmap(vImg
);
408 } // end of wxBitmap::CreateFromXpm
410 bool wxBitmap::LoadFile(
417 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
423 m_refData
= new wxBitmapRefData
;
425 return(pHandler
->LoadFile( this
436 } // end of wxBitmap::LoadFile
438 bool wxBitmap::Create(
448 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
454 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
459 m_refData
= new wxBitmapRefData
;
461 return(pHandler
->Create( this
468 } // end of wxBitmap::Create
470 bool wxBitmap::SaveFile(
471 const wxString
& rFilename
473 , const wxPalette
* pPalette
476 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
482 return pHandler
->SaveFile( this
490 // FIXME what about palette? shouldn't we use it?
491 wxImage vImage
= ConvertToImage();
496 return(vImage
.SaveFile( rFilename
500 } // end of wxBitmap::SaveFile
503 // ----------------------------------------------------------------------------
504 // wxImage-wxBitmap conversion
505 // ----------------------------------------------------------------------------
507 bool wxBitmap::CreateFromImage (
508 const wxImage
& rImage
512 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
513 m_refData
= new wxBitmapRefData();
515 int nSizeLimit
= 1024 * 768 * 3;
516 int nWidth
= rImage
.GetWidth();
517 int nBmpHeight
= rImage
.GetHeight();
518 int nBytePerLine
= nWidth
* 3;
519 int nSizeDWORD
= sizeof(DWORD
);
520 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
523 if (nLineBoundary
> 0)
525 nPadding
= nSizeDWORD
- nLineBoundary
;
526 nBytePerLine
+= nPadding
;
530 // Calc the number of DIBs and heights of DIBs
534 int nHeight
= nSizeLimit
/ nBytePerLine
;
536 if (nHeight
>= nBmpHeight
)
537 nHeight
= nBmpHeight
;
540 nNumDIB
= nBmpHeight
/ nHeight
;
541 nHRemain
= nBmpHeight
% nHeight
;
547 // Set bitmap parameters
549 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
551 SetHeight(nBmpHeight
);
557 nDepth
= wxDisplayDepth();
562 // Copy the palette from the source image
564 SetPalette(rImage
.GetPalette());
565 #endif // wxUSE_PALETTE
568 // Create a DIB header
570 BITMAPINFOHEADER2 vHeader
;
574 // Fill in the DIB header
576 memset(&vHeader
, '\0', 16);
578 vHeader
.cx
= (ULONG
)nWidth
;
579 vHeader
.cy
= (ULONG
)nHeight
;
580 vHeader
.cPlanes
= 1L;
581 vHeader
.cBitCount
= 24;
584 // Memory for DIB data
586 unsigned char* pucBits
;
588 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
591 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
594 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
597 // Create and set the device-dependent bitmap
599 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
600 SIZEL vSize
= {0, 0};
601 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
602 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
604 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
609 memset(&vInfo
, '\0', 16);
611 vInfo
.cx
= (ULONG
)nWidth
;
612 vInfo
.cy
= (ULONG
)nHeight
;
614 vInfo
.cBitCount
= 24; // Set to desired count going in
616 hBmp
= ::GpiCreateBitmap( hPS
623 HPAL hOldPalette
= NULLHANDLE
;
624 if (rImage
.GetPalette().Ok())
626 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
628 #endif // wxUSE_PALETTE
631 // Copy image data into DIB data and then into DDB (in a loop)
633 unsigned char* pData
= rImage
.GetData();
638 unsigned char* ptdata
= pData
;
639 unsigned char* ptbits
;
641 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
646 vError
= ::WinGetLastError(vHabmain
);
647 sError
= wxPMErrorToStr(vError
);
649 for (n
= 0; n
< nNumDIB
; n
++)
651 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
654 // Redefine height and size of the (possibly) last smaller DIB
655 // memory is not reallocated
658 vHeader
.cy
= (DWORD
)(nHeight
);
659 vHeader
.cbImage
= nBytePerLine
* nHeight
;
662 for (j
= 0; j
< nHeight
; j
++)
664 for (i
= 0; i
< nWidth
; i
++)
666 *(ptbits
++) = *(ptdata
+ 2);
667 *(ptbits
++) = *(ptdata
+ 1);
668 *(ptbits
++) = *(ptdata
);
671 for (i
= 0; i
< nPadding
; i
++)
676 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
677 // in combination with setting the bits into the selected bitmap
679 if ((lScans
= ::GpiSetBitmapBits( hPS
680 ,0 // Start at the bottom
681 ,(LONG
)nHeight
// One line per scan
689 vError
= ::WinGetLastError(vHabmain
);
690 sError
= wxPMErrorToStr(vError
);
692 hPSScreen
= ::GpiCreatePS( vHabmain
695 ,PU_PELS
| GPIA_ASSOC
698 POINTL vPoint
[4] = { {0, nOrigin
},
700 {0, 0}, {nWidth
, nHeight
}
704 ::GpiBitBlt( hPSScreen
711 ::GpiDestroyPS(hPSScreen
);
714 SetHBITMAP((WXHBITMAP
)hBmp
);
717 ::GpiSelectPalette(hPS
, hOldPalette
);
718 #endif // wxUSE_PALETTE
721 // Similarly, created an mono-bitmap for the possible mask
723 if (rImage
.HasMask())
727 vHeader
.cy
= nHeight
;
729 vHeader
.cBitCount
= 24;
730 hBmp
= ::GpiCreateBitmap( hPS
736 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
738 nHeight
= nBmpHeight
;
740 nHeight
= nSizeLimit
/ nBytePerLine
;
741 vHeader
.cy
= (DWORD
)(nHeight
);
744 unsigned char cRed
= rImage
.GetMaskRed();
745 unsigned char cGreen
= rImage
.GetMaskGreen();
746 unsigned char cBlue
= rImage
.GetMaskBlue();
747 unsigned char cZero
= 0;
748 unsigned char cOne
= 255;
751 for (n
= 0; n
< nNumDIB
; n
++)
753 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
756 // Redefine height and size of the (possibly) last smaller DIB
757 // memory is not reallocated
760 vHeader
.cy
= (DWORD
)(nHeight
);
761 vHeader
.cbImage
= nBytePerLine
* nHeight
;
764 for (int j
= 0; j
< nHeight
; j
++)
766 for (i
= 0; i
< nWidth
; i
++)
768 unsigned char cRedImage
= (*(ptdata
++)) ;
769 unsigned char cGreenImage
= (*(ptdata
++)) ;
770 unsigned char cBlueImage
= (*(ptdata
++)) ;
772 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
785 for (i
= 0; i
< nPadding
; i
++)
788 lScans
= ::GpiSetBitmapBits( hPS
789 ,0 // Start at the bottom
790 ,(LONG
)nHeight
// One line per scan
794 hPSScreen
= ::GpiCreatePS( vHabmain
797 ,PU_PELS
| GPIA_ASSOC
799 POINTL vPoint2
[4] = { {0, nOrigin
},
801 {0, 0}, {nWidth
, nHeight
}
803 ::GpiBitBlt( hPSScreen
810 ::GpiDestroyPS(hPSScreen
);
815 // Create a wxMask object
817 wxMask
* pMask
= new wxMask();
819 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
821 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
825 // Free allocated resources
827 ::GpiSetBitmap(hPS
, NULLHANDLE
);
829 ::DevCloseDC(hDCScreen
);
833 } // end of wxBitmap::CreateFromImage
835 wxImage
wxBitmap::ConvertToImage() const
840 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
843 // Create an wxImage object
845 int nWidth
= GetWidth();
846 int nHeight
= GetHeight();
849 int nBytePerLine
= nWidth
* 3;
850 int nSizeDWORD
= sizeof(DWORD
);
851 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
853 unsigned char* pData
;
854 unsigned char* lpBits
;
856 BITMAPINFOHEADER2 vDIBh
;
857 BITMAPINFO2 vDIBInfo
;
861 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
862 SIZEL vSizlPage
= {0,0};
863 HDC hDCMem
= NULLHANDLE
;
865 vImage
.Create( nWidth
868 pData
= vImage
.GetData();
871 wxFAIL_MSG( wxT("could not allocate data for image") );
874 if(nLineBoundary
> 0)
876 nPadding
= nSizeDWORD
- nLineBoundary
;
877 nBytePerLine
+= nPadding
;
879 wxDisplaySize( &nDevWidth
883 // Create and fill a DIB header
885 memset(&vDIBh
, '\0', 16);
890 vDIBh
.cBitCount
= 24;
892 memset(&vDIBInfo
, '\0', 16);
894 vDIBInfo
.cx
= nWidth
;
895 vDIBInfo
.cy
= nHeight
;
896 vDIBInfo
.cPlanes
= 1;
897 vDIBInfo
.cBitCount
= 24;
899 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
902 wxFAIL_MSG(wxT("could not allocate data for DIB"));
906 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
907 hBitmap
= (HBITMAP
)GetHBITMAP();
910 // May already be selected into a PS
912 if ((pDC
= GetSelectedInto()) != NULL
)
914 hPSMem
= pDC
->GetHPS();
918 hDCMem
= ::DevOpenDC( vHabmain
925 hPSMem
= ::GpiCreatePS( vHabmain
928 ,PU_PELS
| GPIA_ASSOC
931 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
936 vError
= ::WinGetLastError(vHabmain
);
937 sError
= wxPMErrorToStr(vError
);
941 // Copy data from the device-dependent bitmap to the DIB
943 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
953 vError
= ::WinGetLastError(vHabmain
);
954 sError
= wxPMErrorToStr(vError
);
958 // Copy DIB data into the wxImage object
962 unsigned char* ptdata
= pData
;
963 unsigned char* ptbits
= lpBits
;
965 for (i
= 0; i
< nHeight
; i
++)
967 for (j
= 0; j
< nWidth
; j
++)
969 *(ptdata
++) = *(ptbits
+2);
970 *(ptdata
++) = *(ptbits
+1);
971 *(ptdata
++) = *(ptbits
);
976 if ((pDC
= GetSelectedInto()) == NULL
)
978 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
979 ::GpiDestroyPS(hPSMem
);
980 ::DevCloseDC(hDCMem
);
984 // Similarly, set data according to the possible mask bitmap
986 if (GetMask() && GetMask()->GetMaskBitmap())
988 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
991 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
993 HDC hMemDC
= ::DevOpenDC( vHabmain
1000 HPS hMemPS
= ::GpiCreatePS( vHabmain
1003 ,PU_PELS
| GPIA_ASSOC
1005 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1006 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1007 ::GpiSetBitmap(hMemPS
, hBitmap
);
1008 ::GpiQueryBitmapBits( hPSMem
1014 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1015 ::GpiDestroyPS(hMemPS
);
1016 ::DevCloseDC(hMemDC
);
1019 // Background color set to RGB(16,16,16) in consistent with wxGTK
1021 unsigned char ucRed
= 16;
1022 unsigned char ucGreen
= 16;
1023 unsigned char ucBlue
= 16;
1027 for (i
= 0; i
< nHeight
; i
++)
1029 for (j
= 0; j
< nWidth
; j
++)
1035 *(ptdata
++) = ucRed
;
1036 *(ptdata
++) = ucGreen
;
1037 *(ptdata
++) = ucBlue
;
1043 vImage
.SetMaskColour( ucRed
1047 vImage
.SetMask(true);
1051 vImage
.SetMask(false);
1055 // Free allocated resources
1059 } // end of wxBitmap::ConvertToImage
1061 // ----------------------------------------------------------------------------
1062 // sub bitmap extraction
1063 // ----------------------------------------------------------------------------
1065 wxBitmap
wxBitmap::GetSubBitmap(
1069 wxCHECK_MSG( Ok() &&
1070 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1071 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1072 (rRect
.y
+ rRect
.height
<= GetHeight()),
1073 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1075 wxBitmap
vRet( rRect
.width
1079 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1085 SIZEL vSize
= {0, 0};
1086 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1087 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1088 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1089 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1090 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1091 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1093 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1096 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1097 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1107 // Copy mask if there is one
1111 BITMAPINFOHEADER2 vBmih
;
1113 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1114 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1115 vBmih
.cx
= rRect
.width
;
1116 vBmih
.cy
= rRect
.height
;
1118 vBmih
.cBitCount
= 24;
1120 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1127 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1128 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1130 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1131 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1140 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1141 vRet
.SetMask(pMask
);
1144 ::GpiSetBitmap(hPSSrc
, NULL
);
1145 ::GpiSetBitmap(hPSDst
, NULL
);
1146 ::GpiDestroyPS(hPSSrc
);
1147 ::GpiDestroyPS(hPSDst
);
1148 ::DevCloseDC(hDCSrc
);
1149 ::DevCloseDC(hDCDst
);
1151 } // end of wxBitmap::GetSubBitmap
1153 // ----------------------------------------------------------------------------
1154 // wxBitmap accessors
1155 // ----------------------------------------------------------------------------
1157 void wxBitmap::SetQuality(
1163 GetBitmapData()->m_nQuality
= nQ
;
1164 } // end of wxBitmap::SetQuality
1166 void wxBitmap::SetPalette(
1167 const wxPalette
& rPalette
1172 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1173 } // end of wxBitmap::SetPalette
1175 void wxBitmap::SetMask(
1181 GetBitmapData()->m_pBitmapMask
= pMask
;
1182 } // end of wxBitmap::SetMask
1184 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1187 } // end of wxBitmap::GetBitmapForDC
1189 // ----------------------------------------------------------------------------
1191 // ----------------------------------------------------------------------------
1196 } // end of wxMask::wxMask
1198 // Construct a mask from a bitmap and a colour indicating
1199 // the transparent area
1201 const wxBitmap
& rBitmap
1202 , const wxColour
& rColour
1209 } // end of wxMask::wxMask
1211 // Construct a mask from a bitmap and a palette index indicating
1212 // the transparent area
1214 const wxBitmap
& rBitmap
1222 } // end of wxMask::wxMask
1224 // Construct a mask from a mono bitmap (copies the bitmap).
1226 const wxBitmap
& rBitmap
1231 } // end of wxMask::wxMask
1236 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1237 } // end of wxMask::~wxMask
1239 // Create a mask from a mono bitmap (copies the bitmap).
1240 bool wxMask::Create(
1241 const wxBitmap
& rBitmap
1244 BITMAPINFOHEADER2 vBmih
;
1245 SIZEL vSize
= {0, 0};
1246 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1247 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1248 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1249 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1250 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1251 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1252 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1257 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1260 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1265 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1266 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1267 vBmih
.cx
= rBitmap
.GetWidth();
1268 vBmih
.cy
= rBitmap
.GetHeight();
1270 vBmih
.cBitCount
= 24;
1272 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1279 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1280 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1289 ::GpiDestroyPS(hPSSrc
);
1290 ::GpiDestroyPS(hPSDst
);
1291 ::DevCloseDC(hDCSrc
);
1292 ::DevCloseDC(hDCDst
);
1294 } // end of wxMask::Create
1296 // Create a mask from a bitmap and a palette index indicating
1297 // the transparent area
1298 bool wxMask::Create(
1299 const wxBitmap
& rBitmap
1305 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1308 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1311 unsigned char cGreen
;
1312 unsigned char cBlue
;
1314 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1320 wxColour
vTransparentColour( cRed
1325 return (Create( rBitmap
1331 } // end of wxMask::Create
1333 // Create a mask from a bitmap and a colour indicating
1334 // the transparent area
1335 bool wxMask::Create(
1336 const wxBitmap
& rBitmap
1337 , const wxColour
& rColour
1341 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1345 BITMAPINFOHEADER2 vBmih
;
1346 SIZEL vSize
= {0, 0};
1347 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1348 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1349 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1350 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1351 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1355 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1364 // Scan the bitmap for the transparent colour and set
1365 // the corresponding pixels in the mask to BLACK and
1366 // the rest to WHITE
1369 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1370 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1371 vBmih
.cx
= rBitmap
.GetWidth();
1372 vBmih
.cy
= rBitmap
.GetHeight();
1374 vBmih
.cBitCount
= 1;
1376 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1383 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1384 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1387 // This is not very efficient, but I can't think
1388 // of a better way of doing it
1390 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1392 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1394 POINTL vPt
= {w
, h
};
1395 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1396 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1399 // Doesn't make sense to continue
1405 if (vCol
== vMaskColour
)
1407 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1408 ::GpiSetPel(hPSDst
, &vPt
);
1412 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1413 ::GpiSetPel(hPSDst
, &vPt
);
1417 ::GpiSetBitmap(hPSSrc
, NULL
);
1418 ::GpiSetBitmap(hPSDst
, NULL
);
1419 ::GpiDestroyPS(hPSSrc
);
1420 ::GpiDestroyPS(hPSDst
);
1421 ::DevCloseDC(hDCSrc
);
1422 ::DevCloseDC(hDCDst
);
1424 } // end of wxMask::Create
1426 // ----------------------------------------------------------------------------
1428 // ----------------------------------------------------------------------------
1430 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1432 long WXUNUSED(lFlags
),
1437 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1441 return(pBitmap
? Create( pBitmap
1449 bool wxBitmapHandler::Load(
1457 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1461 return(pBitmap
? LoadFile( pBitmap
1469 bool wxBitmapHandler::Save(
1471 , const wxString
& rName
1475 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1479 return(pBitmap
? SaveFile( pBitmap
1485 bool wxBitmapHandler::Create(
1486 wxBitmap
* WXUNUSED(pBitmap
)
1487 , void* WXUNUSED(pData
)
1488 , long WXUNUSED(lType
)
1489 , int WXUNUSED(nWidth
)
1490 , int WXUNUSED(nHeight
)
1491 , int WXUNUSED(nDepth
)
1497 bool wxBitmapHandler::LoadFile(
1498 wxBitmap
* WXUNUSED(pBitmap
)
1500 , long WXUNUSED(lType
)
1501 , int WXUNUSED(nDesiredWidth
)
1502 , int WXUNUSED(nDesiredHeight
)
1508 bool wxBitmapHandler::SaveFile(
1509 wxBitmap
* WXUNUSED(pBitmap
)
1510 , const wxString
& WXUNUSED(rName
)
1511 , int WXUNUSED(nType
)
1512 , const wxPalette
* WXUNUSED(pPalette
)
1518 // ----------------------------------------------------------------------------
1519 // Utility functions
1520 // ----------------------------------------------------------------------------
1521 HBITMAP
wxInvertMask(
1527 HBITMAP hBmpInvMask
= 0;
1529 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1532 // Get width/height from the bitmap if not given
1534 if (!nWidth
|| !nHeight
)
1536 BITMAPINFOHEADER2 vBmhdr
;
1538 ::GpiQueryBitmapInfoHeader( hBmpMask
1541 nWidth
= (int)vBmhdr
.cx
;
1542 nHeight
= (int)vBmhdr
.cy
;
1545 BITMAPINFOHEADER2 vBmih
;
1546 SIZEL vSize
= {0, 0};
1547 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1548 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1549 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1550 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1551 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1552 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1553 {0, 0}, {nWidth
, nHeight
}
1556 memset(&vBmih
, '\0', 16);
1561 vBmih
.cBitCount
= 24;
1563 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1570 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1571 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1581 ::GpiDestroyPS(hPSSrc
);
1582 ::GpiDestroyPS(hPSDst
);
1583 ::DevCloseDC(hDCSrc
);
1584 ::DevCloseDC(hDCDst
);
1587 } // end of WxWinGdi_InvertMask