15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All rights reserved. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAnimationElement.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSPropertyNames.h" 305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/SVGNames.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSComputedStyleDeclaration.h" 327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/css/parser/CSSParser.h" 3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/frame/UseCounter.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAnimateElement.h" 35f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/svg/SVGElement.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGParserUtilities.h" 371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/FloatConversion.h" 38f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/MathExtras.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : SVGSMILElement(tagName, document) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_fromPropertyValueType(RegularPropertyValue) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_toPropertyValueType(RegularPropertyValue) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_animationValid(false) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_attributeType(AttributeTypeAuto) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_hasInvalidCSSAttributeType(false) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_calcMode(CalcModeLinear) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_animationMode(NoAnimation) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UseCounter::count(document, UseCounter::SVGAnimationElement); 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic void parseKeyTimes(const String& string, Vector<float>& result, bool verifyOrder) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.clear(); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> parseList; 59591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch string.split(';', parseList); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned n = 0; n < parseList.size(); ++n) { 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String timeString = parseList[n]; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool ok; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float time = timeString.toFloat(&ok); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ok || time < 0 || time > 1) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto fail; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (verifyOrder) { 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!n) { 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (time) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto fail; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (time < result.last()) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto fail; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.append(time); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)fail: 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.clear(); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 80591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochtemplate<typename CharType> 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic bool parseKeySplinesInternal(const String& string, Vector<UnitBezier>& result) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 83591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const CharType* ptr = string.getCharacters<CharType>(); 84591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch const CharType* end = ptr + string.length(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 86591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch skipOptionalSVGSpaces(ptr, end); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 88591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch while (ptr < end) { 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float posA = 0; 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parseNumber(ptr, end, posA)) 917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return false; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float posB = 0; 947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parseNumber(ptr, end, posB)) 957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return false; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float posC = 0; 987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parseNumber(ptr, end, posC)) 997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return false; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float posD = 0; 1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parseNumber(ptr, end, posD, DisallowWhitespace)) 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return false; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 105591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch skipOptionalSVGSpaces(ptr, end); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (ptr < end && *ptr == ';') 108591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ptr++; 109591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch skipOptionalSVGSpaces(ptr, end); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.append(UnitBezier(posA, posB, posC, posD)); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ptr == end; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic bool parseKeySplines(const String& string, Vector<UnitBezier>& result) 118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch result.clear(); 120591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (string.isEmpty()) 1217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return true; 1227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool parsed = true; 123591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (string.is8Bit()) 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci parsed = parseKeySplinesInternal<LChar>(string, result); 125591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch else 1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci parsed = parseKeySplinesInternal<UChar>(string, result); 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parsed) { 1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci result.clear(); 1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return false; 1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return true; 132591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 133591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimationElement::isSupportedAttribute(const QualifiedName& attrName) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (supportedAttributes.isEmpty()) { 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::valuesAttr); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::keyTimesAttr); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::keyPointsAttr); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::keySplinesAttr); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::attributeTypeAttr); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::calcModeAttr); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::fromAttr); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::toAttr); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::byAttr); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 148591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimationElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!isSupportedAttribute(name)) { 154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SVGSMILElement::parseAttribute(name, value); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 158926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::valuesAttr) { 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Per the SMIL specification, leading and trailing white space, 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and white space before and after semicolon separators, is allowed and will be ignored. 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) value.string().split(';', m_values); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_values.size(); ++i) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_values[i] = m_values[i].stripWhiteSpace(); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateAnimationMode(); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::keyTimesAttr) { 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) parseKeyTimes(value, m_keyTimes, true); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::keyPointsAttr) { 176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSVGAnimateMotionElement(*this)) { 17702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // This is specified to be an animateMotion attribute only but it is simpler to put it here 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // where the other timing calculatations are. 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) parseKeyTimes(value, m_keyPoints, false); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::keySplinesAttr) { 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!parseKeySplines(value, m_keySplines)) 1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci reportAttributeParsingError(ParsingAttributeFailedError, name, value); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::attributeTypeAttr) { 191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setAttributeType(value); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::calcModeAttr) { 196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setCalcMode(value); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == SVGNames::fromAttr || name == SVGNames::toAttr || name == SVGNames::byAttr) { 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateAnimationMode(); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::svgAttributeChanged(const QualifiedName& attrName) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isSupportedAttribute(attrName)) { 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGSMILElement::svgAttributeChanged(attrName); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) animationAttributeChanged(); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::animationAttributeChanged() 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Assumptions may not hold after an attribute change. 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = false; 22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_lastValuesAnimationFrom = String(); 22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_lastValuesAnimationTo = String(); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setInactive(); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimationElement::getStartTime() const 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return narrowPrecisionToFloat(intervalBegin().value()); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimationElement::getCurrentTime() const 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return narrowPrecisionToFloat(elapsed().value()); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)float SVGAnimationElement::getSimpleDuration() const 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return narrowPrecisionToFloat(simpleDuration().value()); 24002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch} 24102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::beginElement() 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beginElementAt(0); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::beginElementAt(float offset) 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!std::isfinite(offset)) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SMILTime elapsed = this->elapsed(); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addBeginTime(elapsed, elapsed + offset, SMILTimeWithOrigin::ScriptOrigin); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::endElement() 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endElementAt(0); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::endElementAt(float offset) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (!std::isfinite(offset)) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SMILTime elapsed = this->elapsed(); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addEndTime(elapsed, elapsed + offset, SMILTimeWithOrigin::ScriptOrigin); 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::updateAnimationMode() 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#AnimFuncValues 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasAttribute(SVGNames::valuesAttr)) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setAnimationMode(ValuesAnimation); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!toValue().isEmpty()) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setAnimationMode(fromValue().isEmpty() ? ToAnimation : FromToAnimation); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!byValue().isEmpty()) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setAnimationMode(fromValue().isEmpty() ? ByAnimation : FromByAnimation); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setAnimationMode(NoAnimation); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::setCalcMode(const AtomicString& calcMode) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, discrete, ("discrete", AtomicString::ConstructFromLiteral)); 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, linear, ("linear", AtomicString::ConstructFromLiteral)); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, paced, ("paced", AtomicString::ConstructFromLiteral)); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, spline, ("spline", AtomicString::ConstructFromLiteral)); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode == discrete) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCalcMode(CalcModeDiscrete); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (calcMode == linear) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCalcMode(CalcModeLinear); 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (calcMode == paced) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCalcMode(CalcModePaced); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (calcMode == spline) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setCalcMode(CalcModeSpline); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) setCalcMode(isSVGAnimateMotionElement(*this) ? CalcModePaced : CalcModeLinear); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::setAttributeType(const AtomicString& attributeType) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, css, ("CSS", AtomicString::ConstructFromLiteral)); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, xml, ("XML", AtomicString::ConstructFromLiteral)); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attributeType == css) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attributeType = AttributeTypeCSS; 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (attributeType == xml) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attributeType = AttributeTypeXML; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_attributeType = AttributeTypeAuto; 309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) checkInvalidCSSAttributeType(targetElement()); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String SVGAnimationElement::toValue() const 31302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastGetAttribute(SVGNames::toAttr); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String SVGAnimationElement::byValue() const 31802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastGetAttribute(SVGNames::byAttr); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String SVGAnimationElement::fromValue() const 32302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastGetAttribute(SVGNames::fromAttr); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 327f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)bool SVGAnimationElement::isAdditive() 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral)); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value == sum || animationMode() == ByAnimation; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimationElement::isAccumulated() const 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral)); 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value == sum && animationMode() != ToAnimation; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(targetElement); 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 345f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return SVGElement::isAnimatableCSSProperty(attributeName); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName) 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasValidAttributeType() || !targetElement || attributeName == anyQName()) 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DontApplyAnimation; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Always animate CSS properties, using the ApplyCSSAnimation code path, regardless of the attributeType value. 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isTargetAttributeCSSProperty(targetElement, attributeName)) 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ApplyCSSAnimation; 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If attributeType="CSS" and attributeName doesn't point to a CSS property, ignore the animation. 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attributeType() == AttributeTypeCSS) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DontApplyAnimation; 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ApplyXMLAnimation; 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::calculateKeyTimesForCalcModePaced() 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(calcMode() == CalcModePaced); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(animationMode() == ValuesAnimation); 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned valuesCount = m_values.size(); 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(valuesCount >= 1); 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (valuesCount == 1) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME, webkit.org/b/109010: m_keyTimes should not be modified in this function. 375926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_keyTimes.clear(); 376926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<float> keyTimesForPaced; 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float totalDistance = 0; 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) keyTimesForPaced.append(0); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned n = 0; n < valuesCount - 1; ++n) { 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Distance in any units 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float distance = calculateDistance(m_values[n], m_values[n + 1]); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (distance < 0) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalDistance += distance; 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) keyTimesForPaced.append(distance); 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!totalDistance) 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Normalize. 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned n = 1; n < keyTimesForPaced.size() - 1; ++n) 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) keyTimesForPaced[n] = keyTimesForPaced[n - 1] + keyTimesForPaced[n] / totalDistance; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) keyTimesForPaced[keyTimesForPaced.size() - 1] = 1; 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Use key times calculated based on pacing instead of the user provided ones. 397926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_keyTimes = keyTimesForPaced; 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline double solveEpsilon(double duration) { return 1 / (200 * duration); } 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned index; 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned keyTimesCount = m_keyTimes.size(); 406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // For linear and spline animations, the last value must be '1'. In those 407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // cases we don't need to consider the last value, since |percent| is never 408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // greater than one. 409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (keyTimesCount && calcMode() != CalcModeDiscrete) 410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) keyTimesCount--; 411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (index = 1; index < keyTimesCount; ++index) { 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_keyTimes[index] > percent) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return --index; 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned splineIndex) const 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(calcMode() == CalcModeSpline); 421926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size()); 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UnitBezier bezier = m_keySplines[splineIndex]; 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SMILTime duration = simpleDuration(); 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!duration.isFinite()) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) duration = 100.0; 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return narrowPrecisionToFloat(bezier.solve(percent, solveEpsilon(duration.value()))); 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_keyPoints.isEmpty()); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(calcMode() != CalcModePaced); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_keyTimes.size() > 1); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_keyPoints.size() == m_keyTimes.size()); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (percent == 1) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_keyPoints[m_keyPoints.size() - 1]; 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned index = calculateKeyTimesIndex(percent); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float fromKeyPoint = m_keyPoints[index]; 44102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode() == CalcModeDiscrete) 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fromKeyPoint; 44402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(index + 1 < m_keyTimes.size()); 446d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float fromPercent = m_keyTimes[index]; 447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float toPercent = m_keyTimes[index + 1]; 448d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float toKeyPoint = m_keyPoints[index + 1]; 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent); 45002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode() == CalcModeSpline) { 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) keyPointPercent = calculatePercentForSpline(keyPointPercent, index); 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (toKeyPoint - fromKeyPoint) * keyPointPercent + fromKeyPoint; 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimationElement::calculatePercentForFromTo(float percent) const 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode() == CalcModeDiscrete && m_keyTimes.size() == 2) 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return percent > m_keyTimes[1] ? 1 : 0; 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return percent; 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 46502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_keyPoints.isEmpty()); 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_keyPoints.size() == m_keyTimes.size()); 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(calcMode() != CalcModePaced); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = calculatePercentFromKeyPoints(percent); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1)); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) from = m_values[index]; 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to = m_values[index + 1]; 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 47602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned valuesCount = m_values.size(); 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_animationValid); 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(valuesCount >= 1); 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (percent == 1 || valuesCount == 1) { 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) from = m_values[valuesCount - 1]; 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to = m_values[valuesCount - 1]; 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = 1; 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CalcMode calcMode = this->calcMode(); 491f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (isSVGAnimateElement(*this)) { 492f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) SVGAnimateElement& animateElement = toSVGAnimateElement(*this); 493f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (!animateElement.animatedPropertyTypeSupportsAddition()) { 494f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) ASSERT(animateElement.animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this)); 495f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown); 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) calcMode = CalcModeDiscrete; 497f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return currentValuesFromKeyPoints(percent, effectivePercent, from, to); 50102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned keyTimesCount = m_keyTimes.size(); 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!keyTimesCount || valuesCount == keyTimesCount); 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!keyTimesCount || (keyTimesCount > 1 && !m_keyTimes[0])); 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned index = calculateKeyTimesIndex(percent); 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode == CalcModeDiscrete) { 50802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch if (!keyTimesCount) 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) index = static_cast<unsigned>(percent * valuesCount); 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) from = m_values[index]; 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to = m_values[index]; 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = 0; 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 51502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float fromPercent; 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float toPercent; 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (keyTimesCount) { 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fromPercent = m_keyTimes[index]; 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) toPercent = m_keyTimes[index + 1]; 52102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } else { 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) index = static_cast<unsigned>(floorf(percent * (valuesCount - 1))); 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fromPercent = static_cast<float>(index) / (valuesCount - 1); 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) toPercent = static_cast<float>(index + 1) / (valuesCount - 1); 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 52602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index == valuesCount - 1) 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --index; 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) from = m_values[index]; 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to = m_values[index + 1]; 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(toPercent > fromPercent); 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = (percent - fromPercent) / (toPercent - fromPercent); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode == CalcModeSpline) { 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_keySplines.size() == m_values.size() - 1); 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = calculatePercentForSpline(effectivePercent, index); 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 53902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::startedActiveInterval() 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = false; 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 544c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!isValid()) 545c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return; 546c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasValidAttributeType()) 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // These validations are appropriate for all animation modes. 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size()) 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AnimationMode animationMode = this->animationMode(); 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CalcMode calcMode = this->calcMode(); 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode == CalcModeSpline) { 557e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) unsigned splinesCount = m_keySplines.size(); 558e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!splinesCount 559e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount) 560e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) || (animationMode == ValuesAnimation && m_values.size() - 1 != splinesCount) 561e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount)) 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String from = fromValue(); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String to = toValue(); 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String by = byValue(); 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationMode == NoAnimation) 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5709e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if ((animationMode == FromToAnimation || animationMode == FromByAnimation || animationMode == ToAnimation || animationMode == ByAnimation) 5719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) && (fastHasAttribute(SVGNames::keyPointsAttr) && fastHasAttribute(SVGNames::keyTimesAttr) && (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size()))) 5729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return; 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationMode == FromToAnimation) 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateFromAndToValues(from, to); 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (animationMode == ToAnimation) { 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For to-animations the from value is the current accumulated value from lower priority animations. 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The value is not static and is determined during the animation. 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateFromAndToValues(emptyString(), to); 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (animationMode == FromByAnimation) 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateFromAndByValues(from, by); 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (animationMode == ByAnimation) 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateFromAndByValues(emptyString(), by); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (animationMode == ValuesAnimation) { 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = m_values.size() >= 1 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && (calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyTimesAttr) || fastHasAttribute(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size())) 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && (calcMode == CalcModeDiscrete || !m_keyTimes.size() || m_keyTimes.last() == 1) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && (calcMode != CalcModeSpline || ((m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1)) || m_keySplines.size() == m_keyPoints.size() - 1)) 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && (!fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size())); 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_animationValid) 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateToAtEndOfDurationValue(m_values.last()); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (calcMode == CalcModePaced && m_animationValid) 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) calculateKeyTimesForCalcModePaced(); 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (animationMode == PathAnimation) 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()); 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, SVGSMILElement* resultElement) 59802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_animationValid) 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float effectivePercent; 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CalcMode calcMode = this->calcMode(); 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AnimationMode animationMode = this->animationMode(); 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (animationMode == ValuesAnimation) { 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String from; 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String to; 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentValuesForValuesAnimation(percent, effectivePercent, from, to); 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from != m_lastValuesAnimationFrom || to != m_lastValuesAnimationTo) { 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_animationValid = calculateFromAndToValues(from, to); 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_animationValid) 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastValuesAnimationFrom = from; 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastValuesAnimationTo = to; 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = calculatePercentFromKeyPoints(percent); 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (m_keyPoints.isEmpty() && calcMode == CalcModeSpline && m_keyTimes.size() > 1) 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = calculatePercentForSpline(percent, calculateKeyTimesIndex(percent)); 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (animationMode == FromToAnimation || animationMode == ToAnimation) 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = calculatePercentForFromTo(percent); 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) effectivePercent = percent; 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) calculateAnimatedValue(effectivePercent, repeatCount, resultElement); 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::computeCSSPropertyValue(SVGElement* element, CSSPropertyID id, String& value) 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(element); 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't include any properties resulting from CSS Transitions/Animations or SMIL animations, as we want to retrieve the "base value". 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element->setUseOverrideComputedStyle(true); 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) value = CSSComputedStyleDeclaration::create(element)->getPropertyValue(id); 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element->setUseOverrideComputedStyle(false); 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String& value) 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: At the moment the computed style gets returned as a String and needs to get parsed again. 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // In the future we might want to work with the value type directly to avoid the String parsing. 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(targetElement); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Element* parent = targetElement->parentElement(); 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parent || !parent->isSVGElement()) 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 648926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SVGElement* svgParent = toSVGElement(parent); 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeCSSPropertyValue(svgParent, cssPropertyID(attributeName.localName()), value); 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value) 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(targetElement); 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit", AtomicString::ConstructFromLiteral)); 65602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 657f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (value.isEmpty() || value != inherit) 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 659f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return SVGElement::isAnimatableCSSProperty(attributeName); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::determinePropertyValueTypes(const String& from, const String& to) 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* targetElement = this->targetElement(); 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(targetElement); 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const QualifiedName& attributeName = this->attributeName(); 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inheritsFromProperty(targetElement, attributeName, from)) 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_fromPropertyValueType = InheritValue; 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inheritsFromProperty(targetElement, attributeName, to)) 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_toPropertyValueType = InheritValue; 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimationElement::setTargetElement(SVGElement* target) 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 676926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SVGSMILElement::setTargetElement(target); 677926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) checkInvalidCSSAttributeType(target); 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGSMILElement::setAttributeName(attributeName); 683926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) checkInvalidCSSAttributeType(targetElement()); 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target) 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(target, attributeName()); 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 692