]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/graphicc.cpp
Allow OS X Cocoa (or any OS X port) to override GetBestSize and provide a native...
[wxWidgets.git] / src / generic / graphicc.cpp
index f3c5a1f8d8d3db6231918df7ef2c28029403a231..1634379aeebdef25221425bb9b9b10aae3ae3b2f 100644 (file)
     #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,12 +289,16 @@ 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
 {
 public:
     wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp );
+    wxCairoBitmapData( wxGraphicsRenderer* renderer, cairo_surface_t* bitmap );
     ~wxCairoBitmapData();
 
     virtual cairo_surface_t* GetCairoSurface() { return m_surface; }
@@ -330,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 );
@@ -346,7 +358,7 @@ public:
     virtual void BeginLayer(wxDouble opacity);
 
     virtual void EndLayer();
-    
+
     virtual void StrokePath( const wxGraphicsPath& p );
     virtual void FillPath( const wxGraphicsPath& p , wxPolygonFillMode fillStyle = wxWINDING_RULE );
 
@@ -380,7 +392,7 @@ private:
     void Init(cairo_t *context);
 
     cairo_t* m_context;
-    
+
     wxVector<float> m_layerOpacities;
 
     wxDECLARE_NO_COPY_CLASS(wxCairoContext);
@@ -1014,11 +1026,17 @@ void * wxCairoMatrixData::GetNativeMatrix() const
 // wxCairoBitmap implementation
 //-----------------------------------------------------------------------------
 
+wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, cairo_surface_t* bitmap ) :
+    wxGraphicsObjectRefData( renderer )
+{
+    m_surface = bitmap;
+    m_pattern = cairo_pattern_create_for_surface(m_surface);
+}
+
 wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ) : wxGraphicsObjectRefData( renderer )
 {
     wxCHECK_RET( bmp.IsOk(), wxT("Invalid bitmap in wxCairoContext::DrawBitmap"));
 
-    cairo_surface_t* surface;
     int bw = bmp.GetWidth();
     int bh = bmp.GetHeight();
     wxBitmap bmpSource = bmp;  // we need a non-const instance
@@ -1085,12 +1103,17 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
             p.OffsetY(pixData, 1);
         }
     }
+    m_pattern = cairo_pattern_create_for_surface(m_surface);
 }
 
 wxCairoBitmapData::~wxCairoBitmapData()
 {
-    cairo_pattern_destroy(m_pattern);
-    cairo_surface_destroy(m_surface);
+    if (m_pattern)
+        cairo_pattern_destroy(m_pattern);
+    
+    if (m_surface)
+        cairo_surface_destroy(m_surface);
+    
     delete [] m_buffer;
 }
 
@@ -1215,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)
 {
@@ -1246,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)
@@ -1437,8 +1480,8 @@ void wxCairoContext::DoDrawText(const wxString& str, wxDouble x, wxDouble y)
     wxCairoFontData* font_data = (wxCairoFontData*) m_font.GetRefData();
     pango_layout_set_font_description( layout, font_data->GetFont());
     pango_layout_set_text(layout, data, datalen);
-    
-    if (font_data->GetUnderlined()) 
+
+    if (font_data->GetUnderlined())
     {
         PangoAttrList *attrs = pango_attr_list_new();
         PangoAttribute *attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
@@ -1564,7 +1607,7 @@ bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias)
         return true;
 
     m_antialias = antialias;
-    
+
     cairo_antialias_t antialiasMode;
     switch (antialias)
     {
@@ -1585,7 +1628,7 @@ bool wxCairoContext::SetCompositionMode(wxCompositionMode op)
 {
     if ( m_composition == op )
         return true;
-        
+
     m_composition = op;
     cairo_operator_t cop;
     switch (op)
@@ -1649,7 +1692,7 @@ void wxCairoContext::EndLayer()
     cairo_pop_group_to_source(m_context);
     cairo_paint_with_alpha(m_context,opacity);
 }
-    
+
 //-----------------------------------------------------------------------------
 // wxCairoRenderer declaration
 //-----------------------------------------------------------------------------
@@ -1704,6 +1747,9 @@ public :
     // create a native bitmap representation
     virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap );
 
+    // create a graphics bitmap from a native bitmap
+    virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
+
     // create a subimage from a native image representation
     virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h  );
 
@@ -1753,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
 }
 
 
@@ -1863,7 +1914,7 @@ wxGraphicsFont wxCairoRenderer::CreateFont( const wxFont &font , const wxColour
         return wxNullGraphicsFont;
 }
 
-wxGraphicsBitmap wxGraphicsRenderer::CreateBitmap( const wxBitmap& bmp )
+wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp )
 {
     if ( bmp.Ok() )
     {
@@ -1875,10 +1926,38 @@ wxGraphicsBitmap wxGraphicsRenderer::CreateBitmap( const wxBitmap& bmp )
         return wxNullGraphicsBitmap;
 }
 
-wxGraphicsBitmap wxGraphicsRenderer::CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h  )
+wxGraphicsBitmap wxCairoRenderer::CreateBitmapFromNativeBitmap( void* bitmap )
+{
+    if ( bitmap != NULL )
+    {
+        wxGraphicsBitmap p;
+        p.SetRefData(new wxCairoBitmapData( this , (cairo_surface_t*) bitmap ));
+        return p;
+    }
+    else
+        return wxNullGraphicsBitmap;
+}
+
+wxGraphicsBitmap
+wxCairoRenderer::CreateSubBitmap(const wxGraphicsBitmap& WXUNUSED(bitmap),
+                                 wxDouble WXUNUSED(x),
+                                 wxDouble WXUNUSED(y),
+                                 wxDouble WXUNUSED(w),
+                                 wxDouble WXUNUSED(h))
 {
     wxFAIL_MSG("wxCairoRenderer::CreateSubBitmap is not implemented.");
     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