Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / cc / animation / keyframed_animation_curve.cc
1 // Copyright 2012 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 <algorithm>
6
7 #include "cc/animation/keyframed_animation_curve.h"
8 #include "ui/gfx/animation/tween.h"
9 #include "ui/gfx/box_f.h"
10
11 namespace cc {
12
13 namespace {
14
15 template <class Keyframe>
16 void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
17                     ScopedPtrVector<Keyframe>& keyframes) {
18   // Usually, the keyframes will be added in order, so this loop would be
19   // unnecessary and we should skip it if possible.
20   if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) {
21     for (size_t i = 0; i < keyframes.size(); ++i) {
22       if (keyframe->Time() < keyframes[i]->Time()) {
23         keyframes.insert(keyframes.begin() + i, keyframe.Pass());
24         return;
25       }
26     }
27   }
28
29   keyframes.push_back(keyframe.Pass());
30 }
31
32 template <class Keyframes>
33 float GetProgress(double t, size_t i, const Keyframes& keyframes) {
34   float progress =
35       static_cast<float>((t - keyframes[i]->Time()) /
36                          (keyframes[i + 1]->Time() - keyframes[i]->Time()));
37
38   if (keyframes[i]->timing_function())
39     progress = keyframes[i]->timing_function()->GetValue(progress);
40   return progress;
41 }
42
43 }  // namespace
44
45 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
46     : time_(time),
47       timing_function_(timing_function.Pass()) {}
48
49 Keyframe::~Keyframe() {}
50
51 double Keyframe::Time() const {
52   return time_;
53 }
54
55 scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
56     double time,
57     SkColor value,
58     scoped_ptr<TimingFunction> timing_function) {
59   return make_scoped_ptr(
60       new ColorKeyframe(time, value, timing_function.Pass()));
61 }
62
63 ColorKeyframe::ColorKeyframe(double time,
64                              SkColor value,
65                              scoped_ptr<TimingFunction> timing_function)
66     : Keyframe(time, timing_function.Pass()),
67       value_(value) {}
68
69 ColorKeyframe::~ColorKeyframe() {}
70
71 SkColor ColorKeyframe::Value() const { return value_; }
72
73 scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
74   scoped_ptr<TimingFunction> func;
75   if (timing_function())
76     func = timing_function()->Clone();
77   return ColorKeyframe::Create(Time(), Value(), func.Pass());
78 }
79
80 scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
81     double time,
82     float value,
83     scoped_ptr<TimingFunction> timing_function) {
84   return make_scoped_ptr(
85       new FloatKeyframe(time, value, timing_function.Pass()));
86 }
87
88 FloatKeyframe::FloatKeyframe(double time,
89                              float value,
90                              scoped_ptr<TimingFunction> timing_function)
91     : Keyframe(time, timing_function.Pass()),
92       value_(value) {}
93
94 FloatKeyframe::~FloatKeyframe() {}
95
96 float FloatKeyframe::Value() const {
97   return value_;
98 }
99
100 scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
101   scoped_ptr<TimingFunction> func;
102   if (timing_function())
103     func = timing_function()->Clone();
104   return FloatKeyframe::Create(Time(), Value(), func.Pass());
105 }
106
107 scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
108     double time,
109     const TransformOperations& value,
110     scoped_ptr<TimingFunction> timing_function) {
111   return make_scoped_ptr(
112       new TransformKeyframe(time, value, timing_function.Pass()));
113 }
114
115 TransformKeyframe::TransformKeyframe(double time,
116                                      const TransformOperations& value,
117                                      scoped_ptr<TimingFunction> timing_function)
118     : Keyframe(time, timing_function.Pass()),
119       value_(value) {}
120
121 TransformKeyframe::~TransformKeyframe() {}
122
123 const TransformOperations& TransformKeyframe::Value() const {
124   return value_;
125 }
126
127 scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
128   scoped_ptr<TimingFunction> func;
129   if (timing_function())
130     func = timing_function()->Clone();
131   return TransformKeyframe::Create(Time(), Value(), func.Pass());
132 }
133
134 scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
135     double time,
136     const FilterOperations& value,
137     scoped_ptr<TimingFunction> timing_function) {
138   return make_scoped_ptr(
139       new FilterKeyframe(time, value, timing_function.Pass()));
140 }
141
142 FilterKeyframe::FilterKeyframe(double time,
143                                const FilterOperations& value,
144                                scoped_ptr<TimingFunction> timing_function)
145     : Keyframe(time, timing_function.Pass()),
146       value_(value) {}
147
148 FilterKeyframe::~FilterKeyframe() {}
149
150 const FilterOperations& FilterKeyframe::Value() const {
151   return value_;
152 }
153
154 scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
155   scoped_ptr<TimingFunction> func;
156   if (timing_function())
157     func = timing_function()->Clone();
158   return FilterKeyframe::Create(Time(), Value(), func.Pass());
159 }
160
161 scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
162     Create() {
163   return make_scoped_ptr(new KeyframedColorAnimationCurve);
164 }
165
166 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
167
168 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
169
170 void KeyframedColorAnimationCurve::AddKeyframe(
171     scoped_ptr<ColorKeyframe> keyframe) {
172   InsertKeyframe(keyframe.Pass(), keyframes_);
173 }
174
175 double KeyframedColorAnimationCurve::Duration() const {
176   return keyframes_.back()->Time() - keyframes_.front()->Time();
177 }
178
179 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
180   scoped_ptr<KeyframedColorAnimationCurve> to_return(
181       KeyframedColorAnimationCurve::Create());
182   for (size_t i = 0; i < keyframes_.size(); ++i)
183     to_return->AddKeyframe(keyframes_[i]->Clone());
184   return to_return.PassAs<AnimationCurve>();
185 }
186
187 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
188   if (t <= keyframes_.front()->Time())
189     return keyframes_.front()->Value();
190
191   if (t >= keyframes_.back()->Time())
192     return keyframes_.back()->Value();
193
194   size_t i = 0;
195   for (; i < keyframes_.size() - 1; ++i) {
196     if (t < keyframes_[i + 1]->Time())
197       break;
198   }
199
200   float progress = GetProgress(t, i, keyframes_);
201
202   return gfx::Tween::ColorValueBetween(
203       progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
204 }
205
206 // KeyframedFloatAnimationCurve
207
208 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
209     Create() {
210   return make_scoped_ptr(new KeyframedFloatAnimationCurve);
211 }
212
213 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
214
215 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
216
217 void KeyframedFloatAnimationCurve::AddKeyframe(
218     scoped_ptr<FloatKeyframe> keyframe) {
219   InsertKeyframe(keyframe.Pass(), keyframes_);
220 }
221
222 double KeyframedFloatAnimationCurve::Duration() const {
223   return keyframes_.back()->Time() - keyframes_.front()->Time();
224 }
225
226 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
227   scoped_ptr<KeyframedFloatAnimationCurve> to_return(
228       KeyframedFloatAnimationCurve::Create());
229   for (size_t i = 0; i < keyframes_.size(); ++i)
230     to_return->AddKeyframe(keyframes_[i]->Clone());
231   return to_return.PassAs<AnimationCurve>();
232 }
233
234 float KeyframedFloatAnimationCurve::GetValue(double t) const {
235   if (t <= keyframes_.front()->Time())
236     return keyframes_.front()->Value();
237
238   if (t >= keyframes_.back()->Time())
239     return keyframes_.back()->Value();
240
241   size_t i = 0;
242   for (; i < keyframes_.size() - 1; ++i) {
243     if (t < keyframes_[i+1]->Time())
244       break;
245   }
246
247   float progress = GetProgress(t, i, keyframes_);
248
249   return keyframes_[i]->Value() +
250       (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
251 }
252
253 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
254     Create() {
255   return make_scoped_ptr(new KeyframedTransformAnimationCurve);
256 }
257
258 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
259
260 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
261
262 void KeyframedTransformAnimationCurve::AddKeyframe(
263     scoped_ptr<TransformKeyframe> keyframe) {
264   InsertKeyframe(keyframe.Pass(), keyframes_);
265 }
266
267 double KeyframedTransformAnimationCurve::Duration() const {
268   return keyframes_.back()->Time() - keyframes_.front()->Time();
269 }
270
271 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
272   scoped_ptr<KeyframedTransformAnimationCurve> to_return(
273       KeyframedTransformAnimationCurve::Create());
274   for (size_t i = 0; i < keyframes_.size(); ++i)
275     to_return->AddKeyframe(keyframes_[i]->Clone());
276   return to_return.PassAs<AnimationCurve>();
277 }
278
279 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
280 template<typename ValueType, typename KeyframeType>
281 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
282                                double t) {
283   size_t i = 0;
284   for (; i < keyframes->size() - 1; ++i) {
285     if (t < (*keyframes)[i+1]->Time())
286       break;
287   }
288
289   double progress = (t - (*keyframes)[i]->Time()) /
290                     ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
291
292   if ((*keyframes)[i]->timing_function())
293     progress = (*keyframes)[i]->timing_function()->GetValue(progress);
294
295   return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
296 }
297
298 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
299   if (t <= keyframes_.front()->Time())
300     return keyframes_.front()->Value().Apply();
301
302   if (t >= keyframes_.back()->Time())
303     return keyframes_.back()->Value().Apply();
304
305   return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
306 }
307
308 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
309     const gfx::BoxF& box,
310     gfx::BoxF* bounds) const {
311   DCHECK_GE(keyframes_.size(), 2ul);
312   *bounds = gfx::BoxF();
313   for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
314     gfx::BoxF bounds_for_step;
315     float min_progress = 0.0;
316     float max_progress = 1.0;
317     if (keyframes_[i]->timing_function())
318       keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
319     if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
320                                                       keyframes_[i]->Value(),
321                                                       min_progress,
322                                                       max_progress,
323                                                       &bounds_for_step))
324       return false;
325     bounds->Union(bounds_for_step);
326   }
327   return true;
328 }
329
330 bool KeyframedTransformAnimationCurve::AffectsScale() const {
331   for (size_t i = 0; i < keyframes_.size(); ++i) {
332     if (keyframes_[i]->Value().AffectsScale())
333       return true;
334   }
335   return false;
336 }
337
338 bool KeyframedTransformAnimationCurve::IsTranslation() const {
339   for (size_t i = 0; i < keyframes_.size(); ++i) {
340     if (!keyframes_[i]->Value().IsTranslation() &&
341         !keyframes_[i]->Value().IsIdentity())
342       return false;
343   }
344   return true;
345 }
346
347 bool KeyframedTransformAnimationCurve::MaximumTargetScale(
348     bool forward_direction,
349     float* max_scale) const {
350   DCHECK_GE(keyframes_.size(), 2ul);
351   *max_scale = 0.f;
352
353   // If |forward_direction| is true, then skip the first frame, otherwise
354   // skip the last frame, since that is the original position in the animation.
355   size_t start = 1;
356   size_t end = keyframes_.size();
357   if (!forward_direction) {
358     --start;
359     --end;
360   }
361
362   for (size_t i = start; i < end; ++i) {
363     gfx::Vector3dF target_scale_for_segment;
364     if (!keyframes_[i]->Value().ScaleComponent(&target_scale_for_segment))
365       return false;
366     float max_scale_for_segment =
367         fmax(std::abs(target_scale_for_segment.x()),
368              fmax(std::abs(target_scale_for_segment.y()),
369                   std::abs(target_scale_for_segment.z())));
370     *max_scale = fmax(*max_scale, max_scale_for_segment);
371   }
372   return true;
373 }
374
375 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
376     Create() {
377   return make_scoped_ptr(new KeyframedFilterAnimationCurve);
378 }
379
380 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
381
382 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
383
384 void KeyframedFilterAnimationCurve::AddKeyframe(
385     scoped_ptr<FilterKeyframe> keyframe) {
386   InsertKeyframe(keyframe.Pass(), keyframes_);
387 }
388
389 double KeyframedFilterAnimationCurve::Duration() const {
390   return keyframes_.back()->Time() - keyframes_.front()->Time();
391 }
392
393 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
394   scoped_ptr<KeyframedFilterAnimationCurve> to_return(
395       KeyframedFilterAnimationCurve::Create());
396   for (size_t i = 0; i < keyframes_.size(); ++i)
397     to_return->AddKeyframe(keyframes_[i]->Clone());
398   return to_return.PassAs<AnimationCurve>();
399 }
400
401 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
402   if (t <= keyframes_.front()->Time())
403     return keyframes_.front()->Value();
404
405   if (t >= keyframes_.back()->Time())
406     return keyframes_.back()->Value();
407
408   return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
409 }
410
411 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
412   for (size_t i = 0; i < keyframes_.size(); ++i) {
413     if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
414       return true;
415     }
416   }
417   return false;
418 }
419
420 }  // namespace cc