1 //////////////////////////////////////////////////////////////////////////////
2 // Name: SVGCanvasPathCairo.cpp
3 // Purpose: Cairo canvas path
4 // Author: Alex Thuering
5 // Created: 2005/05/12
6 // RCS-ID: $Id: SVGCanvasPathCairo.cpp,v 1.15 2016/07/27 08:54:21 ntalex Exp $
7 // Copyright: (c) 2005 Alex Thuering
8 // Licence: wxWindows licence
9 //////////////////////////////////////////////////////////////////////////////
10
11 #include "SVGCanvasPathCairo.h"
12 #include <wx/log.h>
13
wxSVGCanvasPathCairo(cairo_surface_t * surface,wxSVGMatrix * matrix)14 wxSVGCanvasPathCairo::wxSVGCanvasPathCairo(cairo_surface_t* surface, wxSVGMatrix* matrix) {
15 m_cr = cairo_create(surface);
16 #if 0 //!defined(__WXMAC__) && !defined(__WXMSW__)
17 if (matrix) {
18 // for correct checking of surface size when text is rendered using PangaCairo
19 cairo_matrix_t m;
20 cairo_matrix_init(&m, matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
21 cairo_set_matrix(m_cr, &m);
22 };
23 #endif
24 m_curx = m_cury = m_cubicx = m_cubicy = m_quadx = m_quady = 0;
25 }
26
~wxSVGCanvasPathCairo()27 wxSVGCanvasPathCairo::~wxSVGCanvasPathCairo() {
28 cairo_destroy(m_cr);
29 }
30
End()31 void wxSVGCanvasPathCairo::End() {
32 }
33
GetPath()34 cairo_path_t* wxSVGCanvasPathCairo::GetPath() {
35 return cairo_copy_path(m_cr);
36 }
37
GetBBox(const wxSVGMatrix * matrix)38 wxSVGRect wxSVGCanvasPathCairo::GetBBox(const wxSVGMatrix* matrix) {
39 if (matrix) {
40 cairo_matrix_t m;
41 cairo_matrix_init(&m, matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(),
42 matrix->GetE(), matrix->GetF());
43 cairo_matrix_invert(&m);
44 cairo_set_matrix(m_cr, &m);
45 }
46 double x1, y1, x2, y2;
47 cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
48 if (matrix) {
49 cairo_matrix_t mat;
50 cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
51 cairo_set_matrix(m_cr, &mat);
52 }
53 return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
54 }
55
GetResultBBox(const wxCSSStyleDeclaration & style,const wxSVGMatrix * matrix)56 wxSVGRect wxSVGCanvasPathCairo::GetResultBBox(const wxCSSStyleDeclaration& style, const wxSVGMatrix* matrix) {
57 if (matrix) {
58 cairo_matrix_t m;
59 cairo_matrix_init(&m, matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(),
60 matrix->GetE(), matrix->GetF());
61 cairo_matrix_invert(&m);
62 cairo_set_matrix(m_cr, &m);
63 }
64 ApplyStrokeStyle(m_cr, style);
65 double x1, y1, x2, y2;
66 if (style.GetStrokeWidth() > 0)
67 cairo_stroke_extents(m_cr, &x1, &y1, &x2, &y2);
68 else
69 cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
70 if (matrix) {
71 cairo_matrix_t mat;
72 cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
73 cairo_set_matrix(m_cr, &mat);
74 }
75 return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
76 }
77
MoveToImpl(double x,double y)78 void wxSVGCanvasPathCairo::MoveToImpl(double x, double y) {
79 cairo_move_to(m_cr, x, y);
80 }
81
LineToImpl(double x,double y)82 void wxSVGCanvasPathCairo::LineToImpl(double x, double y) {
83 cairo_line_to(m_cr, x, y);
84 }
85
CurveToCubicImpl(double x1,double y1,double x2,double y2,double x,double y)86 void wxSVGCanvasPathCairo::CurveToCubicImpl(double x1, double y1, double x2,
87 double y2, double x, double y) {
88 cairo_curve_to(m_cr, x1, y1, x2, y2, x, y);
89 }
90
ClosePathImpl()91 bool wxSVGCanvasPathCairo::ClosePathImpl() {
92 cairo_close_path(m_cr);
93 return true;
94 }
95
ApplyStrokeStyle(cairo_t * cr,const wxCSSStyleDeclaration & style)96 void wxSVGCanvasPathCairo::ApplyStrokeStyle(cairo_t* cr, const wxCSSStyleDeclaration& style) {
97 cairo_set_line_width(cr, style.GetStrokeWidth());
98 switch (style.GetStrokeLinecap()) {
99 case wxCSS_VALUE_ROUND:
100 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
101 break;
102 case wxCSS_VALUE_SQUARE:
103 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
104 break;
105 case wxCSS_VALUE_BUTT:
106 default:
107 cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
108 break;
109 }
110 switch (style.GetStrokeLinejoin()) {
111 case wxCSS_VALUE_BEVEL:
112 cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
113 break;
114 case wxCSS_VALUE_ROUND:
115 cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
116 break;
117 case wxCSS_VALUE_MITER:
118 default:
119 cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
120 break;
121 }
122 if (style.GetStrokeDasharray().GetLength() > 0) {
123 double* dashed = new double[style.GetStrokeDasharray().GetLength()];
124 for (int i = 0; i < style.GetStrokeDasharray().GetLength(); i++) {
125 dashed[i] = style.GetStrokeDasharray().Item(i).GetFloatValue();
126 }
127 cairo_set_dash(cr, dashed, style.GetStrokeDasharray().GetLength(), style.GetStrokeDashoffset());
128 delete dashed;
129 } else
130 cairo_set_dash(cr, NULL, 0, 0);
131 }
132