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
345 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
351 m_refData
= new wxBitmapRefData
;
353 return(pHandler
->LoadFile( this
364 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
367 *this = vImage
.ConvertToBitmap();
373 bool wxBitmap::Create(
383 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
389 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
390 "type %d defined."), lType
);
395 m_refData
= new wxBitmapRefData
;
397 return(pHandler
->Create( this
406 bool wxBitmap::SaveFile(
407 const wxString
& rFilename
409 , const wxPalette
* pPalette
412 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
418 return pHandler
->SaveFile( this
426 // FIXME what about palette? shouldn't we use it?
427 wxImage
vImage(*this);
432 return(vImage
.SaveFile( rFilename
438 // ----------------------------------------------------------------------------
439 // wxBitmap accessors
440 // ----------------------------------------------------------------------------
442 void wxBitmap::SetQuality(
448 GetBitmapData()->m_nQuality
= nQ
;
451 #if WXWIN_COMPATIBILITY_2
452 void wxBitmap::SetOk(
458 GetBitmapData()->m_bOk
= bOk
;
460 #endif // WXWIN_COMPATIBILITY_2
462 void wxBitmap::SetPalette(
463 const wxPalette
& rPalette
468 GetBitmapData()->m_vBitmapPalette
= rPalette
;
471 void wxBitmap::SetMask(
477 GetBitmapData()->m_pBitmapMask
= pMask
;
480 // Will try something for OS/2 but not really sure how close
481 // to the msw intent this is.
482 wxBitmap
wxBitmap::GetBitmapForDC(
487 wxBitmap
vTmpBitmap( this->GetWidth()
491 WXHBITMAP vOldBitmap
;
497 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
498 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
500 // TODO: Set the points
502 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
503 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
508 // ----------------------------------------------------------------------------
510 // ----------------------------------------------------------------------------
517 // Construct a mask from a bitmap and a colour indicating
518 // the transparent area
520 const wxBitmap
& rBitmap
521 , const wxColour
& rColour
530 // Construct a mask from a bitmap and a palette index indicating
531 // the transparent area
533 const wxBitmap
& rBitmap
543 // Construct a mask from a mono bitmap (copies the bitmap).
545 const wxBitmap
& rBitmap
555 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
558 // Create a mask from a mono bitmap (copies the bitmap).
560 const wxBitmap
& rBitmap
563 BITMAPINFOHEADER2 vHeader
;
564 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
565 SIZEL vSize
= {0, 0};
570 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
573 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
577 vHeader
.cbFix
= sizeof(vHeader
);
578 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
579 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
581 vHeader
.cBitCount
= 1;
583 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
590 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
591 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
592 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
593 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
594 // TODO: Set the point array
595 ::GpiBitBlt(destPS
, srcPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
597 ::GpiDestroyPS(srcPS
);
598 ::GpiDestroyPS(destPS
);
602 // Create a mask from a bitmap and a palette index indicating
603 // the transparent area
605 const wxBitmap
& rBitmap
611 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
614 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
617 unsigned char cGreen
;
620 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
626 wxColour
vTransparentColour( cRed
631 return (Create( rBitmap
639 // Create a mask from a bitmap and a colour indicating
640 // the transparent area
642 const wxBitmap
& rBitmap
643 , const wxColour
& rColour
646 BITMAPINFOHEADER2 vHeader
;
647 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
648 SIZEL vSize
= {0, 0};
653 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
661 // scan the bitmap for the transparent colour and set
662 // the corresponding pixels in the mask to BLACK and
664 COLORREF vMaskColour
= OS2RGB(rColour
.Red(), rColour
.Green(), rColour
.Blue());
666 vHeader
.cbFix
= sizeof(vHeader
);
667 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
668 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
670 vHeader
.cBitCount
= 1;
672 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
679 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
680 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
681 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
682 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
684 // this is not very efficient, but I can't think
685 // of a better way of doing it
686 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
688 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
695 COLORREF col
= ::GpiQueryPel(srcPS
, &vPoint
);
697 if (col
== vMaskColour
)
699 ::GpiSetColor(destPS
, CLR_WHITE
);
700 ::GpiSetPel(destPS
, &vPoint
);
704 ::GpiSetColor(destPS
, CLR_BLACK
);
705 ::GpiSetPel(destPS
, &vPoint
);
709 ::GpiDestroyPS(srcPS
);
710 ::GpiDestroyPS(destPS
);
714 // ----------------------------------------------------------------------------
716 // ----------------------------------------------------------------------------
718 bool wxBitmapHandler::Create(
727 wxBitmap
* pBitmap
= wxDynamicCast( pImage
731 return(pBitmap
? Create( pBitmap
739 bool wxBitmapHandler::Load(
741 , const wxString
& rName
747 wxBitmap
* pBitmap
= wxDynamicCast( pImage
751 return(pBitmap
? LoadFile( pBitmap
759 bool wxBitmapHandler::Save(
761 , const wxString
& rName
765 wxBitmap
* pBitmap
= wxDynamicCast( pImage
769 return(pBitmap
? SaveFile( pBitmap
775 bool wxBitmapHandler::Create(
776 wxBitmap
* WXUNUSED(pBitmap
)
777 , void* WXUNUSED(pData
)
778 , long WXUNUSED(lType
)
779 , int WXUNUSED(nWidth
)
780 , int WXUNUSED(nHeight
)
781 , int WXUNUSED(nDepth
)
787 bool wxBitmapHandler::LoadFile(
788 wxBitmap
* WXUNUSED(pBitmap
)
789 , const wxString
& WXUNUSED(rName
)
790 , long WXUNUSED(lType
)
791 , int WXUNUSED(nDesiredWidth
)
792 , int WXUNUSED(nDesiredHeight
)
798 bool wxBitmapHandler::SaveFile(
799 wxBitmap
* WXUNUSED(pBitmap
)
800 , const wxString
& WXUNUSED(rName
)
801 , int WXUNUSED(nType
)
802 , const wxPalette
* WXUNUSED(pPalette
)