This source file includes following definitions.
- m_contextElement
- createPropertyForAnimation
- constructFromString
- calculateFromAndToValues
- calculateFromAndByValues
- invokeMethodOnAllTargetProperties
- setAnimatedValueOnAllTargetProperties
- resetAnimation
- startAnimValAnimation
- stopAnimValAnimation
- resetAnimValToBaseVal
- calculateAnimatedValue
- calculateDistance
#include "config.h"
#include "core/svg/SVGAnimatedTypeAnimator.h"
#include "core/svg/SVGAnimateTransformElement.h"
#include "core/svg/SVGAnimatedColor.h"
#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
#include "core/svg/SVGLengthList.h"
#include "core/svg/SVGNumber.h"
#include "core/svg/SVGPaint.h"
#include "core/svg/SVGPointList.h"
#include "core/svg/SVGString.h"
#include "core/svg/SVGTransformList.h"
namespace WebCore {
SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
: m_type(type)
, m_animationElement(animationElement)
, m_contextElement(contextElement)
{
ASSERT(m_animationElement);
ASSERT(m_contextElement);
ASSERT(m_type != AnimatedPoint
&& m_type != AnimatedStringList
&& m_type != AnimatedTransform
&& m_type != AnimatedUnknown);
const QualifiedName& attributeName = m_animationElement->attributeName();
m_animatedProperty = m_contextElement->propertyFromAttribute(attributeName);
if (m_animatedProperty)
ASSERT(m_animatedProperty->type() == m_type);
}
SVGAnimatedTypeAnimator::~SVGAnimatedTypeAnimator()
{
}
PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::createPropertyForAnimation(const String& value)
{
if (isAnimatingSVGDom()) {
if (m_type == AnimatedTransformList) {
ASSERT(m_animationElement);
SVGTransformType transformType = toSVGAnimateTransformElement(m_animationElement)->transformType();
return SVGTransformList::create(transformType, value);
}
ASSERT(m_animatedProperty);
return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
}
ASSERT(isAnimatingCSSProperty());
switch (m_type) {
case AnimatedColor:
return SVGColorProperty::create(value.isEmpty() ? StyleColor::currentColor() : SVGPaint::colorFromRGBColorString(value));
case AnimatedNumber: {
RefPtr<SVGNumber> property = SVGNumber::create();
property->setValueAsString(value, IGNORE_EXCEPTION);
return property.release();
}
case AnimatedLength: {
RefPtr<SVGLength> property = SVGLength::create(LengthModeOther);
property->setValueAsString(value, IGNORE_EXCEPTION);
return property.release();
}
case AnimatedLengthList: {
RefPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther);
property->setValueAsString(value, IGNORE_EXCEPTION);
return property.release();
}
case AnimatedString: {
RefPtr<SVGString> property = SVGString::create();
property->setValueAsString(value, IGNORE_EXCEPTION);
return property.release();
}
case AnimatedBoolean:
case AnimatedNumberList:
case AnimatedNumberOptionalNumber:
case AnimatedPoint:
case AnimatedPoints:
case AnimatedRect:
case AnimatedTransform:
case AnimatedTransformList:
ASSERT_NOT_REACHED();
case AnimatedAngle:
case AnimatedEnumeration:
case AnimatedInteger:
case AnimatedIntegerOptionalInteger:
case AnimatedPath:
case AnimatedPreserveAspectRatio:
case AnimatedStringList:
ASSERT_NOT_REACHED();
case AnimatedUnknown:
ASSERT_NOT_REACHED();
};
ASSERT_NOT_REACHED();
return nullptr;
}
PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::constructFromString(const String& value)
{
return createPropertyForAnimation(value);
}
void SVGAnimatedTypeAnimator::calculateFromAndToValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& toString)
{
from = constructFromString(fromString);
to = constructFromString(toString);
}
void SVGAnimatedTypeAnimator::calculateFromAndByValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& byString)
{
from = constructFromString(fromString);
to = constructFromString(byString);
to->add(from, m_contextElement);
}
namespace {
typedef void (SVGAnimatedPropertyBase::*SVGAnimatedPropertyMethod)();
void invokeMethodOnAllTargetProperties(const Vector<SVGElement*>& list, const QualifiedName& attributeName, SVGAnimatedPropertyMethod method)
{
Vector<SVGElement*>::const_iterator it = list.begin();
Vector<SVGElement*>::const_iterator itEnd = list.end();
for (; it != itEnd; ++it) {
RefPtr<SVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(attributeName);
if (animatedProperty)
(animatedProperty.get()->*method)();
}
}
void setAnimatedValueOnAllTargetProperties(const Vector<SVGElement*>& list, const QualifiedName& attributeName, PassRefPtr<SVGPropertyBase> passValue)
{
RefPtr<SVGPropertyBase> value = passValue;
Vector<SVGElement*>::const_iterator it = list.begin();
Vector<SVGElement*>::const_iterator itEnd = list.end();
for (; it != itEnd; ++it) {
RefPtr<SVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(attributeName);
if (animatedProperty)
animatedProperty->setAnimatedValue(value);
}
}
}
PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimation(const Vector<SVGElement*>& list)
{
ASSERT(isAnimatingSVGDom());
RefPtr<SVGPropertyBase> animatedValue = m_animatedProperty->createAnimatedValue();
ASSERT(animatedValue->type() == m_type);
setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue);
return animatedValue.release();
}
PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::startAnimValAnimation(const Vector<SVGElement*>& list)
{
ASSERT(isAnimatingSVGDom());
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &SVGAnimatedPropertyBase::animationStarted);
return resetAnimation(list);
}
void SVGAnimatedTypeAnimator::stopAnimValAnimation(const Vector<SVGElement*>& list)
{
ASSERT(isAnimatingSVGDom());
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &SVGAnimatedPropertyBase::animationEnded);
}
PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimValToBaseVal(const Vector<SVGElement*>& list)
{
SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
return resetAnimation(list);
}
class ParsePropertyFromString {
public:
explicit ParsePropertyFromString(SVGAnimatedTypeAnimator* animator)
: m_animator(animator)
{
}
PassRefPtr<SVGPropertyBase> operator()(SVGAnimationElement*, const String& value)
{
return m_animator->createPropertyForAnimation(value);
}
private:
SVGAnimatedTypeAnimator* m_animator;
};
void SVGAnimatedTypeAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase* from, SVGPropertyBase* to, SVGPropertyBase* toAtEndOfDuration, SVGPropertyBase* animated)
{
ASSERT(m_animationElement);
ASSERT(m_contextElement);
RefPtr<SVGPropertyBase> fromValue = m_animationElement->animationMode() == ToAnimation ? animated : from;
RefPtr<SVGPropertyBase> toValue = to;
RefPtr<SVGPropertyBase> toAtEndOfDurationValue = toAtEndOfDuration;
RefPtr<SVGPropertyBase> animatedValue = animated;
ParsePropertyFromString parsePropertyFromString(this);
m_animationElement->adjustForInheritance<RefPtr<SVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->fromPropertyValueType(), fromValue, m_contextElement);
m_animationElement->adjustForInheritance<RefPtr<SVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->toPropertyValueType(), toValue, m_contextElement);
animatedValue->calculateAnimatedValue(m_animationElement, percentage, repeatCount, fromValue, toValue, toAtEndOfDurationValue, m_contextElement);
}
float SVGAnimatedTypeAnimator::calculateDistance(const String& fromString, const String& toString)
{
ASSERT(m_animationElement);
ASSERT(m_contextElement);
RefPtr<SVGPropertyBase> fromValue = createPropertyForAnimation(fromString);
RefPtr<SVGPropertyBase> toValue = createPropertyForAnimation(toString);
return fromValue->calculateDistance(toValue, m_contextElement);
}
}