- add third_party src.
[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 static inline SVGAngle& sharedSVGAngle(const String& valueAsString)
35 {
36     DEFINE_STATIC_LOCAL(SVGAngle, sharedAngle, ());
37     sharedAngle.setValueAsString(valueAsString, ASSERT_NO_EXCEPTION);
38     return sharedAngle;
39 }
40
41 PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string)
42 {
43     OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createAngleAndEnumeration(new pair<SVGAngle, unsigned>);
44     pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration();
45
46     SVGAngle angle;
47     SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string,  angle);
48     if (orientType > 0)
49         animatedPair.second = orientType;
50     if (orientType == SVGMarkerOrientAngle)
51         animatedPair.first = angle;
52
53     return animatedType.release();
54 }
55
56 PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
57 {
58     return SVGAnimatedType::createAngleAndEnumeration(constructFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes));
59 }
60
61 void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
62 {
63     stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
64 }
65
66 void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
67 {
68     resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::angleAndEnumeration);
69 }
70
71 void SVGAnimatedAngleAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
72 {
73     animValWillChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
74 }
75
76 void SVGAnimatedAngleAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
77 {
78     animValDidChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
79 }
80
81 void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
82 {
83     ASSERT(from->type() == AnimatedAngle);
84     ASSERT(from->type() == to->type());
85
86     const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration();
87     pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
88     // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
89     if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle)
90         return;
91     const SVGAngle& fromAngle = fromAngleAndEnumeration.first;
92     SVGAngle& toAngle = toAngleAndEnumeration.first;
93     toAngle.setValue(toAngle.value() + fromAngle.value());
94 }
95
96 void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
97 {
98     ASSERT(m_animationElement);
99     ASSERT(m_contextElement);
100
101     const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration();
102     const pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
103     const pair<SVGAngle, unsigned>& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration();
104     pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
105
106     if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
107         // Animating from eg. auto to 90deg, or auto to 90deg.
108         if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
109             // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
110             if (toAngleAndEnumeration.second == SVGMarkerOrientAuto) {
111                 if (percentage < 0.5f) {
112                     animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first;
113                     animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
114                     return;
115                 }
116                 animatedAngleAndEnumeration.first.setValue(0);
117                 animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
118                 return;
119             }
120             animatedAngleAndEnumeration.first.setValue(0);
121             animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
122             return;
123         }
124     }
125
126     // From 'auto' to 'auto'.
127     if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) {
128         animatedAngleAndEnumeration.first.setValue(0);
129         animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
130         return;
131     }
132
133     // If the enumeration value is not angle or auto, its unknown.
134     if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) {
135         animatedAngleAndEnumeration.first.setValue(0);
136         animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
137         return;
138     }
139
140     // Regular from angle to angle animation, with all features like additive etc.
141     animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
142
143     SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
144     const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
145     float animatedAngle = animatedSVGAngle.value();
146     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
147     animatedSVGAngle.setValue(animatedAngle);
148 }
149
150 float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)
151 {
152     SVGAngle from = SVGAngle();
153     from.setValueAsString(fromString, ASSERT_NO_EXCEPTION);
154     SVGAngle to = SVGAngle();
155     to.setValueAsString(toString, ASSERT_NO_EXCEPTION);
156     return fabsf(to.value() - from.value());
157 }
158
159 }