X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fb0400941f5ae04087a9f57b37e3414bd69baa4c..7be740a3fdba6e7203bd82c1674f48207dc00eed:/src/generic/graphicc.cpp diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 552f002b8b..ebc8e253d0 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -12,63 +12,27 @@ #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 +#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 // @@ -174,7 +138,7 @@ public : // 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; @@ -264,6 +228,8 @@ private : double *m_userLengths; wxPen m_pen; + + wxDECLARE_NO_COPY_CLASS(wxCairoPenData); }; class WXDLLIMPEXP_CORE wxCairoBrushData : public wxGraphicsObjectRefData @@ -300,9 +266,11 @@ public: 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; @@ -320,8 +288,6 @@ private : class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext { - DECLARE_NO_COPY_CLASS(wxCairoContext) - public: wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc ); wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC& dc ); @@ -356,10 +322,16 @@ public: 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 ); @@ -379,15 +351,21 @@ public: 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 m_layerOpacities; + + wxDECLARE_NO_COPY_CLASS(wxCairoContext); }; //----------------------------------------------------------------------------- @@ -540,7 +518,7 @@ wxCairoPenData::wxCairoPenData( wxGraphicsRenderer* renderer, const wxPen &pen ) } break; default : - if ( m_pen.GetStyle() >= wxPENSTYLE_FIRST_HATCH + if ( m_pen.GetStyle() >= wxPENSTYLE_FIRST_HATCH && m_pen.GetStyle() <= wxPENSTYLE_LAST_HATCH ) { /* @@ -711,9 +689,10 @@ wxCairoFontData::wxCairoFontData( wxGraphicsRenderer* renderer, const wxFont &fo 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 @@ -887,7 +866,7 @@ void wxCairoPathData::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) } } -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; } @@ -1231,7 +1210,7 @@ void wxCairoContext::StrokePath( const wxGraphicsPath& path ) } } -void wxCairoContext::FillPath( const wxGraphicsPath& path , int fillStyle ) +void wxCairoContext::FillPath( const wxGraphicsPath& path , wxPolygonFillMode fillStyle ) { if ( !m_brush.IsNull() ) { @@ -1399,37 +1378,49 @@ void wxCairoContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDou } -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 } @@ -1529,54 +1520,98 @@ void * wxCairoContext::GetNativeContext() 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 //----------------------------------------------------------------------------- @@ -1703,6 +1738,9 @@ wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * windo wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext() { +#ifdef __WXGTK__ + return CreateContextFromNativeWindow(gdk_get_default_root_window()); +#endif return NULL; // TODO } @@ -1737,7 +1775,7 @@ wxGraphicsMatrix wxCairoRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble wxGraphicsPen wxCairoRenderer::CreatePen(const wxPen& pen) { - if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT ) + if ( !pen.Ok() || pen.GetStyle() == wxPENSTYLE_TRANSPARENT ) return wxNullGraphicsPen; else { @@ -1749,7 +1787,7 @@ wxGraphicsPen wxCairoRenderer::CreatePen(const wxPen& pen) wxGraphicsBrush wxCairoRenderer::CreateBrush(const wxBrush& brush ) { - if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT ) + if ( !brush.Ok() || brush.GetStyle() == wxBRUSHSTYLE_TRANSPARENT ) return wxNullGraphicsBrush; else {