Initial Commit of full native bitmap macOS implementation

Right now, to better test regressions, with dual implementation
This commit is contained in:
Stefan Csomor 2018-09-07 21:44:19 +02:00 committed by Vadim Zeitlin
parent a5aa044a7b
commit e7d21f6638
10 changed files with 532 additions and 302 deletions

View File

@ -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

View File

@ -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<CGContextRef> 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;

View File

@ -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);

View File

@ -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 ;

View File

@ -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

View File

@ -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 );

View File

@ -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);

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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();