#include "wx/wxprec.h"
-#include "wx/dc.h"
-
#ifdef __BORLANDC__
#pragma hdrstop
#endif
+#if wxUSE_GRAPHICS_CONTEXT
+
+#include "wx/dc.h"
+
#ifndef WX_PRECOMP
#include "wx/image.h"
#include "wx/window.h"
#include "wx/module.h"
#endif
-#ifdef __WXGTK__
-#include <gtk/gtk.h>
-#endif
-
-#include "wx/graphics.h"
+#include "wx/private/graphics.h"
#include "wx/rawbmp.h"
-#if wxUSE_GRAPHICS_CONTEXT
-
#include <vector>
using namespace std;
#include <cairo.h>
#ifdef __WXGTK__
-#include "wx/gtk/win_gtk.h"
#include <gtk/gtk.h>
+#include "wx/fontutil.h"
+#include "wx/gtk/dc.h"
#endif
#ifdef __WXMSW__
#endif
#ifdef __WXMAC__
-#include "wx/mac/private.h"
+#include "wx/osx/private.h"
#include <cairo-quartz.h>
#include <cairo-atsui.h>
#endif
~wxCairoFontData();
virtual void Apply( wxGraphicsContext* context );
+#ifdef __WXGTK__
+ const PangoFontDescription* GetFont() const { return m_font; }
+#endif
private :
- wxCharBuffer m_fontName;
double m_size;
- cairo_font_slant_t m_slant;
- cairo_font_weight_t m_weight;
double m_red;
double m_green;
double m_blue;
double m_alpha;
+#ifdef __WXMAC__
cairo_font_face_t *m_font;
- wxFont m_wxFont;
+#elif defined(__WXGTK__)
+ PangoFontDescription* m_font;
+#else
+ wxCharBuffer m_fontName;
+ cairo_font_slant_t m_slant;
+ cairo_font_weight_t m_weight;
+#endif
};
class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
public:
wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc );
+ wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC& dc );
+ wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC& dc );
#ifdef __WXGTK__
wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable );
#endif
break;
case wxLONG_DASH :
- m_lengths = dotted ;
+ m_lengths = dashed ;
m_count = WXSIZEOF(dashed);
break;
case wxSHORT_DASH :
- m_lengths = dotted ;
+ m_lengths = short_dashed ;
m_count = WXSIZEOF(short_dashed);
break;
case wxDOT_DASH :
- m_lengths = dotted ;
+ m_lengths = dotted_dashed ;
m_count = WXSIZEOF(dotted_dashed);
break;
m_green = col.Green()/255.0;
m_blue = col.Blue()/255.0;
m_alpha = col.Alpha()/255.0;
-
m_size = font.GetPointSize();
+
+#ifdef __WXMAC__
+ m_font = cairo_atsui_font_face_create_for_atsu_font_id( font.MacGetATSUFontID() );
+#elif defined(__WXGTK__)
+ m_font = pango_font_description_copy( font.GetNativeFontInfo()->description );
+#else
m_fontName = font.GetFaceName().mb_str(wxConvUTF8);
m_slant = font.GetStyle() == wxFONTSTYLE_ITALIC ? CAIRO_FONT_SLANT_ITALIC:CAIRO_FONT_SLANT_NORMAL;
m_weight = font.GetWeight() == wxFONTWEIGHT_BOLD ? CAIRO_FONT_WEIGHT_BOLD:CAIRO_FONT_WEIGHT_NORMAL;
-#ifdef __WXMAC__
- m_font = cairo_atsui_font_face_create_for_atsu_font_id( font.MacGetATSUFontID() );
-#endif
-#ifdef __WXMSW__
-#endif
-#ifdef __WXGTK__
- // Pango implementation uses the native descriptor
- m_font = NULL;
- m_wxFont = font;
#endif
}
wxCairoFontData::~wxCairoFontData()
{
+#ifdef __WXMAC__
cairo_font_face_destroy( m_font );
+#elif defined(__WXGTK__)
+ pango_font_description_free( m_font );
+#else
+#endif
}
void wxCairoFontData::Apply( wxGraphicsContext* context )
{
-#ifdef __WXGTK__
- // Pango handled differently
-#else
cairo_t * ctext = (cairo_t*) context->GetNativeContext();
cairo_set_source_rgba(ctext,m_red,m_green, m_blue,m_alpha);
- cairo_set_font_face(ctext, m_font );
- // TODO UNDERLINE
- // TODO FIX SIZE
+#ifdef __WXGTK__
+ // the rest is done using Pango layouts
+#elif defined(__WXMAC__)
+ cairo_set_font_face(ctext, m_font);
+ cairo_set_font_size(ctext, m_size );
+#else
+ cairo_select_font_face(ctext, m_fontName, m_slant, m_weights );
+ cairo_set_font_size(ctext, m_size );
#endif
}
}
}
-bool wxCairoPathData::Contains( wxDouble x, wxDouble y, int fillStyle ) const
+bool wxCairoPathData::Contains( wxDouble x, wxDouble y, int WXUNUSED(fillStyle) ) const
{
return cairo_in_stroke( m_pathContext, x, y) != 0;
}
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 __WXGTK__
- Init( gdk_cairo_create( dc.m_window ) );
+#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 );
#endif
}
-#ifdef __WXGTK__
+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)
{
#ifdef __WXGTK__
// something along these lines (copied from dcclient)
- GtkWidget *widget = window->m_wxwindow;
-
// 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 ( !widget )
+ if (window->m_wxwindow == NULL)
{
window = window->GetParent();
- widget = window->m_wxwindow;
}
- wxASSERT_MSG( widget, wxT("wxCairoContext needs a widget") );
+ wxASSERT_MSG( window->m_wxwindow, wxT("wxCairoContext needs a widget") );
- GtkPizza *pizza = GTK_PIZZA( widget );
- GdkDrawable* drawable = pizza->bin_window;
- Init( gdk_cairo_create( drawable ) ) ;
+ Init(gdk_cairo_create(window->GTKGetDrawingWindow()));
#endif
}
while (ri)
{
path.AddRectangle(ri.GetX(), ri.GetY(), ri.GetW(), ri.GetH());
- ri++;
+ ++ri;
}
// Put it in the context
cairo_append_path(m_context, cp);
// clip to that path
-// cairo_clip(m_context);
+ cairo_clip(m_context);
path.UnGetNativePath(cp);
}
{
if ( m_font.IsNull() || str.empty())
return;
-
+
#ifdef __WXGTK__
- const wxCharBuffer data = wxGTK_CONV( str );
+ const wxCharBuffer data = str.utf8_str();
if ( !data )
return;
size_t datalen = strlen(data);
-
+ ((wxCairoFontData*)m_font.GetRefData())->Apply(this);
+
PangoLayout *layout = pango_cairo_create_layout (m_context);
- pango_layout_set_font_description( m_layout, m_wxFont->GetNativeFontInfo()->description);
- pango_layout_set_text (layout, data, datalen);
+ pango_layout_set_font_description( layout, ((wxCairoFontData*)m_font.GetRefData())->GetFont());
+ pango_layout_set_text(layout, data, datalen);
cairo_move_to(m_context, x, y);
pango_cairo_show_layout (m_context, layout);
int w, h;
PangoLayout *layout = pango_cairo_create_layout (m_context);
- pango_layout_set_font_description( layout, m_wxFont->GetNativeFontInfo()->description);
- const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(str, m_wxFont);
- if ( !dataUTF8 )
+ pango_layout_set_font_description( layout, ((wxCairoFontData*)m_font.GetRefData())->GetFont());
+ const wxCharBuffer data = str.utf8_str();
+ if ( !data )
{
return;
}
- pango_layout_set_text( layout, dataUTF8, strlen(dataUTF8) );
+ pango_layout_set_text( layout, data, strlen(data) );
pango_layout_get_pixel_size (layout, &w, &h);
if ( width )
*width = w;
{
cairo_font_extents_t fe;
cairo_font_extents(m_context, &fe);
+
+ // some backends have negative descents
+
+ if ( fe.descent < 0 )
+ fe.descent = -fe.descent;
+
+ if ( fe.height < (fe.ascent + fe.descent ) )
+ {
+ // some backends are broken re height ... (eg currently ATSUI)
+ fe.height = fe.ascent + fe.descent;
+ }
if (height)
*height = fe.height;
// Context
virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc);
-
-#ifdef __WXMSW__
virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc);
-#endif
+ virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc);
virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
+ // create a native bitmap representation
+#if 0
+ virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap )
+ {
+ return wxGraphicsBitmap;
+ }
+
+ // create a subimage from a native image representation
+ virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
+ {
+ return wxGraphicsBitmap;
+ }
+#endif
+
private :
DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoRenderer)
} ;
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 new wxCairoContext(this,dc);
}
-#ifdef __WXMSW__
wxGraphicsContext * wxCairoRenderer::CreateContext( const wxMemoryDC& dc)
{
- return NULL;
+ 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 )
{