Ref<BasicShape> BasicShapePath::blend(const BasicShape& from, double progress) const { ASSERT(type() == from.type()); auto& fromPath = downcast<BasicShapePath>(from); auto resultingPathBytes = std::make_unique<SVGPathByteStream>(); buildAnimatedSVGPathByteStream(*fromPath.m_byteStream, *m_byteStream, *resultingPathBytes, progress); auto result = BasicShapePath::create(WTFMove(resultingPathBytes)); result->setWindRule(windRule()); return WTFMove(result); }
void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) { ASSERT(m_animationElement); ASSERT(m_contextElement); SVGPathByteStream* fromPath = from->path(); SVGPathByteStream* toPath = to->path(); SVGPathByteStream* toAtEndOfDurationPath = toAtEndOfDuration->path(); SVGPathByteStream* animatedPath = animated->path(); OwnPtr<SVGPathByteStream> underlyingPath; bool isToAnimation = m_animationElement->animationMode() == ToAnimation; if (isToAnimation) { underlyingPath = animatedPath->copy(); fromPath = underlyingPath.get(); } // Cache the current animated value before the buildAnimatedSVGPathByteStream() clears animatedPath. OwnPtr<SVGPathByteStream> lastAnimatedPath; if (!fromPath->size() || (m_animationElement->isAdditive() && !isToAnimation)) lastAnimatedPath = animatedPath->copy(); // Pass false to 'resizeAnimatedListIfNeeded' here, as the path animation is not a regular Vector<SVGXXX> type, but a SVGPathByteStream, that works differently. if (!m_animationElement->adjustFromToListValues<SVGPathByteStream>(*fromPath, *toPath, *animatedPath, percentage, false)) return; buildAnimatedSVGPathByteStream(fromPath, toPath, animatedPath, percentage); // Handle additive='sum'. if (lastAnimatedPath) addToSVGPathByteStream(animatedPath, lastAnimatedPath.get()); // Handle accumulate='sum'. if (m_animationElement->isAccumulated() && repeatCount) addToSVGPathByteStream(animatedPath, toAtEndOfDurationPath, repeatCount); }