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/private.h"
32 #include "wx/xpmdecod.h"
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
39 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 wxBitmapRefData::wxBitmapRefData()
54 m_pSelectedInto
= NULL
;
57 m_hBitmap
= (WXHBITMAP
) NULL
;
58 } // end of wxBitmapRefData::wxBitmapRefData
60 void wxBitmapRefData::Free()
62 if ( m_pSelectedInto
)
64 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
68 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
70 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
78 } // end of wxBitmapRefData::Free
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // this function should be called from all wxBitmap ctors
89 // True for all bitmaps created from bits, wxImages, Xpms
91 } // end of wxBitmap::Init
93 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
)
95 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
96 POINTERINFO SIconInfo
;
98 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
100 wxLogLastError(wxT("WinQueryPointerInfo"));
103 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
105 m_refData
= pRefData
;
107 int nWidth
= rIcon
.GetWidth();
108 int nHeight
= rIcon
.GetHeight();
110 pRefData
->m_nWidth
= nWidth
;
111 pRefData
->m_nHeight
= nHeight
;
112 pRefData
->m_nDepth
= wxDisplayDepth();
114 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
116 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
118 pMask
->SetMaskBitmap(GetHBITMAP());
122 } // end of wxBitmap::CopyFromIconOrCursor
124 bool wxBitmap::CopyFromCursor(
125 const wxCursor
& rCursor
132 return(CopyFromIconOrCursor(rCursor
));
133 } // end of wxBitmap::CopyFromCursor
135 bool wxBitmap::CopyFromIcon(
144 return CopyFromIconOrCursor(rIcon
);
145 } // end of wxBitmap::CopyFromIcon
147 wxBitmap::~wxBitmap()
149 } // end of wxBitmap::~wxBitmap
160 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
161 BITMAPINFOHEADER2 vHeader
;
165 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
166 SIZEL vSize
= {0, 0};
169 wxASSERT(vHabmain
!= NULL
);
171 m_refData
= pRefData
;
173 pRefData
->m_nWidth
= nWidth
;
174 pRefData
->m_nHeight
= nHeight
;
175 pRefData
->m_nDepth
= nDepth
;
176 pRefData
->m_nNumColors
= 0;
177 pRefData
->m_pSelectedInto
= NULL
;
179 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
180 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
183 wxLogLastError(wxT("GpiCreatePS Failure"));
189 // We assume that it is in XBM format which is not quite the same as
190 // the format CreateBitmap() wants because the order of bytes in the
193 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
194 const size_t nPadding
= nBytesPerLine
% 2;
195 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
196 const char* pzSrc
= zBits
;
200 pzData
= (char *)malloc(nLen
);
202 char* pzDst
= pzData
;
204 for (nRows
= 0; nRows
< nHeight
; nRows
++)
206 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
208 unsigned char ucVal
= *pzSrc
++;
209 unsigned char ucReversed
= 0;
212 for (nBits
= 0; nBits
< 8; nBits
++)
215 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
218 *pzDst
++ = ucReversed
;
227 // Bits should already be in Windows standard format
229 pzData
= (char *)zBits
; // const_cast is harmless
233 nDepth
= 24; // MAX supported in PM
234 memset(&vHeader
, '\0', 16);
236 vHeader
.cx
= (USHORT
)nWidth
;
237 vHeader
.cy
= (USHORT
)nHeight
;
238 vHeader
.cPlanes
= 1L;
239 vHeader
.cBitCount
= (USHORT
)nDepth
;
240 vHeader
.usReserved
= 0;
242 memset(&vInfo
, '\0', 16);
244 vInfo
.cx
= (USHORT
)nWidth
;
245 vInfo
.cy
= (USHORT
)nHeight
;
247 vInfo
.cBitCount
= (USHORT
)nDepth
;
249 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
253 wxLogLastError(wxT("CreateBitmap"));
257 SetHBITMAP((WXHBITMAP
)hBmp
);
258 } // end of wxBitmap::wxBitmap
271 } // end of wxBitmap::wxBitmap
289 } // end of wxBitmap::wxBitmap
301 } // end of wxBitmap::wxBitmap
303 bool wxBitmap::Create(
310 BITMAPINFOHEADER2 vHeader
;
312 wxASSERT(vHabmain
!= NULL
);
314 m_refData
= new wxBitmapRefData
;
315 GetBitmapData()->m_nWidth
= nW
;
316 GetBitmapData()->m_nHeight
= nH
;
317 GetBitmapData()->m_nDepth
= nD
;
320 // Xpms and bitmaps from other images can also be mono's, but only
321 // mono's need help changing their colors with MemDC changes
325 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
326 SIZEL vSize
= {0, 0};
327 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
328 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
332 memset(&vHeader
, '\0', 16);
337 vHeader
.cBitCount
= 24; //nD;
339 hBmp
= ::GpiCreateBitmap( hPS
354 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
355 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
356 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
361 memset(&vHeader
, '\0', 16);
366 vHeader
.cBitCount
= (USHORT
)lBitCount
;
368 hBmp
= ::GpiCreateBitmap( hPSScreen
375 GetBitmapData()->m_nDepth
= wxDisplayDepth();
376 ::WinReleasePS(hPSScreen
);
378 SetHBITMAP((WXHBITMAP
)hBmp
);
381 } // end of wxBitmap::Create
383 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
387 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
391 m_refData
= new wxBitmapRefData
;
393 return handler
->LoadFile(this, filename
, type
, -1, -1);
396 else // no bitmap handler found
399 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
401 *this = wxBitmap(image
);
406 #endif // wxUSE_IMAGE
411 bool wxBitmap::LoadFile(
418 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
424 m_refData
= new wxBitmapRefData
;
426 return(pHandler
->LoadFile( this
437 } // end of wxBitmap::LoadFile
439 bool wxBitmap::Create(
449 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
455 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
460 m_refData
= new wxBitmapRefData
;
462 return(pHandler
->Create( this
469 } // end of wxBitmap::Create
471 bool wxBitmap::SaveFile(
472 const wxString
& rFilename
474 , const wxPalette
* pPalette
477 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
483 return pHandler
->SaveFile( this
491 // FIXME what about palette? shouldn't we use it?
492 wxImage vImage
= ConvertToImage();
497 return(vImage
.SaveFile( rFilename
501 } // end of wxBitmap::SaveFile
504 // ----------------------------------------------------------------------------
505 // wxImage-wxBitmap conversion
506 // ----------------------------------------------------------------------------
508 bool wxBitmap::CreateFromImage (
509 const wxImage
& rImage
513 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
514 m_refData
= new wxBitmapRefData();
516 int nSizeLimit
= 1024 * 768 * 3;
517 int nWidth
= rImage
.GetWidth();
518 int nBmpHeight
= rImage
.GetHeight();
519 int nBytePerLine
= nWidth
* 3;
520 int nSizeDWORD
= sizeof(DWORD
);
521 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
524 if (nLineBoundary
> 0)
526 nPadding
= nSizeDWORD
- nLineBoundary
;
527 nBytePerLine
+= nPadding
;
531 // Calc the number of DIBs and heights of DIBs
535 int nHeight
= nSizeLimit
/ nBytePerLine
;
537 if (nHeight
>= nBmpHeight
)
538 nHeight
= nBmpHeight
;
541 nNumDIB
= nBmpHeight
/ nHeight
;
542 nHRemain
= nBmpHeight
% nHeight
;
548 // Set bitmap parameters
550 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
552 SetHeight(nBmpHeight
);
558 nDepth
= wxDisplayDepth();
563 // Copy the palette from the source image
565 SetPalette(rImage
.GetPalette());
566 #endif // wxUSE_PALETTE
569 // Create a DIB header
571 BITMAPINFOHEADER2 vHeader
;
575 // Fill in the DIB header
577 memset(&vHeader
, '\0', 16);
579 vHeader
.cx
= (ULONG
)nWidth
;
580 vHeader
.cy
= (ULONG
)nHeight
;
581 vHeader
.cPlanes
= 1L;
582 vHeader
.cBitCount
= 24;
585 // Memory for DIB data
587 unsigned char* pucBits
;
589 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
592 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
595 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
598 // Create and set the device-dependent bitmap
600 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
601 SIZEL vSize
= {0, 0};
602 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
603 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
605 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
610 memset(&vInfo
, '\0', 16);
612 vInfo
.cx
= (ULONG
)nWidth
;
613 vInfo
.cy
= (ULONG
)nHeight
;
615 vInfo
.cBitCount
= 24; // Set to desired count going in
617 hBmp
= ::GpiCreateBitmap( hPS
624 HPAL hOldPalette
= NULLHANDLE
;
625 if (rImage
.GetPalette().Ok())
627 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
629 #endif // wxUSE_PALETTE
632 // Copy image data into DIB data and then into DDB (in a loop)
634 unsigned char* pData
= rImage
.GetData();
639 unsigned char* ptdata
= pData
;
640 unsigned char* ptbits
;
642 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
647 vError
= ::WinGetLastError(vHabmain
);
648 sError
= wxPMErrorToStr(vError
);
650 for (n
= 0; n
< nNumDIB
; n
++)
652 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
655 // Redefine height and size of the (possibly) last smaller DIB
656 // memory is not reallocated
659 vHeader
.cy
= (DWORD
)(nHeight
);
660 vHeader
.cbImage
= nBytePerLine
* nHeight
;
663 for (j
= 0; j
< nHeight
; j
++)
665 for (i
= 0; i
< nWidth
; i
++)
667 *(ptbits
++) = *(ptdata
+ 2);
668 *(ptbits
++) = *(ptdata
+ 1);
669 *(ptbits
++) = *(ptdata
);
672 for (i
= 0; i
< nPadding
; i
++)
677 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
678 // in combination with setting the bits into the selected bitmap
680 if ((lScans
= ::GpiSetBitmapBits( hPS
681 ,0 // Start at the bottom
682 ,(LONG
)nHeight
// One line per scan
690 vError
= ::WinGetLastError(vHabmain
);
691 sError
= wxPMErrorToStr(vError
);
693 hPSScreen
= ::GpiCreatePS( vHabmain
696 ,PU_PELS
| GPIA_ASSOC
699 POINTL vPoint
[4] = { {0, nOrigin
},
701 {0, 0}, {nWidth
, nHeight
}
705 ::GpiBitBlt( hPSScreen
712 ::GpiDestroyPS(hPSScreen
);
715 SetHBITMAP((WXHBITMAP
)hBmp
);
718 ::GpiSelectPalette(hPS
, hOldPalette
);
719 #endif // wxUSE_PALETTE
722 // Similarly, created an mono-bitmap for the possible mask
724 if (rImage
.HasMask())
728 vHeader
.cy
= nHeight
;
730 vHeader
.cBitCount
= 24;
731 hBmp
= ::GpiCreateBitmap( hPS
737 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
739 nHeight
= nBmpHeight
;
741 nHeight
= nSizeLimit
/ nBytePerLine
;
742 vHeader
.cy
= (DWORD
)(nHeight
);
745 unsigned char cRed
= rImage
.GetMaskRed();
746 unsigned char cGreen
= rImage
.GetMaskGreen();
747 unsigned char cBlue
= rImage
.GetMaskBlue();
748 unsigned char cZero
= 0;
749 unsigned char cOne
= 255;
752 for (n
= 0; n
< nNumDIB
; n
++)
754 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
757 // Redefine height and size of the (possibly) last smaller DIB
758 // memory is not reallocated
761 vHeader
.cy
= (DWORD
)(nHeight
);
762 vHeader
.cbImage
= nBytePerLine
* nHeight
;
765 for (int j
= 0; j
< nHeight
; j
++)
767 for (i
= 0; i
< nWidth
; i
++)
769 unsigned char cRedImage
= (*(ptdata
++)) ;
770 unsigned char cGreenImage
= (*(ptdata
++)) ;
771 unsigned char cBlueImage
= (*(ptdata
++)) ;
773 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
786 for (i
= 0; i
< nPadding
; i
++)
789 lScans
= ::GpiSetBitmapBits( hPS
790 ,0 // Start at the bottom
791 ,(LONG
)nHeight
// One line per scan
795 hPSScreen
= ::GpiCreatePS( vHabmain
798 ,PU_PELS
| GPIA_ASSOC
800 POINTL vPoint2
[4] = { {0, nOrigin
},
802 {0, 0}, {nWidth
, nHeight
}
804 ::GpiBitBlt( hPSScreen
811 ::GpiDestroyPS(hPSScreen
);
816 // Create a wxMask object
818 wxMask
* pMask
= new wxMask();
820 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
822 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
826 // Free allocated resources
828 ::GpiSetBitmap(hPS
, NULLHANDLE
);
830 ::DevCloseDC(hDCScreen
);
834 } // end of wxBitmap::CreateFromImage
836 wxImage
wxBitmap::ConvertToImage() const
841 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
844 // Create an wxImage object
846 int nWidth
= GetWidth();
847 int nHeight
= GetHeight();
850 int nBytePerLine
= nWidth
* 3;
851 int nSizeDWORD
= sizeof(DWORD
);
852 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
854 unsigned char* pData
;
855 unsigned char* lpBits
;
857 BITMAPINFOHEADER2 vDIBh
;
858 BITMAPINFO2 vDIBInfo
;
862 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
863 SIZEL vSizlPage
= {0,0};
864 HDC hDCMem
= NULLHANDLE
;
866 vImage
.Create( nWidth
869 pData
= vImage
.GetData();
872 wxFAIL_MSG( wxT("could not allocate data for image") );
875 if(nLineBoundary
> 0)
877 nPadding
= nSizeDWORD
- nLineBoundary
;
878 nBytePerLine
+= nPadding
;
880 wxDisplaySize( &nDevWidth
884 // Create and fill a DIB header
886 memset(&vDIBh
, '\0', 16);
891 vDIBh
.cBitCount
= 24;
893 memset(&vDIBInfo
, '\0', 16);
895 vDIBInfo
.cx
= nWidth
;
896 vDIBInfo
.cy
= nHeight
;
897 vDIBInfo
.cPlanes
= 1;
898 vDIBInfo
.cBitCount
= 24;
900 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
903 wxFAIL_MSG(wxT("could not allocate data for DIB"));
907 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
908 hBitmap
= (HBITMAP
)GetHBITMAP();
911 // May already be selected into a PS
913 if ((pDC
= GetSelectedInto()) != NULL
)
915 hPSMem
= pDC
->GetHPS();
919 hDCMem
= ::DevOpenDC( vHabmain
926 hPSMem
= ::GpiCreatePS( vHabmain
929 ,PU_PELS
| GPIA_ASSOC
932 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
937 vError
= ::WinGetLastError(vHabmain
);
938 sError
= wxPMErrorToStr(vError
);
942 // Copy data from the device-dependent bitmap to the DIB
944 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
954 vError
= ::WinGetLastError(vHabmain
);
955 sError
= wxPMErrorToStr(vError
);
959 // Copy DIB data into the wxImage object
963 unsigned char* ptdata
= pData
;
964 unsigned char* ptbits
= lpBits
;
966 for (i
= 0; i
< nHeight
; i
++)
968 for (j
= 0; j
< nWidth
; j
++)
970 *(ptdata
++) = *(ptbits
+2);
971 *(ptdata
++) = *(ptbits
+1);
972 *(ptdata
++) = *(ptbits
);
977 if ((pDC
= GetSelectedInto()) == NULL
)
979 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
980 ::GpiDestroyPS(hPSMem
);
981 ::DevCloseDC(hDCMem
);
985 // Similarly, set data according to the possible mask bitmap
987 if (GetMask() && GetMask()->GetMaskBitmap())
989 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
992 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
994 HDC hMemDC
= ::DevOpenDC( vHabmain
1001 HPS hMemPS
= ::GpiCreatePS( vHabmain
1004 ,PU_PELS
| GPIA_ASSOC
1006 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1007 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1008 ::GpiSetBitmap(hMemPS
, hBitmap
);
1009 ::GpiQueryBitmapBits( hPSMem
1015 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1016 ::GpiDestroyPS(hMemPS
);
1017 ::DevCloseDC(hMemDC
);
1020 // Background color set to RGB(16,16,16) in consistent with wxGTK
1022 unsigned char ucRed
= 16;
1023 unsigned char ucGreen
= 16;
1024 unsigned char ucBlue
= 16;
1028 for (i
= 0; i
< nHeight
; i
++)
1030 for (j
= 0; j
< nWidth
; j
++)
1036 *(ptdata
++) = ucRed
;
1037 *(ptdata
++) = ucGreen
;
1038 *(ptdata
++) = ucBlue
;
1044 vImage
.SetMaskColour( ucRed
1048 vImage
.SetMask(true);
1052 vImage
.SetMask(false);
1056 // Free allocated resources
1060 } // end of wxBitmap::ConvertToImage
1062 // ----------------------------------------------------------------------------
1063 // sub bitmap extraction
1064 // ----------------------------------------------------------------------------
1066 wxBitmap
wxBitmap::GetSubBitmap(
1070 wxCHECK_MSG( Ok() &&
1071 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1072 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1073 (rRect
.y
+ rRect
.height
<= GetHeight()),
1074 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1076 wxBitmap
vRet( rRect
.width
1080 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1086 SIZEL vSize
= {0, 0};
1087 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1088 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1089 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1090 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1091 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1092 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1094 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1097 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1098 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1108 // Copy mask if there is one
1112 BITMAPINFOHEADER2 vBmih
;
1114 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1115 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1116 vBmih
.cx
= rRect
.width
;
1117 vBmih
.cy
= rRect
.height
;
1119 vBmih
.cBitCount
= 24;
1121 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1128 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1129 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1131 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1132 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1141 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1142 vRet
.SetMask(pMask
);
1145 ::GpiSetBitmap(hPSSrc
, NULL
);
1146 ::GpiSetBitmap(hPSDst
, NULL
);
1147 ::GpiDestroyPS(hPSSrc
);
1148 ::GpiDestroyPS(hPSDst
);
1149 ::DevCloseDC(hDCSrc
);
1150 ::DevCloseDC(hDCDst
);
1152 } // end of wxBitmap::GetSubBitmap
1154 // ----------------------------------------------------------------------------
1155 // wxBitmap accessors
1156 // ----------------------------------------------------------------------------
1158 void wxBitmap::SetQuality(
1164 GetBitmapData()->m_nQuality
= nQ
;
1165 } // end of wxBitmap::SetQuality
1167 void wxBitmap::SetPalette(
1168 const wxPalette
& rPalette
1173 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1174 } // end of wxBitmap::SetPalette
1176 void wxBitmap::SetMask(
1182 GetBitmapData()->m_pBitmapMask
= pMask
;
1183 } // end of wxBitmap::SetMask
1185 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1188 } // end of wxBitmap::GetBitmapForDC
1190 // ----------------------------------------------------------------------------
1192 // ----------------------------------------------------------------------------
1197 } // end of wxMask::wxMask
1199 // Construct a mask from a bitmap and a colour indicating
1200 // the transparent area
1202 const wxBitmap
& rBitmap
1203 , const wxColour
& rColour
1210 } // end of wxMask::wxMask
1212 // Construct a mask from a bitmap and a palette index indicating
1213 // the transparent area
1215 const wxBitmap
& rBitmap
1223 } // end of wxMask::wxMask
1225 // Construct a mask from a mono bitmap (copies the bitmap).
1227 const wxBitmap
& rBitmap
1232 } // end of wxMask::wxMask
1237 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1238 } // end of wxMask::~wxMask
1240 // Create a mask from a mono bitmap (copies the bitmap).
1241 bool wxMask::Create(
1242 const wxBitmap
& rBitmap
1245 BITMAPINFOHEADER2 vBmih
;
1246 SIZEL vSize
= {0, 0};
1247 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1248 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1249 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1250 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1251 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1252 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1253 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1258 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1261 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1266 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1267 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1268 vBmih
.cx
= rBitmap
.GetWidth();
1269 vBmih
.cy
= rBitmap
.GetHeight();
1271 vBmih
.cBitCount
= 24;
1273 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1280 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1281 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1290 ::GpiDestroyPS(hPSSrc
);
1291 ::GpiDestroyPS(hPSDst
);
1292 ::DevCloseDC(hDCSrc
);
1293 ::DevCloseDC(hDCDst
);
1295 } // end of wxMask::Create
1297 // Create a mask from a bitmap and a palette index indicating
1298 // the transparent area
1299 bool wxMask::Create(
1300 const wxBitmap
& rBitmap
1306 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1309 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1312 unsigned char cGreen
;
1313 unsigned char cBlue
;
1315 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1321 wxColour
vTransparentColour( cRed
1326 return (Create( rBitmap
1332 } // end of wxMask::Create
1334 // Create a mask from a bitmap and a colour indicating
1335 // the transparent area
1336 bool wxMask::Create(
1337 const wxBitmap
& rBitmap
1338 , const wxColour
& rColour
1342 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1346 BITMAPINFOHEADER2 vBmih
;
1347 SIZEL vSize
= {0, 0};
1348 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1349 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1350 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1351 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1352 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1356 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1365 // Scan the bitmap for the transparent colour and set
1366 // the corresponding pixels in the mask to BLACK and
1367 // the rest to WHITE
1370 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1371 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1372 vBmih
.cx
= rBitmap
.GetWidth();
1373 vBmih
.cy
= rBitmap
.GetHeight();
1375 vBmih
.cBitCount
= 1;
1377 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1384 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1385 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1388 // This is not very efficient, but I can't think
1389 // of a better way of doing it
1391 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1393 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1395 POINTL vPt
= {w
, h
};
1396 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1397 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1400 // Doesn't make sense to continue
1406 if (vCol
== vMaskColour
)
1408 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1409 ::GpiSetPel(hPSDst
, &vPt
);
1413 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1414 ::GpiSetPel(hPSDst
, &vPt
);
1418 ::GpiSetBitmap(hPSSrc
, NULL
);
1419 ::GpiSetBitmap(hPSDst
, NULL
);
1420 ::GpiDestroyPS(hPSSrc
);
1421 ::GpiDestroyPS(hPSDst
);
1422 ::DevCloseDC(hDCSrc
);
1423 ::DevCloseDC(hDCDst
);
1425 } // end of wxMask::Create
1427 // ----------------------------------------------------------------------------
1429 // ----------------------------------------------------------------------------
1431 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1433 long WXUNUSED(lFlags
),
1438 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1442 return(pBitmap
? Create( pBitmap
1450 bool wxBitmapHandler::Load(
1458 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1462 return(pBitmap
? LoadFile( pBitmap
1470 bool wxBitmapHandler::Save(
1472 , const wxString
& rName
1476 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1480 return(pBitmap
? SaveFile( pBitmap
1486 bool wxBitmapHandler::Create(
1487 wxBitmap
* WXUNUSED(pBitmap
)
1488 , const void* WXUNUSED(pData
)
1489 , long WXUNUSED(lType
)
1490 , int WXUNUSED(nWidth
)
1491 , int WXUNUSED(nHeight
)
1492 , int WXUNUSED(nDepth
)
1498 bool wxBitmapHandler::LoadFile(
1499 wxBitmap
* WXUNUSED(pBitmap
)
1501 , long WXUNUSED(lType
)
1502 , int WXUNUSED(nDesiredWidth
)
1503 , int WXUNUSED(nDesiredHeight
)
1509 bool wxBitmapHandler::LoadFile(
1510 wxBitmap
* WXUNUSED(pBitmap
)
1511 , const wxString
& WXUNUSED(rName
)
1512 , long WXUNUSED(lType
)
1513 , int WXUNUSED(nDesiredWidth
)
1514 , int WXUNUSED(nDesiredHeight
)
1520 bool wxBitmapHandler::SaveFile(
1521 wxBitmap
* WXUNUSED(pBitmap
)
1522 , const wxString
& WXUNUSED(rName
)
1523 , int WXUNUSED(nType
)
1524 , const wxPalette
* WXUNUSED(pPalette
)
1530 // ----------------------------------------------------------------------------
1531 // Utility functions
1532 // ----------------------------------------------------------------------------
1533 HBITMAP
wxInvertMask(
1539 HBITMAP hBmpInvMask
= 0;
1541 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1544 // Get width/height from the bitmap if not given
1546 if (!nWidth
|| !nHeight
)
1548 BITMAPINFOHEADER2 vBmhdr
;
1550 ::GpiQueryBitmapInfoHeader( hBmpMask
1553 nWidth
= (int)vBmhdr
.cx
;
1554 nHeight
= (int)vBmhdr
.cy
;
1557 BITMAPINFOHEADER2 vBmih
;
1558 SIZEL vSize
= {0, 0};
1559 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1560 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1561 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1562 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1563 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1564 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1565 {0, 0}, {nWidth
, nHeight
}
1568 memset(&vBmih
, '\0', 16);
1573 vBmih
.cBitCount
= 24;
1575 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1582 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1583 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1593 ::GpiDestroyPS(hPSSrc
);
1594 ::GpiDestroyPS(hPSDst
);
1595 ::DevCloseDC(hDCSrc
);
1596 ::DevCloseDC(hDCDst
);
1599 } // end of WxWinGdi_InvertMask
1601 HBITMAP
wxFlipBmp( HBITMAP hBmp
, int nWidth
, int nHeight
)
1603 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxFlipBmp") );
1606 // Get width/height from the bitmap if not given
1608 if (!nWidth
|| !nHeight
)
1610 BITMAPINFOHEADER2 vBmhdr
;
1613 ::GpiQueryBitmapInfoHeader( hBmp
,
1615 nWidth
= (int)vBmhdr
.cx
;
1616 nHeight
= (int)vBmhdr
.cy
;
1619 BITMAPINFOHEADER2 vBmih
;
1620 SIZEL vSize
= {0, 0};
1621 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1622 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1626 (PDEVOPENDATA
)&vDop
,
1628 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1632 (PDEVOPENDATA
)&vDop
,
1634 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1637 PU_PELS
| GPIA_ASSOC
);
1638 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1641 PU_PELS
| GPIA_ASSOC
);
1642 POINTL vPoint
[4] = { {0, nHeight
},
1645 {nWidth
, nHeight
} };
1647 memset(&vBmih
, '\0', 16);
1652 vBmih
.cBitCount
= 24;
1654 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1660 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1661 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1663 ::GpiBitBlt( hPSDst
,
1670 ::GpiDestroyPS(hPSSrc
);
1671 ::GpiDestroyPS(hPSDst
);
1672 ::DevCloseDC(hDCSrc
);
1673 ::DevCloseDC(hDCDst
);
1676 } // end of wxFlipBmp