/////////////////////////////////////////////////////////////////////////////// // Name: src/mac/carbon/dataobj.cpp // Purpose: implementation of wxDataObject class // Author: Stefan Csomor // Modified by: // Created: 10/21/99 // RCS-ID: $Id: dataobj.cpp 54368 2008-06-26 07:09:17Z SC $ // Copyright: (c) 1999 Stefan Csomor // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #if wxUSE_DATAOBJ #include "wx/dataobj.h" #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/log.h" #include "wx/dcmemory.h" #include "wx/image.h" #endif #include "wx/mstream.h" #include "wx/metafile.h" #include "wx/tokenzr.h" #include "wx/mac/uma.h" #ifdef __DARWIN__ #include #endif // ---------------------------------------------------------------------------- // wxDataFormat // ---------------------------------------------------------------------------- wxDataFormat::wxDataFormat() { m_type = wxDF_INVALID; m_format = 0; } wxDataFormat::wxDataFormat( wxDataFormatId vType ) { m_format = 0; m_type = wxDF_INVALID; SetType( vType ); } wxDataFormat::wxDataFormat( const wxChar *zId ) { m_format = 0; m_type = wxDF_INVALID; SetId( zId ); } wxDataFormat::wxDataFormat( const wxString& rId ) { m_format = 0; m_type = wxDF_INVALID; SetId( rId ); } wxDataFormat::wxDataFormat(const wxDataFormat& rFormat) { if ( rFormat.m_format ) m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format); else m_format = 0; m_type = rFormat.m_type; m_id = rFormat.m_id; } wxDataFormat::wxDataFormat( NativeFormat vFormat ) { m_format = 0; m_type = wxDF_INVALID; SetId( vFormat ); } wxDataFormat::~wxDataFormat() { if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } } // in order to be correct for 10.3 we restrict to the available types there // http://developer.apple.com/qa/qa2005/qa1406.html // TODO : Use UTCoreTypes.h constants once we support 10.4+ only wxDataFormat& wxDataFormat::operator=(const wxDataFormat& rFormat) { if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } if ( rFormat.m_format ) m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format); m_type = rFormat.m_type; m_id = rFormat.m_id; return *this; } void wxDataFormat::SetType( wxDataFormatId dataType ) { m_type = dataType; if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } switch (m_type) { case wxDF_TEXT: m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.plain-text") ); break; case wxDF_UNICODETEXT: m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") ); break; case wxDF_BITMAP: #if wxMAC_USE_CORE_GRAPHICS m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") ); #else m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.apple.pict") ); #endif break; case wxDF_METAFILE: #if wxMAC_USE_CORE_GRAPHICS m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.adobe.pdf") ); #else m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.apple.pict") ); #endif break; case wxDF_FILENAME: m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.file-url") ); break; default: wxFAIL_MSG( wxT("invalid data format") ); break; } } wxString wxDataFormat::GetId() const { wxCHECK_MSG( !IsStandard(), wxEmptyString, wxT("name of predefined format cannot be retrieved") ); return m_id; } void wxDataFormat::SetId( NativeFormat format ) { if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format); if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) ) { m_type = wxDF_UNICODETEXT; } else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.plain-text") ) ) { m_type = wxDF_TEXT; } #if wxMAC_USE_CORE_GRAPHICS else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.tiff") ) ) { m_type = wxDF_BITMAP; } else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.adobe.pdf") ) ) { m_type = wxDF_METAFILE; } #else else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.apple.pict") ) ) { m_type = wxDF_METAFILE; } #endif else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.file-url") ) ) { m_type = wxDF_FILENAME; } else { m_type = wxDF_PRIVATE; m_id = wxMacCFStringHolder( (CFStringRef) CFRetain((CFStringRef) format )).AsString(); } } void wxDataFormat::SetId( const wxChar* zId ) { m_type = wxDF_PRIVATE; m_id = zId; if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } // since it is private, no need to conform to anything ... m_format = (long) wxMacCFStringHolder(m_id).Detach(); } bool wxDataFormat::operator==(const wxDataFormat& format) const { if (IsStandard() || format.IsStandard()) return ( format.m_type == m_type ); else return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) ); } //------------------------------------------------------------------------- // wxDataObject //------------------------------------------------------------------------- wxDataObject::wxDataObject() { } bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDir ) const { size_t nFormatCount = GetFormatCount( vDir ); bool found = false; if (nFormatCount == 1) { found = (rFormat == GetPreferredFormat()); } else { wxDataFormat *pFormats = new wxDataFormat[nFormatCount]; GetAllFormats( pFormats, vDir ); for (size_t n = 0; n < nFormatCount; n++) { if (pFormats[n] == rFormat) { found = true; break; } } delete [] pFormats; } return found; } void wxDataObject::AddToPasteboard( void * pb, int itemID ) { PasteboardRef pasteboard = (PasteboardRef) pb; // get formats from wxDataObjects wxDataFormat *array = new wxDataFormat[ GetFormatCount() ]; GetAllFormats( array ); for (size_t i = 0; i < GetFormatCount(); i++) { wxDataFormat thisFormat = array[ i ]; // add four bytes at the end for data objs like text that // have a datasize = strlen but still need a buffer for the // string including trailing zero size_t datasize = GetDataSize( thisFormat ); size_t sz = datasize + 4; void* buf = malloc( sz ); if ( buf != NULL ) { // empty the buffer because in some case GetDataHere does not fill buf memset( buf, 0, sz ); if ( GetDataHere( array[ i ], buf ) ) { int counter = 1 ; if ( thisFormat.GetType() == wxDF_FILENAME ) { // the data is D-normalized UTF8 strings of filenames delimited with \n char *fname = strtok((char*) buf,"\n"); while (fname != NULL) { // translate the filepath into a fileurl and put that into the pasteobard CFStringRef path = CFStringCreateWithBytes(NULL,(UInt8*)fname,strlen(fname),kCFStringEncodingUTF8,false); CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path , kCFURLPOSIXPathStyle, false); CFRelease(path); CFDataRef data = CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true); CFRelease(url); PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) counter, (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags); CFRelease( data ); counter++; fname = strtok (NULL,"\n"); } } else { CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize ); if ( thisFormat.GetType() == wxDF_TEXT ) PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID, CFSTR("com.apple.traditional-mac-plain-text") , data, kPasteboardFlavorNoFlags); else PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID, (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags); CFRelease( data ); } } free( buf ); } } delete [] array; } bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat ) { PasteboardRef pasteboard = (PasteboardRef) pb; bool hasData = false; OSStatus err = noErr; ItemCount itemCount; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; flavorIndex < flavorCount && hasData == false ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) hasData = true; else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) hasData = true; } CFRelease (flavorTypeArray); } } return hasData; } bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount() + 1; wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = GetPreferredFormat(); GetAllFormats( &array[1] ); ItemCount itemCount = 0; wxString filenamesPassed; bool transferred = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !transferred && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); // avoid utf8 being treated closer to plain-text than unicode by forcing a conversion if ( UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text") ) ) { flavorType = CFSTR("public.utf16-plain-text"); } wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); if (dataFormat.GetType() == wxDF_FILENAME ) { // revert the translation and decomposition to arrive at a proper utf8 string again CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); CFRelease( url ); CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); CFRelease( cfString ); CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); wxString path = wxMacCFStringHolder(cfMutableString).AsString(); if (!path.empty()) filenamesPassed += path + wxT("\n"); } else { // because some data implementation expect trailing a trailing NUL, we add some headroom void *buf = malloc( flavorDataSize + 4 ); if ( buf ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); transferred = true; free( buf ); } } CFRelease (flavorData); } } else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); void *asciibuf = malloc( flavorDataSize + 1 ); if ( asciibuf ) { memset( asciibuf, 0, flavorDataSize + 1 ); memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); CFRelease (flavorData); SetData( wxDF_TEXT, flavorDataSize, asciibuf ); transferred = true; free( asciibuf ); } else CFRelease (flavorData); } } } CFRelease( flavorTypeArray ); } if (filenamesPassed.length() > 0) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); transferred = true; } } } return transferred; } bool wxDataObject::HasDataInPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount() + 1; wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = GetPreferredFormat(); GetAllFormats( &array[1] ); ItemCount itemCount = 0; bool hasData = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !hasData && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !hasData && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat || dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { hasData = true; } } CFRelease( flavorTypeArray ); } } } return hasData; } // ---------------------------------------------------------------------------- // wxTextDataObject // ---------------------------------------------------------------------------- #if wxUSE_UNICODE void wxTextDataObject::GetAllFormats( wxDataFormat *formats, wxDataObjectBase::Direction dir ) const { *formats++ = wxDataFormat( wxDF_TEXT ); *formats = wxDataFormat( wxDF_UNICODETEXT ); } #endif // ---------------------------------------------------------------------------- // wxFileDataObject // ---------------------------------------------------------------------------- void wxFileDataObject::GetFileNames( wxCharBuffer &buf ) const { wxString filenames; for (size_t i = 0; i < m_filenames.GetCount(); i++) { filenames += m_filenames[i]; filenames += wxT('\n'); } buf = filenames.fn_str(); } bool wxFileDataObject::GetDataHere( void *pBuf ) const { if (pBuf == NULL) return false; wxCharBuffer buf; size_t buffLength; GetFileNames( buf ); buffLength = strlen( buf ); memcpy( pBuf, (const char*)buf, buffLength + 1 ); return true; } size_t wxFileDataObject::GetDataSize() const { wxCharBuffer buf; size_t buffLength; GetFileNames( buf ); buffLength = strlen( buf ); // terminating 0 return buffLength + 1; } bool wxFileDataObject::SetData( size_t nSize, const void *pBuf ) { wxString filenames; #if wxUSE_UNICODE filenames = wxString( (const char*)pBuf, *wxConvFileName ); #else filenames = wxString (wxConvLocal.cWC2WX(wxConvFileName->cMB2WC( (const char*)pBuf))); #endif m_filenames = wxStringTokenize( filenames, wxT("\n"), wxTOKEN_STRTOK ); return true; } void wxFileDataObject::AddFile( const wxString& rFilename ) { m_filenames.Add( rFilename ); } // ---------------------------------------------------------------------------- // wxBitmapDataObject // ---------------------------------------------------------------------------- wxBitmapDataObject::wxBitmapDataObject() { Init(); } wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap ) : wxBitmapDataObjectBase( rBitmap ) { Init(); if (m_bitmap.Ok()) { #if wxMAC_USE_CORE_GRAPHICS SetBitmap( rBitmap ); #else m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle(); m_pictCreated = false; #endif } } wxBitmapDataObject::~wxBitmapDataObject() { Clear(); } void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { Clear(); wxBitmapDataObjectBase::SetBitmap( rBitmap ); if (m_bitmap.Ok()) { #if wxMAC_USE_CORE_GRAPHICS CGImageRef cgImageRef = (CGImageRef) m_bitmap.CGImageCreate(); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( UMAGetSystemVersion() >= 0x1040 ) { CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL ); if ( destination ) { CGImageDestinationAddImage( destination, cgImageRef, NULL ); CGImageDestinationFinalize( destination ); CFRelease( destination ); } m_pictHandle = NewHandle(CFDataGetLength(data)); if ( m_pictHandle ) { memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) ); } CFRelease( data ); } else #endif #ifndef __LP64__ { // export as TIFF GraphicsExportComponent exporter = 0; OSStatus err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeTIFF, &exporter); if (noErr == err) { m_pictHandle = NewHandle(0); if ( m_pictHandle ) { err = GraphicsExportSetInputCGImage( exporter, cgImageRef); err = GraphicsExportSetOutputHandle(exporter, (Handle)m_pictHandle); err = GraphicsExportDoExport(exporter, NULL); } CloseComponent( exporter ); } } #endif CGImageRelease(cgImageRef); #else m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle(); m_pictCreated = false; #endif } } void wxBitmapDataObject::Init() { m_pictHandle = NULL; m_pictCreated = false; } void wxBitmapDataObject::Clear() { if (m_pictHandle != NULL) { #if wxMAC_USE_CORE_GRAPHICS DisposeHandle( (Handle) m_pictHandle ); #else if (m_pictCreated) KillPicture( (PicHandle)m_pictHandle ); #endif m_pictHandle = NULL; } m_pictCreated = false; } bool wxBitmapDataObject::GetDataHere( const wxDataFormat& format, void *pBuf ) const { if (m_pictHandle == NULL) { wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") ); return false; } if (pBuf == NULL) return false; if ( format != GetPreferredFormat() ) return false; memcpy( pBuf, *(Handle)m_pictHandle, GetHandleSize( (Handle)m_pictHandle ) ); return true; } size_t wxBitmapDataObject::GetDataSize( const wxDataFormat& format ) const { if ( format != GetPreferredFormat() ) return 0; if (m_pictHandle != NULL) return GetHandleSize( (Handle)m_pictHandle ); else return 0; } Handle MacCreateDataReferenceHandle(Handle theDataHandle) { Handle dataRef = NULL; OSErr err = noErr; // Create a data reference handle for our data. err = PtrToHand( &theDataHandle, &dataRef, sizeof(Handle)); return dataRef; } size_t wxBitmapDataObject::GetDataSize() const { return GetDataSize(GetPreferredFormat()); } bool wxBitmapDataObject::GetDataHere(void *buf) const { return GetDataHere(GetPreferredFormat(), buf); } bool wxBitmapDataObject::SetData(size_t len, const void *buf) { return SetData(GetPreferredFormat(), len, buf); } size_t wxBitmapDataObject::GetFormatCount(Direction WXUNUSED(dir) ) const { #if wxMAC_USE_CORE_GRAPHICS return 2; #else return 1; #endif } static wxDataFormat s_pict( _T("com.apple.pict") ); void wxBitmapDataObject::GetAllFormats(wxDataFormat *formats, wxDataObjectBase::Direction WXUNUSED(dir) ) const { *formats++ = wxDataFormat( wxDF_BITMAP ); #if wxMAC_USE_CORE_GRAPHICS *formats = s_pict; #endif } bool wxBitmapDataObject::SetData( const wxDataFormat& format, size_t nSize, const void *pBuf ) { Clear(); if ((pBuf == NULL) || (nSize == 0)) return false; #if wxMAC_USE_CORE_GRAPHICS Handle picHandle = NULL ; m_pictHandle = NewHandle( nSize ); memcpy( *(Handle) m_pictHandle, pBuf, nSize ); if ( format == s_pict ) { // pict for IO expects a 512 byte header picHandle = NewHandle( nSize + 512 ); memset( *picHandle , 0 , 512 ); memcpy( *picHandle+512, pBuf, nSize ); } else { picHandle = (Handle) m_pictHandle; } CGImageRef cgImageRef = 0; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( UMAGetSystemVersion() >= 0x1040 ) { CFDataRef data = NULL; HLock( picHandle ); data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) *picHandle, GetHandleSize(picHandle), kCFAllocatorNull); CGImageSourceRef source = CGImageSourceCreateWithData( data, NULL ); if ( source ) { cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); } CFRelease( source ); CFRelease( data ); HUnlock( picHandle ); } else #endif #ifndef __LP64__ { // import from TIFF GraphicsImportComponent importer = 0; OSStatus err = OpenADefaultComponent(GraphicsImporterComponentType, s_pict == format ? kQTFileTypePicture : kQTFileTypeTIFF, &importer); if (noErr == err) { if ( picHandle ) { ComponentResult result = GraphicsImportSetDataHandle(importer, picHandle); if ( result == noErr ) { Rect frame; GraphicsImportGetNaturalBounds( importer, &frame ); GraphicsImportCreateCGImage( importer, &cgImageRef, kGraphicsImportCreateCGImageUsingCurrentSettings ); } } CloseComponent( importer ); } } #endif if ( format == s_pict ) { DisposeHandle( picHandle ); } if ( cgImageRef ) { m_bitmap.Create( CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); // since our context is upside down we dont use CGContextDrawImage HIViewDrawCGImage( (CGContextRef) m_bitmap.GetHBITMAP() , &r, cgImageRef ) ; CGImageRelease(cgImageRef); cgImageRef = NULL; } #else PicHandle picHandle = (PicHandle)NewHandle( nSize ); memcpy( *picHandle, pBuf, nSize ); m_pictHandle = picHandle; // ownership is transferred to the bitmap m_pictCreated = false; #ifndef __LP64__ Rect frame; wxMacGetPictureBounds( picHandle, &frame ); #if wxUSE_METAFILE wxMetafile mf; mf.SetHMETAFILE( (WXHMETAFILE)m_pictHandle ); #endif wxMemoryDC mdc; m_bitmap.Create( frame.right - frame.left, frame.bottom - frame.top ); mdc.SelectObject( m_bitmap ); #if wxUSE_METAFILE mf.Play( &mdc ); #endif mdc.SelectObject( wxNullBitmap ); #endif #endif return m_bitmap.Ok(); } #endif