26 #if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
42 #include <wtf/MathExtras.h>
48 SVGAnimateTransformElement::SVGAnimateTransformElement(
const QualifiedName& tagName, Document* doc)
49 : SVGAnimationElement(tagName, doc)
50 , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
51 , m_baseIndexInTransformList(0)
55 SVGAnimateTransformElement::~SVGAnimateTransformElement()
59 bool SVGAnimateTransformElement::hasValidTarget()
const
61 SVGElement* targetElement = this->targetElement();
62 return SVGAnimationElement::hasValidTarget() && (targetElement->isStyledTransformable() || targetElement->hasTagName(
SVGNames::textTag));
65 void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute* attr)
68 if (attr->value() ==
"translate")
69 m_type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
70 else if (attr->value() ==
"scale")
71 m_type = SVGTransform::SVG_TRANSFORM_SCALE;
72 else if (attr->value() ==
"rotate")
73 m_type = SVGTransform::SVG_TRANSFORM_ROTATE;
74 else if (attr->value() ==
"skewX")
75 m_type = SVGTransform::SVG_TRANSFORM_SKEWX;
76 else if (attr->value() ==
"skewY")
77 m_type = SVGTransform::SVG_TRANSFORM_SKEWY;
79 SVGAnimationElement::parseMappedAttribute(attr);
83 static PassRefPtr<SVGTransformList> transformListFor(SVGElement* element)
86 if (element->isStyledTransformable())
87 return static_cast<SVGStyledTransformableElement*>(element)->transform();
89 return static_cast<SVGTextElement*>(element)->transform();
93 void SVGAnimateTransformElement::resetToBaseValue(
const String& baseValue)
95 if (!hasValidTarget())
97 if (baseValue.isEmpty()) {
99 RefPtr<SVGTransformList>
list = transformListFor(targetElement());
105 void SVGAnimateTransformElement::calculateAnimatedValue(
float percentage,
unsigned repeat, SVGSMILElement* resultElement)
107 if (!hasValidTarget())
109 SVGElement* targetElement = resultElement->targetElement();
110 RefPtr<SVGTransformList> transformList = transformListFor(targetElement);
111 ASSERT(transformList);
115 transformList->clear(ec);
116 if (isAccumulated() && repeat) {
117 SVGTransform accumulatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(repeat).addToSVGTransform(SVGTransform());
118 transformList->appendItem(accumulatedTransform, ec);
120 SVGTransform transform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentage).addToSVGTransform(m_fromTransform);
121 transformList->appendItem(transform, ec);
124 bool SVGAnimateTransformElement::calculateFromAndToValues(
const String& fromString,
const String& toString)
126 m_fromTransform = parseTransformValue(fromString);
127 if (!m_fromTransform.isValid())
129 m_toTransform = parseTransformValue(toString);
130 return m_toTransform.isValid();
133 bool SVGAnimateTransformElement::calculateFromAndByValues(
const String& fromString,
const String& byString)
136 m_fromTransform = parseTransformValue(fromString);
137 if (!m_fromTransform.isValid())
139 m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(byString));
140 return m_toTransform.isValid();
143 SVGTransform SVGAnimateTransformElement::parseTransformValue(
const String& value)
const
146 return SVGTransform(m_type);
149 String parseString(
"(" + value +
")");
150 const UChar* ptr = parseString.characters();
151 SVGTransformable::parseTransformValue(m_type, ptr, ptr + parseString.length(), result);
155 void SVGAnimateTransformElement::applyResultsToTarget()
157 if (!hasValidTarget())
160 SVGElement* targetElement = this->targetElement();
161 if (targetElement->renderer())
162 targetElement->renderer()->setNeedsLayout(
true);
165 HashSet<SVGElementInstance*>* instances = document()->accessSVGExtensions()->instancesForElement(targetElement);
168 RefPtr<SVGTransformList> transformList = transformListFor(targetElement);
169 HashSet<SVGElementInstance*>::iterator
end = instances->end();
170 for (HashSet<SVGElementInstance*>::iterator it = instances->begin(); it != end; ++it) {
171 SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
172 ASSERT(shadowTreeElement);
173 if (shadowTreeElement->isStyledTransformable())
174 static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransform(transformList.get());
176 static_cast<SVGTextElement*>(shadowTreeElement)->setTransform(transformList.get());
177 if (shadowTreeElement->renderer())
178 shadowTreeElement->renderer()->setNeedsLayout(
true);
182 float SVGAnimateTransformElement::calculateDistance(
const String& fromString,
const String& toString)
186 SVGTransform from = parseTransformValue(fromString);
189 SVGTransform to = parseTransformValue(toString);
190 if (!to.isValid() || from.type() != to.type())
192 if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) {
193 FloatSize diff = to.translate() - from.translate();
194 return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
196 if (to.type() == SVGTransform::SVG_TRANSFORM_ROTATE)
197 return fabsf(to.angle() - from.angle());
198 if (to.type() == SVGTransform::SVG_TRANSFORM_SCALE) {
199 FloatSize diff = to.scale() - from.scale();
200 return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
208 #endif // ENABLE(SVG)
DOM::QualifiedName transformAttr
DOM::QualifiedName typeAttr
DOM::QualifiedName textTag
QStringList list(const QString &fileClass)