1/*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#ifndef TimingFunction_h
26#define TimingFunction_h
27
28#include "platform/animation/AnimationUtilities.h" // For blend()
29#include "platform/animation/UnitBezier.h"
30#include "wtf/OwnPtr.h"
31#include "wtf/PassOwnPtr.h"
32#include "wtf/PassRefPtr.h"
33#include "wtf/RefCounted.h"
34#include "wtf/StdLibExtras.h"
35#include "wtf/text/StringBuilder.h"
36#include "wtf/text/WTFString.h"
37#include <algorithm>
38
39namespace blink {
40
41class PLATFORM_EXPORT TimingFunction : public RefCounted<TimingFunction> {
42public:
43
44    enum Type {
45        LinearFunction, CubicBezierFunction, StepsFunction
46    };
47
48    virtual ~TimingFunction() { }
49
50    Type type() const { return m_type; }
51
52    virtual String toString() const = 0;
53
54    // Evaluates the timing function at the given fraction. The accuracy parameter provides a hint as to the required
55    // accuracy and is not guaranteed.
56    virtual double evaluate(double fraction, double accuracy) const = 0;
57
58    // This function returns the minimum and maximum values obtainable when
59    // calling evaluate();
60    virtual void range(double* minValue, double* maxValue) const = 0;
61
62protected:
63    TimingFunction(Type type)
64        : m_type(type)
65    {
66    }
67
68private:
69    Type m_type;
70};
71
72class PLATFORM_EXPORT LinearTimingFunction FINAL : public TimingFunction {
73public:
74    static LinearTimingFunction* shared()
75    {
76        DEFINE_STATIC_REF(LinearTimingFunction, linear, (adoptRef(new LinearTimingFunction())));
77        return linear;
78    }
79
80    virtual ~LinearTimingFunction() { }
81
82    virtual String toString() const OVERRIDE;
83
84    virtual double evaluate(double fraction, double) const OVERRIDE;
85
86    virtual void range(double* minValue, double* maxValue) const OVERRIDE;
87private:
88    LinearTimingFunction()
89        : TimingFunction(LinearFunction)
90    {
91    }
92};
93
94class PLATFORM_EXPORT CubicBezierTimingFunction FINAL : public TimingFunction {
95public:
96    enum SubType {
97        Ease,
98        EaseIn,
99        EaseOut,
100        EaseInOut,
101        Custom
102    };
103
104    static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
105    {
106        return adoptRef(new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
107    }
108
109    static CubicBezierTimingFunction* preset(SubType subType)
110    {
111        switch (subType) {
112        case Ease:
113            {
114                DEFINE_STATIC_REF(CubicBezierTimingFunction, ease, (adoptRef(new CubicBezierTimingFunction(Ease, 0.25, 0.1, 0.25, 1.0))));
115                return ease;
116            }
117        case EaseIn:
118            {
119                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeIn, (adoptRef(new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0))));
120                return easeIn;
121            }
122        case EaseOut:
123            {
124                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeOut, (adoptRef(new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0))));
125                return easeOut;
126            }
127        case EaseInOut:
128            {
129                DEFINE_STATIC_REF(CubicBezierTimingFunction, easeInOut, (adoptRef(new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0))));
130                return easeInOut;
131            }
132        default:
133            ASSERT_NOT_REACHED();
134            return 0;
135        }
136    }
137
138    virtual ~CubicBezierTimingFunction() { }
139
140    virtual String toString() const OVERRIDE;
141
142    virtual double evaluate(double fraction, double accuracy) const OVERRIDE;
143    virtual void range(double* minValue, double* maxValue) const OVERRIDE;
144
145    double x1() const { return m_x1; }
146    double y1() const { return m_y1; }
147    double x2() const { return m_x2; }
148    double y2() const { return m_y2; }
149
150    SubType subType() const { return m_subType; }
151
152private:
153    explicit CubicBezierTimingFunction(SubType subType, double x1, double y1, double x2, double y2)
154        : TimingFunction(CubicBezierFunction)
155        , m_x1(x1)
156        , m_y1(y1)
157        , m_x2(x2)
158        , m_y2(y2)
159        , m_subType(subType)
160    {
161    }
162
163    double m_x1;
164    double m_y1;
165    double m_x2;
166    double m_y2;
167    SubType m_subType;
168    mutable OwnPtr<UnitBezier> m_bezier;
169};
170
171class PLATFORM_EXPORT StepsTimingFunction FINAL : public TimingFunction {
172public:
173    enum StepAtPosition {
174        Start,
175        Middle,
176        End
177    };
178
179    static PassRefPtr<StepsTimingFunction> create(int steps, StepAtPosition stepAtPosition)
180    {
181        return adoptRef(new StepsTimingFunction(steps, stepAtPosition));
182    }
183
184    static StepsTimingFunction* preset(StepAtPosition position)
185    {
186        DEFINE_STATIC_REF(StepsTimingFunction, start, create(1, Start));
187        DEFINE_STATIC_REF(StepsTimingFunction, middle, create(1, Middle));
188        DEFINE_STATIC_REF(StepsTimingFunction, end, create(1, End));
189        switch (position) {
190        case Start:
191            return start;
192        case Middle:
193            return middle;
194        case End:
195            return end;
196        default:
197            ASSERT_NOT_REACHED();
198            return end;
199        }
200    }
201
202
203    virtual ~StepsTimingFunction() { }
204
205    virtual String toString() const OVERRIDE;
206
207    virtual double evaluate(double fraction, double) const OVERRIDE;
208
209    virtual void range(double* minValue, double* maxValue) const OVERRIDE;
210    int numberOfSteps() const { return m_steps; }
211    StepAtPosition stepAtPosition() const { return m_stepAtPosition; }
212
213private:
214    StepsTimingFunction(int steps, StepAtPosition stepAtPosition)
215        : TimingFunction(StepsFunction)
216        , m_steps(steps)
217        , m_stepAtPosition(stepAtPosition)
218    {
219    }
220
221    int m_steps;
222    StepAtPosition m_stepAtPosition;
223};
224
225PLATFORM_EXPORT bool operator==(const LinearTimingFunction&, const TimingFunction&);
226PLATFORM_EXPORT bool operator==(const CubicBezierTimingFunction&, const TimingFunction&);
227PLATFORM_EXPORT bool operator==(const StepsTimingFunction&, const TimingFunction&);
228
229PLATFORM_EXPORT bool operator==(const TimingFunction&, const TimingFunction&);
230PLATFORM_EXPORT bool operator!=(const TimingFunction&, const TimingFunction&);
231
232#define DEFINE_TIMING_FUNCTION_TYPE_CASTS(typeName) \
233    DEFINE_TYPE_CASTS( \
234        typeName##TimingFunction, TimingFunction, value, \
235        value->type() == TimingFunction::typeName##Function, \
236        value.type() == TimingFunction::typeName##Function)
237
238DEFINE_TIMING_FUNCTION_TYPE_CASTS(Linear);
239DEFINE_TIMING_FUNCTION_TYPE_CASTS(CubicBezier);
240DEFINE_TIMING_FUNCTION_TYPE_CASTS(Steps);
241
242} // namespace blink
243
244#endif // TimingFunction_h
245