| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_VALUE_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_VALUE_H_ |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/memory/ptr_util.h" |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/wtf/casting.h" |
| #include "third_party/blink/renderer/platform/wtf/vector.h" |
| |
| namespace blink { |
| |
| // Represents the components of a PropertySpecificKeyframe's value that change |
| // smoothly as it interpolates to an adjacent value. |
| class CORE_EXPORT InterpolableValue { |
| USING_FAST_MALLOC(InterpolableValue); |
| |
| public: |
| virtual ~InterpolableValue() = default; |
| |
| // Interpolates from |this| InterpolableValue towards |to| at the given |
| // |progress|, placing the output in |result|. That is: |
| // |
| // result = this * (1 - progress) + to * progress |
| // |
| // Callers must make sure that |this|, |to|, and |result| are all of the same |
| // concrete subclass. |
| virtual void Interpolate(const InterpolableValue& to, |
| const double progress, |
| InterpolableValue& result) const = 0; |
| |
| virtual bool IsNumber() const { return false; } |
| virtual bool IsBool() const { return false; } |
| virtual bool IsList() const { return false; } |
| virtual bool IsLength() const { return false; } |
| virtual bool IsAspectRatio() const { return false; } |
| virtual bool IsShadow() const { return false; } |
| virtual bool IsFilter() const { return false; } |
| virtual bool IsTransformList() const { return false; } |
| |
| // TODO(alancutter): Remove Equals(). |
| virtual bool Equals(const InterpolableValue&) const = 0; |
| virtual void Scale(double scale) = 0; |
| virtual void Add(const InterpolableValue& other) = 0; |
| // The default implementation should be sufficient for most types, but |
| // subclasses can override this to be more efficient if they chose. |
| virtual void ScaleAndAdd(double scale, const InterpolableValue& other) { |
| Scale(scale); |
| Add(other); |
| } |
| virtual void AssertCanInterpolateWith( |
| const InterpolableValue& other) const = 0; |
| |
| // Clone this value, optionally zeroing out the components at the same time. |
| // These are not virtual to allow for covariant return types; see |
| // documentation on RawClone/RawCloneAndZero. |
| std::unique_ptr<InterpolableValue> Clone() const { |
| return std::unique_ptr<InterpolableValue>(RawClone()); |
| } |
| std::unique_ptr<InterpolableValue> CloneAndZero() const { |
| return std::unique_ptr<InterpolableValue>(RawCloneAndZero()); |
| } |
| |
| private: |
| // Helper methods to allow covariant Clone/CloneAndZero methods. Concrete |
| // subclasses should not expose these methods publically, but instead should |
| // declare their own version of Clone/CloneAndZero with a concrete return type |
| // if it is useful for their clients. |
| virtual InterpolableValue* RawClone() const = 0; |
| virtual InterpolableValue* RawCloneAndZero() const = 0; |
| }; |
| |
| class CORE_EXPORT InterpolableNumber final : public InterpolableValue { |
| public: |
| explicit InterpolableNumber(double value) : value_(value) {} |
| |
| double Value() const { return value_; } |
| void Set(double value) { value_ = value; } |
| |
| // InterpolableValue |
| void Interpolate(const InterpolableValue& to, |
| const double progress, |
| InterpolableValue& result) const final; |
| bool IsNumber() const final { return true; } |
| bool Equals(const InterpolableValue& other) const final; |
| void Scale(double scale) final; |
| void Add(const InterpolableValue& other) final; |
| void AssertCanInterpolateWith(const InterpolableValue& other) const final; |
| |
| private: |
| InterpolableNumber* RawClone() const final { |
| return new InterpolableNumber(value_); |
| } |
| InterpolableNumber* RawCloneAndZero() const final { |
| return new InterpolableNumber(0); |
| } |
| |
| double value_; |
| }; |
| |
| class CORE_EXPORT InterpolableList : public InterpolableValue { |
| public: |
| // Explicitly delete operator= because MSVC automatically generate |
| // copy constructors and operator= for dll-exported classes. |
| // Since InterpolableList is not copyable, automatically generated |
| // operator= causes MSVC compiler error. |
| // However, we cannot use DISALLOW_COPY_AND_ASSIGN because InterpolableList |
| // has its own copy constructor. So just delete operator= here. |
| InterpolableList& operator=(const InterpolableList&) = delete; |
| |
| explicit InterpolableList(wtf_size_t size) : values_(size) {} |
| |
| InterpolableList(const InterpolableList& other) : values_(other.length()) { |
| for (wtf_size_t i = 0; i < length(); i++) |
| Set(i, other.values_[i]->Clone()); |
| } |
| |
| const InterpolableValue* Get(wtf_size_t position) const { |
| return values_[position].get(); |
| } |
| std::unique_ptr<InterpolableValue>& GetMutable(wtf_size_t position) { |
| return values_[position]; |
| } |
| wtf_size_t length() const { return values_.size(); } |
| void Set(wtf_size_t position, std::unique_ptr<InterpolableValue> value) { |
| values_[position] = std::move(value); |
| } |
| |
| // InterpolableValue |
| void Interpolate(const InterpolableValue& to, |
| const double progress, |
| InterpolableValue& result) const final; |
| bool IsList() const final { return true; } |
| bool Equals(const InterpolableValue& other) const final; |
| void Scale(double scale) final; |
| void Add(const InterpolableValue& other) final; |
| // We override this to avoid two passes on the list from the base version. |
| void ScaleAndAdd(double scale, const InterpolableValue& other) final; |
| void AssertCanInterpolateWith(const InterpolableValue& other) const final; |
| |
| private: |
| InterpolableList* RawClone() const final { |
| return new InterpolableList(*this); |
| } |
| InterpolableList* RawCloneAndZero() const final; |
| |
| Vector<std::unique_ptr<InterpolableValue>> values_; |
| }; |
| |
| template <> |
| struct DowncastTraits<InterpolableNumber> { |
| static bool AllowFrom(const InterpolableValue& value) { |
| return value.IsNumber(); |
| } |
| }; |
| template <> |
| struct DowncastTraits<InterpolableList> { |
| static bool AllowFrom(const InterpolableValue& value) { |
| return value.IsList(); |
| } |
| }; |
| |
| } // namespace blink |
| |
| #endif |