+ }
+ m_pattern = cairo_pattern_create_for_surface(m_surface);
+}
+
+wxCairoBitmapData::~wxCairoBitmapData()
+{
+ if (m_pattern)
+ cairo_pattern_destroy(m_pattern);
+
+ if (m_surface)
+ cairo_surface_destroy(m_surface);
+
+ delete [] m_buffer;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// wxCairoContext implementation
+//-----------------------------------------------------------------------------
+
+class wxCairoOffsetHelper
+{
+public :
+ wxCairoOffsetHelper( cairo_t* ctx , bool offset )
+ {
+ m_ctx = ctx;
+ m_offset = offset;
+ if ( m_offset )
+ cairo_translate( m_ctx, 0.5, 0.5 );
+ }
+ ~wxCairoOffsetHelper( )
+ {
+ if ( m_offset )
+ cairo_translate( m_ctx, -0.5, -0.5 );
+ }
+public :
+ cairo_t* m_ctx;
+ bool m_offset;
+} ;
+
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC& dc )
+: wxGraphicsContext(renderer)
+{
+#ifdef __WXGTK20__
+ const wxDCImpl *impl = dc.GetImpl();
+ Init( (cairo_t*) impl->GetCairoContext() );
+
+ wxPoint org = dc.GetDeviceOrigin();
+ cairo_translate( m_context, org.x, org.y );
+
+ double sx,sy;
+ dc.GetUserScale( &sx, &sy );
+ cairo_scale( m_context, sx, sy );
+
+ org = dc.GetLogicalOrigin();
+ cairo_translate( m_context, -org.x, -org.y );
+#endif
+}
+
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc )
+: wxGraphicsContext(renderer)
+{
+#ifdef __WXGTK20__
+ wxGTKDCImpl *impldc = (wxGTKDCImpl*) dc.GetImpl();
+ Init( gdk_cairo_create( impldc->GetGDKWindow() ) );
+
+#if 0
+ wxGraphicsMatrix matrix = CreateMatrix();
+
+ wxPoint org = dc.GetDeviceOrigin();
+ matrix.Translate( org.x, org.y );
+
+ org = dc.GetLogicalOrigin();
+ matrix.Translate( -org.x, -org.y );
+
+ double sx,sy;
+ dc.GetUserScale( &sx, &sy );
+ matrix.Scale( sx, sy );
+
+ ConcatTransform( matrix );
+#endif
+#endif
+
+#ifdef __WXMAC__
+ int width, height;
+ dc.GetSize( &width, &height );
+ CGContextRef cgcontext = (CGContextRef)dc.GetWindow()->MacGetCGContextRef();
+ cairo_surface_t* surface = cairo_quartz_surface_create_for_cg_context(cgcontext, width, height);
+ Init( cairo_create( surface ) );
+ cairo_surface_destroy( surface );
+#endif
+}
+
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC& dc )
+: wxGraphicsContext(renderer)
+{
+#ifdef __WXGTK20__
+ wxGTKDCImpl *impldc = (wxGTKDCImpl*) dc.GetImpl();
+ Init( gdk_cairo_create( impldc->GetGDKWindow() ) );
+
+#if 0
+ wxGraphicsMatrix matrix = CreateMatrix();
+
+ wxPoint org = dc.GetDeviceOrigin();
+ matrix.Translate( org.x, org.y );
+
+ org = dc.GetLogicalOrigin();
+ matrix.Translate( -org.x, -org.y );
+
+ double sx,sy;
+ dc.GetUserScale( &sx, &sy );
+ matrix.Scale( sx, sy );
+
+ ConcatTransform( matrix );
+#endif
+#endif
+
+#ifdef __WXMAC__
+ int width, height;
+ dc.GetSize( &width, &height );
+ CGContextRef cgcontext = (CGContextRef)dc.GetWindow()->MacGetCGContextRef();
+ cairo_surface_t* surface = cairo_quartz_surface_create_for_cg_context(cgcontext, width, height);
+ Init( cairo_create( surface ) );
+ cairo_surface_destroy( surface );
+#endif
+}
+
+#ifdef __WXGTK20__
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable )
+: wxGraphicsContext(renderer)
+{
+ Init( gdk_cairo_create( drawable ) );
+}
+#endif
+
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
+: wxGraphicsContext(renderer)
+{
+ Init( context );
+}
+
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
+: wxGraphicsContext(renderer)
+{
+#ifdef __WXGTK__
+ // something along these lines (copied from dcclient)
+
+ // Some controls don't have m_wxwindow - like wxStaticBox, but the user
+ // code should still be able to create wxClientDCs for them, so we will
+ // use the parent window here then.
+ if (window->m_wxwindow == NULL)
+ {
+ window = window->GetParent();
+ }
+
+ wxASSERT_MSG( window->m_wxwindow, wxT("wxCairoContext needs a widget") );
+
+ Init(gdk_cairo_create(window->GTKGetDrawingWindow()));
+#endif
+}
+
+wxCairoContext::~wxCairoContext()
+{
+ if ( m_context )
+ {
+ PopState();
+ PopState();
+ cairo_destroy(m_context);
+ }
+}
+
+void wxCairoContext::Init(cairo_t *context)
+{
+ m_context = context ;
+ PushState();
+ PushState();
+}
+
+
+void wxCairoContext::Clip( const wxRegion& region )
+{
+ // Create a path with all the rectangles in the region
+ wxGraphicsPath path = GetRenderer()->CreatePath();
+ wxRegionIterator ri(region);
+ while (ri)
+ {
+ path.AddRectangle(ri.GetX(), ri.GetY(), ri.GetW(), ri.GetH());
+ ++ri;
+ }
+
+ // Put it in the context
+ cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
+ cairo_append_path(m_context, cp);
+
+ // clip to that path
+ cairo_clip(m_context);
+ path.UnGetNativePath(cp);
+}
+
+void wxCairoContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
+{
+ // Create a path with this rectangle
+ wxGraphicsPath path = GetRenderer()->CreatePath();
+ path.AddRectangle(x,y,w,h);
+
+ // Put it in the context
+ cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
+ cairo_append_path(m_context, cp);
+
+ // clip to that path
+ cairo_clip(m_context);
+ path.UnGetNativePath(cp);
+}
+
+void wxCairoContext::ResetClip()
+{
+ cairo_reset_clip(m_context);