1 /////////////////////////////////////////////////////////////////////////////
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"
30 //#include "wx/msw/dib.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 #if !USE_SHARED_LIBRARIES
38 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
39 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
44 // ============================================================================
46 // ============================================================================
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 wxBitmapRefData::wxBitmapRefData()
55 m_pSelectedInto
= NULL
;
60 void wxBitmapRefData::Free()
62 wxASSERT_MSG( !m_pSelectedInto
,
63 wxT("deleting bitmap still selected into wxMemoryDC") );
67 if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) )
69 wxLogLastError("GpiDeleteBitmap(hbitmap)");
77 // ----------------------------------------------------------------------------
79 // ----------------------------------------------------------------------------
81 // this function should be called from all wxBitmap ctors
84 // m_refData = NULL; done in the base class ctor
87 wxTheBitmapList
->AddBitmap(this);
90 bool wxBitmap::CopyFromIconOrCursor(
91 const wxGDIImage
& rIcon
94 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
98 pRefData
->m_nWidth
= rIcon
.GetWidth();
99 pRefData
->m_nHeight
= rIcon
.GetHeight();
100 pRefData
->m_nDepth
= wxDisplayDepth();
102 pRefData
->m_hBitmap
= (WXHBITMAP
)rIcon
.GetHandle();
104 pRefData
->m_pBitmapMask
= new wxMask();
106 #if WXWIN_COMPATIBILITY_2
107 pRefData
->m_bOk
= TRUE
;
108 #endif // WXWIN_COMPATIBILITY_2
112 bool wxBitmap::CopyFromCursor(
113 const wxCursor
& rCursor
120 return(CopyFromIconOrCursor(rCursor
));
123 bool wxBitmap::CopyFromIcon(
132 #if WXWIN_COMPATIBILITY_2
133 refData
->m_ok
= TRUE
;
134 #endif // WXWIN_COMPATIBILITY_2
136 return CopyFromIconOrCursor(rIcon
);
139 wxBitmap::~wxBitmap()
142 wxTheBitmapList
->DeleteObject(this);
154 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
155 BITMAPINFOHEADER2 vHeader
;
159 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
160 SIZEL vSize
= {0, 0};
162 wxASSERT(vHabmain
!= NULL
);
164 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
166 vHeader
.cbFix
= sizeof(vHeader
);
167 vHeader
.cx
= (USHORT
)nTheWidth
;
168 vHeader
.cy
= (USHORT
)nTheHeight
;
169 vHeader
.cPlanes
= 1L;
170 vHeader
.cBitCount
= nNoBits
;
171 vHeader
.ulCompression
= BCA_UNCOMP
;
172 vHeader
.cxResolution
= 0;
173 vHeader
.cyResolution
= 0;
174 vHeader
.cclrUsed
= 0;
175 vHeader
.cclrImportant
= 0;
176 vHeader
.usUnits
= BRU_METRIC
;
177 vHeader
.usRecording
= BRA_BOTTOMUP
;
178 vHeader
.usRendering
= BRH_NOTHALFTONED
;
181 vHeader
.ulColorEncoding
= 0;
182 vHeader
.ulIdentifier
= 0;
184 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
187 wxLogLastError("GpiCreatePS Failure");
193 m_refData
= pRefData
;
195 pRefData
->m_nWidth
= nTheWidth
;
196 pRefData
->m_nHeight
= nTheHeight
;
197 pRefData
->m_nDepth
= nNoBits
;
198 pRefData
->m_nNumColors
= 0;
199 pRefData
->m_pSelectedInto
= NULL
;
201 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
204 wxLogLastError("CreateBitmap");
206 SetHBITMAP((WXHBITMAP
)hBmp
);
209 // Create from XPM data
212 , wxControl
* WXUNUSED(pAnItem
))
216 (void)Create( (void *)ppData
217 ,wxBITMAP_TYPE_XPM_DATA
257 const wxString
& rFilename
268 bool wxBitmap::Create(
275 BITMAPINFOHEADER2 vHeader
;
279 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
280 SIZEL vSize
= {0, 0};
283 wxASSERT(vHabmain
!= NULL
);
285 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
286 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
287 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
289 vHeader
.cbFix
= sizeof(vHeader
);
290 vHeader
.cx
= (USHORT
)nW
;
291 vHeader
.cy
= (USHORT
)nH
;
292 vHeader
.cPlanes
= (USHORT
)nD
;
293 vHeader
.cBitCount
= lBitCount
;
294 vHeader
.ulCompression
= BCA_UNCOMP
;
295 vHeader
.cxResolution
= 0;
296 vHeader
.cyResolution
= 0;
297 vHeader
.cclrUsed
= 0;
298 vHeader
.cclrImportant
= 0;
299 vHeader
.usUnits
= BRU_METRIC
;
300 vHeader
.usRecording
= BRA_BOTTOMUP
;
301 vHeader
.usRendering
= BRH_NOTHALFTONED
;
304 vHeader
.ulColorEncoding
= 0;
305 vHeader
.ulIdentifier
= 0;
308 m_refData
= new wxBitmapRefData
;
310 GetBitmapData()->m_nWidth
= nW
;
311 GetBitmapData()->m_nHeight
= nH
;
312 GetBitmapData()->m_nDepth
= nD
;
316 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
319 wxLogLastError("CreateBitmap");
326 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
327 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
330 wxLogLastError("CreateBitmap");
332 GetBitmapData()->m_nDepth
= wxDisplayDepth();
334 SetHBITMAP((WXHBITMAP
)hBmp
);
336 #if WXWIN_COMPATIBILITY_2
337 GetBitmapData()->m_bOk
= hBmp
!= 0;
338 #endif // WXWIN_COMPATIBILITY_2
343 bool wxBitmap::LoadFile(
344 const wxString
& rFilename
350 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
356 m_refData
= new wxBitmapRefData
;
358 return(pHandler
->LoadFile( this
369 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
372 *this = vImage
.ConvertToBitmap();
378 bool wxBitmap::Create(
388 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
394 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
395 "type %d defined."), lType
);
400 m_refData
= new wxBitmapRefData
;
402 return(pHandler
->Create( this
411 bool wxBitmap::SaveFile(
412 const wxString
& rFilename
414 , const wxPalette
* pPalette
417 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
423 return pHandler
->SaveFile( this
431 // FIXME what about palette? shouldn't we use it?
432 wxImage
vImage(*this);
437 return(vImage
.SaveFile( rFilename
443 // ----------------------------------------------------------------------------
444 // wxBitmap accessors
445 // ----------------------------------------------------------------------------
447 void wxBitmap::SetQuality(
453 GetBitmapData()->m_nQuality
= nQ
;
456 #if WXWIN_COMPATIBILITY_2
457 void wxBitmap::SetOk(
463 GetBitmapData()->m_bOk
= bOk
;
465 #endif // WXWIN_COMPATIBILITY_2
467 void wxBitmap::SetPalette(
468 const wxPalette
& rPalette
473 GetBitmapData()->m_vBitmapPalette
= rPalette
;
476 void wxBitmap::SetMask(
482 GetBitmapData()->m_pBitmapMask
= pMask
;
485 // Will try something for OS/2 but not really sure how close
486 // to the msw intent this is.
487 wxBitmap
wxBitmap::GetBitmapForDC(
492 wxBitmap
vTmpBitmap( this->GetWidth()
496 WXHBITMAP vOldBitmap
;
502 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
503 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
505 // TODO: Set the points
507 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
508 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
513 // ----------------------------------------------------------------------------
515 // ----------------------------------------------------------------------------
522 // Construct a mask from a bitmap and a colour indicating
523 // the transparent area
525 const wxBitmap
& rBitmap
526 , const wxColour
& rColour
535 // Construct a mask from a bitmap and a palette index indicating
536 // the transparent area
538 const wxBitmap
& rBitmap
548 // Construct a mask from a mono bitmap (copies the bitmap).
550 const wxBitmap
& rBitmap
560 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
563 // Create a mask from a mono bitmap (copies the bitmap).
565 const wxBitmap
& rBitmap
568 BITMAPINFOHEADER2 vHeader
;
569 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
570 SIZEL vSize
= {0, 0};
575 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
578 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
582 vHeader
.cbFix
= sizeof(vHeader
);
583 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
584 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
586 vHeader
.cBitCount
= 1;
588 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
595 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
596 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
597 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
598 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
599 // TODO: Set the point array
600 ::GpiBitBlt(destPS
, srcPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
602 ::GpiDestroyPS(srcPS
);
603 ::GpiDestroyPS(destPS
);
607 // Create a mask from a bitmap and a palette index indicating
608 // the transparent area
610 const wxBitmap
& rBitmap
616 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
619 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
622 unsigned char cGreen
;
625 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
631 wxColour
vTransparentColour( cRed
636 return (Create( rBitmap
644 // Create a mask from a bitmap and a colour indicating
645 // the transparent area
647 const wxBitmap
& rBitmap
648 , const wxColour
& rColour
651 BITMAPINFOHEADER2 vHeader
;
652 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
653 SIZEL vSize
= {0, 0};
658 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
666 // scan the bitmap for the transparent colour and set
667 // the corresponding pixels in the mask to BLACK and
669 COLORREF vMaskColour
= OS2RGB(rColour
.Red(), rColour
.Green(), rColour
.Blue());
671 vHeader
.cbFix
= sizeof(vHeader
);
672 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
673 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
675 vHeader
.cBitCount
= 1;
677 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
684 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
685 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
686 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
687 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
689 // this is not very efficient, but I can't think
690 // of a better way of doing it
691 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
693 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
700 COLORREF col
= ::GpiQueryPel(srcPS
, &vPoint
);
702 if (col
== vMaskColour
)
704 ::GpiSetColor(destPS
, CLR_WHITE
);
705 ::GpiSetPel(destPS
, &vPoint
);
709 ::GpiSetColor(destPS
, CLR_BLACK
);
710 ::GpiSetPel(destPS
, &vPoint
);
714 ::GpiDestroyPS(srcPS
);
715 ::GpiDestroyPS(destPS
);
719 // ----------------------------------------------------------------------------
721 // ----------------------------------------------------------------------------
723 bool wxBitmapHandler::Create(
732 wxBitmap
* pBitmap
= wxDynamicCast( pImage
736 return(pBitmap
? Create( pBitmap
744 bool wxBitmapHandler::Load(
746 , const wxString
& rName
752 wxBitmap
* pBitmap
= wxDynamicCast( pImage
756 return(pBitmap
? LoadFile( pBitmap
764 bool wxBitmapHandler::Save(
766 , const wxString
& rName
770 wxBitmap
* pBitmap
= wxDynamicCast( pImage
774 return(pBitmap
? SaveFile( pBitmap
780 bool wxBitmapHandler::Create(
781 wxBitmap
* WXUNUSED(pBitmap
)
782 , void* WXUNUSED(pData
)
783 , long WXUNUSED(lType
)
784 , int WXUNUSED(nWidth
)
785 , int WXUNUSED(nHeight
)
786 , int WXUNUSED(nDepth
)
792 bool wxBitmapHandler::LoadFile(
793 wxBitmap
* WXUNUSED(pBitmap
)
794 , const wxString
& WXUNUSED(rName
)
795 , long WXUNUSED(lType
)
796 , int WXUNUSED(nDesiredWidth
)
797 , int WXUNUSED(nDesiredHeight
)
803 bool wxBitmapHandler::SaveFile(
804 wxBitmap
* WXUNUSED(pBitmap
)
805 , const wxString
& WXUNUSED(rName
)
806 , int WXUNUSED(nType
)
807 , const wxPalette
* WXUNUSED(pPalette
)