Unicode compilation fixes
[wxWidgets.git] / src / dfb / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/bitmap.cpp
3 // Purpose: wxBitmap implementation
4 // Author: Vaclav Slavik
5 // Created: 2006-08-04
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #ifndef WX_PRECOMP
19 #include "wx/app.h"
20 #include "wx/log.h"
21 #endif
22
23 #include "wx/bitmap.h"
24 #include "wx/colour.h"
25 #include "wx/image.h"
26
27 #include "wx/dfb/private.h"
28
29 //-----------------------------------------------------------------------------
30 // helpers
31 //-----------------------------------------------------------------------------
32
33 // Creates a surface that will use wxImage's pixel data (RGB only)
34 static wxIDirectFBSurfacePtr CreateSurfaceForImage(const wxImage& image)
35 {
36 wxCHECK_MSG( image.Ok(), NULL, _T("invalid image") );
37 // FIXME_DFB: implement alpha handling by merging alpha buffer with RGB
38 // into a temporary RGBA surface
39 wxCHECK_MSG( !image.HasAlpha(), NULL, _T("alpha channel not supported") );
40
41 DFBSurfaceDescription desc;
42 desc.flags = (DFBSurfaceDescriptionFlags)
43 (DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
44 DSDESC_PREALLOCATED);
45 desc.caps = DSCAPS_NONE;
46 desc.width = image.GetWidth();
47 desc.height = image.GetHeight();
48 desc.pixelformat = DSPF_RGB24;
49 desc.preallocated[0].data = image.GetData();
50 desc.preallocated[0].pitch = 3 * desc.width;
51
52 return wxIDirectFB::Get()->CreateSurface(&desc);
53 }
54
55 //-----------------------------------------------------------------------------
56 // wxBitmapRefData
57 //-----------------------------------------------------------------------------
58
59 class wxBitmapRefData: public wxObjectRefData
60 {
61 public:
62 wxBitmapRefData()
63 {
64 m_mask = NULL;
65 #if wxUSE_PALETTE
66 m_palette = NULL;
67 #endif
68 }
69
70 wxBitmapRefData(const wxBitmapRefData& data)
71 {
72 m_surface = data.m_surface ? data.m_surface->Clone() : NULL;
73
74 m_mask = data.m_mask ? new wxMask(*data.m_mask) : NULL;
75 #if wxUSE_PALETTE
76 m_palette = data.m_palette ? new wxPalette(*data.m_palette) : NULL;
77 #endif
78 }
79
80 virtual ~wxBitmapRefData()
81 {
82 delete m_mask;
83 #if wxUSE_PALETTE
84 delete m_palette;
85 #endif
86 }
87
88 wxIDirectFBSurfacePtr m_surface;
89 wxMask *m_mask;
90 #if wxUSE_PALETTE
91 wxPalette *m_palette;
92 #endif
93 };
94
95 #define M_BITMAP ((wxBitmapRefData *)m_refData)
96
97 //-----------------------------------------------------------------------------
98 // wxBitmap
99 //-----------------------------------------------------------------------------
100
101 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase)
102 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxBitmapBase)
103
104 wxBitmap::wxBitmap(int width, int height, int depth)
105 {
106 Create(width, height, depth);
107 }
108
109 bool wxBitmap::Create(const wxIDirectFBSurfacePtr& surface)
110 {
111 UnRef();
112
113 wxCHECK_MSG( surface, false, _T("invalid surface") );
114
115 m_refData = new wxBitmapRefData();
116 M_BITMAP->m_surface = surface;
117 return true;
118 }
119
120 bool wxBitmap::Create(int width, int height, int depth)
121 {
122 UnRef();
123
124 wxCHECK_MSG( width > 0 && height > 0, false, wxT("invalid bitmap size") );
125 wxCHECK_MSG( depth == -1, false, wxT("only default depth supported now") );
126
127 DFBSurfaceDescription desc;
128 desc.flags = (DFBSurfaceDescriptionFlags)(
129 DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT);
130 desc.caps = DSCAPS_NONE;
131 desc.width = width;
132 desc.height = height;
133
134 return Create(wxIDirectFB::Get()->CreateSurface(&desc));
135 }
136
137 #if wxUSE_IMAGE
138 wxBitmap::wxBitmap(const wxImage& image, int depth)
139 {
140 wxCHECK_RET( image.Ok(), wxT("invalid image") );
141
142 // create surface in screen's format:
143 if ( !Create(image.GetWidth(), image.GetHeight(), depth) )
144 return;
145
146 // then copy the image to it:
147 wxIDirectFBSurfacePtr src(CreateSurfaceForImage(image));
148 wxIDirectFBSurfacePtr dst = M_BITMAP->m_surface;
149
150 if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
151 return;
152 if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) )
153 return;
154
155 // FIXME: implement mask creation from image's mask (or alpha channel?)
156 wxASSERT_MSG( !image.HasMask(), _T("image masks are ignored for now") );
157 }
158
159 wxImage wxBitmap::ConvertToImage() const
160 {
161 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
162
163 wxImage img(GetWidth(), GetHeight());
164 wxIDirectFBSurfacePtr dst(CreateSurfaceForImage(img));
165 wxIDirectFBSurfacePtr src = M_BITMAP->m_surface;
166
167 if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
168 return wxNullImage;
169 if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) )
170 return wxNullImage;
171
172 // FIXME: implement mask setting in the image
173 wxASSERT_MSG( GetMask() == NULL, _T("bitmap masks are ignored for now") );
174
175 return img;
176 }
177 #endif // wxUSE_IMAGE
178
179 wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type)
180 {
181 LoadFile(filename, type);
182 }
183
184 wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
185 {
186 wxCHECK_RET( depth == 1, wxT("can only create mono bitmap from XBM data") );
187
188 wxFAIL_MSG( _T("not implemented") );
189 }
190
191 bool wxBitmap::IsOk() const
192 {
193 return (m_refData != NULL && M_BITMAP->m_surface);
194 }
195
196 int wxBitmap::GetHeight() const
197 {
198 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
199
200 int h = -1;
201 M_BITMAP->m_surface->GetSize(NULL, &h);
202 return h;
203 }
204
205 int wxBitmap::GetWidth() const
206 {
207 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
208
209 int w = -1;
210 M_BITMAP->m_surface->GetSize(&w, NULL);
211 return w;
212 }
213
214 int wxBitmap::GetDepth() const
215 {
216 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
217
218 return M_BITMAP->m_surface->GetDepth();
219 }
220
221 wxMask *wxBitmap::GetMask() const
222 {
223 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
224
225 return M_BITMAP->m_mask;
226 }
227
228 void wxBitmap::SetMask(wxMask *mask)
229 {
230 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
231
232 AllocExclusive();
233 delete M_BITMAP->m_mask;
234 M_BITMAP->m_mask = mask;
235 }
236
237 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
238 {
239 *this = *((wxBitmap*)(&icon));
240 return true;
241 }
242
243 wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
244 {
245 wxCHECK_MSG( Ok() &&
246 rect.x >= 0 && rect.y >= 0 &&
247 rect.x+rect.width <= GetWidth() &&
248 rect.y+rect.height <= GetHeight(),
249 wxNullBitmap,
250 wxT("invalid bitmap or bitmap region") );
251
252 // NB: DirectFB subsurfaces share the same pixels buffer, so we must
253 // clone the obtained subsurface
254 DFBRectangle r = { rect.x, rect.y, rect.width, rect.height };
255 return wxBitmap(M_BITMAP->m_surface->GetSubSurface(&r)->Clone());
256 }
257
258 #warning "to common code"
259 bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
260 {
261 UnRef();
262
263 wxBitmapHandler *handler = FindHandler(type);
264
265 if ( handler == NULL )
266 {
267 wxImage image;
268 if ( !image.LoadFile(name, type) || !image.Ok() )
269 {
270 wxLogError(_("No bitmap handler for type %d defined."), type);
271 return false;
272 }
273 else
274 {
275 *this = wxBitmap(image);
276 return true;
277 }
278 }
279
280 m_refData = new wxBitmapRefData();
281
282 return handler->LoadFile(this, name, type, -1, -1);
283 }
284
285 #warning "to common code"
286 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
287 {
288 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
289
290 wxBitmapHandler *handler = FindHandler(type);
291
292 if ( handler == NULL )
293 {
294 wxImage image = ConvertToImage();
295 #if wxUSE_PALETTE
296 if ( palette )
297 image.SetPalette(*palette);
298 #endif // wxUSE_PALETTE
299
300 if ( image.Ok() )
301 return image.SaveFile(filename, type);
302 else
303 {
304 wxLogError(_("No bitmap handler for type %d defined."), type);
305 return false;
306 }
307 }
308
309 return handler->SaveFile(this, filename, type, palette);
310 }
311
312 #if wxUSE_PALETTE
313 wxPalette *wxBitmap::GetPalette() const
314 {
315 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
316
317 return M_BITMAP->m_palette;
318 }
319
320 void wxBitmap::SetPalette(const wxPalette& palette)
321 {
322 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
323 wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
324
325 AllocExclusive();
326 delete M_BITMAP->m_palette;
327 M_BITMAP->m_palette = NULL;
328
329 if ( !palette.Ok() ) return;
330
331 M_BITMAP->m_palette = new wxPalette(palette);
332 }
333 #endif // wxUSE_PALETTE
334
335 void wxBitmap::SetHeight(int height)
336 {
337 AllocExclusive();
338
339 wxFAIL_MSG( _T("SetHeight not implemented") );
340 }
341
342 void wxBitmap::SetWidth(int width)
343 {
344 AllocExclusive();
345
346 wxFAIL_MSG( _T("SetWidth not implemented") );
347 }
348
349 void wxBitmap::SetDepth(int depth)
350 {
351 AllocExclusive();
352
353 wxFAIL_MSG( _T("SetDepth not implemented") );
354 }
355
356 wxIDirectFBSurfacePtr wxBitmap::GetDirectFBSurface() const
357 {
358 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
359
360 return M_BITMAP->m_surface;
361 }
362
363 wxObjectRefData *wxBitmap::CreateRefData() const
364 {
365 return new wxBitmapRefData;
366 }
367
368 wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *data) const
369 {
370 return new wxBitmapRefData(*(wxBitmapRefData *)data);
371 }
372
373
374 /*static*/
375 void wxBitmap::InitStandardHandlers()
376 {
377 // not wxBitmap handlers, we rely on wxImage
378 }