summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authoravallee@chromium.org <avallee@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-24 22:51:36 +0000
committeravallee@chromium.org <avallee@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-24 22:51:36 +0000
commit12076fa6270fda6ea535da61cafe7116ec2e6f00 (patch)
tree4cda7c226d5fbba708df61cdb3c7c517a71f8ee9 /cc
parent565f6193e85668f26de953516dbd8a341ae2b457 (diff)
downloadchromium_src-12076fa6270fda6ea535da61cafe7116ec2e6f00.zip
chromium_src-12076fa6270fda6ea535da61cafe7116ec2e6f00.tar.gz
chromium_src-12076fa6270fda6ea535da61cafe7116ec2e6f00.tar.bz2
Add Color animation curves.
Implement animation curves for colors. This is the first step towards accelerating background-color animations. + Add ColorValueBetween to gfx::Tween. + Add test/color_utils which gives EXPECT_COLOR_EQ to check SkColors and print in a sane format. ~ Fixed discrepancy between two methods of interpolating ints. ~ Factored out GetProgress into template function to simplify code in the implementations of GetValue(double), there was a lot of duplication there. TESTED: Added tests for the new KeyframedColorAnimations and AnimatedColor classes. Added tests to tweening. R=ajuma BUG=290234 Review URL: https://codereview.chromium.org/25901002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@230856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/animation/animation.cc3
-rw-r--r--cc/animation/animation.h1
-rw-r--r--cc/animation/animation_curve.cc7
-rw-r--r--cc/animation/animation_curve.h14
-rw-r--r--cc/animation/keyframed_animation_curve.cc91
-rw-r--r--cc/animation/keyframed_animation_curve.h46
-rw-r--r--cc/animation/keyframed_animation_curve_unittest.cc94
-rw-r--r--cc/animation/layer_animation_controller.cc7
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/output/filter_operation.cc73
-rw-r--r--cc/output/filter_operations_unittest.cc5
11 files changed, 277 insertions, 65 deletions
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 6b45917..6b5966b 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -33,7 +33,8 @@ COMPILE_ASSERT(static_cast<int>(cc::Animation::RunStateEnumSize) ==
static const char* const s_targetPropertyNames[] = {
"Transform",
"Opacity",
- "Filter"
+ "Filter",
+ "BackgroundColor"
};
COMPILE_ASSERT(static_cast<int>(cc::Animation::TargetPropertyEnumSize) ==
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index 9946298..f640318 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -47,6 +47,7 @@ class CC_EXPORT Animation {
Transform = 0,
Opacity,
Filter,
+ BackgroundColor,
// This sentinel must be last.
TargetPropertyEnumSize
};
diff --git a/cc/animation/animation_curve.cc b/cc/animation/animation_curve.cc
index cf04da7..65c21db 100644
--- a/cc/animation/animation_curve.cc
+++ b/cc/animation/animation_curve.cc
@@ -8,6 +8,13 @@
namespace cc {
+const ColorAnimationCurve* AnimationCurve::ToColorAnimationCurve() const {
+ DCHECK(Type() == AnimationCurve::Color);
+ return static_cast<const ColorAnimationCurve*>(this);
+}
+
+AnimationCurve::CurveType ColorAnimationCurve::Type() const { return Color; }
+
const FloatAnimationCurve* AnimationCurve::ToFloatAnimationCurve() const {
DCHECK(Type() == AnimationCurve::Float);
return static_cast<const FloatAnimationCurve*>(this);
diff --git a/cc/animation/animation_curve.h b/cc/animation/animation_curve.h
index f4cdb10..f84bb1a 100644
--- a/cc/animation/animation_curve.h
+++ b/cc/animation/animation_curve.h
@@ -16,6 +16,7 @@ class BoxF;
namespace cc {
+class ColorAnimationCurve;
class FilterAnimationCurve;
class FloatAnimationCurve;
class TransformAnimationCurve;
@@ -24,7 +25,7 @@ class TransformOperations;
// An animation curve is a function that returns a value given a time.
class CC_EXPORT AnimationCurve {
public:
- enum CurveType { Float, Transform, Filter };
+ enum CurveType { Color, Float, Transform, Filter };
virtual ~AnimationCurve() {}
@@ -32,11 +33,22 @@ class CC_EXPORT AnimationCurve {
virtual CurveType Type() const = 0;
virtual scoped_ptr<AnimationCurve> Clone() const = 0;
+ const ColorAnimationCurve* ToColorAnimationCurve() const;
const FloatAnimationCurve* ToFloatAnimationCurve() const;
const TransformAnimationCurve* ToTransformAnimationCurve() const;
const FilterAnimationCurve* ToFilterAnimationCurve() const;
};
+class CC_EXPORT ColorAnimationCurve : public AnimationCurve {
+ public:
+ virtual ~ColorAnimationCurve() {}
+
+ virtual SkColor GetValue(double t) const = 0;
+
+ // Partial Animation implementation.
+ virtual CurveType Type() const OVERRIDE;
+};
+
class CC_EXPORT FloatAnimationCurve : public AnimationCurve {
public:
virtual ~FloatAnimationCurve() {}
diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc
index 14dfd9c..d855dec 100644
--- a/cc/animation/keyframed_animation_curve.cc
+++ b/cc/animation/keyframed_animation_curve.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/animation/keyframed_animation_curve.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/box_f.h"
namespace cc {
@@ -26,6 +27,17 @@ void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
keyframes.push_back(keyframe.Pass());
}
+template <class Keyframes>
+float GetProgress(double t, size_t i, const Keyframes& keyframes) {
+ float progress =
+ static_cast<float>((t - keyframes[i]->Time()) /
+ (keyframes[i + 1]->Time() - keyframes[i]->Time()));
+
+ if (keyframes[i]->timing_function())
+ progress = keyframes[i]->timing_function()->GetValue(progress);
+ return progress;
+}
+
scoped_ptr<TimingFunction> CloneTimingFunction(
const TimingFunction* timing_function) {
DCHECK(timing_function);
@@ -46,6 +58,31 @@ double Keyframe::Time() const {
return time_;
}
+scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
+ double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function) {
+ return make_scoped_ptr(
+ new ColorKeyframe(time, value, timing_function.Pass()));
+}
+
+ColorKeyframe::ColorKeyframe(double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function)
+ : Keyframe(time, timing_function.Pass()),
+ value_(value) {}
+
+ColorKeyframe::~ColorKeyframe() {}
+
+SkColor ColorKeyframe::Value() const { return value_; }
+
+scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
+ scoped_ptr<TimingFunction> func;
+ if (timing_function())
+ func = CloneTimingFunction(timing_function());
+ return ColorKeyframe::Create(Time(), Value(), func.Pass());
+}
+
scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
double time,
float value,
@@ -127,6 +164,53 @@ scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
return FilterKeyframe::Create(Time(), Value(), func.Pass());
}
+scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
+ Create() {
+ return make_scoped_ptr(new KeyframedColorAnimationCurve);
+}
+
+KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
+
+KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
+
+void KeyframedColorAnimationCurve::AddKeyframe(
+ scoped_ptr<ColorKeyframe> keyframe) {
+ InsertKeyframe(keyframe.Pass(), keyframes_);
+}
+
+double KeyframedColorAnimationCurve::Duration() const {
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
+}
+
+scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
+ scoped_ptr<KeyframedColorAnimationCurve> to_return(
+ KeyframedColorAnimationCurve::Create());
+ for (size_t i = 0; i < keyframes_.size(); ++i)
+ to_return->AddKeyframe(keyframes_[i]->Clone());
+ return to_return.PassAs<AnimationCurve>();
+}
+
+SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
+ if (t <= keyframes_.front()->Time())
+ return keyframes_.front()->Value();
+
+ if (t >= keyframes_.back()->Time())
+ return keyframes_.back()->Value();
+
+ size_t i = 0;
+ for (; i < keyframes_.size() - 1; ++i) {
+ if (t < keyframes_[i + 1]->Time())
+ break;
+ }
+
+ float progress = GetProgress(t, i, keyframes_);
+
+ return gfx::Tween::ColorValueBetween(
+ progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
+}
+
+// KeyframedFloatAnimationCurve
+
scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
Create() {
return make_scoped_ptr(new KeyframedFloatAnimationCurve);
@@ -166,12 +250,7 @@ float KeyframedFloatAnimationCurve::GetValue(double t) const {
break;
}
- float progress =
- static_cast<float>((t - keyframes_[i]->Time()) /
- (keyframes_[i+1]->Time() - keyframes_[i]->Time()));
-
- if (keyframes_[i]->timing_function())
- progress = keyframes_[i]->timing_function()->GetValue(progress);
+ float progress = GetProgress(t, i, keyframes_);
return keyframes_[i]->Value() +
(keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
diff --git a/cc/animation/keyframed_animation_curve.h b/cc/animation/keyframed_animation_curve.h
index 5892dc7..4b5ac3b 100644
--- a/cc/animation/keyframed_animation_curve.h
+++ b/cc/animation/keyframed_animation_curve.h
@@ -31,6 +31,26 @@ class CC_EXPORT Keyframe {
DISALLOW_COPY_AND_ASSIGN(Keyframe);
};
+class CC_EXPORT ColorKeyframe : public Keyframe {
+ public:
+ static scoped_ptr<ColorKeyframe> Create(
+ double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function);
+ virtual ~ColorKeyframe();
+
+ SkColor Value() const;
+
+ scoped_ptr<ColorKeyframe> Clone() const;
+
+ private:
+ ColorKeyframe(double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function);
+
+ SkColor value_;
+};
+
class CC_EXPORT FloatKeyframe : public Keyframe {
public:
static scoped_ptr<FloatKeyframe> Create(
@@ -93,6 +113,32 @@ class CC_EXPORT FilterKeyframe : public Keyframe {
FilterOperations value_;
};
+class CC_EXPORT KeyframedColorAnimationCurve : public ColorAnimationCurve {
+ public:
+ // It is required that the keyframes be sorted by time.
+ static scoped_ptr<KeyframedColorAnimationCurve> Create();
+
+ virtual ~KeyframedColorAnimationCurve();
+
+ void AddKeyframe(scoped_ptr<ColorKeyframe> keyframe);
+
+ // AnimationCurve implementation
+ virtual double Duration() const OVERRIDE;
+ virtual scoped_ptr<AnimationCurve> Clone() const OVERRIDE;
+
+ // BackgrounColorAnimationCurve implementation
+ virtual SkColor GetValue(double t) const OVERRIDE;
+
+ private:
+ KeyframedColorAnimationCurve();
+
+ // Always sorted in order of increasing time. No two keyframes have the
+ // same time.
+ ScopedPtrVector<ColorKeyframe> keyframes_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyframedColorAnimationCurve);
+};
+
class CC_EXPORT KeyframedFloatAnimationCurve : public FloatAnimationCurve {
public:
// It is required that the keyframes be sorted by time.
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc
index 7eb3b1c..63e9866 100644
--- a/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/cc/animation/keyframed_animation_curve_unittest.cc
@@ -7,7 +7,9 @@
#include "cc/animation/transform_operations.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/box_f.h"
+#include "ui/gfx/test/color_util.h"
namespace cc {
namespace {
@@ -22,6 +24,98 @@ void ExpectBrightness(double brightness, const FilterOperations& filter) {
EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
}
+// Tests that a color animation with one keyframe works as expected.
+TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) {
+ SkColor color = SkColorSetARGB(255, 255, 255, 255);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(2.f));
+}
+
+// Tests that a color animation with two keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
+ SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
+}
+
+// Tests that a color animation with three keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
+ SkColor color_c = SkColorSetARGB(255, 0, 0, 255);
+ SkColor color_midpoint1 =
+ gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
+ SkColor color_midpoint2 =
+ gfx::Tween::ColorValueBetween(0.5, color_b, color_c);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(2.0, color_c, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint1, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint2, curve->GetValue(1.5f));
+ EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(3.f));
+}
+
+// Tests that a colro animation with multiple keys at a given time works sanely.
+TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 64, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 192, 0, 0);
+
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(2.0, color_b, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.5f));
+
+ SkColor value = curve->GetValue(1.0f);
+ EXPECT_EQ(255u, SkColorGetA(value));
+ int red_value = SkColorGetR(value);
+ EXPECT_LE(64, red_value);
+ EXPECT_GE(192, red_value);
+
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(3.f));
+}
+
// Tests that a float animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index daebc44..f720229 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -187,6 +187,8 @@ void LayerAnimationController::AccumulatePropertyUpdates(
break;
}
+ case Animation::BackgroundColor: { break; }
+
case Animation::TargetPropertyEnumSize:
NOTREACHED();
}
@@ -710,6 +712,11 @@ void LayerAnimationController::TickAnimations(double monotonic_time) {
break;
}
+ case Animation::BackgroundColor: {
+ // Not yet implemented.
+ break;
+ }
+
// Do nothing for sentinel value.
case Animation::TargetPropertyEnumSize:
NOTREACHED();
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 226ab24..c0f4023 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -326,6 +326,7 @@
'dependencies': [
'../skia/skia.gyp:skia',
'../ui/gfx/gfx.gyp:gfx',
+ '../ui/ui.gyp:ui_test_support',
],
},
],
diff --git a/cc/output/filter_operation.cc b/cc/output/filter_operation.cc
index 672dba7..50f111f 100644
--- a/cc/output/filter_operation.cc
+++ b/cc/output/filter_operation.cc
@@ -8,6 +8,7 @@
#include "cc/base/math_util.h"
#include "cc/output/filter_operation.h"
#include "third_party/skia/include/core/SkMath.h"
+#include "ui/gfx/animation/tween.h"
namespace cc {
@@ -97,52 +98,6 @@ FilterOperation::FilterOperation(const FilterOperation& other)
FilterOperation::~FilterOperation() {
}
-// TODO(ajuma): Define a version of gfx::Tween::ValueBetween for floats, and use
-// that instead.
-static float BlendFloats(float from, float to, double progress) {
- return from * (1.0 - progress) + to * progress;
-}
-
-static int BlendInts(int from, int to, double progress) {
- return static_cast<int>(
- MathUtil::Round(from * (1.0 - progress) + to * progress));
-}
-
-static uint8_t BlendColorComponents(uint8_t from,
- uint8_t to,
- uint8_t from_alpha,
- uint8_t to_alpha,
- uint8_t blended_alpha,
- double progress) {
- // Since progress can be outside [0, 1], blending can produce a value outside
- // [0, 255].
- int blended_premultiplied = BlendInts(SkMulDiv255Round(from, from_alpha),
- SkMulDiv255Round(to, to_alpha),
- progress);
- int blended = static_cast<int>(
- MathUtil::Round(blended_premultiplied * 255.f / blended_alpha));
- return static_cast<uint8_t>(MathUtil::ClampToRange(blended, 0, 255));
-}
-
-static SkColor BlendSkColors(SkColor from, SkColor to, double progress) {
- int from_a = SkColorGetA(from);
- int to_a = SkColorGetA(to);
- int blended_a = BlendInts(from_a, to_a, progress);
- if (blended_a <= 0)
- return SkColorSetARGB(0, 0, 0, 0);
- blended_a = std::min(blended_a, 255);
-
- // TODO(ajuma): Use SkFourByteInterp once http://crbug.com/260369 is fixed.
- uint8_t blended_r = BlendColorComponents(
- SkColorGetR(from), SkColorGetR(to), from_a, to_a, blended_a, progress);
- uint8_t blended_g = BlendColorComponents(
- SkColorGetG(from), SkColorGetG(to), from_a, to_a, blended_a, progress);
- uint8_t blended_b = BlendColorComponents(
- SkColorGetB(from), SkColorGetB(to), from_a, to_a, blended_a, progress);
-
- return SkColorSetARGB(blended_a, blended_r, blended_g, blended_b);
-}
-
static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
switch (type) {
case FilterOperation::GRAYSCALE:
@@ -239,21 +194,25 @@ FilterOperation FilterOperation::Blend(const FilterOperation* from,
}
blended_filter.set_amount(ClampAmountForFilterType(
- BlendFloats(from_op.amount(), to_op.amount(), progress), to_op.type()));
+ gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
+ to_op.type()));
if (to_op.type() == FilterOperation::DROP_SHADOW) {
- gfx::Point blended_offset(BlendInts(from_op.drop_shadow_offset().x(),
- to_op.drop_shadow_offset().x(),
- progress),
- BlendInts(from_op.drop_shadow_offset().y(),
- to_op.drop_shadow_offset().y(),
- progress));
+ gfx::Point blended_offset(
+ gfx::Tween::LinearIntValueBetween(progress,
+ from_op.drop_shadow_offset().x(),
+ to_op.drop_shadow_offset().x()),
+ gfx::Tween::LinearIntValueBetween(progress,
+ from_op.drop_shadow_offset().y(),
+ to_op.drop_shadow_offset().y()));
blended_filter.set_drop_shadow_offset(blended_offset);
- blended_filter.set_drop_shadow_color(BlendSkColors(
- from_op.drop_shadow_color(), to_op.drop_shadow_color(), progress));
+ blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
+ progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
} else if (to_op.type() == FilterOperation::ZOOM) {
- blended_filter.set_zoom_inset(std::max(
- BlendInts(from_op.zoom_inset(), to_op.zoom_inset(), progress), 0));
+ blended_filter.set_zoom_inset(
+ std::max(gfx::Tween::LinearIntValueBetween(
+ from_op.zoom_inset(), to_op.zoom_inset(), progress),
+ 0));
}
return blended_filter;
diff --git a/cc/output/filter_operations_unittest.cc b/cc/output/filter_operations_unittest.cc
index e975ed5..7f439b9 100644
--- a/cc/output/filter_operations_unittest.cc
+++ b/cc/output/filter_operations_unittest.cc
@@ -412,6 +412,11 @@ TEST(FilterOperationsTest, BlendDropShadowFilters) {
gfx::Point(-2, -4), 0.f, SkColorSetARGB(0, 0, 0, 0));
EXPECT_EQ(expected, blended);
+ blended = FilterOperation::Blend(&from, &to, 0.25);
+ expected = FilterOperation::CreateDropShadowFilter(
+ gfx::Point(1, 1), 3.f, SkColorSetARGB(24, 32, 64, 128));
+ EXPECT_EQ(expected, blended);
+
blended = FilterOperation::Blend(&from, &to, 0.75);
expected = FilterOperation::CreateDropShadowFilter(
gfx::Point(2, 4), 5.f, SkColorSetARGB(42, 30, 61, 121));