void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); // To animation uses contributions from the lower priority animations as the base value. SVGNumberList& fromNumberList = from->numberList(); SVGNumberList& animatedNumberList = animated->numberList(); if (animationMode == ToAnimation) fromNumberList = animatedNumberList; SVGNumberList& toNumberList = to->numberList(); unsigned itemsCount = fromNumberList.size(); if (itemsCount != toNumberList.size()) { if (percentage < 0.5) { if (animationMode != ToAnimation) animatedNumberList = fromNumberList; } else animatedNumberList = toNumberList; return; } if (itemsCount != animatedNumberList.size()) animatedNumberList.resize(itemsCount); for (unsigned i = 0; i < itemsCount; ++i) SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberList[i], fromNumberList[i], toNumberList[i]); }
void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); // To animation uses contributions from the lower priority animations as the base value. SVGLengthList& fromLengthList = from->lengthList(); SVGLengthList& animatedLengthList = animated->lengthList(); if (animationMode == ToAnimation) fromLengthList = animatedLengthList; // Replace 'inherit' by their computed property values. SVGLengthList& toLengthList = to->lengthList(); if (animationElement->fromPropertyValueType() == InheritValue) { String fromLengthString; animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromLengthString); fromLengthList.parse(fromLengthString, m_lengthMode); } if (animationElement->toPropertyValueType() == InheritValue) { String toLengthString; animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toLengthString); toLengthList.parse(toLengthString, m_lengthMode); } unsigned itemsCount = fromLengthList.size(); if (itemsCount != toLengthList.size()) { if (percentage < 0.5) { if (animationMode != ToAnimation) animatedLengthList = fromLengthList; } else animatedLengthList = toLengthList; return; } bool animatedListSizeEqual = itemsCount == animatedLengthList.size(); if (!animatedListSizeEqual) animatedLengthList.clear(); SVGLengthContext lengthContext(m_contextElement); ExceptionCode ec = 0; for (unsigned i = 0; i < itemsCount; ++i) { float result = animatedListSizeEqual ? animatedLengthList[i].value(lengthContext) : 0; SVGLengthType unitType = percentage < 0.5 ? fromLengthList[i].unitType() : toLengthList[i].unitType(); SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, result, fromLengthList[i].value(lengthContext), toLengthList[i].value(lengthContext)); if (!animatedListSizeEqual) animatedLengthList.append(SVGLength(lengthContext, result, m_lengthMode, unitType)); else { animatedLengthList[i].setValue(lengthContext, result, m_lengthMode, unitType, ec); ASSERT(!ec); } } }
void SVGAnimatedBooleanAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); bool& animateString = animated->boolean(); if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1) animateString = to->boolean(); else animateString = from->boolean(); }
void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); Color& fromColor = from->color(); Color& toColor = to->color(); Color& animatedColor = animated->color(); // To animation uses contributions from the lower priority animations as the base value. if (animationMode == ToAnimation) fromColor = animatedColor; // Replace 'currentColor' / 'inherit' by their computed property values. AnimatedPropertyValueType fromPropertyValueType = animationElement->fromPropertyValueType(); if (fromPropertyValueType == CurrentColorValue) animationElement->adjustForCurrentColor(m_contextElement, fromColor); else if (fromPropertyValueType == InheritValue) { String fromColorString; animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromColorString); fromColor = SVGColor::colorFromRGBColorString(fromColorString); } AnimatedPropertyValueType toPropertyValueType = animationElement->toPropertyValueType(); if (toPropertyValueType == CurrentColorValue) animationElement->adjustForCurrentColor(m_contextElement, toColor); else if (toPropertyValueType == InheritValue) { String toColorString; animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toColorString); toColor = SVGColor::colorFromRGBColorString(toColorString); } Color color; if (animationElement->calcMode() == CalcModeDiscrete) color = percentage < 0.5 ? fromColor : toColor; else color = ColorDistance(fromColor, toColor).scaledDistance(percentage).addToColorAndClamp(fromColor); // FIXME: Accumulate colors. if (animationElement->isAdditive() && animationMode != ToAnimation) animatedColor = ColorDistance::addColorsAndClamp(animatedColor, color); else animatedColor = color; return; }
void SVGAnimatedIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); // To animation uses contributions from the lower priority animations as the base value. int& animatedInt = animated->integer(); if (animationMode == ToAnimation) from->integer() = animatedInt; float result = animatedInt; SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, result, from->integer(), to->integer()); animatedInt = static_cast<int>(roundf(result)); }
void SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); // To animation uses contributions from the lower priority animations as the base value. pair<float, float>& fromNumberPair = from->numberOptionalNumber(); pair<float, float>& animatedNumberPair = animated->numberOptionalNumber(); if (animationMode == ToAnimation) fromNumberPair = animatedNumberPair; pair<float, float>& toNumberPair = to->numberOptionalNumber(); SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberPair.first, fromNumberPair.first, toNumberPair.first); SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberPair.second, fromNumberPair.second, toNumberPair.second); }
void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); SVGPathByteStream* toPath = to->path(); ASSERT(toPath); SVGPathByteStream* fromPath = from->path(); ASSERT(fromPath); SVGPathByteStream* animatedPath = animated->path(); ASSERT(animatedPath); if (animationMode == ToAnimation) fromPath->initializeFrom(animatedPath); if (!percentage) { animatedPath->initializeFrom(fromPath); return; } if (percentage == 1) { animatedPath->initializeFrom(toPath); return; } OwnPtr<SVGPathByteStream> newAnimatedPath = adoptPtr(animatedPath); bool success = SVGPathParserFactory::self()->buildAnimatedSVGPathByteStream(fromPath, toPath, newAnimatedPath, percentage); animatedPath = newAnimatedPath.leakPtr(); if (success) return; if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation) animatedPath->initializeFrom(toPath); else animatedPath->initializeFrom(fromPath); }
void SVGAnimatedPathAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString) { ASSERT(m_contextElement); ASSERT(m_animationElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); bool success = false; to = constructFromString(toString, success); // For to-animations the from number is calculated later. if (!success || animationMode == ToAnimation) { from = SVGAnimatedType::createPath(SVGPathByteStream::create()); return; } from = constructFromString(fromString, success); if (success) return; from = SVGAnimatedType::createPath(SVGPathByteStream::create()); }
void SVGAnimatedRectAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement); AnimationMode animationMode = animationElement->animationMode(); // To animation uses contributions from the lower priority animations as the base value. FloatRect& animatedRect = animated->rect(); if (animationMode == ToAnimation) from->rect() = animatedRect; const FloatRect& fromRect = from->rect(); const FloatRect& toRect = to->rect(); FloatRect newRect; if (animationElement->calcMode() == CalcModeDiscrete) newRect = percentage < 0.5 ? fromRect : toRect; else newRect = FloatRect((toRect.x() - fromRect.x()) * percentage + fromRect.x(), (toRect.y() - fromRect.y()) * percentage + fromRect.y(), (toRect.width() - fromRect.width()) * percentage + fromRect.width(), (toRect.height() - fromRect.height()) * percentage + fromRect.height()); // FIXME: This is not correct for values animation. Right now we transform values-animation to multiple from-to-animations and // accumulate every single value to the previous one. But accumulation should just take into account after a complete cycle // of values-animaiton. See example at: http://www.w3.org/TR/2001/REC-smil-animation-20010904/#RepeatingAnim if (animationElement->isAccumulated() && repeatCount) { newRect += toRect; newRect.scale(repeatCount); } if (animationElement->isAdditive() && animationMode != ToAnimation) animatedRect += newRect; else animatedRect = newRect; }