15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Rob Buis <buis@kde.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAnimateMotionElement.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/SVGNames.h" 27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/ElementTraversal.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGResource.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGPathData.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGMPathElement.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGParserUtilities.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGPathElement.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGPathUtilities.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/AffineTransform.h" 36f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/MathExtras.h" 37f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/StdLibExtras.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 4002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace SVGNames; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)inline SVGAnimateMotionElement::SVGAnimateMotionElement(Document& document) 4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) : SVGAnimationElement(animateMotionTag, document) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_hasToPointAtEndOfDuration(false) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCalcMode(CalcModePaced); 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)DEFINE_NODE_FACTORY(SVGAnimateMotionElement) 515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 52f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)SVGAnimateMotionElement::~SVGAnimateMotionElement() 53f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 54f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 55f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateMotionElement::hasValidAttributeType() 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* targetElement = this->targetElement(); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!targetElement) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't have a special attribute name to verify the animation type. Check the element name instead. 63591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!targetElement->isSVGGraphicsElement()) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: SVG 1.1 section 19.2.15 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems. 67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return (isSVGGElement(*targetElement) 68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGDefsElement(*targetElement) 69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGUseElement(*targetElement) 70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGImageElement(*targetElement) 71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGSwitchElement(*targetElement) 72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGPathElement(*targetElement) 73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGRectElement(*targetElement) 74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGCircleElement(*targetElement) 75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGEllipseElement(*targetElement) 76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGLineElement(*targetElement) 77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGPolylineElement(*targetElement) 78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGPolygonElement(*targetElement) 79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGTextElement(*targetElement) 80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGClipPathElement(*targetElement) 81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGMaskElement(*targetElement) 82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGAElement(*targetElement) 83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGForeignObjectElement(*targetElement) 84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateMotionElement::hasValidAttributeName() 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // AnimateMotion does not use attributeName so it is always valid. 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimateMotionElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::pathAttr) { 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_path = Path(); 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) buildPathFromString(value, m_path); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateAnimationPath(); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SVGAnimationElement::parseAttribute(name, value); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, autoVal, ("auto", AtomicString::ConstructFromLiteral)); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, autoReverse, ("auto-reverse", AtomicString::ConstructFromLiteral)); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& rotate = getAttribute(SVGNames::rotateAttr); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rotate == autoVal) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RotateAuto; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rotate == autoReverse) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RotateAutoReverse; 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RotateAngle; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::updateAnimationPath() 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationPath = Path(); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool foundMPath = false; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (SVGMPathElement* mpath = Traversal<SVGMPathElement>::firstChild(*this); mpath; mpath = Traversal<SVGMPathElement>::nextSibling(*mpath)) { 123d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (SVGPathElement* pathElement = mpath->pathElement()) { 124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) updatePathFromGraphicsElement(pathElement, m_animationPath); 125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) foundMPath = true; 126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!foundMPath && fastHasAttribute(SVGNames::pathAttr)) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationPath = m_path; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateAnimationMode(); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 136591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochtemplate<typename CharType> 137591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool parsePointInternal(const String& string, FloatPoint& point) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const CharType* ptr = string.getCharacters<CharType>(); 140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const CharType* end = ptr + string.length(); 14102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!skipOptionalSVGSpaces(ptr, end)) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 14402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float x = 0; 146591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!parseNumber(ptr, end, x)) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 14802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float y = 0; 150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!parseNumber(ptr, end, y)) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) point = FloatPoint(x, y); 15402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // disallow anything except spaces at the end 156591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return !skipOptionalSVGSpaces(ptr, end); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 158591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 159591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool parsePoint(const String& string, FloatPoint& point) 160591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 161591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (string.isEmpty()) 162591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (string.is8Bit()) 164591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return parsePointInternal<LChar>(string, point); 165591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return parsePointInternal<UChar>(string, point); 166591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 167591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::resetAnimatedType() 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasValidAttributeType()) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* targetElement = this->targetElement(); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!targetElement) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (AffineTransform* transform = targetElement->supplementalTransform()) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transform->makeIdentity(); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::clearAnimatedType(SVGElement* targetElement) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!targetElement) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 183f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 184f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) AffineTransform* transform = targetElement->supplementalTransform(); 185f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (!transform) 186f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return; 187f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 188f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) transform->makeIdentity(); 189f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 190f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (RenderObject* targetRenderer = targetElement->renderer()) { 191f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) targetRenderer->setNeedsTransformUpdate(); 192f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RenderSVGResource::markForLayoutAndParentResourceInvalidation(targetRenderer); 193f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateMotionElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parsePoint(toAtEndOfDurationString, m_toPointAtEndOfDuration); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasToPointAtEndOfDuration = true; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasToPointAtEndOfDuration = false; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parsePoint(fromString, m_fromPoint); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parsePoint(toString, m_toPoint); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 21002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString) 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasToPointAtEndOfDuration = false; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationMode() == ByAnimation && !isAdditive()) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parsePoint(fromString, m_fromPoint); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint byPoint; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) parsePoint(byString, byPoint); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y()); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement*) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* targetElement = this->targetElement(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!targetElement) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform* transform = targetElement->supplementalTransform(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!transform) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderObject* targetRenderer = targetElement->renderer()) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetRenderer->setNeedsTransformUpdate(); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isAdditive()) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transform->makeIdentity(); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationMode() != PathAnimation) { 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint toPointAtEndOfDuration = m_toPoint; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAccumulated() && repeatCount && m_hasToPointAtEndOfDuration) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) toPointAtEndOfDuration = m_toPointAtEndOfDuration; 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float animatedX = 0; 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animateAdditiveNumber(percentage, repeatCount, m_fromPoint.x(), m_toPoint.x(), toPointAtEndOfDuration.x(), animatedX); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float animatedY = 0; 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animateAdditiveNumber(percentage, repeatCount, m_fromPoint.y(), m_toPoint.y(), toPointAtEndOfDuration.y(), animatedY); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transform->translate(animatedX, animatedY); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch ASSERT(!m_animationPath.isEmpty()); 2540019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch 2550019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch float positionOnPath = m_animationPath.length() * percentage; 2567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch FloatPoint position; 2577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch float angle; 25809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool ok = m_animationPath.pointAndNormalAtLength(positionOnPath, position, angle); 2590019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch if (!ok) 2600019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch return; 2617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 2627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // Handle accumulate="sum". 2637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (isAccumulated() && repeatCount) { 2647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch FloatPoint positionAtEndOfDuration = m_animationPath.pointAtLength(m_animationPath.length(), ok); 2657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (ok) 2667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch position.move(positionAtEndOfDuration.x() * repeatCount, positionAtEndOfDuration.y() * repeatCount); 2677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 2687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 2697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch transform->translate(position.x(), position.y()); 2700019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch RotateMode rotateMode = this->rotateMode(); 2710019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch if (rotateMode != RotateAuto && rotateMode != RotateAutoReverse) 2720019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch return; 2730019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch if (rotateMode == RotateAutoReverse) 2740019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch angle += 180; 2750019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch transform->rotate(angle); 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::applyResultsToTarget() 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We accumulate to the target element transform list so there is not much to do here. 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* targetElement = this->targetElement(); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!targetElement) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderObject* renderer = targetElement->renderer()) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform* t = targetElement->supplementalTransform(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!t) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ...except in case where we have additional instances in <use> trees. 293323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement(); 294323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end(); 295323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) { 296323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) SVGElement* shadowTreeElement = *it; 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(shadowTreeElement); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform* transform = shadowTreeElement->supplementalTransform(); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!transform) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f()); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderObject* renderer = shadowTreeElement->renderer()) { 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) renderer->setNeedsTransformUpdate(); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimateMotionElement::calculateDistance(const String& fromString, const String& toString) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint from; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint to; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parsePoint(fromString, from)) 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parsePoint(toString, to)) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize diff = to - from; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateMotionElement::updateAnimationMode() 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_animationPath.isEmpty()) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setAnimationMode(PathAnimation); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGAnimationElement::updateAnimationMode(); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 330