]>
Commit | Line | Data |
---|---|---|
b3c86150 VS |
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 | ||
b3c86150 VS |
27 | #include "wx/dfb/private.h" |
28 | ||
29 | //----------------------------------------------------------------------------- | |
30 | // helpers | |
31 | //----------------------------------------------------------------------------- | |
32 | ||
e2badebb VS |
33 | // NB: Most of this conversion code is needed because of differences between |
34 | // wxImage and wxDFB's wxBitmap representations: | |
35 | // (1) wxImage uses RGB order, while DirectFB uses BGR | |
36 | // (2) wxImage has alpha channel in a separate plane, while DirectFB puts | |
37 | // all components into single BGRA plane | |
38 | ||
b39fc8d7 | 39 | // pitch = stride = # of bytes between the start of N-th line and (N+1)-th line |
e2badebb VS |
40 | // {Src,Dst}PixSize = # of bytes used to represent one pixel |
41 | template<int SrcPixSize, int DstPixSize> | |
b39fc8d7 VS |
42 | static void CopyPixelsAndSwapRGB(unsigned w, unsigned h, |
43 | const unsigned char *src, | |
44 | unsigned src_pitch, | |
45 | unsigned char *dst, | |
46 | unsigned dst_pitch) | |
47 | { | |
e2badebb VS |
48 | unsigned src_advance = src_pitch - SrcPixSize * w; |
49 | unsigned dst_advance = dst_pitch - DstPixSize * w; | |
b39fc8d7 VS |
50 | for ( unsigned y = 0; y < h; y++, src += src_advance, dst += dst_advance ) |
51 | { | |
e2badebb | 52 | for ( unsigned x = 0; x < w; x++, src += SrcPixSize, dst += DstPixSize ) |
b39fc8d7 VS |
53 | { |
54 | // copy with RGB -> BGR translation: | |
55 | dst[0] = src[2]; | |
56 | dst[1] = src[1]; | |
57 | dst[2] = src[0]; | |
58 | } | |
59 | } | |
60 | } | |
61 | ||
62 | static void CopySurfaceToImage(const wxIDirectFBSurfacePtr& surface, | |
e2badebb | 63 | wxImage& image) |
b39fc8d7 | 64 | { |
b39fc8d7 VS |
65 | wxIDirectFBSurface::Locked locked(surface, DSLF_READ); |
66 | wxCHECK_RET( locked.ptr, _T("failed to lock surface") ); | |
67 | ||
e2badebb VS |
68 | const unsigned width = image.GetWidth(); |
69 | const unsigned height = image.GetHeight(); | |
70 | const DFBSurfacePixelFormat format = surface->GetPixelFormat(); | |
71 | ||
72 | // copy RGB data from the surface: | |
73 | switch ( format ) | |
74 | { | |
75 | case DSPF_RGB24: | |
76 | CopyPixelsAndSwapRGB<3,3> | |
77 | ( | |
78 | width, height, | |
79 | (unsigned char*)locked.ptr, locked.pitch, | |
80 | image.GetData(), width * 3 | |
81 | ); | |
82 | break; | |
83 | ||
84 | case DSPF_RGB32: | |
85 | case DSPF_ARGB: | |
86 | CopyPixelsAndSwapRGB<4,3> | |
87 | ( | |
88 | width, height, | |
89 | (unsigned char*)locked.ptr, locked.pitch, | |
90 | image.GetData(), width * 3 | |
91 | ); | |
92 | break; | |
93 | ||
94 | default: | |
95 | wxFAIL_MSG( "unexpected pixel format" ); | |
96 | return; | |
97 | } | |
98 | ||
99 | // extract alpha channel if the bitmap has it: | |
100 | if ( format == DSPF_ARGB ) | |
101 | { | |
102 | // create alpha plane: | |
103 | image.SetAlpha(); | |
104 | ||
105 | // and copy alpha data to it: | |
106 | const unsigned advance = locked.pitch - 4 * width; | |
107 | unsigned char *alpha = image.GetAlpha(); | |
108 | // NB: "+3" is to get pointer to alpha component | |
109 | const unsigned char *src = ((unsigned char*)locked.ptr) + 3; | |
110 | ||
111 | for ( unsigned y = 0; y < height; y++, src += advance ) | |
112 | for ( unsigned x = 0; x < width; x++, src += 4 ) | |
113 | *(alpha++) = *src; | |
114 | } | |
b39fc8d7 VS |
115 | } |
116 | ||
117 | static void CopyImageToSurface(const wxImage& image, | |
118 | const wxIDirectFBSurfacePtr& surface) | |
119 | { | |
b39fc8d7 | 120 | wxIDirectFBSurface::Locked locked(surface, DSLF_WRITE); |
e2badebb VS |
121 | wxCHECK_RET( locked.ptr, "failed to lock surface" ); |
122 | ||
123 | const unsigned width = image.GetWidth(); | |
124 | const unsigned height = image.GetHeight(); | |
125 | const DFBSurfacePixelFormat format = surface->GetPixelFormat(); | |
126 | ||
127 | // copy RGB data to the surface: | |
128 | switch ( format ) | |
129 | { | |
130 | case DSPF_RGB24: | |
131 | CopyPixelsAndSwapRGB<3,3> | |
132 | ( | |
133 | width, height, | |
134 | image.GetData(), width * 3, | |
135 | (unsigned char*)locked.ptr, locked.pitch | |
136 | ); | |
137 | break; | |
138 | ||
139 | case DSPF_RGB32: | |
140 | case DSPF_ARGB: | |
141 | CopyPixelsAndSwapRGB<3,4> | |
142 | ( | |
143 | width, height, | |
144 | image.GetData(), width * 3, | |
145 | (unsigned char*)locked.ptr, locked.pitch | |
146 | ); | |
147 | break; | |
148 | ||
149 | default: | |
150 | wxFAIL_MSG( "unexpected pixel format" ); | |
151 | return; | |
152 | } | |
153 | ||
154 | // if the image has alpha channel, merge it in: | |
155 | if ( format == DSPF_ARGB ) | |
156 | { | |
157 | wxCHECK_RET( image.HasAlpha(), "logic error - ARGB, but no alpha" ); | |
b39fc8d7 | 158 | |
e2badebb VS |
159 | const unsigned advance = locked.pitch - 4 * width; |
160 | const unsigned char *alpha = image.GetAlpha(); | |
161 | // NB: "+3" is to get pointer to alpha component | |
162 | unsigned char *dest = ((unsigned char*)locked.ptr) + 3; | |
163 | ||
164 | for ( unsigned y = 0; y < height; y++, dest += advance ) | |
165 | for ( unsigned x = 0; x < width; x++, dest += 4 ) | |
166 | *dest = *(alpha++); | |
167 | } | |
b39fc8d7 VS |
168 | } |
169 | ||
a46d4814 VS |
170 | // Creates a surface that will use wxImage's pixel data (RGB only) |
171 | static wxIDirectFBSurfacePtr CreateSurfaceForImage(const wxImage& image) | |
172 | { | |
173 | wxCHECK_MSG( image.Ok(), NULL, _T("invalid image") ); | |
174 | // FIXME_DFB: implement alpha handling by merging alpha buffer with RGB | |
175 | // into a temporary RGBA surface | |
176 | wxCHECK_MSG( !image.HasAlpha(), NULL, _T("alpha channel not supported") ); | |
177 | ||
b39fc8d7 VS |
178 | // NB: wxImage uses RGB order of bytes while DirectFB uses BGR, so we |
179 | // cannot use preallocated surface that shares data with wxImage, we | |
180 | // have to copy the data to temporary surface instead | |
a46d4814 VS |
181 | DFBSurfaceDescription desc; |
182 | desc.flags = (DFBSurfaceDescriptionFlags) | |
b39fc8d7 | 183 | (DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT); |
a46d4814 VS |
184 | desc.caps = DSCAPS_NONE; |
185 | desc.width = image.GetWidth(); | |
186 | desc.height = image.GetHeight(); | |
187 | desc.pixelformat = DSPF_RGB24; | |
a46d4814 VS |
188 | |
189 | return wxIDirectFB::Get()->CreateSurface(&desc); | |
190 | } | |
b3c86150 | 191 | |
b3c86150 VS |
192 | //----------------------------------------------------------------------------- |
193 | // wxBitmapRefData | |
194 | //----------------------------------------------------------------------------- | |
195 | ||
196 | class wxBitmapRefData: public wxObjectRefData | |
197 | { | |
198 | public: | |
199 | wxBitmapRefData() | |
200 | { | |
201 | m_mask = NULL; | |
202 | #if wxUSE_PALETTE | |
203 | m_palette = NULL; | |
204 | #endif | |
205 | } | |
206 | ||
207 | wxBitmapRefData(const wxBitmapRefData& data) | |
208 | { | |
2ee16da2 | 209 | m_surface = data.m_surface ? data.m_surface->Clone() : NULL; |
a5b31f4e | 210 | |
b3c86150 VS |
211 | m_mask = data.m_mask ? new wxMask(*data.m_mask) : NULL; |
212 | #if wxUSE_PALETTE | |
213 | m_palette = data.m_palette ? new wxPalette(*data.m_palette) : NULL; | |
214 | #endif | |
215 | } | |
216 | ||
2ee16da2 | 217 | virtual ~wxBitmapRefData() |
b3c86150 VS |
218 | { |
219 | delete m_mask; | |
220 | #if wxUSE_PALETTE | |
221 | delete m_palette; | |
222 | #endif | |
223 | } | |
224 | ||
52c8d32a VS |
225 | wxIDirectFBSurfacePtr m_surface; |
226 | wxMask *m_mask; | |
b3c86150 | 227 | #if wxUSE_PALETTE |
52c8d32a | 228 | wxPalette *m_palette; |
b3c86150 VS |
229 | #endif |
230 | }; | |
231 | ||
232 | #define M_BITMAP ((wxBitmapRefData *)m_refData) | |
233 | ||
234 | //----------------------------------------------------------------------------- | |
235 | // wxBitmap | |
236 | //----------------------------------------------------------------------------- | |
237 | ||
452418c4 | 238 | IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase) |
b3c86150 VS |
239 | IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxBitmapBase) |
240 | ||
241 | wxBitmap::wxBitmap(int width, int height, int depth) | |
242 | { | |
243 | Create(width, height, depth); | |
244 | } | |
245 | ||
4562386d VS |
246 | bool wxBitmap::Create(const wxIDirectFBSurfacePtr& surface) |
247 | { | |
248 | UnRef(); | |
249 | ||
250 | wxCHECK_MSG( surface, false, _T("invalid surface") ); | |
251 | ||
252 | m_refData = new wxBitmapRefData(); | |
253 | M_BITMAP->m_surface = surface; | |
254 | return true; | |
255 | } | |
256 | ||
b3c86150 | 257 | bool wxBitmap::Create(int width, int height, int depth) |
e2badebb VS |
258 | { |
259 | wxCHECK_MSG( depth == -1, false, wxT("only default depth supported now") ); | |
260 | ||
261 | return CreateWithFormat(width, height, -1); | |
262 | } | |
263 | ||
264 | bool wxBitmap::CreateWithFormat(int width, int height, int dfbFormat) | |
b3c86150 VS |
265 | { |
266 | UnRef(); | |
267 | ||
268 | wxCHECK_MSG( width > 0 && height > 0, false, wxT("invalid bitmap size") ); | |
269 | ||
270 | DFBSurfaceDescription desc; | |
271 | desc.flags = (DFBSurfaceDescriptionFlags)( | |
272 | DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT); | |
273 | desc.caps = DSCAPS_NONE; | |
274 | desc.width = width; | |
275 | desc.height = height; | |
276 | ||
e2badebb VS |
277 | if ( dfbFormat != -1 ) |
278 | { | |
279 | desc.flags = (DFBSurfaceDescriptionFlags)( | |
280 | desc.flags | DSDESC_PIXELFORMAT); | |
281 | desc.pixelformat = (DFBSurfacePixelFormat)dfbFormat; | |
282 | } | |
283 | ||
4562386d | 284 | return Create(wxIDirectFB::Get()->CreateSurface(&desc)); |
b3c86150 VS |
285 | } |
286 | ||
b3c86150 VS |
287 | #if wxUSE_IMAGE |
288 | wxBitmap::wxBitmap(const wxImage& image, int depth) | |
289 | { | |
290 | wxCHECK_RET( image.Ok(), wxT("invalid image") ); | |
e2badebb | 291 | wxCHECK_RET( depth == -1, wxT("only default depth supported now") ); |
a46d4814 | 292 | |
e2badebb VS |
293 | // create surface in screen's format (unless we need alpha channel, |
294 | // in which case use ARGB): | |
295 | if ( !CreateWithFormat(image.GetWidth(), image.GetHeight(), | |
296 | image.HasAlpha() ? DSPF_ARGB : -1) ) | |
a46d4814 VS |
297 | return; |
298 | ||
299 | // then copy the image to it: | |
a46d4814 VS |
300 | wxIDirectFBSurfacePtr dst = M_BITMAP->m_surface; |
301 | ||
e2badebb | 302 | switch ( dst->GetPixelFormat() ) |
b39fc8d7 | 303 | { |
e2badebb VS |
304 | case DSPF_RGB24: |
305 | case DSPF_RGB32: | |
306 | case DSPF_ARGB: | |
307 | CopyImageToSurface(image, dst); | |
308 | break; | |
b39fc8d7 | 309 | |
e2badebb VS |
310 | default: |
311 | { | |
312 | // wxBitmap uses different pixel format, so we have to use a | |
313 | // temporary surface and blit to the bitmap via it: | |
314 | wxIDirectFBSurfacePtr src(CreateSurfaceForImage(image)); | |
315 | CopyImageToSurface(image, src); | |
316 | ||
317 | if ( !dst->SetBlittingFlags(DSBLIT_NOFX) ) | |
318 | return; | |
319 | if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) ) | |
320 | return; | |
321 | } | |
b39fc8d7 | 322 | } |
a46d4814 VS |
323 | |
324 | // FIXME: implement mask creation from image's mask (or alpha channel?) | |
325 | wxASSERT_MSG( !image.HasMask(), _T("image masks are ignored for now") ); | |
b3c86150 VS |
326 | } |
327 | ||
328 | wxImage wxBitmap::ConvertToImage() const | |
329 | { | |
330 | wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") ); | |
331 | ||
a46d4814 | 332 | wxImage img(GetWidth(), GetHeight()); |
a46d4814 VS |
333 | wxIDirectFBSurfacePtr src = M_BITMAP->m_surface; |
334 | ||
e2badebb | 335 | switch ( src->GetPixelFormat() ) |
b39fc8d7 | 336 | { |
e2badebb VS |
337 | case DSPF_RGB24: |
338 | case DSPF_RGB32: | |
339 | case DSPF_ARGB: | |
340 | CopySurfaceToImage(src, img); | |
341 | break; | |
342 | default: | |
343 | { | |
344 | // wxBitmap uses different pixel format, so we have to use a | |
345 | // temporary surface and blit to the bitmap via it: | |
346 | wxIDirectFBSurfacePtr dst(CreateSurfaceForImage(img)); | |
b39fc8d7 | 347 | |
e2badebb VS |
348 | if ( !dst->SetBlittingFlags(DSBLIT_NOFX) ) |
349 | return wxNullImage; | |
350 | if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) ) | |
351 | return wxNullImage; | |
b39fc8d7 | 352 | |
e2badebb VS |
353 | CopySurfaceToImage(dst, img); |
354 | } | |
b39fc8d7 | 355 | } |
a46d4814 VS |
356 | |
357 | // FIXME: implement mask setting in the image | |
358 | wxASSERT_MSG( GetMask() == NULL, _T("bitmap masks are ignored for now") ); | |
359 | ||
360 | return img; | |
b3c86150 VS |
361 | } |
362 | #endif // wxUSE_IMAGE | |
363 | ||
364 | wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type) | |
365 | { | |
366 | LoadFile(filename, type); | |
367 | } | |
368 | ||
369 | wxBitmap::wxBitmap(const char bits[], int width, int height, int depth) | |
370 | { | |
371 | wxCHECK_RET( depth == 1, wxT("can only create mono bitmap from XBM data") ); | |
949e0a38 VS |
372 | |
373 | wxFAIL_MSG( _T("not implemented") ); | |
b3c86150 VS |
374 | } |
375 | ||
b7cacb43 | 376 | bool wxBitmap::IsOk() const |
b3c86150 VS |
377 | { |
378 | return (m_refData != NULL && M_BITMAP->m_surface); | |
379 | } | |
380 | ||
b3c86150 VS |
381 | int wxBitmap::GetHeight() const |
382 | { | |
383 | wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); | |
384 | ||
385 | int h = -1; | |
52c8d32a | 386 | M_BITMAP->m_surface->GetSize(NULL, &h); |
b3c86150 VS |
387 | return h; |
388 | } | |
389 | ||
390 | int wxBitmap::GetWidth() const | |
391 | { | |
392 | wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); | |
393 | ||
394 | int w = -1; | |
52c8d32a | 395 | M_BITMAP->m_surface->GetSize(&w, NULL); |
b3c86150 VS |
396 | return w; |
397 | } | |
398 | ||
399 | int wxBitmap::GetDepth() const | |
400 | { | |
401 | wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); | |
402 | ||
a5b31f4e | 403 | return M_BITMAP->m_surface->GetDepth(); |
b3c86150 VS |
404 | } |
405 | ||
406 | wxMask *wxBitmap::GetMask() const | |
407 | { | |
408 | wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); | |
409 | ||
410 | return M_BITMAP->m_mask; | |
411 | } | |
412 | ||
413 | void wxBitmap::SetMask(wxMask *mask) | |
414 | { | |
415 | wxCHECK_RET( Ok(), wxT("invalid bitmap") ); | |
416 | ||
55ccdb93 | 417 | AllocExclusive(); |
b3c86150 VS |
418 | delete M_BITMAP->m_mask; |
419 | M_BITMAP->m_mask = mask; | |
420 | } | |
421 | ||
422 | bool wxBitmap::CopyFromIcon(const wxIcon& icon) | |
423 | { | |
424 | *this = *((wxBitmap*)(&icon)); | |
425 | return true; | |
426 | } | |
427 | ||
428 | wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const | |
429 | { | |
430 | wxCHECK_MSG( Ok() && | |
431 | rect.x >= 0 && rect.y >= 0 && | |
432 | rect.x+rect.width <= GetWidth() && | |
433 | rect.y+rect.height <= GetHeight(), | |
434 | wxNullBitmap, | |
435 | wxT("invalid bitmap or bitmap region") ); | |
436 | ||
4562386d VS |
437 | // NB: DirectFB subsurfaces share the same pixels buffer, so we must |
438 | // clone the obtained subsurface | |
439 | DFBRectangle r = { rect.x, rect.y, rect.width, rect.height }; | |
440 | return wxBitmap(M_BITMAP->m_surface->GetSubSurface(&r)->Clone()); | |
b3c86150 VS |
441 | } |
442 | ||
443 | #warning "to common code" | |
444 | bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type) | |
445 | { | |
446 | UnRef(); | |
447 | ||
448 | wxBitmapHandler *handler = FindHandler(type); | |
449 | ||
450 | if ( handler == NULL ) | |
451 | { | |
452 | wxImage image; | |
453 | if ( !image.LoadFile(name, type) || !image.Ok() ) | |
454 | { | |
ec5006bd | 455 | wxLogError(_("No bitmap handler for type %d defined."), type); |
b3c86150 VS |
456 | return false; |
457 | } | |
458 | else | |
459 | { | |
460 | *this = wxBitmap(image); | |
461 | return true; | |
462 | } | |
463 | } | |
464 | ||
465 | m_refData = new wxBitmapRefData(); | |
466 | ||
467 | return handler->LoadFile(this, name, type, -1, -1); | |
468 | } | |
469 | ||
470 | #warning "to common code" | |
471 | bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const | |
472 | { | |
473 | wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") ); | |
474 | ||
475 | wxBitmapHandler *handler = FindHandler(type); | |
476 | ||
477 | if ( handler == NULL ) | |
478 | { | |
479 | wxImage image = ConvertToImage(); | |
480 | #if wxUSE_PALETTE | |
481 | if ( palette ) | |
482 | image.SetPalette(*palette); | |
483 | #endif // wxUSE_PALETTE | |
484 | ||
485 | if ( image.Ok() ) | |
486 | return image.SaveFile(filename, type); | |
487 | else | |
488 | { | |
ec5006bd | 489 | wxLogError(_("No bitmap handler for type %d defined."), type); |
b3c86150 VS |
490 | return false; |
491 | } | |
492 | } | |
493 | ||
494 | return handler->SaveFile(this, filename, type, palette); | |
495 | } | |
496 | ||
497 | #if wxUSE_PALETTE | |
498 | wxPalette *wxBitmap::GetPalette() const | |
499 | { | |
500 | wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); | |
501 | ||
502 | return M_BITMAP->m_palette; | |
503 | } | |
504 | ||
505 | void wxBitmap::SetPalette(const wxPalette& palette) | |
506 | { | |
507 | wxCHECK_RET( Ok(), wxT("invalid bitmap") ); | |
508 | wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") ); | |
509 | ||
55ccdb93 | 510 | AllocExclusive(); |
b3c86150 VS |
511 | delete M_BITMAP->m_palette; |
512 | M_BITMAP->m_palette = NULL; | |
513 | ||
514 | if ( !palette.Ok() ) return; | |
515 | ||
516 | M_BITMAP->m_palette = new wxPalette(palette); | |
517 | } | |
518 | #endif // wxUSE_PALETTE | |
519 | ||
520 | void wxBitmap::SetHeight(int height) | |
521 | { | |
522 | AllocExclusive(); | |
3278b06e VS |
523 | |
524 | wxFAIL_MSG( _T("SetHeight not implemented") ); | |
b3c86150 VS |
525 | } |
526 | ||
527 | void wxBitmap::SetWidth(int width) | |
528 | { | |
529 | AllocExclusive(); | |
3278b06e VS |
530 | |
531 | wxFAIL_MSG( _T("SetWidth not implemented") ); | |
b3c86150 VS |
532 | } |
533 | ||
534 | void wxBitmap::SetDepth(int depth) | |
535 | { | |
536 | AllocExclusive(); | |
3278b06e VS |
537 | |
538 | wxFAIL_MSG( _T("SetDepth not implemented") ); | |
b3c86150 VS |
539 | } |
540 | ||
52c8d32a | 541 | wxIDirectFBSurfacePtr wxBitmap::GetDirectFBSurface() const |
b3c86150 VS |
542 | { |
543 | wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); | |
544 | ||
545 | return M_BITMAP->m_surface; | |
546 | } | |
547 | ||
548 | wxObjectRefData *wxBitmap::CreateRefData() const | |
549 | { | |
550 | return new wxBitmapRefData; | |
551 | } | |
552 | ||
553 | wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *data) const | |
554 | { | |
555 | return new wxBitmapRefData(*(wxBitmapRefData *)data); | |
556 | } | |
557 | ||
558 | ||
559 | /*static*/ | |
560 | void wxBitmap::InitStandardHandlers() | |
561 | { | |
562 | // not wxBitmap handlers, we rely on wxImage | |
563 | } |