1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/bitmap.cpp
3 // Purpose: wxBitmap implementation
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
23 #include "wx/bitmap.h"
24 #include "wx/colour.h"
27 #warning "move this to common"
28 #include "wx/xpmdecod.h"
30 #include "wx/dfb/private.h"
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
36 // Convert wxColour into it's quantized value in lower-precision
37 // pixel format (needed for masking by colour).
38 static wxColour
wxQuantizeColour(const wxColour
& clr
, const wxBitmap
& bmp
)
41 pixel_format_t
*pf
= bmp
.GetMGLbitmap_t()->pf
;
43 if ( pf
->redAdjust
== 0 && pf
->greenAdjust
== 0 && pf
->blueAdjust
== 0 )
46 return wxColour((unsigned char)((clr
.Red() >> pf
->redAdjust
) << pf
->redAdjust
),
47 (unsigned char)((clr
.Green() >> pf
->greenAdjust
) << pf
->greenAdjust
),
48 (unsigned char)((clr
.Blue() >> pf
->blueAdjust
) << pf
->blueAdjust
));
53 //-----------------------------------------------------------------------------
55 //-----------------------------------------------------------------------------
57 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
59 wxMask::wxMask() : m_bitmap(NULL
)
63 wxMask::wxMask(const wxBitmap
& bitmap
)
69 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
72 Create(bitmap
, colour
);
76 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
79 Create(bitmap
, paletteIndex
);
81 #endif // wxUSE_PALETTE
83 wxMask::wxMask(const wxMask
& mask
)
85 m_bitmap
= mask
.m_bitmap
? new wxBitmap(*mask
.m_bitmap
) : NULL
;
93 #warning "move this to common code"
94 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
99 wxColour
clr(wxQuantizeColour(colour
, bitmap
));
101 wxImage
imgSrc(bitmap
.ConvertToImage());
102 imgSrc
.SetMask(false);
103 wxImage
image(imgSrc
.ConvertToMono(clr
.Red(), clr
.Green(), clr
.Blue()));
107 m_bitmap
= new wxBitmap(image
, 1);
109 return m_bitmap
->Ok();
113 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
116 wxPalette
*pal
= bitmap
.GetPalette();
118 wxCHECK_MSG( pal
, false, wxT("Cannot create mask from bitmap without palette") );
120 pal
->GetRGB(paletteIndex
, &r
, &g
, &b
);
122 return Create(bitmap
, wxColour(r
, g
, b
));
124 #endif // wxUSE_PALETTE
126 bool wxMask::Create(const wxBitmap
& bitmap
)
131 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap") );
132 wxCHECK_MSG( bitmap
.GetDepth() == 1, false, wxT("Cannot create mask from colour bitmap") );
134 m_bitmap
= new wxBitmap(bitmap
);
138 const wxBitmap
& wxMask::GetBitmap() const
140 return m_bitmap
? *m_bitmap
: wxNullBitmap
;
144 //-----------------------------------------------------------------------------
146 //-----------------------------------------------------------------------------
148 class wxBitmapRefData
: public wxObjectRefData
159 wxBitmapRefData(const wxBitmapRefData
& data
)
161 if ( data
.m_surface
)
162 m_surface
= data
.m_surface
->Clone();
164 m_mask
= data
.m_mask
? new wxMask(*data
.m_mask
) : NULL
;
166 m_palette
= data
.m_palette
? new wxPalette(*data
.m_palette
) : NULL
;
178 wxIDirectFBSurfacePtr m_surface
;
181 wxPalette
*m_palette
;
185 #define M_BITMAP ((wxBitmapRefData *)m_refData)
187 //-----------------------------------------------------------------------------
189 //-----------------------------------------------------------------------------
191 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
, wxObject
)
192 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxBitmapBase
)
194 wxBitmap::wxBitmap(int width
, int height
, int depth
)
196 Create(width
, height
, depth
);
199 bool wxBitmap::Create(const wxIDirectFBSurfacePtr
& surface
)
203 wxCHECK_MSG( surface
, false, _T("invalid surface") );
205 m_refData
= new wxBitmapRefData();
206 M_BITMAP
->m_surface
= surface
;
210 bool wxBitmap::Create(int width
, int height
, int depth
)
214 wxCHECK_MSG( width
> 0 && height
> 0, false, wxT("invalid bitmap size") );
215 wxCHECK_MSG( depth
== -1, false, wxT("only default depth supported now") );
217 DFBSurfaceDescription desc
;
218 desc
.flags
= (DFBSurfaceDescriptionFlags
)(
219 DSDESC_CAPS
| DSDESC_WIDTH
| DSDESC_HEIGHT
);
220 desc
.caps
= DSCAPS_NONE
;
222 desc
.height
= height
;
224 return Create(wxIDirectFB::Get()->CreateSurface(&desc
));
227 #warning "FIXME: move this to common code"
228 bool wxBitmap::CreateFromXpm(const char **bits
)
230 wxCHECK_MSG( bits
!= NULL
, false, wxT("invalid bitmap data") );
232 #if wxUSE_IMAGE && wxUSE_XPM
233 wxXPMDecoder decoder
;
234 wxImage img
= decoder
.ReadData(bits
);
235 wxCHECK_MSG( img
.Ok(), false, wxT("invalid bitmap data") );
237 *this = wxBitmap(img
);
241 wxFAIL_MSG( _T("creating bitmaps from XPMs not supported") );
243 #endif // wxUSE_IMAGE && wxUSE_XPM
247 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
249 wxCHECK_RET( image
.Ok(), wxT("invalid image") );
252 wxImage
wxBitmap::ConvertToImage() const
254 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
256 return wxNullImage
; // FIXME
258 #endif // wxUSE_IMAGE
260 wxBitmap::wxBitmap(const wxString
&filename
, wxBitmapType type
)
262 LoadFile(filename
, type
);
265 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
267 wxCHECK_RET( depth
== 1, wxT("can only create mono bitmap from XBM data") );
269 wxFAIL_MSG( _T("not implemented") );
272 bool wxBitmap::Ok() const
274 return (m_refData
!= NULL
&& M_BITMAP
->m_surface
);
277 bool wxBitmap::operator==(const wxBitmap
& bmp
) const
279 // FIXME: is this the right way to compare bitmaps?
280 return (m_refData
== bmp
.m_refData
);
283 int wxBitmap::GetHeight() const
285 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
288 M_BITMAP
->m_surface
->GetSize(NULL
, &h
);
292 int wxBitmap::GetWidth() const
294 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
297 M_BITMAP
->m_surface
->GetSize(&w
, NULL
);
301 int wxBitmap::GetDepth() const
303 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
305 return M_BITMAP
->m_surface
->GetDepth();
308 wxMask
*wxBitmap::GetMask() const
310 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
312 return M_BITMAP
->m_mask
;
315 void wxBitmap::SetMask(wxMask
*mask
)
317 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
319 delete M_BITMAP
->m_mask
;
320 M_BITMAP
->m_mask
= mask
;
323 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
325 *this = *((wxBitmap
*)(&icon
));
329 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
& rect
) const
332 rect
.x
>= 0 && rect
.y
>= 0 &&
333 rect
.x
+rect
.width
<= GetWidth() &&
334 rect
.y
+rect
.height
<= GetHeight(),
336 wxT("invalid bitmap or bitmap region") );
338 // NB: DirectFB subsurfaces share the same pixels buffer, so we must
339 // clone the obtained subsurface
340 DFBRectangle r
= { rect
.x
, rect
.y
, rect
.width
, rect
.height
};
341 return wxBitmap(M_BITMAP
->m_surface
->GetSubSurface(&r
)->Clone());
344 #warning "to common code"
345 bool wxBitmap::LoadFile(const wxString
&name
, wxBitmapType type
)
349 wxBitmapHandler
*handler
= FindHandler(type
);
351 if ( handler
== NULL
)
354 if ( !image
.LoadFile(name
, type
) || !image
.Ok() )
356 wxLogError("no bitmap handler for type %d defined.", type
);
361 *this = wxBitmap(image
);
366 m_refData
= new wxBitmapRefData();
368 return handler
->LoadFile(this, name
, type
, -1, -1);
371 #warning "to common code"
372 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, const wxPalette
*palette
) const
374 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
376 wxBitmapHandler
*handler
= FindHandler(type
);
378 if ( handler
== NULL
)
380 wxImage image
= ConvertToImage();
383 image
.SetPalette(*palette
);
384 #endif // wxUSE_PALETTE
387 return image
.SaveFile(filename
, type
);
390 wxLogError("no bitmap handler for type %d defined.", type
);
395 return handler
->SaveFile(this, filename
, type
, palette
);
399 wxPalette
*wxBitmap::GetPalette() const
401 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
403 return M_BITMAP
->m_palette
;
406 void wxBitmap::SetPalette(const wxPalette
& palette
)
408 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
409 wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
411 delete M_BITMAP
->m_palette
;
412 M_BITMAP
->m_palette
= NULL
;
414 if ( !palette
.Ok() ) return;
416 M_BITMAP
->m_palette
= new wxPalette(palette
);
418 #endif // wxUSE_PALETTE
420 void wxBitmap::SetHeight(int height
)
426 void wxBitmap::SetWidth(int width
)
432 void wxBitmap::SetDepth(int depth
)
438 wxIDirectFBSurfacePtr
wxBitmap::GetDirectFBSurface() const
440 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
442 return M_BITMAP
->m_surface
;
445 wxObjectRefData
*wxBitmap::CreateRefData() const
447 return new wxBitmapRefData
;
450 wxObjectRefData
*wxBitmap::CloneRefData(const wxObjectRefData
*data
) const
452 return new wxBitmapRefData(*(wxBitmapRefData
*)data
);
457 void wxBitmap::InitStandardHandlers()
459 // not wxBitmap handlers, we rely on wxImage