1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/dataobj.cpp
3 // Purpose: implementation of wxDataObject class
4 // Author: Stefan Csomor
7 // Copyright: (c) 1999 Stefan Csomor
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
16 #include "wx/dataobj.h"
21 #include "wx/dcmemory.h"
25 #include "wx/mstream.h"
26 #include "wx/metafile.h"
27 #include "wx/tokenzr.h"
28 #include "wx/filename.h"
30 #include "wx/osx/private.h"
32 #if wxOSX_USE_COCOA_OR_CARBON
33 #include <QuickTime/QuickTime.h>
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 wxDataFormat::wxDataFormat()
42 m_type
= wxDF_INVALID
;
46 wxDataFormat::wxDataFormat( wxDataFormatId vType
)
49 m_type
= wxDF_INVALID
;
53 wxDataFormat::wxDataFormat( const wxChar
*zId
)
56 m_type
= wxDF_INVALID
;
60 wxDataFormat::wxDataFormat( const wxString
& rId
)
63 m_type
= wxDF_INVALID
;
67 wxDataFormat::wxDataFormat(const wxDataFormat
& rFormat
)
69 if ( rFormat
.m_format
)
70 m_format
= (NativeFormat
) CFStringCreateCopy(NULL
, (CFStringRef
)rFormat
.m_format
);
73 m_type
= rFormat
.m_type
;
77 wxDataFormat::wxDataFormat( NativeFormat vFormat
)
80 m_type
= wxDF_INVALID
;
84 wxDataFormat::~wxDataFormat()
88 CFRelease( (CFStringRef
) m_format
);
93 // in order to be correct for 10.3 we restrict to the available types there
94 // http://developer.apple.com/qa/qa2005/qa1406.html
95 // TODO : Use UTCoreTypes.h constants once we support 10.4+ only
97 wxDataFormat
& wxDataFormat::operator=(const wxDataFormat
& rFormat
)
101 CFRelease( (CFStringRef
) m_format
);
104 if ( rFormat
.m_format
)
105 m_format
= (NativeFormat
) CFStringCreateCopy(NULL
, (CFStringRef
)rFormat
.m_format
);
106 m_type
= rFormat
.m_type
;
111 void wxDataFormat::SetType( wxDataFormatId dataType
)
116 CFRelease( (CFStringRef
) m_format
);
123 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypePlainText
);
126 case wxDF_UNICODETEXT
:
127 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypeUTF16PlainText
);
131 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypeHTML
);
135 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypeTIFF
);
138 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypePDF
);
142 m_format
= (long) CFStringCreateCopy( NULL
, kUTTypeFileURL
);
146 wxFAIL_MSG( wxT("invalid data format") );
151 wxString
wxDataFormat::GetId() const
153 return wxCFStringRef(wxCFRetain((CFStringRef
)m_format
)).AsString();
156 void wxDataFormat::SetId( NativeFormat format
)
160 CFRelease( (CFStringRef
) m_format
);
163 m_format
= (NativeFormat
) CFStringCreateCopy(NULL
, (CFStringRef
)format
);
164 if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypeHTML
) )
168 if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypeUTF16PlainText
) )
170 m_type
= wxDF_UNICODETEXT
;
172 else if ( UTTypeConformsTo( (CFStringRef
)format
,kUTTypeUTF16ExternalPlainText
) )
174 m_type
= wxDF_UNICODETEXT
;
176 else if ( UTTypeConformsTo( (CFStringRef
)format
,kUTTypeUTF8PlainText
) )
178 m_type
= wxDF_UNICODETEXT
;
180 else if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypePlainText
) )
184 else if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypeImage
) )
186 m_type
= wxDF_BITMAP
;
188 else if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypePDF
) )
190 m_type
= wxDF_METAFILE
;
192 else if ( UTTypeConformsTo( (CFStringRef
)format
, kUTTypeFileURL
) ||
193 UTTypeConformsTo( (CFStringRef
)format
, kPasteboardTypeFileURLPromise
))
195 m_type
= wxDF_FILENAME
;
199 m_type
= wxDF_PRIVATE
;
200 m_id
= wxCFStringRef( (CFStringRef
) CFRetain((CFStringRef
) format
)).AsString();
204 void wxDataFormat::SetId( const wxString
& zId
)
206 m_type
= wxDF_PRIVATE
;
210 CFRelease( (CFStringRef
) m_format
);
213 // since it is private, no need to conform to anything ...
214 m_format
= (long) wxCFRetain( (CFStringRef
) wxCFStringRef(m_id
) );
217 bool wxDataFormat::operator==(const wxDataFormat
& format
) const
219 if (IsStandard() || format
.IsStandard())
220 return (format
.m_type
== m_type
);
222 return ( UTTypeConformsTo( (CFStringRef
) m_format
, (CFStringRef
) format
.m_format
) );
225 //-------------------------------------------------------------------------
227 //-------------------------------------------------------------------------
229 wxDataObject::wxDataObject()
233 bool wxDataObject::IsSupportedFormat( const wxDataFormat
& rFormat
, Direction vDir
) const
235 size_t nFormatCount
= GetFormatCount( vDir
);
238 if (nFormatCount
== 1)
240 found
= (rFormat
== GetPreferredFormat());
244 wxDataFormat
*pFormats
= new wxDataFormat
[nFormatCount
];
245 GetAllFormats( pFormats
, vDir
);
247 for (size_t n
= 0; n
< nFormatCount
; n
++)
249 if (pFormats
[n
] == rFormat
)
262 void wxDataObject::AddToPasteboard( void * pb
, wxIntPtr itemID
)
264 PasteboardRef pasteboard
= (PasteboardRef
) pb
;
265 // get formats from wxDataObjects
266 wxDataFormat
*array
= new wxDataFormat
[ GetFormatCount() ];
267 GetAllFormats( array
);
269 for (size_t i
= 0; i
< GetFormatCount(); i
++)
271 wxDataFormat thisFormat
= array
[ i
];
273 // add four bytes at the end for data objs like text that
274 // have a datasize = strlen but still need a buffer for the
275 // string including trailing zero
277 size_t datasize
= GetDataSize( thisFormat
);
278 if ( datasize
== wxCONV_FAILED
&& thisFormat
.GetType() == wxDF_TEXT
)
280 // conversion to local text failed, so we must use unicode
281 // if wxDF_UNICODETEXT is already on the 'todo' list, skip this iteration
282 // otherwise force it
284 for (j
= 0; j
< GetFormatCount(); j
++)
286 if ( array
[j
].GetType() == wxDF_UNICODETEXT
)
289 if ( j
< GetFormatCount() )
292 thisFormat
.SetType(wxDF_UNICODETEXT
);
293 datasize
= GetDataSize( thisFormat
);
296 size_t sz
= datasize
+ 4;
297 void* buf
= malloc( sz
);
300 // empty the buffer because in some case GetDataHere does not fill buf
301 memset( buf
, 0, sz
);
302 if ( GetDataHere( thisFormat
, buf
) )
304 wxIntPtr counter
= 1 ;
305 if ( thisFormat
.GetType() == wxDF_FILENAME
)
307 // the data is D-normalized UTF8 strings of filenames delimited with \n
308 char *fname
= strtok((char*) buf
,"\n");
309 while (fname
!= NULL
)
311 // translate the filepath into a fileurl and put that into the pasteobard
312 CFStringRef path
= CFStringCreateWithBytes(NULL
,(UInt8
*)fname
,strlen(fname
),kCFStringEncodingUTF8
,false);
313 CFURLRef url
= CFURLCreateWithFileSystemPath(NULL
, path
, kCFURLPOSIXPathStyle
, false);
315 CFDataRef data
= CFURLCreateData(NULL
,url
,kCFStringEncodingUTF8
,true);
317 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) counter
,
318 (CFStringRef
) thisFormat
.GetFormatId() , data
, kPasteboardFlavorNoFlags
);
321 fname
= strtok (NULL
,"\n");
327 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (UInt8
*)buf
, datasize
);
328 if ( thisFormat
.GetType() == wxDF_TEXT
)
329 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) itemID
,
330 CFSTR("com.apple.traditional-mac-plain-text") , data
, kPasteboardFlavorNoFlags
);
332 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) itemID
,
333 (CFStringRef
) thisFormat
.GetFormatId() , data
, kPasteboardFlavorNoFlags
);
344 bool wxDataObject::IsFormatInPasteboard( void * pb
, const wxDataFormat
&dataFormat
)
346 PasteboardRef pasteboard
= (PasteboardRef
) pb
;
347 bool hasData
= false;
348 OSStatus err
= noErr
;
351 // we synchronize here once again, so we don't mind which flags get returned
352 PasteboardSynchronize( pasteboard
);
354 err
= PasteboardGetItemCount( pasteboard
, &itemCount
);
357 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
&& hasData
== false ; itemIndex
++ )
359 PasteboardItemID itemID
;
360 CFArrayRef flavorTypeArray
;
363 err
= PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
);
367 err
= PasteboardCopyItemFlavors( pasteboard
, itemID
, &flavorTypeArray
);
371 flavorCount
= CFArrayGetCount( flavorTypeArray
);
373 for( CFIndex flavorIndex
= 0; flavorIndex
< flavorCount
&& hasData
== false ; flavorIndex
++ )
375 CFStringRef flavorType
;
377 flavorType
= (CFStringRef
)CFArrayGetValueAtIndex( flavorTypeArray
,
380 wxDataFormat
flavorFormat( (wxDataFormat::NativeFormat
) flavorType
);
381 if ( dataFormat
== flavorFormat
)
383 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
&& flavorFormat
.GetType() == wxDF_TEXT
)
386 CFRelease (flavorTypeArray
);
393 bool wxDataObject::GetFromPasteboard( void * pb
)
395 PasteboardRef pasteboard
= (PasteboardRef
) pb
;
397 size_t formatcount
= GetFormatCount(wxDataObject::Set
);
398 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
399 GetAllFormats(array
, wxDataObject::Set
);
401 ItemCount itemCount
= 0;
402 wxString filenamesPassed
;
403 bool transferred
= false;
404 bool pastelocationset
= false;
406 // we synchronize here once again, so we don't mind which flags get returned
407 PasteboardSynchronize( pasteboard
);
409 OSStatus err
= PasteboardGetItemCount( pasteboard
, &itemCount
);
412 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
414 // go through the data in our order of preference
415 wxDataFormat dataFormat
= array
[ i
];
417 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
&& transferred
== false ; itemIndex
++ )
419 PasteboardItemID itemID
= 0;
420 CFArrayRef flavorTypeArray
= NULL
;
421 CFIndex flavorCount
= 0;
423 err
= PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
);
427 err
= PasteboardCopyItemFlavors( pasteboard
, itemID
, &flavorTypeArray
);
431 flavorCount
= CFArrayGetCount( flavorTypeArray
);
433 for( CFIndex flavorIndex
= 0; !transferred
&& flavorIndex
< flavorCount
; flavorIndex
++ )
435 CFStringRef flavorType
;
436 CFDataRef flavorData
;
437 CFIndex flavorDataSize
;
439 flavorType
= (CFStringRef
)CFArrayGetValueAtIndex( flavorTypeArray
,
442 wxDataFormat
flavorFormat( (wxDataFormat::NativeFormat
) flavorType
);
444 if ( dataFormat
== flavorFormat
)
446 if ( UTTypeConformsTo( (CFStringRef
)flavorType
, kPasteboardTypeFileURLPromise
) )
448 if ( !pastelocationset
)
450 wxString tempdir
= wxFileName::GetTempDir() + wxFILE_SEP_PATH
+ "wxtemp.XXXXXX";
451 char* result
= mkdtemp((char*)tempdir
.fn_str().data());
456 wxCFRef
<CFURLRef
> dest(CFURLCreateFromFileSystemRepresentation(NULL
,(const UInt8
*)result
,strlen(result
),true));
457 PasteboardSetPasteLocation(pasteboard
, dest
);
458 pastelocationset
= true;
461 else if ( flavorFormat
.GetType() != wxDF_PRIVATE
)
463 // indicate the expected format for the type, benefiting from native conversions eg utf8 -> utf16
464 flavorType
= (CFStringRef
) wxDataFormat( flavorFormat
.GetType()).GetFormatId();
467 err
= PasteboardCopyItemFlavorData( pasteboard
, itemID
, flavorType
, &flavorData
);
470 flavorDataSize
= CFDataGetLength( flavorData
);
471 if (dataFormat
.GetType() == wxDF_FILENAME
)
473 // revert the translation and decomposition to arrive at a proper utf8 string again
474 CFURLRef url
= CFURLCreateWithBytes( kCFAllocatorDefault
, CFDataGetBytePtr( flavorData
), flavorDataSize
, kCFStringEncodingUTF8
, NULL
);
475 CFStringRef cfString
= CFURLCopyFileSystemPath( url
, kCFURLPOSIXPathStyle
);
477 CFMutableStringRef cfMutableString
= CFStringCreateMutableCopy(NULL
, 0, cfString
);
478 CFRelease( cfString
);
479 CFStringNormalize(cfMutableString
,kCFStringNormalizationFormC
);
480 wxString path
= wxCFStringRef(cfMutableString
).AsString();
482 filenamesPassed
+= path
+ wxT("\n");
486 // because some data implementation expect trailing a trailing NUL, we add some headroom
487 void *buf
= malloc( flavorDataSize
+ 4 );
490 memset( buf
, 0, flavorDataSize
+ 4 );
491 memcpy( buf
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
493 if (dataFormat
.GetType() == wxDF_TEXT
)
494 wxMacConvertNewlines10To13( (char*) buf
);
495 SetData( flavorFormat
, flavorDataSize
, buf
);
500 CFRelease (flavorData
);
503 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
&& flavorFormat
.GetType() == wxDF_TEXT
)
505 err
= PasteboardCopyItemFlavorData( pasteboard
, itemID
, flavorType
, &flavorData
);
508 flavorDataSize
= CFDataGetLength( flavorData
);
509 void *asciibuf
= malloc( flavorDataSize
+ 1 );
512 memset( asciibuf
, 0, flavorDataSize
+ 1 );
513 memcpy( asciibuf
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
514 CFRelease (flavorData
);
516 SetData( wxDF_TEXT
, flavorDataSize
, asciibuf
);
521 CFRelease (flavorData
);
525 CFRelease( flavorTypeArray
);
527 if ( !filenamesPassed
.empty() )
529 wxCharBuffer buf
= filenamesPassed
.fn_str();
530 SetData( wxDF_FILENAME
, strlen( buf
), (const char*)buf
);
538 bool wxDataObject::HasDataInPasteboard( void * pb
)
540 PasteboardRef pasteboard
= (PasteboardRef
) pb
;
541 size_t formatcount
= GetFormatCount(wxDataObject::Set
);
542 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
543 GetAllFormats(array
, wxDataObject::Set
);
544 ItemCount itemCount
= 0;
545 bool hasData
= false;
547 // we synchronize here once again, so we don't mind which flags get returned
548 PasteboardSynchronize( pasteboard
);
550 OSStatus err
= PasteboardGetItemCount( pasteboard
, &itemCount
);
553 for (size_t i
= 0; !hasData
&& i
< formatcount
; i
++)
555 // go through the data in our order of preference
556 wxDataFormat dataFormat
= array
[ i
];
558 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
&& hasData
== false ; itemIndex
++ )
560 PasteboardItemID itemID
= 0;
561 CFArrayRef flavorTypeArray
= NULL
;
562 CFIndex flavorCount
= 0;
564 err
= PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
);
568 err
= PasteboardCopyItemFlavors( pasteboard
, itemID
, &flavorTypeArray
);
572 flavorCount
= CFArrayGetCount( flavorTypeArray
);
574 for( CFIndex flavorIndex
= 0; !hasData
&& flavorIndex
< flavorCount
; flavorIndex
++ )
576 CFStringRef flavorType
;
578 flavorType
= (CFStringRef
)CFArrayGetValueAtIndex( flavorTypeArray
,
581 wxDataFormat
flavorFormat( (wxDataFormat::NativeFormat
) flavorType
);
583 if ( dataFormat
== flavorFormat
||
584 (dataFormat
.GetType() == wxDF_UNICODETEXT
&& flavorFormat
.GetType() == wxDF_TEXT
) )
589 CFRelease( flavorTypeArray
);
598 void wxDataObject::AddSupportedTypes( void* cfarray
)
600 size_t nFormats
= GetFormatCount(wxDataObject::Set
);
601 wxDataFormat
*array
= new wxDataFormat
[nFormats
];
602 GetAllFormats(array
, wxDataObject::Set
);
604 for (size_t i
= 0; i
< nFormats
; i
++)
606 wxDataFormat dataFormat
= array
[ i
];
608 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
|| dataFormat
.GetType() == wxDF_TEXT
)
610 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypeUTF16PlainText
);
611 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypePlainText
);
613 else if ( dataFormat
.GetType() == wxDF_FILENAME
)
615 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypeFileURL
);
616 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kPasteboardTypeFileURLPromise
);
618 else if ( dataFormat
.GetType() == wxDF_HTML
)
620 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypeHTML
);
622 else if ( dataFormat
.GetType() == wxDF_BITMAP
)
624 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypeTIFF
);
625 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypePICT
);
627 else if ( dataFormat
.GetType() == wxDF_METAFILE
)
629 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, kUTTypePDF
);
631 else if ( dataFormat
.GetType() == wxDF_PRIVATE
)
633 CFArrayAppendValue((CFMutableArrayRef
)cfarray
, (CFStringRef
) dataFormat
.GetFormatId());
641 // ----------------------------------------------------------------------------
643 // ----------------------------------------------------------------------------
646 void wxTextDataObject::GetAllFormats(wxDataFormat
*formats
,
647 wxDataObjectBase::Direction
WXUNUSED(dir
)) const
649 *formats
++ = wxDataFormat(wxDF_UNICODETEXT
);
650 *formats
= wxDataFormat(wxDF_TEXT
);
654 // ----------------------------------------------------------------------------
656 // ----------------------------------------------------------------------------
658 void wxFileDataObject::GetFileNames( wxCharBuffer
&buf
) const
662 for (size_t i
= 0; i
< m_filenames
.GetCount(); i
++)
664 filenames
+= m_filenames
[i
];
665 filenames
+= wxT('\n');
668 buf
= filenames
.fn_str();
671 bool wxFileDataObject::GetDataHere( void *pBuf
) const
680 buffLength
= strlen( buf
);
681 memcpy( pBuf
, (const char*)buf
, buffLength
+ 1 );
686 size_t wxFileDataObject::GetDataSize() const
692 buffLength
= strlen( buf
);
694 return buffLength
+ 1;
697 bool wxFileDataObject::SetData( size_t WXUNUSED(nSize
), const void *pBuf
)
702 filenames
= wxString( (const char*)pBuf
, *wxConvFileName
);
704 filenames
= wxString (wxConvLocal
.cWC2WX(wxConvFileName
->cMB2WC( (const char*)pBuf
)));
707 m_filenames
= wxStringTokenize( filenames
, wxT("\n"), wxTOKEN_STRTOK
);
712 void wxFileDataObject::AddFile( const wxString
& rFilename
)
714 m_filenames
.Add( rFilename
);
717 // ----------------------------------------------------------------------------
718 // wxBitmapDataObject
719 // ----------------------------------------------------------------------------
721 wxBitmapDataObject::wxBitmapDataObject()
726 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap
& rBitmap
)
727 : wxBitmapDataObjectBase( rBitmap
)
733 SetBitmap( rBitmap
);
737 wxBitmapDataObject::~wxBitmapDataObject()
742 void wxBitmapDataObject::SetBitmap( const wxBitmap
& rBitmap
)
745 wxBitmapDataObjectBase::SetBitmap( rBitmap
);
748 CGImageRef cgImageRef
= (CGImageRef
) m_bitmap
.CreateCGImage();
750 CFMutableDataRef data
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
751 CGImageDestinationRef destination
= CGImageDestinationCreateWithData( data
, kUTTypeTIFF
, 1 , NULL
);
754 CGImageDestinationAddImage( destination
, cgImageRef
, NULL
);
755 CGImageDestinationFinalize( destination
);
756 CFRelease( destination
);
758 m_pictHandle
= NewHandle(CFDataGetLength(data
));
761 memcpy( *(Handle
)m_pictHandle
, (const char *)CFDataGetBytePtr(data
), CFDataGetLength(data
) );
765 CGImageRelease(cgImageRef
);
769 void wxBitmapDataObject::Init()
772 m_pictCreated
= false;
775 void wxBitmapDataObject::Clear()
777 if (m_pictHandle
!= NULL
)
779 DisposeHandle( (Handle
) m_pictHandle
);
782 m_pictCreated
= false;
785 bool wxBitmapDataObject::GetDataHere( void *pBuf
) const
787 if (m_pictHandle
== NULL
)
789 wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
796 memcpy( pBuf
, *(Handle
)m_pictHandle
, GetHandleSize( (Handle
)m_pictHandle
) );
801 size_t wxBitmapDataObject::GetDataSize() const
803 if (m_pictHandle
!= NULL
)
804 return GetHandleSize( (Handle
)m_pictHandle
);
809 Handle
MacCreateDataReferenceHandle(Handle theDataHandle
)
811 Handle dataRef
= NULL
;
814 // Create a data reference handle for our data.
815 err
= PtrToHand( &theDataHandle
, &dataRef
, sizeof(Handle
));
820 bool wxBitmapDataObject::SetData( size_t nSize
, const void *pBuf
)
824 if ((pBuf
== NULL
) || (nSize
== 0))
827 Handle picHandle
= NewHandle( nSize
);
828 memcpy( *picHandle
, pBuf
, nSize
);
829 m_pictHandle
= picHandle
;
830 CGImageRef cgImageRef
= 0;
832 CFDataRef data
= CFDataCreateWithBytesNoCopy( kCFAllocatorDefault
, (const UInt8
*) pBuf
, nSize
, kCFAllocatorNull
);
833 CGImageSourceRef source
= CGImageSourceCreateWithData( data
, NULL
);
836 cgImageRef
= CGImageSourceCreateImageAtIndex(source
, 0, NULL
);
843 m_bitmap
.Create( CGImageGetWidth(cgImageRef
) , CGImageGetHeight(cgImageRef
) );
844 CGRect r
= CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef
) , CGImageGetHeight(cgImageRef
) );
845 // since our context is upside down we dont use CGContextDrawImage
846 wxMacDrawCGImage( (CGContextRef
) m_bitmap
.GetHBITMAP() , &r
, cgImageRef
) ;
847 CGImageRelease(cgImageRef
);
851 return m_bitmap
.IsOk();