1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef KeyframeAnimationEffect_h 32 #define KeyframeAnimationEffect_h 33 34 #include "core/animation/AnimatableValue.h" 35 #include "core/animation/AnimationEffect.h" 36 #include "wtf/HashMap.h" 37 #include "wtf/HashSet.h" 38 #include "wtf/PassOwnPtr.h" 39 #include "wtf/PassRefPtr.h" 40 #include "wtf/RefCounted.h" 41 #include "wtf/Vector.h" 42 43 namespace WebCore { 44 45 typedef HashSet<CSSPropertyID> PropertySet; 46 47 // Represents the keyframes set through the API. 48 class Keyframe : public RefCounted<Keyframe> { 49 public: 50 static PassRefPtr<Keyframe> create() 51 { 52 return adoptRef(new Keyframe); 53 } 54 static bool compareOffsets(const RefPtr<Keyframe>& a, const RefPtr<Keyframe>& b) 55 { 56 return a->offset() < b->offset(); 57 } 58 void setOffset(double offset) { m_offset = offset; } 59 double offset() const { return m_offset; } 60 void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; } 61 AnimationEffect::CompositeOperation composite() const { return m_composite; } 62 void setPropertyValue(CSSPropertyID, const AnimatableValue*); 63 const AnimatableValue* propertyValue(CSSPropertyID) const; 64 PropertySet properties() const; 65 private: 66 Keyframe(); 67 double m_offset; 68 AnimationEffect::CompositeOperation m_composite; 69 typedef HashMap<CSSPropertyID, RefPtr<AnimatableValue> > PropertyValueMap; 70 PropertyValueMap m_propertyValues; 71 }; 72 73 class KeyframeAnimationEffect : public AnimationEffect { 74 public: 75 typedef Vector<RefPtr<Keyframe> > KeyframeVector; 76 // FIXME: Implement accumulation. 77 static PassRefPtr<KeyframeAnimationEffect> create(const KeyframeVector& keyframes) 78 { 79 return adoptRef(new KeyframeAnimationEffect(keyframes)); 80 } 81 82 // AnimationEffect implementation. 83 virtual PassOwnPtr<CompositableValueMap> sample(int iteration, double fraction) const OVERRIDE; 84 85 // FIXME: Implement setFrames() 86 const KeyframeVector& getFrames() const { return m_keyframes; } 87 88 private: 89 class PropertySpecificKeyframe { 90 public: 91 PropertySpecificKeyframe(double offset, const AnimatableValue*, CompositeOperation); 92 double offset() const { return m_offset; } 93 const CompositableValue* value() const { return m_value.get(); } 94 PassOwnPtr<PropertySpecificKeyframe> cloneWithOffset(double offset) const; 95 private: 96 // Used by cloneWithOffset(). 97 PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue>); 98 double m_offset; 99 RefPtr<CompositableValue> m_value; 100 }; 101 102 class PropertySpecificKeyframeGroup { 103 public: 104 void appendKeyframe(PassOwnPtr<PropertySpecificKeyframe>); 105 void removeRedundantKeyframes(); 106 void addSyntheticKeyframeIfRequired(); 107 PassRefPtr<CompositableValue> sample(int iteration, double offset) const; 108 private: 109 typedef Vector<OwnPtr<PropertySpecificKeyframe> > PropertySpecificKeyframeVector; 110 PropertySpecificKeyframeVector m_keyframes; 111 }; 112 113 KeyframeAnimationEffect(const KeyframeVector& keyframes); 114 115 KeyframeVector normalizedKeyframes() const; 116 // Lazily computes the groups of property-specific keyframes. 117 void ensureKeyframeGroups(); 118 119 KeyframeVector m_keyframes; 120 // The spec describes filtering the normalized keyframes at sampling time 121 // to get the 'property-specific keyframes'. For efficiency, we cache the 122 // property-specific lists. 123 typedef HashMap<CSSPropertyID, OwnPtr<PropertySpecificKeyframeGroup> > KeyframeGroupMap; 124 OwnPtr<KeyframeGroupMap> m_keyframeGroups; 125 }; 126 127 } // namespace WebCore 128 129 #endif // KeyframeAnimationEffect_h 130