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 // Creates a surface that will use wxImage's pixel data (RGB only)
37 static wxIDirectFBSurfacePtr
CreateSurfaceForImage(const wxImage
& image
)
39 wxCHECK_MSG( image
.Ok(), NULL
, _T("invalid image") );
40 // FIXME_DFB: implement alpha handling by merging alpha buffer with RGB
41 // into a temporary RGBA surface
42 wxCHECK_MSG( !image
.HasAlpha(), NULL
, _T("alpha channel not supported") );
44 DFBSurfaceDescription desc
;
45 desc
.flags
= (DFBSurfaceDescriptionFlags
)
46 (DSDESC_CAPS
| DSDESC_WIDTH
| DSDESC_HEIGHT
| DSDESC_PIXELFORMAT
|
48 desc
.caps
= DSCAPS_NONE
;
49 desc
.width
= image
.GetWidth();
50 desc
.height
= image
.GetHeight();
51 desc
.pixelformat
= DSPF_RGB24
;
52 desc
.preallocated
[0].data
= image
.GetData();
53 desc
.preallocated
[0].pitch
= 3 * desc
.width
;
55 return wxIDirectFB::Get()->CreateSurface(&desc
);
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
62 class wxBitmapRefData
: public wxObjectRefData
73 wxBitmapRefData(const wxBitmapRefData
& data
)
76 m_surface
= data
.m_surface
->Clone();
78 m_mask
= data
.m_mask
? new wxMask(*data
.m_mask
) : NULL
;
80 m_palette
= data
.m_palette
? new wxPalette(*data
.m_palette
) : NULL
;
92 wxIDirectFBSurfacePtr m_surface
;
99 #define M_BITMAP ((wxBitmapRefData *)m_refData)
101 //-----------------------------------------------------------------------------
103 //-----------------------------------------------------------------------------
105 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
, wxObject
)
106 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxBitmapBase
)
108 wxBitmap::wxBitmap(int width
, int height
, int depth
)
110 Create(width
, height
, depth
);
113 bool wxBitmap::Create(const wxIDirectFBSurfacePtr
& surface
)
117 wxCHECK_MSG( surface
, false, _T("invalid surface") );
119 m_refData
= new wxBitmapRefData();
120 M_BITMAP
->m_surface
= surface
;
124 bool wxBitmap::Create(int width
, int height
, int depth
)
128 wxCHECK_MSG( width
> 0 && height
> 0, false, wxT("invalid bitmap size") );
129 wxCHECK_MSG( depth
== -1, false, wxT("only default depth supported now") );
131 DFBSurfaceDescription desc
;
132 desc
.flags
= (DFBSurfaceDescriptionFlags
)(
133 DSDESC_CAPS
| DSDESC_WIDTH
| DSDESC_HEIGHT
);
134 desc
.caps
= DSCAPS_NONE
;
136 desc
.height
= height
;
138 return Create(wxIDirectFB::Get()->CreateSurface(&desc
));
141 #warning "FIXME: move this to common code"
142 bool wxBitmap::CreateFromXpm(const char **bits
)
144 wxCHECK_MSG( bits
!= NULL
, false, wxT("invalid bitmap data") );
146 #if wxUSE_IMAGE && wxUSE_XPM
147 wxXPMDecoder decoder
;
148 wxImage img
= decoder
.ReadData(bits
);
149 wxCHECK_MSG( img
.Ok(), false, wxT("invalid bitmap data") );
151 *this = wxBitmap(img
);
155 wxFAIL_MSG( _T("creating bitmaps from XPMs not supported") );
157 #endif // wxUSE_IMAGE && wxUSE_XPM
161 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
163 wxCHECK_RET( image
.Ok(), wxT("invalid image") );
165 // create surface in screen's format:
166 if ( !Create(image
.GetWidth(), image
.GetHeight(), depth
) )
169 // then copy the image to it:
170 wxIDirectFBSurfacePtr
src(CreateSurfaceForImage(image
));
171 wxIDirectFBSurfacePtr dst
= M_BITMAP
->m_surface
;
173 if ( !dst
->SetBlittingFlags(DSBLIT_NOFX
) )
175 if ( !dst
->Blit(src
->GetRaw(), NULL
, 0, 0) )
178 // FIXME: implement mask creation from image's mask (or alpha channel?)
179 wxASSERT_MSG( !image
.HasMask(), _T("image masks are ignored for now") );
182 wxImage
wxBitmap::ConvertToImage() const
184 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
186 wxImage
img(GetWidth(), GetHeight());
187 wxIDirectFBSurfacePtr
dst(CreateSurfaceForImage(img
));
188 wxIDirectFBSurfacePtr src
= M_BITMAP
->m_surface
;
190 if ( !dst
->SetBlittingFlags(DSBLIT_NOFX
) )
192 if ( !dst
->Blit(src
->GetRaw(), NULL
, 0, 0) )
195 // FIXME: implement mask setting in the image
196 wxASSERT_MSG( GetMask() == NULL
, _T("bitmap masks are ignored for now") );
200 #endif // wxUSE_IMAGE
202 wxBitmap::wxBitmap(const wxString
&filename
, wxBitmapType type
)
204 LoadFile(filename
, type
);
207 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
209 wxCHECK_RET( depth
== 1, wxT("can only create mono bitmap from XBM data") );
211 wxFAIL_MSG( _T("not implemented") );
214 bool wxBitmap::Ok() const
216 return (m_refData
!= NULL
&& M_BITMAP
->m_surface
);
219 bool wxBitmap::operator==(const wxBitmap
& bmp
) const
221 // FIXME: is this the right way to compare bitmaps?
222 return (m_refData
== bmp
.m_refData
);
225 int wxBitmap::GetHeight() const
227 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
230 M_BITMAP
->m_surface
->GetSize(NULL
, &h
);
234 int wxBitmap::GetWidth() const
236 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
239 M_BITMAP
->m_surface
->GetSize(&w
, NULL
);
243 int wxBitmap::GetDepth() const
245 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
247 return M_BITMAP
->m_surface
->GetDepth();
250 wxMask
*wxBitmap::GetMask() const
252 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
254 return M_BITMAP
->m_mask
;
257 void wxBitmap::SetMask(wxMask
*mask
)
259 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
261 delete M_BITMAP
->m_mask
;
262 M_BITMAP
->m_mask
= mask
;
265 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
267 *this = *((wxBitmap
*)(&icon
));
271 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
& rect
) const
274 rect
.x
>= 0 && rect
.y
>= 0 &&
275 rect
.x
+rect
.width
<= GetWidth() &&
276 rect
.y
+rect
.height
<= GetHeight(),
278 wxT("invalid bitmap or bitmap region") );
280 // NB: DirectFB subsurfaces share the same pixels buffer, so we must
281 // clone the obtained subsurface
282 DFBRectangle r
= { rect
.x
, rect
.y
, rect
.width
, rect
.height
};
283 return wxBitmap(M_BITMAP
->m_surface
->GetSubSurface(&r
)->Clone());
286 #warning "to common code"
287 bool wxBitmap::LoadFile(const wxString
&name
, wxBitmapType type
)
291 wxBitmapHandler
*handler
= FindHandler(type
);
293 if ( handler
== NULL
)
296 if ( !image
.LoadFile(name
, type
) || !image
.Ok() )
298 wxLogError("no bitmap handler for type %d defined.", type
);
303 *this = wxBitmap(image
);
308 m_refData
= new wxBitmapRefData();
310 return handler
->LoadFile(this, name
, type
, -1, -1);
313 #warning "to common code"
314 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, const wxPalette
*palette
) const
316 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
318 wxBitmapHandler
*handler
= FindHandler(type
);
320 if ( handler
== NULL
)
322 wxImage image
= ConvertToImage();
325 image
.SetPalette(*palette
);
326 #endif // wxUSE_PALETTE
329 return image
.SaveFile(filename
, type
);
332 wxLogError("no bitmap handler for type %d defined.", type
);
337 return handler
->SaveFile(this, filename
, type
, palette
);
341 wxPalette
*wxBitmap::GetPalette() const
343 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
345 return M_BITMAP
->m_palette
;
348 void wxBitmap::SetPalette(const wxPalette
& palette
)
350 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
351 wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
353 delete M_BITMAP
->m_palette
;
354 M_BITMAP
->m_palette
= NULL
;
356 if ( !palette
.Ok() ) return;
358 M_BITMAP
->m_palette
= new wxPalette(palette
);
360 #endif // wxUSE_PALETTE
362 void wxBitmap::SetHeight(int height
)
366 wxFAIL_MSG( _T("SetHeight not implemented") );
369 void wxBitmap::SetWidth(int width
)
373 wxFAIL_MSG( _T("SetWidth not implemented") );
376 void wxBitmap::SetDepth(int depth
)
380 wxFAIL_MSG( _T("SetDepth not implemented") );
383 wxIDirectFBSurfacePtr
wxBitmap::GetDirectFBSurface() const
385 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
387 return M_BITMAP
->m_surface
;
390 wxObjectRefData
*wxBitmap::CreateRefData() const
392 return new wxBitmapRefData
;
395 wxObjectRefData
*wxBitmap::CloneRefData(const wxObjectRefData
*data
) const
397 return new wxBitmapRefData(*(wxBitmapRefData
*)data
);
402 void wxBitmap::InitStandardHandlers()
404 // not wxBitmap handlers, we rely on wxImage