97fc7f9879796622023115c57af11144c1d51d42
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGAngle.cpp
1 /*
2     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4
5     This file is part of the KDE project
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20     Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #ifdef SVG_SUPPORT
25 #include <math.h>
26
27 #include <ksvg2/ksvg.h>
28
29 #include "SVGAngle.h"
30 #include "SVGHelper.h"
31
32 using namespace WebCore;
33
34 const double deg2rad = 0.017453292519943295769; // pi/180
35 const double deg2grad = 400.0 / 360.0;
36
37 #define rad2grad deg2grad / deg2rad
38
39 SVGAngle::SVGAngle(const SVGStyledElement* context)
40     : Shared<SVGAngle>()
41     , m_unitType(SVG_ANGLETYPE_UNKNOWN)
42     , m_value(0)
43     , m_valueInSpecifiedUnits(0)
44     , m_context(context)
45 {
46 }
47
48 SVGAngle::~SVGAngle()
49 {
50 }
51
52 SVGAngle::SVGAngleType SVGAngle::unitType() const
53 {
54     return m_unitType;
55 }
56
57 void SVGAngle::setValue(float value)
58 {
59     m_value = value;
60 }
61
62 float SVGAngle::value() const
63 {
64     return m_value;
65 }
66
67 // calc m_value
68 void SVGAngle::calculate()
69 {
70     if (m_unitType == SVG_ANGLETYPE_GRAD)
71         m_value = m_valueInSpecifiedUnits / deg2grad;
72     else if (m_unitType == SVG_ANGLETYPE_RAD)
73         m_value = m_valueInSpecifiedUnits / deg2rad;
74     else if (m_unitType == SVG_ANGLETYPE_UNSPECIFIED || m_unitType == SVG_ANGLETYPE_DEG)
75         m_value = m_valueInSpecifiedUnits;
76 }
77
78 void SVGAngle::setValueInSpecifiedUnits(float valueInSpecifiedUnits)
79 {
80     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
81     calculate();
82 }
83
84 float SVGAngle::valueInSpecifiedUnits() const
85 {
86     return m_valueInSpecifiedUnits;
87 }
88
89 void SVGAngle::setValueAsString(const String& s)
90 {
91     m_valueAsString = s;
92
93     bool bOK;
94     m_valueInSpecifiedUnits = m_valueAsString.deprecatedString().toDouble(&bOK);
95     m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
96
97     if (!bOK) {
98         if (m_valueAsString.endsWith("deg"))
99             m_unitType = SVG_ANGLETYPE_DEG;
100         else if (m_valueAsString.endsWith("grad"))
101             m_unitType = SVG_ANGLETYPE_GRAD;
102         else if (m_valueAsString.endsWith("rad"))
103             m_unitType = SVG_ANGLETYPE_RAD;
104     }
105     
106     calculate();
107 }
108
109 String SVGAngle::valueAsString() const
110 {
111     m_valueAsString = String::number(m_valueInSpecifiedUnits);
112
113     switch(m_unitType) {
114         case SVG_ANGLETYPE_UNSPECIFIED:
115         case SVG_ANGLETYPE_DEG:
116             m_valueAsString += "deg";
117             break;
118         case SVG_ANGLETYPE_RAD:
119             m_valueAsString += "rad";
120             break;
121         case SVG_ANGLETYPE_GRAD:
122             m_valueAsString += "grad";
123             break;
124         case SVG_ANGLETYPE_UNKNOWN:
125             break;
126     }
127     
128     return m_valueAsString;
129 }
130
131 void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits)
132 {
133     m_unitType = (SVGAngleType)unitType;
134     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
135     calculate();
136 }
137
138 void SVGAngle::convertToSpecifiedUnits(unsigned short unitType)
139 {
140     if (m_unitType == unitType)
141         return;
142
143     if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_RAD)
144         m_valueInSpecifiedUnits *= deg2rad;
145     else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_RAD)
146         m_valueInSpecifiedUnits /= rad2grad;
147     else if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_GRAD)
148         m_valueInSpecifiedUnits *= deg2grad;
149     else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_GRAD)
150         m_valueInSpecifiedUnits *= rad2grad;
151     else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_DEG)
152         m_valueInSpecifiedUnits /= deg2rad;
153     else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_DEG)
154         m_valueInSpecifiedUnits /= deg2grad;
155
156     m_unitType = (SVGAngleType)unitType;
157 }
158
159 // Helpers
160 double SVGAngle::todeg(double rad)
161 {
162     return rad / deg2rad;
163 }
164
165 double SVGAngle::torad(double deg)
166 {
167     return deg * deg2rad;
168 }
169
170 double SVGAngle::shortestArcBisector(double angle1, double angle2)
171 {
172     double bisector = (angle1 + angle2) / 2;
173
174     if (fabs(angle1 - angle2) > 180)
175         bisector += 180;
176
177     return bisector;
178 }
179
180 const SVGStyledElement *SVGAngle::context() const
181 {
182     return m_context;
183 }
184
185 void SVGAngle::setContext(const SVGStyledElement *context)
186 {
187     m_context = context;
188 }
189
190
191 // vim:ts=4:noet
192 #endif // SVG_SUPPORT
193