Remove all lines containing cvs/svn "$Id$" keyword.
[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 // Copyright: (c) 2006 REA Elektronik GmbH
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16
17 #ifndef WX_PRECOMP
18 #include "wx/app.h"
19 #include "wx/log.h"
20 #endif
21
22 #include "wx/bitmap.h"
23 #include "wx/colour.h"
24 #include "wx/image.h"
25 #include "wx/rawbmp.h"
26
27 #include "wx/dfb/private.h"
28
29 //-----------------------------------------------------------------------------
30 // helpers for translating between wx and DFB pixel formats
31 //-----------------------------------------------------------------------------
32
33 namespace
34 {
35
36 // NB: Most of this conversion code is needed because of differences between
37 // wxImage and wxDFB's wxBitmap representations:
38 // (1) wxImage uses RGB order, while DirectFB uses BGR
39 // (2) wxImage has alpha channel in a separate plane, while DirectFB puts
40 // all components into single BGRA plane
41
42 // pitch = stride = # of bytes between the start of N-th line and (N+1)-th line
43 // {Src,Dst}PixSize = # of bytes used to represent one pixel
44 template<int SrcPixSize, int DstPixSize>
45 void CopyPixelsAndSwapRGB(unsigned w, unsigned h,
46 const unsigned char *src,
47 unsigned src_pitch,
48 unsigned char *dst,
49 unsigned dst_pitch)
50 {
51 unsigned src_advance = src_pitch - SrcPixSize * w;
52 unsigned dst_advance = dst_pitch - DstPixSize * w;
53 for ( unsigned y = 0; y < h; y++, src += src_advance, dst += dst_advance )
54 {
55 for ( unsigned x = 0; x < w; x++, src += SrcPixSize, dst += DstPixSize )
56 {
57 // copy with RGB -> BGR translation:
58 dst[0] = src[2];
59 dst[1] = src[1];
60 dst[2] = src[0];
61 }
62 }
63 }
64
65 void CopySurfaceToImage(const wxIDirectFBSurfacePtr& surface, wxImage& image)
66 {
67 wxIDirectFBSurface::Locked locked(surface, DSLF_READ);
68 wxCHECK_RET( locked.ptr, "failed to lock surface" );
69
70 const unsigned width = image.GetWidth();
71 const unsigned height = image.GetHeight();
72 const DFBSurfacePixelFormat format = surface->GetPixelFormat();
73
74 // copy RGB data from the surface:
75 switch ( format )
76 {
77 case DSPF_RGB24:
78 CopyPixelsAndSwapRGB<3,3>
79 (
80 width, height,
81 (unsigned char*)locked.ptr, locked.pitch,
82 image.GetData(), width * 3
83 );
84 break;
85
86 case DSPF_RGB32:
87 case DSPF_ARGB:
88 CopyPixelsAndSwapRGB<4,3>
89 (
90 width, height,
91 (unsigned char*)locked.ptr, locked.pitch,
92 image.GetData(), width * 3
93 );
94 break;
95
96 default:
97 wxFAIL_MSG( "unexpected pixel format" );
98 return;
99 }
100
101 // extract alpha channel if the bitmap has it:
102 if ( format == DSPF_ARGB )
103 {
104 // create alpha plane:
105 image.SetAlpha();
106
107 // and copy alpha data to it:
108 const unsigned advance = locked.pitch - 4 * width;
109 unsigned char *alpha = image.GetAlpha();
110 // NB: "+3" is to get pointer to alpha component
111 const unsigned char *src = ((unsigned char*)locked.ptr) + 3;
112
113 for ( unsigned y = 0; y < height; y++, src += advance )
114 for ( unsigned x = 0; x < width; x++, src += 4 )
115 *(alpha++) = *src;
116 }
117 }
118
119 void CopyImageToSurface(const wxImage& image,
120 const wxIDirectFBSurfacePtr& surface)
121 {
122 wxIDirectFBSurface::Locked locked(surface, DSLF_WRITE);
123 wxCHECK_RET( locked.ptr, "failed to lock surface" );
124
125 const unsigned width = image.GetWidth();
126 const unsigned height = image.GetHeight();
127 const DFBSurfacePixelFormat format = surface->GetPixelFormat();
128
129 // copy RGB data to the surface:
130 switch ( format )
131 {
132 case DSPF_RGB24:
133 CopyPixelsAndSwapRGB<3,3>
134 (
135 width, height,
136 image.GetData(), width * 3,
137 (unsigned char*)locked.ptr, locked.pitch
138 );
139 break;
140
141 case DSPF_RGB32:
142 case DSPF_ARGB:
143 CopyPixelsAndSwapRGB<3,4>
144 (
145 width, height,
146 image.GetData(), width * 3,
147 (unsigned char*)locked.ptr, locked.pitch
148 );
149 break;
150
151 default:
152 wxFAIL_MSG( "unexpected pixel format" );
153 return;
154 }
155
156 // if the image has alpha channel, merge it in:
157 if ( format == DSPF_ARGB )
158 {
159 wxCHECK_RET( image.HasAlpha(), "logic error - ARGB, but no alpha" );
160
161 const unsigned advance = locked.pitch - 4 * width;
162 const unsigned char *alpha = image.GetAlpha();
163 // NB: "+3" is to get pointer to alpha component
164 unsigned char *dest = ((unsigned char*)locked.ptr) + 3;
165
166 for ( unsigned y = 0; y < height; y++, dest += advance )
167 for ( unsigned x = 0; x < width; x++, dest += 4 )
168 *dest = *(alpha++);
169 }
170 }
171
172 wxIDirectFBSurfacePtr
173 CreateSurfaceWithFormat(int w, int h, DFBSurfacePixelFormat format)
174 {
175 DFBSurfaceDescription desc;
176 desc.flags = (DFBSurfaceDescriptionFlags)
177 (DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT);
178 desc.caps = DSCAPS_NONE;
179 desc.width = w;
180 desc.height = h;
181
182 if ( format != DSPF_UNKNOWN )
183 {
184 desc.flags = (DFBSurfaceDescriptionFlags)(
185 desc.flags | DSDESC_PIXELFORMAT);
186 desc.pixelformat = format;
187 }
188
189 return wxIDirectFB::Get()->CreateSurface(&desc);
190 }
191
192 // Creates a surface that will use wxImage's pixel data (RGB only)
193 wxIDirectFBSurfacePtr CreateSurfaceForImage(const wxImage& image)
194 {
195 wxCHECK_MSG( image.IsOk(), NULL, "invalid image" );
196 // FIXME_DFB: implement alpha handling by merging alpha buffer with RGB
197 // into a temporary RGBA surface
198 wxCHECK_MSG( !image.HasAlpha(), NULL, "alpha channel not supported" );
199
200 // NB: wxImage uses RGB order of bytes while DirectFB uses BGR, so we
201 // cannot use preallocated surface that shares data with wxImage, we
202 // have to copy the data to temporary surface instead
203 return CreateSurfaceWithFormat(image.GetWidth(), image.GetHeight(),
204 DSPF_RGB24);
205 }
206
207 bool ConvertSurfaceToFormat(wxIDirectFBSurfacePtr& surface,
208 DFBSurfacePixelFormat format)
209 {
210 if ( surface->GetPixelFormat() == format )
211 return true;
212
213 int w, h;
214 surface->GetSize(&w, &h);
215 wxIDirectFBSurfacePtr s = CreateSurfaceWithFormat(w, h, format);
216 if ( !s )
217 return false;
218
219 if ( !s->SetBlittingFlags(DSBLIT_NOFX) )
220 return false;
221 if ( !s->Blit(surface->GetRaw(), NULL, 0, 0) )
222 return false;
223
224 surface = s;
225 return true;
226 }
227
228 DFBSurfacePixelFormat DepthToFormat(int depth)
229 {
230 switch ( depth )
231 {
232 case 24:
233 return DSPF_RGB24;
234 case 32:
235 // NB: we treat depth=32 as requesting ARGB for consistency with
236 // other ports
237 return DSPF_ARGB;
238 default:
239 wxFAIL_MSG( "unsupported depth requested" );
240 // fall through
241 case -1:
242 return DSPF_UNKNOWN;
243 }
244 }
245
246 // ----------------------------------------------------------------------------
247 // monochrome bitmap functions
248 // ----------------------------------------------------------------------------
249
250 // this function works with destination buffer of type T and not char (where T
251 // is typically wxUint32 for RGB32, wxUint16 for RGB16 &c) as we don't need
252 // access to the individual pixel components -- and so it's not suitable for
253 // the pixel formats with pixel size not equal to 8, 16 or 32
254 template <typename T, int White, int Black>
255 void
256 CopyBits(int width,
257 int height,
258 const unsigned char *src,
259 const wxIDirectFBSurface::Locked locked)
260 {
261 static const int BITS_PER_BYTE = 8;
262
263 // extra padding to add to dst at the end of each row: this works on the
264 // assumption that all rows are aligned at multiples of T (and usually 4
265 // bytes) boundary so check for it (and change the code if this assert is
266 // ever triggered)
267 wxASSERT_MSG( !(locked.pitch % sizeof(T)), "image rows not aligned?" );
268 const int padDst = (locked.pitch - width*sizeof(T))/sizeof(T);
269
270 int x = 0; // position in the current bitmap row
271
272 // a single char in src corresponds to 8 destination pixels and the last
273 // char in the row contains padding if necessary, i.e. there is always an
274 // integer number of chars per row
275 const unsigned char * const
276 srcEnd = src + ((width + BITS_PER_BYTE - 1)/BITS_PER_BYTE)*height;
277
278 // we operate with sizeof(T), not 1, bytes at once
279 T *dst = static_cast<T *>(locked.ptr);
280 while ( src < srcEnd )
281 {
282 unsigned char val = *src++;
283
284 for ( int bit = 0; bit < BITS_PER_BYTE; bit++ )
285 {
286 *dst++ = val & 1 ? White : Black;
287 val >>= 1;
288 if ( ++x == width )
289 {
290 dst += padDst;
291 x = 0;
292 break;
293 }
294 }
295 }
296 }
297
298 bool
299 CopyBitsToSurface(const unsigned char *bits,
300 int width,
301 int height,
302 wxIDirectFBSurfacePtr& surface)
303 {
304 wxIDirectFBSurface::Locked locked(surface, DSLF_WRITE);
305 wxCHECK_MSG( locked.ptr, false, "failed to lock surface" );
306
307 const DFBSurfacePixelFormat format = surface->GetPixelFormat();
308
309 switch ( format )
310 {
311 case DSPF_LUT8:
312 // we suppose that these indices correspond to the palette entries
313 // for white and black, respectively, but a better idea would be to
314 // use IDirectFBPalette::FindBestMatch() to determine them
315 CopyBits<wxUint8, 0xff, 0>(width, height, bits, locked);
316 break;
317
318 case DSPF_RGB16:
319 CopyBits<wxUint16, 0xffff, 0>(width, height, bits, locked);
320 break;
321
322 case DSPF_RGB32:
323 CopyBits<wxUint32, 0xffffffff, 0>(width, height, bits, locked);
324 break;
325
326 default:
327 // we don't really have time to implement efficient support for all
328 // the other formats so simply (and awfully slowly, of course...)
329 // convert everything else from RGB32
330 surface = CreateSurfaceWithFormat(width, height, DSPF_RGB32);
331 if ( !surface )
332 return false;
333
334 if ( !CopyBitsToSurface(bits, width, height, surface) )
335 return false;
336
337 if ( !ConvertSurfaceToFormat(surface, format) )
338 return false;
339 }
340
341 return true;
342 }
343
344 } // anonymous namespace
345
346 //-----------------------------------------------------------------------------
347 // wxBitmapRefData
348 //-----------------------------------------------------------------------------
349
350 class wxBitmapRefData: public wxGDIRefData
351 {
352 public:
353 wxBitmapRefData()
354 {
355 m_mask = NULL;
356 #if wxUSE_PALETTE
357 m_palette = NULL;
358 #endif
359 }
360
361 wxBitmapRefData(const wxBitmapRefData& data)
362 {
363 m_surface = data.m_surface ? data.m_surface->Clone() : NULL;
364
365 m_mask = data.m_mask ? new wxMask(*data.m_mask) : NULL;
366 #if wxUSE_PALETTE
367 m_palette = data.m_palette ? new wxPalette(*data.m_palette) : NULL;
368 #endif
369 }
370
371 virtual ~wxBitmapRefData()
372 {
373 delete m_mask;
374 #if wxUSE_PALETTE
375 delete m_palette;
376 #endif
377 }
378
379 virtual bool IsOk() const { return m_surface; }
380
381 wxIDirectFBSurfacePtr m_surface;
382 wxMask *m_mask;
383 #if wxUSE_PALETTE
384 wxPalette *m_palette;
385 #endif
386 };
387
388 #define M_BITMAP ((wxBitmapRefData *)m_refData)
389
390 //-----------------------------------------------------------------------------
391 // wxBitmap
392 //-----------------------------------------------------------------------------
393
394 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxBitmapBase)
395
396 bool wxBitmap::Create(const wxIDirectFBSurfacePtr& surface)
397 {
398 UnRef();
399
400 wxCHECK_MSG( surface, false, "invalid surface" );
401
402 m_refData = new wxBitmapRefData();
403 M_BITMAP->m_surface = surface;
404 return true;
405 }
406
407 bool wxBitmap::Create(int width, int height, int depth)
408 {
409 return CreateWithFormat(width, height, DepthToFormat(depth));
410 }
411
412 bool wxBitmap::CreateWithFormat(int width, int height, int dfbFormat)
413 {
414 UnRef();
415
416 wxCHECK_MSG( width > 0 && height > 0, false, wxT("invalid bitmap size") );
417
418 return Create(CreateSurfaceWithFormat(width, height,
419 DFBSurfacePixelFormat(dfbFormat)));
420 }
421
422 #if wxUSE_IMAGE
423 wxBitmap::wxBitmap(const wxImage& imageOrig, int depth)
424 {
425 wxCHECK_RET( imageOrig.IsOk(), wxT("invalid image") );
426
427 wxImage image(imageOrig);
428
429 // convert mask to alpha channel, because wxMask isn't implemented yet
430 // FIXME: don't do this, implement proper wxMask support
431 if ( image.HasMask() )
432 image.InitAlpha();
433
434 DFBSurfacePixelFormat format = DepthToFormat(depth);
435 if ( format == DSPF_UNKNOWN && image.HasAlpha() )
436 format = DSPF_ARGB;
437
438 // create surface in screen's format (unless we need alpha channel,
439 // in which case use ARGB):
440 if ( !CreateWithFormat(image.GetWidth(), image.GetHeight(), format) )
441 return;
442
443 // then copy the image to it:
444 wxIDirectFBSurfacePtr dst = M_BITMAP->m_surface;
445
446 switch ( dst->GetPixelFormat() )
447 {
448 case DSPF_RGB24:
449 case DSPF_RGB32:
450 case DSPF_ARGB:
451 CopyImageToSurface(image, dst);
452 break;
453
454 default:
455 {
456 // wxBitmap uses different pixel format, so we have to use a
457 // temporary surface and blit to the bitmap via it:
458 wxIDirectFBSurfacePtr src(CreateSurfaceForImage(image));
459 CopyImageToSurface(image, src);
460
461 if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
462 return;
463 if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) )
464 return;
465 }
466 }
467 }
468
469 wxImage wxBitmap::ConvertToImage() const
470 {
471 wxCHECK_MSG( IsOk(), wxNullImage, wxT("invalid bitmap") );
472
473 wxImage img(GetWidth(), GetHeight());
474 wxIDirectFBSurfacePtr src = M_BITMAP->m_surface;
475
476 switch ( src->GetPixelFormat() )
477 {
478 case DSPF_RGB24:
479 case DSPF_RGB32:
480 case DSPF_ARGB:
481 CopySurfaceToImage(src, img);
482 break;
483 default:
484 {
485 // wxBitmap uses different pixel format, so we have to use a
486 // temporary surface and blit to the bitmap via it:
487 wxIDirectFBSurfacePtr dst(CreateSurfaceForImage(img));
488
489 if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
490 return wxNullImage;
491 if ( !dst->Blit(src->GetRaw(), NULL, 0, 0) )
492 return wxNullImage;
493
494 CopySurfaceToImage(dst, img);
495 }
496 }
497
498 // FIXME: implement mask setting in the image
499 wxASSERT_MSG( GetMask() == NULL, "bitmap masks are ignored for now" );
500
501 return img;
502 }
503 #endif // wxUSE_IMAGE
504
505 void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
506 {
507 wxCHECK_MSG( IsOk(), NULL, "invalid bitmap" );
508
509 AllocExclusive();
510
511 DFBSurfacePixelFormat format;
512 if ( bpp == 32 )
513 format = DSPF_ARGB;
514 else
515 format = DSPF_RGB24;
516
517 // convert the bitmap into format compatible with requested raw access;
518 // note that we don't bother converting the bitmap back in UngetRawData(),
519 // as unpacked formats (RGB24, RGB32) are the common case and converting
520 // between them while blitting is fast enough (FIXME?)
521 if ( !ConvertSurfaceToFormat(M_BITMAP->m_surface, format) )
522 return NULL;
523
524 void *bits = NULL;
525 if ( !M_BITMAP->m_surface->Lock
526 (
527 (DFBSurfaceLockFlags)(DSLF_READ | DSLF_WRITE),
528 &bits,
529 &data.m_stride
530 ) )
531 return NULL;
532
533 M_BITMAP->m_surface->GetSize(&data.m_width, &data.m_height);
534
535 return bits;
536 }
537
538 void wxBitmap::UngetRawData(wxPixelDataBase& WXUNUSED(data))
539 {
540 M_BITMAP->m_surface->Unlock();
541 }
542
543 bool wxBitmap::HasAlpha() const
544 {
545 wxCHECK_MSG( IsOk(), false, "invalid bitmap" );
546
547 return M_BITMAP->m_surface->GetPixelFormat() == DSPF_ARGB;
548 }
549
550 wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type)
551 {
552 LoadFile(filename, type);
553 }
554
555 wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
556 {
557 wxCHECK_RET( depth == 1, wxT("can only create mono bitmap from XBM data") );
558
559 // create bitmap in the device-dependent format
560 if ( !CreateWithFormat(width, height, DSPF_UNKNOWN) )
561 return;
562
563 if ( !CopyBitsToSurface((const unsigned char *)bits,
564 width, height, M_BITMAP->m_surface) )
565 UnRef();
566 }
567
568 int wxBitmap::GetHeight() const
569 {
570 wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
571
572 int h = -1;
573 M_BITMAP->m_surface->GetSize(NULL, &h);
574 return h;
575 }
576
577 int wxBitmap::GetWidth() const
578 {
579 wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
580
581 int w = -1;
582 M_BITMAP->m_surface->GetSize(&w, NULL);
583 return w;
584 }
585
586 int wxBitmap::GetDepth() const
587 {
588 wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
589
590 return M_BITMAP->m_surface->GetDepth();
591 }
592
593 wxMask *wxBitmap::GetMask() const
594 {
595 wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
596
597 return M_BITMAP->m_mask;
598 }
599
600 void wxBitmap::SetMask(wxMask *mask)
601 {
602 wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
603
604 AllocExclusive();
605 delete M_BITMAP->m_mask;
606 M_BITMAP->m_mask = mask;
607 }
608
609 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
610 {
611 *this = *((wxBitmap*)(&icon));
612 return true;
613 }
614
615 wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
616 {
617 wxCHECK_MSG( IsOk() &&
618 rect.x >= 0 && rect.y >= 0 &&
619 rect.x+rect.width <= GetWidth() &&
620 rect.y+rect.height <= GetHeight(),
621 wxNullBitmap,
622 wxT("invalid bitmap or bitmap region") );
623
624 // NB: DirectFB subsurfaces share the same pixels buffer, so we must
625 // clone the obtained subsurface
626 DFBRectangle r = { rect.x, rect.y, rect.width, rect.height };
627 return wxBitmap(M_BITMAP->m_surface->GetSubSurface(&r)->Clone());
628 }
629
630 #warning "to common code"
631 bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
632 {
633 UnRef();
634
635 wxBitmapHandler *handler = FindHandler(type);
636
637 if ( handler == NULL )
638 {
639 wxImage image;
640 if ( !image.LoadFile(name, type) || !image.IsOk() )
641 {
642 wxLogError(_("No bitmap handler for type %d defined."), type);
643 return false;
644 }
645 else
646 {
647 *this = wxBitmap(image);
648 return true;
649 }
650 }
651
652 m_refData = new wxBitmapRefData();
653
654 return handler->LoadFile(this, name, type, -1, -1);
655 }
656
657 #warning "to common code"
658 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
659 {
660 wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") );
661
662 wxBitmapHandler *handler = FindHandler(type);
663
664 if ( handler == NULL )
665 {
666 wxImage image = ConvertToImage();
667 #if wxUSE_PALETTE
668 if ( palette )
669 image.SetPalette(*palette);
670 #endif // wxUSE_PALETTE
671
672 if ( image.IsOk() )
673 return image.SaveFile(filename, type);
674 else
675 {
676 wxLogError(_("No bitmap handler for type %d defined."), type);
677 return false;
678 }
679 }
680
681 return handler->SaveFile(this, filename, type, palette);
682 }
683
684 #if wxUSE_PALETTE
685 wxPalette *wxBitmap::GetPalette() const
686 {
687 wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
688
689 return M_BITMAP->m_palette;
690 }
691
692 void wxBitmap::SetPalette(const wxPalette& palette)
693 {
694 wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
695 wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
696
697 AllocExclusive();
698 wxDELETE(M_BITMAP->m_palette);
699
700 if ( !palette.IsOk() ) return;
701
702 M_BITMAP->m_palette = new wxPalette(palette);
703 }
704 #endif // wxUSE_PALETTE
705
706 void wxBitmap::SetHeight(int height)
707 {
708 AllocExclusive();
709
710 wxFAIL_MSG( "SetHeight not implemented" );
711 }
712
713 void wxBitmap::SetWidth(int width)
714 {
715 AllocExclusive();
716
717 wxFAIL_MSG( "SetWidth not implemented" );
718 }
719
720 void wxBitmap::SetDepth(int depth)
721 {
722 DFBSurfacePixelFormat format = DepthToFormat(depth);
723 if ( M_BITMAP->m_surface->GetPixelFormat() == format )
724 return;
725
726 AllocExclusive();
727
728 int w, h;
729 M_BITMAP->m_surface->GetSize(&w, &h);
730 wxIDirectFBSurfacePtr s = CreateSurfaceWithFormat(w, h, format);
731 if ( !s )
732 return;
733 if ( !s->SetBlittingFlags(DSBLIT_NOFX) )
734 return;
735 if ( !s->Blit(M_BITMAP->m_surface->GetRaw(), NULL, 0, 0) )
736 return;
737
738 M_BITMAP->m_surface = s;
739 }
740
741 wxIDirectFBSurfacePtr wxBitmap::GetDirectFBSurface() const
742 {
743 wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
744
745 return M_BITMAP->m_surface;
746 }
747
748 wxGDIRefData *wxBitmap::CreateGDIRefData() const
749 {
750 return new wxBitmapRefData;
751 }
752
753 wxGDIRefData *wxBitmap::CloneGDIRefData(const wxGDIRefData *data) const
754 {
755 return new wxBitmapRefData(*(wxBitmapRefData *)data);
756 }
757
758
759 /*static*/
760 void wxBitmap::InitStandardHandlers()
761 {
762 // not wxBitmap handlers, we rely on wxImage
763 }