/* * Copyright (C) 2004, 2005 Nikolas Zimmermann * Copyright (C) 2004, 2005, 2006 Rob Buis * Copyright (C) 2007 Eric Seidel * Copyright (C) 2008-2021 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron McCormack * Copyright (C) Research In Motion Limited 2011. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #pragma once #include "SVGSMILElement.h" #include "SVGTests.h" #include "UnitBezier.h" namespace WebCore { class ConditionEventListener; class TimeContainer; // If we have 'currentColor' or 'inherit' as animation value, we need to grab // the value during the animation since the value can be animated itself. enum AnimatedPropertyValueType { RegularPropertyValue, CurrentColorValue, InheritValue }; class SVGAnimationElement : public SVGSMILElement, public SVGTests { WTF_MAKE_ISO_ALLOCATED(SVGAnimationElement); public: float getStartTime() const; float getCurrentTime() const; float getSimpleDuration() const; void beginElement(); void beginElementAt(float offset); void endElement(); void endElementAt(float offset); static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); bool isAdditive() const override; bool isAccumulated() const; AnimationMode animationMode() const { return m_animationMode; } CalcMode calcMode() const { return m_calcMode; } AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; } AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; } void animateAdditiveNumber(float percentage, unsigned repeatCount, float fromNumber, float toNumber, float toAtEndOfDurationNumber, float& animatedNumber) { float number; if (calcMode() == CalcMode::Discrete) number = percentage < 0.5 ? fromNumber : toNumber; else number = (toNumber - fromNumber) * percentage + fromNumber; if (isAccumulated() && repeatCount) number += toAtEndOfDurationNumber * repeatCount; if (isAdditive() && animationMode() != AnimationMode::To) animatedNumber += number; else animatedNumber = number; } enum class AttributeType : uint8_t { CSS, XML, Auto }; AttributeType attributeType() const { return m_attributeType; } protected: SVGAnimationElement(const QualifiedName&, Document&); using PropertyRegistry = SVGPropertyOwnerRegistry; const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; } virtual void resetAnimation(); static bool isSupportedAttribute(const QualifiedName&); void parseAttribute(const QualifiedName&, const AtomString&) override; void svgAttributeChanged(const QualifiedName&) override; String toValue() const; String byValue() const; String fromValue() const; String targetAttributeBaseValue(); // from SVGSMILElement void startedActiveInterval() override; void updateAnimation(float percent, unsigned repeat) override; AnimatedPropertyValueType m_fromPropertyValueType { RegularPropertyValue }; AnimatedPropertyValueType m_toPropertyValueType { RegularPropertyValue }; void setAttributeName(const QualifiedName&) override { } virtual void updateAnimationMode(); void setAnimationMode(AnimationMode animationMode) { m_animationMode = animationMode; } void setCalcMode(CalcMode calcMode) { m_calcMode = calcMode; } private: void animationAttributeChanged() override; void setAttributeType(const AtomString&); virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) = 0; virtual bool calculateFromAndToValues(const String& fromString, const String& toString) = 0; virtual bool calculateFromAndByValues(const String& fromString, const String& byString) = 0; virtual void calculateAnimatedValue(float percent, unsigned repeatCount) = 0; virtual std::optional calculateDistance(const String& /*fromString*/, const String& /*toString*/) = 0; const Vector& keyTimes() const; void currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to); void calculateKeyTimesForCalcModePaced(); float calculatePercentFromKeyPoints(float percent) const; void currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const; float calculatePercentForSpline(float percent, unsigned splineIndex) const; float calculatePercentForFromTo(float percent) const; unsigned calculateKeyTimesIndex(float percent) const; void setCalcMode(const AtomString&); bool m_animationValid { false }; AttributeType m_attributeType { AttributeType::Auto }; Vector m_values; Vector m_keyTimesFromAttribute; Vector m_keyTimesForPaced; Vector m_keyPoints; Vector m_keySplines; String m_lastValuesAnimationFrom; String m_lastValuesAnimationTo; CalcMode m_calcMode { CalcMode::Linear }; AnimationMode m_animationMode { AnimationMode::None }; PropertyRegistry m_propertyRegistry { *this }; }; } // namespace WebCore