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");
191 m_refData
= pRefData
;
193 pRefData
->m_nWidth
= nTheWidth
;
194 pRefData
->m_nHeight
= nTheHeight
;
195 pRefData
->m_nDepth
= nNoBits
;
196 pRefData
->m_nNumColors
= 0;
197 pRefData
->m_pSelectedInto
= NULL
;
199 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
202 wxLogLastError("CreateBitmap");
204 SetHBITMAP((WXHBITMAP
)hBmp
);
207 // Create from XPM data
210 , wxControl
* WXUNUSED(pAnItem
))
214 (void)Create( (void *)ppData
215 ,wxBITMAP_TYPE_XPM_DATA
255 const wxString
& rFilename
266 bool wxBitmap::Create(
273 BITMAPINFOHEADER2 vHeader
;
277 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
278 SIZEL vSize
= {0, 0};
281 wxASSERT(vHabmain
!= NULL
);
283 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
284 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
285 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
287 vHeader
.cbFix
= sizeof(vHeader
);
288 vHeader
.cx
= (USHORT
)nW
;
289 vHeader
.cy
= (USHORT
)nH
;
290 vHeader
.cPlanes
= (USHORT
)nD
;
291 vHeader
.cBitCount
= lBitCount
;
292 vHeader
.ulCompression
= BCA_UNCOMP
;
293 vHeader
.cxResolution
= 0;
294 vHeader
.cyResolution
= 0;
295 vHeader
.cclrUsed
= 0;
296 vHeader
.cclrImportant
= 0;
297 vHeader
.usUnits
= BRU_METRIC
;
298 vHeader
.usRecording
= BRA_BOTTOMUP
;
299 vHeader
.usRendering
= BRH_NOTHALFTONED
;
302 vHeader
.ulColorEncoding
= 0;
303 vHeader
.ulIdentifier
= 0;
306 m_refData
= new wxBitmapRefData
;
308 GetBitmapData()->m_nWidth
= nW
;
309 GetBitmapData()->m_nHeight
= nH
;
310 GetBitmapData()->m_nDepth
= nD
;
314 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
317 wxLogLastError("CreateBitmap");
324 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
325 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
328 wxLogLastError("CreateBitmap");
330 GetBitmapData()->m_nDepth
= wxDisplayDepth();
332 SetHBITMAP((WXHBITMAP
)hBmp
);
334 #if WXWIN_COMPATIBILITY_2
335 GetBitmapData()->m_bOk
= hBmp
!= 0;
336 #endif // WXWIN_COMPATIBILITY_2
341 bool wxBitmap::LoadFile(
342 const wxString
& rFilename
348 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
354 m_refData
= new wxBitmapRefData
;
356 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
750 wxBitmap
* pBitmap
= wxDynamicCast( pImage
754 return(pBitmap
? LoadFile( pBitmap
762 bool wxBitmapHandler::Save(
764 , const wxString
& rName
768 wxBitmap
* pBitmap
= wxDynamicCast( pImage
772 return(pBitmap
? SaveFile( pBitmap
778 bool wxBitmapHandler::Create(
779 wxBitmap
* WXUNUSED(pBitmap
)
780 , void* WXUNUSED(pData
)
781 , long WXUNUSED(lType
)
782 , int WXUNUSED(nWidth
)
783 , int WXUNUSED(nHeight
)
784 , int WXUNUSED(nDepth
)
790 bool wxBitmapHandler::LoadFile(
791 wxBitmap
* WXUNUSED(pBitmap
)
792 , const wxString
& WXUNUSED(rName
)
793 , long WXUNUSED(lType
)
794 , int WXUNUSED(nDesiredWidth
)
795 , int WXUNUSED(nDesiredHeight
)
801 bool wxBitmapHandler::SaveFile(
802 wxBitmap
* WXUNUSED(pBitmap
)
803 , const wxString
& WXUNUSED(rName
)
804 , int WXUNUSED(nType
)
805 , const wxPalette
* WXUNUSED(pPalette
)