File indexing completed on 2024-04-28 11:39:08

0001 /*
0002     Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2006 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #include "wtf/Platform.h"
0024 
0025 #if ENABLE(SVG)
0026 #include "SVGAngle.h"
0027 
0028 #include <math.h>
0029 #include <wtf/MathExtras.h>
0030 
0031 namespace WebCore
0032 {
0033 
0034 SVGAngle::SVGAngle()
0035     : RefCounted<SVGAngle>(0)
0036     , m_unitType(SVG_ANGLETYPE_UNKNOWN)
0037     , m_value(0)
0038     , m_valueInSpecifiedUnits(0)
0039 {
0040 }
0041 
0042 SVGAngle::~SVGAngle()
0043 {
0044 }
0045 
0046 SVGAngle::SVGAngleType SVGAngle::unitType() const
0047 {
0048     return m_unitType;
0049 }
0050 
0051 void SVGAngle::setValue(float value)
0052 {
0053     m_value = value;
0054 }
0055 
0056 float SVGAngle::value() const
0057 {
0058     return m_value;
0059 }
0060 
0061 // calc m_value
0062 void SVGAngle::calculate()
0063 {
0064     if (m_unitType == SVG_ANGLETYPE_GRAD) {
0065         m_value = grad2deg(m_valueInSpecifiedUnits);
0066     } else if (m_unitType == SVG_ANGLETYPE_RAD) {
0067         m_value = rad2deg(m_valueInSpecifiedUnits);
0068     } else if (m_unitType == SVG_ANGLETYPE_UNSPECIFIED || m_unitType == SVG_ANGLETYPE_DEG) {
0069         m_value = m_valueInSpecifiedUnits;
0070     }
0071 }
0072 
0073 void SVGAngle::setValueInSpecifiedUnits(float valueInSpecifiedUnits)
0074 {
0075     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
0076     calculate();
0077 }
0078 
0079 float SVGAngle::valueInSpecifiedUnits() const
0080 {
0081     return m_valueInSpecifiedUnits;
0082 }
0083 
0084 void SVGAngle::setValueAsString(const String &s)
0085 {
0086     m_valueAsString = s;
0087 
0088     bool bOK;
0089     m_valueInSpecifiedUnits = m_valueAsString.toFloat(&bOK);
0090     m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
0091 
0092     if (!bOK) {
0093         if (m_valueAsString.endsWith("deg")) {
0094             m_unitType = SVG_ANGLETYPE_DEG;
0095         } else if (m_valueAsString.endsWith("grad")) {
0096             m_unitType = SVG_ANGLETYPE_GRAD;
0097         } else if (m_valueAsString.endsWith("rad")) {
0098             m_unitType = SVG_ANGLETYPE_RAD;
0099         }
0100     }
0101 
0102     calculate();
0103 }
0104 
0105 String SVGAngle::valueAsString() const
0106 {
0107     m_valueAsString = String::number(m_valueInSpecifiedUnits);
0108 
0109     switch (m_unitType) {
0110     case SVG_ANGLETYPE_UNSPECIFIED:
0111     case SVG_ANGLETYPE_DEG:
0112         m_valueAsString += "deg";
0113         break;
0114     case SVG_ANGLETYPE_RAD:
0115         m_valueAsString += "rad";
0116         break;
0117     case SVG_ANGLETYPE_GRAD:
0118         m_valueAsString += "grad";
0119         break;
0120     case SVG_ANGLETYPE_UNKNOWN:
0121         break;
0122     }
0123 
0124     return m_valueAsString;
0125 }
0126 
0127 void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits)
0128 {
0129     m_unitType = (SVGAngleType)unitType;
0130     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
0131     calculate();
0132 }
0133 
0134 void SVGAngle::convertToSpecifiedUnits(unsigned short unitType)
0135 {
0136     if (m_unitType == unitType) {
0137         return;
0138     }
0139 
0140     if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_RAD) {
0141         m_valueInSpecifiedUnits = deg2rad(m_valueInSpecifiedUnits);
0142     } else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_RAD) {
0143         m_valueInSpecifiedUnits = grad2rad(m_valueInSpecifiedUnits);
0144     } else if (m_unitType == SVG_ANGLETYPE_DEG && unitType == SVG_ANGLETYPE_GRAD) {
0145         m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits);
0146     } else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_GRAD) {
0147         m_valueInSpecifiedUnits = rad2grad(m_valueInSpecifiedUnits);
0148     } else if (m_unitType == SVG_ANGLETYPE_RAD && unitType == SVG_ANGLETYPE_DEG) {
0149         m_valueInSpecifiedUnits = rad2deg(m_valueInSpecifiedUnits);
0150     } else if (m_unitType == SVG_ANGLETYPE_GRAD && unitType == SVG_ANGLETYPE_DEG) {
0151         m_valueInSpecifiedUnits = grad2deg(m_valueInSpecifiedUnits);
0152     }
0153 
0154     m_unitType = (SVGAngleType)unitType;
0155 }
0156 
0157 // Helpers
0158 double SVGAngle::todeg(double rad)
0159 {
0160     return rad2deg(rad);
0161 }
0162 
0163 double SVGAngle::torad(double deg)
0164 {
0165     return deg2rad(deg);
0166 }
0167 
0168 double SVGAngle::shortestArcBisector(double angle1, double angle2)
0169 {
0170     double bisector = (angle1 + angle2) / 2;
0171 
0172     if (fabs(angle1 - angle2) > 180) {
0173         bisector += 180;
0174     }
0175 
0176     return bisector;
0177 }
0178 
0179 }
0180 
0181 #endif // ENABLE(SVG)