Commit 3bb121da authored by fs's avatar fs Committed by Commit bot

SVGPath object "mutability" cleanup

Move addToSVGPathByteStream to SVGPath.cpp (the only place using it),
rename it to addPathByteStreams. Move the "regular" blending out into a
helper(blendPathByteStreams), and eliminate the redundant copy. Make the
functions more "functional" (return the result.)

Add a (private) setter for byte-stream data and use that to ensure
invalidation of the cached path. Also add an SVGPath::create(...)
accepting a SVGPathByteStream and use that in PathSVGInterpolation.

Inline mutableByteStream into the remaining user.

Review URL: https://codereview.chromium.org/1460253002

Cr-Commit-Position: refs/heads/master@{#361128}
parent 72ee18e7
...@@ -433,12 +433,12 @@ PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa ...@@ -433,12 +433,12 @@ PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa
PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableValue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes) PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableValue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes)
{ {
RefPtrWillBeRawPtr<SVGPath> result = SVGPath::create(); OwnPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create();
InterpolatedPathSource source(toInterpolableList(value), pathSegTypes); InterpolatedPathSource source(toInterpolableList(value), pathSegTypes);
SVGPathByteStreamBuilder builder(result->mutableByteStream()); SVGPathByteStreamBuilder builder(*pathByteStream);
SVGPathParser parser(&source, &builder); SVGPathParser parser(&source, &builder);
parser.parsePathDataFromSource(UnalteredParsing, false); parser.parsePathDataFromSource(UnalteredParsing, false);
return result.release(); return SVGPath::create(pathByteStream.release());
} }
PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue(SVGElement&) const PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue(SVGElement&) const
......
...@@ -36,6 +36,35 @@ ...@@ -36,6 +36,35 @@
namespace blink { namespace blink {
namespace {
PassOwnPtr<SVGPathByteStream> blendPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, float progress)
{
OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create();
SVGPathByteStreamBuilder builder(*resultStream);
SVGPathByteStreamSource fromSource(fromStream);
SVGPathByteStreamSource toSource(toStream);
SVGPathBlender blender(&fromSource, &toSource, &builder);
blender.blendAnimatedPath(progress);
return resultStream.release();
}
PassOwnPtr<SVGPathByteStream> addPathByteStreams(PassOwnPtr<SVGPathByteStream> fromStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1)
{
if (fromStream->isEmpty() || byStream.isEmpty())
return fromStream;
OwnPtr<SVGPathByteStream> tempFromStream = fromStream;
OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create();
SVGPathByteStreamBuilder builder(*resultStream);
SVGPathByteStreamSource fromSource(*tempFromStream);
SVGPathByteStreamSource bySource(byStream);
SVGPathBlender blender(&fromSource, &bySource, &builder);
blender.addAnimatedPath(repeatCount);
return resultStream.release();
}
}
SVGPath::SVGPath() SVGPath::SVGPath()
: SVGPropertyBase(classType()) : SVGPropertyBase(classType())
{ {
...@@ -63,7 +92,7 @@ const Path& SVGPath::path() const ...@@ -63,7 +92,7 @@ const Path& SVGPath::path() const
PassRefPtrWillBeRawPtr<SVGPath> SVGPath::clone() const PassRefPtrWillBeRawPtr<SVGPath> SVGPath::clone() const
{ {
return adoptRefWillBeNoop(new SVGPath(byteStream().copy())); return SVGPath::create(byteStream().copy());
} }
PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPath::cloneForAnimation(const String& value) const PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPath::cloneForAnimation(const String& value) const
...@@ -81,7 +110,7 @@ SVGPathByteStream& SVGPath::ensureByteStream() ...@@ -81,7 +110,7 @@ SVGPathByteStream& SVGPath::ensureByteStream()
return *m_byteStream.get(); return *m_byteStream.get();
} }
void SVGPath::byteStreamWillChange() void SVGPath::byteStreamChanged()
{ {
m_cachedPath.clear(); m_cachedPath.clear();
} }
...@@ -91,12 +120,6 @@ const SVGPathByteStream& SVGPath::byteStream() const ...@@ -91,12 +120,6 @@ const SVGPathByteStream& SVGPath::byteStream() const
return const_cast<SVGPath*>(this)->ensureByteStream(); return const_cast<SVGPath*>(this)->ensureByteStream();
} }
SVGPathByteStream& SVGPath::mutableByteStream()
{
byteStreamWillChange();
return ensureByteStream();
}
String SVGPath::valueAsString() const String SVGPath::valueAsString() const
{ {
String string; String string;
...@@ -106,17 +129,24 @@ String SVGPath::valueAsString() const ...@@ -106,17 +129,24 @@ String SVGPath::valueAsString() const
void SVGPath::setValueAsString(const String& string, ExceptionState& exceptionState) void SVGPath::setValueAsString(const String& string, ExceptionState& exceptionState)
{ {
if (!buildSVGPathByteStreamFromString(string, mutableByteStream(), UnalteredParsing)) if (!buildSVGPathByteStreamFromString(string, ensureByteStream(), UnalteredParsing))
exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\""); exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\"");
byteStreamChanged();
}
void SVGPath::setValueAsByteStream(PassOwnPtr<SVGPathByteStream> byteStream)
{
m_byteStream = byteStream;
byteStreamChanged();
} }
void SVGPath::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*) void SVGPath::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
{ {
RefPtrWillBeRawPtr<SVGPath> otherList = toSVGPath(other); const SVGPathByteStream& otherPathByteStream = toSVGPath(other)->byteStream();
if (byteStream().size() != otherList->byteStream().size()) if (byteStream().size() != otherPathByteStream.size())
return; return;
addToSVGPathByteStream(mutableByteStream(), otherList->byteStream()); setValueAsByteStream(addPathByteStreams(m_byteStream.release(), otherPathByteStream));
} }
void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
...@@ -124,56 +154,47 @@ void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, floa ...@@ -124,56 +154,47 @@ void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, floa
ASSERT(animationElement); ASSERT(animationElement);
bool isToAnimation = animationElement->animationMode() == ToAnimation; bool isToAnimation = animationElement->animationMode() == ToAnimation;
const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue);
const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue); const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue);
const RefPtrWillBeRawPtr<SVGPath> toAtEndOfDuration = toSVGPath(toAtEndOfDurationValue);
const SVGPathByteStream& toStream = to->byteStream(); const SVGPathByteStream& toStream = to->byteStream();
const SVGPathByteStream* fromStream = &from->byteStream();
OwnPtr<SVGPathByteStream> copy;
// If no 'to' value is given, nothing to animate. // If no 'to' value is given, nothing to animate.
if (!toStream.size()) if (!toStream.size())
return; return;
const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue);
const SVGPathByteStream* fromStream = &from->byteStream();
OwnPtr<SVGPathByteStream> copy;
if (isToAnimation) { if (isToAnimation) {
copy = byteStream().copy(); copy = byteStream().copy();
fromStream = copy.get(); fromStream = copy.get();
} }
byteStreamWillChange();
// If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. // 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 (fromStream->size() != toStream.size() && fromStream->size()) {
if (percentage < 0.5) { if (percentage < 0.5) {
if (!isToAnimation) { if (!isToAnimation) {
m_byteStream = fromStream->copy(); setValueAsByteStream(fromStream->copy());
return; return;
} }
} else { } else {
m_byteStream = toStream.copy(); setValueAsByteStream(toStream.copy());
return; return;
} }
} }
OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release(); OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release();
OwnPtr<SVGPathByteStream> newStream = blendPathByteStreams(*fromStream, toStream, percentage);
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'. // Handle additive='sum'.
if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation)) if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation))
addToSVGPathByteStream(*m_byteStream, *lastAnimatedStream); newStream = addPathByteStreams(newStream.release(), *lastAnimatedStream);
// Handle accumulate='sum'. // Handle accumulate='sum'.
if (animationElement->isAccumulated() && repeatCount) if (animationElement->isAccumulated() && repeatCount)
addToSVGPathByteStream(*m_byteStream, toAtEndOfDuration->byteStream(), repeatCount); newStream = addPathByteStreams(newStream.release(), toSVGPath(toAtEndOfDurationValue)->byteStream(), repeatCount);
setValueAsByteStream(newStream.release());
} }
float SVGPath::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> to, SVGElement*) float SVGPath::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> to, SVGElement*)
......
...@@ -47,13 +47,16 @@ public: ...@@ -47,13 +47,16 @@ public:
{ {
return adoptRefWillBeNoop(new SVGPath()); return adoptRefWillBeNoop(new SVGPath());
} }
static PassRefPtrWillBeRawPtr<SVGPath> create(PassOwnPtr<SVGPathByteStream> pathByteStream)
{
return adoptRefWillBeNoop(new SVGPath(pathByteStream));
}
~SVGPath() override; ~SVGPath() override;
const Path& path() const; const Path& path() const;
const SVGPathByteStream& byteStream() const; const SVGPathByteStream& byteStream() const;
SVGPathByteStream& mutableByteStream();
// SVGPropertyBase: // SVGPropertyBase:
PassRefPtrWillBeRawPtr<SVGPath> clone() const; PassRefPtrWillBeRawPtr<SVGPath> clone() const;
...@@ -72,7 +75,8 @@ private: ...@@ -72,7 +75,8 @@ private:
explicit SVGPath(PassOwnPtr<SVGPathByteStream>); explicit SVGPath(PassOwnPtr<SVGPathByteStream>);
SVGPathByteStream& ensureByteStream(); SVGPathByteStream& ensureByteStream();
void byteStreamWillChange(); void byteStreamChanged();
void setValueAsByteStream(PassOwnPtr<SVGPathByteStream>);
OwnPtr<SVGPathByteStream> m_byteStream; OwnPtr<SVGPathByteStream> m_byteStream;
mutable OwnPtr<Path> m_cachedPath; mutable OwnPtr<Path> m_cachedPath;
......
...@@ -20,11 +20,9 @@ ...@@ -20,11 +20,9 @@
#include "config.h" #include "config.h"
#include "core/svg/SVGPathUtilities.h" #include "core/svg/SVGPathUtilities.h"
#include "core/svg/SVGPathBlender.h"
#include "core/svg/SVGPathBuilder.h" #include "core/svg/SVGPathBuilder.h"
#include "core/svg/SVGPathByteStreamBuilder.h" #include "core/svg/SVGPathByteStreamBuilder.h"
#include "core/svg/SVGPathByteStreamSource.h" #include "core/svg/SVGPathByteStreamSource.h"
#include "core/svg/SVGPathElement.h"
#include "core/svg/SVGPathParser.h" #include "core/svg/SVGPathParser.h"
#include "core/svg/SVGPathStringBuilder.h" #include "core/svg/SVGPathStringBuilder.h"
#include "core/svg/SVGPathStringSource.h" #include "core/svg/SVGPathStringSource.h"
...@@ -85,21 +83,6 @@ bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result ...@@ -85,21 +83,6 @@ bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result
return ok; return ok;
} }
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);
}
unsigned getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length) unsigned getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length)
{ {
if (stream.isEmpty()) if (stream.isEmpty())
......
...@@ -40,8 +40,6 @@ bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream&, PathPar ...@@ -40,8 +40,6 @@ bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream&, PathPar
// SVGPathByteStream -> String // SVGPathByteStream -> String
bool buildStringFromByteStream(const SVGPathByteStream&, String&, PathParsingMode); bool buildStringFromByteStream(const SVGPathByteStream&, String&, PathParsingMode);
bool addToSVGPathByteStream(SVGPathByteStream&, const SVGPathByteStream&, unsigned repeatCount = 1);
unsigned getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream&, float length); unsigned getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream&, float length);
float getTotalLengthOfSVGPathByteStream(const SVGPathByteStream&); float getTotalLengthOfSVGPathByteStream(const SVGPathByteStream&);
FloatPoint getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream&, float length); FloatPoint getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream&, float length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment