Respect composition mode in wxOSX wxGraphicsContext::DrawBitmap()

Pass the current composition mode to wxOSXDrawNSImage() instead of
always using NSCompositeSourceOver in it.

See #23240, #23245.

(cherry picked from commit e269245b97ced95f60b11fb7ea988a3f7a993e7f with
some extra changes for ABI compatibility in 3.2)
This commit is contained in:
Stefan Csomor 2023-02-09 18:23:14 +01:00 committed by Vadim Zeitlin
parent 6e38c8081d
commit 393b57511c
4 changed files with 85 additions and 5 deletions

View File

@ -239,6 +239,10 @@ All:
- Add move ctor and assignment to wxString (Pavel Tyunin, #23224).
wxOSX:
- Respect composition mode when drawing bitmaps (#23240).
3.2.2: (released 2023-02-08)
----------------------------

View File

@ -34,10 +34,17 @@ OSStatus WXDLLIMPEXP_CORE wxMacDrawCGImage(
CGContextRef inContext,
const CGRect * inBounds,
CGImageRef inImage) ;
void WXDLLIMPEXP_CORE wxOSXDrawNSImage(
CGContextRef inContext,
const CGRect * inBounds,
WX_NSImage inImage) ;
void WXDLLIMPEXP_CORE wxOSXDrawNSImage(
CGContextRef inContext,
const CGRect * inBounds,
WX_NSImage inImage,
wxCompositionMode composition) ;
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 );

View File

@ -2427,7 +2427,7 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDo
if (EnsureIsValid())
{
CGRect r = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h );
wxOSXDrawNSImage( m_cgContext, &r, bmp.GetNSImage());
wxOSXDrawNSImage( m_cgContext, &r, bmp.GetNSImage(), m_composition);
}
#else
wxGraphicsBitmap bitmap = GetRenderer()->CreateBitmap(bmp);
@ -2490,7 +2490,7 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl
#if wxOSX_USE_COCOA
{
CGRect r = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h );
wxOSXDrawNSImage( m_cgContext, &r, icon.GetNSImage());
wxOSXDrawNSImage( m_cgContext, &r, icon.GetNSImage(), m_composition);
}
#endif

View File

@ -287,10 +287,78 @@ CGContextRef WXDLLIMPEXP_CORE wxOSXCreateBitmapContextFromImage( WXImage nsimage
return hbitmap;
}
namespace
{
#if wxOSX_USE_COCOA
NSCompositingOperation wxOSXNSCompositionFromWXComposition( wxCompositionMode composition )
{
NSCompositingOperation mode = NSCompositingOperationSourceOver;
switch( composition )
{
case wxCOMPOSITION_CLEAR:
mode = NSCompositingOperationClear;
break;
case wxCOMPOSITION_SOURCE:
mode = NSCompositingOperationCopy;
break;
case wxCOMPOSITION_OVER:
mode = NSCompositingOperationSourceOver;
break;
case wxCOMPOSITION_IN:
mode = NSCompositingOperationSourceIn;
break;
case wxCOMPOSITION_OUT:
mode = NSCompositingOperationSourceOut;
break;
case wxCOMPOSITION_ATOP:
mode = NSCompositingOperationSourceAtop;
break;
case wxCOMPOSITION_DEST_OVER:
mode = NSCompositingOperationDestinationOver;
break;
case wxCOMPOSITION_DEST_IN:
mode = NSCompositingOperationDestinationIn;
break;
case wxCOMPOSITION_DEST_OUT:
mode = NSCompositingOperationDestinationOut;
break;
case wxCOMPOSITION_DEST_ATOP:
mode = NSCompositingOperationDestinationAtop;
break;
case wxCOMPOSITION_XOR:
mode = NSCompositingOperationExclusion; // Not NSCompositingOperationXOR!
break;
case wxCOMPOSITION_ADD:
mode = NSCompositingOperationPlusLighter ;
break;
case wxCOMPOSITION_DIFF:
mode = NSCompositingOperationDifference ;
break;
default:
mode = NSCompositingOperationSourceOver;
break;
}
return mode;
}
#endif
} // anonymous namespace
#if wxOSX_USE_COCOA
void WXDLLIMPEXP_CORE wxOSXDrawNSImage(
CGContextRef inContext,
const CGRect * inBounds,
WXImage inImage)
{
wxOSXDrawNSImage(inContext, inBounds, inImage, wxCOMPOSITION_OVER);
}
#endif
void WXDLLIMPEXP_CORE wxOSXDrawNSImage(
CGContextRef inContext,
const CGRect * inBounds,
WXImage inImage,
wxCompositionMode composition)
{
if (inImage != nil)
{
@ -301,13 +369,14 @@ void WXDLLIMPEXP_CORE wxOSXDrawNSImage(
CGContextScaleCTM(inContext, 1, -1);
#if wxOSX_USE_COCOA
NSGraphicsContext *previousContext = [NSGraphicsContext currentContext];
NSGraphicsContext *previousContext = [NSGraphicsContext currentContext];
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext graphicsContextWithCGContext:inContext flipped:NO];
[NSGraphicsContext setCurrentContext:nsGraphicsContext];
[inImage drawInRect:NSRectFromCGRect(r) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[inImage drawInRect:NSRectFromCGRect(r) fromRect:NSZeroRect operation:wxOSXNSCompositionFromWXComposition(composition) fraction:1.0];
[NSGraphicsContext setCurrentContext:previousContext];
#else
CGContextDrawImage(inContext, *inBounds, [inImage CGImage]);
CGContextDrawImage(inContext, r, [inImage CGImage]);
#endif
CGContextRestoreGState(inContext);