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"
21 #include "wx/palette.h"
22 #include "wx/dcmemory.h"
23 #include "wx/bitmap.h"
27 #include "wx/os2/private.h"
31 #include "wx/xpmdecod.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
38 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
40 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
42 // ============================================================================
44 // ============================================================================
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 wxBitmapRefData::wxBitmapRefData()
53 m_pSelectedInto
= NULL
;
56 m_hBitmap
= (WXHBITMAP
) NULL
;
57 } // end of wxBitmapRefData::wxBitmapRefData
59 void wxBitmapRefData::Free()
61 if ( m_pSelectedInto
)
63 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
67 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
69 wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)"));
77 } // end of wxBitmapRefData::Free
79 // ----------------------------------------------------------------------------
81 // ----------------------------------------------------------------------------
83 // this function should be called from all wxBitmap ctors
88 // True for all bitmaps created from bits, wxImages, Xpms
90 } // end of wxBitmap::Init
92 bool wxBitmap::CopyFromIconOrCursor(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
;
115 wxMask
* pMask
= new wxMask(SIconInfo
.hbmPointer
);
117 pMask
->SetMaskBitmap(GetHBITMAP());
121 } // end of wxBitmap::CopyFromIconOrCursor
123 bool wxBitmap::CopyFromCursor(
124 const wxCursor
& rCursor
131 return(CopyFromIconOrCursor(rCursor
));
132 } // end of wxBitmap::CopyFromCursor
134 bool wxBitmap::CopyFromIcon(
143 return CopyFromIconOrCursor(rIcon
);
144 } // end of wxBitmap::CopyFromIcon
146 wxBitmap::~wxBitmap()
148 } // end of wxBitmap::~wxBitmap
159 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
160 BITMAPINFOHEADER2 vHeader
;
164 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
165 SIZEL vSize
= {0, 0};
168 wxASSERT(vHabmain
!= NULL
);
170 m_refData
= pRefData
;
172 pRefData
->m_nWidth
= nWidth
;
173 pRefData
->m_nHeight
= nHeight
;
174 pRefData
->m_nDepth
= nDepth
;
175 pRefData
->m_nNumColors
= 0;
176 pRefData
->m_pSelectedInto
= NULL
;
178 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
179 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
182 wxLogLastError(wxT("GpiCreatePS Failure"));
188 // We assume that it is in XBM format which is not quite the same as
189 // the format CreateBitmap() wants because the order of bytes in the
192 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
193 const size_t nPadding
= nBytesPerLine
% 2;
194 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
195 const char* pzSrc
= zBits
;
199 pzData
= (char *)malloc(nLen
);
201 char* pzDst
= pzData
;
203 for (nRows
= 0; nRows
< nHeight
; nRows
++)
205 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
207 unsigned char ucVal
= *pzSrc
++;
208 unsigned char ucReversed
= 0;
211 for (nBits
= 0; nBits
< 8; nBits
++)
214 ucReversed
= (unsigned char)(ucReversed
| (ucVal
& 0x01));
217 *pzDst
++ = ucReversed
;
226 // Bits should already be in Windows standard format
228 pzData
= (char *)zBits
; // const_cast is harmless
232 nDepth
= 24; // MAX supported in PM
233 memset(&vHeader
, '\0', 16);
235 vHeader
.cx
= (USHORT
)nWidth
;
236 vHeader
.cy
= (USHORT
)nHeight
;
237 vHeader
.cPlanes
= 1L;
238 vHeader
.cBitCount
= (USHORT
)nDepth
;
239 vHeader
.usReserved
= 0;
241 memset(&vInfo
, '\0', 16);
243 vInfo
.cx
= (USHORT
)nWidth
;
244 vInfo
.cy
= (USHORT
)nHeight
;
246 vInfo
.cBitCount
= (USHORT
)nDepth
;
248 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
252 wxLogLastError(wxT("CreateBitmap"));
256 SetHBITMAP((WXHBITMAP
)hBmp
);
257 } // end of wxBitmap::wxBitmap
270 } // end of wxBitmap::wxBitmap
288 } // end of wxBitmap::wxBitmap
300 } // end of wxBitmap::wxBitmap
302 bool wxBitmap::Create(
309 BITMAPINFOHEADER2 vHeader
;
311 wxASSERT(vHabmain
!= NULL
);
313 m_refData
= new wxBitmapRefData
;
314 GetBitmapData()->m_nWidth
= nW
;
315 GetBitmapData()->m_nHeight
= nH
;
316 GetBitmapData()->m_nDepth
= nD
;
319 // Xpms and bitmaps from other images can also be mono's, but only
320 // mono's need help changing their colors with MemDC changes
324 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
325 SIZEL vSize
= {0, 0};
326 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
327 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
331 memset(&vHeader
, '\0', 16);
336 vHeader
.cBitCount
= 24; //nD;
338 hBmp
= ::GpiCreateBitmap( hPS
353 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
354 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
355 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
360 memset(&vHeader
, '\0', 16);
365 vHeader
.cBitCount
= (USHORT
)lBitCount
;
367 hBmp
= ::GpiCreateBitmap( hPSScreen
374 GetBitmapData()->m_nDepth
= wxDisplayDepth();
375 ::WinReleasePS(hPSScreen
);
377 SetHBITMAP((WXHBITMAP
)hBmp
);
380 } // end of wxBitmap::Create
382 bool wxBitmap::CreateFromXpm(
386 #if wxUSE_IMAGE && wxUSE_XPM
389 wxCHECK_MSG(ppData
!= NULL
, false, wxT("invalid bitmap data"));
391 wxXPMDecoder vDecoder
;
392 wxImage vImg
= vDecoder
.ReadData(ppData
);
394 wxCHECK_MSG(vImg
.Ok(), false, wxT("invalid bitmap data"));
396 *this = wxBitmap(vImg
);
401 } // end of wxBitmap::CreateFromXpm
403 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
407 wxBitmapHandler
*handler
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
);
411 m_refData
= new wxBitmapRefData
;
413 return handler
->LoadFile(this, filename
, type
, -1, -1);
416 else // no bitmap handler found
419 if ( image
.LoadFile( filename
, type
) && image
.Ok() )
421 *this = wxBitmap(image
);
426 #endif // wxUSE_IMAGE
431 bool wxBitmap::LoadFile(
438 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
444 m_refData
= new wxBitmapRefData
;
446 return(pHandler
->LoadFile( this
457 } // end of wxBitmap::LoadFile
459 bool wxBitmap::Create(
469 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
475 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
);
480 m_refData
= new wxBitmapRefData
;
482 return(pHandler
->Create( this
489 } // end of wxBitmap::Create
491 bool wxBitmap::SaveFile(
492 const wxString
& rFilename
494 , const wxPalette
* pPalette
497 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
503 return pHandler
->SaveFile( this
511 // FIXME what about palette? shouldn't we use it?
512 wxImage vImage
= ConvertToImage();
517 return(vImage
.SaveFile( rFilename
521 } // end of wxBitmap::SaveFile
524 // ----------------------------------------------------------------------------
525 // wxImage-wxBitmap conversion
526 // ----------------------------------------------------------------------------
528 bool wxBitmap::CreateFromImage (
529 const wxImage
& rImage
533 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
534 m_refData
= new wxBitmapRefData();
536 int nSizeLimit
= 1024 * 768 * 3;
537 int nWidth
= rImage
.GetWidth();
538 int nBmpHeight
= rImage
.GetHeight();
539 int nBytePerLine
= nWidth
* 3;
540 int nSizeDWORD
= sizeof(DWORD
);
541 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
544 if (nLineBoundary
> 0)
546 nPadding
= nSizeDWORD
- nLineBoundary
;
547 nBytePerLine
+= nPadding
;
551 // Calc the number of DIBs and heights of DIBs
555 int nHeight
= nSizeLimit
/ nBytePerLine
;
557 if (nHeight
>= nBmpHeight
)
558 nHeight
= nBmpHeight
;
561 nNumDIB
= nBmpHeight
/ nHeight
;
562 nHRemain
= nBmpHeight
% nHeight
;
568 // Set bitmap parameters
570 wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image"));
572 SetHeight(nBmpHeight
);
578 nDepth
= wxDisplayDepth();
583 // Copy the palette from the source image
585 SetPalette(rImage
.GetPalette());
586 #endif // wxUSE_PALETTE
589 // Create a DIB header
591 BITMAPINFOHEADER2 vHeader
;
595 // Fill in the DIB header
597 memset(&vHeader
, '\0', 16);
599 vHeader
.cx
= (ULONG
)nWidth
;
600 vHeader
.cy
= (ULONG
)nHeight
;
601 vHeader
.cPlanes
= 1L;
602 vHeader
.cBitCount
= 24;
605 // Memory for DIB data
607 unsigned char* pucBits
;
609 pucBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
612 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
615 memset(pucBits
, '\0', (nBytePerLine
* nHeight
));
618 // Create and set the device-dependent bitmap
620 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
621 SIZEL vSize
= {0, 0};
622 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
623 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
625 HDC hDCScreen
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
630 memset(&vInfo
, '\0', 16);
632 vInfo
.cx
= (ULONG
)nWidth
;
633 vInfo
.cy
= (ULONG
)nHeight
;
635 vInfo
.cBitCount
= 24; // Set to desired count going in
637 hBmp
= ::GpiCreateBitmap( hPS
644 HPAL hOldPalette
= NULLHANDLE
;
645 if (rImage
.GetPalette().Ok())
647 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
649 #endif // wxUSE_PALETTE
652 // Copy image data into DIB data and then into DDB (in a loop)
654 unsigned char* pData
= rImage
.GetData();
659 unsigned char* ptdata
= pData
;
660 unsigned char* ptbits
;
662 if ((hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
)
667 vError
= ::WinGetLastError(vHabmain
);
668 sError
= wxPMErrorToStr(vError
);
670 for (n
= 0; n
< nNumDIB
; n
++)
672 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
675 // Redefine height and size of the (possibly) last smaller DIB
676 // memory is not reallocated
679 vHeader
.cy
= (DWORD
)(nHeight
);
680 vHeader
.cbImage
= nBytePerLine
* nHeight
;
683 for (j
= 0; j
< nHeight
; j
++)
685 for (i
= 0; i
< nWidth
; i
++)
687 *(ptbits
++) = *(ptdata
+ 2);
688 *(ptbits
++) = *(ptdata
+ 1);
689 *(ptbits
++) = *(ptdata
);
692 for (i
= 0; i
< nPadding
; i
++)
697 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
698 // in combination with setting the bits into the selected bitmap
700 if ((lScans
= ::GpiSetBitmapBits( hPS
701 ,0 // Start at the bottom
702 ,(LONG
)nHeight
// One line per scan
710 vError
= ::WinGetLastError(vHabmain
);
711 sError
= wxPMErrorToStr(vError
);
713 hPSScreen
= ::GpiCreatePS( vHabmain
716 ,PU_PELS
| GPIA_ASSOC
719 POINTL vPoint
[4] = { {0, nOrigin
},
721 {0, 0}, {nWidth
, nHeight
}
725 ::GpiBitBlt( hPSScreen
732 ::GpiDestroyPS(hPSScreen
);
735 SetHBITMAP((WXHBITMAP
)hBmp
);
738 ::GpiSelectPalette(hPS
, hOldPalette
);
739 #endif // wxUSE_PALETTE
742 // Similarly, created an mono-bitmap for the possible mask
744 if (rImage
.HasMask())
748 vHeader
.cy
= nHeight
;
750 vHeader
.cBitCount
= 24;
751 hBmp
= ::GpiCreateBitmap( hPS
757 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
759 nHeight
= nBmpHeight
;
761 nHeight
= nSizeLimit
/ nBytePerLine
;
762 vHeader
.cy
= (DWORD
)(nHeight
);
765 unsigned char cRed
= rImage
.GetMaskRed();
766 unsigned char cGreen
= rImage
.GetMaskGreen();
767 unsigned char cBlue
= rImage
.GetMaskBlue();
768 unsigned char cZero
= 0;
769 unsigned char cOne
= 255;
772 for (n
= 0; n
< nNumDIB
; n
++)
774 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
777 // Redefine height and size of the (possibly) last smaller DIB
778 // memory is not reallocated
781 vHeader
.cy
= (DWORD
)(nHeight
);
782 vHeader
.cbImage
= nBytePerLine
* nHeight
;
785 for (int j
= 0; j
< nHeight
; j
++)
787 for (i
= 0; i
< nWidth
; i
++)
789 unsigned char cRedImage
= (*(ptdata
++)) ;
790 unsigned char cGreenImage
= (*(ptdata
++)) ;
791 unsigned char cBlueImage
= (*(ptdata
++)) ;
793 if ((cRedImage
!= cRed
) || (cGreenImage
!= cGreen
) || (cBlueImage
!= cBlue
))
806 for (i
= 0; i
< nPadding
; i
++)
809 lScans
= ::GpiSetBitmapBits( hPS
810 ,0 // Start at the bottom
811 ,(LONG
)nHeight
// One line per scan
815 hPSScreen
= ::GpiCreatePS( vHabmain
818 ,PU_PELS
| GPIA_ASSOC
820 POINTL vPoint2
[4] = { {0, nOrigin
},
822 {0, 0}, {nWidth
, nHeight
}
824 ::GpiBitBlt( hPSScreen
831 ::GpiDestroyPS(hPSScreen
);
836 // Create a wxMask object
838 wxMask
* pMask
= new wxMask();
840 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
842 hBmpOld
= ::GpiSetBitmap(hPS
, hBmpOld
);
846 // Free allocated resources
848 ::GpiSetBitmap(hPS
, NULLHANDLE
);
850 ::DevCloseDC(hDCScreen
);
854 } // end of wxBitmap::CreateFromImage
856 wxImage
wxBitmap::ConvertToImage() const
861 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
864 // Create an wxImage object
866 int nWidth
= GetWidth();
867 int nHeight
= GetHeight();
870 int nBytePerLine
= nWidth
* 3;
871 int nSizeDWORD
= sizeof(DWORD
);
872 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
874 unsigned char* pData
;
875 unsigned char* lpBits
;
877 BITMAPINFOHEADER2 vDIBh
;
878 BITMAPINFO2 vDIBInfo
;
882 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
883 SIZEL vSizlPage
= {0,0};
884 HDC hDCMem
= NULLHANDLE
;
886 vImage
.Create( nWidth
889 pData
= vImage
.GetData();
892 wxFAIL_MSG( wxT("could not allocate data for image") );
895 if(nLineBoundary
> 0)
897 nPadding
= nSizeDWORD
- nLineBoundary
;
898 nBytePerLine
+= nPadding
;
900 wxDisplaySize( &nDevWidth
904 // Create and fill a DIB header
906 memset(&vDIBh
, '\0', 16);
911 vDIBh
.cBitCount
= 24;
913 memset(&vDIBInfo
, '\0', 16);
915 vDIBInfo
.cx
= nWidth
;
916 vDIBInfo
.cy
= nHeight
;
917 vDIBInfo
.cPlanes
= 1;
918 vDIBInfo
.cBitCount
= 24;
920 lpBits
= (unsigned char *)malloc(nBytePerLine
* nHeight
);
923 wxFAIL_MSG(wxT("could not allocate data for DIB"));
927 memset(lpBits
, '\0', (nBytePerLine
* nHeight
));
928 hBitmap
= (HBITMAP
)GetHBITMAP();
931 // May already be selected into a PS
933 if ((pDC
= GetSelectedInto()) != NULL
)
935 hPSMem
= pDC
->GetHPS();
939 hDCMem
= ::DevOpenDC( vHabmain
946 hPSMem
= ::GpiCreatePS( vHabmain
949 ,PU_PELS
| GPIA_ASSOC
952 if ((hOldBitmap
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
)
957 vError
= ::WinGetLastError(vHabmain
);
958 sError
= wxPMErrorToStr(vError
);
962 // Copy data from the device-dependent bitmap to the DIB
964 if ((lScans
= ::GpiQueryBitmapBits( hPSMem
974 vError
= ::WinGetLastError(vHabmain
);
975 sError
= wxPMErrorToStr(vError
);
979 // Copy DIB data into the wxImage object
983 unsigned char* ptdata
= pData
;
984 unsigned char* ptbits
= lpBits
;
986 for (i
= 0; i
< nHeight
; i
++)
988 for (j
= 0; j
< nWidth
; j
++)
990 *(ptdata
++) = *(ptbits
+2);
991 *(ptdata
++) = *(ptbits
+1);
992 *(ptdata
++) = *(ptbits
);
997 if ((pDC
= GetSelectedInto()) == NULL
)
999 ::GpiSetBitmap(hPSMem
, NULLHANDLE
);
1000 ::GpiDestroyPS(hPSMem
);
1001 ::DevCloseDC(hDCMem
);
1005 // Similarly, set data according to the possible mask bitmap
1007 if (GetMask() && GetMask()->GetMaskBitmap())
1009 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
1012 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1014 HDC hMemDC
= ::DevOpenDC( vHabmain
1018 ,(PDEVOPENDATA
)&vDop
1021 HPS hMemPS
= ::GpiCreatePS( vHabmain
1024 ,PU_PELS
| GPIA_ASSOC
1026 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
1027 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
1028 ::GpiSetBitmap(hMemPS
, hBitmap
);
1029 ::GpiQueryBitmapBits( hPSMem
1035 ::GpiSetBitmap(hMemPS
, NULLHANDLE
);
1036 ::GpiDestroyPS(hMemPS
);
1037 ::DevCloseDC(hMemDC
);
1040 // Background color set to RGB(16,16,16) in consistent with wxGTK
1042 unsigned char ucRed
= 16;
1043 unsigned char ucGreen
= 16;
1044 unsigned char ucBlue
= 16;
1048 for (i
= 0; i
< nHeight
; i
++)
1050 for (j
= 0; j
< nWidth
; j
++)
1056 *(ptdata
++) = ucRed
;
1057 *(ptdata
++) = ucGreen
;
1058 *(ptdata
++) = ucBlue
;
1064 vImage
.SetMaskColour( ucRed
1068 vImage
.SetMask(true);
1072 vImage
.SetMask(false);
1076 // Free allocated resources
1080 } // end of wxBitmap::ConvertToImage
1082 // ----------------------------------------------------------------------------
1083 // sub bitmap extraction
1084 // ----------------------------------------------------------------------------
1086 wxBitmap
wxBitmap::GetSubBitmap(
1090 wxCHECK_MSG( Ok() &&
1091 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1092 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1093 (rRect
.y
+ rRect
.height
<= GetHeight()),
1094 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1096 wxBitmap
vRet( rRect
.width
1100 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1106 SIZEL vSize
= {0, 0};
1107 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1108 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1109 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1110 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1111 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1112 POINTL vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
},
1114 {rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
}
1117 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1118 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1128 // Copy mask if there is one
1132 BITMAPINFOHEADER2 vBmih
;
1134 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1135 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1136 vBmih
.cx
= rRect
.width
;
1137 vBmih
.cy
= rRect
.height
;
1139 vBmih
.cBitCount
= 24;
1141 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1148 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1149 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1151 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1152 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1161 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1162 vRet
.SetMask(pMask
);
1165 ::GpiSetBitmap(hPSSrc
, NULL
);
1166 ::GpiSetBitmap(hPSDst
, NULL
);
1167 ::GpiDestroyPS(hPSSrc
);
1168 ::GpiDestroyPS(hPSDst
);
1169 ::DevCloseDC(hDCSrc
);
1170 ::DevCloseDC(hDCDst
);
1172 } // end of wxBitmap::GetSubBitmap
1174 // ----------------------------------------------------------------------------
1175 // wxBitmap accessors
1176 // ----------------------------------------------------------------------------
1178 void wxBitmap::SetQuality(
1184 GetBitmapData()->m_nQuality
= nQ
;
1185 } // end of wxBitmap::SetQuality
1187 void wxBitmap::SetPalette(
1188 const wxPalette
& rPalette
1193 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1194 } // end of wxBitmap::SetPalette
1196 void wxBitmap::SetMask(
1202 GetBitmapData()->m_pBitmapMask
= pMask
;
1203 } // end of wxBitmap::SetMask
1205 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const
1208 } // end of wxBitmap::GetBitmapForDC
1210 // ----------------------------------------------------------------------------
1212 // ----------------------------------------------------------------------------
1217 } // end of wxMask::wxMask
1219 // Construct a mask from a bitmap and a colour indicating
1220 // the transparent area
1222 const wxBitmap
& rBitmap
1223 , const wxColour
& rColour
1230 } // end of wxMask::wxMask
1232 // Construct a mask from a bitmap and a palette index indicating
1233 // the transparent area
1235 const wxBitmap
& rBitmap
1243 } // end of wxMask::wxMask
1245 // Construct a mask from a mono bitmap (copies the bitmap).
1247 const wxBitmap
& rBitmap
1252 } // end of wxMask::wxMask
1257 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1258 } // end of wxMask::~wxMask
1260 // Create a mask from a mono bitmap (copies the bitmap).
1261 bool wxMask::Create(
1262 const wxBitmap
& rBitmap
1265 BITMAPINFOHEADER2 vBmih
;
1266 SIZEL vSize
= {0, 0};
1267 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1268 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1269 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1270 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1271 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1272 POINTL vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()},
1273 {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}
1278 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1281 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1286 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1287 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1288 vBmih
.cx
= rBitmap
.GetWidth();
1289 vBmih
.cy
= rBitmap
.GetHeight();
1291 vBmih
.cBitCount
= 24;
1293 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1300 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1301 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1310 ::GpiDestroyPS(hPSSrc
);
1311 ::GpiDestroyPS(hPSDst
);
1312 ::DevCloseDC(hDCSrc
);
1313 ::DevCloseDC(hDCDst
);
1315 } // end of wxMask::Create
1317 // Create a mask from a bitmap and a palette index indicating
1318 // the transparent area
1319 bool wxMask::Create(
1320 const wxBitmap
& rBitmap
1326 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1329 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1332 unsigned char cGreen
;
1333 unsigned char cBlue
;
1335 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1341 wxColour
vTransparentColour( cRed
1346 return (Create( rBitmap
1352 } // end of wxMask::Create
1354 // Create a mask from a bitmap and a colour indicating
1355 // the transparent area
1356 bool wxMask::Create(
1357 const wxBitmap
& rBitmap
1358 , const wxColour
& rColour
1362 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1366 BITMAPINFOHEADER2 vBmih
;
1367 SIZEL vSize
= {0, 0};
1368 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1369 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1370 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1371 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1372 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1376 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1385 // Scan the bitmap for the transparent colour and set
1386 // the corresponding pixels in the mask to BLACK and
1387 // the rest to WHITE
1390 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1391 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1392 vBmih
.cx
= rBitmap
.GetWidth();
1393 vBmih
.cy
= rBitmap
.GetHeight();
1395 vBmih
.cBitCount
= 1;
1397 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1404 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1405 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1408 // This is not very efficient, but I can't think
1409 // of a better way of doing it
1411 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1413 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1415 POINTL vPt
= {w
, h
};
1416 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1417 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1420 // Doesn't make sense to continue
1426 if (vCol
== vMaskColour
)
1428 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1429 ::GpiSetPel(hPSDst
, &vPt
);
1433 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1434 ::GpiSetPel(hPSDst
, &vPt
);
1438 ::GpiSetBitmap(hPSSrc
, NULL
);
1439 ::GpiSetBitmap(hPSDst
, NULL
);
1440 ::GpiDestroyPS(hPSSrc
);
1441 ::GpiDestroyPS(hPSDst
);
1442 ::DevCloseDC(hDCSrc
);
1443 ::DevCloseDC(hDCDst
);
1445 } // end of wxMask::Create
1447 // ----------------------------------------------------------------------------
1449 // ----------------------------------------------------------------------------
1451 bool wxBitmapHandler::Create( wxGDIImage
* pImage
,
1453 long WXUNUSED(lFlags
),
1458 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1462 return(pBitmap
? Create( pBitmap
1470 bool wxBitmapHandler::Load(
1478 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1482 return(pBitmap
? LoadFile( pBitmap
1490 bool wxBitmapHandler::Save(
1492 , const wxString
& rName
1496 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1500 return(pBitmap
? SaveFile( pBitmap
1506 bool wxBitmapHandler::Create(
1507 wxBitmap
* WXUNUSED(pBitmap
)
1508 , void* WXUNUSED(pData
)
1509 , long WXUNUSED(lType
)
1510 , int WXUNUSED(nWidth
)
1511 , int WXUNUSED(nHeight
)
1512 , int WXUNUSED(nDepth
)
1518 bool wxBitmapHandler::LoadFile(
1519 wxBitmap
* WXUNUSED(pBitmap
)
1521 , long WXUNUSED(lType
)
1522 , int WXUNUSED(nDesiredWidth
)
1523 , int WXUNUSED(nDesiredHeight
)
1529 bool wxBitmapHandler::LoadFile(
1530 wxBitmap
* WXUNUSED(pBitmap
)
1531 , const wxString
& WXUNUSED(rName
)
1532 , long WXUNUSED(lType
)
1533 , int WXUNUSED(nDesiredWidth
)
1534 , int WXUNUSED(nDesiredHeight
)
1540 bool wxBitmapHandler::SaveFile(
1541 wxBitmap
* WXUNUSED(pBitmap
)
1542 , const wxString
& WXUNUSED(rName
)
1543 , int WXUNUSED(nType
)
1544 , const wxPalette
* WXUNUSED(pPalette
)
1550 // ----------------------------------------------------------------------------
1551 // Utility functions
1552 // ----------------------------------------------------------------------------
1553 HBITMAP
wxInvertMask(
1559 HBITMAP hBmpInvMask
= 0;
1561 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1564 // Get width/height from the bitmap if not given
1566 if (!nWidth
|| !nHeight
)
1568 BITMAPINFOHEADER2 vBmhdr
;
1570 ::GpiQueryBitmapInfoHeader( hBmpMask
1573 nWidth
= (int)vBmhdr
.cx
;
1574 nHeight
= (int)vBmhdr
.cy
;
1577 BITMAPINFOHEADER2 vBmih
;
1578 SIZEL vSize
= {0, 0};
1579 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1580 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1581 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1582 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1583 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1584 POINTL vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
},
1585 {0, 0}, {nWidth
, nHeight
}
1588 memset(&vBmih
, '\0', 16);
1593 vBmih
.cBitCount
= 24;
1595 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1602 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1603 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1613 ::GpiDestroyPS(hPSSrc
);
1614 ::GpiDestroyPS(hPSDst
);
1615 ::DevCloseDC(hDCSrc
);
1616 ::DevCloseDC(hDCDst
);
1619 } // end of WxWinGdi_InvertMask
1621 HBITMAP
wxFlipBmp( HBITMAP hBmp
, int nWidth
, int nHeight
)
1623 wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxFlipBmp") );
1626 // Get width/height from the bitmap if not given
1628 if (!nWidth
|| !nHeight
)
1630 BITMAPINFOHEADER2 vBmhdr
;
1633 ::GpiQueryBitmapInfoHeader( hBmp
,
1635 nWidth
= (int)vBmhdr
.cx
;
1636 nHeight
= (int)vBmhdr
.cy
;
1639 BITMAPINFOHEADER2 vBmih
;
1640 SIZEL vSize
= {0, 0};
1641 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1642 HDC hDCSrc
= ::DevOpenDC( vHabmain
,
1646 (PDEVOPENDATA
)&vDop
,
1648 HDC hDCDst
= ::DevOpenDC( vHabmain
,
1652 (PDEVOPENDATA
)&vDop
,
1654 HPS hPSSrc
= ::GpiCreatePS( vHabmain
,
1657 PU_PELS
| GPIA_ASSOC
);
1658 HPS hPSDst
= ::GpiCreatePS( vHabmain
,
1661 PU_PELS
| GPIA_ASSOC
);
1662 POINTL vPoint
[4] = { {0, nHeight
},
1665 {nWidth
, nHeight
} };
1667 memset(&vBmih
, '\0', 16);
1672 vBmih
.cBitCount
= 24;
1674 HBITMAP hInvBmp
= ::GpiCreateBitmap( hPSDst
,
1680 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
);
1681 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
);
1683 ::GpiBitBlt( hPSDst
,
1690 ::GpiDestroyPS(hPSSrc
);
1691 ::GpiDestroyPS(hPSDst
);
1692 ::DevCloseDC(hDCSrc
);
1693 ::DevCloseDC(hDCDst
);
1696 } // end of wxFlipBmp