예제 #1
0
void SVGAnimatedPathAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
{
    ASSERT(from->type() == AnimatedPath);
    ASSERT(from->type() == to->type());

    SVGPathByteStream* fromPath = from->path();
    SVGPathByteStream* toPath = to->path();
    unsigned fromPathSize = fromPath->size();
    if (!fromPathSize || fromPathSize != toPath->size())
        return;
    addToSVGPathByteStream(toPath, fromPath);
}
예제 #2
0
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);
}
bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result, PathParsingMode parsingMode)
{
    result.clear();
    if (d.isEmpty())
        return true;

    // The string length is typically a minor overestimate of eventual byte stream size, so it avoids us a lot of reallocs.
    result.reserveInitialCapacity(d.length());

    SVGPathByteStreamBuilder builder(result);
    SVGPathStringSource source(d);
    SVGPathParser parser(&source, &builder);
    bool ok = parser.parsePathDataFromSource(parsingMode);
    result.shrinkToFit();
    return ok;
}
예제 #5
0
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);
}
예제 #6
0
bool buildStringFromByteStream(const SVGPathByteStream& stream, String& result, PathParsingMode parsingMode)
{
    if (stream.isEmpty())
        return true;

    SVGPathByteStreamSource source(stream);
    return SVGPathParser::parseToString(source, result, parsingMode);
}
예제 #7
0
bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result, PathParsingMode parsingMode)
{
    result.clear();
    if (d.isEmpty())
        return true;

    SVGPathStringSource source(d);
    return SVGPathParser::parseToByteStream(source, result, parsingMode);
}
예제 #8
0
bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream& result, PathParsingMode parsingMode)
{
    result.clear();
    if (list.isEmpty())
        return true;

    SVGPathSegListSource source(list);
    return SVGPathParser::parseToByteStream(source, result, parsingMode);
}
예제 #9
0
bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
{
    if (stream.isEmpty())
        return true;

    SVGPathBuilder builder(result);
    SVGPathByteStreamSource source(stream);
    return SVGPathParser::parse(source, builder);
}
예제 #10
0
bool buildSVGPathSegListFromByteStream(const SVGPathByteStream& stream, SVGPathElement& element, SVGPathSegList& result, PathParsingMode parsingMode)
{
    if (stream.isEmpty())
        return true;

    SVGPathSegListBuilder builder(element, result, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole);
    SVGPathByteStreamSource source(stream);
    return SVGPathParser::parse(source, builder, parsingMode);
}
bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
{
    if (stream.isEmpty())
        return true;

    SVGPathBuilder builder(result);
    SVGPathByteStreamSource source(stream);
    SVGPathParser parser(&source, &builder);
    return parser.parsePathDataFromSource(NormalizedParsing);
}
FloatPoint getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float length)
{
    if (stream.isEmpty())
        return FloatPoint();

    SVGPathTraversalStateBuilder builder(PathTraversalState::TraversalPointAtLength, length);
    SVGPathByteStreamSource source(stream);
    SVGPathParser parser(&source, &builder);
    parser.parsePathDataFromSource(NormalizedParsing);
    return builder.currentPoint();
}
float getTotalLengthOfSVGPathByteStream(const SVGPathByteStream& stream)
{
    if (stream.isEmpty())
        return 0;

    SVGPathTraversalStateBuilder builder(PathTraversalState::TraversalTotalLength);
    SVGPathByteStreamSource source(stream);
    SVGPathParser parser(&source, &builder);
    parser.parsePathDataFromSource(NormalizedParsing);
    return builder.totalLength();
}
unsigned getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length)
{
    if (stream.isEmpty())
        return 0;

    SVGPathTraversalStateBuilder builder(PathTraversalState::TraversalSegmentAtLength, length);
    SVGPathByteStreamSource source(stream);
    SVGPathParser parser(&source, &builder);
    parser.parsePathDataFromSource(NormalizedParsing);
    return builder.pathSegmentIndex();
}
bool buildStringFromByteStream(const SVGPathByteStream& stream, String& result, PathParsingMode parsingMode)
{
    if (stream.isEmpty())
        return true;

    SVGPathStringBuilder builder;
    SVGPathByteStreamSource source(stream);
    SVGPathParser parser(&source, &builder);
    bool ok = parser.parsePathDataFromSource(parsingMode);
    result = builder.result();
    return ok;
}
예제 #16
0
bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length, unsigned& pathSeg)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::SegmentAtLength);
    SVGPathTraversalStateBuilder builder(traversalState, length);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    pathSeg = builder.pathSegmentIndex();
    return ok;
}
예제 #17
0
bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float& totalLength)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::TotalLength);

    SVGPathTraversalStateBuilder builder(traversalState);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    totalLength = builder.totalLength();
    return ok;
}
예제 #18
0
bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float length, SVGPoint& point)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength);

    SVGPathTraversalStateBuilder builder(traversalState, length);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    point = builder.currentPoint();
    return ok;
}
예제 #19
0
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);
}
예제 #20
0
bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPathByteStream& result, PathParsingMode parsingMode)
{
    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
    ASSERT(parsingMode == UnalteredParsing);

    SVGPathSegList appendedItemList(PathSegUnalteredRole);
    appendedItemList.append(WTFMove(pathSeg));

    SVGPathByteStream appendedByteStream;
    SVGPathSegListSource source(appendedItemList);
    bool ok = SVGPathParser::parseToByteStream(source, result, parsingMode, false);

    if (ok)
        result.append(appendedByteStream);

    return ok;
}
예제 #21
0
void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
{
    ASSERT(m_animationElement);
    ASSERT(m_contextElement);

    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
    AnimationMode animationMode = animationElement->animationMode();

    SVGPathByteStream* toPath = to->path();
    ASSERT(toPath);

    SVGPathByteStream* fromPath = from->path();
    ASSERT(fromPath);

    SVGPathByteStream* animatedPath = animated->path();
    ASSERT(animatedPath);

    if (animationMode == ToAnimation)
        fromPath->initializeFrom(animatedPath);

    if (!percentage) {
        animatedPath->initializeFrom(fromPath);
        return;
    }

    if (percentage == 1) {
        animatedPath->initializeFrom(toPath);
        return;
    }

    OwnPtr<SVGPathByteStream> newAnimatedPath = adoptPtr(animatedPath);
    bool success = SVGPathParserFactory::self()->buildAnimatedSVGPathByteStream(fromPath, toPath, newAnimatedPath, percentage);
    animatedPath = newAnimatedPath.leakPtr();
    if (success)
        return;

    if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation)
        animatedPath->initializeFrom(toPath);
    else
        animatedPath->initializeFrom(fromPath);
}