#include "wx/dynarray.h"
#include "wx/dc.h"
+enum wxAntialiasMode
+{
+ wxANTIALIAS_NONE, // should be 0
+ wxANTIALIAS_DEFAULT,
+};
+
+enum wxCompositionMode
+{
+ // R = Result, S = Source, D = Destination, premultiplied with alpha
+ // Ra, Sa, Da their alpha components
+
+ // classic Porter-Duff compositions
+ // http://keithp.com/~keithp/porterduff/p253-porter.pdf
+
+ wxCOMPOSITION_CLEAR, /* R = 0 */
+ wxCOMPOSITION_SOURCE, /* R = S */
+ wxCOMPOSITION_OVER, /* R = S + D*(1 - Sa) */
+ wxCOMPOSITION_IN, /* R = S*Da */
+ wxCOMPOSITION_OUT, /* R = S*(1 - Da) */
+ wxCOMPOSITION_ATOP, /* R = S*Da + D*(1 - Sa) */
+
+ wxCOMPOSITION_DEST, /* R = D, essentially a noop */
+ wxCOMPOSITION_DEST_OVER, /* R = S*(1 - Da) + D */
+ wxCOMPOSITION_DEST_IN, /* R = D*Sa */
+ wxCOMPOSITION_DEST_OUT, /* R = D*(1 - Sa) */
+ wxCOMPOSITION_DEST_ATOP, /* R = S*(1 - Da) + D*Sa */
+ wxCOMPOSITION_XOR, /* R = S*(1 - Da) + D*(1 - Sa) */
+
+ // mathematical compositions
+ wxCOMPOSITION_ADD, /* R = S + D */
+};
+
class WXDLLIMPEXP_FWD_CORE wxWindowDC;
class WXDLLIMPEXP_FWD_CORE wxMemoryDC;
#if wxUSE_PRINTING_ARCHITECTURE
// returns the native context
virtual void * GetNativeContext() = 0;
- // returns the current logical function
- virtual wxRasterOperationMode GetLogicalFunction() const { return m_logicalFunction; }
+ // returns the current shape antialiasing mode
+ virtual wxAntialiasMode GetAntialiasMode() const { return m_antialias; }
+
+ // sets the antialiasing mode, returns true if it supported
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias) = 0;
- // sets the current logical function, returns true if it supported
- virtual bool SetLogicalFunction(wxRasterOperationMode function);
+ // returns the current compositing operator
+ virtual wxCompositionMode GetCompositionMode() const { return m_composition; }
+
+ // sets the compositing operator, returns true if it supported
+ virtual bool SetCompositionMode(wxCompositionMode op) = 0;
// returns the size of the graphics context in device coordinates
virtual void GetSize( wxDouble* width, wxDouble* height);
// returns the alpha on this context
virtual wxDouble GetAlpha() const;
#endif
+
+ // all rendering is done into a fully transparent temporary context
+ virtual void BeginLayer(wxDouble opacity) = 0;
+
+ // composites back the drawings into the content with the opacity given at
+ // the BeginLayer call
+ virtual void EndLayer() = 0;
+
//
// transformation : changes the current transformation matrix CTM of the context
//
// draws a polygon
virtual void DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
- // draws a polygon
+ // draws a rectangle
virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h);
// draws an ellipse
wxGraphicsPen m_pen;
wxGraphicsBrush m_brush;
wxGraphicsFont m_font;
- wxRasterOperationMode m_logicalFunction;
+ wxAntialiasMode m_antialias;
+ wxCompositionMode m_composition;
protected:
// implementations of overloaded public functions: we use different names
return (deg * M_PI) / 180.0;
}
+static bool TranslateRasterOp(wxRasterOperationMode function, wxCompositionMode *op)
+{
+ switch ( function )
+ {
+ case wxCOPY: // (default) src
+ *op = wxCOMPOSITION_SOURCE; //
+ break;
+ case wxOR: // src OR dst
+ *op = wxCOMPOSITION_ADD;
+ break;
+ case wxNO_OP: // dst
+ *op = wxCOMPOSITION_DEST; // ignore the source
+ break;
+ case wxCLEAR: // 0
+ *op = wxCOMPOSITION_CLEAR;// clear dst
+ break;
+ case wxXOR: // src XOR dst
+ *op = wxCOMPOSITION_XOR;
+ break;
+
+ case wxAND: // src AND dst
+ case wxAND_INVERT: // (NOT src) AND dst
+ case wxAND_REVERSE:// src AND (NOT dst)
+ case wxEQUIV: // (NOT src) XOR dst
+ case wxINVERT: // NOT dst
+ case wxNAND: // (NOT src) OR (NOT dst)
+ case wxNOR: // (NOT src) AND (NOT dst)
+ case wxOR_INVERT: // (NOT src) OR dst
+ case wxOR_REVERSE: // src OR (NOT dst)
+ case wxSET: // 1
+ case wxSRC_INVERT: // NOT src
+ default:
+ return false;
+ }
+ return true;
+}
+
//-----------------------------------------------------------------------------
// wxDC bridge class
//-----------------------------------------------------------------------------
return;
m_logicalFunction = function;
- if ( m_graphicContext->SetLogicalFunction( function ) )
- m_logicalFunctionSupported=true;
+
+ wxCompositionMode mode;
+ m_logicalFunctionSupported = TranslateRasterOp( function, &mode);
+ if (m_logicalFunctionSupported)
+ m_logicalFunctionSupported = m_graphicContext->SetCompositionMode(mode);
+
+ if (mode == wxCOMPOSITION_XOR)
+ m_graphicContext->SetAntialiasMode(wxANTIALIAS_NONE);
else
- m_logicalFunctionSupported=false;
+ m_graphicContext->SetAntialiasMode(wxANTIALIAS_DEFAULT);
}
bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
if ( logical_func == wxNO_OP )
return true;
- else if ( !m_graphicContext->SetLogicalFunction( logical_func ) )
+
+ wxCompositionMode mode;
+ if ( !TranslateRasterOp(logical_func, &mode) )
{
- wxFAIL_MSG( wxT("Blitting is only supported with wxCOPY logical operation.") );
+ wxFAIL_MSG( wxT("Blitting is not supported with this logical operation.") );
return false;
}
- if (xsrcMask == -1 && ysrcMask == -1)
+ bool retval = true;
+
+ wxCompositionMode formerMode = m_graphicContext->GetCompositionMode();
+ if (m_graphicContext->SetCompositionMode(mode))
{
- xsrcMask = xsrc;
- ysrcMask = ysrc;
- }
+ wxAntialiasMode formerAa = m_graphicContext->GetAntialiasMode();
+ if (mode == wxCOMPOSITION_XOR)
+ {
+ m_graphicContext->SetAntialiasMode(wxANTIALIAS_NONE);
+ }
+
+ if (xsrcMask == -1 && ysrcMask == -1)
+ {
+ xsrcMask = xsrc;
+ ysrcMask = ysrc;
+ }
- wxRect subrect(source->LogicalToDeviceX(xsrc),
- source->LogicalToDeviceY(ysrc),
- source->LogicalToDeviceXRel(srcWidth),
- source->LogicalToDeviceYRel(srcHeight));
+ wxRect subrect(source->LogicalToDeviceX(xsrc),
+ source->LogicalToDeviceY(ysrc),
+ source->LogicalToDeviceXRel(srcWidth),
+ source->LogicalToDeviceYRel(srcHeight));
- // if needed clip the subrect down to the size of the source DC
- wxCoord sw, sh;
- source->GetSize(&sw, &sh);
- sw = source->LogicalToDeviceXRel(sw);
- sh = source->LogicalToDeviceYRel(sh);
- if (subrect.x + subrect.width > sw)
- subrect.width = sw - subrect.x;
- if (subrect.y + subrect.height > sh)
- subrect.height = sh - subrect.y;
+ // if needed clip the subrect down to the size of the source DC
+ wxCoord sw, sh;
+ source->GetSize(&sw, &sh);
+ sw = source->LogicalToDeviceXRel(sw);
+ sh = source->LogicalToDeviceYRel(sh);
+ if (subrect.x + subrect.width > sw)
+ subrect.width = sw - subrect.x;
+ if (subrect.y + subrect.height > sh)
+ subrect.height = sh - subrect.y;
- wxBitmap blit = source->GetAsBitmap( &subrect );
+ wxBitmap blit = source->GetAsBitmap( &subrect );
- if ( blit.IsOk() )
- {
- if ( !useMask && blit.GetMask() )
- blit.SetMask(NULL);
+ if ( blit.IsOk() )
+ {
+ if ( !useMask && blit.GetMask() )
+ blit.SetMask(NULL);
- m_graphicContext->DrawBitmap( blit, xdest, ydest,
- dstWidth, dstHeight);
- }
- else
- {
- wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") );
- return false;
+ m_graphicContext->DrawBitmap( blit, xdest, ydest,
+ dstWidth, dstHeight);
+ }
+ else
+ {
+ wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") );
+ retval = false;
+ }
+
+ if (mode == wxCOMPOSITION_XOR)
+ {
+ m_graphicContext->SetAntialiasMode(formerAa);
+ }
}
+ // reset composition
+ m_graphicContext->SetCompositionMode(formerMode);
- // reset logical function
- m_graphicContext->SetLogicalFunction( m_logicalFunction );
-
- return true;
+ return retval;
}
void wxGCDCImpl::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
IMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject)
-wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer)
+wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) :
+ wxGraphicsObject(renderer),
+ m_antialias(wxANTIALIAS_DEFAULT),
+ m_composition(wxCOMPOSITION_OVER)
{
- m_logicalFunction = wxCOPY;
}
wxGraphicsContext::~wxGraphicsContext()
m_font = font;
}
-bool wxGraphicsContext::SetLogicalFunction( wxRasterOperationMode function )
-{
- if ( function == wxCOPY )
- {
- m_logicalFunction = function;
- return true;
- }
- return false;
-}
-
void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour )
{
if ( font.Ok() )
virtual void * GetNativeContext();
- virtual bool SetLogicalFunction( wxRasterOperationMode function );
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+ virtual bool SetCompositionMode(wxCompositionMode op);
+
+ virtual void BeginLayer(wxDouble opacity);
+
+ virtual void EndLayer();
+
virtual void StrokePath( const wxGraphicsPath& p );
virtual void FillPath( const wxGraphicsPath& p , wxPolygonFillMode fillStyle = wxWINDING_RULE );
virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
cairo_t* m_context;
+
+ wxVector<float> m_layerOpacities;
wxDECLARE_NO_COPY_CLASS(wxCairoContext);
};
return m_context;
}
-// Cairo doesn't support bitwise logical function (a.k.a. ROP, raster output
-// mode). Cairo supports Porter-Duff compositing operators, but they are quite
-// different, although in some cases have similar names.
-bool wxCairoContext::SetLogicalFunction( wxRasterOperationMode function )
+bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias)
{
- if (m_logicalFunction == function)
+ if (m_antialias == antialias)
return true;
- cairo_operator_t op;
+ m_antialias = antialias;
+
+ cairo_antialias_t antialiasMode;
+ switch (antialias)
+ {
+ case wxANTIALIAS_DEFAULT:
+ antialiasMode = CAIRO_ANTIALIAS_DEFAULT;
+ break;
+ case wxANTIALIAS_NONE:
+ antialiasMode = CAIRO_ANTIALIAS_NONE;
+ break;
+ default:
+ return false;
+ }
+ cairo_set_antialias(m_context, antialiasMode);
+ return true;
+}
- switch ( function )
+bool wxCairoContext::SetCompositionMode(wxCompositionMode op)
+{
+ if ( m_composition == op )
+ return true;
+
+ m_composition = op;
+ cairo_operator_t cop;
+ switch (op)
{
- case wxCOPY: // (default) src
- op = CAIRO_OPERATOR_OVER; // (also default)
+ case wxCOMPOSITION__CLEAR:
+ cop = CAIRO_OPERATOR_CLEAR;
break;
- case wxOR: // src OR dst
- op = CAIRO_OPERATOR_ADD;
+ case wxCOMPOSITION_SOURCE:
+ cop = CAIRO_OPERATOR_SOURCE;
break;
- case wxNO_OP: // dst
- op = CAIRO_OPERATOR_DEST; // ignore the source
+ case wxCOMPOSITION_OVER:
+ cop = CAIRO_OPERATOR_OVER;
break;
- case wxCLEAR: // 0
- op = CAIRO_OPERATOR_CLEAR;// clear dst
+ case wxCOMPOSITION_IN:
+ cop = CAIRO_OPERATOR_IN;
+ break;
+ case wxCOMPOSITION_OUT:
+ cop = CAIRO_OPERATOR_OUT;
+ break;
+ case wxCOMPOSITION_ATOP:
+ cop = CAIRO_OPERATOR_ATOP;
+ break;
+ case wxCOMPOSITION_DEST:
+ cop = CAIRO_OPERATOR_DEST;
+ break;
+ case wxCOMPOSITION_DEST_OVER:
+ cop = CAIRO_OPERATOR_DEST_OVER;
+ break;
+ case wxCOMPOSITION_DEST_IN:
+ cop = CAIRO_OPERATOR_DEST_IN;
+ break;
+ case wxCOMPOSITION_DEST_OUT:
+ cop = CAIRO_OPERATOR_DEST_OUT;
+ break;
+ case wxCOMPOSITION_DEST_ATOP:
+ cop = CAIRO_OPERATOR_DEST_ATOP;
+ break;
+ case wxCOMPOSITION_XOR:
+ cop = CAIRO_OPERATOR_XOR;
+ break;
+ case wxCOMPOSITION_ADD:
+ cop = CAIRO_OPERATOR_ADD;
break;
-
- case wxAND: // src AND dst
- case wxAND_INVERT: // (NOT src) AND dst
- case wxAND_REVERSE:// src AND (NOT dst)
- case wxEQUIV: // (NOT src) XOR dst
- case wxINVERT: // NOT dst
- case wxNAND: // (NOT src) OR (NOT dst)
- case wxNOR: // (NOT src) AND (NOT dst)
- case wxOR_INVERT: // (NOT src) OR dst
- case wxOR_REVERSE: // src OR (NOT dst)
- case wxSET: // 1
- case wxSRC_INVERT: // NOT src
- //wxXOR does _not_ correspond to CAIRO_OPERATOR_XOR
- case wxXOR: // src XOR dst
default:
return false;
}
-
- m_logicalFunction = function;
- cairo_set_operator(m_context, op);
+ cairo_set_operator(m_context, cop);
return true;
}
+void wxCairoContext::BeginLayer(wxDouble opacity)
+{
+ m_layerOpacities.push_back(opacity);
+ cairo_push_group(m_context);
+}
+void wxCairoContext::EndLayer()
+{
+ float opacity = m_layerOpacities.back();
+ m_layerOpacities.pop_back();
+ cairo_pop_group_to_source(m_context);
+ cairo_paint_with_alpha(m_context,opacity);
+}
+
//-----------------------------------------------------------------------------
// wxCairoRenderer declaration
//-----------------------------------------------------------------------------
// draws a polygon
virtual void DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+
+ virtual bool SetCompositionMode(wxCompositionMode op);
+
+ virtual void BeginLayer(wxDouble opacity);
+
+ virtual void EndLayer();
+
virtual void Translate( wxDouble dx , wxDouble dy );
virtual void Scale( wxDouble xScale , wxDouble yScale );
virtual void Rotate( wxDouble angle );
void wxGDIPlusContext::StrokeLines( size_t n, const wxPoint2DDouble *points)
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( !m_pen.IsNull() )
{
wxGDIPlusOffsetHelper helper( m_context , ShouldOffset() );
void wxGDIPlusContext::DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode WXUNUSED(fillStyle) )
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
wxGDIPlusOffsetHelper helper( m_context , ShouldOffset() );
Point *cpoints = new Point[n];
for (size_t i = 0; i < n; i++)
void wxGDIPlusContext::StrokePath( const wxGraphicsPath& path )
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( !m_pen.IsNull() )
{
wxGDIPlusOffsetHelper helper( m_context , ShouldOffset() );
void wxGDIPlusContext::FillPath( const wxGraphicsPath& path , wxPolygonFillMode fillStyle )
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( !m_brush.IsNull() )
{
wxGDIPlusOffsetHelper helper( m_context , ShouldOffset() );
}
}
+bool wxGDIPlusContext::SetAntialiasMode(wxAntialiasMode antialias)
+{
+ if (m_antialias == antialias)
+ return true;
+
+ m_antialias = antialias;
+
+ SmoothingMode antialiasMode;
+ switch (antialias)
+ {
+ case wxANTIALIAS_DEFAULT:
+ antialiasMode = SmoothingModeHighQuality;
+ break;
+ case wxANTIALIAS_NONE:
+ antialiasMode = SmoothingModeNone;
+ break;
+ default:
+ return false;
+ }
+ m_context->SetSmoothingMode(antialiasMode);
+ return true;
+}
+
+bool wxGDIPlusContext::SetCompositionMode(wxCompositionMode op)
+{
+ if ( m_composition == op )
+ return true;
+
+ m_composition = op;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return true;
+
+ CompositingMode cop;
+ switch (op)
+ {
+ case wxCOMPOSITION_SOURCE:
+ cop = CompositingModeSourceCopy;
+ break;
+ case wxCOMPOSITION_OVER:
+ cop = CompositingModeSourceOver;
+ break;
+ default:
+ return false;
+ }
+
+ m_context->SetCompositingMode(cop);
+ return true;
+}
+
+void wxGDIPlusContext::BeginLayer(wxDouble opacity)
+{
+ // TODO
+}
+
+void wxGDIPlusContext::EndLayer()
+{
+ // TODO
+}
+
void wxGDIPlusContext::Rotate( wxDouble angle )
{
m_context->RotateTransform( RadToDeg(angle) );
void wxGDIPlusContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
Bitmap* image = static_cast<wxGDIPlusBitmapData*>(bmp.GetRefData())->GetGDIPlusBitmap();
if ( image )
{
void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
// the built-in conversion fails when there is alpha in the HICON (eg XP style icons), we can only
// find out by looking at the bitmap data whether there really was alpha in it
HICON hIcon = (HICON)icon.GetHICON();
wxDouble x, wxDouble y,
const wxGraphicsBrush& brush)
{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
wxCHECK_RET( !m_font.IsNull(),
wxT("wxGDIPlusContext::DrawText - no valid font set") );
// Modified by:
// Created: 01/02/97
// RCS-ID: $Id$
-// Copyright: (c) Stefan Csomor
+// copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
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
}
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 );
}
}
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") );
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
//
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)
+ if (EnsureIsValid()==false)
+ return true;
+
+ if (m_antialias == antialias)
return true;
+
+ m_antialias = antialias;
+
+ bool antialiasMode;
+ switch (antialias)
+ {
+ 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;
-
- 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_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 )
{
- retval = true;
- switch ( function )
+ 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 )
- {
- retval = true;
- }
- else if ( function == wxINVERT || function == wxXOR )
+ CGBlendMode mode = kCGBlendModeNormal;
+ switch( op )
{
- // 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 )
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
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
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
{
CGContextSaveGState( m_cgContext );
{
if (EnsureIsValid()==false)
return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
#ifdef __WXMAC__
wxMacCoreGraphicsBitmapData* refdata =static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
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) );
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{