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 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
;
58 void wxBitmapRefData::Free()
60 wxASSERT_MSG( !m_pSelectedInto
,
61 wxT("deleting bitmap still selected into wxMemoryDC") );
65 if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) )
67 wxLogLastError("GpiDeleteBitmap(hbitmap)");
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 // this function should be called from all wxBitmap ctors
82 // m_refData = NULL; done in the base class ctor
85 wxTheBitmapList
->AddBitmap(this);
88 bool wxBitmap::CopyFromIconOrCursor(
89 const wxGDIImage
& rIcon
92 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
96 pRefData
->m_nWidth
= rIcon
.GetWidth();
97 pRefData
->m_nHeight
= rIcon
.GetHeight();
98 pRefData
->m_nDepth
= wxDisplayDepth();
100 pRefData
->m_hBitmap
= (WXHBITMAP
)rIcon
.GetHandle();
102 pRefData
->m_pBitmapMask
= new wxMask();
104 #if WXWIN_COMPATIBILITY_2
105 pRefData
->m_bOk
= TRUE
;
106 #endif // WXWIN_COMPATIBILITY_2
110 bool wxBitmap::CopyFromCursor(
111 const wxCursor
& rCursor
118 return(CopyFromIconOrCursor(rCursor
));
121 bool wxBitmap::CopyFromIcon(
130 #if WXWIN_COMPATIBILITY_2
131 refData
->m_ok
= TRUE
;
132 #endif // WXWIN_COMPATIBILITY_2
134 return CopyFromIconOrCursor(rIcon
);
137 wxBitmap::~wxBitmap()
140 wxTheBitmapList
->DeleteObject(this);
152 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
153 BITMAPINFOHEADER2 vHeader
;
157 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
158 SIZEL vSize
= {0, 0};
160 wxASSERT(vHabmain
!= NULL
);
162 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
164 vHeader
.cbFix
= sizeof(vHeader
);
165 vHeader
.cx
= (USHORT
)nTheWidth
;
166 vHeader
.cy
= (USHORT
)nTheHeight
;
167 vHeader
.cPlanes
= 1L;
168 vHeader
.cBitCount
= nNoBits
;
169 vHeader
.ulCompression
= BCA_UNCOMP
;
170 vHeader
.cxResolution
= 0;
171 vHeader
.cyResolution
= 0;
172 vHeader
.cclrUsed
= 0;
173 vHeader
.cclrImportant
= 0;
174 vHeader
.usUnits
= BRU_METRIC
;
175 vHeader
.usRecording
= BRA_BOTTOMUP
;
176 vHeader
.usRendering
= BRH_NOTHALFTONED
;
179 vHeader
.ulColorEncoding
= 0;
180 vHeader
.ulIdentifier
= 0;
182 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
185 wxLogLastError("GpiCreatePS Failure");
188 m_refData
= pRefData
;
190 pRefData
->m_nWidth
= nTheWidth
;
191 pRefData
->m_nHeight
= nTheHeight
;
192 pRefData
->m_nDepth
= nNoBits
;
193 pRefData
->m_nNumColors
= 0;
194 pRefData
->m_pSelectedInto
= NULL
;
196 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
199 wxLogLastError("CreateBitmap");
201 SetHBITMAP((WXHBITMAP
)hBmp
);
204 // Create from XPM data
207 , wxControl
* WXUNUSED(pAnItem
))
211 (void)Create( (void *)ppData
212 ,wxBITMAP_TYPE_XPM_DATA
252 const wxString
& rFilename
263 bool wxBitmap::Create(
270 BITMAPINFOHEADER2 vHeader
;
274 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
275 SIZEL vSize
= {0, 0};
278 wxASSERT(vHabmain
!= NULL
);
280 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
281 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
282 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
284 vHeader
.cbFix
= sizeof(vHeader
);
285 vHeader
.cx
= (USHORT
)nW
;
286 vHeader
.cy
= (USHORT
)nH
;
287 vHeader
.cPlanes
= (USHORT
)nD
;
288 vHeader
.cBitCount
= lBitCount
;
289 vHeader
.ulCompression
= BCA_UNCOMP
;
290 vHeader
.cxResolution
= 0;
291 vHeader
.cyResolution
= 0;
292 vHeader
.cclrUsed
= 0;
293 vHeader
.cclrImportant
= 0;
294 vHeader
.usUnits
= BRU_METRIC
;
295 vHeader
.usRecording
= BRA_BOTTOMUP
;
296 vHeader
.usRendering
= BRH_NOTHALFTONED
;
299 vHeader
.ulColorEncoding
= 0;
300 vHeader
.ulIdentifier
= 0;
303 m_refData
= new wxBitmapRefData
;
305 GetBitmapData()->m_nWidth
= nW
;
306 GetBitmapData()->m_nHeight
= nH
;
307 GetBitmapData()->m_nDepth
= nD
;
311 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
314 wxLogLastError("CreateBitmap");
321 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
322 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
325 wxLogLastError("CreateBitmap");
327 GetBitmapData()->m_nDepth
= wxDisplayDepth();
329 SetHBITMAP((WXHBITMAP
)hBmp
);
331 #if WXWIN_COMPATIBILITY_2
332 GetBitmapData()->m_bOk
= hBmp
!= 0;
333 #endif // WXWIN_COMPATIBILITY_2
338 bool wxBitmap::LoadFile(
339 const wxString
& rFilename
347 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
353 m_refData
= new wxBitmapRefData
;
355 return(pHandler
->LoadFile( this
367 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
370 *this = vImage
.ConvertToBitmap();
376 bool wxBitmap::Create(
386 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
392 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
393 "type %d defined."), lType
);
398 m_refData
= new wxBitmapRefData
;
400 return(pHandler
->Create( this
409 bool wxBitmap::SaveFile(
410 const wxString
& rFilename
412 , const wxPalette
* pPalette
415 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
421 return pHandler
->SaveFile( this
429 // FIXME what about palette? shouldn't we use it?
430 wxImage
vImage(*this);
435 return(vImage
.SaveFile( rFilename
441 // ----------------------------------------------------------------------------
442 // wxBitmap accessors
443 // ----------------------------------------------------------------------------
445 void wxBitmap::SetQuality(
451 GetBitmapData()->m_nQuality
= nQ
;
454 #if WXWIN_COMPATIBILITY_2
455 void wxBitmap::SetOk(
461 GetBitmapData()->m_bOk
= bOk
;
463 #endif // WXWIN_COMPATIBILITY_2
465 void wxBitmap::SetPalette(
466 const wxPalette
& rPalette
471 GetBitmapData()->m_vBitmapPalette
= rPalette
;
474 void wxBitmap::SetMask(
480 GetBitmapData()->m_pBitmapMask
= pMask
;
483 // Will try something for OS/2 but not really sure how close
484 // to the msw intent this is.
485 wxBitmap
wxBitmap::GetBitmapForDC(
490 wxBitmap
vTmpBitmap( this->GetWidth()
494 WXHBITMAP vOldBitmap
;
500 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
501 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
503 // TODO: Set the points
505 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
506 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
511 // ----------------------------------------------------------------------------
513 // ----------------------------------------------------------------------------
520 // Construct a mask from a bitmap and a colour indicating
521 // the transparent area
523 const wxBitmap
& rBitmap
524 , const wxColour
& rColour
533 // Construct a mask from a bitmap and a palette index indicating
534 // the transparent area
536 const wxBitmap
& rBitmap
546 // Construct a mask from a mono bitmap (copies the bitmap).
548 const wxBitmap
& rBitmap
558 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
561 // Create a mask from a mono bitmap (copies the bitmap).
563 const wxBitmap
& rBitmap
566 BITMAPINFOHEADER2 vHeader
;
567 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
568 SIZEL vSize
= {0, 0};
573 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
576 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
580 vHeader
.cbFix
= sizeof(vHeader
);
581 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
582 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
584 vHeader
.cBitCount
= 1;
586 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
593 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
594 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
595 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
596 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
597 // TODO: Set the point array
598 ::GpiBitBlt(destPS
, srcPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
600 ::GpiDestroyPS(srcPS
);
601 ::GpiDestroyPS(destPS
);
605 // Create a mask from a bitmap and a palette index indicating
606 // the transparent area
608 const wxBitmap
& rBitmap
614 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
617 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
620 unsigned char cGreen
;
623 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
629 wxColour
vTransparentColour( cRed
634 return (Create( rBitmap
642 // Create a mask from a bitmap and a colour indicating
643 // the transparent area
645 const wxBitmap
& rBitmap
646 , const wxColour
& rColour
649 BITMAPINFOHEADER2 vHeader
;
650 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
651 SIZEL vSize
= {0, 0};
656 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
664 // scan the bitmap for the transparent colour and set
665 // the corresponding pixels in the mask to BLACK and
667 COLORREF vMaskColour
= OS2RGB(rColour
.Red(), rColour
.Green(), rColour
.Blue());
669 vHeader
.cbFix
= sizeof(vHeader
);
670 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
671 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
673 vHeader
.cBitCount
= 1;
675 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
682 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
683 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
684 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
685 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
687 // this is not very efficient, but I can't think
688 // of a better way of doing it
689 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
691 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
698 COLORREF col
= ::GpiQueryPel(srcPS
, &vPoint
);
700 if (col
== vMaskColour
)
702 ::GpiSetColor(destPS
, CLR_WHITE
);
703 ::GpiSetPel(destPS
, &vPoint
);
707 ::GpiSetColor(destPS
, CLR_BLACK
);
708 ::GpiSetPel(destPS
, &vPoint
);
712 ::GpiDestroyPS(srcPS
);
713 ::GpiDestroyPS(destPS
);
717 // ----------------------------------------------------------------------------
719 // ----------------------------------------------------------------------------
721 bool wxBitmapHandler::Create(
730 wxBitmap
* pBitmap
= wxDynamicCast( pImage
734 return(pBitmap
? Create( pBitmap
742 bool wxBitmapHandler::Load(
744 , const wxString
& rName
751 wxBitmap
* pBitmap
= wxDynamicCast( pImage
755 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
)
796 , long WXUNUSED(lType
)
797 , int WXUNUSED(nDesiredWidth
)
798 , int WXUNUSED(nDesiredHeight
)
804 bool wxBitmapHandler::SaveFile(
805 wxBitmap
* WXUNUSED(pBitmap
)
806 , const wxString
& WXUNUSED(rName
)
807 , int WXUNUSED(nType
)
808 , const wxPalette
* WXUNUSED(pPalette
)