#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
#if wxUSE_GRAPHICS_CONTEXT
-#include "wx/dc.h"
+#include "wx/graphics.h"
#ifndef WX_PRECOMP
-#include "wx/image.h"
-#include "wx/window.h"
-#include "wx/dc.h"
-#include "wx/utils.h"
-#include "wx/dialog.h"
-#include "wx/app.h"
-#include "wx/bitmap.h"
-#include "wx/dcmemory.h"
-#include "wx/log.h"
-#include "wx/icon.h"
-#include "wx/dcprint.h"
-#include "wx/module.h"
+ #include "wx/bitmap.h"
+ #include "wx/icon.h"
+ #include "wx/dcclient.h"
+ #include "wx/dcmemory.h"
+ #include "wx/dcprint.h"
#endif
#include "wx/private/graphics.h"
#include "wx/rawbmp.h"
-
-#include <vector>
+#include "wx/vector.h"
using namespace std;
-//-----------------------------------------------------------------------------
-// constants
-//-----------------------------------------------------------------------------
-
-const double RAD2DEG = 180.0 / M_PI;
-
-//-----------------------------------------------------------------------------
-// Local functions
-//-----------------------------------------------------------------------------
-
-static inline double dmin(double a, double b)
-{
- return a < b ? a : b;
-}
-static inline double dmax(double a, double b)
-{
- return a > b ? a : b;
-}
-
-static inline double DegToRad(double deg)
-{
- return (deg * M_PI) / 180.0;
-}
-static inline double RadToDeg(double deg)
-{
- return (deg * 180.0) / M_PI;
-}
-
//-----------------------------------------------------------------------------
// device context implementation
//
// gets the bounding box enclosing all points (possibly including control points)
virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const;
- virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxWINDING_RULE) const;
+ virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxWINDING_RULE) const;
private :
cairo_t* m_pathContext;
double *m_userLengths;
wxPen m_pen;
+
+ wxDECLARE_NO_COPY_CLASS(wxCairoPenData);
};
class WXDLLIMPEXP_CORE wxCairoBrushData : public wxGraphicsObjectRefData
virtual void Apply( wxGraphicsContext* context );
#ifdef __WXGTK__
const PangoFontDescription* GetFont() const { return m_font; }
+ bool GetUnderlined() const { return m_underlined; }
#endif
private :
double m_size;
+ bool m_underlined;
double m_red;
double m_green;
double m_blue;
class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
{
- DECLARE_NO_COPY_CLASS(wxCairoContext)
-
public:
wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc );
wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC& dc );
virtual void * GetNativeContext();
- virtual bool SetLogicalFunction( int function );
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+ virtual bool SetCompositionMode(wxCompositionMode op);
+
+ virtual void BeginLayer(wxDouble opacity);
+
+ virtual void EndLayer();
+
virtual void StrokePath( const wxGraphicsPath& p );
- virtual void FillPath( const wxGraphicsPath& p , int fillStyle = wxWINDING_RULE );
+ virtual void FillPath( const wxGraphicsPath& p , wxPolygonFillMode fillStyle = wxWINDING_RULE );
virtual void Translate( wxDouble dx , wxDouble dy );
virtual void Scale( wxDouble xScale , wxDouble yScale );
virtual void PushState();
virtual void PopState();
- virtual void DrawText( const wxString &str, wxDouble x, wxDouble y);
virtual void GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
wxDouble *descent, wxDouble *externalLeading ) const;
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
+protected:
+ virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
+
private:
void Init(cairo_t *context);
cairo_t* m_context;
+
+ wxVector<float> m_layerOpacities;
+
+ wxDECLARE_NO_COPY_CLASS(wxCairoContext);
};
//-----------------------------------------------------------------------------
}
break;
default :
- if ( m_pen.GetStyle() >= wxPENSTYLE_FIRST_HATCH
+ if ( m_pen.GetStyle() >= wxPENSTYLE_FIRST_HATCH
&& m_pen.GetStyle() <= wxPENSTYLE_LAST_HATCH )
{
/*
m_blue = col.Blue()/255.0;
m_alpha = col.Alpha()/255.0;
m_size = font.GetPointSize();
+ m_underlined = font.GetUnderlined();
#ifdef __WXMAC__
- m_font = cairo_atsui_font_face_create_for_atsu_font_id( font.MacGetATSUFontID() );
+ m_font = cairo_quartz_font_face_create_for_cgfont( font.OSXGetCGFont() );
#elif defined(__WXGTK__)
m_font = pango_font_description_copy( font.GetNativeFontInfo()->description );
#else
}
}
-bool wxCairoPathData::Contains( wxDouble x, wxDouble y, int WXUNUSED(fillStyle) ) const
+bool wxCairoPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillMode WXUNUSED(fillStyle) ) const
{
return cairo_in_stroke( m_pathContext, x, y) != 0;
}
}
}
-void wxCairoContext::FillPath( const wxGraphicsPath& path , int fillStyle )
+void wxCairoContext::FillPath( const wxGraphicsPath& path , wxPolygonFillMode fillStyle )
{
if ( !m_brush.IsNull() )
{
}
-void wxCairoContext::DrawText( const wxString &str, wxDouble x, wxDouble y )
+void wxCairoContext::DoDrawText(const wxString& str, wxDouble x, wxDouble y)
{
- wxCHECK_RET( !m_font.IsNull(), wxT("wxCairoContext::DrawText - no valid font set") );
+ wxCHECK_RET( !m_font.IsNull(),
+ wxT("wxCairoContext::DrawText - no valid font set") );
if ( str.empty())
return;
-#ifdef __WXGTK__
const wxCharBuffer data = str.utf8_str();
if ( !data )
return;
- size_t datalen = strlen(data);
+
((wxCairoFontData*)m_font.GetRefData())->Apply(this);
+#ifdef __WXGTK__
+ size_t datalen = strlen(data);
+
PangoLayout *layout = pango_cairo_create_layout (m_context);
- pango_layout_set_font_description( layout, ((wxCairoFontData*)m_font.GetRefData())->GetFont());
+ 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())
+ {
+ PangoAttrList *attrs = pango_attr_list_new();
+ PangoAttribute *attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
+ pango_attr_list_insert(attrs, attr);
+ pango_layout_set_attributes(layout, attrs);
+ pango_attr_list_unref(attrs);
+ }
+
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;
cairo_font_extents(m_context, &fe);
cairo_move_to(m_context, x, y+fe.ascent);
- const wxWX2MBbuf buf(str.mb_str(wxConvUTF8));
- cairo_show_text(m_context,buf);
+ cairo_show_text(m_context, data);
#endif
}
return m_context;
}
-// Cairo doesn't support bitwise logical function (a.k.a. ROP, raster output
-// mode). Cairo supports Porter-Duff compositing operators, but they are quite
-// different, although in some cases have similar names.
-bool wxCairoContext::SetLogicalFunction( int function )
+bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias)
{
- if (m_logicalFunction == function)
+ if (m_antialias == antialias)
return true;
- cairo_operator_t op;
+ m_antialias = antialias;
+
+ cairo_antialias_t antialiasMode;
+ switch (antialias)
+ {
+ case wxANTIALIAS_DEFAULT:
+ antialiasMode = CAIRO_ANTIALIAS_DEFAULT;
+ break;
+ case wxANTIALIAS_NONE:
+ antialiasMode = CAIRO_ANTIALIAS_NONE;
+ break;
+ default:
+ return false;
+ }
+ cairo_set_antialias(m_context, antialiasMode);
+ return true;
+}
- switch ( function )
+bool wxCairoContext::SetCompositionMode(wxCompositionMode op)
+{
+ if ( m_composition == op )
+ return true;
+
+ m_composition = op;
+ cairo_operator_t cop;
+ switch (op)
{
- case wxCOPY: // (default) src
- op = CAIRO_OPERATOR_OVER; // (also default)
+ case wxCOMPOSITION_CLEAR:
+ cop = CAIRO_OPERATOR_CLEAR;
break;
- case wxOR: // src OR dst
- op = CAIRO_OPERATOR_ADD;
+ case wxCOMPOSITION_SOURCE:
+ cop = CAIRO_OPERATOR_SOURCE;
break;
- case wxNO_OP: // dst
- op = CAIRO_OPERATOR_DEST; // ignore the source
+ case wxCOMPOSITION_OVER:
+ cop = CAIRO_OPERATOR_OVER;
break;
- case wxCLEAR: // 0
- op = CAIRO_OPERATOR_CLEAR;// clear dst
+ case wxCOMPOSITION_IN:
+ cop = CAIRO_OPERATOR_IN;
+ break;
+ case wxCOMPOSITION_OUT:
+ cop = CAIRO_OPERATOR_OUT;
+ break;
+ case wxCOMPOSITION_ATOP:
+ cop = CAIRO_OPERATOR_ATOP;
+ break;
+ case wxCOMPOSITION_DEST:
+ cop = CAIRO_OPERATOR_DEST;
+ break;
+ case wxCOMPOSITION_DEST_OVER:
+ cop = CAIRO_OPERATOR_DEST_OVER;
+ break;
+ case wxCOMPOSITION_DEST_IN:
+ cop = CAIRO_OPERATOR_DEST_IN;
+ break;
+ case wxCOMPOSITION_DEST_OUT:
+ cop = CAIRO_OPERATOR_DEST_OUT;
+ break;
+ case wxCOMPOSITION_DEST_ATOP:
+ cop = CAIRO_OPERATOR_DEST_ATOP;
+ break;
+ case wxCOMPOSITION_XOR:
+ cop = CAIRO_OPERATOR_XOR;
+ break;
+ case wxCOMPOSITION_ADD:
+ cop = CAIRO_OPERATOR_ADD;
break;
-
- case wxAND: // src AND dst
- case wxAND_INVERT: // (NOT src) AND dst
- case wxAND_REVERSE:// src AND (NOT dst)
- case wxEQUIV: // (NOT src) XOR dst
- case wxINVERT: // NOT dst
- case wxNAND: // (NOT src) OR (NOT dst)
- case wxNOR: // (NOT src) AND (NOT dst)
- case wxOR_INVERT: // (NOT src) OR dst
- case wxOR_REVERSE: // src OR (NOT dst)
- case wxSET: // 1
- case wxSRC_INVERT: // NOT src
- //wxXOR does _not_ correspond to CAIRO_OPERATOR_XOR
- case wxXOR: // src XOR dst
default:
return false;
}
-
- m_logicalFunction = function;
- cairo_set_operator(m_context, op);
+ cairo_set_operator(m_context, cop);
return true;
}
+void wxCairoContext::BeginLayer(wxDouble opacity)
+{
+ m_layerOpacities.push_back(opacity);
+ cairo_push_group(m_context);
+}
+void wxCairoContext::EndLayer()
+{
+ float opacity = m_layerOpacities.back();
+ m_layerOpacities.pop_back();
+ cairo_pop_group_to_source(m_context);
+ cairo_paint_with_alpha(m_context,opacity);
+}
+
//-----------------------------------------------------------------------------
// wxCairoRenderer declaration
//-----------------------------------------------------------------------------
wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext()
{
+#ifdef __WXGTK__
+ return CreateContextFromNativeWindow(gdk_get_default_root_window());
+#endif
return NULL;
// TODO
}
wxGraphicsPen wxCairoRenderer::CreatePen(const wxPen& pen)
{
- if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT )
+ if ( !pen.Ok() || pen.GetStyle() == wxPENSTYLE_TRANSPARENT )
return wxNullGraphicsPen;
else
{
wxGraphicsBrush wxCairoRenderer::CreateBrush(const wxBrush& brush )
{
- if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT )
+ if ( !brush.Ok() || brush.GetStyle() == wxBRUSHSTYLE_TRANSPARENT )
return wxNullGraphicsBrush;
else
{