summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp367
1 files changed, 0 insertions, 367 deletions
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp b/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp
deleted file mode 100644
index dd6ffa3a832..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-
-#include "core/animation/TimedItem.h"
-#include "wtf/text/StringHash.h"
-
-namespace {
-
-using namespace WebCore;
-
-class ReplaceCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<ReplaceCompositableValue> create(const AnimatableValue* value)
- {
- return adoptRef(new ReplaceCompositableValue(value));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return false;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return PassRefPtr<AnimatableValue>(m_value);
- }
-private:
- ReplaceCompositableValue(const AnimatableValue* value)
- : m_value(const_cast<AnimatableValue*>(value))
- {
- }
- RefPtr<AnimatableValue> m_value;
-};
-
-class AddCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<AddCompositableValue> create(const AnimatableValue* value)
- {
- return adoptRef(new AddCompositableValue(value));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return true;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return AnimatableValue::add(underlyingValue, m_value.get());
- }
-private:
- AddCompositableValue(const AnimatableValue* value)
- : m_value(const_cast<AnimatableValue*>(value))
- {
- }
- RefPtr<AnimatableValue> m_value;
-};
-
-class BlendedCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<BlendedCompositableValue> create(const AnimationEffect::CompositableValue* before, const AnimationEffect::CompositableValue* after, double fraction)
- {
- return adoptRef(new BlendedCompositableValue(before, after, fraction));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return m_dependsOnUnderlyingValue;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return AnimatableValue::interpolate(m_before->compositeOnto(underlyingValue).get(), m_after->compositeOnto(underlyingValue).get(), m_fraction);
- }
-private:
- BlendedCompositableValue(const AnimationEffect::CompositableValue* before, const AnimationEffect::CompositableValue* after, double fraction)
- : m_before(const_cast<AnimationEffect::CompositableValue*>(before))
- , m_after(const_cast<AnimationEffect::CompositableValue*>(after))
- , m_fraction(fraction)
- , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after->dependsOnUnderlyingValue())
- { }
- RefPtr<AnimationEffect::CompositableValue> m_before;
- RefPtr<AnimationEffect::CompositableValue> m_after;
- double m_fraction;
- bool m_dependsOnUnderlyingValue;
-};
-
-} // namespace
-
-
-namespace WebCore {
-
-Keyframe::Keyframe()
- : m_offset(nullValue())
- , m_composite(AnimationEffect::CompositeReplace)
-{ }
-
-Keyframe::Keyframe(const Keyframe& copyFrom)
- : m_offset(copyFrom.m_offset)
- , m_composite(copyFrom.m_composite)
-{
- for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
- setPropertyValue(iter->key, iter->value.get());
-}
-
-void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* value)
-{
- m_propertyValues.add(property, const_cast<AnimatableValue*>(value));
-}
-
-void Keyframe::clearPropertyValue(CSSPropertyID property)
-{
- m_propertyValues.remove(property);
-}
-
-const AnimatableValue* Keyframe::propertyValue(CSSPropertyID property) const
-{
- ASSERT(m_propertyValues.contains(property));
- return m_propertyValues.get(property);
-}
-
-PropertySet Keyframe::properties() const
-{
- // This is not used in time-critical code, so we probably don't need to
- // worry about caching this result.
- PropertySet properties;
- for (PropertyValueMap::const_iterator iter = m_propertyValues.begin(); iter != m_propertyValues.end(); ++iter)
- properties.add(*iter.keys());
- return properties;
-}
-
-PassRefPtr<Keyframe> Keyframe::cloneWithOffset(double offset) const
-{
- RefPtr<Keyframe> theClone = clone();
- theClone->setOffset(offset);
- return theClone.release();
-}
-
-KeyframeAnimationEffect::KeyframeAnimationEffect(const KeyframeVector& keyframes)
- : m_keyframes(keyframes)
-{
-}
-
-PropertySet KeyframeAnimationEffect::properties() const
-{
- PropertySet result;
- const KeyframeVector& frames = getFrames();
- if (!frames.size()) {
- return result;
- }
- result = frames[0]->properties();
- for (size_t i = 1; i < frames.size(); i++) {
- PropertySet extras = frames[i]->properties();
- for (PropertySet::const_iterator it = extras.begin(); it != extras.end(); ++it) {
- result.add(*it);
- }
- }
- return result;
-}
-
-PassOwnPtr<AnimationEffect::CompositableValueList> KeyframeAnimationEffect::sample(int iteration, double fraction) const
-{
- ASSERT(iteration >= 0);
- ASSERT(!isNull(fraction));
- const_cast<KeyframeAnimationEffect*>(this)->ensureKeyframeGroups();
- OwnPtr<CompositableValueList> map = adoptPtr(new CompositableValueList());
- for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter)
- map->append(std::make_pair(iter->key, iter->value->sample(iteration, fraction)));
- return map.release();
-}
-
-KeyframeAnimationEffect::KeyframeVector KeyframeAnimationEffect::normalizedKeyframes() const
-{
- KeyframeVector keyframes = m_keyframes;
-
- // Set offsets at 0.0 and 1.0 at ends if unset.
- if (keyframes.size() >= 2) {
- Keyframe* firstKeyframe = keyframes.first().get();
- if (isNull(firstKeyframe->offset()))
- firstKeyframe->setOffset(0.0);
- }
- if (keyframes.size() >= 1) {
- Keyframe* lastKeyframe = keyframes.last().get();
- if (lastKeyframe && isNull(lastKeyframe->offset()))
- lastKeyframe->setOffset(1.0);
- }
-
- // FIXME: Distribute offsets where missing.
- for (KeyframeVector::iterator iter = keyframes.begin(); iter != keyframes.end(); ++iter)
- ASSERT(!isNull((*iter)->offset()));
-
- // Sort by offset.
- std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
- return keyframes;
-}
-
-void KeyframeAnimationEffect::ensureKeyframeGroups() const
-{
- if (m_keyframeGroups)
- return;
-
- m_keyframeGroups = adoptPtr(new KeyframeGroupMap);
- const KeyframeVector& keyframes = normalizedKeyframes();
- for (KeyframeVector::const_iterator keyframeIter = keyframes.begin(); keyframeIter != keyframes.end(); ++keyframeIter) {
- const Keyframe* keyframe = keyframeIter->get();
- PropertySet keyframeProperties = keyframe->properties();
- for (PropertySet::const_iterator propertyIter = keyframeProperties.begin(); propertyIter != keyframeProperties.end(); ++propertyIter) {
- CSSPropertyID property = *propertyIter;
- KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(property);
- if (groupIter == m_keyframeGroups->end()) {
- KeyframeGroupMap::AddResult result = m_keyframeGroups->add(property, adoptPtr(new PropertySpecificKeyframeGroup));
- ASSERT(result.isNewEntry);
- groupIter = result.iterator;
- }
- groupIter->value->appendKeyframe(adoptPtr(
- new PropertySpecificKeyframe(keyframe->offset(), keyframe->propertyValue(property), keyframe->composite())));
- }
- }
-
- // Add synthetic keyframes.
- for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
- iter->value->addSyntheticKeyframeIfRequired();
- iter->value->removeRedundantKeyframes();
- }
-}
-
-
-KeyframeAnimationEffect::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, const AnimatableValue* value, CompositeOperation composite)
- : m_offset(offset)
- , m_value(composite == AnimationEffect::CompositeReplace ?
- static_cast<PassRefPtr<CompositableValue> >(ReplaceCompositableValue::create(value)) :
- static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create(value)))
-{
-}
-
-KeyframeAnimationEffect::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue> value)
- : m_offset(offset)
- , m_value(value)
-{
- ASSERT(!isNull(m_offset));
-}
-
-PassOwnPtr<KeyframeAnimationEffect::PropertySpecificKeyframe> KeyframeAnimationEffect::PropertySpecificKeyframe::cloneWithOffset(double offset) const
-{
- return adoptPtr(new PropertySpecificKeyframe(offset, PassRefPtr<CompositableValue>(m_value)));
-}
-
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnPtr<PropertySpecificKeyframe> keyframe)
-{
- ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->offset());
- m_keyframes.append(keyframe);
-}
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::removeRedundantKeyframes()
-{
- // As an optimization, removes keyframes in the following categories, as
- // they will never be used by sample().
- // - End keyframes with the same offset as their neighbor
- // - Interior keyframes with the same offset as both their neighbors
- // Note that synthetic keyframes must be added before this method is
- // called.
- ASSERT(m_keyframes.size() >= 2);
- for (int i = m_keyframes.size() - 1; i >= 0; --i) {
- double offset = m_keyframes[i]->offset();
- bool hasSameOffsetAsPreviousNeighbor = !i || m_keyframes[i - 1]->offset() == offset;
- bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.size() - 1) || m_keyframes[i + 1]->offset() == offset;
- if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor)
- m_keyframes.remove(i);
- }
- ASSERT(m_keyframes.size() >= 2);
-}
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfRequired()
-{
- ASSERT(!m_keyframes.isEmpty());
- double offset = m_keyframes.first()->offset();
- bool allOffsetsEqual = true;
- for (PropertySpecificKeyframeVector::const_iterator iter = m_keyframes.begin() + 1; iter != m_keyframes.end(); ++iter) {
- if ((*iter)->offset() != offset) {
- allOffsetsEqual = false;
- break;
- }
- }
- if (!allOffsetsEqual)
- return;
-
- if (!offset)
- appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
- else
- m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, AnimatableValue::neutralValue(), CompositeAdd)));
-}
-
-PassRefPtr<AnimationEffect::CompositableValue> KeyframeAnimationEffect::PropertySpecificKeyframeGroup::sample(int iteration, double offset) const
-{
- // FIXME: Implement accumulation.
- ASSERT_UNUSED(iteration, iteration >= 0);
- ASSERT(!isNull(offset));
-
- // Bail if offset is null, as this can lead to buffer overflow below.
- if (isNull(offset))
- return const_cast<CompositableValue*>(m_keyframes.first()->value());
-
- double minimumOffset = m_keyframes.first()->offset();
- double maximumOffset = m_keyframes.last()->offset();
- ASSERT(minimumOffset != maximumOffset);
-
- PropertySpecificKeyframeVector::const_iterator before;
- PropertySpecificKeyframeVector::const_iterator after;
-
- // Note that this algorithm is simpler than that in the spec because we
- // have removed keyframes with equal offsets in
- // removeRedundantKeyframes().
- if (offset < minimumOffset) {
- before = m_keyframes.begin();
- after = before + 1;
- ASSERT((*before)->offset() > offset);
- ASSERT((*after)->offset() > offset);
- } else if (offset >= maximumOffset) {
- after = m_keyframes.end() - 1;
- before = after - 1;
- ASSERT((*before)->offset() < offset);
- ASSERT((*after)->offset() <= offset);
- } else {
- // FIXME: This is inefficient for large numbers of keyframes. Consider
- // using binary search.
- after = m_keyframes.begin();
- while ((*after)->offset() <= offset)
- ++after;
- before = after - 1;
- ASSERT((*before)->offset() <= offset);
- ASSERT((*after)->offset() > offset);
- }
-
- if ((*before)->offset() == offset)
- return const_cast<CompositableValue*>((*before)->value());
- if ((*after)->offset() == offset)
- return const_cast<CompositableValue*>((*after)->value());
- return BlendedCompositableValue::create((*before)->value(), (*after)->value(),
- (offset - (*before)->offset()) / ((*after)->offset() - (*before)->offset()));
-}
-
-} // namespace