1/* 2 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "core/svg/SVGAnimatedLength.h" 22 23#include "bindings/v8/ExceptionStatePlaceholder.h" 24#include "core/svg/SVGAnimateElement.h" 25#include "core/svg/SVGAnimatedNumber.h" 26 27namespace WebCore { 28 29SVGAnimatedLengthAnimator::SVGAnimatedLengthAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) 30 : SVGAnimatedTypeAnimator(AnimatedLength, animationElement, contextElement) 31 , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())) 32{ 33} 34 35static inline SVGLength& sharedSVGLength(SVGLengthMode mode, const String& valueAsString) 36{ 37 DEFINE_STATIC_LOCAL(SVGLength, sharedLength, ()); 38 sharedLength.setValueAsString(valueAsString, mode, ASSERT_NO_EXCEPTION); 39 return sharedLength; 40} 41 42PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string) 43{ 44 return SVGAnimatedType::createLength(new SVGLength(m_lengthMode, string)); 45} 46 47PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) 48{ 49 return SVGAnimatedType::createLength(constructFromBaseValue<SVGAnimatedLength>(animatedTypes)); 50} 51 52void SVGAnimatedLengthAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) 53{ 54 stopAnimValAnimationForType<SVGAnimatedLength>(animatedTypes); 55} 56 57void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) 58{ 59 resetFromBaseValue<SVGAnimatedLength>(animatedTypes, type, &SVGAnimatedType::length); 60} 61 62void SVGAnimatedLengthAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes) 63{ 64 animValWillChangeForType<SVGAnimatedLength>(animatedTypes); 65} 66 67void SVGAnimatedLengthAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes) 68{ 69 animValDidChangeForType<SVGAnimatedLength>(animatedTypes); 70} 71 72void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to) 73{ 74 ASSERT(from->type() == AnimatedLength); 75 ASSERT(from->type() == to->type()); 76 77 SVGLengthContext lengthContext(m_contextElement); 78 const SVGLength& fromLength = from->length(); 79 SVGLength& toLength = to->length(); 80 81 toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION); 82} 83 84static SVGLength parseLengthFromString(SVGAnimationElement* animationElement, const String& string) 85{ 86 return sharedSVGLength(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()), string); 87} 88 89void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) 90{ 91 ASSERT(m_animationElement); 92 ASSERT(m_contextElement); 93 94 SVGLength fromSVGLength = m_animationElement->animationMode() == ToAnimation ? animated->length() : from->length(); 95 SVGLength toSVGLength = to->length(); 96 const SVGLength& toAtEndOfDurationSVGLength = toAtEndOfDuration->length(); 97 SVGLength& animatedSVGLength = animated->length(); 98 99 // Apply CSS inheritance rules. 100 m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement); 101 m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement); 102 103 SVGLengthContext lengthContext(m_contextElement); 104 float animatedNumber = animatedSVGLength.value(lengthContext); 105 SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType(); 106 m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext), toAtEndOfDurationSVGLength.value(lengthContext), animatedNumber); 107 108 animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION); 109} 110 111float SVGAnimatedLengthAnimator::calculateDistance(const String& fromString, const String& toString) 112{ 113 ASSERT(m_animationElement); 114 ASSERT(m_contextElement); 115 SVGLengthMode lengthMode = SVGLength::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName()); 116 SVGLength from = SVGLength(lengthMode, fromString); 117 SVGLength to = SVGLength(lengthMode, toString); 118 SVGLengthContext lengthContext(m_contextElement); 119 return fabsf(to.value(lengthContext) - from.value(lengthContext)); 120} 121 122} 123