From c0e69d720d8b15f788fe0998806f18c46f7d5d8b Mon Sep 17 00:00:00 2001
From: Kevin Ollivier <kevino@theolliviers.com>
Date: Wed, 18 Nov 2009 19:05:42 +0000
Subject: [PATCH] Forward port of r60190 (wxMSW Cairo support) to trunk.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62681 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 include/wx/graphics.h    |  1 +
 include/wx/msw/setup0.h  | 12 +++++++++
 src/common/dcgraph.cpp   | 10 +++++++-
 src/generic/graphicc.cpp | 53 +++++++++++++++++++++++++++++++++++++---
 4 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/include/wx/graphics.h b/include/wx/graphics.h
index 8d6c126e7b..34f92d7cd5 100644
--- a/include/wx/graphics.h
+++ b/include/wx/graphics.h
@@ -611,6 +611,7 @@ public:
 
     static wxGraphicsRenderer* GetDefaultRenderer();
 
+    static wxGraphicsRenderer* GetCairoRenderer();
     // Context
 
     virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc) = 0;
diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h
index 6ff9903c96..a85d303489 100644
--- a/include/wx/msw/setup0.h
+++ b/include/wx/msw/setup0.h
@@ -666,6 +666,18 @@
 #define wxUSE_GRAPHICS_CONTEXT 0
 #endif
 
+// Enable the new wxCairoContext classes for an advanced
+// 2D drawing API.  (Still somewhat experimental)
+//
+// Please note that you will need to link with Cairo for this to work.
+//
+// Default is 0
+//
+// Recommended setting: 1
+#ifndef wxUSE_CAIRO
+#define wxUSE_CAIRO 0
+#endif
+
 // ----------------------------------------------------------------------------
 // Individual GUI controls
 // ----------------------------------------------------------------------------
diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp
index 6a63c43f98..ee399d4907 100644
--- a/src/common/dcgraph.cpp
+++ b/src/common/dcgraph.cpp
@@ -172,7 +172,15 @@ wxGCDCImpl::wxGCDCImpl( wxDC *owner, const wxMemoryDC& dc ) :
    wxDCImpl( owner )
 {
     Init();
-    SetGraphicsContext( wxGraphicsContext::Create(dc) );
+    wxGraphicsContext* context;
+#if wxUSE_CAIRO
+    wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetCairoRenderer();
+    context = renderer->CreateContext(dc);
+#else
+    context = wxGraphicsContext::Create(dc);
+#endif
+
+    SetGraphicsContext( context );
 }
 
 #if wxUSE_PRINTING_ARCHITECTURE
diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp
index 50965a5b99..1634379aee 100644
--- a/src/generic/graphicc.cpp
+++ b/src/generic/graphicc.cpp
@@ -15,10 +15,11 @@
     #pragma hdrstop
 #endif
 
-#if wxUSE_GRAPHICS_CONTEXT
-
+#include "wx/cairo.h"
 #include "wx/graphics.h"
 
+#if wxUSE_GRAPHICS_CONTEXT && wxUSE_CAIRO
+
 #ifndef WX_PRECOMP
     #include "wx/bitmap.h"
     #include "wx/icon.h"
@@ -60,6 +61,10 @@ using namespace std;
 #endif
 
 #include <cairo.h>
+#ifdef __WXMSW__
+#include <cairo-win32.h>
+#endif
+
 #ifdef __WXGTK__
 #include <gtk/gtk.h>
 #include "wx/fontutil.h"
@@ -284,6 +289,9 @@ private :
     cairo_font_slant_t m_slant;
     cairo_font_weight_t m_weight;
 #endif
+#ifdef __WXMSW__
+    wxCairoContext( wxGraphicsRenderer* renderer, HDC context );
+#endif
 };
 
 class wxCairoBitmapData : public wxGraphicsObjectRefData
@@ -331,6 +339,9 @@ public:
     }
 
     virtual void Clip( const wxRegion &region );
+#ifdef __WXMSW__
+    cairo_surface_t* m_mswSurface;
+#endif
 
     // clips drawings to the rect
     virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
@@ -1227,6 +1238,18 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawa
 }
 #endif
 
+#ifdef __WXMSW__
+wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, HDC handle )
+: wxGraphicsContext(renderer)
+{
+    m_mswSurface = cairo_win32_surface_create(handle);
+    m_context = cairo_create(m_mswSurface);
+    PushState();
+    PushState();
+}
+#endif
+
+
 wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
 : wxGraphicsContext(renderer)
 {
@@ -1258,9 +1281,17 @@ wxCairoContext::~wxCairoContext()
     if ( m_context )
     {
         PopState();
+#ifdef __WXMSW__
+    m_mswSurface = cairo_win32_surface_create((HDC)window->GetHandle());
+    m_context = cairo_create(m_mswSurface);
+#endif
         PopState();
         cairo_destroy(m_context);
     }
+#ifdef __WXMSW__
+    if ( m_mswSurface )
+        cairo_surface_destroy(m_mswSurface);
+#endif
 }
 
 void wxCairoContext::Init(cairo_t *context)
@@ -1768,7 +1799,12 @@ wxGraphicsContext * wxCairoRenderer::CreateContext( const wxPrinterDC& dc)
 
 wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeContext( void * context )
 {
+#if __WXMSW__
+    return new wxCairoContext(this,(HDC)context);
+#endif
+#if __WXGTK__
     return new wxCairoContext(this,(cairo_t*)context);
+#endif
 }
 
 
@@ -1913,4 +1949,15 @@ wxCairoRenderer::CreateSubBitmap(const wxGraphicsBitmap& WXUNUSED(bitmap),
     return wxNullGraphicsBitmap;
 }
 
-#endif  // wxUSE_GRAPHICS_CONTEXT
+#endif  // wxUSE_GRAPHICS_CONTEXT && wxUSE_CAIRO
+
+#if wxUSE_GRAPHICS_CONTEXT
+wxGraphicsRenderer* wxGraphicsRenderer::GetCairoRenderer()
+{
+#if wxUSE_CAIRO
+    return &gs_cairoGraphicsRenderer;
+#else
+    return NULL;
+#endif
+}
+#endif
-- 
2.47.2