18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2007 Rob Buis <buis@kde.org> 4dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2008 Apple Inc. All rights reserved. 5dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * 6dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is free software; you can redistribute it and/or 7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * modify it under the terms of the GNU Library General Public 8dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * License as published by the Free Software Foundation; either 9dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * version 2 of the License, or (at your option) any later version. 10dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * 11dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is distributed in the hope that it will be useful, 12dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of 13dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Library General Public License for more details. 15dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * 16dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * You should have received a copy of the GNU Library General Public License 17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * along with this library; see the file COPYING.LIB. If not, write to 18dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Boston, MA 02110-1301, USA. 20dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch */ 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG) && ENABLE(SVG_ANIMATION) 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGAnimateMotionElement.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderObject.h" 29967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "RenderSVGResource.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGElementInstance.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGMPathElement.h" 32f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "SVGNames.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGParserUtilities.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGPathElement.h" 35f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "SVGPathParserFactory.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGTransformList.h" 37f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <wtf/MathExtras.h> 38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h> 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace SVGNames; 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monseninline SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tagName, Document* document) 455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen : SVGAnimationElement(tagName, document) 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_baseIndexInTransformList(0) 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_angle(0) 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const QualifiedName& tagName, Document* document) 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return adoptRef(new SVGAnimateMotionElement(tagName, document)); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool SVGAnimateMotionElement::hasValidAttributeType() const 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGElement* targetElement = this->targetElement(); 5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!targetElement) 6081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // We don't have a special attribute name to verify the animation type. Check the element name instead. 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(SVGNames::textTag)) 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Spec: SVG 1.1 section 19.2.15 6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems. 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (targetElement->hasTagName(gTag) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(defsTag) 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(useTag) 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(imageTag) 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(switchTag) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(pathTag) 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(rectTag) 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(circleTag) 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(ellipseTag) 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(lineTag) 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(polylineTag) 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(polygonTag) 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(textTag) 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(clipPathTag) 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(maskTag) 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(aTag) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG_FOREIGN_OBJECT) 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project || targetElement->hasTagName(foreignObjectTag) 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ) 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 91e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid SVGAnimateMotionElement::parseMappedAttribute(Attribute* attr) 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (attr->name() == SVGNames::pathAttr) { 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_path = Path(); 95dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch SVGPathParserFactory* factory = SVGPathParserFactory::self(); 96dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch factory->buildPathFromString(attr->value(), m_path); 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGAnimationElement::parseMappedAttribute(attr); 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(const AtomicString, autoVal, ("auto")); 104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(const AtomicString, autoReverse, ("auto-reverse")); 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String rotate = getAttribute(SVGNames::rotateAttr); 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rotate == autoVal) 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return RotateAuto; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rotate == autoReverse) 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return RotateAutoReverse; 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return RotateAngle; 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPath SVGAnimateMotionElement::animationPath() const 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (Node* child = firstChild(); child; child = child->nextSibling()) { 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (child->hasTagName(SVGNames::mpathTag)) { 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGMPathElement* mPath = static_cast<SVGMPathElement*>(child); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGPathElement* pathElement = mPath->pathElement(); 119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Path path; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (pathElement) 121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch pathElement->toPathData(path); 122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return path; 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasAttribute(SVGNames::pathAttr)) 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_path; 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Path(); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool parsePoint(const String& s, FloatPoint& point) 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (s.isEmpty()) 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* cur = s.characters(); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* end = cur + s.length(); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!skipOptionalSpaces(cur, end)) 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float x = 0; 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!parseNumber(cur, end, x)) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch float y = 0; 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!parseNumber(cur, end, y)) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project point = FloatPoint(x, y); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // disallow anything except spaces at the end 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !skipOptionalSpaces(cur, end); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGAnimateMotionElement::resetToBaseValue(const String&) 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!hasValidAttributeType()) 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch AffineTransform* transform = targetElement()->supplementalTransform(); 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!transform) 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian transform->makeIdentity(); 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString) 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parsePoint(fromString, m_fromPoint); 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parsePoint(toString, m_toPoint); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parsePoint(fromString, m_fromPoint); 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatPoint byPoint; 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project parsePoint(byString, byPoint); 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y()); 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned, SVGSMILElement*) 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch SVGElement* targetElement = this->targetElement(); 18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!targetElement) 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch AffineTransform* transform = targetElement->supplementalTransform(); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!transform) 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 18981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (RenderObject* targetRenderer = targetElement->renderer()) 19081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch targetRenderer->setNeedsTransformUpdate(); 191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isAdditive()) 1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian transform->makeIdentity(); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Implement accumulate. 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (animationMode() == PathAnimation) { 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!animationPath().isEmpty()); 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Path path = animationPath(); 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float positionOnPath = path.length() * percentage; 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ok; 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatPoint position = path.pointAtLength(positionOnPath, ok); 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ok) { 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project transform->translate(position.x(), position.y()); 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RotateMode rotateMode = this->rotateMode(); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) { 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float angle = path.normalAngleAtLength(positionOnPath, ok); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (rotateMode == RotateAutoReverse) 20981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch angle += 180; 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project transform->rotate(angle); 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatSize diff = m_toPoint - m_fromPoint; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project transform->translate(diff.width() * percentage + m_fromPoint.x(), diff.height() * percentage + m_fromPoint.y()); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGAnimateMotionElement::applyResultsToTarget() 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We accumulate to the target element transform list so there is not much to do here. 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGElement* targetElement = this->targetElement(); 223967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!targetElement) 224967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return; 225967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 226967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (RenderObject* renderer = targetElement->renderer()) 227967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 228967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 2295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick AffineTransform* t = targetElement->supplementalTransform(); 2305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!t) 2315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ...except in case where we have additional instances in <use> trees. 234d0825bca7fe65beaee391d30da42e937db621564Steve Block const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement(); 235d0825bca7fe65beaee391d30da42e937db621564Steve Block const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); 236d0825bca7fe65beaee391d30da42e937db621564Steve Block for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(shadowTreeElement); 2398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block AffineTransform* transform = shadowTreeElement->supplementalTransform(); 2405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!transform) 2415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick continue; 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f()); 243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (RenderObject* renderer = shadowTreeElement->renderer()) { 244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block renderer->setNeedsTransformUpdate(); 245967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat SVGAnimateMotionElement::calculateDistance(const String& fromString, const String& toString) 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatPoint from; 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatPoint to; 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!parsePoint(fromString, from)) 25581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return -1; 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!parsePoint(toString, to)) 25781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return -1; 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatSize diff = to - from; 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ENABLE(SVG) 264