Chromium Code Reviews| Index: Source/core/svg/SVGPathBlender.cpp |
| diff --git a/Source/core/svg/SVGPathBlender.cpp b/Source/core/svg/SVGPathBlender.cpp |
| index 3e0fb27661e770a10ee6c9dd825b94d8b537384a..dbd5aabda028b20d82aeb66bd3007a5044ce4e9f 100644 |
| --- a/Source/core/svg/SVGPathBlender.cpp |
| +++ b/Source/core/svg/SVGPathBlender.cpp |
| @@ -20,6 +20,7 @@ |
| #include "config.h" |
| #include "core/svg/SVGPathBlender.h" |
| +#include "core/svg/SVGPathConsumer.h" |
| #include "core/svg/SVGPathSeg.h" |
| #include "core/svg/SVGPathSource.h" |
| #include "platform/animation/AnimationUtilities.h" |
| @@ -34,6 +35,9 @@ SVGPathBlender::SVGPathBlender(SVGPathSource* fromSource, SVGPathSource* toSourc |
| , m_progress(0) |
| , m_addTypesCount(0) |
| , m_isInFirstHalfOfAnimation(false) |
| + , m_typesAreEqual(false) |
| + , m_fromIsAbsolute(false) |
| + , m_toIsAbsolute(false) |
| { |
| ASSERT(m_fromSource); |
| ASSERT(m_toSource); |
| @@ -56,25 +60,26 @@ static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint& |
| float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode) |
| { |
| if (m_addTypesCount) { |
| - ASSERT(m_fromMode == m_toMode); |
| + ASSERT(m_typesAreEqual); |
| return from + to * m_addTypesCount; |
| } |
| - if (m_fromMode == m_toMode) |
| + if (m_typesAreEqual) |
| return blend(from, to, m_progress); |
| float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_fromCurrentPoint.y(); |
| float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCurrentPoint.y(); |
| // Transform toY to the coordinate mode of fromY |
| - float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, m_progress); |
| + float animValue = blend(from, m_fromIsAbsolute ? to + toValue : to - toValue, m_progress); |
| + // If we're in the first half of the animation, we should use the type of the from segment. |
| if (m_isInFirstHalfOfAnimation) |
| return animValue; |
| // Transform the animated point to the coordinate mode, needed for the current progress. |
| float currentValue = blend(fromValue, toValue, m_progress); |
| - return m_toMode == AbsoluteCoordinates ? animValue + currentValue : animValue - currentValue; |
| + return !m_fromIsAbsolute ? animValue + currentValue : animValue - currentValue; |
| } |
| FloatPoint SVGPathBlender::blendAnimatedFloatPointSameCoordinates(const FloatPoint& fromPoint, const FloatPoint& toPoint) |
| @@ -89,24 +94,25 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPointSameCoordinates(const FloatPoi |
| FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint) |
| { |
| - if (m_fromMode == m_toMode) |
| + if (m_typesAreEqual) |
| return blendAnimatedFloatPointSameCoordinates(fromPoint, toPoint); |
| // Transform toPoint to the coordinate mode of fromPoint |
| FloatPoint animatedPoint = toPoint; |
| - if (m_fromMode == AbsoluteCoordinates) |
| + if (m_fromIsAbsolute) |
| animatedPoint += m_toCurrentPoint; |
| else |
| animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y()); |
| animatedPoint = blendFloatPoint(fromPoint, animatedPoint, m_progress); |
| + // If we're in the first half of the animation, we should use the type of the from segment. |
| if (m_isInFirstHalfOfAnimation) |
| return animatedPoint; |
| // Transform the animated point to the coordinate mode, needed for the current progress. |
| FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, m_progress); |
| - if (m_toMode == AbsoluteCoordinates) |
| + if (!m_fromIsAbsolute) |
| return animatedPoint + currentPoint; |
| animatedPoint.move(-currentPoint.x(), -currentPoint.y()); |
| @@ -119,8 +125,8 @@ PathSegmentData SVGPathBlender::blendMoveToSegment(const PathSegmentData& fromSe |
| blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSeg.command; |
| blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, toSeg.targetPoint); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -130,8 +136,8 @@ PathSegmentData SVGPathBlender::blendLineToSegment(const PathSegmentData& fromSe |
| blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSeg.command; |
| blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, toSeg.targetPoint); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -141,8 +147,8 @@ PathSegmentData SVGPathBlender::blendLineToHorizontalSegment(const PathSegmentDa |
| blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSeg.command; |
| blendedSegment.targetPoint.setX(blendAnimatedDimensonalFloat(fromSeg.targetPoint.x(), toSeg.targetPoint.x(), BlendHorizontal)); |
| - m_fromCurrentPoint.setX(m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint.x() : m_fromCurrentPoint.x() + fromSeg.targetPoint.x()); |
| - m_toCurrentPoint.setX(m_toMode == AbsoluteCoordinates ? toSeg.targetPoint.x() : m_toCurrentPoint.x() + toSeg.targetPoint.x()); |
| + m_fromCurrentPoint.setX(m_fromIsAbsolute ? fromSeg.targetPoint.x() : m_fromCurrentPoint.x() + fromSeg.targetPoint.x()); |
| + m_toCurrentPoint.setX(m_toIsAbsolute ? toSeg.targetPoint.x() : m_toCurrentPoint.x() + toSeg.targetPoint.x()); |
| return blendedSegment; |
| } |
| @@ -152,8 +158,8 @@ PathSegmentData SVGPathBlender::blendLineToVerticalSegment(const PathSegmentData |
| blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSeg.command; |
| blendedSegment.targetPoint.setY(blendAnimatedDimensonalFloat(fromSeg.targetPoint.y(), toSeg.targetPoint.y(), BlendVertical)); |
| - m_fromCurrentPoint.setY(m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint.y() : m_fromCurrentPoint.y() + fromSeg.targetPoint.y()); |
| - m_toCurrentPoint.setY(m_toMode == AbsoluteCoordinates ? toSeg.targetPoint.y() : m_toCurrentPoint.y() + toSeg.targetPoint.y()); |
| + m_fromCurrentPoint.setY(m_fromIsAbsolute ? fromSeg.targetPoint.y() : m_fromCurrentPoint.y() + fromSeg.targetPoint.y()); |
| + m_toCurrentPoint.setY(m_toIsAbsolute ? toSeg.targetPoint.y() : m_toCurrentPoint.y() + toSeg.targetPoint.y()); |
| return blendedSegment; |
| } |
| @@ -165,8 +171,8 @@ PathSegmentData SVGPathBlender::blendCurveToCubicSegment(const PathSegmentData& |
| blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1); |
| blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -177,8 +183,8 @@ PathSegmentData SVGPathBlender::blendCurveToCubicSmoothSegment(const PathSegment |
| blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, toSeg.targetPoint); |
| blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -189,8 +195,8 @@ PathSegmentData SVGPathBlender::blendCurveToQuadraticSegment(const PathSegmentDa |
| blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, toSeg.targetPoint); |
| blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -200,8 +206,8 @@ PathSegmentData SVGPathBlender::blendCurveToQuadraticSmoothSegment(const PathSeg |
| blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSeg.command; |
| blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, toSeg.targetPoint); |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -222,8 +228,8 @@ PathSegmentData SVGPathBlender::blendArcToSegment(const PathSegmentData& fromSeg |
| blendedSegment.arcSweep = m_isInFirstHalfOfAnimation ? fromSeg.arcSweep : toSeg.arcSweep; |
| } |
| - m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| - m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| + m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; |
| + m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + toSeg.targetPoint; |
| return blendedSegment; |
| } |
| @@ -277,18 +283,6 @@ void SVGPathBlender::blendSegments(const PathSegmentData& fromSeg, const PathSeg |
| m_consumer->emitSegment(blendedSegment); |
| } |
| -static inline PathCoordinateMode coordinateModeOfCommand(const SVGPathSegType& type) |
| -{ |
| - if (type < PathSegMoveToAbs) |
| - return AbsoluteCoordinates; |
| - |
| - // Odd number = relative command |
| - if (type % 2) |
| - return RelativeCoordinates; |
| - |
| - return AbsoluteCoordinates; |
| -} |
| - |
| bool SVGPathBlender::addAnimatedPath(unsigned repeatCount) |
| { |
| TemporaryChange<unsigned> change(m_addTypesCount, repeatCount); |
| @@ -315,14 +309,20 @@ bool SVGPathBlender::blendAnimatedPath(float progress) |
| return false; |
| } |
| - if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType(toSeg.command)) |
| - return false; |
| + m_typesAreEqual = fromSeg.command == toSeg.command; |
| - m_fromMode = coordinateModeOfCommand(fromSeg.command); |
| - m_toMode = coordinateModeOfCommand(toSeg.command); |
| + // If the types are equal, they'll blend regardless of parameters. |
| + if (!m_typesAreEqual) { |
| + // Addition require segments with the same type. |
| + if (m_addTypesCount) |
| + return false; |
| + // Allow the segments to differ in "relativeness". |
| + if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType(toSeg.command)) |
| + return false; |
| + } |
| - if (m_addTypesCount && m_fromMode != m_toMode) |
| - return false; |
| + m_fromIsAbsolute = isAbsolutePathSegType(fromSeg.command); |
|
pdr.
2015/04/01 00:03:49
If m_typesAreEqual is false, won't we neglect to u
fs
2015/04/01 09:15:54
Hmm, no (or I don't understand what you mean.) Thi
|
| + m_toIsAbsolute = isAbsolutePathSegType(toSeg.command); |
| blendSegments(fromSeg, toSeg); |