1/* 2 * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "SVGAnimatedPath.h" 22 23#include "SVGAnimateElement.h" 24#include "SVGAnimatedPathSegListPropertyTearOff.h" 25#include "SVGPathUtilities.h" 26 27namespace WebCore { 28 29SVGAnimatedPathAnimator::SVGAnimatedPathAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) 30 : SVGAnimatedTypeAnimator(AnimatedPath, animationElement, contextElement) 31{ 32} 33 34std::unique_ptr<SVGAnimatedType> SVGAnimatedPathAnimator::constructFromString(const String& string) 35{ 36 auto byteStream = std::make_unique<SVGPathByteStream>(); 37 buildSVGPathByteStreamFromString(string, byteStream.get(), UnalteredParsing); 38 return SVGAnimatedType::createPath(WTF::move(byteStream)); 39} 40 41std::unique_ptr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) 42{ 43 ASSERT(animatedTypes.size() >= 1); 44 SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get()); 45 const SVGPathSegList& baseValue = property->currentBaseValue(); 46 47 // Build initial path byte stream. 48 auto byteStream = std::make_unique<SVGPathByteStream>(); 49 buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing); 50 51 Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff>> result; 52 53 SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end(); 54 for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) 55 result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get())); 56 57 SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement()); 58 59 size_t resultSize = result.size(); 60 for (size_t i = 0; i < resultSize; ++i) 61 result[i]->animationStarted(byteStream.get(), &baseValue); 62 63 return SVGAnimatedType::createPath(WTF::move(byteStream)); 64} 65 66void SVGAnimatedPathAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) 67{ 68 stopAnimValAnimationForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes); 69} 70 71void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) 72{ 73 ASSERT(animatedTypes.size() >= 1); 74 ASSERT(type); 75 ASSERT(type->type() == m_type); 76 const SVGPathSegList& baseValue = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get())->currentBaseValue(); 77 buildSVGPathByteStreamFromSVGPathSegList(baseValue, type->path(), UnalteredParsing); 78} 79 80void SVGAnimatedPathAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes) 81{ 82 animValWillChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes); 83} 84 85void SVGAnimatedPathAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes) 86{ 87 animValDidChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes); 88} 89 90void SVGAnimatedPathAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to) 91{ 92 ASSERT(from->type() == AnimatedPath); 93 ASSERT(from->type() == to->type()); 94 95 SVGPathByteStream* fromPath = from->path(); 96 SVGPathByteStream* toPath = to->path(); 97 unsigned fromPathSize = fromPath->size(); 98 if (!fromPathSize || fromPathSize != toPath->size()) 99 return; 100 addToSVGPathByteStream(toPath, fromPath); 101} 102 103void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) 104{ 105 ASSERT(m_animationElement); 106 ASSERT(m_contextElement); 107 108 SVGPathByteStream* fromPath = from->path(); 109 SVGPathByteStream* toPath = to->path(); 110 SVGPathByteStream* toAtEndOfDurationPath = toAtEndOfDuration->path(); 111 SVGPathByteStream* animatedPath = animated->path(); 112 113 std::unique_ptr<SVGPathByteStream> underlyingPath; 114 bool isToAnimation = m_animationElement->animationMode() == ToAnimation; 115 if (isToAnimation) { 116 underlyingPath = animatedPath->copy(); 117 fromPath = underlyingPath.get(); 118 } 119 120 // Cache the current animated value before the buildAnimatedSVGPathByteStream() clears animatedPath. 121 std::unique_ptr<SVGPathByteStream> lastAnimatedPath; 122 if (!fromPath->size() || (m_animationElement->isAdditive() && !isToAnimation)) 123 lastAnimatedPath = animatedPath->copy(); 124 125 // Pass false to 'resizeAnimatedListIfNeeded' here, as the path animation is not a regular Vector<SVGXXX> type, but a SVGPathByteStream, that works differently. 126 if (!m_animationElement->adjustFromToListValues<SVGPathByteStream>(*fromPath, *toPath, *animatedPath, percentage, false)) 127 return; 128 129 buildAnimatedSVGPathByteStream(fromPath, toPath, animatedPath, percentage); 130 131 // Handle additive='sum'. 132 if (lastAnimatedPath) 133 addToSVGPathByteStream(animatedPath, lastAnimatedPath.get()); 134 135 // Handle accumulate='sum'. 136 if (m_animationElement->isAccumulated() && repeatCount) 137 addToSVGPathByteStream(animatedPath, toAtEndOfDurationPath, repeatCount); 138} 139 140float SVGAnimatedPathAnimator::calculateDistance(const String&, const String&) 141{ 142 // FIXME: Support paced animations. 143 return -1; 144} 145 146} 147