Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Library General Public License | 14 * You should have received a copy of the GNU Library General Public License |
| 15 * along with this library; see the file COPYING.LIB. If not, write to | 15 * along with this library; see the file COPYING.LIB. If not, write to |
| 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
| 18 */ | 18 */ |
| 19 | 19 |
| 20 #include "config.h" | 20 #include "config.h" |
| 21 #include "core/svg/SVGPathBlender.h" | 21 #include "core/svg/SVGPathBlender.h" |
| 22 | 22 |
| 23 #include "core/svg/SVGPathConsumer.h" | |
| 23 #include "core/svg/SVGPathSeg.h" | 24 #include "core/svg/SVGPathSeg.h" |
| 24 #include "core/svg/SVGPathSource.h" | 25 #include "core/svg/SVGPathSource.h" |
| 25 #include "platform/animation/AnimationUtilities.h" | 26 #include "platform/animation/AnimationUtilities.h" |
| 26 #include "wtf/TemporaryChange.h" | 27 #include "wtf/TemporaryChange.h" |
| 27 | 28 |
| 28 namespace blink { | 29 namespace blink { |
| 29 | 30 |
| 30 SVGPathBlender::SVGPathBlender(SVGPathSource* fromSource, SVGPathSource* toSourc e, SVGPathConsumer* consumer) | 31 SVGPathBlender::SVGPathBlender(SVGPathSource* fromSource, SVGPathSource* toSourc e, SVGPathConsumer* consumer) |
| 31 : m_fromSource(fromSource) | 32 : m_fromSource(fromSource) |
| 32 , m_toSource(toSource) | 33 , m_toSource(toSource) |
| 33 , m_consumer(consumer) | 34 , m_consumer(consumer) |
| 34 , m_progress(0) | 35 , m_progress(0) |
| 35 , m_addTypesCount(0) | 36 , m_addTypesCount(0) |
| 36 , m_isInFirstHalfOfAnimation(false) | 37 , m_isInFirstHalfOfAnimation(false) |
| 38 , m_typesAreEqual(false) | |
| 39 , m_fromIsAbsolute(false) | |
| 40 , m_toIsAbsolute(false) | |
| 37 { | 41 { |
| 38 ASSERT(m_fromSource); | 42 ASSERT(m_fromSource); |
| 39 ASSERT(m_toSource); | 43 ASSERT(m_toSource); |
| 40 ASSERT(m_consumer); | 44 ASSERT(m_consumer); |
| 41 } | 45 } |
| 42 | 46 |
| 43 DEFINE_TRACE(SVGPathBlender) | 47 DEFINE_TRACE(SVGPathBlender) |
| 44 { | 48 { |
| 45 visitor->trace(m_fromSource); | 49 visitor->trace(m_fromSource); |
| 46 visitor->trace(m_toSource); | 50 visitor->trace(m_toSource); |
| 47 visitor->trace(m_consumer); | 51 visitor->trace(m_consumer); |
| 48 } | 52 } |
| 49 | 53 |
| 50 // Helper functions | 54 // Helper functions |
| 51 static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint& b, float progress) | 55 static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint& b, float progress) |
| 52 { | 56 { |
| 53 return FloatPoint(blend(a.x(), b.x(), progress), blend(a.y(), b.y(), progres s)); | 57 return FloatPoint(blend(a.x(), b.x(), progress), blend(a.y(), b.y(), progres s)); |
| 54 } | 58 } |
| 55 | 59 |
| 56 float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBl endMode blendMode) | 60 float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBl endMode blendMode) |
| 57 { | 61 { |
| 58 if (m_addTypesCount) { | 62 if (m_addTypesCount) { |
| 59 ASSERT(m_fromMode == m_toMode); | 63 ASSERT(m_typesAreEqual); |
| 60 return from + to * m_addTypesCount; | 64 return from + to * m_addTypesCount; |
| 61 } | 65 } |
| 62 | 66 |
| 63 if (m_fromMode == m_toMode) | 67 if (m_typesAreEqual) |
| 64 return blend(from, to, m_progress); | 68 return blend(from, to, m_progress); |
| 65 | 69 |
| 66 float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_ fromCurrentPoint.y(); | 70 float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_ fromCurrentPoint.y(); |
| 67 float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCu rrentPoint.y(); | 71 float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCu rrentPoint.y(); |
| 68 | 72 |
| 69 // Transform toY to the coordinate mode of fromY | 73 // Transform toY to the coordinate mode of fromY |
| 70 float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toVal ue : to - toValue, m_progress); | 74 float animValue = blend(from, m_fromIsAbsolute ? to + toValue : to - toValue , m_progress); |
| 71 | 75 |
| 76 // If we're in the first half of the animation, we should use the type of th e from segment. | |
| 72 if (m_isInFirstHalfOfAnimation) | 77 if (m_isInFirstHalfOfAnimation) |
| 73 return animValue; | 78 return animValue; |
| 74 | 79 |
| 75 // Transform the animated point to the coordinate mode, needed for the curre nt progress. | 80 // Transform the animated point to the coordinate mode, needed for the curre nt progress. |
| 76 float currentValue = blend(fromValue, toValue, m_progress); | 81 float currentValue = blend(fromValue, toValue, m_progress); |
| 77 return m_toMode == AbsoluteCoordinates ? animValue + currentValue : animValu e - currentValue; | 82 return !m_fromIsAbsolute ? animValue + currentValue : animValue - currentVal ue; |
| 78 } | 83 } |
| 79 | 84 |
| 80 FloatPoint SVGPathBlender::blendAnimatedFloatPointSameCoordinates(const FloatPoi nt& fromPoint, const FloatPoint& toPoint) | 85 FloatPoint SVGPathBlender::blendAnimatedFloatPointSameCoordinates(const FloatPoi nt& fromPoint, const FloatPoint& toPoint) |
| 81 { | 86 { |
| 82 if (m_addTypesCount) { | 87 if (m_addTypesCount) { |
| 83 FloatPoint repeatedToPoint = toPoint; | 88 FloatPoint repeatedToPoint = toPoint; |
| 84 repeatedToPoint.scale(m_addTypesCount, m_addTypesCount); | 89 repeatedToPoint.scale(m_addTypesCount, m_addTypesCount); |
| 85 return fromPoint + repeatedToPoint; | 90 return fromPoint + repeatedToPoint; |
| 86 } | 91 } |
| 87 return blendFloatPoint(fromPoint, toPoint, m_progress); | 92 return blendFloatPoint(fromPoint, toPoint, m_progress); |
| 88 } | 93 } |
| 89 | 94 |
| 90 FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint) | 95 FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint) |
| 91 { | 96 { |
| 92 if (m_fromMode == m_toMode) | 97 if (m_typesAreEqual) |
| 93 return blendAnimatedFloatPointSameCoordinates(fromPoint, toPoint); | 98 return blendAnimatedFloatPointSameCoordinates(fromPoint, toPoint); |
| 94 | 99 |
| 95 // Transform toPoint to the coordinate mode of fromPoint | 100 // Transform toPoint to the coordinate mode of fromPoint |
| 96 FloatPoint animatedPoint = toPoint; | 101 FloatPoint animatedPoint = toPoint; |
| 97 if (m_fromMode == AbsoluteCoordinates) | 102 if (m_fromIsAbsolute) |
| 98 animatedPoint += m_toCurrentPoint; | 103 animatedPoint += m_toCurrentPoint; |
| 99 else | 104 else |
| 100 animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y()); | 105 animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y()); |
| 101 | 106 |
| 102 animatedPoint = blendFloatPoint(fromPoint, animatedPoint, m_progress); | 107 animatedPoint = blendFloatPoint(fromPoint, animatedPoint, m_progress); |
| 103 | 108 |
| 109 // If we're in the first half of the animation, we should use the type of th e from segment. | |
| 104 if (m_isInFirstHalfOfAnimation) | 110 if (m_isInFirstHalfOfAnimation) |
| 105 return animatedPoint; | 111 return animatedPoint; |
| 106 | 112 |
| 107 // Transform the animated point to the coordinate mode, needed for the curre nt progress. | 113 // Transform the animated point to the coordinate mode, needed for the curre nt progress. |
| 108 FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoi nt, m_progress); | 114 FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoi nt, m_progress); |
| 109 if (m_toMode == AbsoluteCoordinates) | 115 if (!m_fromIsAbsolute) |
| 110 return animatedPoint + currentPoint; | 116 return animatedPoint + currentPoint; |
| 111 | 117 |
| 112 animatedPoint.move(-currentPoint.x(), -currentPoint.y()); | 118 animatedPoint.move(-currentPoint.x(), -currentPoint.y()); |
| 113 return animatedPoint; | 119 return animatedPoint; |
| 114 } | 120 } |
| 115 | 121 |
| 116 PathSegmentData SVGPathBlender::blendMoveToSegment(const PathSegmentData& fromSe g, const PathSegmentData& toSeg) | 122 PathSegmentData SVGPathBlender::blendMoveToSegment(const PathSegmentData& fromSe g, const PathSegmentData& toSeg) |
| 117 { | 123 { |
| 118 PathSegmentData blendedSegment; | 124 PathSegmentData blendedSegment; |
| 119 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 125 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 120 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 126 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 121 | 127 |
| 122 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 128 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 123 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 129 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 124 return blendedSegment; | 130 return blendedSegment; |
| 125 } | 131 } |
| 126 | 132 |
| 127 PathSegmentData SVGPathBlender::blendLineToSegment(const PathSegmentData& fromSe g, const PathSegmentData& toSeg) | 133 PathSegmentData SVGPathBlender::blendLineToSegment(const PathSegmentData& fromSe g, const PathSegmentData& toSeg) |
| 128 { | 134 { |
| 129 PathSegmentData blendedSegment; | 135 PathSegmentData blendedSegment; |
| 130 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 136 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 131 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 137 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 132 | 138 |
| 133 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 139 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 134 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 140 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 135 return blendedSegment; | 141 return blendedSegment; |
| 136 } | 142 } |
| 137 | 143 |
| 138 PathSegmentData SVGPathBlender::blendLineToHorizontalSegment(const PathSegmentDa ta& fromSeg, const PathSegmentData& toSeg) | 144 PathSegmentData SVGPathBlender::blendLineToHorizontalSegment(const PathSegmentDa ta& fromSeg, const PathSegmentData& toSeg) |
| 139 { | 145 { |
| 140 PathSegmentData blendedSegment; | 146 PathSegmentData blendedSegment; |
| 141 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 147 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 142 blendedSegment.targetPoint.setX(blendAnimatedDimensonalFloat(fromSeg.targetP oint.x(), toSeg.targetPoint.x(), BlendHorizontal)); | 148 blendedSegment.targetPoint.setX(blendAnimatedDimensonalFloat(fromSeg.targetP oint.x(), toSeg.targetPoint.x(), BlendHorizontal)); |
| 143 | 149 |
| 144 m_fromCurrentPoint.setX(m_fromMode == AbsoluteCoordinates ? fromSeg.targetPo int.x() : m_fromCurrentPoint.x() + fromSeg.targetPoint.x()); | 150 m_fromCurrentPoint.setX(m_fromIsAbsolute ? fromSeg.targetPoint.x() : m_fromC urrentPoint.x() + fromSeg.targetPoint.x()); |
| 145 m_toCurrentPoint.setX(m_toMode == AbsoluteCoordinates ? toSeg.targetPoint.x( ) : m_toCurrentPoint.x() + toSeg.targetPoint.x()); | 151 m_toCurrentPoint.setX(m_toIsAbsolute ? toSeg.targetPoint.x() : m_toCurrentPo int.x() + toSeg.targetPoint.x()); |
| 146 return blendedSegment; | 152 return blendedSegment; |
| 147 } | 153 } |
| 148 | 154 |
| 149 PathSegmentData SVGPathBlender::blendLineToVerticalSegment(const PathSegmentData & fromSeg, const PathSegmentData& toSeg) | 155 PathSegmentData SVGPathBlender::blendLineToVerticalSegment(const PathSegmentData & fromSeg, const PathSegmentData& toSeg) |
| 150 { | 156 { |
| 151 PathSegmentData blendedSegment; | 157 PathSegmentData blendedSegment; |
| 152 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 158 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 153 blendedSegment.targetPoint.setY(blendAnimatedDimensonalFloat(fromSeg.targetP oint.y(), toSeg.targetPoint.y(), BlendVertical)); | 159 blendedSegment.targetPoint.setY(blendAnimatedDimensonalFloat(fromSeg.targetP oint.y(), toSeg.targetPoint.y(), BlendVertical)); |
| 154 | 160 |
| 155 m_fromCurrentPoint.setY(m_fromMode == AbsoluteCoordinates ? fromSeg.targetPo int.y() : m_fromCurrentPoint.y() + fromSeg.targetPoint.y()); | 161 m_fromCurrentPoint.setY(m_fromIsAbsolute ? fromSeg.targetPoint.y() : m_fromC urrentPoint.y() + fromSeg.targetPoint.y()); |
| 156 m_toCurrentPoint.setY(m_toMode == AbsoluteCoordinates ? toSeg.targetPoint.y( ) : m_toCurrentPoint.y() + toSeg.targetPoint.y()); | 162 m_toCurrentPoint.setY(m_toIsAbsolute ? toSeg.targetPoint.y() : m_toCurrentPo int.y() + toSeg.targetPoint.y()); |
| 157 return blendedSegment; | 163 return blendedSegment; |
| 158 } | 164 } |
| 159 | 165 |
| 160 PathSegmentData SVGPathBlender::blendCurveToCubicSegment(const PathSegmentData& fromSeg, const PathSegmentData& toSeg) | 166 PathSegmentData SVGPathBlender::blendCurveToCubicSegment(const PathSegmentData& fromSeg, const PathSegmentData& toSeg) |
| 161 { | 167 { |
| 162 PathSegmentData blendedSegment; | 168 PathSegmentData blendedSegment; |
| 163 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 169 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 164 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 170 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 165 blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1 ); | 171 blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1 ); |
| 166 blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2 ); | 172 blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2 ); |
| 167 | 173 |
| 168 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 174 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 169 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 175 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 170 return blendedSegment; | 176 return blendedSegment; |
| 171 } | 177 } |
| 172 | 178 |
| 173 PathSegmentData SVGPathBlender::blendCurveToCubicSmoothSegment(const PathSegment Data& fromSeg, const PathSegmentData& toSeg) | 179 PathSegmentData SVGPathBlender::blendCurveToCubicSmoothSegment(const PathSegment Data& fromSeg, const PathSegmentData& toSeg) |
| 174 { | 180 { |
| 175 PathSegmentData blendedSegment; | 181 PathSegmentData blendedSegment; |
| 176 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 182 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 177 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 183 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 178 blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2 ); | 184 blendedSegment.point2 = blendAnimatedFloatPoint(fromSeg.point2, toSeg.point2 ); |
| 179 | 185 |
| 180 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 186 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 181 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 187 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 182 return blendedSegment; | 188 return blendedSegment; |
| 183 } | 189 } |
| 184 | 190 |
| 185 PathSegmentData SVGPathBlender::blendCurveToQuadraticSegment(const PathSegmentDa ta& fromSeg, const PathSegmentData& toSeg) | 191 PathSegmentData SVGPathBlender::blendCurveToQuadraticSegment(const PathSegmentDa ta& fromSeg, const PathSegmentData& toSeg) |
| 186 { | 192 { |
| 187 PathSegmentData blendedSegment; | 193 PathSegmentData blendedSegment; |
| 188 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 194 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 189 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 195 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 190 blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1 ); | 196 blendedSegment.point1 = blendAnimatedFloatPoint(fromSeg.point1, toSeg.point1 ); |
| 191 | 197 |
| 192 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 198 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 193 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 199 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 194 return blendedSegment; | 200 return blendedSegment; |
| 195 } | 201 } |
| 196 | 202 |
| 197 PathSegmentData SVGPathBlender::blendCurveToQuadraticSmoothSegment(const PathSeg mentData& fromSeg, const PathSegmentData& toSeg) | 203 PathSegmentData SVGPathBlender::blendCurveToQuadraticSmoothSegment(const PathSeg mentData& fromSeg, const PathSegmentData& toSeg) |
| 198 { | 204 { |
| 199 PathSegmentData blendedSegment; | 205 PathSegmentData blendedSegment; |
| 200 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 206 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 201 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 207 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 202 | 208 |
| 203 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 209 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 204 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 210 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 205 return blendedSegment; | 211 return blendedSegment; |
| 206 } | 212 } |
| 207 | 213 |
| 208 PathSegmentData SVGPathBlender::blendArcToSegment(const PathSegmentData& fromSeg , const PathSegmentData& toSeg) | 214 PathSegmentData SVGPathBlender::blendArcToSegment(const PathSegmentData& fromSeg , const PathSegmentData& toSeg) |
| 209 { | 215 { |
| 210 ASSERT(!m_addTypesCount || fromSeg.command == toSeg.command); | 216 ASSERT(!m_addTypesCount || fromSeg.command == toSeg.command); |
| 211 | 217 |
| 212 PathSegmentData blendedSegment; | 218 PathSegmentData blendedSegment; |
| 213 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; | 219 blendedSegment.command = m_isInFirstHalfOfAnimation ? fromSeg.command : toSe g.command; |
| 214 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); | 220 blendedSegment.targetPoint = blendAnimatedFloatPoint(fromSeg.targetPoint, to Seg.targetPoint); |
| 215 blendedSegment.point1 = blendAnimatedFloatPointSameCoordinates(fromSeg.arcRa dii(), toSeg.arcRadii()); | 221 blendedSegment.point1 = blendAnimatedFloatPointSameCoordinates(fromSeg.arcRa dii(), toSeg.arcRadii()); |
| 216 blendedSegment.point2 = blendAnimatedFloatPointSameCoordinates(fromSeg.point 2, toSeg.point2); | 222 blendedSegment.point2 = blendAnimatedFloatPointSameCoordinates(fromSeg.point 2, toSeg.point2); |
| 217 if (m_addTypesCount) { | 223 if (m_addTypesCount) { |
| 218 blendedSegment.arcLarge = fromSeg.arcLarge || toSeg.arcLarge; | 224 blendedSegment.arcLarge = fromSeg.arcLarge || toSeg.arcLarge; |
| 219 blendedSegment.arcSweep = fromSeg.arcSweep || toSeg.arcSweep; | 225 blendedSegment.arcSweep = fromSeg.arcSweep || toSeg.arcSweep; |
| 220 } else { | 226 } else { |
| 221 blendedSegment.arcLarge = m_isInFirstHalfOfAnimation ? fromSeg.arcLarge : toSeg.arcLarge; | 227 blendedSegment.arcLarge = m_isInFirstHalfOfAnimation ? fromSeg.arcLarge : toSeg.arcLarge; |
| 222 blendedSegment.arcSweep = m_isInFirstHalfOfAnimation ? fromSeg.arcSweep : toSeg.arcSweep; | 228 blendedSegment.arcSweep = m_isInFirstHalfOfAnimation ? fromSeg.arcSweep : toSeg.arcSweep; |
| 223 } | 229 } |
| 224 | 230 |
| 225 m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromSeg.targetPoint : m_fromCurrentPoint + fromSeg.targetPoint; | 231 m_fromCurrentPoint = m_fromIsAbsolute ? fromSeg.targetPoint : m_fromCurrentP oint + fromSeg.targetPoint; |
| 226 m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toSeg.targetPoint : m_t oCurrentPoint + toSeg.targetPoint; | 232 m_toCurrentPoint = m_toIsAbsolute ? toSeg.targetPoint : m_toCurrentPoint + t oSeg.targetPoint; |
| 227 return blendedSegment; | 233 return blendedSegment; |
| 228 } | 234 } |
| 229 | 235 |
| 230 void SVGPathBlender::blendSegments(const PathSegmentData& fromSeg, const PathSeg mentData& toSeg) | 236 void SVGPathBlender::blendSegments(const PathSegmentData& fromSeg, const PathSeg mentData& toSeg) |
| 231 { | 237 { |
| 232 PathSegmentData blendedSegment; | 238 PathSegmentData blendedSegment; |
| 233 switch (toSeg.command) { | 239 switch (toSeg.command) { |
| 234 case PathSegMoveToRel: | 240 case PathSegMoveToRel: |
| 235 case PathSegMoveToAbs: | 241 case PathSegMoveToAbs: |
| 236 blendedSegment = blendMoveToSegment(fromSeg, toSeg); | 242 blendedSegment = blendMoveToSegment(fromSeg, toSeg); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 case PathSegArcAbs: | 276 case PathSegArcAbs: |
| 271 blendedSegment = blendArcToSegment(fromSeg, toSeg); | 277 blendedSegment = blendArcToSegment(fromSeg, toSeg); |
| 272 break; | 278 break; |
| 273 default: | 279 default: |
| 274 ASSERT_NOT_REACHED(); | 280 ASSERT_NOT_REACHED(); |
| 275 } | 281 } |
| 276 | 282 |
| 277 m_consumer->emitSegment(blendedSegment); | 283 m_consumer->emitSegment(blendedSegment); |
| 278 } | 284 } |
| 279 | 285 |
| 280 static inline PathCoordinateMode coordinateModeOfCommand(const SVGPathSegType& t ype) | |
| 281 { | |
| 282 if (type < PathSegMoveToAbs) | |
| 283 return AbsoluteCoordinates; | |
| 284 | |
| 285 // Odd number = relative command | |
| 286 if (type % 2) | |
| 287 return RelativeCoordinates; | |
| 288 | |
| 289 return AbsoluteCoordinates; | |
| 290 } | |
| 291 | |
| 292 bool SVGPathBlender::addAnimatedPath(unsigned repeatCount) | 286 bool SVGPathBlender::addAnimatedPath(unsigned repeatCount) |
| 293 { | 287 { |
| 294 TemporaryChange<unsigned> change(m_addTypesCount, repeatCount); | 288 TemporaryChange<unsigned> change(m_addTypesCount, repeatCount); |
| 295 return blendAnimatedPath(0); | 289 return blendAnimatedPath(0); |
| 296 } | 290 } |
| 297 | 291 |
| 298 bool SVGPathBlender::blendAnimatedPath(float progress) | 292 bool SVGPathBlender::blendAnimatedPath(float progress) |
| 299 { | 293 { |
| 300 m_isInFirstHalfOfAnimation = progress < 0.5f; | 294 m_isInFirstHalfOfAnimation = progress < 0.5f; |
| 301 m_progress = progress; | 295 m_progress = progress; |
| 302 | 296 |
| 303 bool fromSourceHadData = m_fromSource->hasMoreData(); | 297 bool fromSourceHadData = m_fromSource->hasMoreData(); |
| 304 while (m_toSource->hasMoreData()) { | 298 while (m_toSource->hasMoreData()) { |
| 305 PathSegmentData toSeg = m_toSource->parseSegment(); | 299 PathSegmentData toSeg = m_toSource->parseSegment(); |
| 306 if (toSeg.command == PathSegUnknown) | 300 if (toSeg.command == PathSegUnknown) |
| 307 return false; | 301 return false; |
| 308 | 302 |
| 309 PathSegmentData fromSeg; | 303 PathSegmentData fromSeg; |
| 310 fromSeg.command = toSeg.command; | 304 fromSeg.command = toSeg.command; |
| 311 | 305 |
| 312 if (m_fromSource->hasMoreData()) { | 306 if (m_fromSource->hasMoreData()) { |
| 313 fromSeg = m_fromSource->parseSegment(); | 307 fromSeg = m_fromSource->parseSegment(); |
| 314 if (fromSeg.command == PathSegUnknown) | 308 if (fromSeg.command == PathSegUnknown) |
| 315 return false; | 309 return false; |
| 316 } | 310 } |
| 317 | 311 |
| 318 if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType(toSe g.command)) | 312 m_typesAreEqual = fromSeg.command == toSeg.command; |
| 319 return false; | |
| 320 | 313 |
| 321 m_fromMode = coordinateModeOfCommand(fromSeg.command); | 314 // If the types are equal, they'll blend regardless of parameters. |
| 322 m_toMode = coordinateModeOfCommand(toSeg.command); | 315 if (!m_typesAreEqual) { |
| 316 // Addition require segments with the same type. | |
| 317 if (m_addTypesCount) | |
| 318 return false; | |
| 319 // Allow the segments to differ in "relativeness". | |
| 320 if (toAbsolutePathSegType(fromSeg.command) != toAbsolutePathSegType( toSeg.command)) | |
| 321 return false; | |
| 322 } | |
| 323 | 323 |
| 324 if (m_addTypesCount && m_fromMode != m_toMode) | 324 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
| |
| 325 return false; | 325 m_toIsAbsolute = isAbsolutePathSegType(toSeg.command); |
| 326 | 326 |
| 327 blendSegments(fromSeg, toSeg); | 327 blendSegments(fromSeg, toSeg); |
| 328 | 328 |
| 329 if (!fromSourceHadData) | 329 if (!fromSourceHadData) |
| 330 continue; | 330 continue; |
| 331 if (m_fromSource->hasMoreData() != m_toSource->hasMoreData()) | 331 if (m_fromSource->hasMoreData() != m_toSource->hasMoreData()) |
| 332 return false; | 332 return false; |
| 333 } | 333 } |
| 334 return true; | 334 return true; |
| 335 } | 335 } |
| 336 | 336 |
| 337 } | 337 } |
| OLD | NEW |