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