void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) { ASSERT(resultElement); SVGElement* targetElement = this->targetElement(); if (!targetElement || !isSVGAnimateElement(*resultElement)) return; ASSERT(percentage >= 0 && percentage <= 1); ASSERT(m_animator); ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this)); ASSERT(animatedPropertyType() != AnimatedUnknown); ASSERT(m_fromProperty); ASSERT(m_fromProperty->type() == animatedPropertyType()); ASSERT(m_toProperty); SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement); ASSERT(resultAnimationElement->m_animatedProperty); ASSERT(resultAnimationElement->animatedPropertyType() == animatedPropertyType()); if (isSVGSetElement(*this)) percentage = 1; if (calcMode() == CalcModeDiscrete) percentage = percentage < 0.5 ? 0 : 1; // Target element might have changed. m_animator->setContextElement(targetElement); // Values-animation accumulates using the last values entry corresponding to the end of duration time. SVGPropertyBase* toAtEndOfDurationProperty = m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty.get() : m_toProperty.get(); m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromProperty.get(), m_toProperty.get(), toAtEndOfDurationProperty, resultAnimationElement->m_animatedProperty.get()); }
SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document& document) : SVGAnimationElement(tagName, document) , m_animatedPropertyType(AnimatedString) { ASSERT(isSVGAnimateElement(*this)); ScriptWrappable::init(this); }
void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) { ASSERT(resultElement); SVGElement* targetElement = this->targetElement(); if (!targetElement || !isSVGAnimateElement(*resultElement)) return; ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement)); ASSERT(percentage >= 0 && percentage <= 1); ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); ASSERT(m_animatedPropertyType != AnimatedUnknown); ASSERT(m_animator); ASSERT(m_animator->type() == m_animatedPropertyType); ASSERT(m_fromType); ASSERT(m_fromType->type() == m_animatedPropertyType); ASSERT(m_toType); SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement); ASSERT(resultAnimationElement->m_animatedType); ASSERT(resultAnimationElement->m_animatedPropertyType == m_animatedPropertyType); if (hasTagName(SVGNames::setTag)) percentage = 1; if (calcMode() == CalcModeDiscrete) percentage = percentage < 0.5 ? 0 : 1; // Target element might have changed. m_animator->setContextElement(targetElement); // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do // if after calculateAnimatedValue() ran the cached pointers in the list propery tear // offs would point nowhere, and we couldn't create copies of those values anymore, // while detaching. This is covered by assertions, moving this down would fire them. if (!m_animatedProperties.isEmpty()) m_animator->animValWillChange(m_animatedProperties); // Values-animation accumulates using the last values entry corresponding to the end of duration time. SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get(); m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement->m_animatedType.get()); }
void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to) { unsigned valuesCount = m_values.size(); ASSERT(m_animationValid); ASSERT(valuesCount >= 1); if (percent == 1 || valuesCount == 1) { from = m_values[valuesCount - 1]; to = m_values[valuesCount - 1]; effectivePercent = 1; return; } CalcMode calcMode = this->calcMode(); if (isSVGAnimateElement(*this)) { SVGAnimateElement& animateElement = toSVGAnimateElement(*this); if (!animateElement.animatedPropertyTypeSupportsAddition()) { ASSERT(animateElement.animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this)); ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown); calcMode = CalcModeDiscrete; } } if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) return currentValuesFromKeyPoints(percent, effectivePercent, from, to); unsigned keyTimesCount = m_keyTimes.size(); ASSERT(!keyTimesCount || valuesCount == keyTimesCount); ASSERT(!keyTimesCount || (keyTimesCount > 1 && !m_keyTimes[0])); unsigned index = calculateKeyTimesIndex(percent); if (calcMode == CalcModeDiscrete) { if (!keyTimesCount) index = static_cast<unsigned>(percent * valuesCount); from = m_values[index]; to = m_values[index]; effectivePercent = 0; return; } float fromPercent; float toPercent; if (keyTimesCount) { fromPercent = m_keyTimes[index]; toPercent = m_keyTimes[index + 1]; } else { index = static_cast<unsigned>(floorf(percent * (valuesCount - 1))); fromPercent = static_cast<float>(index) / (valuesCount - 1); toPercent = static_cast<float>(index + 1) / (valuesCount - 1); } if (index == valuesCount - 1) --index; from = m_values[index]; to = m_values[index + 1]; ASSERT(toPercent > fromPercent); effectivePercent = (percent - fromPercent) / (toPercent - fromPercent); if (calcMode == CalcModeSpline) { ASSERT(m_keySplines.size() == m_values.size() - 1); effectivePercent = calculatePercentForSpline(effectivePercent, index); } }
SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document& document) : SVGAnimationElement(tagName, document) { ASSERT(isSVGAnimateElement(*this)); ScriptWrappable::init(this); }