switching to compositing operators (fixes #9881), adding layers
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58917 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
// Modified by:
|
||||
// Created: 01/02/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Stefan Csomor
|
||||
// copyright: (c) Stefan Csomor
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -77,6 +77,35 @@ extern bool wxOSXLockFocus( WXWidget view) ;
|
||||
extern void wxOSXUnlockFocus( WXWidget view) ;
|
||||
#endif
|
||||
|
||||
#if 1 // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
|
||||
|
||||
// TODO test whether this private API also works under 10.3
|
||||
|
||||
// copying values from NSCompositingModes (see also webkit and cairo sources)
|
||||
|
||||
typedef enum CGCompositeOperation {
|
||||
kCGCompositeOperationClear = 0,
|
||||
kCGCompositeOperationCopy = 1,
|
||||
kCGCompositeOperationSourceOver = 2,
|
||||
kCGCompositeOperationSourceIn = 3,
|
||||
kCGCompositeOperationSourceOut = 4,
|
||||
kCGCompositeOperationSourceAtop = 5,
|
||||
kCGCompositeOperationDestinationOver = 6,
|
||||
kCGCompositeOperationDestinationIn = 7,
|
||||
kCGCompositeOperationDestinationOut = 8,
|
||||
kCGCompositeOperationDestinationAtop = 9,
|
||||
kCGCompositeOperationXOR = 10,
|
||||
kCGCompositeOperationPlusDarker = 11,
|
||||
// NS only, unsupported by CG : Highlight
|
||||
kCGCompositeOperationPlusLighter = 12
|
||||
} CGCompositeOperation ;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
CG_EXTERN void CGContextSetCompositeOperation (CGContextRef context, int operation);
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constants
|
||||
@@ -534,12 +563,7 @@ void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context )
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( context->GetLogicalFunction() == wxINVERT || context->GetLogicalFunction() == wxXOR )
|
||||
{
|
||||
CGContextSetRGBStrokeColor( cg , (CGFloat) 1.0,(CGFloat) 1.0 , (CGFloat) 1.0, (CGFloat) 1.0 );
|
||||
}
|
||||
else
|
||||
CGContextSetStrokeColorWithColor( cg , m_color );
|
||||
CGContextSetStrokeColorWithColor( cg , m_color );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,7 +853,7 @@ wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* rendere
|
||||
OSStatus status = noErr;
|
||||
m_macATSUIStyle = NULL;
|
||||
|
||||
status = ATSUCreateAndCopyStyle( (ATSUStyle) font.MacGetATSUStyle() , &m_macATSUIStyle );
|
||||
status = ATSUCreateAndcopyStyle( (ATSUStyle) font.MacGetATSUStyle() , &m_macATSUIStyle );
|
||||
|
||||
wxASSERT_MSG( status == noErr, wxT("couldn't create ATSU style") );
|
||||
|
||||
@@ -1316,7 +1340,14 @@ public:
|
||||
|
||||
virtual void * GetNativeContext();
|
||||
|
||||
bool SetLogicalFunction( wxRasterOperationMode function );
|
||||
virtual bool SetAntialiasMode(wxAntialiasMode antialias);
|
||||
|
||||
virtual bool SetCompositionMode(wxCompositionMode op);
|
||||
|
||||
virtual void BeginLayer(wxDouble opacity);
|
||||
|
||||
virtual void EndLayer();
|
||||
|
||||
//
|
||||
// transformation
|
||||
//
|
||||
@@ -1627,69 +1658,160 @@ bool wxMacCoreGraphicsContext::EnsureIsValid()
|
||||
return m_cgContext != NULL;
|
||||
}
|
||||
|
||||
// TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes)
|
||||
|
||||
bool wxMacCoreGraphicsContext::SetLogicalFunction( wxRasterOperationMode function )
|
||||
bool wxMacCoreGraphicsContext::SetAntialiasMode(wxAntialiasMode antialias)
|
||||
{
|
||||
if (m_logicalFunction == function)
|
||||
return true;
|
||||
|
||||
if (EnsureIsValid()==false)
|
||||
return true;
|
||||
|
||||
bool retval = false;
|
||||
bool shouldAntiAlias = true;
|
||||
CGBlendMode mode = kCGBlendModeNormal;
|
||||
|
||||
#if defined(__WXMAC__) && ( wxOSX_USE_IPHONE || ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ) )
|
||||
#if wxOSX_USE_IPHONE
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( UMAGetSystemVersion() >= 0x1050 )
|
||||
#endif
|
||||
if (m_antialias == antialias)
|
||||
return true;
|
||||
|
||||
m_antialias = antialias;
|
||||
|
||||
bool antialiasMode;
|
||||
switch (antialias)
|
||||
{
|
||||
retval = true;
|
||||
switch ( function )
|
||||
case wxANTIALIAS_DEFAULT:
|
||||
antialiasMode = true;
|
||||
break;
|
||||
case wxANTIALIAS_NONE:
|
||||
antialiasMode = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
CGContextSetShouldAntialias(m_cgContext, antialiasMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxMacCoreGraphicsContext::SetCompositionMode(wxCompositionMode op)
|
||||
{
|
||||
if (EnsureIsValid()==false)
|
||||
return true;
|
||||
|
||||
if ( m_composition == op )
|
||||
return true;
|
||||
|
||||
m_composition = op;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return true;
|
||||
|
||||
#if wxOSX_USE_COCOA_OR_CARBON
|
||||
#if 1 // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
|
||||
if ( UMAGetSystemVersion() < 0x1060 )
|
||||
{
|
||||
CGCompositeOperation cop = kCGCompositeOperationSourceOver;
|
||||
CGBlendMode mode = kCGBlendModeNormal;
|
||||
switch( op )
|
||||
{
|
||||
// TODO find best corresponding porter duff modes
|
||||
case wxCOPY :
|
||||
mode = kCGBlendModeCopy;
|
||||
break;
|
||||
case wxCLEAR :
|
||||
mode = kCGBlendModeClear;
|
||||
break;
|
||||
case wxXOR :
|
||||
mode = kCGBlendModeXOR;
|
||||
shouldAntiAlias = false;
|
||||
break;
|
||||
default :
|
||||
retval = false;
|
||||
break;
|
||||
case wxCOMPOSITION_CLEAR:
|
||||
cop = kCGCompositeOperationClear;
|
||||
break;
|
||||
case wxCOMPOSITION_SOURCE:
|
||||
cop = kCGCompositeOperationCopy;
|
||||
break;
|
||||
case wxCOMPOSITION_OVER:
|
||||
mode = kCGBlendModeNormal;
|
||||
break;
|
||||
case wxCOMPOSITION_IN:
|
||||
cop = kCGCompositeOperationSourceIn;
|
||||
break;
|
||||
case wxCOMPOSITION_OUT:
|
||||
cop = kCGCompositeOperationSourceOut;
|
||||
break;
|
||||
case wxCOMPOSITION_ATOP:
|
||||
cop = kCGCompositeOperationSourceAtop;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_OVER:
|
||||
cop = kCGCompositeOperationDestinationOver;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_IN:
|
||||
cop = kCGCompositeOperationDestinationIn;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_OUT:
|
||||
cop = kCGCompositeOperationDestinationOut;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_ATOP:
|
||||
cop = kCGCompositeOperationDestinationAtop;
|
||||
break;
|
||||
case wxCOMPOSITION_XOR:
|
||||
cop = kCGCompositeOperationXOR;
|
||||
break;
|
||||
case wxCOMPOSITION_ADD:
|
||||
mode = kCGBlendModePlusLighter ;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if ( cop != kCGCompositeOperationSourceOver )
|
||||
CGContextSetCompositeOperation(m_cgContext, cop);
|
||||
else
|
||||
CGContextSetBlendMode(m_cgContext, mode);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
if ( function == wxCOPY )
|
||||
CGBlendMode mode = kCGBlendModeNormal;
|
||||
switch( op )
|
||||
{
|
||||
retval = true;
|
||||
}
|
||||
else if ( function == wxINVERT || function == wxXOR )
|
||||
{
|
||||
// change color to white
|
||||
mode = kCGBlendModeExclusion;
|
||||
shouldAntiAlias = false;
|
||||
retval = true;
|
||||
case wxCOMPOSITION_CLEAR:
|
||||
mode = kCGBlendModeClear;
|
||||
break;
|
||||
case wxCOMPOSITION_SOURCE:
|
||||
mode = kCGBlendModeCopy;
|
||||
break;
|
||||
case wxCOMPOSITION_OVER:
|
||||
mode = kCGBlendModeNormal;
|
||||
break;
|
||||
case wxCOMPOSITION_IN:
|
||||
mode = kCGBlendModeSourceIn;
|
||||
break;
|
||||
case wxCOMPOSITION_OUT:
|
||||
mode = kCGBlendModeSourceOut;
|
||||
break;
|
||||
case wxCOMPOSITION_ATOP:
|
||||
mode = kCGBlendModeSourceAtop;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_OVER:
|
||||
mode = kCGBlendModeDestinationOver;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_IN:
|
||||
mode = kCGBlendModeDestinationIn;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_OUT:
|
||||
mode = kCGBlendModeDestinationOut;
|
||||
break;
|
||||
case wxCOMPOSITION_DEST_ATOP:
|
||||
mode = kCGBlendModeDestinationAtop;
|
||||
break;
|
||||
case wxCOMPOSITION_XOR:
|
||||
mode = kCGBlendModeXOR;
|
||||
break;
|
||||
|
||||
case wxCOMPOSITION_ADD:
|
||||
mode = kCGBlendModePlusLighter ;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
CGContextSetBlendMode(m_cgContext, mode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (retval)
|
||||
{
|
||||
m_logicalFunction = function;
|
||||
CGContextSetBlendMode( m_cgContext, mode );
|
||||
CGContextSetShouldAntialias(m_cgContext, shouldAntiAlias);
|
||||
}
|
||||
return retval ;
|
||||
void wxMacCoreGraphicsContext::BeginLayer(wxDouble opacity)
|
||||
{
|
||||
CGContextSaveGState(m_cgContext);
|
||||
CGContextSetAlpha(m_cgContext, opacity);
|
||||
CGContextBeginTransparencyLayer(m_cgContext, 0);
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::EndLayer()
|
||||
{
|
||||
CGContextEndTransparencyLayer(m_cgContext);
|
||||
CGContextRestoreGState(m_cgContext);
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion )
|
||||
@@ -1782,6 +1904,9 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path )
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
|
||||
|
||||
((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
|
||||
@@ -1794,6 +1919,9 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , wxPolygonF
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
if ( !m_brush.IsNull() && ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
|
||||
{
|
||||
// when using shading, we cannot draw pen and brush at the same time
|
||||
@@ -1847,6 +1975,9 @@ void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , wxPolygonF
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
|
||||
{
|
||||
CGContextSaveGState( m_cgContext );
|
||||
@@ -1944,6 +2075,9 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble
|
||||
{
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
#ifdef __WXMAC__
|
||||
wxMacCoreGraphicsBitmapData* refdata =static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
|
||||
@@ -1984,6 +2118,9 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
CGRect r = CGRectMake( (CGFloat) 0.0 , (CGFloat) 0.0 , (CGFloat) w , (CGFloat) h );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
CGContextTranslateCTM( m_cgContext,(CGFloat) x ,(CGFloat) (y + h) );
|
||||
@@ -2018,6 +2155,9 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
#if wxOSX_USE_CORE_TEXT
|
||||
if ( UMAGetSystemVersion() >= 0x1050 )
|
||||
{
|
||||
@@ -2078,6 +2218,9 @@ void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str,
|
||||
if (EnsureIsValid()==false)
|
||||
return;
|
||||
|
||||
if (m_composition == wxCOMPOSITION_DEST)
|
||||
return;
|
||||
|
||||
#if wxOSX_USE_CORE_TEXT
|
||||
if ( UMAGetSystemVersion() >= 0x1050 )
|
||||
{
|
||||
|
Reference in New Issue
Block a user