1 //////////////////////////////////////////////////////////////////////////////
2 // Name:        SVGTransform.cpp
3 // Purpose:
4 // Author:      Alex Thuering
5 // Created:     2005/04/29
6 // RCS-ID:      $Id: SVGTransform.cpp,v 1.8 2015/03/21 18:20:28 ntalex Exp $
7 // Copyright:   (c) 2005 Alex Thuering
8 // Licence:     wxWindows licence
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #include "SVGTransform.h"
12 #include <wx/math.h>
13 #include <wx/tokenzr.h>
14 
SetTranslate(double tx,double ty)15 void wxSVGTransform::SetTranslate(double tx, double ty) {
16 	m_type = wxSVG_TRANSFORM_TRANSLATE;
17 	m_angle = 0;
18 	m_matrix = wxSVGMatrix(1, 0, 0, 1, tx, ty);
19 }
20 
SetScale(double sx,double sy)21 void wxSVGTransform::SetScale(double sx, double sy) {
22 	m_type = wxSVG_TRANSFORM_SCALE;
23 	m_angle = 0;
24 	m_matrix = wxSVGMatrix(sx, 0, 0, sy, 0, 0);
25 }
26 
SetRotate(double angle,double cx,double cy)27 void wxSVGTransform::SetRotate(double angle, double cx, double cy) {
28 	m_type = wxSVG_TRANSFORM_ROTATE;
29 	m_angle = angle;
30 	m_cx = cx;
31 	m_cy = cy;
32 	if (cx == 0 && cy == 0) {
33 		angle = angle * M_PI / 180;
34 		m_matrix = wxSVGMatrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0);
35 	} else {
36 		angle = angle * M_PI / 180;
37 		m_matrix = wxSVGMatrix(cos(angle), sin(angle), -sin(angle), cos(angle), cx, cy);
38 		m_matrix = m_matrix.Translate(-cx, -cy);
39 	}
40 }
41 
SetSkewX(double angle)42 void wxSVGTransform::SetSkewX(double angle) {
43 	m_type = wxSVG_TRANSFORM_SKEWX;
44 	m_angle = angle;
45 	m_matrix = wxSVGMatrix(1, 0, tan(angle * M_PI / 180), 1, 0, 0);
46 }
47 
SetSkewY(double angle)48 void wxSVGTransform::SetSkewY(double angle) {
49 	m_type = wxSVG_TRANSFORM_SKEWY;
50 	m_angle = angle;
51 	m_matrix = wxSVGMatrix(1, tan(angle * M_PI / 180), 0, 1, 0, 0);
52 }
53 
GetValueAsString() const54 wxString wxSVGTransform::GetValueAsString() const {
55 	wxString value;
56 	switch (m_type) {
57 	case wxSVG_TRANSFORM_UNKNOWN:
58 		break;
59 	case wxSVG_TRANSFORM_MATRIX:
60 		value = wxString::Format(wxT("matrix(%g,%g,%g,%g,%g,%g)"),
61 				m_matrix.GetA(), m_matrix.GetB(), m_matrix.GetC(),
62 				m_matrix.GetD(), m_matrix.GetE(), m_matrix.GetF());
63 		break;
64 	case wxSVG_TRANSFORM_TRANSLATE:
65 		value = wxString::Format(wxT("translate(%g,%g)"), m_matrix.GetE(), m_matrix.GetF());
66 		break;
67 	case wxSVG_TRANSFORM_SCALE:
68 		if (m_matrix.GetA() == m_matrix.GetD())
69 			value = wxString::Format(wxT("scale(%g)"), m_matrix.GetA());
70 		else
71 			value = wxString::Format(wxT("scale(%g,%g)"), m_matrix.GetA(), m_matrix.GetD());
72 		break;
73 	case wxSVG_TRANSFORM_ROTATE:
74 		if (m_cx == 0 && m_cy == 0)
75 			value = wxString::Format(wxT("rotate(%g)"), m_angle);
76 		else
77 //      double a = m_angle*M_PI/180;
78 //      double cosa = cos(a);
79 //      double sina = sin(a);
80 //      double e = m_matrix.GetE();
81 //      double f = m_matrix.GetF();
82 //      double cx = cosa != 1 ? (e*(1-cosa) - f*sina)/(1-cosa)/2 : 0;
83 //      double cy = cosa != 1 ? e*sina/(1-cosa)/2 + f/2 : 0;
84 			value = wxString::Format(wxT("rotate(%g,%g,%g)"), m_angle, m_cx, m_cy);
85 		break;
86 	case wxSVG_TRANSFORM_SKEWX:
87 		value = wxString::Format(wxT("skewX(%g)"), m_angle);
88 		break;
89 	case wxSVG_TRANSFORM_SKEWY:
90 		value = wxString::Format(wxT("skewY(%g)"), m_angle);
91 		break;
92 	}
93 	return value;
94 }
95 
SetValueAsString(const wxString & value)96 void wxSVGTransform::SetValueAsString(const wxString& value) {
97 	if (value.length() == 0)
98 		return;
99 	double params[6] = { 0, 0, 0, 0, 0, 0 };
100 	wxStringTokenizer tkz(value.AfterFirst(wxT('(')).BeforeLast(wxT(')')),
101 			wxT(","));
102 	int pi = 0;
103 	while (tkz.HasMoreTokens() && pi < 6) {
104 		tkz.GetNextToken().ToDouble(&params[pi]);
105 		pi++;
106 	}
107 	if (pi == 0)
108 		return;
109 	if (value.substr(0, 9) == wxT("translate"))
110 		SetTranslate(params[0], params[1]);
111 	else if (value.substr(0, 5) == wxT("scale"))
112 		SetScale(params[0], pi == 1 ? params[0] : params[1]);
113 	else if (value.substr(0, 6) == wxT("rotate"))
114 		SetRotate(params[0], params[1], params[2]);
115 	else if (value.substr(0, 5) == wxT("skewX"))
116 		SetSkewX(params[0]);
117 	else if (value.substr(0, 5) == wxT("skewY"))
118 		SetSkewY(params[0]);
119 	else if (value.substr(0, 6) == wxT("matrix"))
120 		SetMatrix(wxSVGMatrix(params[0], params[1], params[2], params[3], params[4], params[5]));
121 }
122