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();
}
Example #2
0
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);
}
Example #7
0
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;
}
Example #8
0
void OfflineDataModel::handleUninstallationFinished( int index )
{
    emit uninstallationFinished( fromSource( index ) );
}
Example #9
0
void OfflineDataModel::handleInstallationFailed( int index, const QString &error )
{
    emit installationFailed( fromSource( index ), error );
}
Example #10
0
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);
}