void SVGPath::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
{
    RefPtrWillBeRawPtr<SVGPath> otherList = toSVGPath(other);
    if (byteStream().size() != otherList->byteStream().size())
        return;

    addToSVGPathByteStream(mutableByteStream(), otherList->byteStream());
}
void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
{
    ASSERT(animationElement);
    bool isToAnimation = animationElement->animationMode() == ToAnimation;

    const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue);
    const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue);
    const RefPtrWillBeRawPtr<SVGPath> toAtEndOfDuration = toSVGPath(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(*m_byteStream);

    SVGPathByteStreamSource fromSource(*fromStream);
    SVGPathByteStreamSource toSource(toStream);

    SVGPathBlender blender(&fromSource, &toSource, &builder);
    blender.blendAnimatedPath(percentage);

    // Handle additive='sum'.
    if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation))
        addToSVGPathByteStream(*m_byteStream, *lastAnimatedStream);

    // Handle accumulate='sum'.
    if (animationElement->isAccumulated() && repeatCount)
        addToSVGPathByteStream(*m_byteStream, toAtEndOfDuration->byteStream(), repeatCount);
}
Exemple #3
0
void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
{
    ASSERT(animationElement);
    bool isToAnimation = animationElement->animationMode() == ToAnimation;

    const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue);
    const SVGPathByteStream& toStream = to->byteStream();

    // If no 'to' value is given, nothing to animate.
    if (!toStream.size())
        return;

    const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue);
    const SVGPathByteStream* fromStream = &from->byteStream();

    RefPtr<SVGPathByteStream> copy;
    if (isToAnimation) {
        copy = byteStream().clone();
        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_pathValue = from->pathValue();
                return;
            }
        } else {
            m_pathValue = to->pathValue();
            return;
        }
    }

    RefPtr<SVGPathByteStream> newStream = blendPathByteStreams(*fromStream, toStream, percentage);

    // Handle additive='sum'.
    if (animationElement->isAdditive() && !isToAnimation)
        newStream = conditionallyAddPathByteStreams(newStream.release(), byteStream());

    // Handle accumulate='sum'.
    if (animationElement->isAccumulated() && repeatCount)
        newStream = conditionallyAddPathByteStreams(newStream.release(), toSVGPath(toAtEndOfDurationValue)->byteStream(), repeatCount);

    m_pathValue = CSSPathValue::create(newStream.release());
}