1// Copyright (c) 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 "ui/compositor/transform_animation_curve_adapter.h"
6
7namespace ui {
8
9TransformAnimationCurveAdapter::TransformAnimationCurveAdapter(
10    gfx::Tween::Type tween_type,
11    gfx::Transform initial_value,
12    gfx::Transform target_value,
13    base::TimeDelta duration)
14    : tween_type_(tween_type),
15      initial_value_(initial_value),
16      target_value_(target_value),
17      duration_(duration) {
18  gfx::DecomposeTransform(&decomposed_initial_value_, initial_value_);
19  gfx::DecomposeTransform(&decomposed_target_value_, target_value_);
20}
21
22TransformAnimationCurveAdapter::~TransformAnimationCurveAdapter() {
23}
24
25double TransformAnimationCurveAdapter::Duration() const {
26  return duration_.InSecondsF();
27}
28
29scoped_ptr<cc::AnimationCurve> TransformAnimationCurveAdapter::Clone() const {
30  scoped_ptr<TransformAnimationCurveAdapter> to_return(
31      new TransformAnimationCurveAdapter(tween_type_,
32                                         initial_value_,
33                                         target_value_,
34                                         duration_));
35  return to_return.PassAs<cc::AnimationCurve>();
36}
37
38gfx::Transform TransformAnimationCurveAdapter::GetValue(
39    double t) const {
40  if (t >= duration_.InSecondsF())
41    return target_value_;
42  if (t <= 0.0)
43    return initial_value_;
44  double progress = t / duration_.InSecondsF();
45
46  gfx::DecomposedTransform to_return;
47  gfx::BlendDecomposedTransforms(&to_return,
48                                 decomposed_target_value_,
49                                 decomposed_initial_value_,
50                                 gfx::Tween::CalculateValue(tween_type_,
51                                                            progress));
52  return gfx::ComposeTransform(to_return);
53}
54
55bool TransformAnimationCurveAdapter::AnimatedBoundsForBox(
56    const gfx::BoxF& box,
57    gfx::BoxF* bounds) const {
58  // TODO(ajuma): Once cc::TransformOperation::BlendedBoundsForBox supports
59  // computing bounds for TransformOperationMatrix, use that to compute
60  // the bounds we need here.
61  return false;
62}
63
64bool TransformAnimationCurveAdapter::AffectsScale() const {
65  return !initial_value_.IsIdentityOrTranslation() ||
66         !target_value_.IsIdentityOrTranslation();
67}
68
69bool TransformAnimationCurveAdapter::IsTranslation() const {
70  return initial_value_.IsIdentityOrTranslation() &&
71         target_value_.IsIdentityOrTranslation();
72}
73
74bool TransformAnimationCurveAdapter::MaximumTargetScale(
75    bool forward_direction,
76    float* max_scale) const {
77  return false;
78}
79
80InverseTransformCurveAdapter::InverseTransformCurveAdapter(
81    TransformAnimationCurveAdapter base_curve,
82    gfx::Transform initial_value,
83    base::TimeDelta duration)
84    : base_curve_(base_curve),
85      initial_value_(initial_value),
86      duration_(duration) {
87  effective_initial_value_ = base_curve_.GetValue(0.0) * initial_value_;
88}
89
90InverseTransformCurveAdapter::~InverseTransformCurveAdapter() {
91}
92
93double InverseTransformCurveAdapter::Duration() const {
94  return duration_.InSeconds();
95}
96
97scoped_ptr<cc::AnimationCurve> InverseTransformCurveAdapter::Clone() const {
98  scoped_ptr<InverseTransformCurveAdapter> to_return(
99      new InverseTransformCurveAdapter(base_curve_,
100                                       initial_value_,
101                                       duration_));
102  return to_return.PassAs<cc::AnimationCurve>();
103}
104
105gfx::Transform InverseTransformCurveAdapter::GetValue(
106    double t) const {
107  if (t <= 0.0)
108    return initial_value_;
109
110  gfx::Transform base_transform = base_curve_.GetValue(t);
111  // Invert base
112  gfx::Transform to_return(gfx::Transform::kSkipInitialization);
113  bool is_invertible = base_transform.GetInverse(&to_return);
114  DCHECK(is_invertible);
115
116  to_return.PreconcatTransform(effective_initial_value_);
117  return to_return;
118}
119
120bool InverseTransformCurveAdapter::AnimatedBoundsForBox(
121    const gfx::BoxF& box,
122    gfx::BoxF* bounds) const {
123  // TODO(ajuma): Once cc::TransformOperation::BlendedBoundsForBox supports
124  // computing bounds for TransformOperationMatrix, use that to compute
125  // the bounds we need here.
126  return false;
127}
128
129bool InverseTransformCurveAdapter::AffectsScale() const {
130  return !initial_value_.IsIdentityOrTranslation() ||
131         base_curve_.AffectsScale();
132}
133
134bool InverseTransformCurveAdapter::IsTranslation() const {
135  return initial_value_.IsIdentityOrTranslation() &&
136         base_curve_.IsTranslation();
137}
138
139bool InverseTransformCurveAdapter::MaximumTargetScale(bool forward_direction,
140                                                      float* max_scale) const {
141  return false;
142}
143
144}  // namespace ui
145