forward port from 2.8
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49788 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -101,9 +101,20 @@ static inline double RadToDeg(double deg)
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef __WXGTK__
|
||||
#include "wx/gtk/win_gtk.h"
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <cairo-win32.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#include "wx/mac/private.h"
|
||||
#include <cairo-quartz.h>
|
||||
#include <cairo-atsui.h>
|
||||
#endif
|
||||
|
||||
class WXDLLIMPEXP_CORE wxCairoPathData : public wxGraphicsPathData
|
||||
{
|
||||
public :
|
||||
@@ -299,6 +310,8 @@ private :
|
||||
double m_green;
|
||||
double m_blue;
|
||||
double m_alpha;
|
||||
cairo_font_face_t *m_font;
|
||||
wxFont m_wxFont;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
|
||||
@@ -315,6 +328,18 @@ public:
|
||||
wxCairoContext();
|
||||
virtual ~wxCairoContext();
|
||||
|
||||
virtual bool ShouldOffset() const
|
||||
{
|
||||
int penwidth = 0 ;
|
||||
if ( !m_pen.IsNull() )
|
||||
{
|
||||
penwidth = (int)((wxCairoPenData*)m_pen.GetRefData())->GetWidth();
|
||||
if ( penwidth == 0 )
|
||||
penwidth = 1;
|
||||
}
|
||||
return ( penwidth % 2 ) == 1;
|
||||
}
|
||||
|
||||
virtual void Clip( const wxRegion ®ion );
|
||||
|
||||
// clips drawings to the rect
|
||||
@@ -352,6 +377,8 @@ public:
|
||||
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
|
||||
|
||||
private:
|
||||
void Init(cairo_t *context);
|
||||
|
||||
cairo_t* m_context;
|
||||
};
|
||||
|
||||
@@ -679,20 +706,34 @@ wxCairoFontData::wxCairoFontData( wxGraphicsRenderer* renderer, const wxFont &fo
|
||||
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()
|
||||
{
|
||||
cairo_font_face_destroy( m_font );
|
||||
}
|
||||
|
||||
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_select_font_face(ctext,m_fontName,m_slant,m_weight);
|
||||
cairo_set_font_size(ctext,m_size);
|
||||
cairo_set_font_face(ctext, m_font );
|
||||
// TODO UNDERLINE
|
||||
// TODO FIX SIZE
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -965,32 +1006,54 @@ void * wxCairoMatrixData::GetNativeMatrix() const
|
||||
// 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 wxWindowDC& dc )
|
||||
: wxGraphicsContext(renderer)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
m_context = gdk_cairo_create( dc.m_window ) ;
|
||||
Init( gdk_cairo_create( dc.m_window ) );
|
||||
#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
|
||||
PushState();
|
||||
PushState();
|
||||
}
|
||||
|
||||
#ifdef __WXGTK__
|
||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable )
|
||||
: wxGraphicsContext(renderer)
|
||||
{
|
||||
m_context = gdk_cairo_create( drawable ) ;
|
||||
PushState();
|
||||
PushState();
|
||||
Init( gdk_cairo_create( drawable ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
|
||||
: wxGraphicsContext(renderer)
|
||||
{
|
||||
m_context = context ;
|
||||
PushState();
|
||||
PushState();
|
||||
Init( context );
|
||||
}
|
||||
|
||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
||||
@@ -1014,10 +1077,8 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
||||
|
||||
GtkPizza *pizza = GTK_PIZZA( widget );
|
||||
GdkDrawable* drawable = pizza->bin_window;
|
||||
m_context = gdk_cairo_create( drawable ) ;
|
||||
Init( gdk_cairo_create( drawable ) ) ;
|
||||
#endif
|
||||
PushState();
|
||||
PushState();
|
||||
}
|
||||
|
||||
wxCairoContext::~wxCairoContext()
|
||||
@@ -1030,6 +1091,13 @@ wxCairoContext::~wxCairoContext()
|
||||
}
|
||||
}
|
||||
|
||||
void wxCairoContext::Init(cairo_t *context)
|
||||
{
|
||||
m_context = context ;
|
||||
PushState();
|
||||
PushState();
|
||||
}
|
||||
|
||||
|
||||
void wxCairoContext::Clip( const wxRegion& region )
|
||||
{
|
||||
@@ -1062,7 +1130,7 @@ void wxCairoContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
|
||||
cairo_append_path(m_context, cp);
|
||||
|
||||
// clip to that path
|
||||
cairo_clip(m_context);
|
||||
// cairo_clip(m_context);
|
||||
path.UnGetNativePath(cp);
|
||||
}
|
||||
|
||||
@@ -1076,6 +1144,7 @@ void wxCairoContext::StrokePath( const wxGraphicsPath& path )
|
||||
{
|
||||
if ( !m_pen.IsNull() )
|
||||
{
|
||||
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||
cairo_append_path(m_context,cp);
|
||||
((wxCairoPenData*)m_pen.GetRefData())->Apply(this);
|
||||
@@ -1088,6 +1157,7 @@ void wxCairoContext::FillPath( const wxGraphicsPath& path , int fillStyle )
|
||||
{
|
||||
if ( !m_brush.IsNull() )
|
||||
{
|
||||
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||
cairo_append_path(m_context,cp);
|
||||
((wxCairoBrushData*)m_brush.GetRefData())->Apply(this);
|
||||
@@ -1256,8 +1326,21 @@ void wxCairoContext::DrawText( const wxString &str, wxDouble x, wxDouble y )
|
||||
if ( m_font.IsNull() || str.empty())
|
||||
return;
|
||||
|
||||
((wxCairoFontData*)m_font.GetRefData())->Apply(this);
|
||||
#ifdef __WXGTK__
|
||||
const wxCharBuffer data = wxGTK_CONV( str );
|
||||
if ( !data )
|
||||
return;
|
||||
size_t datalen = strlen(data);
|
||||
|
||||
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);
|
||||
cairo_move_to(m_context, x, y);
|
||||
pango_cairo_show_layout (m_context, layout);
|
||||
|
||||
g_object_unref (layout);
|
||||
#else
|
||||
((wxCairoFontData*)m_font.GetRefData())->Apply(this);
|
||||
// Cairo's x,y for drawing text is at the baseline, so we need to adjust
|
||||
// the position we move to by the ascent.
|
||||
cairo_font_extents_t fe;
|
||||
@@ -1266,14 +1349,49 @@ void wxCairoContext::DrawText( const wxString &str, wxDouble x, wxDouble y )
|
||||
|
||||
const wxWX2MBbuf buf(str.mb_str(wxConvUTF8));
|
||||
cairo_show_text(m_context,buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
|
||||
wxDouble *descent, wxDouble *externalLeading ) const
|
||||
{
|
||||
if ( width )
|
||||
*width = 0;
|
||||
if ( height )
|
||||
*height = 0;
|
||||
if ( descent )
|
||||
*descent = 0;
|
||||
if ( externalLeading )
|
||||
*externalLeading = 0;
|
||||
|
||||
if ( m_font.IsNull() || str.empty())
|
||||
return;
|
||||
|
||||
#ifdef __WXGTK__
|
||||
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 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
pango_layout_set_text( layout, dataUTF8, strlen(dataUTF8) );
|
||||
pango_layout_get_pixel_size (layout, &w, &h);
|
||||
if ( width )
|
||||
*width = w;
|
||||
if ( height )
|
||||
*height = h;
|
||||
if (descent)
|
||||
{
|
||||
PangoLayoutIter *iter = pango_layout_get_iter(layout);
|
||||
int baseline = pango_layout_iter_get_baseline(iter);
|
||||
pango_layout_iter_free(iter);
|
||||
*descent = h - PANGO_PIXELS(baseline);
|
||||
}
|
||||
g_object_unref (layout);
|
||||
#else
|
||||
((wxCairoFontData*)m_font.GetRefData())->Apply((wxCairoContext*)this);
|
||||
|
||||
if (width)
|
||||
@@ -1296,6 +1414,7 @@ void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDoub
|
||||
if ( externalLeading )
|
||||
*externalLeading = wxMax(0, fe.height - (fe.ascent + fe.descent));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void wxCairoContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const
|
||||
|
Reference in New Issue
Block a user