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_set_matrix(m_cr, &m);
44 	}
45 	double x1, y1, x2, y2;
46 	cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
47 	if (matrix) {
48 		cairo_matrix_t mat;
49 		cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
50 		cairo_set_matrix(m_cr, &mat);
51 	}
52 	return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
53 }
54 
GetResultBBox(const wxCSSStyleDeclaration & style,const wxSVGMatrix * matrix)55 wxSVGRect wxSVGCanvasPathCairo::GetResultBBox(const wxCSSStyleDeclaration& style, const wxSVGMatrix* matrix) {
56 	if (matrix) {
57 		cairo_matrix_t m;
58 		cairo_matrix_init(&m, matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(),
59 				matrix->GetE(), matrix->GetF());
60 		cairo_set_matrix(m_cr, &m);
61 	}
62 	ApplyStrokeStyle(m_cr, style);
63 	double x1, y1, x2, y2;
64 	if (style.GetStrokeWidth() > 0)
65 		cairo_stroke_extents(m_cr, &x1, &y1, &x2, &y2);
66 	else
67 		cairo_fill_extents(m_cr, &x1, &y1, &x2, &y2);
68 	if (matrix) {
69 		cairo_matrix_t mat;
70 		cairo_matrix_init(&mat, 1, 0, 0, 1, 0, 0);
71 		cairo_set_matrix(m_cr, &mat);
72 	}
73 	return wxSVGRect(x1, y1, x2 - x1, y2 - y1);
74 }
75 
MoveToImpl(double x,double y)76 void wxSVGCanvasPathCairo::MoveToImpl(double x, double y) {
77 	cairo_move_to(m_cr, x, y);
78 }
79 
LineToImpl(double x,double y)80 void wxSVGCanvasPathCairo::LineToImpl(double x, double y) {
81 	cairo_line_to(m_cr, x, y);
82 }
83 
CurveToCubicImpl(double x1,double y1,double x2,double y2,double x,double y)84 void wxSVGCanvasPathCairo::CurveToCubicImpl(double x1, double y1, double x2,
85 		double y2, double x, double y) {
86 	cairo_curve_to(m_cr, x1, y1, x2, y2, x, y);
87 }
88 
ClosePathImpl()89 bool wxSVGCanvasPathCairo::ClosePathImpl() {
90 	cairo_close_path(m_cr);
91 	return true;
92 }
93 
ApplyStrokeStyle(cairo_t * cr,const wxCSSStyleDeclaration & style)94 void wxSVGCanvasPathCairo::ApplyStrokeStyle(cairo_t* cr, const wxCSSStyleDeclaration& style) {
95 	cairo_set_line_width(cr, style.GetStrokeWidth());
96 	switch (style.GetStrokeLinecap()) {
97 	case wxCSS_VALUE_ROUND:
98 		cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
99 		break;
100 	case wxCSS_VALUE_SQUARE:
101 		cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
102 		break;
103 	case wxCSS_VALUE_BUTT:
104 	default:
105 		cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
106 		break;
107 	}
108 	switch (style.GetStrokeLinejoin()) {
109 	case wxCSS_VALUE_BEVEL:
110 		cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
111 		break;
112 	case wxCSS_VALUE_ROUND:
113 		cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
114 		break;
115 	case wxCSS_VALUE_MITER:
116 	default:
117 		cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
118 		break;
119 	}
120 	if (style.GetStrokeDasharray().GetLength() > 0) {
121 		double* dashed = new double[style.GetStrokeDasharray().GetLength()];
122 		for (int i = 0; i < style.GetStrokeDasharray().GetLength(); i++) {
123 			dashed[i] = style.GetStrokeDasharray().Item(i).GetFloatValue();
124 		}
125 		cairo_set_dash(cr, dashed, style.GetStrokeDasharray().GetLength(), 0.0);
126 		delete[] dashed;
127 	} else
128 		cairo_set_dash(cr, NULL, 0, 0);
129 }
130