1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
31 #include "wx/os2/private.h"
34 //#include "wx/msw/dib.h"
36 #include "wx/xpmdecod.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 wxBitmapRefData::wxBitmapRefData()
58 m_pSelectedInto
= NULL
;
61 m_hBitmap
= (WXHBITMAP
) NULL
;
62 } // end of wxBitmapRefData::wxBitmapRefData
64 void wxBitmapRefData::Free()
66 wxASSERT_MSG( !m_pSelectedInto
,
67 wxT("deleting bitmap still selected into wxMemoryDC") );
71 if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
))
73 wxLogLastError("GpiDeleteBitmap(hbitmap)");
79 } // end of wxBitmapRefData::Free
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 // this function should be called from all wxBitmap ctors
88 } // end of wxBitmap::Init
90 bool wxBitmap::CopyFromIconOrCursor(
91 const wxGDIImage
& rIcon
94 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
95 POINTERINFO SIconInfo
;
97 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
99 wxLogLastError(wxT("WinQueryPointerInfo"));
102 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
104 m_refData
= pRefData
;
106 int nWidth
= rIcon
.GetWidth();
107 int nHeight
= rIcon
.GetHeight();
109 pRefData
->m_nWidth
= nWidth
;
110 pRefData
->m_nHeight
= nHeight
;
111 pRefData
->m_nDepth
= wxDisplayDepth();
113 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
116 // No mask in the Info struct in OS/2
119 } // end of wxBitmap::CopyFromIconOrCursor
121 bool wxBitmap::CopyFromCursor(
122 const wxCursor
& rCursor
129 return(CopyFromIconOrCursor(rCursor
));
130 } // end of wxBitmap::CopyFromCursor
132 bool wxBitmap::CopyFromIcon(
141 return CopyFromIconOrCursor(rIcon
);
142 } // end of wxBitmap::CopyFromIcon
144 wxBitmap::~wxBitmap()
146 } // end of wxBitmap::~wxBitmap
157 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
158 BITMAPINFOHEADER2 vHeader
;
162 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
163 SIZEL vSize
= {0, 0};
166 wxASSERT(vHabmain
!= NULL
);
168 m_refData
= pRefData
;
170 pRefData
->m_nWidth
= nWidth
;
171 pRefData
->m_nHeight
= nHeight
;
172 pRefData
->m_nDepth
= nDepth
;
173 pRefData
->m_nNumColors
= 0;
174 pRefData
->m_pSelectedInto
= NULL
;
176 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
177 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
180 wxLogLastError("GpiCreatePS Failure");
186 // We assume that it is in XBM format which is not quite the same as
187 // the format CreateBitmap() wants because the order of bytes in the
190 const size_t nBytesPerLine
= (nWidth
+ 7) / 8;
191 const size_t nPadding
= nBytesPerLine
% 2;
192 const size_t nLen
= nHeight
* (nPadding
+ nBytesPerLine
);
193 const char* pzSrc
= zBits
;
197 pzData
= (char *)malloc(nLen
);
199 char* pzDst
= pzData
;
201 for (nRows
= 0; nRows
< nHeight
; nRows
++)
203 for (nCols
= 0; nCols
< nBytesPerLine
; nCols
++)
205 unsigned char ucVal
= *pzSrc
++;
206 unsigned char ucReversed
= 0;
209 for (nBits
= 0; nBits
< 8; nBits
++)
212 ucReversed
|= (ucVal
& 0x01);
215 *pzDst
++ = ucReversed
;
224 // Bits should already be in Windows standard format
226 pzData
= (char *)zBits
; // const_cast is harmless
229 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
230 vHeader
.cbFix
= sizeof(vHeader
);
231 vHeader
.cx
= (USHORT
)nWidth
;
232 vHeader
.cy
= (USHORT
)nHeight
;
233 vHeader
.cPlanes
= 1L;
234 vHeader
.cBitCount
= nDepth
;
235 vHeader
.usReserved
= 0;
236 vHeader
.ulCompression
= BCA_UNCOMP
;
237 vHeader
.usRecording
= BRA_BOTTOMUP
;
238 vHeader
.usRendering
= BRH_NOTHALFTONED
;
239 vHeader
.ulColorEncoding
= BCE_RGB
;
240 vHeader
.ulIdentifier
= 0;
242 memset(&vInfo
, '\0', sizeof(BITMAPINFO2
));
243 vInfo
.cbFix
= sizeof(vInfo
);
244 vInfo
.cx
= (USHORT
)nWidth
;
245 vInfo
.cy
= (USHORT
)nHeight
;
247 vInfo
.cBitCount
= nDepth
;
248 vInfo
.usReserved
= 0;
249 vInfo
.ulCompression
= BCA_UNCOMP
;
250 vInfo
.usRecording
= BRA_BOTTOMUP
;
251 vInfo
.usRendering
= BRH_NOTHALFTONED
;
252 vInfo
.ulColorEncoding
= BCE_RGB
;
253 vInfo
.ulIdentifier
= 0;
255 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
);
259 wxLogLastError("CreateBitmap");
262 SetHBITMAP((WXHBITMAP
)hBmp
);
263 } // end of wxBitmap::wxBitmap
277 } // end of wxBitmap::wxBitmap
295 } // end of wxBitmap::wxBitmap
298 const wxString
& rFilename
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
;
327 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
328 SIZEL vSize
= {0, 0};
329 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
330 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
332 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
333 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
337 vHeader
.cBitCount
= nD
;
339 hBmp
= ::GpiCreateBitmap( hPS
354 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
355 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
356 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
358 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
359 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
363 vHeader
.cBitCount
= lBitCount
;
365 hBmp
= ::GpiCreateBitmap( hPSScreen
372 GetBitmapData()->m_nDepth
= wxDisplayDepth();
373 ::WinReleasePS(hPSScreen
);
375 SetHBITMAP((WXHBITMAP
)hBmp
);
377 #if WXWIN_COMPATIBILITY_2
378 GetBitmapData()->m_bOk
= hBmp
!= 0;
379 #endif // WXWIN_COMPATIBILITY_2
382 } // end of wxBitmap::Create
384 bool wxBitmap::CreateFromXpm(
388 #if wxUSE_IMAGE && wxUSE_XPM
391 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
393 wxXPMDecoder vDecoder
;
394 wxImage vImg
= vDecoder
.ReadData(ppData
);
396 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
398 *this = wxBitmap(vImg
);
403 } // end of wxBitmap::CreateFromXpm
405 bool wxBitmap::LoadFile(
406 const wxString
& rFilename
410 HPS hPs
= NULLHANDLE
;
414 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
420 m_refData
= new wxBitmapRefData
;
422 return(pHandler
->LoadFile( this
434 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
437 *this = wxBitmap(vImage
);
441 } // end of wxBitmap::LoadFile
443 bool wxBitmap::Create(
453 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
459 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
460 "type %d defined."), lType
);
465 m_refData
= new wxBitmapRefData
;
467 return(pHandler
->Create( this
474 } // end of wxBitmap::Create
476 bool wxBitmap::SaveFile(
477 const wxString
& rFilename
479 , const wxPalette
* pPalette
482 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
488 return pHandler
->SaveFile( this
496 // FIXME what about palette? shouldn't we use it?
497 wxImage vImage
= ConvertToImage();
502 return(vImage
.SaveFile( rFilename
506 } // end of wxBitmap::SaveFile
509 // ----------------------------------------------------------------------------
510 // wxImage-wxBitmap convertion
511 // ----------------------------------------------------------------------------
513 bool wxBitmap::CreateFromImage (
514 const wxImage
& rImage
518 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
519 m_refData
= new wxBitmapRefData();
521 int nSizeLimit
= 1024 * 768 * 3;
522 int nWidth
= rImage
.GetWidth();
523 int nBmpHeight
= rImage
.GetHeight();
524 int nBytePerLine
= nWidth
* 3;
525 int nSizeDWORD
= sizeof(DWORD
);
526 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
529 if (nLineBoundary
> 0)
531 nPadding
= nSizeDWORD
- nLineBoundary
;
532 nBytePerLine
+= nPadding
;
536 // Calc the number of DIBs and heights of DIBs
540 int nHeight
= nSizeLimit
/ nBytePerLine
;
542 if (nHeight
>= nBmpHeight
)
543 nHeight
= nBmpHeight
;
546 nNumDIB
= nBmpHeight
/ nHeight
;
547 nHRemain
= nBmpHeight
% nHeight
;
553 // Set bitmap parameters
555 wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image"));
557 SetHeight(nBmpHeight
);
559 nDepth
= wxDisplayDepth();
564 // Copy the palette from the source image
566 SetPalette(rImage
.GetPalette());
567 #endif // wxUSE_PALETTE
570 // Create a DIB header
572 BITMAPINFOHEADER2 vHeader
;
575 // Fill in the DIB header
577 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
578 vHeader
.cbFix
= sizeof(vHeader
);
579 vHeader
.cx
= (USHORT
)nWidth
;
580 vHeader
.cy
= (USHORT
)nHeight
;
581 vHeader
.cPlanes
= 1L;
582 vHeader
.cBitCount
= 24;
583 vHeader
.ulCompression
= BCA_UNCOMP
;
584 vHeader
.cbImage
= nBytePerLine
* nHeight
;
585 vHeader
.cclrUsed
= 0;
588 // These seem not really needed for our purpose here.
590 vHeader
.cxResolution
= 0;
591 vHeader
.cyResolution
= 0;
592 vHeader
.cclrImportant
= 0;
593 vHeader
.usUnits
= BRU_METRIC
;
594 vHeader
.usReserved
= 0;
597 vHeader
.usRecording
= BRA_BOTTOMUP
;
598 vHeader
.usRendering
= BRH_NOTHALFTONED
;
599 vHeader
.ulColorEncoding
= BCE_RGB
;
600 vHeader
.ulIdentifier
= 0;
603 // Memory for DIB data
605 unsigned char* pucBits
;
607 pucBits
= (unsigned char *)malloc(vHeader
.cbImage
);
610 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
615 // Create and set the device-dependent bitmap
617 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
618 SIZEL vSize
= {0, 0};
619 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
620 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
624 hBmp
= ::GpiCreateBitmap( hPS
630 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
632 HPAL hOldPalette
= NULLHANDLE
;
633 if (rImage
.GetPalette().Ok())
635 hOldPalette
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE());
637 #endif // wxUSE_PALETTE
640 // Copy image data into DIB data and then into DDB (in a loop)
642 unsigned char* pData
= rImage
.GetData();
647 unsigned char* ptdata
= pData
;
648 unsigned char* ptbits
;
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
679 POINTL vPoint
[4] = { 0, nOrigin
,
681 0, 0, nWidth
, nHeight
693 SetHBITMAP((WXHBITMAP
)hBmp
);
696 ::GpiSelectPalette(hPS
, hOldPalette
);
697 #endif // wxUSE_PALETTE
700 // Similarly, created an mono-bitmap for the possible mask
702 if (rImage
.HasMask())
704 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
705 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
707 vHeader
.cy
= nHeight
;
709 vHeader
.cBitCount
= 1;
710 hBmp
= ::GpiCreateBitmap( hPS
716 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
718 nHeight
= nBmpHeight
;
720 nHeight
= nSizeLimit
/ nBytePerLine
;
721 vHeader
.cy
= (DWORD
)(nHeight
);
722 vHeader
.cbImage
= nBytePerLine
* nHeight
;
725 unsigned char cRed
= rImage
.GetMaskRed();
726 unsigned char cGreen
= rImage
.GetMaskGreen();
727 unsigned char cBlue
= rImage
.GetMaskBlue();
728 unsigned char cZero
= 0;
729 unsigned char cOne
= 255;
732 for (n
= 0; n
< nNumDIB
; n
++)
734 if (nNumDIB
> 1 && n
== nNumDIB
- 1 && nHRemain
> 0)
737 // Redefine height and size of the (possibly) last smaller DIB
738 // memory is not reallocated
741 vHeader
.cy
= (DWORD
)(nHeight
);
742 vHeader
.cbImage
= nBytePerLine
* nHeight
;
745 for (int j
= 0; j
< nHeight
; j
++)
747 for (i
= 0; i
< nWidth
; i
++)
749 if ((*(ptdata
++) != cRed
) || (*(ptdata
++) != cGreen
) || (*(ptdata
++) != cBlue
))
762 for (i
= 0; i
< nPadding
; i
++)
765 POINTL vPoint
[4] = { 0, nOrigin
,
767 0, 0, nWidth
, nHeight
781 // Create a wxMask object
783 wxMask
* pMask
= new wxMask();
785 pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
);
787 hBmpOld
= ::GpiSetBitmap(hPS
, hBmp
);
791 // Free allocated resources
793 ::GpiSetBitmap(hPS
, NULLHANDLE
);
798 } // end of wxBitmap::CreateFromImage
800 wxImage
wxBitmap::ConvertToImage() const
804 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
807 // Create an wxImage object
809 int nWidth
= GetWidth();
810 int nHeight
= GetHeight();
813 int nBytePerLine
= nWidth
* 3;
814 int nSizeDWORD
= sizeof(DWORD
);
815 int nLineBoundary
= nBytePerLine
% nSizeDWORD
;
817 unsigned char* pData
;
818 unsigned char* lpBits
;
820 BITMAPINFOHEADER2 vDIBh
;
821 BITMAPINFO2 vDIBInfo
;
823 PSZ pszData
[4] = { "Display", NULL
, NULL
, NULL
};
826 SIZEL vSizlPage
= {0,0};
829 vImage
.Create( nWidth
832 pData
= vImage
.GetData();
835 wxFAIL_MSG( wxT("could not allocate data for image") );
838 if(nLineBoundary
> 0)
840 nPadding
= nSizeDWORD
- nLineBoundary
;
841 nBytePerLine
+= nPadding
;
843 wxDisplaySize( &nDevWidth
847 // Create and fill a DIB header
849 memset(&vDIBh
, '\0', sizeof(BITMAPINFOHEADER2
));
850 vDIBh
.cbFix
= sizeof(BITMAPINFOHEADER2
);
854 vDIBh
.cbImage
= nBytePerLine
* nHeight
;
855 vDIBh
.cBitCount
= 24;
857 memset(&vDIBInfo
, '\0', sizeof(BITMAPINFO2
));
858 vDIBInfo
.cbFix
= sizeof(BITMAPINFO2
);
859 vDIBInfo
.cPlanes
= 1;
860 vDIBInfo
.cBitCount
= 24;
861 vDIBInfo
.ulCompression
= BCA_UNCOMP
;
862 vDIBInfo
.usReserved
= 0;
863 vDIBInfo
.usRecording
= BRA_BOTTOMUP
;
864 vDIBInfo
.usRendering
= BRH_NOTHALFTONED
;
865 vDIBInfo
.ulColorEncoding
= BCE_RGB
;
866 vDIBInfo
.ulIdentifier
= 0;
868 lpBits
= (unsigned char *)malloc(vDIBh
.cbImage
);
871 wxFAIL_MSG(wxT("could not allocate data for DIB"));
877 // Copy data from the device-dependent bitmap to the DIB
879 hDCMem
= ::DevOpenDC( vHabmain
883 ,(PDEVOPENDATA
)pszData
886 hPSMem
= ::GpiCreatePS( vHabmain
889 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
891 hBitmap
= ::GpiCreateBitmap( hPSMem
897 lScans
= ::GpiQueryBitmapBits( hPSMem
905 // Copy DIB data into the wxImage object
909 unsigned char* ptdata
= pData
;
910 unsigned char* ptbits
= lpBits
;
912 for (i
= 0; i
< nHeight
; i
++)
914 for (j
= 0; j
< nWidth
; j
++)
916 *(ptdata
++) = *(ptbits
+2);
917 *(ptdata
++) = *(ptbits
+1);
918 *(ptdata
++) = *(ptbits
);
925 // Similarly, set data according to the possible mask bitmap
927 if (GetMask() && GetMask()->GetMaskBitmap())
929 hBitmap
= (HBITMAP
)GetMask()->GetMaskBitmap();
932 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
934 HDC hMemDC
= ::DevOpenDC( vHabmain
938 ,(PDEVOPENDATA
)pszData
941 HPS hMemPS
= ::GpiCreatePS( vHabmain
944 ,PU_PELS
| GPIA_ASSOC
| GPIT_MICRO
946 ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0));
947 ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) );
948 ::GpiQueryBitmapBits( hPSMem
954 ::GpiDestroyPS(hMemPS
);
955 ::DevCloseDC(hMemDC
);
958 // Background color set to RGB(16,16,16) in consistent with wxGTK
960 unsigned char ucRed
= 16;
961 unsigned char ucGreen
= 16;
962 unsigned char ucBlue
= 16;
966 for (i
= 0; i
< nHeight
; i
++)
968 for (j
= 0; j
< nWidth
; j
++)
975 *(ptdata
++) = ucGreen
;
976 *(ptdata
++) = ucBlue
;
982 vImage
.SetMaskColour( ucRed
986 vImage
.SetMask(TRUE
);
990 vImage
.SetMask(FALSE
);
994 // Free allocated resources
996 ::GpiDestroyPS(hPSMem
);
997 ::DevCloseDC(hDCMem
);
1000 } // end of wxBitmap::ConvertToImage
1002 // ----------------------------------------------------------------------------
1003 // sub bitmap extraction
1004 // ----------------------------------------------------------------------------
1006 wxBitmap
wxBitmap::GetSubBitmap(
1010 wxCHECK_MSG( Ok() &&
1011 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
1012 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
1013 (rRect
.y
+ rRect
.height
<= GetHeight()),
1014 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
1016 wxBitmap
vRet( rRect
.width
1020 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
1026 SIZEL vSize
= {0, 0};
1027 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1028 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1029 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1030 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1031 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1032 POINTL vPoint
[4] = { rRect
.x
, rRect
.y
,
1033 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
,
1034 0, 0, GetWidth(), GetHeight()
1037 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1038 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1048 // Copy mask if there is one
1052 BITMAPINFOHEADER2 vBmih
;
1054 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1055 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1056 vBmih
.cx
= rRect
.width
;
1057 vBmih
.cy
= rRect
.height
;
1059 vBmih
.cBitCount
= 1;
1061 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
1068 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
1069 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
1071 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
1072 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
1081 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
1082 vRet
.SetMask(pMask
);
1085 ::GpiSetBitmap(hPSSrc
, NULL
);
1086 ::GpiSetBitmap(hPSDst
, NULL
);
1087 ::GpiDestroyPS(hPSSrc
);
1088 ::GpiDestroyPS(hPSDst
);
1089 ::DevCloseDC(hDCSrc
);
1090 ::DevCloseDC(hDCDst
);
1092 } // end of wxBitmap::GetSubBitmap
1094 // ----------------------------------------------------------------------------
1095 // wxBitmap accessors
1096 // ----------------------------------------------------------------------------
1098 void wxBitmap::SetQuality(
1104 GetBitmapData()->m_nQuality
= nQ
;
1105 } // end of wxBitmap::SetQuality
1107 #if WXWIN_COMPATIBILITY_2
1108 void wxBitmap::SetOk(
1114 GetBitmapData()->m_bOk
= bOk
;
1115 } // end of wxBitmap::SetOk
1116 #endif // WXWIN_COMPATIBILITY_2
1118 void wxBitmap::SetPalette(
1119 const wxPalette
& rPalette
1124 GetBitmapData()->m_vBitmapPalette
= rPalette
;
1125 } // end of wxBitmap::SetPalette
1127 void wxBitmap::SetMask(
1133 GetBitmapData()->m_pBitmapMask
= pMask
;
1134 } // end of wxBitmap::SetMask
1136 wxBitmap
wxBitmap::GetBitmapForDC(
1141 } // end of wxBitmap::GetBitmapForDC
1143 // ----------------------------------------------------------------------------
1145 // ----------------------------------------------------------------------------
1150 } // end of wxMask::wxMask
1152 // Construct a mask from a bitmap and a colour indicating
1153 // the transparent area
1155 const wxBitmap
& rBitmap
1156 , const wxColour
& rColour
1163 } // end of wxMask::wxMask
1165 // Construct a mask from a bitmap and a palette index indicating
1166 // the transparent area
1168 const wxBitmap
& rBitmap
1176 } // end of wxMask::wxMask
1178 // Construct a mask from a mono bitmap (copies the bitmap).
1180 const wxBitmap
& rBitmap
1185 } // end of wxMask::wxMask
1190 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1191 } // end of wxMask::~wxMask
1193 // Create a mask from a mono bitmap (copies the bitmap).
1194 bool wxMask::Create(
1195 const wxBitmap
& rBitmap
1198 BITMAPINFOHEADER2 vBmih
;
1199 SIZEL vSize
= {0, 0};
1200 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1201 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1202 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1203 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1204 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1205 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1206 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1211 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1214 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1219 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1220 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1221 vBmih
.cx
= rBitmap
.GetWidth();
1222 vBmih
.cy
= rBitmap
.GetHeight();
1224 vBmih
.cBitCount
= 1;
1226 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1233 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1234 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1243 ::GpiDestroyPS(hPSSrc
);
1244 ::GpiDestroyPS(hPSDst
);
1245 ::DevCloseDC(hDCSrc
);
1246 ::DevCloseDC(hDCDst
);
1248 } // end of wxMask::Create
1250 // Create a mask from a bitmap and a palette index indicating
1251 // the transparent area
1252 bool wxMask::Create(
1253 const wxBitmap
& rBitmap
1259 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1262 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1265 unsigned char cGreen
;
1266 unsigned char cBlue
;
1268 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1274 wxColour
vTransparentColour( cRed
1279 return (Create( rBitmap
1285 } // end of wxMask::Create
1287 // Create a mask from a bitmap and a colour indicating
1288 // the transparent area
1289 bool wxMask::Create(
1290 const wxBitmap
& rBitmap
1291 , const wxColour
& rColour
1295 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1299 BITMAPINFOHEADER2 vBmih
;
1300 SIZEL vSize
= {0, 0};
1301 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1302 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1303 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1304 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1305 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1306 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1307 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1312 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1321 // Scan the bitmap for the transparent colour and set
1322 // the corresponding pixels in the mask to BLACK and
1323 // the rest to WHITE
1326 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1327 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1328 vBmih
.cx
= rBitmap
.GetWidth();
1329 vBmih
.cy
= rBitmap
.GetHeight();
1331 vBmih
.cBitCount
= 1;
1333 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1340 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1341 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1344 // This is not very efficient, but I can't think
1345 // of a better way of doing it
1347 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1349 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1351 POINTL vPt
= {w
, h
};
1352 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1353 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1356 // Doesn't make sense to continue
1362 if (vCol
== vMaskColour
)
1364 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1365 ::GpiSetPel(hPSDst
, &vPt
);
1369 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1370 ::GpiSetPel(hPSDst
, &vPt
);
1374 ::GpiSetBitmap(hPSSrc
, NULL
);
1375 ::GpiSetBitmap(hPSDst
, NULL
);
1376 ::GpiDestroyPS(hPSSrc
);
1377 ::GpiDestroyPS(hPSDst
);
1378 ::DevCloseDC(hDCSrc
);
1379 ::DevCloseDC(hDCDst
);
1381 } // end of wxMask::Create
1383 // ----------------------------------------------------------------------------
1385 // ----------------------------------------------------------------------------
1387 bool wxBitmapHandler::Create(
1396 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1400 return(pBitmap
? Create( pBitmap
1408 bool wxBitmapHandler::Load(
1410 , const wxString
& rName
1417 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1421 return(pBitmap
? LoadFile( pBitmap
1430 bool wxBitmapHandler::Save(
1432 , const wxString
& rName
1436 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1440 return(pBitmap
? SaveFile( pBitmap
1446 bool wxBitmapHandler::Create(
1447 wxBitmap
* WXUNUSED(pBitmap
)
1448 , void* WXUNUSED(pData
)
1449 , long WXUNUSED(lType
)
1450 , int WXUNUSED(nWidth
)
1451 , int WXUNUSED(nHeight
)
1452 , int WXUNUSED(nDepth
)
1458 bool wxBitmapHandler::LoadFile(
1459 wxBitmap
* WXUNUSED(pBitmap
)
1460 , const wxString
& WXUNUSED(rName
)
1462 , long WXUNUSED(lType
)
1463 , int WXUNUSED(nDesiredWidth
)
1464 , int WXUNUSED(nDesiredHeight
)
1470 bool wxBitmapHandler::SaveFile(
1471 wxBitmap
* WXUNUSED(pBitmap
)
1472 , const wxString
& WXUNUSED(rName
)
1473 , int WXUNUSED(nType
)
1474 , const wxPalette
* WXUNUSED(pPalette
)
1480 // ----------------------------------------------------------------------------
1481 // Utility functions
1482 // ----------------------------------------------------------------------------
1483 HBITMAP
wxInvertMask(
1489 HBITMAP hBmpInvMask
= 0;
1491 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1494 // Get width/height from the bitmap if not given
1496 if (!nWidth
|| !nHeight
)
1498 BITMAPINFOHEADER2 vBmhdr
;
1500 ::GpiQueryBitmapInfoHeader( hBmpMask
1503 nWidth
= (int)vBmhdr
.cx
;
1504 nHeight
= (int)vBmhdr
.cy
;
1507 BITMAPINFOHEADER2 vBmih
;
1508 SIZEL vSize
= {0, 0};
1509 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1510 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1511 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1512 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1513 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1514 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1515 0, 0, nWidth
, nHeight
1518 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1519 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1523 vBmih
.cBitCount
= 1;
1525 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1532 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1533 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1543 ::GpiDestroyPS(hPSSrc
);
1544 ::GpiDestroyPS(hPSDst
);
1545 ::DevCloseDC(hDCSrc
);
1546 ::DevCloseDC(hDCDst
);
1549 } // end of WxWinGdi_InvertMask