From f29faa0217e827871c841a209dc228810bf590d4 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 22 Sep 2018 10:18:27 +0200 Subject: [PATCH] optimize handling of high-res native images --- include/wx/osx/cocoa/private.h | 2 +- include/wx/osx/core/private.h | 2 -- src/osx/carbon/utilscocoa.mm | 20 +++++++++++++++----- src/osx/core/bitmap.cpp | 29 ++++++++++------------------- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index 599ad14eb6..de91d02245 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -41,7 +41,7 @@ WX_NSImage WXDLLIMPEXP_CORE wxOSXGetNSImageFromCGImage( CGImageRef image, double 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); - +double WXDLLIMPEXP_CORE wxOSXGetImageScaleFactor(WXImage image); wxBitmap WXDLLIMPEXP_CORE wxOSXCreateSystemBitmap(const wxString& id, const wxString &client, const wxSize& size); WXWindow WXDLLIMPEXP_CORE wxOSXGetMainWindow(); WXWindow WXDLLIMPEXP_CORE wxOSXGetKeyWindow(); diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index 3ae1783205..b9cffaa443 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -104,8 +104,6 @@ protected : // Quartz -WXDLLIMPEXP_CORE CGImageRef wxMacCreateCGImageFromBitmap( const wxBitmap& bitmap ); - WXDLLIMPEXP_CORE CGDataProviderRef wxMacCGDataProviderCreateWithCFData( CFDataRef data ); WXDLLIMPEXP_CORE CGDataConsumerRef wxMacCGDataConsumerCreateWithCFData( CFMutableDataRef data ); WXDLLIMPEXP_CORE CGDataProviderRef wxMacCGDataProviderCreateWithMemoryBuffer( const wxMemoryBuffer& buf ); diff --git a/src/osx/carbon/utilscocoa.mm b/src/osx/carbon/utilscocoa.mm index 73a4d4a07b..6c5ace2279 100644 --- a/src/osx/carbon/utilscocoa.mm +++ b/src/osx/carbon/utilscocoa.mm @@ -248,11 +248,7 @@ CGContextRef WXDLLIMPEXP_CORE wxOSXCreateBitmapContextFromImage( WXImage nsimage { double scale = wxOSXGetMainScreenContentScaleFactor(); -#if wxOSX_USE_COCOA - NSSize imageSize = [nsimage size]; -#else - CGSize imageSize = [nsimage size]; -#endif + CGSize imageSize = wxOSXGetImageSize(nsimage); hbitmap = CGBitmapContextCreate(NULL, imageSize.width*scale, imageSize.height*scale, 8, 0, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst); CGContextScaleCTM( hbitmap, scale, scale ); @@ -329,6 +325,20 @@ void wxOSXSetImageSize(WXImage image, CGFloat width, CGFloat height) #endif } +double wxOSXGetImageScaleFactor(WXImage image) +{ +#if wxOSX_USE_COCOA + NSSize imagesize = [image size]; + int width = [[image bestRepresentationForRect:NSMakeRect(0, 0, imagesize.width, imagesize.height) context:nil hints:nil] pixelsWide]; + if ( width == 0 ) // there are multi-res representations which return 0 for the pixel dimensions + return wxOSXGetMainScreenContentScaleFactor(); + + return width / [image size].width; +#else + return [image scale]; +#endif +} + CGSize wxOSXGetImageSize(WXImage image) { #if wxOSX_USE_COCOA diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index a870521711..85d90e13bd 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -138,20 +138,6 @@ static size_t GetBestBytesPerRow( size_t rawBytes ) return (((rawBytes)+kBestByteAlignement-1) & ~(kBestByteAlignement-1) ); } -#if wxUSE_GUI && !defined(__WXOSX_IPHONE__) - -// this is used for more controls than just the wxBitmap button, also for notebooks etc - -CGImageRef wxMacCreateCGImageFromBitmap( const wxBitmap& bitmap ) -{ - const wxBitmapRefData * bmap = bitmap.GetBitmapData() ; - if ( bmap == NULL ) - return NULL ; - return (CGImageRef) bmap->CreateCGImage(); -} - -#endif //wxUSE_BMPBUTTON - void wxBitmapRefData::Init() { m_nsImage = NULL; @@ -230,6 +216,8 @@ bool wxBitmapRefData::Create( WXImage image ) wxMacCocoaRetain(image); + m_scaleFactor = wxOSXGetImageScaleFactor(image); + return true; } @@ -289,7 +277,7 @@ bool wxBitmapRefData::Create(int w, int h, int d, double logicalscale) size_t m_width = wxMax(1, w); size_t m_height = wxMax(1, h); - int m_scaleFactor = logicalscale; + m_scaleFactor = logicalscale; m_hBitmap = NULL; size_t m_bytesPerRow = GetBestBytesPerRow(m_width * 4); @@ -314,7 +302,7 @@ int wxBitmapRefData::GetWidth() const if ( m_hBitmap ) return (int) CGBitmapContextGetWidth(m_hBitmap); else - return (int) wxOSXGetImageSize(m_nsImage).width; + return (int) wxOSXGetImageSize(m_nsImage).width * m_scaleFactor; } int wxBitmapRefData::GetHeight() const @@ -324,7 +312,7 @@ int wxBitmapRefData::GetHeight() const if ( m_hBitmap ) return (int) CGBitmapContextGetHeight(m_hBitmap); else - return (int) wxOSXGetImageSize(m_nsImage).height; + return (int) wxOSXGetImageSize(m_nsImage).height * m_scaleFactor; } int wxBitmapRefData::GetDepth() const @@ -1274,6 +1262,11 @@ wxImage wxBitmap::ConvertToImage() const wxCHECK_MSG( IsOk(), wxNullImage, wxT("invalid bitmap") ); + // this call may trigger a conversion from platform image to bitmap, issue it + // before any measurements are taken, multi-resolution platform images may be + // rendered incorrectly otherwise + unsigned char* sourcestart = (unsigned char*) GetBitmapData()->GetRawAccess() ; + // create an wxImage object int width = GetWidth(); int height = GetHeight(); @@ -1282,8 +1275,6 @@ 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*) GetBitmapData()->GetRawAccess() ; - bool hasAlpha = false ; bool hasMask = false ; int maskBytesPerRow = 0 ;