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"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
42 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
44 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 wxBitmapRefData::wxBitmapRefData()
57 m_pSelectedInto
= NULL
;
60 m_hBitmap
= (WXHBITMAP
) NULL
;
61 } // end of wxBitmapRefData::wxBitmapRefData
63 void wxBitmapRefData::Free()
65 wxASSERT_MSG( !m_pSelectedInto
,
66 wxT("deleting bitmap still selected into wxMemoryDC") );
70 if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) )
72 wxLogLastError("GpiDeleteBitmap(hbitmap)");
78 } // end of wxBitmapRefData::Free
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // this function should be called from all wxBitmap ctors
87 // m_refData = NULL; done in the base class ctor
90 wxTheBitmapList
->AddBitmap(this);
93 bool wxBitmap::CopyFromIconOrCursor(
94 const wxGDIImage
& rIcon
97 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
101 pRefData
->m_nWidth
= rIcon
.GetWidth();
102 pRefData
->m_nHeight
= rIcon
.GetHeight();
103 pRefData
->m_nDepth
= wxDisplayDepth();
105 pRefData
->m_hBitmap
= (WXHBITMAP
)rIcon
.GetHandle();
107 pRefData
->m_pBitmapMask
= new wxMask();
109 #if WXWIN_COMPATIBILITY_2
110 pRefData
->m_bOk
= TRUE
;
111 #endif // WXWIN_COMPATIBILITY_2
115 bool wxBitmap::CopyFromCursor(
116 const wxCursor
& rCursor
123 return(CopyFromIconOrCursor(rCursor
));
126 bool wxBitmap::CopyFromIcon(
135 return CopyFromIconOrCursor(rIcon
);
138 wxBitmap::~wxBitmap()
141 wxTheBitmapList
->DeleteObject(this);
153 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
154 BITMAPINFOHEADER2 vHeader
;
158 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
159 SIZEL vSize
= {0, 0};
161 wxASSERT(vHabmain
!= NULL
);
163 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
165 vHeader
.cbFix
= sizeof(vHeader
);
166 vHeader
.cx
= (USHORT
)nTheWidth
;
167 vHeader
.cy
= (USHORT
)nTheHeight
;
168 vHeader
.cPlanes
= 1L;
169 vHeader
.cBitCount
= nNoBits
;
170 vHeader
.ulCompression
= BCA_UNCOMP
;
171 vHeader
.cxResolution
= 0;
172 vHeader
.cyResolution
= 0;
173 vHeader
.cclrUsed
= 0;
174 vHeader
.cclrImportant
= 0;
175 vHeader
.usUnits
= BRU_METRIC
;
176 vHeader
.usRecording
= BRA_BOTTOMUP
;
177 vHeader
.usRendering
= BRH_NOTHALFTONED
;
180 vHeader
.ulColorEncoding
= 0;
181 vHeader
.ulIdentifier
= 0;
183 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
186 wxLogLastError("GpiCreatePS Failure");
189 m_refData
= pRefData
;
191 pRefData
->m_nWidth
= nTheWidth
;
192 pRefData
->m_nHeight
= nTheHeight
;
193 pRefData
->m_nDepth
= nNoBits
;
194 pRefData
->m_nNumColors
= 0;
195 pRefData
->m_pSelectedInto
= NULL
;
197 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
200 wxLogLastError("CreateBitmap");
202 SetHBITMAP((WXHBITMAP
)hBmp
);
205 // Create from XPM data
208 , wxControl
* WXUNUSED(pAnItem
))
212 (void)Create( (void *)ppData
213 ,wxBITMAP_TYPE_XPM_DATA
253 const wxString
& rFilename
264 bool wxBitmap::Create(
271 BITMAPINFOHEADER2 vHeader
;
275 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
276 SIZEL vSize
= {0, 0};
279 wxASSERT(vHabmain
!= NULL
);
281 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
282 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
283 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
285 vHeader
.cbFix
= sizeof(vHeader
);
286 vHeader
.cx
= (USHORT
)nW
;
287 vHeader
.cy
= (USHORT
)nH
;
288 vHeader
.cPlanes
= (USHORT
)nD
;
289 vHeader
.cBitCount
= lBitCount
;
290 vHeader
.ulCompression
= BCA_UNCOMP
;
291 vHeader
.cxResolution
= 0;
292 vHeader
.cyResolution
= 0;
293 vHeader
.cclrUsed
= 0;
294 vHeader
.cclrImportant
= 0;
295 vHeader
.usUnits
= BRU_METRIC
;
296 vHeader
.usRecording
= BRA_BOTTOMUP
;
297 vHeader
.usRendering
= BRH_NOTHALFTONED
;
300 vHeader
.ulColorEncoding
= 0;
301 vHeader
.ulIdentifier
= 0;
304 m_refData
= new wxBitmapRefData
;
306 GetBitmapData()->m_nWidth
= nW
;
307 GetBitmapData()->m_nHeight
= nH
;
308 GetBitmapData()->m_nDepth
= nD
;
312 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
315 wxLogLastError("CreateBitmap");
322 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
323 hBmp
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
);
326 wxLogLastError("CreateBitmap");
328 GetBitmapData()->m_nDepth
= wxDisplayDepth();
330 SetHBITMAP((WXHBITMAP
)hBmp
);
332 #if WXWIN_COMPATIBILITY_2
333 GetBitmapData()->m_bOk
= hBmp
!= 0;
334 #endif // WXWIN_COMPATIBILITY_2
339 bool wxBitmap::LoadFile(
340 const wxString
& rFilename
344 HPS hPs
= NULLHANDLE
;
348 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
354 m_refData
= new wxBitmapRefData
;
356 return(pHandler
->LoadFile( this
368 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
371 *this = vImage
.ConvertToBitmap();
377 bool wxBitmap::Create(
387 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
393 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
394 "type %d defined."), lType
);
399 m_refData
= new wxBitmapRefData
;
401 return(pHandler
->Create( this
410 bool wxBitmap::SaveFile(
411 const wxString
& rFilename
413 , const wxPalette
* pPalette
416 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
422 return pHandler
->SaveFile( this
430 // FIXME what about palette? shouldn't we use it?
431 wxImage
vImage(*this);
436 return(vImage
.SaveFile( rFilename
442 // ----------------------------------------------------------------------------
443 // wxBitmap accessors
444 // ----------------------------------------------------------------------------
446 void wxBitmap::SetQuality(
452 GetBitmapData()->m_nQuality
= nQ
;
455 #if WXWIN_COMPATIBILITY_2
456 void wxBitmap::SetOk(
462 GetBitmapData()->m_bOk
= bOk
;
464 #endif // WXWIN_COMPATIBILITY_2
466 void wxBitmap::SetPalette(
467 const wxPalette
& rPalette
472 GetBitmapData()->m_vBitmapPalette
= rPalette
;
475 void wxBitmap::SetMask(
481 GetBitmapData()->m_pBitmapMask
= pMask
;
484 // Will try something for OS/2 but not really sure how close
485 // to the msw intent this is.
486 wxBitmap
wxBitmap::GetBitmapForDC(
491 wxBitmap
vTmpBitmap( this->GetWidth()
495 WXHBITMAP vOldBitmap
;
501 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
502 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
504 // TODO: Set the points
506 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
507 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
512 // ----------------------------------------------------------------------------
514 // ----------------------------------------------------------------------------
521 // Construct a mask from a bitmap and a colour indicating
522 // the transparent area
524 const wxBitmap
& rBitmap
525 , const wxColour
& rColour
534 // Construct a mask from a bitmap and a palette index indicating
535 // the transparent area
537 const wxBitmap
& rBitmap
547 // Construct a mask from a mono bitmap (copies the bitmap).
549 const wxBitmap
& rBitmap
559 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
562 // Create a mask from a mono bitmap (copies the bitmap).
564 const wxBitmap
& rBitmap
567 BITMAPINFOHEADER2 vHeader
;
568 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
569 SIZEL vSize
= {0, 0};
574 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
577 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
581 vHeader
.cbFix
= sizeof(vHeader
);
582 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
583 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
585 vHeader
.cBitCount
= 1;
587 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
594 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
595 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
596 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
597 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
598 // TODO: Set the point array
599 ::GpiBitBlt(destPS
, srcPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
601 ::GpiDestroyPS(srcPS
);
602 ::GpiDestroyPS(destPS
);
606 // Create a mask from a bitmap and a palette index indicating
607 // the transparent area
609 const wxBitmap
& rBitmap
615 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
618 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
621 unsigned char cGreen
;
624 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
630 wxColour
vTransparentColour( cRed
635 return (Create( rBitmap
643 // Create a mask from a bitmap and a colour indicating
644 // the transparent area
646 const wxBitmap
& rBitmap
647 , const wxColour
& rColour
650 BITMAPINFOHEADER2 vHeader
;
651 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
652 SIZEL vSize
= {0, 0};
657 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
665 // scan the bitmap for the transparent colour and set
666 // the corresponding pixels in the mask to BLACK and
668 COLORREF vMaskColour
= OS2RGB(rColour
.Red(), rColour
.Green(), rColour
.Blue());
670 vHeader
.cbFix
= sizeof(vHeader
);
671 vHeader
.cx
= (USHORT
)rBitmap
.GetWidth();
672 vHeader
.cy
= (USHORT
)rBitmap
.GetHeight();
674 vHeader
.cBitCount
= 1;
676 m_hMaskBitmap
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
683 HPS srcPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
684 ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP());
685 HPS destPS
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
686 ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
);
688 // this is not very efficient, but I can't think
689 // of a better way of doing it
690 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
692 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
699 COLORREF col
= ::GpiQueryPel(srcPS
, &vPoint
);
701 if (col
== vMaskColour
)
703 ::GpiSetColor(destPS
, CLR_WHITE
);
704 ::GpiSetPel(destPS
, &vPoint
);
708 ::GpiSetColor(destPS
, CLR_BLACK
);
709 ::GpiSetPel(destPS
, &vPoint
);
713 ::GpiDestroyPS(srcPS
);
714 ::GpiDestroyPS(destPS
);
718 // ----------------------------------------------------------------------------
720 // ----------------------------------------------------------------------------
722 bool wxBitmapHandler::Create(
731 wxBitmap
* pBitmap
= wxDynamicCast( pImage
735 return(pBitmap
? Create( pBitmap
743 bool wxBitmapHandler::Load(
745 , const wxString
& rName
752 wxBitmap
* pBitmap
= wxDynamicCast( pImage
756 return(pBitmap
? LoadFile( pBitmap
765 bool wxBitmapHandler::Save(
767 , const wxString
& rName
771 wxBitmap
* pBitmap
= wxDynamicCast( pImage
775 return(pBitmap
? SaveFile( pBitmap
781 bool wxBitmapHandler::Create(
782 wxBitmap
* WXUNUSED(pBitmap
)
783 , void* WXUNUSED(pData
)
784 , long WXUNUSED(lType
)
785 , int WXUNUSED(nWidth
)
786 , int WXUNUSED(nHeight
)
787 , int WXUNUSED(nDepth
)
793 bool wxBitmapHandler::LoadFile(
794 wxBitmap
* WXUNUSED(pBitmap
)
795 , const wxString
& WXUNUSED(rName
)
797 , long WXUNUSED(lType
)
798 , int WXUNUSED(nDesiredWidth
)
799 , int WXUNUSED(nDesiredHeight
)
805 bool wxBitmapHandler::SaveFile(
806 wxBitmap
* WXUNUSED(pBitmap
)
807 , const wxString
& WXUNUSED(rName
)
808 , int WXUNUSED(nType
)
809 , const wxPalette
* WXUNUSED(pPalette
)