+ if ( m_composition == op )
+ return true;
+
+ m_composition = op;
+ cairo_operator_t cop;
+ switch (op)
+ {
+ case wxCOMPOSITION_CLEAR:
+ cop = CAIRO_OPERATOR_CLEAR;
+ break;
+ case wxCOMPOSITION_SOURCE:
+ cop = CAIRO_OPERATOR_SOURCE;
+ break;
+ case wxCOMPOSITION_OVER:
+ cop = CAIRO_OPERATOR_OVER;
+ break;
+ 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;
+ default:
+ return false;
+ }
+ 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
+//-----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_CORE wxCairoRenderer : public wxGraphicsRenderer
+{
+public :
+ wxCairoRenderer() {}
+
+ virtual ~wxCairoRenderer() {}
+
+ // Context
+
+ virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc);
+ virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc);
+ virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc);
+
+ virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
+
+ virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window );
+
+ virtual wxGraphicsContext * CreateContext( wxWindow* window );
+
+ virtual wxGraphicsContext * CreateMeasuringContext();
+
+ // Path
+
+ virtual wxGraphicsPath CreatePath();
+
+ // Matrix
+
+ virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
+ wxDouble tx=0.0, wxDouble ty=0.0);
+
+
+ virtual wxGraphicsPen CreatePen(const wxPen& pen) ;
+
+ virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ;
+
+ // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
+ virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
+ const wxColour&c1, const wxColour&c2) ;
+
+ // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
+ // with radius r and color cColor
+ virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
+ const wxColour &oColor, const wxColour &cColor) ;
+
+ // sets the font
+ virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
+
+ // create a native bitmap representation
+ virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap );
+
+ // create a subimage from a native image representation
+ virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
+
+private :
+ DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoRenderer)
+} ;
+
+//-----------------------------------------------------------------------------
+// wxCairoRenderer implementation
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxCairoRenderer,wxGraphicsRenderer)
+
+static wxCairoRenderer gs_cairoGraphicsRenderer;
+// temporary hack to allow creating a cairo context on any platform
+extern wxGraphicsRenderer* gCairoRenderer;
+wxGraphicsRenderer* gCairoRenderer = &gs_cairoGraphicsRenderer;
+
+#ifdef __WXGTK__
+wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer()
+{
+ return &gs_cairoGraphicsRenderer;
+}
+#endif
+
+wxGraphicsContext * wxCairoRenderer::CreateContext( const wxWindowDC& dc)
+{
+ return new wxCairoContext(this,dc);
+}
+
+wxGraphicsContext * wxCairoRenderer::CreateContext( const wxMemoryDC& dc)
+{
+ return new wxCairoContext(this,dc);
+}
+
+wxGraphicsContext * wxCairoRenderer::CreateContext( const wxPrinterDC& dc)
+{
+#ifdef __WXGTK20__
+ const wxDCImpl *impl = dc.GetImpl();
+ cairo_t* context = (cairo_t*) impl->GetCairoContext();
+ if (context)
+ return new wxCairoContext(this,dc);
+ else
+#endif
+ return NULL;
+}
+
+wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeContext( void * context )
+{
+ return new wxCairoContext(this,(cairo_t*)context);
+}
+
+
+wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * window )
+{
+#ifdef __WXGTK__
+ return new wxCairoContext(this,(GdkDrawable*)window);
+#else
+ return NULL;
+#endif
+}
+
+wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext()
+{
+#ifdef __WXGTK__
+ return CreateContextFromNativeWindow(gdk_get_default_root_window());
+#endif
+ return NULL;
+ // TODO