diff --git a/include/wx/defs.h b/include/wx/defs.h index 6181458f7f..c2336f6223 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2584,7 +2584,6 @@ typedef int (* LINKAGEMODE wxListIterateFunction)(void *current); #define WX_OPAQUE_TYPE( name ) struct wxOpaque##name -typedef void* WXHBITMAP; typedef void* WXHCURSOR; typedef void* WXRECTPTR; typedef void* WXPOINTPTR; @@ -2628,6 +2627,7 @@ DECLARE_WXOSX_OPAQUE_CGREF( CGFont ) typedef CGColorRef WXCOLORREF; typedef CGImageRef WXCGIMAGEREF; typedef CGContextRef WXHDC; +typedef CGContextRef WXHBITMAP; /* * carbon diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index f5cec1dac4..b3fa967ef9 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -30,7 +30,7 @@ class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; // 8 bit is chosen only for performance reasons, note also that this is the inverse value range // from alpha, where 0 = invisible , 255 = fully drawn -class WXDLLIMPEXP_CORE wxMask: public wxObject +class WXDLLIMPEXP_CORE wxMask: public wxMaskBase { wxDECLARE_DYNAMIC_CLASS(wxMask); @@ -52,8 +52,6 @@ public: virtual ~wxMask(); - bool Create(const wxBitmap& bitmap, const wxColour& colour); - bool Create(const wxBitmap& bitmap); bool Create(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ; wxBitmap GetBitmap() const; @@ -64,20 +62,36 @@ public: // a 8 bit depth mask void* GetRawAccess() const; - int GetBytesPerRow() const { return m_bytesPerRow ; } + int GetBytesPerRow() const; + int GetWidth() const; + int GetHeight() const; + // renders/updates native representation when necessary void RealizeNative() ; WXHBITMAP GetHBITMAP() const ; +protected: + // this function is called from Create() to free the existing mask data + virtual void FreeData() wxOVERRIDE; + + // these functions must be overridden to implement the corresponding public + // Create() methods, they shouldn't call FreeData() as it's already called + // by the public wrappers + virtual bool InitFromColour(const wxBitmap& bitmap, + const wxColour& colour) wxOVERRIDE; + virtual bool InitFromMonoBitmap(const wxBitmap& bitmap) wxOVERRIDE; private: +#if !wxOSX_BITMAP_NATIVE_ACCESS wxMemoryBuffer m_memBuf ; int m_bytesPerRow ; int m_width ; int m_height ; +#endif + void DoCreateMaskBitmap(int width, int height, int bytesPerRow = -1); - WXHBITMAP m_maskBitmap ; + wxCFRef m_maskBitmap ; }; @@ -146,7 +160,10 @@ public: virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = NULL) const; - wxBitmapRefData *GetBitmapData() const + const wxBitmapRefData *GetBitmapData() const + { return (const wxBitmapRefData *)m_refData; } + + wxBitmapRefData *GetBitmapData() { return (wxBitmapRefData *)m_refData; } // copies the contents and mask of the given (colour) icon to the bitmap @@ -155,10 +172,17 @@ public: int GetWidth() const; int GetHeight() const; int GetDepth() const; + +#if WXWIN_COMPATIBILITY_3_0 + wxDEPRECATED_MSG("this value is determined during creation, this method could lead to inconsistencies") void SetWidth(int w); + wxDEPRECATED_MSG("this value is determined during creation, this method could lead to inconsistencies") void SetHeight(int h); + wxDEPRECATED_MSG("this value is determined during creation, this method could lead to inconsistencies") void SetDepth(int d); + wxDEPRECATED_MSG("this value is determined during creation, this method could lead to inconsistencies") void SetOk(bool isOk); +#endif #if wxUSE_PALETTE wxPalette* GetPalette() const; @@ -193,18 +217,34 @@ public: // returns an autoreleased version of the image WX_UIImage GetUIImage() const; #endif + +#if WXWIN_COMPATIBILITY_3_0 + +#if wxOSX_USE_ICONREF // returns a IconRef which must be retained before and released after usage + wxDEPRECATED_MSG("IconRefs are deprecated, this will be removed in the future") IconRef GetIconRef() const; // returns a IconRef which must be released after usage + wxDEPRECATED_MSG("IconRefs are deprecated, this will be removed in the future") IconRef CreateIconRef() const; +#endif + // get read only access to the underlying buffer - void *GetRawAccess() const ; + wxDEPRECATED_MSG("use GetRawData for accessing the buffer") + const void *GetRawAccess() const; // brackets to the underlying OS structure for read/write access // makes sure that no cached images will be constructed until terminated - void *BeginRawAccess() ; - void EndRawAccess() ; + wxDEPRECATED_MSG("use GetRawData for accessing the buffer") + void *BeginRawAccess(); + wxDEPRECATED_MSG("use GetRawData for accessing the buffer") + void EndRawAccess(); +#endif double GetScaleFactor() const; + + void SetSelectedInto(wxDC *dc); + wxDC *GetSelectedInto() const; + protected: virtual wxGDIRefData *CreateGDIRefData() const; virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const; diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index ed70b80794..bb0f15d06c 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -32,8 +32,11 @@ OSStatus WXDLLIMPEXP_CORE wxMacDrawCGImage( CGContextRef inContext, const CGRect * inBounds, CGImageRef inImage) ; +WX_NSImage WXDLLIMPEXP_CORE wxOSXGetSystemImage(const wxString& name); WX_NSImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromCGImage( CGImageRef image, double scale = 1.0, bool isTemplate = false); WX_NSImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromIconRef( WXHICON iconref ); +WX_NSImage WXDLLIMPEXP_CORE wxOSXGetIconForType(OSType type ); +void WXDLLIMPEXP_CORE wxOSXSetImageSize(WX_NSImage image, CGFloat width, CGFloat height); CGImageRef WXDLLIMPEXP_CORE wxOSXCreateCGImageFromNSImage( WX_NSImage nsimage, double *scale = NULL ); CGImageRef WXDLLIMPEXP_CORE wxOSXGetCGImageFromNSImage( WX_NSImage nsimage, CGRect* r, CGContextRef cg); CGContextRef WXDLLIMPEXP_CORE wxOSXCreateBitmapContextFromNSImage( WX_NSImage nsimage, bool *isTemplate = NULL); diff --git a/include/wx/osx/icon.h b/include/wx/osx/icon.h index 2540a346d8..a06afeeccc 100644 --- a/include/wx/osx/icon.h +++ b/include/wx/osx/icon.h @@ -51,7 +51,9 @@ public: wxSize GetSize() const { return wxSize(GetWidth(), GetHeight()); } +#if wxOSX_USE_ICONREF WXHICON GetHICON() const; +#endif #if wxOSX_USE_COCOA WX_NSImage GetNSImage() const ; diff --git a/include/wx/osx/setup0.h b/include/wx/osx/setup0.h index a1307bf4d4..49bf354be5 100644 --- a/include/wx/osx/setup0.h +++ b/include/wx/osx/setup0.h @@ -1622,6 +1622,13 @@ // make sure we have the proper dispatcher for the console event loop #define wxUSE_SELECT_DISPATCHER 1 #define wxUSE_EPOLL_DISPATCHER 0 + +// set to 1 if you have older code that still needs icon refs +#define wxOSX_USE_ICONREF 0 + +// set to 0 if you have code that has problems with the new bitmap implementation +#define wxOSX_BITMAP_NATIVE_ACCESS 1 + /* --- end OSX options --- */ #endif diff --git a/src/osx/carbon/cursor.cpp b/src/osx/carbon/cursor.cpp index 9f6e7f69bf..7b83407bcb 100644 --- a/src/osx/carbon/cursor.cpp +++ b/src/osx/carbon/cursor.cpp @@ -256,7 +256,7 @@ void wxCursor::CreateFromImage(const wxImage & image) int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); #if wxOSX_USE_COCOA wxBitmap bmp( image ); - CGImageRef cgimage = wxMacCreateCGImageFromBitmap(bmp); + CGImageRef cgimage = bmp.CreateCGImage(); if ( cgimage ) { M_CURSORDATA->m_hCursor = wxMacCocoaCreateCursorFromCGImage( cgimage, hotSpotX, hotSpotY ); diff --git a/src/osx/carbon/icon.cpp b/src/osx/carbon/icon.cpp index 1d74771428..2ae7bde730 100644 --- a/src/osx/carbon/icon.cpp +++ b/src/osx/carbon/icon.cpp @@ -28,11 +28,18 @@ class WXDLLEXPORT wxIconRefData : public wxGDIRefData { public: wxIconRefData() { Init(); } +#if wxOSX_USE_ICONREF wxIconRefData( WXHICON iconref, int desiredWidth, int desiredHeight ); +#else + wxIconRefData( WX_NSImage image, int desiredWidth, int desiredHeight ); +#endif virtual ~wxIconRefData() { Free(); } +#if wxOSX_USE_ICONREF virtual bool IsOk() const wxOVERRIDE { return m_iconRef != NULL; } - +#else + virtual bool IsOk() const wxOVERRIDE { return m_nsImage != NULL; } +#endif virtual void Free(); void SetWidth( int width ) { m_width = width; } @@ -41,7 +48,9 @@ public: int GetWidth() const { return m_width; } int GetHeight() const { return m_height; } +#if wxOSX_USE_ICONREF WXHICON GetHICON() const { return (WXHICON) m_iconRef; } +#endif #if wxOSX_USE_COCOA WX_NSImage GetNSImage() const; #endif @@ -49,7 +58,9 @@ public: private: void Init(); +#if wxOSX_USE_ICONREF IconRef m_iconRef; +#endif #if wxOSX_USE_COCOA mutable NSImage* m_nsImage; #endif @@ -60,7 +71,7 @@ private: wxDECLARE_NO_COPY_CLASS(wxIconRefData); }; - +#if wxOSX_USE_ICONREF wxIconRefData::wxIconRefData( WXHICON icon, int desiredWidth, int desiredHeight ) { Init(); @@ -70,10 +81,28 @@ wxIconRefData::wxIconRefData( WXHICON icon, int desiredWidth, int desiredHeight SetWidth( desiredWidth == -1 ? 32 : desiredWidth ) ; SetHeight( desiredHeight == -1 ? 32 : desiredHeight ) ; } +#else +wxIconRefData::wxIconRefData( NSImage* icon, int desiredWidth, int desiredHeight ) +{ + Init(); + + if ( icon ) + { + m_nsImage = icon; + wxMacCocoaRetain(icon); + } + + // Standard sizes + SetWidth( desiredWidth == -1 ? 32 : desiredWidth ) ; + SetHeight( desiredHeight == -1 ? 32 : desiredHeight ) ; +} +#endif void wxIconRefData::Init() { +#if wxOSX_USE_ICONREF m_iconRef = NULL ; +#endif #if wxOSX_USE_COCOA m_nsImage = NULL; #endif @@ -83,16 +112,18 @@ void wxIconRefData::Init() void wxIconRefData::Free() { +#if wxOSX_USE_ICONREF if ( m_iconRef ) { ReleaseIconRef( m_iconRef ) ; m_iconRef = NULL ; } +#endif #if wxOSX_USE_COCOA if ( m_nsImage ) { - CFRelease(m_nsImage); + wxMacCocoaRelease(m_nsImage); } #endif } @@ -102,11 +133,13 @@ WX_NSImage wxIconRefData::GetNSImage() const { wxASSERT( IsOk() ); +#if wxOSX_USE_ICONREF if ( m_nsImage == 0 ) { m_nsImage = wxOSXGetNSImageFromIconRef(m_iconRef); CFRetain(m_nsImage); } +#endif return m_nsImage; } @@ -139,6 +172,7 @@ wxIcon::wxIcon( LoadFile( icon_file, flags, desiredWidth, desiredHeight ); } +#if wxOSX_USE_ICONREF wxIcon::wxIcon(WXHICON icon, const wxSize& size) : wxGDIObject() { @@ -148,6 +182,7 @@ wxIcon::wxIcon(WXHICON icon, const wxSize& size) m_refData = new wxIconRefData( icon, size.x, size.y ) ; } +#endif wxIcon::~wxIcon() { @@ -166,12 +201,14 @@ wxIcon::CloneGDIRefData(const wxGDIRefData * WXUNUSED(data)) const return new wxIconRefData; } +#if wxOSX_USE_ICONREF WXHICON wxIcon::GetHICON() const { wxASSERT( IsOk() ) ; return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ; } +#endif int wxIcon::GetWidth() const { @@ -242,6 +279,7 @@ bool wxIcon::LoadIconFromSystemResource(const wxString& resourceName, int desire { UnRef(); +#if wxOSX_USE_ICONREF OSType theId = 0 ; if ( resourceName == wxT("wxICON_INFORMATION") ) @@ -335,7 +373,7 @@ bool wxIcon::LoadIconFromSystemResource(const wxString& resourceName, int desire return true ; } } - +#endif return false; } @@ -347,6 +385,7 @@ bool wxIcon::LoadIconFromBundleResource(const wxString& resourceName, int desire { UnRef(); +#if wxOSX_USE_ICONREF IconRef iconRef = NULL ; // first look in the resource fork @@ -395,7 +434,7 @@ bool wxIcon::LoadIconFromBundleResource(const wxString& resourceName, int desire m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ); return true; } - +#endif return false; } @@ -406,9 +445,10 @@ bool wxIcon::LoadIconFromFile(const wxString& filename, int desiredWidth, int de { UnRef(); - OSStatus err; bool result = false; +#if wxOSX_USE_ICONREF + OSStatus err; // Get a file system reference FSRef fsRef; err = FSPathMakeRef( (const wxUint8*)filename.utf8_str().data(), &fsRef, NULL ); @@ -436,6 +476,7 @@ bool wxIcon::LoadIconFromFile(const wxString& filename, int desiredWidth, int de // Release the iconFamily before returning ReleaseResource( (Handle) iconFamily ); +#endif return result; } @@ -487,6 +528,7 @@ void wxIcon::CopyFromBitmap( const wxBitmap& bmp ) { UnRef() ; +#if wxOSX_USE_ICONREF // as the bitmap owns that ref, we have to acquire it as well int w = bmp.GetWidth() ; @@ -502,7 +544,9 @@ void wxIcon::CopyFromBitmap( const wxBitmap& bmp ) { m_refData = new wxIconRefData( (WXHICON) bmp.CreateIconRef() , bmp.GetWidth(), bmp.GetHeight() ) ; } - +#else + m_refData = new wxIconRefData( bmp.GetNSImage() , bmp.GetWidth(), bmp.GetHeight() ) ; +#endif } wxIMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler); diff --git a/src/osx/carbon/utilscocoa.mm b/src/osx/carbon/utilscocoa.mm index 9b70c90360..99d05565bf 100644 --- a/src/osx/carbon/utilscocoa.mm +++ b/src/osx/carbon/utilscocoa.mm @@ -203,10 +203,23 @@ double wxOSXGetMainScreenContentScaleFactor() #if wxOSX_USE_COCOA -wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &WXUNUSED(client), const wxSize& WXUNUSED(size)) +WX_NSImage wxOSXGetSystemImage(const wxString& name) { wxCFStringRef cfname(name); - return wxBitmap( [NSImage imageNamed:cfname.AsNSString()] ); + NSImage* nsimage = [NSImage imageNamed:cfname.AsNSString()]; + return nsimage; +} + +wxBitmap wxOSXCreateSystemBitmap(const wxString& name, const wxString &client, const wxSize& sizeHint) +{ + NSImage* nsimage = wxOSXGetSystemImage(name); + if ( nsimage ) + { + // if ( sizeHint != wxDefaultSize ) + // [nsimage setSize:NSMakeSize(sizeHint.GetHeight(), sizeHint.GetWidth())]; + return wxBitmap( nsimage ); + } + return wxNullBitmap; } WX_NSImage wxOSXGetNSImageFromCGImage( CGImageRef image, double scaleFactor, bool isTemplate ) @@ -274,6 +287,16 @@ double wxOSXGetMainScreenContentScaleFactor() return [[NSScreen mainScreen] backingScaleFactor]; } +WX_NSImage wxOSXGetIconForType(OSType type ) +{ + return [[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode(type)]; +} + +void wxOSXSetImageSize(WX_NSImage image, CGFloat width, CGFloat height) +{ + [image setSize:NSMakeSize(width, height)]; +} + CGImageRef wxOSXCreateCGImageFromNSImage( WX_NSImage nsimage, double *scaleptr ) { // based on http://www.mail-archive.com/cocoa-dev@lists.apple.com/msg18065.html diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index 2bad5c9462..900173547e 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -62,6 +62,16 @@ public: void Free(); void SetOk( bool isOk) { m_ok = isOk; } +#if wxOSX_BITMAP_NATIVE_ACCESS + int GetWidth() const { return CGBitmapContextGetWidth(m_hBitmap); } + int GetHeight() const { return CGBitmapContextGetHeight(m_hBitmap); } + int GetDepth() const { return CGBitmapContextGetBitsPerPixel(m_hBitmap); } + int GetBytesPerRow() const { return CGBitmapContextGetBytesPerRow(m_hBitmap); } + bool HasAlpha() const { + CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(m_hBitmap); + return !( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast) ; + } +#else void SetWidth( int width ) { m_width = width; } void SetHeight( int height ) { m_height = height; } void SetDepth( int depth ) { m_depth = depth; } @@ -69,12 +79,16 @@ public: int GetWidth() const { return m_width; } int GetHeight() const { return m_height; } int GetDepth() const { return m_depth; } + int GetBytesPerRow() const { return m_bytesPerRow; } + bool HasAlpha() const { return m_hasAlpha; } +#endif double GetScaleFactor() const { return m_scaleFactor; } - void *GetRawAccess() const; + + const void *GetRawAccess() const; + void *GetRawAccess(); void *BeginRawAccess(); void EndRawAccess(); - bool HasAlpha() const { return m_hasAlpha; } void UseAlpha( bool useAlpha ); bool IsTemplate() const { return m_isTemplate; } @@ -96,37 +110,46 @@ public: bool HasNativeSize(); #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF // caller should increase ref count if needed longer // than the bitmap exists IconRef GetIconRef(); +#endif #endif CGContextRef GetBitmapContext() const; - int GetBytesPerRow() const { return m_bytesPerRow; } - private : + void SetSelectedInto(wxDC *dc); + wxDC *GetSelectedInto() const; + +private : bool Create(int width , int height , int depth, double logicalscale); bool Create( CGImageRef image, double scale ); bool Create( CGContextRef bitmapcontext); void Init(); +#if !wxOSX_BITMAP_NATIVE_ACCESS int m_width; int m_height; int m_bytesPerRow; int m_depth; bool m_hasAlpha; wxMemoryBuffer m_memBuf; +#endif int m_rawAccessCount; bool m_ok; mutable CGImageRef m_cgImageRef; bool m_isTemplate; #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF IconRef m_iconRef; +#endif #endif - CGContextRef m_hBitmap; + wxCFRef m_hBitmap; double m_scaleFactor; + wxDC* m_selectedInto; }; @@ -143,122 +166,55 @@ static int GetBestBytesPerRow( int rawBytes ) // this is used for more controls than just the wxBitmap button, also for notebooks etc -void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType ) -{ - memset( info , 0 , sizeof(ControlButtonContentInfo) ) ; - if ( bitmap.IsOk() ) - { - wxBitmapRefData * bmap = bitmap.GetBitmapData() ; - if ( bmap == NULL ) - return ; - - if ( forceType == 0 ) - { - forceType = kControlContentCGImageRef; - } - - if ( forceType == kControlContentIconRef ) - { - wxBitmap scaleBmp ; - wxBitmapRefData* bmp = bmap ; - - if ( !bmap->HasNativeSize() ) - { - // as PICT conversion will only result in a 16x16 icon, let's attempt - // a few scales for better results - - int w = bitmap.GetWidth() ; - int h = bitmap.GetHeight() ; - int sz = wxMax( w , h ) ; - if ( sz == 24 || sz == 64 ) - { - scaleBmp = wxBitmap( bitmap.ConvertToImage().Scale( w * 2 , h * 2 ) ) ; - bmp = scaleBmp.GetBitmapData() ; - } - } - - info->contentType = kControlContentIconRef ; - info->u.iconRef = bmp->GetIconRef() ; - AcquireIconRef( info->u.iconRef ) ; - } - else if ( forceType == kControlContentCGImageRef ) - { - info->contentType = kControlContentCGImageRef ; - info->u.imageRef = (CGImageRef) bmap->CreateCGImage() ; - } - } -} - CGImageRef wxMacCreateCGImageFromBitmap( const wxBitmap& bitmap ) { - wxBitmapRefData * bmap = bitmap.GetBitmapData() ; + const wxBitmapRefData * bmap = bitmap.GetBitmapData() ; if ( bmap == NULL ) return NULL ; return (CGImageRef) bmap->CreateCGImage(); } -void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) -{ - if ( info->contentType == kControlContentIconRef ) - { - ReleaseIconRef( info->u.iconRef ) ; - } - else if ( info->contentType == kControlNoContent ) - { - // there's no bitmap at all, fall through silently - } - else if ( info->contentType == kControlContentPictHandle ) - { - // owned by the bitmap, no release here - } - else if ( info->contentType == kControlContentCGImageRef ) - { - CGImageRelease( info->u.imageRef ) ; - } - else - { - wxFAIL_MSG(wxT("Unexpected bitmap type") ) ; - } -} - #endif //wxUSE_BMPBUTTON -#define M_BITMAPDATA ((wxBitmapRefData *)m_refData) - void wxBitmapRefData::Init() { +#if !wxOSX_BITMAP_NATIVE_ACCESS m_width = 0 ; m_height = 0 ; m_depth = 0 ; m_bytesPerRow = 0; + m_hasAlpha = false; +#endif m_ok = false ; m_bitmapMask = NULL ; m_cgImageRef = NULL ; m_isTemplate = false; #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF m_iconRef = NULL ; +#endif #endif m_hBitmap = NULL ; m_rawAccessCount = 0 ; - m_hasAlpha = false; m_scaleFactor = 1.0; + m_selectedInto = NULL; } wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy) : wxGDIRefData() { Init(); - Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth, tocopy.m_scaleFactor); + Create(tocopy.GetWidth(), tocopy.GetHeight(), tocopy.GetDepth(), tocopy.GetScaleFactor()); if (tocopy.m_bitmapMask) m_bitmapMask = new wxMask(*tocopy.m_bitmapMask); - else if (tocopy.m_hasAlpha) + else if (tocopy.HasAlpha()) UseAlpha(true); unsigned char* dest = (unsigned char*)GetRawAccess(); unsigned char* source = (unsigned char*)tocopy.GetRawAccess(); - size_t numbytes = m_bytesPerRow * m_height; + size_t numbytes = GetBytesPerRow() * GetHeight(); memcpy( dest, source, numbytes ); } @@ -283,48 +239,59 @@ wxBitmapRefData::wxBitmapRefData(CGImageRef image, double scale) { Init(); Create( image, scale ); -} +} // code from Technical Q&A QA1509 bool wxBitmapRefData::Create(CGImageRef image, double scale) { if ( image != NULL ) { +#if wxOSX_BITMAP_NATIVE_ACCESS + int m_width, m_height, m_depth, m_bytesPerRow; +#endif m_width = CGImageGetWidth(image); m_height = CGImageGetHeight(image); m_depth = 32; m_hBitmap = NULL; m_scaleFactor = scale; - + m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ; +#if !wxOSX_BITMAP_NATIVE_ACCESS size_t size = m_bytesPerRow * m_height ; void* data = m_memBuf.GetWriteBuf( size ) ; if ( data != NULL ) { memset( data , 0 , size ) ; m_memBuf.UngetWriteBuf( size ) ; +#else + void* data = NULL; +#endif CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image); if ( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast ) { m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst ); } - else + else { +#if !wxOSX_BITMAP_NATIVE_ACCESS m_hasAlpha = true; +#endif m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst ); } CGRect rect = CGRectMake(0,0,m_width,m_height); CGContextDrawImage(m_hBitmap, rect, image); - + wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ; CGContextTranslateCTM( m_hBitmap, 0, m_height ); CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor ); +#if !wxOSX_BITMAP_NATIVE_ACCESS } /* data != NULL */ +#endif } m_ok = ( m_hBitmap != NULL ) ; - + return m_ok ; - + } bool wxBitmapRefData::Create(CGContextRef context) @@ -332,35 +299,40 @@ bool wxBitmapRefData::Create(CGContextRef context) if ( context != NULL && CGBitmapContextGetData(context) ) { m_hBitmap = context; +#if !wxOSX_BITMAP_NATIVE_ACCESS m_bytesPerRow = CGBitmapContextGetBytesPerRow(context); m_width = CGBitmapContextGetWidth(context); m_height = CGBitmapContextGetHeight(context); m_depth = CGBitmapContextGetBitsPerPixel(context) ; - +#endif // our own contexts conform to this, always. - wxASSERT( m_depth == 32 ); - - size_t size = m_bytesPerRow * m_height ; + wxASSERT( GetDepth() == 32 ); + +#if !wxOSX_BITMAP_NATIVE_ACCESS + size_t size = GetBytesPerRow() * GetHeight() ; void* data = m_memBuf.GetWriteBuf( size ) ; memcpy( data , CGBitmapContextGetData(context) , size ) ; m_memBuf.UngetWriteBuf( size ) ; +#endif // determine content scale CGRect userrect = CGRectMake(0, 0, 10, 10); CGRect devicerect; devicerect = CGContextConvertRectToDeviceSpace(context, userrect); m_scaleFactor = devicerect.size.height / userrect.size.height; - + CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(context); - + if ( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast ) { // no alpha } else { +#if !wxOSX_BITMAP_NATIVE_ACCESS m_hasAlpha = true; +#endif } } m_ok = ( m_hBitmap != NULL ) ; @@ -370,6 +342,9 @@ bool wxBitmapRefData::Create(CGContextRef context) bool wxBitmapRefData::Create( int w , int h , int d, double logicalscale ) { +#if wxOSX_BITMAP_NATIVE_ACCESS + int m_width, m_height, m_depth, m_bytesPerRow; +#endif m_width = wxMax(1, w); m_height = wxMax(1, h); m_depth = d ; @@ -377,18 +352,23 @@ bool wxBitmapRefData::Create( int w , int h , int d, double logicalscale ) m_hBitmap = NULL ; m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ; +#if !wxOSX_BITMAP_NATIVE_ACCESS size_t size = m_bytesPerRow * m_height ; void* data = m_memBuf.GetWriteBuf( size ) ; if ( data != NULL ) { memset( data , 0 , size ) ; m_memBuf.UngetWriteBuf( size ) ; - +#else + void* data = NULL; +#endif m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst ); wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ; CGContextTranslateCTM( m_hBitmap, 0, m_height ); - CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor ); + CGContextScaleCTM( m_hBitmap, 1*GetScaleFactor(), -1*GetScaleFactor() ); +#if !wxOSX_BITMAP_NATIVE_ACCESS } /* data != NULL */ +#endif m_ok = ( m_hBitmap != NULL ) ; return m_ok ; @@ -396,31 +376,57 @@ bool wxBitmapRefData::Create( int w , int h , int d, double logicalscale ) void wxBitmapRefData::UseAlpha( bool use ) { - if ( m_hasAlpha == use ) + if ( HasAlpha() == use ) return ; +#if !wxOSX_BITMAP_NATIVE_ACCESS m_hasAlpha = use ; + void *data = m_memBuf.GetData(); +#else + void *data = NULL; +#endif + CGContextRef hBitmap = CGBitmapContextCreate(data, GetWidth(), GetHeight(), 8, GetBytesPerRow(), wxMacGetGenericRGBColorSpace(), use ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst ); +#if wxOSX_BITMAP_NATIVE_ACCESS + memcpy(CGBitmapContextGetData(hBitmap),CGBitmapContextGetData(m_hBitmap),GetBytesPerRow()*GetHeight()); +#endif + wxASSERT_MSG( hBitmap , wxT("Unable to create CGBitmapContext context") ) ; + CGContextTranslateCTM( hBitmap, 0, GetHeight() ); + CGContextScaleCTM( hBitmap, 1*GetScaleFactor(), -1*GetScaleFactor() ); - CGContextRelease( m_hBitmap ); - m_hBitmap = CGBitmapContextCreate((char*) m_memBuf.GetData(), m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), m_hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst ); - wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ; - CGContextTranslateCTM( m_hBitmap, 0, m_height ); - CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor ); + m_hBitmap.reset(hBitmap); } -void *wxBitmapRefData::GetRawAccess() const +const void *wxBitmapRefData::GetRawAccess() const { wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ; +#if !wxOSX_BITMAP_NATIVE_ACCESS return m_memBuf.GetData() ; +#else + return CGBitmapContextGetData(m_hBitmap); +#endif } +void *wxBitmapRefData::GetRawAccess() +{ + wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ; + wxASSERT_MSG( m_rawAccessCount == 1, "Direct write access must be within Begin/EndRawAccess" ) ; +#if !wxOSX_BITMAP_NATIVE_ACCESS + return m_memBuf.GetData() ; +#else + return CGBitmapContextGetData(m_hBitmap); +#endif +} + + void *wxBitmapRefData::BeginRawAccess() { wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ) ; wxASSERT( m_rawAccessCount == 0 ) ; #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF wxASSERT_MSG( m_iconRef == NULL , wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; +#endif #endif ++m_rawAccessCount ; @@ -432,7 +438,7 @@ void *wxBitmapRefData::BeginRawAccess() m_cgImageRef = NULL ; } - return m_memBuf.GetData() ; + return GetRawAccess() ; } void wxBitmapRefData::EndRawAccess() @@ -453,6 +459,7 @@ bool wxBitmapRefData::HasNativeSize() } #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF IconRef wxBitmapRefData::GetIconRef() { if ( m_iconRef == NULL ) @@ -534,7 +541,7 @@ IconRef wxBitmapRefData::GetIconRef() unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ; unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; - for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) + for ( int y = 0 ; y < h ; ++y, sourcePtr += GetBytesPerRow() , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) { unsigned char * source = sourcePtr; unsigned char * masksource = masksourcePtr; @@ -610,7 +617,7 @@ IconRef wxBitmapRefData::GetIconRef() unsigned char * sourcePtr = (unsigned char*) GetRawAccess() ; unsigned char * masksourcePtr = mask ? (unsigned char*) mask->GetRawAccess() : NULL ; - for ( int y = 0 ; y < h ; ++y, sourcePtr += m_bytesPerRow , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) + for ( int y = 0 ; y < h ; ++y, sourcePtr += GetBytesPerRow() , masksourcePtr += mask ? mask->GetBytesPerRow() : 0 ) { unsigned char * source = sourcePtr; unsigned char * masksource = masksourcePtr; @@ -664,7 +671,7 @@ IconRef wxBitmapRefData::GetIconRef() return m_iconRef ; } - +#endif #endif CGImageRef wxBitmapRefData::CreateCGImage() const @@ -674,7 +681,7 @@ CGImageRef wxBitmapRefData::CreateCGImage() const CGImageRef image ; if ( m_rawAccessCount > 0 || m_cgImageRef == NULL ) { - if ( m_depth != 1 && m_bitmapMask == NULL ) + if ( GetDepth() != 1 && m_bitmapMask == NULL ) { #if 0 // in order for this code to work properly, wxMask would have to invert black and white @@ -693,10 +700,10 @@ CGImageRef wxBitmapRefData::CreateCGImage() const } else { - size_t imageSize = m_height * m_bytesPerRow ; - void * dataBuffer = m_memBuf.GetData() ; - int w = m_width ; - int h = m_height ; + size_t imageSize = GetHeight() * GetBytesPerRow() ; + + int w = GetWidth() ; + int h = GetHeight() ; CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ; wxMemoryBuffer membuf; @@ -704,10 +711,10 @@ CGImageRef wxBitmapRefData::CreateCGImage() const { alphaInfo = kCGImageAlphaFirst ; unsigned char *destalphastart = (unsigned char*) membuf.GetWriteBuf( imageSize ) ; - memcpy( destalphastart , dataBuffer , imageSize ) ; + memcpy( destalphastart , GetRawAccess() , imageSize ) ; unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ; int maskrowbytes = m_bitmapMask->GetBytesPerRow() ; - for ( int y = 0 ; y < h ; ++y , destalphastart += m_bytesPerRow, sourcemaskstart += maskrowbytes) + for ( int y = 0 ; y < h ; ++y , destalphastart += GetBytesPerRow(), sourcemaskstart += maskrowbytes) { unsigned char *sourcemask = sourcemaskstart ; unsigned char *destalpha = destalphastart ; @@ -720,7 +727,7 @@ CGImageRef wxBitmapRefData::CreateCGImage() const } else { - if ( m_hasAlpha ) + if ( HasAlpha() ) { #if wxOSX_USE_PREMULTIPLIED_ALPHA alphaInfo = kCGImageAlphaPremultipliedFirst ; @@ -728,33 +735,35 @@ CGImageRef wxBitmapRefData::CreateCGImage() const alphaInfo = kCGImageAlphaFirst ; #endif } - - membuf = m_memBuf; +#if wxOSX_BITMAP_NATIVE_ACCESS + memcpy(membuf.GetWriteBuf( imageSize ),GetRawAccess(),imageSize); + membuf.UngetWriteBuf(imageSize); +#endif } CGDataProviderRef dataProvider = NULL ; - if ( m_depth == 1 ) + if ( GetDepth() == 1 ) { // TODO CHECK ALIGNMENT wxMemoryBuffer maskBuf; - unsigned char * maskBufData = (unsigned char*) maskBuf.GetWriteBuf( m_width * m_height ); + unsigned char * maskBufData = (unsigned char*) maskBuf.GetWriteBuf( GetWidth() * GetHeight() ); unsigned char * bufData = (unsigned char *) membuf.GetData() ; // copy one color component size_t i = 0; - for( int y = 0 ; y < m_height ; bufData+= m_bytesPerRow, ++y ) + for( int y = 0 ; y < GetHeight() ; bufData+= GetBytesPerRow(), ++y ) { unsigned char *bufDataIter = bufData+3; - for ( int x = 0 ; x < m_width ; bufDataIter += 4, ++x, ++i ) + for ( int x = 0 ; x < GetWidth() ; bufDataIter += 4, ++x, ++i ) { maskBufData[i] = *bufDataIter; } } - maskBuf.UngetWriteBuf( m_width * m_height ); + maskBuf.UngetWriteBuf( GetWidth() * GetHeight() ); dataProvider = wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf ); - image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false ); + image = ::CGImageMaskCreate( w, h, 8, 8, GetWidth() , dataProvider, NULL, false ); } else { @@ -762,7 +771,7 @@ CGImageRef wxBitmapRefData::CreateCGImage() const dataProvider = wxMacCGDataProviderCreateWithMemoryBuffer( membuf ); image = ::CGImageCreate( - w, h, 8 , 32 , m_bytesPerRow , colorSpace, alphaInfo , + w, h, 8 , 32 , GetBytesPerRow() , colorSpace, alphaInfo , dataProvider, NULL , false , kCGRenderingIntentDefault ); } CGDataProviderRelease( dataProvider); @@ -789,6 +798,30 @@ CGContextRef wxBitmapRefData::GetBitmapContext() const return m_hBitmap; } +void wxBitmapRefData::SetSelectedInto(wxDC *dc) +{ + if ( dc == NULL ) + { + if ( m_selectedInto != NULL ) + EndRawAccess(); + } + else + { + wxASSERT_MSG( m_selectedInto == NULL || m_selectedInto == dc, "Bitmap already selected into a different dc"); + + if ( m_selectedInto == NULL ) + (void) BeginRawAccess(); + } + + m_selectedInto = dc; +} + +wxDC *wxBitmapRefData::GetSelectedInto() const +{ + return m_selectedInto; +} + + void wxBitmapRefData::Free() { wxASSERT_MSG( m_rawAccessCount == 0 , wxT("Bitmap still selected when destroyed") ) ; @@ -799,18 +832,15 @@ void wxBitmapRefData::Free() m_cgImageRef = NULL ; } #ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF if ( m_iconRef ) { ReleaseIconRef( m_iconRef ) ; m_iconRef = NULL ; } #endif - if ( m_hBitmap ) - { - CGContextRelease(m_hBitmap); - m_hBitmap = NULL ; - } - +#endif + m_hBitmap.reset(); wxDELETE(m_bitmapMask); } @@ -848,11 +878,9 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits) { - wxBitmapRefData* bitmapRefData; + m_refData = new wxBitmapRefData( the_width , the_height , no_bits ) ; - m_refData = bitmapRefData = new wxBitmapRefData( the_width , the_height , no_bits ) ; - - if (bitmapRefData->IsOk()) + if (GetBitmapData()->IsOk()) { if ( no_bits == 1 ) { @@ -861,9 +889,9 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits linesize++; unsigned char* linestart = (unsigned char*) bits ; - unsigned char* destptr = (unsigned char*) BeginRawAccess() ; + unsigned char* destptr = (unsigned char*) GetBitmapData()->BeginRawAccess() ; - for ( int y = 0 ; y < the_height ; ++y , linestart += linesize, destptr += M_BITMAPDATA->GetBytesPerRow() ) + for ( int y = 0 ; y < the_height ; ++y , linestart += linesize, destptr += GetBitmapData()->GetBytesPerRow() ) { unsigned char* destination = destptr; int index, bit, mask; @@ -891,13 +919,13 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits } } - EndRawAccess() ; + GetBitmapData()->EndRawAccess() ; } else { wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); } - } /* bitmapRefData->IsOk() */ + } } wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, int depth) @@ -930,40 +958,43 @@ wxGDIRefData* wxBitmap::CloneGDIRefData(const wxGDIRefData* data) const return new wxBitmapRefData(*static_cast(data)); } -void * wxBitmap::GetRawAccess() const +#if WXWIN_COMPATIBILITY_3_0 +const void * wxBitmap::GetRawAccess() const { wxCHECK_MSG( IsOk() , NULL , wxT("invalid bitmap") ) ; - return M_BITMAPDATA->GetRawAccess() ; + return GetBitmapData()->GetRawAccess() ; } void * wxBitmap::BeginRawAccess() { wxCHECK_MSG( IsOk() , NULL , wxT("invalid bitmap") ) ; - return M_BITMAPDATA->BeginRawAccess() ; + return GetBitmapData()->BeginRawAccess() ; } void wxBitmap::EndRawAccess() { wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; - M_BITMAPDATA->EndRawAccess() ; + GetBitmapData()->EndRawAccess() ; } +#endif CGImageRef wxBitmap::CreateCGImage() const { wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ; - return M_BITMAPDATA->CreateCGImage() ; + return GetBitmapData()->CreateCGImage() ; } -#ifndef __WXOSX_IPHONE__ +#if wxOSX_USE_ICONREF + IconRef wxBitmap::GetIconRef() const { wxCHECK_MSG( IsOk(), NULL , wxT("invalid bitmap") ) ; - return M_BITMAPDATA->GetIconRef() ; + return GetBitmapData()->GetIconRef() ; } IconRef wxBitmap::CreateIconRef() const @@ -986,7 +1017,7 @@ bool wxBitmap::Create(WX_NSImage image) bool isTemplate; if (!Create(wxOSXCreateBitmapContextFromNSImage(image, &isTemplate))) return false; - M_BITMAPDATA->SetTemplate(isTemplate); + GetBitmapData()->SetTemplate(isTemplate); return true; } @@ -998,16 +1029,16 @@ wxBitmap::wxBitmap(CGContextRef bitmapcontext) bool wxBitmap::Create(CGContextRef bitmapcontext) { UnRef(); - + m_refData = new wxBitmapRefData( bitmapcontext ); - - return M_BITMAPDATA->IsOk() ; + + return GetBitmapData()->IsOk() ; } WX_NSImage wxBitmap::GetNSImage() const { wxCFRef< CGImageRef > cgimage(CreateCGImage()); - return wxOSXGetNSImageFromCGImage( cgimage, GetScaleFactor(), M_BITMAPDATA->IsTemplate() ); + return wxOSXGetNSImageFromCGImage( cgimage, GetScaleFactor(), GetBitmapData()->IsTemplate() ); } #endif @@ -1038,8 +1069,8 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const int destheight = rect.height*scale ; { - unsigned char *sourcedata = (unsigned char*) GetRawAccess() ; - unsigned char *destdata = (unsigned char*) ret.BeginRawAccess() ; + unsigned char *sourcedata = (unsigned char*) GetBitmapData()->GetRawAccess() ; + unsigned char *destdata = (unsigned char*) ret.GetBitmapData()->BeginRawAccess() ; wxASSERT((sourcedata != NULL) && (destdata != NULL)); if ( (sourcedata != NULL) && (destdata != NULL) ) @@ -1054,20 +1085,19 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const memcpy( dest , source , destlinesize ) ; } } - ret.EndRawAccess() ; + ret.GetBitmapData()->EndRawAccess() ; } - - if ( M_BITMAPDATA->m_bitmapMask ) + if ( GetBitmapData()->m_bitmapMask ) { wxMemoryBuffer maskbuf ; int rowBytes = GetBestBytesPerRow( destwidth * kMaskBytesPerPixel ); size_t maskbufsize = rowBytes * destheight ; - int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ; + int sourcelinesize = GetBitmapData()->m_bitmapMask->GetBytesPerRow() ; int destlinesize = rowBytes ; - unsigned char *source = (unsigned char *) M_BITMAPDATA->m_bitmapMask->GetRawAccess() ; + unsigned char *source = (unsigned char *) GetBitmapData()->m_bitmapMask->GetRawAccess() ; unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ; wxASSERT( (source != NULL) && (destdata != NULL) ) ; @@ -1102,7 +1132,7 @@ bool wxBitmap::Create(int w, int h, int d) m_refData = new wxBitmapRefData( w , h , d ); - return M_BITMAPDATA->IsOk() ; + return GetBitmapData()->IsOk() ; } bool wxBitmap::Create(int w, int h, const wxDC& dc) @@ -1114,22 +1144,22 @@ bool wxBitmap::Create(int w, int h, const wxDC& dc) bool wxBitmap::CreateScaled(int w, int h, int d, double logicalScale) { UnRef(); - + if ( d < 0 ) d = wxDisplayDepth() ; - + m_refData = new wxBitmapRefData( w*logicalScale , h*logicalScale , d, logicalScale ); - - return M_BITMAPDATA->IsOk() ; + + return GetBitmapData()->IsOk() ; } bool wxBitmap::Create(CGImageRef image, double scale) { UnRef(); - + m_refData = new wxBitmapRefData( image, scale ); - - return M_BITMAPDATA->IsOk() ; + + return GetBitmapData()->IsOk() ; } bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) @@ -1149,7 +1179,7 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) #if wxUSE_IMAGE double scale = 1.0; wxString fname = filename; - + if ( type == wxBITMAP_TYPE_PNG ) { if ( wxOSXGetMainScreenContentScaleFactor() > 1.9 ) @@ -1157,7 +1187,7 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) wxFileName fn(filename); fn.MakeAbsolute(); fn.SetName(fn.GetName()+"@2x"); - + if ( fn.Exists() ) { fname = fn.GetFullPath(); @@ -1210,7 +1240,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) int height = image.GetHeight(); // we always use 32 bit internally here depth = 32; - + wxBitmapRefData* bitmapRefData; m_refData = bitmapRefData = new wxBitmapRefData( width, height, depth, scale) ; @@ -1233,12 +1263,12 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) if ( hasAlpha ) UseAlpha() ; - unsigned char* destinationstart = (unsigned char*) BeginRawAccess() ; + unsigned char* destinationstart = (unsigned char*) GetBitmapData()->BeginRawAccess() ; unsigned char* data = image.GetData(); if ( destinationstart != NULL && data != NULL ) { const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ; - for (int y = 0; y < height; destinationstart += M_BITMAPDATA->GetBytesPerRow(), y++) + for (int y = 0; y < height; destinationstart += GetBitmapData()->GetBytesPerRow(), y++) { unsigned char * destination = destinationstart; for (int x = 0; x < width; x++) @@ -1268,11 +1298,11 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) } } - EndRawAccess() ; + GetBitmapData()->EndRawAccess() ; } if ( image.HasMask() ) SetMask( new wxMask( *this , wxColour( image.GetMaskRed() , image.GetMaskGreen() , image.GetMaskBlue() ) ) ) ; - } /* bitmapRefData->IsOk() */ + } } wxImage wxBitmap::ConvertToImage() const @@ -1289,7 +1319,7 @@ wxImage wxBitmap::ConvertToImage() const unsigned char *data = image.GetData(); wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); - unsigned char* sourcestart = (unsigned char*) GetRawAccess() ; + unsigned char* sourcestart = (unsigned char*) GetBitmapData()->GetRawAccess() ; bool hasAlpha = false ; bool hasMask = false ; @@ -1323,7 +1353,7 @@ wxImage wxBitmap::ConvertToImage() const static const int MASK_BLUE = 3; static const int MASK_BLUE_REPLACEMENT = 2; - for (int yy = 0; yy < height; yy++ , sourcestart += M_BITMAPDATA->GetBytesPerRow() , mask += maskBytesPerRow ) + for (int yy = 0; yy < height; yy++ , sourcestart += GetBitmapData()->GetBytesPerRow() , mask += maskBytesPerRow ) { unsigned char * maskp = mask ; const wxUint32 * source = (wxUint32*)sourcestart; @@ -1411,66 +1441,66 @@ int wxBitmap::GetHeight() const { wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->GetHeight(); + return GetBitmapData()->GetHeight(); } int wxBitmap::GetWidth() const { wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->GetWidth() ; + return GetBitmapData()->GetWidth() ; } double wxBitmap::GetScaleFactor() const { wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); - - return M_BITMAPDATA->GetScaleFactor() ; + + return GetBitmapData()->GetScaleFactor() ; } int wxBitmap::GetDepth() const { wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); - return M_BITMAPDATA->GetDepth(); + return GetBitmapData()->GetDepth(); } wxMask *wxBitmap::GetMask() const { wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ); - return M_BITMAPDATA->m_bitmapMask; + return GetBitmapData()->m_bitmapMask; } bool wxBitmap::HasAlpha() const { wxCHECK_MSG( IsOk(), false , wxT("invalid bitmap") ); - return M_BITMAPDATA->HasAlpha() ; + return GetBitmapData()->HasAlpha() ; } void wxBitmap::SetWidth(int w) { AllocExclusive(); - M_BITMAPDATA->SetWidth(w); + wxASSERT_MSG( GetWidth() == w, "Changing the bitmap width is not supported"); } void wxBitmap::SetHeight(int h) { AllocExclusive(); - M_BITMAPDATA->SetHeight(h); + wxASSERT_MSG( GetHeight() == h, "Changing the bitmap height is not supported"); } void wxBitmap::SetDepth(int d) { AllocExclusive(); - M_BITMAPDATA->SetDepth(d); + wxASSERT_MSG( d == -1 || GetDepth() == d, "Changing the bitmap depth is not supported"); } void wxBitmap::SetOk(bool isOk) { AllocExclusive(); - M_BITMAPDATA->SetOk(isOk); + GetBitmapData()->SetOk(isOk); } #if wxUSE_PALETTE @@ -1478,13 +1508,13 @@ wxPalette *wxBitmap::GetPalette() const { wxCHECK_MSG( IsOk(), NULL, wxT("Invalid bitmap GetPalette()") ); - return &M_BITMAPDATA->m_bitmapPalette; + return & const_cast(GetBitmapData())->m_bitmapPalette; } void wxBitmap::SetPalette(const wxPalette& palette) { AllocExclusive(); - M_BITMAPDATA->m_bitmapPalette = palette ; + GetBitmapData()->m_bitmapPalette = palette ; } #endif // wxUSE_PALETTE @@ -1492,16 +1522,16 @@ void wxBitmap::SetMask(wxMask *mask) { AllocExclusive(); // Remove existing mask if there is one. - delete M_BITMAPDATA->m_bitmapMask; + delete GetBitmapData()->m_bitmapMask; - M_BITMAPDATA->m_bitmapMask = mask ; + GetBitmapData()->m_bitmapMask = mask ; } WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const { wxUnusedVar(mask); - return WXHBITMAP(M_BITMAPDATA->GetBitmapContext()); + return WXHBITMAP(GetBitmapData()->GetBitmapContext()); } // ---------------------------------------------------------------------------- @@ -1513,20 +1543,13 @@ wxMask::wxMask() Init() ; } -wxMask::wxMask(const wxMask &tocopy) : wxObject() +wxMask::wxMask(const wxMask &tocopy) : wxMaskBase() { Init(); - m_bytesPerRow = tocopy.m_bytesPerRow; - m_width = tocopy.m_width; - m_height = tocopy.m_height; - - size_t size = m_bytesPerRow * m_height; - unsigned char* dest = (unsigned char*)m_memBuf.GetWriteBuf( size ); - unsigned char* source = (unsigned char*)tocopy.m_memBuf.GetData(); - memcpy( dest, source, size ); - m_memBuf.UngetWriteBuf( size ) ; - RealizeNative() ; + DoCreateMaskBitmap( tocopy.GetWidth(), tocopy.GetHeight(), tocopy.GetBytesPerRow()); + int size = tocopy.GetHeight() * tocopy.GetBytesPerRow(); + memcpy( GetRawAccess(), tocopy.GetRawAccess(), size); } // Construct a mask from a bitmap and a colour indicating @@ -1534,14 +1557,14 @@ wxMask::wxMask(const wxMask &tocopy) : wxObject() wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour ) { Init() ; - Create( bitmap, colour ); + wxMaskBase::Create( bitmap, colour ); } // Construct a mask from a mono bitmap (copies the bitmap). wxMask::wxMask( const wxBitmap& bitmap ) { Init() ; - Create( bitmap ); + wxMaskBase::Create( bitmap ); } // Construct a mask from a mono bitmap (copies the bitmap). @@ -1554,29 +1577,82 @@ wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPe wxMask::~wxMask() { - if ( m_maskBitmap ) - { - CGContextRelease( (CGContextRef) m_maskBitmap ); - m_maskBitmap = NULL ; - } } void wxMask::Init() { +#if !wxOSX_BITMAP_NATIVE_ACCESS m_width = m_height = m_bytesPerRow = 0 ; - m_maskBitmap = NULL ; +#endif } void *wxMask::GetRawAccess() const { + wxCHECK_MSG( m_maskBitmap, NULL , wxT("invalid mask") ) ; +#if !wxOSX_BITMAP_NATIVE_ACCESS return m_memBuf.GetData() ; +#else + return CGBitmapContextGetData(m_maskBitmap); +#endif } +int wxMask::GetBytesPerRow() const +{ +#if !wxOSX_BITMAP_NATIVE_ACCESS + return m_bytesPerRow ; +#else + return CGBitmapContextGetBytesPerRow(m_maskBitmap); +#endif +} + +int wxMask::GetWidth() const +{ +#if !wxOSX_BITMAP_NATIVE_ACCESS + return m_width ; +#else + return CGBitmapContextGetWidth(m_maskBitmap); +#endif +} + +int wxMask::GetHeight() const +{ +#if !wxOSX_BITMAP_NATIVE_ACCESS + return m_height ; +#else + return CGBitmapContextGetHeight(m_maskBitmap); +#endif +} + + // The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed // bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well +void wxMask::DoCreateMaskBitmap(int width, int height, int bytesPerRow) +{ + wxCFRef colorspace = CGColorSpaceCreateDeviceGray(); + + if ( bytesPerRow < 0 ) + bytesPerRow = GetBestBytesPerRow(width * kMaskBytesPerPixel); +#if !wxOSX_BITMAP_NATIVE_ACCESS + m_width = width; + m_height = height; + m_bytesPerRow = bytesPerRow; + size_t size = m_bytesPerRow * m_height; + unsigned char* data = (unsigned char*)m_memBuf.GetWriteBuf(size); +#else + unsigned char* data = NULL; +#endif + m_maskBitmap = CGBitmapContextCreate(data, width, height, kMaskBytesPerPixel * 8, bytesPerRow, colorspace, + kCGImageAlphaNone); +#if !wxOSX_BITMAP_NATIVE_ACCESS + m_memBuf.UngetWriteBuf(size); +#endif + wxASSERT_MSG(m_maskBitmap, wxT("Unable to create CGBitmapContext context")); +} + void wxMask::RealizeNative() { +#if 0 if ( m_maskBitmap ) { CGContextRelease( (CGContextRef) m_maskBitmap ); @@ -1592,104 +1668,103 @@ void wxMask::RealizeNative() kCGImageAlphaNone ); CGColorSpaceRelease( colorspace ); wxASSERT_MSG( m_maskBitmap , wxT("Unable to create CGBitmapContext context") ) ; +#endif } // Create a mask from a mono bitmap (copies the bitmap). bool wxMask::Create(const wxMemoryBuffer& data,int width , int height , int bytesPerRow) { - m_memBuf = data ; - m_width = width ; - m_height = height ; - m_bytesPerRow = bytesPerRow ; - wxASSERT( data.GetDataLen() == (size_t)(height * bytesPerRow) ) ; + DoCreateMaskBitmap(width, height, bytesPerRow); + RealizeNative() ; return true ; } -// Create a mask from a mono bitmap (copies the bitmap). -bool wxMask::Create(const wxBitmap& bitmap) +bool wxMask::InitFromMonoBitmap(const wxBitmap& bitmap) { +#if wxOSX_BITMAP_NATIVE_ACCESS + int m_width, m_height, m_bytesPerRow; +#endif m_width = bitmap.GetWidth() ; m_height = bitmap.GetHeight() ; - m_bytesPerRow = GetBestBytesPerRow( m_width * kMaskBytesPerPixel ) ; - size_t size = m_bytesPerRow * m_height ; - unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; + DoCreateMaskBitmap(m_width, m_height); +#if wxOSX_BITMAP_NATIVE_ACCESS + m_bytesPerRow = GetBytesPerRow(); +#endif + + // pixel access needs a non-const bitmap currently + wxBitmap bmp(bitmap); + wxNativePixelData data(bmp); + + wxNativePixelData::Iterator p(data); + + unsigned char * destdatabase = (unsigned char*) GetRawAccess(); wxASSERT( destdatabase != NULL ) ; - - if ( destdatabase ) + if ( destdatabase != NULL) { - memset( destdatabase , 0 , size ) ; - unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; - - for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow ) + for ( int y = 0 ; y < m_height; ++y, destdatabase += m_bytesPerRow ) { + wxNativePixelData::Iterator rowStart = p; unsigned char *destdata = destdatabase ; - unsigned char r, g, b; - - for ( int x = 0 ; x < m_width ; ++x ) + for ( int x = 0 ; x < m_width ; ++x, ++p ) { - srcdata++ ; - r = *srcdata++ ; - g = *srcdata++ ; - b = *srcdata++ ; - - if ( ( r + g + b ) > 0x10 ) + if ( ( p.Red() + p.Green() + p.Blue() ) > 0x10 ) *destdata++ = 0xFF ; else *destdata++ = 0x00 ; } + p = rowStart; + p.OffsetY(data, 1); } } - m_memBuf.UngetWriteBuf( size ) ; - RealizeNative() ; - return true; } -// Create a mask from a bitmap and a colour indicating -// the transparent area -bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) +bool wxMask::InitFromColour(const wxBitmap& bitmap, const wxColour& colour) { +#if wxOSX_BITMAP_NATIVE_ACCESS + int m_width, m_height, m_bytesPerRow; +#endif m_width = bitmap.GetWidth() ; m_height = bitmap.GetHeight() ; - m_bytesPerRow = GetBestBytesPerRow( m_width * kMaskBytesPerPixel ) ; - size_t size = m_bytesPerRow * m_height ; - unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; + DoCreateMaskBitmap(m_width, m_height); +#if wxOSX_BITMAP_NATIVE_ACCESS + m_bytesPerRow = GetBytesPerRow(); +#endif + + // pixel access needs a non-const bitmap currently + wxBitmap bmp(bitmap); + wxNativePixelData data(bmp); + + wxNativePixelData::Iterator p(data); + + unsigned char * destdatabase = (unsigned char*) GetRawAccess(); wxASSERT( destdatabase != NULL ) ; if ( destdatabase != NULL) { - memset( destdatabase , 0 , size ) ; - unsigned char * srcdatabase = (unsigned char*) bitmap.GetRawAccess() ; - size_t sourceBytesRow = bitmap.GetBitmapData()->GetBytesPerRow(); - - for ( int y = 0 ; y < m_height ; ++y , srcdatabase+= sourceBytesRow, destdatabase += m_bytesPerRow) + for ( int y = 0 ; y < m_height; ++y, destdatabase += m_bytesPerRow ) { - unsigned char *srcdata = srcdatabase ; + wxNativePixelData::Iterator rowStart = p; unsigned char *destdata = destdatabase ; - unsigned char r, g, b; - - for ( int x = 0 ; x < m_width ; ++x ) + for ( int x = 0 ; x < m_width ; ++x, ++p ) { - srcdata++ ; - r = *srcdata++ ; - g = *srcdata++ ; - b = *srcdata++ ; - - if ( colour == wxColour( r , g , b ) ) + if ( wxColour( p.Red(), p.Green(), p.Blue() ) == colour ) *destdata++ = 0xFF ; else *destdata++ = 0x00 ; - } + } + p = rowStart; + p.OffsetY(data, 1); } } - m_memBuf.UngetWriteBuf( size ) ; + RealizeNative() ; return true; @@ -1697,23 +1772,36 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) wxBitmap wxMask::GetBitmap() const { - wxBitmap bitmap(m_width, m_height, 1); - unsigned char* dst = static_cast(bitmap.BeginRawAccess()); - const int dst_stride = bitmap.GetBitmapData()->GetBytesPerRow(); - const unsigned char* src = static_cast(GetRawAccess()); - for (int j = 0; j < m_height; j++, src += m_bytesPerRow, dst += dst_stride) +#if wxOSX_BITMAP_NATIVE_ACCESS + int m_width, m_height, m_bytesPerRow; + m_width = GetWidth(); + m_height = GetHeight(); + m_bytesPerRow = GetBytesPerRow(); +#endif + + wxBitmap bitmap(m_width, m_height, 32); + wxNativePixelData data(bitmap); + + wxNativePixelData::Iterator p(data); + + const unsigned char* srcbase = static_cast(GetRawAccess()); + + for (int y = 0; y < m_height; ++y, srcbase += m_bytesPerRow) { - unsigned char* d = dst; - for (int i = 0; i < m_width; i++) + wxNativePixelData::Iterator rowStart = p; + const unsigned char* src = srcbase; + for (int x = 0; x < m_width; ++x, ++p, ++src) { - const unsigned char byte = src[i]; - *d++ = 0xff; - *d++ = byte; - *d++ = byte; - *d++ = byte; + const unsigned char byte = *src; + p.Alpha() = 0xff; + p.Red() = byte; + p.Green() = byte; + p.Blue() = byte; } + p = rowStart; + p.OffsetY(data, 1); } - bitmap.EndRawAccess(); + return bitmap; } @@ -1722,6 +1810,12 @@ WXHBITMAP wxMask::GetHBITMAP() const return m_maskBitmap ; } +void wxMask::FreeData() +{ + return m_maskBitmap.reset(); +} + + // ---------------------------------------------------------------------------- // Standard Handlers // ---------------------------------------------------------------------------- @@ -1729,12 +1823,12 @@ WXHBITMAP wxMask::GetHBITMAP() const class WXDLLEXPORT wxBundleResourceHandler: public wxBitmapHandler { wxDECLARE_ABSTRACT_CLASS(wxBundleResourceHandler); - + public: inline wxBundleResourceHandler() { } - + virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, wxBitmapType type, @@ -1847,27 +1941,40 @@ void wxBitmap::InitStandardHandlers() // raw bitmap access support // ---------------------------------------------------------------------------- -void *wxBitmap::GetRawData(wxPixelDataBase& data, int WXUNUSED(bpp)) +void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp) { if ( !IsOk() ) // no bitmap, no data (raw or otherwise) return NULL; + if ( bpp != GetDepth() ) + return NULL; + data.m_width = GetWidth() ; data.m_height = GetHeight() ; data.m_stride = GetBitmapData()->GetBytesPerRow() ; - return BeginRawAccess() ; + return GetBitmapData()->BeginRawAccess() ; } void wxBitmap::UngetRawData(wxPixelDataBase& WXUNUSED(dataBase)) { - EndRawAccess() ; + GetBitmapData()->EndRawAccess() ; } void wxBitmap::UseAlpha(bool use ) { // remember that we are using alpha channel: // we'll need to create a proper mask in UngetRawData() - M_BITMAPDATA->UseAlpha( use ); + GetBitmapData()->UseAlpha( use ); +} + +void wxBitmap::SetSelectedInto(wxDC *dc) +{ + GetBitmapData()->SetSelectedInto(dc) ; +} + +wxDC* wxBitmap::GetSelectedInto() const +{ + return GetBitmapData()->GetSelectedInto() ; } diff --git a/src/osx/core/dcmemory.cpp b/src/osx/core/dcmemory.cpp index 4d66d1cef9..4aba6ca8a0 100644 --- a/src/osx/core/dcmemory.cpp +++ b/src/osx/core/dcmemory.cpp @@ -56,7 +56,7 @@ wxMemoryDCImpl::~wxMemoryDCImpl() { if ( m_selected.IsOk() ) { - m_selected.EndRawAccess() ; + m_selected.SetSelectedInto(NULL); wxDELETE(m_graphicContext); } } @@ -65,14 +65,18 @@ void wxMemoryDCImpl::DoSelect( const wxBitmap& bitmap ) { if ( m_selected.IsOk() ) { - m_selected.EndRawAccess() ; + m_selected.SetSelectedInto(NULL); wxDELETE(m_graphicContext); } m_selected = bitmap; if (m_selected.IsOk()) { - m_selected.BeginRawAccess() ; + wxASSERT_MSG( !bitmap.GetSelectedInto() || + (bitmap.GetSelectedInto() == GetOwner()), + wxT("Bitmap is selected in another wxMemoryDC, delete the first wxMemoryDC or use SelectObject(NULL)") ); + + m_selected.SetSelectedInto(GetOwner()); m_width = bitmap.GetScaledWidth(); m_height = bitmap.GetScaledHeight(); m_contentScaleFactor = bitmap.GetScaleFactor();