/* * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef KeyframeEffectModel_h #define KeyframeEffectModel_h #include "core/animation/AnimationEffect.h" #include "core/animation/AnimationNode.h" #include "core/animation/InterpolationEffect.h" #include "core/animation/StringKeyframe.h" #include "core/animation/animatable/AnimatableValueKeyframe.h" #include "platform/animation/TimingFunction.h" #include "platform/heap/Handle.h" #include "wtf/HashMap.h" #include "wtf/HashSet.h" #include "wtf/PassOwnPtr.h" #include "wtf/PassRefPtr.h" #include "wtf/RefCounted.h" #include "wtf/Vector.h" namespace blink { class Element; class KeyframeEffectModelTest; class KeyframeEffectModelBase : public AnimationEffect { public: // FIXME: Implement accumulation. typedef WillBeHeapVector > PropertySpecificKeyframeVector; class PropertySpecificKeyframeGroup : public NoBaseWillBeGarbageCollected { public: void appendKeyframe(PassOwnPtrWillBeRawPtr); const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; } void trace(Visitor*); private: void removeRedundantKeyframes(); void addSyntheticKeyframeIfRequired(const KeyframeEffectModelBase* context); PropertySpecificKeyframeVector m_keyframes; friend class KeyframeEffectModelBase; }; bool isReplaceOnly(); PropertySet properties() const; typedef WillBeHeapVector > KeyframeVector; const KeyframeVector& getFrames() const { return m_keyframes; } // FIXME: Implement setFrames() const PropertySpecificKeyframeVector& getPropertySpecificKeyframes(CSSPropertyID id) const { ensureKeyframeGroups(); return m_keyframeGroups->get(id)->keyframes(); } // AnimationEffect implementation. virtual PassOwnPtrWillBeRawPtr > > sample(int iteration, double fraction, double iterationDuration) const OVERRIDE; virtual bool isKeyframeEffectModel() const OVERRIDE { return true; } virtual bool isAnimatableValueKeyframeEffectModel() const { return false; } virtual bool isStringKeyframeEffectModel() const { return false; } virtual void trace(Visitor*) OVERRIDE; // FIXME: This is a hack used to resolve CSSValues to AnimatableValues while we have a valid handle on an element. // This should be removed once StringKeyframes no longer uses InterpolableAnimatableValues. void forceConversionsToAnimatableValues(Element* element) { ensureKeyframeGroups(); ensureInterpolationEffect(element); } protected: static KeyframeVector normalizedKeyframes(const KeyframeVector& keyframes); // Lazily computes the groups of property-specific keyframes. void ensureKeyframeGroups() const; void ensureInterpolationEffect(Element* = 0) const; KeyframeVector m_keyframes; // The spec describes filtering the normalized keyframes at sampling time // to get the 'property-specific keyframes'. For efficiency, we cache the // property-specific lists. typedef WillBeHeapHashMap > KeyframeGroupMap; mutable OwnPtrWillBeMember m_keyframeGroups; mutable RefPtrWillBeMember m_interpolationEffect; friend class KeyframeEffectModelTest; bool affects(CSSPropertyID property) { ensureKeyframeGroups(); return m_keyframeGroups->contains(property); } }; template class KeyframeEffectModel FINAL : public KeyframeEffectModelBase { public: typedef WillBeHeapVector > KeyframeVector; static PassRefPtrWillBeRawPtr > create(const KeyframeVector& keyframes) { return adoptRefWillBeNoop(new KeyframeEffectModel(keyframes)); } private: KeyframeEffectModel(const KeyframeVector& keyframes) { m_keyframes.appendVector(keyframes); } virtual bool isAnimatableValueKeyframeEffectModel() const { return false; } virtual bool isStringKeyframeEffectModel() const { return false; } }; typedef KeyframeEffectModelBase::KeyframeVector KeyframeVector; typedef KeyframeEffectModelBase::PropertySpecificKeyframeVector PropertySpecificKeyframeVector; typedef KeyframeEffectModel AnimatableValueKeyframeEffectModel; typedef AnimatableValueKeyframeEffectModel::KeyframeVector AnimatableValueKeyframeVector; typedef AnimatableValueKeyframeEffectModel::PropertySpecificKeyframeVector AnimatableValuePropertySpecificKeyframeVector; typedef KeyframeEffectModel StringKeyframeEffectModel; typedef StringKeyframeEffectModel::KeyframeVector StringKeyframeVector; typedef StringKeyframeEffectModel::PropertySpecificKeyframeVector StringPropertySpecificKeyframeVector; DEFINE_TYPE_CASTS(KeyframeEffectModelBase, AnimationEffect, value, value->isKeyframeEffectModel(), value.isKeyframeEffectModel()); DEFINE_TYPE_CASTS(AnimatableValueKeyframeEffectModel, KeyframeEffectModelBase, value, value->isAnimatableValueKeyframeEffectModel(), value.isAnimatableValueKeyframeEffectModel()); inline const AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(const AnimationEffect* base) { return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base)); } inline AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(AnimationEffect* base) { return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base)); } template <> inline bool KeyframeEffectModel::isAnimatableValueKeyframeEffectModel() const { return true; } template <> inline bool KeyframeEffectModel::isStringKeyframeEffectModel() const { return true; } } // namespace blink #endif // KeyframeEffectModel_h