Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGAnimatedAngle.cpp
1 /*
2  * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "core/svg/SVGAnimatedAngle.h"
22
23 #include "bindings/v8/ExceptionStatePlaceholder.h"
24 #include "core/svg/SVGAnimateElement.h"
25 #include "core/svg/SVGMarkerElement.h"
26
27 namespace WebCore {
28
29 SVGAnimatedAngleAnimator::SVGAnimatedAngleAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
30     : SVGAnimatedTypeAnimator(AnimatedAngle, animationElement, contextElement)
31 {
32 }
33
34 PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string)
35 {
36     OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createAngleAndEnumeration(new pair<SVGAngle, unsigned>);
37     pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration();
38
39     SVGAngle angle;
40     SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string,  angle);
41     if (orientType > 0)
42         animatedPair.second = orientType;
43     if (orientType == SVGMarkerOrientAngle)
44         animatedPair.first = angle;
45
46     return animatedType.release();
47 }
48
49 PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
50 {
51     return SVGAnimatedType::createAngleAndEnumeration(constructFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes));
52 }
53
54 void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
55 {
56     stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
57 }
58
59 void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
60 {
61     resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::angleAndEnumeration);
62 }
63
64 void SVGAnimatedAngleAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
65 {
66     animValWillChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
67 }
68
69 void SVGAnimatedAngleAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
70 {
71     animValDidChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
72 }
73
74 void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
75 {
76     ASSERT(from->type() == AnimatedAngle);
77     ASSERT(from->type() == to->type());
78
79     const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration();
80     pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
81     // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
82     if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle)
83         return;
84     const SVGAngle& fromAngle = fromAngleAndEnumeration.first;
85     SVGAngle& toAngle = toAngleAndEnumeration.first;
86     toAngle.setValue(toAngle.value() + fromAngle.value());
87 }
88
89 void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
90 {
91     ASSERT(m_animationElement);
92     ASSERT(m_contextElement);
93
94     const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration();
95     const pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
96     const pair<SVGAngle, unsigned>& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration();
97     pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
98
99     if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
100         // Animating from eg. auto to 90deg, or auto to 90deg.
101         if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
102             // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
103             if (toAngleAndEnumeration.second == SVGMarkerOrientAuto) {
104                 if (percentage < 0.5f) {
105                     animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first;
106                     animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
107                     return;
108                 }
109                 animatedAngleAndEnumeration.first.setValue(0);
110                 animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
111                 return;
112             }
113             animatedAngleAndEnumeration.first.setValue(0);
114             animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
115             return;
116         }
117     }
118
119     // From 'auto' to 'auto'.
120     if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) {
121         animatedAngleAndEnumeration.first.setValue(0);
122         animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
123         return;
124     }
125
126     // If the enumeration value is not angle or auto, its unknown.
127     if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) {
128         animatedAngleAndEnumeration.first.setValue(0);
129         animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
130         return;
131     }
132
133     // Regular from angle to angle animation, with all features like additive etc.
134     animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
135
136     SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
137     const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
138     float animatedAngle = animatedSVGAngle.value();
139     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
140     animatedSVGAngle.setValue(animatedAngle);
141 }
142
143 float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)
144 {
145     SVGAngle from = SVGAngle();
146     from.setValueAsString(fromString, ASSERT_NO_EXCEPTION);
147     SVGAngle to = SVGAngle();
148     to.setValueAsString(toString, ASSERT_NO_EXCEPTION);
149     return fabsf(to.value() - from.value());
150 }
151
152 }