| 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
|
| index b2aa2f9a4f26db1c469fcf1c652ac560f01e3462..c3b149386c0b6c2f26e4fcad59be66db49019dbb 100644
|
| --- a/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
|
| +++ b/third_party/WebKit/Source/core/animation/PathSVGInterpolation.cpp
|
| @@ -5,26 +5,10 @@
|
| #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/SVGPathSegArcAbs.h"
|
| -#include "core/svg/SVGPathSegArcRel.h"
|
| -#include "core/svg/SVGPathSegClosePath.h"
|
| -#include "core/svg/SVGPathSegCurvetoCubicAbs.h"
|
| -#include "core/svg/SVGPathSegCurvetoCubicRel.h"
|
| -#include "core/svg/SVGPathSegCurvetoCubicSmoothAbs.h"
|
| -#include "core/svg/SVGPathSegCurvetoCubicSmoothRel.h"
|
| -#include "core/svg/SVGPathSegCurvetoQuadraticAbs.h"
|
| -#include "core/svg/SVGPathSegCurvetoQuadraticRel.h"
|
| -#include "core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h"
|
| -#include "core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h"
|
| -#include "core/svg/SVGPathSegLinetoAbs.h"
|
| -#include "core/svg/SVGPathSegLinetoHorizontalAbs.h"
|
| -#include "core/svg/SVGPathSegLinetoHorizontalRel.h"
|
| -#include "core/svg/SVGPathSegLinetoRel.h"
|
| -#include "core/svg/SVGPathSegLinetoVerticalAbs.h"
|
| -#include "core/svg/SVGPathSegLinetoVerticalRel.h"
|
| -#include "core/svg/SVGPathSegMovetoAbs.h"
|
| -#include "core/svg/SVGPathSegMovetoRel.h"
|
| +#include "core/svg/SVGPathParser.h"
|
|
|
| namespace blink {
|
|
|
| @@ -37,16 +21,6 @@ struct SubPathCoordinates {
|
| double currentY = 0;
|
| };
|
|
|
| -SVGPathSegType absolutePathSegType(const SVGPathSeg& item)
|
| -{
|
| - return toAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()));
|
| -}
|
| -
|
| -bool isAbsolutePathSegType(const SVGPathSeg& item)
|
| -{
|
| - return isAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()));
|
| -}
|
| -
|
| PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isAbsolute, double currentValue)
|
| {
|
| if (isAbsolute)
|
| @@ -82,7 +56,7 @@ double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAb
|
| return currentValue - previousValue;
|
| }
|
|
|
| -PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const SVGPathSeg& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const PathSegmentData&, SubPathCoordinates& coordinates)
|
| {
|
| coordinates.currentX = coordinates.initialX;
|
| coordinates.currentY = coordinates.initialY;
|
| @@ -91,22 +65,24 @@ PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const SVGPathS
|
| return InterpolableBool::create(false);
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegClosePathFromInterpolableValue(const InterpolableValue&, SVGPathSegType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegClosePathFromInterpolableValue(const InterpolableValue&, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| coordinates.currentX = coordinates.initialX;
|
| coordinates.currentY = coordinates.initialY;
|
|
|
| - return SVGPathSegClosePath::create(element);
|
| + PathSegmentData segment;
|
| + segment.command = segType;
|
| + return segment;
|
| }
|
|
|
| -PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const SVGPathSegSingleCoordinate& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| OwnPtr<InterpolableList> result = InterpolableList::create(2);
|
| - result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX));
|
| - result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY));
|
| + result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX));
|
| + result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY));
|
|
|
| - if (absolutePathSegType(item) == PathSegMoveToAbs) {
|
| + 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;
|
| @@ -115,12 +91,14 @@ PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const S
|
| return result.release();
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegSingleCoordinateFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegSingleCoordinateFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| const InterpolableList& list = toInterpolableList(value);
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX);
|
| - float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY);
|
| + 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.
|
| @@ -128,210 +106,153 @@ PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegSingleCoordinateFromInterpolableValue(
|
| coordinates.initialY = coordinates.currentY;
|
| }
|
|
|
| - switch (segType) {
|
| - case PathSegMoveToAbs:
|
| - return SVGPathSegMovetoAbs::create(element, x, y);
|
| - case PathSegMoveToRel:
|
| - return SVGPathSegMovetoRel::create(element, x, y);
|
| - case PathSegLineToAbs:
|
| - return SVGPathSegLinetoAbs::create(element, x, y);
|
| - case PathSegLineToRel:
|
| - return SVGPathSegLinetoRel::create(element, x, y);
|
| - case PathSegCurveToQuadraticSmoothAbs:
|
| - return SVGPathSegCurvetoQuadraticSmoothAbs::create(element, x, y);
|
| - case PathSegCurveToQuadraticSmoothRel:
|
| - return SVGPathSegCurvetoQuadraticSmoothRel::create(element, x, y);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + return segment;
|
| }
|
|
|
| -PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const SVGPathSegCurvetoCubic& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| OwnPtr<InterpolableList> result = InterpolableList::create(6);
|
| - result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates.currentX));
|
| - result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates.currentY));
|
| - result->set(2, controlToInterpolableValue(item.x2(), isAbsolute, coordinates.currentX));
|
| - result->set(3, controlToInterpolableValue(item.y2(), isAbsolute, coordinates.currentY));
|
| - result->set(4, specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX));
|
| - result->set(5, specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY));
|
| + 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();
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegCurvetoCubicFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| const InterpolableList& list = toInterpolableList(value);
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX);
|
| - float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY);
|
| - float x2 = controlFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX);
|
| - float y2 = controlFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY);
|
| - float x = specifiedFromInterpolableValue(list.get(4), isAbsolute, coordinates.currentX);
|
| - float y = specifiedFromInterpolableValue(list.get(5), isAbsolute, coordinates.currentY);
|
| -
|
| - switch (segType) {
|
| - case PathSegCurveToCubicAbs:
|
| - return SVGPathSegCurvetoCubicAbs::create(element, x, y, x1, y1, x2, y2);
|
| - case PathSegCurveToCubicRel:
|
| - return SVGPathSegCurvetoCubicRel::create(element, x, y, x1, y1, x2, y2);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + 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 SVGPathSegCurvetoQuadratic& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| OwnPtr<InterpolableList> result = InterpolableList::create(4);
|
| - result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates.currentX));
|
| - result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates.currentY));
|
| - result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX));
|
| - result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY));
|
| + 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();
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoQuadraticFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegCurvetoQuadraticFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| const InterpolableList& list = toInterpolableList(value);
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX);
|
| - float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY);
|
| - float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX);
|
| - float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY);
|
| - switch (segType) {
|
| - case PathSegCurveToQuadraticAbs:
|
| - return SVGPathSegCurvetoQuadraticAbs::create(element, x, y, x1, y1);
|
| - case PathSegCurveToQuadraticRel:
|
| - return SVGPathSegCurvetoQuadraticRel::create(element, x, y, x1, y1);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + 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 SVGPathSegArc& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| OwnPtr<InterpolableList> result = InterpolableList::create(7);
|
| - result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX));
|
| - result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY));
|
| - result->set(2, InterpolableNumber::create(item.r1()));
|
| - result->set(3, InterpolableNumber::create(item.r2()));
|
| - result->set(4, InterpolableNumber::create(item.angle()));
|
| - result->set(5, InterpolableBool::create(item.largeArcFlag()));
|
| - result->set(6, InterpolableBool::create(item.sweepFlag()));
|
| + 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();
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegArcFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegArcFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| const InterpolableList& list = toInterpolableList(value);
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX);
|
| - float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY);
|
| - float r1 = toInterpolableNumber(list.get(2))->value();
|
| - float r2 = toInterpolableNumber(list.get(3))->value();
|
| - float angle = toInterpolableNumber(list.get(4))->value();
|
| - bool largeArcFlag = toInterpolableBool(list.get(5))->value();
|
| - bool sweepFlag = toInterpolableBool(list.get(6))->value();
|
| - switch (segType) {
|
| - case PathSegArcAbs:
|
| - return SVGPathSegArcAbs::create(element, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
|
| - case PathSegArcRel:
|
| - return SVGPathSegArcRel::create(element, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + 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.point1.setX(toInterpolableNumber(list.get(2))->value());
|
| + segment.point1.setY(toInterpolableNumber(list.get(3))->value());
|
| + segment.point2.setX(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 SVGPathSegLinetoHorizontal& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| - return specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| + return specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.currentX);
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoHorizontalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegLinetoHorizontalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentX);
|
| -
|
| - switch (segType) {
|
| - case PathSegLineToHorizontalAbs:
|
| - return SVGPathSegLinetoHorizontalAbs::create(element, x);
|
| - case PathSegLineToHorizontalRel:
|
| - return SVGPathSegLinetoHorizontalRel::create(element, x);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + PathSegmentData segment;
|
| + segment.command = segType;
|
| + segment.targetPoint.setX(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentX));
|
| + return segment;
|
| }
|
|
|
| -PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const SVGPathSegLinetoVertical& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| - return specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| + return specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.currentY);
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoVerticalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegLinetoVerticalFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float y = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentY);
|
| -
|
| - switch (segType) {
|
| - case PathSegLineToVerticalAbs:
|
| - return SVGPathSegLinetoVerticalAbs::create(element, y);
|
| - case PathSegLineToVerticalRel:
|
| - return SVGPathSegLinetoVerticalRel::create(element, y);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + PathSegmentData segment;
|
| + segment.command = segType;
|
| + segment.targetPoint.setY(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentY));
|
| + return segment;
|
| }
|
|
|
| -PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const SVGPathSegCurvetoCubicSmooth& item, SubPathCoordinates& coordinates)
|
| +PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
|
| {
|
| - bool isAbsolute = isAbsolutePathSegType(item);
|
| + bool isAbsolute = isAbsolutePathSegType(segment.command);
|
| OwnPtr<InterpolableList> result = InterpolableList::create(4);
|
| - result->set(0, controlToInterpolableValue(item.x2(), isAbsolute, coordinates.currentX));
|
| - result->set(1, controlToInterpolableValue(item.y2(), isAbsolute, coordinates.currentY));
|
| - result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.currentX));
|
| - result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.currentY));
|
| + 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();
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicSmoothFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegCurvetoCubicSmoothFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| const InterpolableList& list = toInterpolableList(value);
|
| bool isAbsolute = isAbsolutePathSegType(segType);
|
| - float x2 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates.currentX);
|
| - float y2 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates.currentY);
|
| - float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinates.currentX);
|
| - float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinates.currentY);
|
| - switch (segType) {
|
| - case PathSegCurveToCubicSmoothAbs:
|
| - return SVGPathSegCurvetoCubicSmoothAbs::create(element, x, y, x2, y2);
|
| - case PathSegCurveToCubicSmoothRel:
|
| - return SVGPathSegCurvetoCubicSmoothRel::create(element, x, y, x2, y2);
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| - }
|
| + 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 SVGPathSeg& item, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType)
|
| +PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType)
|
| {
|
| - SVGPathSegType segType = static_cast<SVGPathSegType>(item.pathSegType());
|
| -
|
| if (ptrSegType)
|
| - *ptrSegType = segType;
|
| + *ptrSegType = segment.command;
|
|
|
| - switch (segType) {
|
| + switch (segment.command) {
|
| case PathSegClosePath:
|
| - return pathSegClosePathToInterpolableValue(item, coordinates);
|
| + return pathSegClosePathToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegMoveToAbs:
|
| case PathSegMoveToRel:
|
| @@ -339,31 +260,31 @@ PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const SVGPathSeg& item,
|
| case PathSegLineToRel:
|
| case PathSegCurveToQuadraticSmoothAbs:
|
| case PathSegCurveToQuadraticSmoothRel:
|
| - return pathSegSingleCoordinateToInterpolableValue(static_cast<const SVGPathSegSingleCoordinate&>(item), coordinates);
|
| + return pathSegSingleCoordinateToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegCurveToCubicAbs:
|
| case PathSegCurveToCubicRel:
|
| - return pathSegCurvetoCubicToInterpolableValue(static_cast<const SVGPathSegCurvetoCubic&>(item), coordinates);
|
| + return pathSegCurvetoCubicToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegCurveToQuadraticAbs:
|
| case PathSegCurveToQuadraticRel:
|
| - return pathSegCurvetoQuadraticToInterpolableValue(static_cast<const SVGPathSegCurvetoQuadratic&>(item), coordinates);
|
| + return pathSegCurvetoQuadraticToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegArcAbs:
|
| case PathSegArcRel:
|
| - return pathSegArcToInterpolableValue(static_cast<const SVGPathSegArc&>(item), coordinates);
|
| + return pathSegArcToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegLineToHorizontalAbs:
|
| case PathSegLineToHorizontalRel:
|
| - return pathSegLinetoHorizontalToInterpolableValue(static_cast<const SVGPathSegLinetoHorizontal&>(item), coordinates);
|
| + return pathSegLinetoHorizontalToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegLineToVerticalAbs:
|
| case PathSegLineToVerticalRel:
|
| - return pathSegLinetoVerticalToInterpolableValue(static_cast<const SVGPathSegLinetoVertical&>(item), coordinates);
|
| + return pathSegLinetoVerticalToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegCurveToCubicSmoothAbs:
|
| case PathSegCurveToCubicSmoothRel:
|
| - return pathSegCurvetoCubicSmoothToInterpolableValue(static_cast<const SVGPathSegCurvetoCubicSmooth&>(item), coordinates);
|
| + return pathSegCurvetoCubicSmoothToInterpolableValue(segment, coordinates);
|
|
|
| case PathSegUnknown:
|
| ASSERT_NOT_REACHED();
|
| @@ -372,11 +293,11 @@ PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const SVGPathSeg& item,
|
| return nullptr;
|
| }
|
|
|
| -PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPathElement* element)
|
| +PathSegmentData pathSegFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
|
| {
|
| switch (segType) {
|
| case PathSegClosePath:
|
| - return pathSegClosePathFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegClosePathFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegMoveToAbs:
|
| case PathSegMoveToRel:
|
| @@ -384,37 +305,87 @@ PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegFromInterpolableValue(const Interpolab
|
| case PathSegLineToRel:
|
| case PathSegCurveToQuadraticSmoothAbs:
|
| case PathSegCurveToQuadraticSmoothRel:
|
| - return pathSegSingleCoordinateFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegSingleCoordinateFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegCurveToCubicAbs:
|
| case PathSegCurveToCubicRel:
|
| - return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegCurveToQuadraticAbs:
|
| case PathSegCurveToQuadraticRel:
|
| - return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegArcAbs:
|
| case PathSegArcRel:
|
| - return pathSegArcFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegArcFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegLineToHorizontalAbs:
|
| case PathSegLineToHorizontalRel:
|
| - return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegLineToVerticalAbs:
|
| case PathSegLineToVerticalRel:
|
| - return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegCurveToCubicSmoothAbs:
|
| case PathSegCurveToCubicSmoothRel:
|
| - return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, coordinates, element);
|
| + return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, coordinates);
|
|
|
| case PathSegUnknown:
|
| ASSERT_NOT_REACHED();
|
| }
|
| ASSERT_NOT_REACHED();
|
| - return nullptr;
|
| + 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
|
| @@ -424,36 +395,50 @@ PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa
|
| ASSERT(start->type() == SVGPathSegList::classType());
|
| ASSERT(end->type() == SVGPathSegList::classType());
|
|
|
| - SVGPathSegList* startList = static_cast<SVGPathSegList*>(start);
|
| - SVGPathSegList* endList = static_cast<SVGPathSegList*>(end);
|
| - size_t length = startList->length();
|
| - if (length != endList->length())
|
| + const SVGPathByteStream& startPath = static_cast<SVGPathSegList*>(start)->byteStream();
|
| + const SVGPathByteStream& endPath = static_cast<SVGPathSegList*>(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;
|
| - for (size_t i = 0; i < length; i++) {
|
| - if (absolutePathSegType(*startList->at(i)) != absolutePathSegType(*endList->at(i)))
|
| + 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.
|
| - startValue->set(i, pathSegToInterpolableValue(*startList->at(i), startCoordinates, nullptr));
|
| - endValue->set(i, pathSegToInterpolableValue(*endList->at(i), endCoordinates, &pathSegTypes.at(i)));
|
| + 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, SVGPathElement* element)
|
| {
|
| - const InterpolableList& listValue = toInterpolableList(value);
|
| RefPtrWillBeRawPtr<SVGPathSegList> result = SVGPathSegList::create(element);
|
| - SubPathCoordinates coordinates;
|
| - for (size_t i = 0; i < listValue.length(); i++)
|
| - result->append(pathSegFromInterpolableValue(*listValue.get(i), pathSegTypes.at(i), coordinates, element));
|
| + result->invalidateList();
|
| + InterpolatedPathSource source(toInterpolableList(value), pathSegTypes);
|
| + SVGPathByteStreamBuilder builder(result->mutableByteStream());
|
| + SVGPathParser parser(&source, &builder);
|
| + parser.parsePathDataFromSource(UnalteredParsing, false);
|
| return result.release();
|
| }
|
|
|
|
|