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);
}
PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertSVGValue(const SVGPropertyBase& svgValue) const
{
    if (svgValue.type() != AnimatedPath)
        return nullptr;

    SVGPathByteStreamSource pathSource(toSVGPath(svgValue).byteStream());
    size_t length = 0;
    PathCoordinates currentCoordinates;
    Vector<OwnPtr<InterpolableValue>> interpolablePathSegs;
    Vector<SVGPathSegType> pathSegTypes;

    while (pathSource.hasMoreData()) {
        const PathSegmentData segment = pathSource.parseSegment();
        interpolablePathSegs.append(SVGPathSegInterpolationFunctions::consumePathSeg(segment, currentCoordinates));
        pathSegTypes.append(segment.command);
        length++;
    }

    OwnPtr<InterpolableList> pathArgs = InterpolableList::create(length);
    for (size_t i = 0; i < interpolablePathSegs.size(); i++)
        pathArgs->set(i, interpolablePathSegs[i].release());

    OwnPtr<InterpolableList> result = InterpolableList::create(PathComponentIndexCount);
    result->set(PathArgsIndex, pathArgs.release());
    result->set(PathNeutralIndex, InterpolableNumber::create(0));

    return InterpolationValue::create(*this, result.release(), SVGPathNonInterpolableValue::create(pathSegTypes));
}
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, RawPtr<SVGPropertyBase> fromValue, RawPtr<SVGPropertyBase> toValue, RawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
{
    ASSERT(animationElement);
    bool isToAnimation = animationElement->getAnimationMode() == ToAnimation;

    const SVGPath& to = toSVGPath(*toValue);
    const SVGPathByteStream& toStream = to.byteStream();

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

    const SVGPath& from = toSVGPath(*fromValue);
    const SVGPathByteStream* fromStream = &from.byteStream();

    OwnPtr<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;
        }
    }

    OwnPtr<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());
}
Exemplo n.º 5
0
InterpolationValue SVGPathInterpolationType::maybeConvertSVGValue(
    const SVGPropertyBase& svgValue) const {
  if (svgValue.type() != AnimatedPath)
    return nullptr;

  return PathInterpolationFunctions::convertValue(
      toSVGPath(svgValue).byteStream());
}
void SVGPath::add(RawPtr<SVGPropertyBase> other, SVGElement*)
{
    const SVGPathByteStream& otherPathByteStream = toSVGPath(other)->byteStream();
    if (byteStream().size() != otherPathByteStream.size()
        || byteStream().isEmpty()
        || otherPathByteStream.isEmpty())
        return;

    m_pathValue = CSSPathValue::create(addPathByteStreams(byteStream(), otherPathByteStream));
}