Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / animation / TimingFunction.cpp
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "platform/animation/TimingFunction.h"
7
8 #include "wtf/MathExtras.h"
9
10 namespace WebCore {
11
12 String LinearTimingFunction::toString() const
13 {
14     return "linear";
15 }
16
17 double LinearTimingFunction::evaluate(double fraction, double) const
18 {
19     return fraction;
20 }
21
22 String CubicBezierTimingFunction::toString() const
23 {
24     switch (this->subType()) {
25     case CubicBezierTimingFunction::Ease:
26         return "ease";
27     case CubicBezierTimingFunction::EaseIn:
28         return "ease-in";
29     case CubicBezierTimingFunction::EaseOut:
30         return "ease-out";
31     case CubicBezierTimingFunction::EaseInOut:
32         return "ease-in-out";
33     case CubicBezierTimingFunction::Custom:
34         return "cubic-bezier(" + String::numberToStringECMAScript(this->x1()) + ", " +
35             String::numberToStringECMAScript(this->y1()) + ", " + String::numberToStringECMAScript(this->x2()) +
36             ", " + String::numberToStringECMAScript(this->y2()) + ")";
37     default:
38         ASSERT_NOT_REACHED();
39     }
40     return "";
41 }
42
43 double CubicBezierTimingFunction::evaluate(double fraction, double accuracy) const
44 {
45     if (!m_bezier)
46         m_bezier = adoptPtr(new UnitBezier(m_x1, m_y1, m_x2, m_y2));
47     return m_bezier->solve(fraction, accuracy);
48 }
49
50 String StepsTimingFunction::toString() const
51 {
52     StringBuilder builder;
53     switch (this->subType()) {
54     case StepsTimingFunction::Start:
55         return "step-start";
56     case StepsTimingFunction::Middle:
57         return "step-middle";
58     case StepsTimingFunction::End:
59         return "step-end";
60     case StepsTimingFunction::Custom:
61         builder.append("steps(" + String::numberToStringECMAScript(this->numberOfSteps()) + ", ");
62
63         if (this->stepAtPosition() == StepsTimingFunction::StepAtStart)
64             builder.append("start");
65         else if (this->stepAtPosition() == StepsTimingFunction::StepAtMiddle)
66             builder.append("middle");
67         else if (this->stepAtPosition() == StepsTimingFunction::StepAtEnd)
68             builder.append("end");
69         else
70             ASSERT_NOT_REACHED();
71
72         builder.append(")");
73         break;
74     default:
75         ASSERT_NOT_REACHED();
76     }
77     return builder.toString();
78 }
79
80 double StepsTimingFunction::evaluate(double fraction, double) const
81 {
82     double startOffset = 0;
83     switch (m_stepAtPosition) {
84     case StepAtStart:
85         startOffset = 1;
86         break;
87     case StepAtMiddle:
88         startOffset = 0.5;
89         break;
90     case StepAtEnd:
91         startOffset = 0;
92         break;
93     default:
94         ASSERT_NOT_REACHED();
95         break;
96     }
97     return clampTo(floor((m_steps * fraction) + startOffset) / m_steps, 0.0, 1.0);
98 }
99
100 // Equals operators
101 bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs)
102 {
103     return rhs.type() == TimingFunction::LinearFunction;
104 }
105
106 bool operator==(const CubicBezierTimingFunction& lhs, const TimingFunction& rhs)
107 {
108     if (rhs.type() != TimingFunction::CubicBezierFunction)
109         return false;
110
111     const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs);
112     if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom))
113         return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2());
114
115     return lhs.subType() == ctf.subType();
116 }
117
118 bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs)
119 {
120     if (rhs.type() != TimingFunction::StepsFunction)
121         return false;
122
123     const StepsTimingFunction& stf = toStepsTimingFunction(rhs);
124     if ((lhs.subType() == StepsTimingFunction::Custom) && (stf.subType() == StepsTimingFunction::Custom))
125         return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtPosition() == stf.stepAtPosition());
126
127     return lhs.subType() == stf.subType();
128 }
129
130 // The generic operator== *must* come after the
131 // non-generic operator== otherwise it will end up calling itself.
132 bool operator==(const TimingFunction& lhs, const TimingFunction& rhs)
133 {
134     switch (lhs.type()) {
135     case TimingFunction::LinearFunction: {
136         const LinearTimingFunction& linear = toLinearTimingFunction(lhs);
137         return (linear == rhs);
138     }
139     case TimingFunction::CubicBezierFunction: {
140         const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(lhs);
141         return (cubic == rhs);
142     }
143     case TimingFunction::StepsFunction: {
144         const StepsTimingFunction& step = toStepsTimingFunction(lhs);
145         return (step == rhs);
146     }
147     default:
148         ASSERT_NOT_REACHED();
149     }
150     return false;
151 }
152
153 // No need to define specific operator!= as they can all come via this function.
154 bool operator!=(const TimingFunction& lhs, const TimingFunction& rhs)
155 {
156     return !(lhs == rhs);
157 }
158
159 } // namespace WebCore