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

Unified Diff: third_party/WebKit/Source/core/animation/PathSVGInterpolation.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/PathSVGInterpolation.cpp
diff --git a/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp b/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
deleted file mode 100644
index faec714bc5ed886d48b6e0f8590fa8ed31e808e8..0000000000000000000000000000000000000000
--- a/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "config.h"
-#include "core/animation/PathSVGInterpolation.h"
-
-#include "core/svg/SVGPathByteStreamBuilder.h"
-#include "core/svg/SVGPathByteStreamSource.h"
-#include "core/svg/SVGPathElement.h"
-#include "core/svg/SVGPathParser.h"
-
-namespace blink {
-
-namespace {
-
-struct SubPathCoordinates {
- double initialX = 0;
- double initialY = 0;
- double currentX = 0;
- double currentY = 0;
-};
-
-PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isAbsolute, double currentValue)
-{
- if (isAbsolute)
- return InterpolableNumber::create(value);
- return InterpolableNumber::create(currentValue + value);
-}
-
-double controlFromInterpolableValue(const InterpolableValue* number, bool isAbsolute, double currentValue)
-{
- double value = toInterpolableNumber(number)->value();
-
- if (isAbsolute)
- return value;
- return value - currentValue;
-}
-
-PassOwnPtr<InterpolableNumber> specifiedToInterpolableValue(double value, bool isAbsolute, double& currentValue)
-{
- if (isAbsolute)
- currentValue = value;
- else
- currentValue += value;
- return InterpolableNumber::create(currentValue);
-}
-
-double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAbsolute, double& currentValue)
-{
- double previousValue = currentValue;
- currentValue = toInterpolableNumber(number)->value();
-
- if (isAbsolute)
- return currentValue;
- return currentValue - previousValue;
-}
-
-PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const PathSegmentData&, SubPathCoordinates& coordinates)
-{
- coordinates.currentX = coordinates.initialX;
- coordinates.currentY = coordinates.initialY;
-
- // arbitrary
- return InterpolableBool::create(false);
-}
-
-PathSegmentData pathSegClosePathFromInterpolableValue(const InterpolableValue&, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- coordinates.currentX = coordinates.initialX;
- coordinates.currentY = coordinates.initialY;
-
- PathSegmentData segment;
- segment.command = segType;
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- OwnPtr<InterpolableList> result = InterpolableList::create(2);
- result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
- result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
-
- if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) {
- // Any upcoming 'closepath' commands bring us back to the location we have just moved to.
- coordinates.initialX = coordinates.currentX;
- coordinates.initialY = coordinates.currentY;
- }
-
- return result.release();
-}
-
-PathSegmentData pathSegSingleCoordinateFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- const InterpolableList& list = toInterpolableList(value);
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX));
- segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY));
-
- if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) {
- // Any upcoming 'closepath' commands bring us back to the location we have just moved to.
- coordinates.initialX = coordinates.currentX;
- coordinates.initialY = coordinates.currentY;
- }
-
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- OwnPtr<InterpolableList> result = InterpolableList::create(6);
- result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordinates.currentX));
- result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordinates.currentY));
- result->set(2, controlToInterpolableValue(segment.x2(), isAbsolute, coordinates.currentX));
- result->set(3, controlToInterpolableValue(segment.y2(), isAbsolute, coordinates.currentY));
- result->set(4, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
- result->set(5, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
- return result.release();
-}
-
-PathSegmentData pathSegCurvetoCubicFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- const InterpolableList& list = toInterpolableList(value);
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX));
- segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY));
- segment.point2.setX(controlFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX));
- segment.point2.setY(controlFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY));
- segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(4), isAbsolute, coordinates.currentX));
- segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(5), isAbsolute, coordinates.currentY));
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- OwnPtr<InterpolableList> result = InterpolableList::create(4);
- result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordinates.currentX));
- result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordinates.currentY));
- result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
- result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
- return result.release();
-}
-
-PathSegmentData pathSegCurvetoQuadraticFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- const InterpolableList& list = toInterpolableList(value);
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX));
- segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY));
- segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX));
- segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY));
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- OwnPtr<InterpolableList> result = InterpolableList::create(7);
- result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
- result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
- result->set(2, InterpolableNumber::create(segment.r1()));
- result->set(3, InterpolableNumber::create(segment.r2()));
- result->set(4, InterpolableNumber::create(segment.arcAngle()));
- result->set(5, InterpolableBool::create(segment.largeArcFlag()));
- result->set(6, InterpolableBool::create(segment.sweepFlag()));
- return result.release();
-}
-
-PathSegmentData pathSegArcFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- const InterpolableList& list = toInterpolableList(value);
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX));
- segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY));
- segment.arcRadii().setX(toInterpolableNumber(list.get(2))->value());
- segment.arcRadii().setY(toInterpolableNumber(list.get(3))->value());
- segment.setArcAngle(toInterpolableNumber(list.get(4))->value());
- segment.arcLarge = toInterpolableBool(list.get(5))->value();
- segment.arcSweep = toInterpolableBool(list.get(6))->value();
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- return specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX);
-}
-
-PathSegmentData pathSegLinetoHorizontalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.targetPoint.setX(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentX));
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- return specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY);
-}
-
-PathSegmentData pathSegLinetoVerticalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.targetPoint.setY(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentY));
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
-{
- bool isAbsolute = isAbsolutePathSegType(segment.command);
- OwnPtr<InterpolableList> result = InterpolableList::create(4);
- result->set(0, controlToInterpolableValue(segment.x2(), isAbsolute, coordinates.currentX));
- result->set(1, controlToInterpolableValue(segment.y2(), isAbsolute, coordinates.currentY));
- result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
- result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
- return result.release();
-}
-
-PathSegmentData pathSegCurvetoCubicSmoothFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- const InterpolableList& list = toInterpolableList(value);
- bool isAbsolute = isAbsolutePathSegType(segType);
- PathSegmentData segment;
- segment.command = segType;
- segment.point2.setX(controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX));
- segment.point2.setY(controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY));
- segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX));
- segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY));
- return segment;
-}
-
-PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType)
-{
- if (ptrSegType)
- *ptrSegType = segment.command;
-
- switch (segment.command) {
- case PathSegClosePath:
- return pathSegClosePathToInterpolableValue(segment, coordinates);
-
- case PathSegMoveToAbs:
- case PathSegMoveToRel:
- case PathSegLineToAbs:
- case PathSegLineToRel:
- case PathSegCurveToQuadraticSmoothAbs:
- case PathSegCurveToQuadraticSmoothRel:
- return pathSegSingleCoordinateToInterpolableValue(segment, coordinates);
-
- case PathSegCurveToCubicAbs:
- case PathSegCurveToCubicRel:
- return pathSegCurvetoCubicToInterpolableValue(segment, coordinates);
-
- case PathSegCurveToQuadraticAbs:
- case PathSegCurveToQuadraticRel:
- return pathSegCurvetoQuadraticToInterpolableValue(segment, coordinates);
-
- case PathSegArcAbs:
- case PathSegArcRel:
- return pathSegArcToInterpolableValue(segment, coordinates);
-
- case PathSegLineToHorizontalAbs:
- case PathSegLineToHorizontalRel:
- return pathSegLinetoHorizontalToInterpolableValue(segment, coordinates);
-
- case PathSegLineToVerticalAbs:
- case PathSegLineToVerticalRel:
- return pathSegLinetoVerticalToInterpolableValue(segment, coordinates);
-
- case PathSegCurveToCubicSmoothAbs:
- case PathSegCurveToCubicSmoothRel:
- return pathSegCurvetoCubicSmoothToInterpolableValue(segment, coordinates);
-
- case PathSegUnknown:
- ASSERT_NOT_REACHED();
- }
- ASSERT_NOT_REACHED();
- return nullptr;
-}
-
-PathSegmentData pathSegFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
-{
- switch (segType) {
- case PathSegClosePath:
- return pathSegClosePathFromInterpolableValue(value, segType, coordinates);
-
- case PathSegMoveToAbs:
- case PathSegMoveToRel:
- case PathSegLineToAbs:
- case PathSegLineToRel:
- case PathSegCurveToQuadraticSmoothAbs:
- case PathSegCurveToQuadraticSmoothRel:
- return pathSegSingleCoordinateFromInterpolableValue(value, segType, coordinates);
-
- case PathSegCurveToCubicAbs:
- case PathSegCurveToCubicRel:
- return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordinates);
-
- case PathSegCurveToQuadraticAbs:
- case PathSegCurveToQuadraticRel:
- return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coordinates);
-
- case PathSegArcAbs:
- case PathSegArcRel:
- return pathSegArcFromInterpolableValue(value, segType, coordinates);
-
- case PathSegLineToHorizontalAbs:
- case PathSegLineToHorizontalRel:
- return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coordinates);
-
- case PathSegLineToVerticalAbs:
- case PathSegLineToVerticalRel:
- return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordinates);
-
- case PathSegCurveToCubicSmoothAbs:
- case PathSegCurveToCubicSmoothRel:
- return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, coordinates);
-
- case PathSegUnknown:
- ASSERT_NOT_REACHED();
- }
- ASSERT_NOT_REACHED();
- return PathSegmentData();
-}
-
-class InterpolatedPathSource : public SVGPathSource {
-public:
- InterpolatedPathSource(const InterpolableList& listValue, const Vector<SVGPathSegType>& pathSegTypes)
- : m_currentIndex(0)
- , m_list(listValue)
- , m_segmentTypes(pathSegTypes)
- {
- ASSERT(m_list.length() == m_segmentTypes.size());
- }
-
-private:
- bool hasMoreData() const override;
- SVGPathSegType peekSegmentType() override;
- PathSegmentData parseSegment() override;
-
- SubPathCoordinates m_normalizationState;
- size_t m_currentIndex;
- const InterpolableList& m_list;
- const Vector<SVGPathSegType>& m_segmentTypes;
-};
-
-bool InterpolatedPathSource::hasMoreData() const
-{
- return m_currentIndex < m_list.length();
-}
-
-SVGPathSegType InterpolatedPathSource::peekSegmentType()
-{
- ASSERT(hasMoreData());
- return m_segmentTypes.at(m_currentIndex);
-}
-
-PathSegmentData InterpolatedPathSource::parseSegment()
-{
- PathSegmentData segment = pathSegFromInterpolableValue(*m_list.get(m_currentIndex), m_segmentTypes.at(m_currentIndex), m_normalizationState);
- ++m_currentIndex;
- return segment;
-}
-
-size_t countPathCommands(const SVGPathByteStream& path)
-{
- size_t count = 0;
- SVGPathByteStreamSource pathSource(path);
- while (pathSource.hasMoreData()) {
- pathSource.parseSegment();
- ++count;
- }
- return count;
-}
-
-} // namespace
-
-PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBase* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute)
-{
- ASSERT(start->type() == SVGPath::classType());
- ASSERT(end->type() == SVGPath::classType());
-
- const SVGPathByteStream& startPath = static_cast<SVGPath*>(start)->byteStream();
- const SVGPathByteStream& endPath = static_cast<SVGPath*>(end)->byteStream();
-
- if (startPath.size() != endPath.size())
- return nullptr;
-
- size_t length = countPathCommands(startPath);
-
- SVGPathByteStreamSource startPathSource(startPath);
- SVGPathByteStreamSource endPathSource(endPath);
-
- 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;
-
- // Like Firefox SMIL, we use the final path seg type.
- const PathSegmentData startSeg = startPathSource.parseSegment();
- startValue->set(i, pathSegToInterpolableValue(startSeg, startCoordinates, nullptr));
-
- const PathSegmentData endSeg = endPathSource.parseSegment();
- endValue->set(i, pathSegToInterpolableValue(endSeg, endCoordinates, &pathSegTypes.at(i)));
-
- ++i;
- }
- ASSERT(!endPathSource.hasMoreData());
- ASSERT(i == length);
-
- return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.release(), attribute, pathSegTypes));
-}
-
-PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableValue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes)
-{
- RefPtrWillBeRawPtr<SVGPath> result = SVGPath::create();
- InterpolatedPathSource source(toInterpolableList(value), pathSegTypes);
- SVGPathByteStreamBuilder builder(result->mutableByteStream());
- SVGPathParser parser(&source, &builder);
- parser.parsePathDataFromSource(UnalteredParsing, false);
- return result.release();
-}
-
-PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue(SVGElement&) const
-{
- return fromInterpolableValue(*m_cachedValue, m_pathSegTypes);
-}
-
-}

Powered by Google App Engine
This is Rietveld 408576698