SVGAnimateTransformElement.cpp [plain text]
#include "config.h"
#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
#include "SVGAnimateTransformElement.h"
#include "AffineTransform.h"
#include "RenderObject.h"
#include "SVGAngle.h"
#include "SVGParserUtilities.h"
#include "SVGSVGElement.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransform.h"
#include "SVGTransformList.h"
#include "TimeScheduler.h"
#include <math.h>
#include <wtf/MathExtras.h>
using namespace std;
namespace WebCore {
SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document* doc)
: SVGAnimationElement(tagName, doc)
, m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
{
}
SVGAnimateTransformElement::~SVGAnimateTransformElement()
{
}
bool SVGAnimateTransformElement::hasValidTarget() const
{
return (SVGAnimationElement::hasValidTarget() && targetElement()->isStyledTransformable());
}
void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == SVGNames::typeAttr) {
if (attr->value() == "translate")
m_type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
else if (attr->value() == "scale")
m_type = SVGTransform::SVG_TRANSFORM_SCALE;
else if (attr->value() == "rotate")
m_type = SVGTransform::SVG_TRANSFORM_ROTATE;
else if (attr->value() == "skewX")
m_type = SVGTransform::SVG_TRANSFORM_SKEWX;
else if (attr->value() == "skewY")
m_type = SVGTransform::SVG_TRANSFORM_SKEWY;
} else
SVGAnimationElement::parseMappedAttribute(attr);
}
bool SVGAnimateTransformElement::updateAnimatedValue(EAnimationMode animationMode, float timePercentage, unsigned valueIndex, float percentagePast)
{
if (animationMode == TO_ANIMATION)
m_animatedTransform = SVGTransformDistance(m_baseTransform, m_toTransform).scaledDistance(timePercentage).addToSVGTransform(m_baseTransform);
else
m_animatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentagePast).addToSVGTransform(m_fromTransform);
return (m_animatedTransform != m_baseTransform);
}
bool SVGAnimateTransformElement::updateAnimationBaseValueFromElement()
{
m_baseTransform = SVGTransform();
m_toTransform = SVGTransform();
m_fromTransform = SVGTransform();
m_animatedTransform = SVGTransform();
if (!targetElement()->isStyledTransformable())
return false;
SVGStyledTransformableElement* transform = static_cast<SVGStyledTransformableElement*>(targetElement());
RefPtr<SVGTransformList> transformList = transform->transform();
if (!transformList)
return false;
m_baseTransform = transformList->concatenateForType(m_type);
if (m_baseTransform.type() == SVGTransform::SVG_TRANSFORM_UNKNOWN)
m_baseTransform = SVGTransform(m_type);
return true;
}
void SVGAnimateTransformElement::applyAnimatedValueToElement()
{
if (!targetElement()->isStyledTransformable())
return;
SVGStyledTransformableElement* transform = static_cast<SVGStyledTransformableElement*>(targetElement());
RefPtr<SVGTransformList> transformList = transform->transform();
if (!transformList)
return;
ExceptionCode ec;
if (!isAdditive())
transformList->clear(ec);
transformList->appendItem(m_animatedTransform, ec);
transform->setTransform(transformList.get());
if (transform->renderer())
transform->renderer()->setNeedsLayout(true); }
bool SVGAnimateTransformElement::calculateFromAndToValues(EAnimationMode animationMode, unsigned valueIndex)
{
switch (animationMode) {
case FROM_TO_ANIMATION:
m_fromTransform = parseTransformValue(m_from);
case TO_ANIMATION:
m_toTransform = parseTransformValue(m_to);
break;
case FROM_BY_ANIMATION:
m_fromTransform = parseTransformValue(m_from);
m_toTransform = parseTransformValue(m_by);
break;
case BY_ANIMATION:
m_fromTransform = parseTransformValue(m_from);
m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(m_by));
break;
case VALUES_ANIMATION:
m_fromTransform = parseTransformValue(m_values[valueIndex]);
m_toTransform = ((valueIndex + 1) < m_values.size()) ? parseTransformValue(m_values[valueIndex + 1]) : m_fromTransform;
break;
case NO_ANIMATION:
ASSERT_NOT_REACHED();
}
return true;
}
SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value) const
{
SVGTransform result;
const UChar* ptr = value.characters();
SVGTransformable::parseTransformValue(m_type, ptr, ptr + value.length(), result); return result;
}
}
#endif // ENABLE(SVG)