15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAngle.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/svg/SVGAnimationElement.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGParserUtilities.h"
30f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/MathExtras.h"
31f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/text/WTFString.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerOrientType>()
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (entries.isEmpty()) {
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        entries.append(std::make_pair(SVGMarkerOrientAuto, "auto"));
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        entries.append(std::make_pair(SVGMarkerOrientAngle, "angle"));
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        entries.append(std::make_pair(SVGMarkerOrientAutoStartReverse, "auto-start-reverse"));
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return entries;
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitemplate<> unsigned short getMaxExposedEnumValue<SVGMarkerOrientType>()
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return SVGMarkerOrientAngle;
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SVGMarkerOrientEnumeration::SVGMarkerOrientEnumeration(SVGAngle* angle)
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : SVGEnumeration<SVGMarkerOrientType>(SVGMarkerOrientAngle)
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_angle(angle)
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SVGMarkerOrientEnumeration::~SVGMarkerOrientEnumeration()
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SVGMarkerOrientEnumeration::notifyChange()
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(m_angle);
64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_angle->orientTypeChanged();
65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void SVGMarkerOrientEnumeration::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // SVGMarkerOrientEnumeration is only animated via SVGAngle
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT_NOT_REACHED();
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid SVGMarkerOrientEnumeration::calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // SVGMarkerOrientEnumeration is only animated via SVGAngle
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT_NOT_REACHED();
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochfloat SVGMarkerOrientEnumeration::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // SVGMarkerOrientEnumeration is only animated via SVGAngle
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT_NOT_REACHED();
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return -1.0;
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGAngle::SVGAngle()
87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_valueInSpecifiedUnits(0)
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_orientType(SVGMarkerOrientEnumeration::create(this))
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SVGAngle::SVGAngle(SVGAngleType unitType, float valueInSpecifiedUnits, SVGMarkerOrientType orientType)
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_unitType(unitType)
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_valueInSpecifiedUnits(valueInSpecifiedUnits)
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_orientType(SVGMarkerOrientEnumeration::create(this))
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_orientType->setEnumValue(orientType);
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SVGAngle::~SVGAngle()
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SVGAngle> SVGAngle::clone() const
106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return adoptRef(new SVGAngle(m_unitType, m_valueInSpecifiedUnits, m_orientType->enumValue()));
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAngle::value() const
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_unitType) {
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_GRAD:
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return grad2deg(m_valueInSpecifiedUnits);
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_RAD:
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return rad2deg(m_valueInSpecifiedUnits);
1175d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    case SVG_ANGLETYPE_TURN:
1185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return turn2deg(m_valueInSpecifiedUnits);
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNSPECIFIED:
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNKNOWN:
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_DEG:
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_valueInSpecifiedUnits;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAngle::setValue(float value)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_unitType) {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_GRAD:
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_valueInSpecifiedUnits = deg2grad(value);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_RAD:
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_valueInSpecifiedUnits = deg2rad(value);
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    case SVG_ANGLETYPE_TURN:
1395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_valueInSpecifiedUnits = deg2turn(value);
1405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        break;
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNSPECIFIED:
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNKNOWN:
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_DEG:
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_valueInSpecifiedUnits = value;
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_orientType->setEnumValue(SVGMarkerOrientAngle);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochtemplate<typename CharType>
151591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic SVGAngle::SVGAngleType stringToAngleType(const CharType*& ptr, const CharType* end)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If there's no unit given, the angle type is unspecified.
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ptr == end)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    SVGAngle::SVGAngleType type = SVGAngle::SVG_ANGLETYPE_UNKNOWN;
1585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    const CharType firstChar = *ptr++;
1595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (isHTMLSpace<CharType>(firstChar)) {
1615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        type = SVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
1625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    } else if (end - ptr >= 2) {
1635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        const CharType secondChar = *ptr++;
1645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        const CharType thirdChar = *ptr++;
1655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (firstChar == 'd' && secondChar == 'e' && thirdChar == 'g') {
1665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            type = SVGAngle::SVG_ANGLETYPE_DEG;
1675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        } else if (firstChar == 'r' && secondChar == 'a' && thirdChar == 'd') {
1685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            type = SVGAngle::SVG_ANGLETYPE_RAD;
1695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        } else if (ptr != end) {
1705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            const CharType fourthChar = *ptr++;
1715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if (firstChar == 'g' && secondChar == 'r' && thirdChar == 'a' && fourthChar == 'd')
1725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                type = SVGAngle::SVG_ANGLETYPE_GRAD;
1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            else if (firstChar == 't' && secondChar == 'u' && thirdChar == 'r' && fourthChar == 'n')
1745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                type = SVGAngle::SVG_ANGLETYPE_TURN;
1755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        }
1765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!skipOptionalSVGSpaces(ptr, end))
1795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return type;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String SVGAngle::valueAsString() const
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_unitType) {
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_DEG: {
1883c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        DEFINE_STATIC_LOCAL(String, degString, ("deg"));
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String::number(m_valueInSpecifiedUnits) + degString;
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_RAD: {
1923c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        DEFINE_STATIC_LOCAL(String, radString, ("rad"));
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String::number(m_valueInSpecifiedUnits) + radString;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_GRAD: {
1963c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        DEFINE_STATIC_LOCAL(String, gradString, ("grad"));
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String::number(m_valueInSpecifiedUnits) + gradString;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    case SVG_ANGLETYPE_TURN: {
2005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        DEFINE_STATIC_LOCAL(String, turnString, ("turn"));
2015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return String::number(m_valueInSpecifiedUnits) + turnString;
2025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNSPECIFIED:
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNKNOWN:
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return String::number(m_valueInSpecifiedUnits);
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
212591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochtemplate<typename CharType>
213591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool parseValue(const String& value, float& valueInSpecifiedUnits, SVGAngle::SVGAngleType& unitType)
214591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
215591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const CharType* ptr = value.getCharacters<CharType>();
216591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const CharType* end = ptr + value.length();
217591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
2185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!parseNumber(ptr, end, valueInSpecifiedUnits, AllowLeadingWhitespace))
219591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return false;
220591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
221591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    unitType = stringToAngleType(ptr, end);
222591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (unitType == SVGAngle::SVG_ANGLETYPE_UNKNOWN)
223591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return false;
224591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
225591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return true;
226591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
227591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
22851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SVGAngle::setValueAsString(const String& value, ExceptionState& exceptionState)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value.isEmpty()) {
231d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (value == "auto") {
236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_orientType->setEnumValue(SVGMarkerOrientAuto);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (value == "auto-start-reverse") {
2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_orientType->setEnumValue(SVGMarkerOrientAutoStartReverse);
2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float valueInSpecifiedUnits = 0;
247591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    SVGAngleType unitType = SVG_ANGLETYPE_UNKNOWN;
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
249591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    bool success = value.is8Bit() ? parseValue<LChar>(value, valueInSpecifiedUnits, unitType)
250591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch                                  : parseValue<UChar>(value, valueInSpecifiedUnits, unitType);
251591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (!success) {
25209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_orientType->setEnumValue(SVGMarkerOrientAngle);
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_unitType = unitType;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_valueInSpecifiedUnits = valueInSpecifiedUnits;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SVGAngle::newValueSpecifiedUnits(SVGAngleType unitType, float valueInSpecifiedUnits)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_orientType->setEnumValue(SVGMarkerOrientAngle);
264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_unitType = unitType;
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_valueInSpecifiedUnits = valueInSpecifiedUnits;
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SVGAngle::convertToSpecifiedUnits(SVGAngleType unitType, ExceptionState& exceptionState)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_unitType == SVG_ANGLETYPE_UNKNOWN) {
27109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "Cannot convert from unknown or invalid units.");
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unitType == m_unitType)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_unitType) {
2795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    case SVG_ANGLETYPE_TURN:
2805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        switch (unitType) {
2815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_GRAD:
2825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = turn2grad(m_valueInSpecifiedUnits);
2835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
2845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_UNSPECIFIED:
2855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_DEG:
2865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = turn2deg(m_valueInSpecifiedUnits);
2875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
2885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_RAD:
2895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = deg2rad(turn2deg(m_valueInSpecifiedUnits));
2905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
2915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_TURN:
2925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_UNKNOWN:
2935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            ASSERT_NOT_REACHED();
2945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
2955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        }
2965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        break;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_RAD:
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (unitType) {
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_GRAD:
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = rad2grad(m_valueInSpecifiedUnits);
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_UNSPECIFIED:
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_DEG:
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = rad2deg(m_valueInSpecifiedUnits);
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_TURN:
3075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = deg2turn(rad2deg(m_valueInSpecifiedUnits));
3085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_RAD:
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_UNKNOWN:
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT_NOT_REACHED();
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_GRAD:
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (unitType) {
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_RAD:
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = grad2rad(m_valueInSpecifiedUnits);
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_UNSPECIFIED:
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_DEG:
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = grad2deg(m_valueInSpecifiedUnits);
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_TURN:
3255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = grad2turn(m_valueInSpecifiedUnits);
3265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_GRAD:
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_UNKNOWN:
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT_NOT_REACHED();
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNSPECIFIED:
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Spec: For angles, a unitless value is treated the same as if degrees were specified.
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_DEG:
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (unitType) {
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_RAD:
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = deg2rad(m_valueInSpecifiedUnits);
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_GRAD:
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits);
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_TURN:
3445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_valueInSpecifiedUnits = deg2turn(m_valueInSpecifiedUnits);
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        case SVG_ANGLETYPE_UNSPECIFIED:
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_DEG:
3485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            break;
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case SVG_ANGLETYPE_UNKNOWN:
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT_NOT_REACHED();
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SVG_ANGLETYPE_UNKNOWN:
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_NOT_REACHED();
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_unitType = unitType;
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_orientType->setEnumValue(SVGMarkerOrientAngle);
361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
363d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void SVGAngle::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SVGAngle> otherAngle = toSVGAngle(other);
366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (orientType()->enumValue() != SVGMarkerOrientAngle || otherAngle->orientType()->enumValue() != SVGMarkerOrientAngle)
369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setValue(value() + otherAngle->value());
372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
37407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid SVGAngle::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(animationElement);
377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool isToAnimation = animationElement->animationMode() == ToAnimation;
378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SVGAngle> fromAngle = isToAnimation ? this : toSVGAngle(from);
380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SVGAngle> toAngle = toSVGAngle(to);
381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SVGAngle> toAtEndOfDurationAngle = toSVGAngle(toAtEndOfDuration);
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SVGMarkerOrientType fromOrientType = fromAngle->orientType()->enumValue();
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SVGMarkerOrientType toOrientType = toAngle->orientType()->enumValue();
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (fromOrientType != toOrientType) {
3877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Animating from eg. 90deg to auto.
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (fromOrientType == SVGMarkerOrientAngle) {
389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
3907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (toOrientType == SVGMarkerOrientAuto || toOrientType == SVGMarkerOrientAutoStartReverse) {
391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (percentage < 0.5f) {
392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    newValueSpecifiedUnits(fromAngle->unitType(), fromAngle->valueInSpecifiedUnits());
393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    return;
394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                }
3957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                orientType()->setEnumValue(toOrientType);
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                return;
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            }
398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_valueInSpecifiedUnits = 0;
399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            orientType()->setEnumValue(SVGMarkerOrientUnknown);
400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return;
4017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        } else if (toOrientType == SVGMarkerOrientAuto || toOrientType == SVGMarkerOrientAutoStartReverse) {
4027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // Animating from e.g 'auto' to 'auto-start-reverse'
4037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (percentage >= 0.5f) {
4047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                m_valueInSpecifiedUnits = 0;
4057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                orientType()->setEnumValue(toOrientType);
4067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                return;
4077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            }
408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
4117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // From 'auto' to 'auto', or 'auto-start-reverse' to 'auto-start-reverse'
4127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (fromOrientType == SVGMarkerOrientAuto || fromOrientType == SVGMarkerOrientAutoStartReverse) {
413d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_valueInSpecifiedUnits = 0;
4147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        orientType()->setEnumValue(fromOrientType);
415d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
416d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
417d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
418d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // If the enumeration value is not angle or auto, its unknown.
419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (fromOrientType != SVGMarkerOrientAngle) {
420d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_valueInSpecifiedUnits = 0;
421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        orientType()->setEnumValue(SVGMarkerOrientUnknown);
422d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Regular from angle to angle animation, with all features like additive etc.
426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float animatedValue = value();
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngle->value(), toAngle->value(), toAtEndOfDurationAngle->value(), animatedValue);
428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    orientType()->setEnumValue(SVGMarkerOrientAngle);
429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setValue(animatedValue);
430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
43207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochfloat SVGAngle::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
433d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
434d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return fabsf(value() - toSVGAngle(other)->value());
435d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SVGAngle::orientTypeChanged()
438d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
4397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (orientType()->enumValue() == SVGMarkerOrientAuto || orientType()->enumValue() == SVGMarkerOrientAutoStartReverse) {
440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_valueInSpecifiedUnits = 0;
442d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
446