Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp

Issue 1413463008: Web Animations: Migrate SVG path interpolation to interpolation types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp
diff --git a/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp b/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp
similarity index 78%
rename from third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
rename to third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp
index faec714bc5ed886d48b6e0f8590fa8ed31e808e8..7e256b2613591def8380e991d9f263c6dd91f8a2 100644
--- a/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
+++ b/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp
@@ -3,15 +3,44 @@
// found in the LICENSE file.
#include "config.h"
-#include "core/animation/PathSVGInterpolation.h"
+#include "core/animation/SVGPathInterpolationType.h"
+#include "core/animation/InterpolationEnvironment.h"
+#include "core/animation/StringKeyframe.h"
+#include "core/svg/SVGPath.h"
#include "core/svg/SVGPathByteStreamBuilder.h"
#include "core/svg/SVGPathByteStreamSource.h"
#include "core/svg/SVGPathElement.h"
#include "core/svg/SVGPathParser.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace blink {
+class SVGPathNonInterpolableValue : public NonInterpolableValue {
+public:
+ virtual ~SVGPathNonInterpolableValue() {}
+
+ static PassRefPtr<SVGPathNonInterpolableValue> create(Vector<SVGPathSegType>& pathSegTypes)
+ {
+ return adoptRef(new SVGPathNonInterpolableValue(pathSegTypes));
+ }
+
+ const Vector<SVGPathSegType>& pathSegTypes() const { return m_pathSegTypes; }
+
+ DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
+
+private:
+ SVGPathNonInterpolableValue(Vector<SVGPathSegType>& pathSegTypes)
+ {
+ m_pathSegTypes.swap(pathSegTypes);
+ }
+
+ Vector<SVGPathSegType> m_pathSegTypes;
+};
+
+DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGPathNonInterpolableValue);
+DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGPathNonInterpolableValue);
+
namespace {
struct SubPathCoordinates {
@@ -245,11 +274,8 @@ PathSegmentData pathSegCurvetoCubicSmoothFromInterpolableValue(const Interpolabl
return segment;
}
-PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType)
+PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
{
- if (ptrSegType)
- *ptrSegType = segment.command;
-
switch (segment.command) {
case PathSegClosePath:
return pathSegClosePathToInterpolableValue(segment, coordinates);
@@ -388,62 +414,96 @@ size_t countPathCommands(const SVGPathByteStream& path)
return count;
}
+bool canComposite(const InterpolationValue& first, const InterpolationValue& second)
+{
+ const Vector<SVGPathSegType>& firstSegTypes = toSVGPathNonInterpolableValue(first.nonInterpolableValue())->pathSegTypes();
+ const Vector<SVGPathSegType>& secondSegTypes = toSVGPathNonInterpolableValue(second.nonInterpolableValue())->pathSegTypes();
+
+ if (firstSegTypes.size() != secondSegTypes.size()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < firstSegTypes.size(); ++i) {
+ if (toAbsolutePathSegType(firstSegTypes[i]) != toAbsolutePathSegType(secondSegTypes[i]))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace
-PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute)
+void SVGPathInterpolationType::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) const
{
- ASSERT(start->type() == SVGPath::classType());
- ASSERT(end->type() == SVGPath::classType());
+ if (!canComposite(*underlyingValue.get(), value)) {
+ underlyingValue.set(&value);
+ return;
+ }
- const SVGPathByteStream& startPath = static_cast<SVGPath*>(start)->byteStream();
- const SVGPathByteStream& endPath = static_cast<SVGPath*>(end)->byteStream();
+ underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(underlyingFraction, value.interpolableValue());
+}
- if (startPath.size() != endPath.size())
+PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertNeutral(const UnderlyingValue& underlyingValue) const
+{
+ const InterpolationValue* underlying = underlyingValue.get();
+ if (!underlying)
return nullptr;
+ RefPtr<NonInterpolableValue> nonInterpolableValue = const_cast<NonInterpolableValue*>(underlying->nonInterpolableValue());
+ return InterpolationValue::create(*this, underlying->interpolableValue().cloneAndZero(), nonInterpolableValue.release());
+}
- size_t length = countPathCommands(startPath);
-
- SVGPathByteStreamSource startPathSource(startPath);
- SVGPathByteStreamSource endPathSource(endPath);
+PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertSVGValue(const SVGPropertyBase& svgValue) const
+{
+ if (svgValue.type() != AnimatedPath)
+ return nullptr;
- Vector<SVGPathSegType> pathSegTypes(length);
- OwnPtr<InterpolableList> startValue = InterpolableList::create(length);
- OwnPtr<InterpolableList> endValue = InterpolableList::create(length);
- SubPathCoordinates startCoordinates;
- SubPathCoordinates endCoordinates;
- size_t i = 0;
- while (startPathSource.hasMoreData()) {
- if (toAbsolutePathSegType(startPathSource.peekSegmentType()) != toAbsolutePathSegType(endPathSource.peekSegmentType()))
- return nullptr;
+ const SVGPathByteStream& path = toSVGPath(svgValue).byteStream();
- // Like Firefox SMIL, we use the final path seg type.
- const PathSegmentData startSeg = startPathSource.parseSegment();
- startValue->set(i, pathSegToInterpolableValue(startSeg, startCoordinates, nullptr));
+ size_t length = countPathCommands(path);
- const PathSegmentData endSeg = endPathSource.parseSegment();
- endValue->set(i, pathSegToInterpolableValue(endSeg, endCoordinates, &pathSegTypes.at(i)));
+ SVGPathByteStreamSource pathSource(path);
+ Vector<SVGPathSegType> pathSegTypes(length);
+ OwnPtr<InterpolableList> value = InterpolableList::create(length);
+ SubPathCoordinates coordinates;
+ size_t i = 0;
+ while (pathSource.hasMoreData()) {
+ const PathSegmentData segment = pathSource.parseSegment();
+ value->set(i, pathSegToInterpolableValue(segment, coordinates));
+ pathSegTypes[i] = segment.command;
++i;
}
- ASSERT(!endPathSource.hasMoreData());
+ ASSERT(!pathSource.hasMoreData());
ASSERT(i == length);
- return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.release(), attribute, pathSegTypes));
+ return InterpolationValue::create(*this, value.release(), SVGPathNonInterpolableValue::create(pathSegTypes));
+}
+
+PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
+{
+ return maybeConvertSVGValue(environment.svgBaseValue());
}
-PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableValue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes)
+RefPtrWillBeRawPtr<SVGPropertyBase> SVGPathInterpolationType::appliedSVGValue(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue) const
{
RefPtrWillBeRawPtr<SVGPath> result = SVGPath::create();
- InterpolatedPathSource source(toInterpolableList(value), pathSegTypes);
+ InterpolatedPathSource source(toInterpolableList(interpolableValue), toSVGPathNonInterpolableValue(nonInterpolableValue)->pathSegTypes());
SVGPathByteStreamBuilder builder(result->mutableByteStream());
+ // TODO(ericwilligers): We shouldn't be parsing at application time.
fs 2015/11/03 10:03:12 Drive-by note: This is not really a "parsing" oper
SVGPathParser parser(&source, &builder);
parser.parsePathDataFromSource(UnalteredParsing, false);
return result.release();
}
-PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue(SVGElement&) const
+PassOwnPtr<PairwisePrimitiveInterpolation> SVGPathInterpolationType::mergeSingleConversions(InterpolationValue& startValue, InterpolationValue& endValue) const
{
- return fromInterpolableValue(*m_cachedValue, m_pathSegTypes);
-}
+ if (!canComposite(startValue, endValue))
+ return nullptr;
+ return PairwisePrimitiveInterpolation::create(*this,
+ startValue.mutableComponent().interpolableValue.release(),
+ endValue.mutableComponent().interpolableValue.release(),
+ endValue.mutableComponent().nonInterpolableValue.release());
}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698