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>
|
#include <cairo.h>
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
|
#include "wx/gtk/win_gtk.h"
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#endif
|
#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
|
class WXDLLIMPEXP_CORE wxCairoPathData : public wxGraphicsPathData
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
@@ -299,6 +310,8 @@ private :
|
|||||||
double m_green;
|
double m_green;
|
||||||
double m_blue;
|
double m_blue;
|
||||||
double m_alpha;
|
double m_alpha;
|
||||||
|
cairo_font_face_t *m_font;
|
||||||
|
wxFont m_wxFont;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
|
class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
|
||||||
@@ -315,6 +328,18 @@ public:
|
|||||||
wxCairoContext();
|
wxCairoContext();
|
||||||
virtual ~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 );
|
virtual void Clip( const wxRegion ®ion );
|
||||||
|
|
||||||
// clips drawings to the rect
|
// clips drawings to the rect
|
||||||
@@ -352,6 +377,8 @@ public:
|
|||||||
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
|
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Init(cairo_t *context);
|
||||||
|
|
||||||
cairo_t* m_context;
|
cairo_t* m_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -679,20 +706,34 @@ wxCairoFontData::wxCairoFontData( wxGraphicsRenderer* renderer, const wxFont &fo
|
|||||||
m_fontName = font.GetFaceName().mb_str(wxConvUTF8);
|
m_fontName = font.GetFaceName().mb_str(wxConvUTF8);
|
||||||
m_slant = font.GetStyle() == wxFONTSTYLE_ITALIC ? CAIRO_FONT_SLANT_ITALIC:CAIRO_FONT_SLANT_NORMAL;
|
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;
|
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()
|
wxCairoFontData::~wxCairoFontData()
|
||||||
{
|
{
|
||||||
|
cairo_font_face_destroy( m_font );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCairoFontData::Apply( wxGraphicsContext* context )
|
void wxCairoFontData::Apply( wxGraphicsContext* context )
|
||||||
{
|
{
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
// Pango handled differently
|
||||||
|
#else
|
||||||
cairo_t * ctext = (cairo_t*) context->GetNativeContext();
|
cairo_t * ctext = (cairo_t*) context->GetNativeContext();
|
||||||
cairo_set_source_rgba(ctext,m_red,m_green, m_blue,m_alpha);
|
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_face(ctext, m_font );
|
||||||
cairo_set_font_size(ctext,m_size);
|
|
||||||
// TODO UNDERLINE
|
// TODO UNDERLINE
|
||||||
// TODO FIX SIZE
|
// TODO FIX SIZE
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -965,32 +1006,54 @@ void * wxCairoMatrixData::GetNativeMatrix() const
|
|||||||
// wxCairoContext implementation
|
// 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 )
|
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc )
|
||||||
: wxGraphicsContext(renderer)
|
: wxGraphicsContext(renderer)
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK__
|
#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
|
#endif
|
||||||
PushState();
|
|
||||||
PushState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable )
|
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable )
|
||||||
: wxGraphicsContext(renderer)
|
: wxGraphicsContext(renderer)
|
||||||
{
|
{
|
||||||
m_context = gdk_cairo_create( drawable ) ;
|
Init( gdk_cairo_create( drawable ) );
|
||||||
PushState();
|
|
||||||
PushState();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
|
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
|
||||||
: wxGraphicsContext(renderer)
|
: wxGraphicsContext(renderer)
|
||||||
{
|
{
|
||||||
m_context = context ;
|
Init( context );
|
||||||
PushState();
|
|
||||||
PushState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
||||||
@@ -1014,10 +1077,8 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
|||||||
|
|
||||||
GtkPizza *pizza = GTK_PIZZA( widget );
|
GtkPizza *pizza = GTK_PIZZA( widget );
|
||||||
GdkDrawable* drawable = pizza->bin_window;
|
GdkDrawable* drawable = pizza->bin_window;
|
||||||
m_context = gdk_cairo_create( drawable ) ;
|
Init( gdk_cairo_create( drawable ) ) ;
|
||||||
#endif
|
#endif
|
||||||
PushState();
|
|
||||||
PushState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCairoContext::~wxCairoContext()
|
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 )
|
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);
|
cairo_append_path(m_context, cp);
|
||||||
|
|
||||||
// clip to that path
|
// clip to that path
|
||||||
cairo_clip(m_context);
|
// cairo_clip(m_context);
|
||||||
path.UnGetNativePath(cp);
|
path.UnGetNativePath(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1076,6 +1144,7 @@ void wxCairoContext::StrokePath( const wxGraphicsPath& path )
|
|||||||
{
|
{
|
||||||
if ( !m_pen.IsNull() )
|
if ( !m_pen.IsNull() )
|
||||||
{
|
{
|
||||||
|
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||||
cairo_append_path(m_context,cp);
|
cairo_append_path(m_context,cp);
|
||||||
((wxCairoPenData*)m_pen.GetRefData())->Apply(this);
|
((wxCairoPenData*)m_pen.GetRefData())->Apply(this);
|
||||||
@@ -1088,6 +1157,7 @@ void wxCairoContext::FillPath( const wxGraphicsPath& path , int fillStyle )
|
|||||||
{
|
{
|
||||||
if ( !m_brush.IsNull() )
|
if ( !m_brush.IsNull() )
|
||||||
{
|
{
|
||||||
|
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||||
cairo_append_path(m_context,cp);
|
cairo_append_path(m_context,cp);
|
||||||
((wxCairoBrushData*)m_brush.GetRefData())->Apply(this);
|
((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())
|
if ( m_font.IsNull() || str.empty())
|
||||||
return;
|
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
|
// Cairo's x,y for drawing text is at the baseline, so we need to adjust
|
||||||
// the position we move to by the ascent.
|
// the position we move to by the ascent.
|
||||||
cairo_font_extents_t fe;
|
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));
|
const wxWX2MBbuf buf(str.mb_str(wxConvUTF8));
|
||||||
cairo_show_text(m_context,buf);
|
cairo_show_text(m_context,buf);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
|
void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
|
||||||
wxDouble *descent, wxDouble *externalLeading ) const
|
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())
|
if ( m_font.IsNull() || str.empty())
|
||||||
return;
|
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);
|
((wxCairoFontData*)m_font.GetRefData())->Apply((wxCairoContext*)this);
|
||||||
|
|
||||||
if (width)
|
if (width)
|
||||||
@@ -1296,6 +1414,7 @@ void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDoub
|
|||||||
if ( externalLeading )
|
if ( externalLeading )
|
||||||
*externalLeading = wxMax(0, fe.height - (fe.ascent + fe.descent));
|
*externalLeading = wxMax(0, fe.height - (fe.ascent + fe.descent));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCairoContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const
|
void wxCairoContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const
|
||||||
|
Reference in New Issue
Block a user