bool AnimatablePath::usesDefaultInterpolationWith(const AnimatableValue* value) const { // Default interpolation is used if the paths have different lengths, // or the paths have a segment with different types (ignoring "relativeness"). const StylePath* toPath = toAnimatablePath(value)->path(); if (!m_path || !toPath) return true; SVGPathByteStreamSource fromSource(path()->byteStream()); SVGPathByteStreamSource toSource(toPath->byteStream()); while (fromSource.hasMoreData()) { if (!toSource.hasMoreData()) return true; PathSegmentData fromSeg = fromSource.parseSegment(); PathSegmentData toSeg = toSource.parseSegment(); ASSERT(fromSeg.command != PathSegUnknown); ASSERT(toSeg.command != PathSegUnknown); if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType(toSeg.command)) return true; } return toSource.hasMoreData(); }
void SVGPathSegList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) { invalidateList(); ASSERT(animationElement); bool isToAnimation = animationElement->animationMode() == ToAnimation; const RefPtr<SVGPathSegList> from = toSVGPathSegList(fromValue); const RefPtr<SVGPathSegList> to = toSVGPathSegList(toValue); const RefPtr<SVGPathSegList> toAtEndOfDuration = toSVGPathSegList(toAtEndOfDurationValue); const SVGPathByteStream* toStream = to->byteStream(); const SVGPathByteStream* fromStream = from->byteStream(); OwnPtr<SVGPathByteStream> copy; // If no 'to' value is given, nothing to animate. if (!toStream->size()) return; if (isToAnimation) { copy = byteStream()->copy(); fromStream = copy.get(); } // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. if (fromStream->size() != toStream->size() && fromStream->size()) { if (percentage < 0.5) { if (!isToAnimation) { m_byteStream = fromStream->copy(); return; } } else { m_byteStream = toStream->copy(); return; } } OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release(); m_byteStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder; builder.setCurrentByteStream(m_byteStream.get()); SVGPathByteStreamSource fromSource(fromStream); SVGPathByteStreamSource toSource(toStream); SVGPathBlender blender; blender.blendAnimatedPath(percentage, &fromSource, &toSource, &builder); // Handle additive='sum'. if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation)) addToSVGPathByteStream(m_byteStream.get(), lastAnimatedStream.get()); // Handle accumulate='sum'. if (animationElement->isAccumulated() && repeatCount) { const SVGPathByteStream* toAtEndOfDurationStream = toAtEndOfDuration->byteStream(); addToSVGPathByteStream(m_byteStream.get(), toAtEndOfDurationStream, repeatCount); } }
bool buildAnimatedSVGPathByteStream(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, SVGPathByteStream& result, float progress) { ASSERT(&toStream != &result); result.clear(); if (toStream.isEmpty()) return true; SVGPathByteStreamBuilder builder(result); SVGPathByteStreamSource fromSource(fromStream); SVGPathByteStreamSource toSource(toStream); return SVGPathBlender::blendAnimatedPath(fromSource, toSource, builder, progress); }
bool addToSVGPathByteStream(SVGPathByteStream& fromStream, const SVGPathByteStream& byStream, unsigned repeatCount) { if (fromStream.isEmpty() || byStream.isEmpty()) return true; OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream.copy(); fromStream.clear(); SVGPathByteStreamBuilder builder(fromStream); SVGPathByteStreamSource fromSource(*fromStreamCopy); SVGPathByteStreamSource bySource(byStream); SVGPathBlender blender(&fromSource, &bySource, &builder); return blender.addAnimatedPath(repeatCount); }
PassRefPtr<AnimatableValue> AnimatablePath::interpolateTo(const AnimatableValue* value, double fraction) const { if (usesDefaultInterpolationWith(value)) return defaultInterpolateTo(this, value, fraction); std::unique_ptr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*byteStream); SVGPathByteStreamSource fromSource(path()->byteStream()); SVGPathByteStreamSource toSource(toAnimatablePath(value)->path()->byteStream()); SVGPathBlender blender(&fromSource, &toSource, &builder); bool ok = blender.blendAnimatedPath(fraction); ASSERT_UNUSED(ok, ok); return AnimatablePath::create(StylePath::create(std::move(byteStream))); }
bool addToSVGPathByteStream(SVGPathByteStream& streamToAppendTo, const SVGPathByteStream& byStream, unsigned repeatCount) { // Why return when streamToAppendTo is empty? Don't we still need to append? if (streamToAppendTo.isEmpty() || byStream.isEmpty()) return true; // Is it OK to make the SVGPathByteStreamBuilder from a stream, and then clear that stream? SVGPathByteStreamBuilder builder(streamToAppendTo); SVGPathByteStream fromStreamCopy = streamToAppendTo; streamToAppendTo.clear(); SVGPathByteStreamSource fromSource(fromStreamCopy); SVGPathByteStreamSource bySource(byStream); return SVGPathBlender::addAnimatedPath(fromSource, bySource, builder, repeatCount); }
bool addToSVGPathByteStream(SVGPathByteStream* fromStream, const SVGPathByteStream* byStream, unsigned repeatCount) { ASSERT(fromStream); ASSERT(byStream); if (fromStream->isEmpty() || byStream->isEmpty()) return true; SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(fromStream); OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream->copy(); fromStream->clear(); SVGPathByteStreamSource fromSource(fromStreamCopy.get()); SVGPathByteStreamSource bySource(byStream); SVGPathBlender* blender = globalSVGPathBlender(); bool ok = blender->addAnimatedPath(&fromSource, &bySource, builder, repeatCount); blender->cleanup(); return ok; }
void OfflineDataModel::handleUninstallationFinished( int index ) { emit uninstallationFinished( fromSource( index ) ); }
void OfflineDataModel::handleInstallationFailed( int index, const QString &error ) { emit installationFailed( fromSource( index ), error ); }
void OfflineDataModel::handleInstallationProgress( int index, qreal progress ) { emit installationProgressed( fromSource( index ), progress ); }
bool canBlendSVGPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream) { SVGPathByteStreamSource fromSource(fromStream); SVGPathByteStreamSource toSource(toStream); return SVGPathBlender::canBlendPaths(fromSource, toSource); }