Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/animation/PathSVGInterpolation.h" | 6 #include "core/animation/PathSVGInterpolation.h" |
| 7 | 7 |
| 8 #include "core/svg/SVGPathByteStreamBuilder.h" | |
| 9 #include "core/svg/SVGPathByteStreamSource.h" | |
| 8 #include "core/svg/SVGPathElement.h" | 10 #include "core/svg/SVGPathElement.h" |
| 9 #include "core/svg/SVGPathSegArcAbs.h" | 11 #include "core/svg/SVGPathParser.h" |
| 10 #include "core/svg/SVGPathSegArcRel.h" | |
| 11 #include "core/svg/SVGPathSegClosePath.h" | |
| 12 #include "core/svg/SVGPathSegCurvetoCubicAbs.h" | |
| 13 #include "core/svg/SVGPathSegCurvetoCubicRel.h" | |
| 14 #include "core/svg/SVGPathSegCurvetoCubicSmoothAbs.h" | |
| 15 #include "core/svg/SVGPathSegCurvetoCubicSmoothRel.h" | |
| 16 #include "core/svg/SVGPathSegCurvetoQuadraticAbs.h" | |
| 17 #include "core/svg/SVGPathSegCurvetoQuadraticRel.h" | |
| 18 #include "core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h" | |
| 19 #include "core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h" | |
| 20 #include "core/svg/SVGPathSegLinetoAbs.h" | |
| 21 #include "core/svg/SVGPathSegLinetoHorizontalAbs.h" | |
| 22 #include "core/svg/SVGPathSegLinetoHorizontalRel.h" | |
| 23 #include "core/svg/SVGPathSegLinetoRel.h" | |
| 24 #include "core/svg/SVGPathSegLinetoVerticalAbs.h" | |
| 25 #include "core/svg/SVGPathSegLinetoVerticalRel.h" | |
| 26 #include "core/svg/SVGPathSegMovetoAbs.h" | |
| 27 #include "core/svg/SVGPathSegMovetoRel.h" | |
| 28 | 12 |
| 29 namespace blink { | 13 namespace blink { |
| 30 | 14 |
| 31 namespace { | 15 namespace { |
| 32 | 16 |
| 33 struct SubPathCoordinates { | 17 struct SubPathCoordinates { |
| 34 double initialX = 0; | 18 double initialX = 0; |
| 35 double initialY = 0; | 19 double initialY = 0; |
| 36 double currentX = 0; | 20 double currentX = 0; |
| 37 double currentY = 0; | 21 double currentY = 0; |
| 38 }; | 22 }; |
| 39 | 23 |
| 40 SVGPathSegType absolutePathSegType(const SVGPathSeg& item) | |
| 41 { | |
| 42 return toAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()) ); | |
| 43 } | |
| 44 | |
| 45 bool isAbsolutePathSegType(const SVGPathSeg& item) | |
| 46 { | |
| 47 return isAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()) ); | |
| 48 } | |
| 49 | |
| 50 PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isA bsolute, double currentValue) | 24 PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isA bsolute, double currentValue) |
| 51 { | 25 { |
| 52 if (isAbsolute) | 26 if (isAbsolute) |
| 53 return InterpolableNumber::create(value); | 27 return InterpolableNumber::create(value); |
| 54 return InterpolableNumber::create(currentValue + value); | 28 return InterpolableNumber::create(currentValue + value); |
| 55 } | 29 } |
| 56 | 30 |
| 57 double controlFromInterpolableValue(const InterpolableValue* number, bool isAbso lute, double currentValue) | 31 double controlFromInterpolableValue(const InterpolableValue* number, bool isAbso lute, double currentValue) |
| 58 { | 32 { |
| 59 double value = toInterpolableNumber(number)->value(); | 33 double value = toInterpolableNumber(number)->value(); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 75 double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAb solute, double& currentValue) | 49 double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAb solute, double& currentValue) |
| 76 { | 50 { |
| 77 double previousValue = currentValue; | 51 double previousValue = currentValue; |
| 78 currentValue = toInterpolableNumber(number)->value(); | 52 currentValue = toInterpolableNumber(number)->value(); |
| 79 | 53 |
| 80 if (isAbsolute) | 54 if (isAbsolute) |
| 81 return currentValue; | 55 return currentValue; |
| 82 return currentValue - previousValue; | 56 return currentValue - previousValue; |
| 83 } | 57 } |
| 84 | 58 |
| 85 PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const SVGPathS eg& item, SubPathCoordinates& coordinates) | 59 PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const PathSegm entData&, SubPathCoordinates& coordinates) |
| 86 { | 60 { |
| 87 coordinates.currentX = coordinates.initialX; | 61 coordinates.currentX = coordinates.initialX; |
| 88 coordinates.currentY = coordinates.initialY; | 62 coordinates.currentY = coordinates.initialY; |
| 89 | 63 |
| 90 // arbitrary | 64 // arbitrary |
| 91 return InterpolableBool::create(false); | 65 return InterpolableBool::create(false); |
| 92 } | 66 } |
| 93 | 67 |
| 94 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegClosePathFromInterpolableValue(const I nterpolableValue&, SVGPathSegType, SubPathCoordinates& coordinates, SVGPathEleme nt* element) | 68 PathSegmentData pathSegClosePathFromInterpolableValue(const InterpolableValue&, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 95 { | 69 { |
| 96 coordinates.currentX = coordinates.initialX; | 70 coordinates.currentX = coordinates.initialX; |
| 97 coordinates.currentY = coordinates.initialY; | 71 coordinates.currentY = coordinates.initialY; |
| 98 | 72 |
| 99 return SVGPathSegClosePath::create(element); | 73 PathSegmentData segment; |
| 74 segment.command = segType; | |
| 75 return segment; | |
| 100 } | 76 } |
| 101 | 77 |
| 102 PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const S VGPathSegSingleCoordinate& item, SubPathCoordinates& coordinates) | 78 PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates) |
| 103 { | 79 { |
| 104 bool isAbsolute = isAbsolutePathSegType(item); | 80 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 105 OwnPtr<InterpolableList> result = InterpolableList::create(2); | 81 OwnPtr<InterpolableList> result = InterpolableList::create(2); |
| 106 result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); | 82 result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX)); |
| 107 result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); | 83 result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY)); |
| 108 | 84 |
| 109 if (absolutePathSegType(item) == PathSegMoveToAbs) { | 85 if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) { |
| 110 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. | 86 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. |
| 111 coordinates.initialX = coordinates.currentX; | 87 coordinates.initialX = coordinates.currentX; |
| 112 coordinates.initialY = coordinates.currentY; | 88 coordinates.initialY = coordinates.currentY; |
| 113 } | 89 } |
| 114 | 90 |
| 115 return result.release(); | 91 return result.release(); |
| 116 } | 92 } |
| 117 | 93 |
| 118 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegSingleCoordinateFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) | 94 PathSegmentData pathSegSingleCoordinateFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 119 { | 95 { |
| 120 const InterpolableList& list = toInterpolableList(value); | 96 const InterpolableList& list = toInterpolableList(value); |
| 121 bool isAbsolute = isAbsolutePathSegType(segType); | 97 bool isAbsolute = isAbsolutePathSegType(segType); |
| 122 float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinate s.currentX); | 98 PathSegmentData segment; |
| 123 float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinate s.currentY); | 99 segment.command = segType; |
| 100 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsol ute, coordinates.currentX)); | |
| 101 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsol ute, coordinates.currentY)); | |
| 124 | 102 |
| 125 if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) { | 103 if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) { |
| 126 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. | 104 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. |
| 127 coordinates.initialX = coordinates.currentX; | 105 coordinates.initialX = coordinates.currentX; |
| 128 coordinates.initialY = coordinates.currentY; | 106 coordinates.initialY = coordinates.currentY; |
| 129 } | 107 } |
| 130 | 108 |
| 131 switch (segType) { | 109 return segment; |
| 132 case PathSegMoveToAbs: | |
| 133 return SVGPathSegMovetoAbs::create(element, x, y); | |
| 134 case PathSegMoveToRel: | |
| 135 return SVGPathSegMovetoRel::create(element, x, y); | |
| 136 case PathSegLineToAbs: | |
| 137 return SVGPathSegLinetoAbs::create(element, x, y); | |
| 138 case PathSegLineToRel: | |
| 139 return SVGPathSegLinetoRel::create(element, x, y); | |
| 140 case PathSegCurveToQuadraticSmoothAbs: | |
| 141 return SVGPathSegCurvetoQuadraticSmoothAbs::create(element, x, y); | |
| 142 case PathSegCurveToQuadraticSmoothRel: | |
| 143 return SVGPathSegCurvetoQuadraticSmoothRel::create(element, x, y); | |
| 144 default: | |
| 145 ASSERT_NOT_REACHED(); | |
| 146 return nullptr; | |
| 147 } | |
| 148 } | 110 } |
| 149 | 111 |
| 150 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const SVGPa thSegCurvetoCubic& item, SubPathCoordinates& coordinates) | 112 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const PathS egmentData& segment, SubPathCoordinates& coordinates) |
| 151 { | 113 { |
| 152 bool isAbsolute = isAbsolutePathSegType(item); | 114 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 153 OwnPtr<InterpolableList> result = InterpolableList::create(6); | 115 OwnPtr<InterpolableList> result = InterpolableList::create(6); |
| 154 result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates .currentX)); | 116 result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordina tes.currentX)); |
| 155 result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates .currentY)); | 117 result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordina tes.currentY)); |
| 156 result->set(2, controlToInterpolableValue(item.x2(), isAbsolute, coordinates .currentX)); | 118 result->set(2, controlToInterpolableValue(segment.x2(), isAbsolute, coordina tes.currentX)); |
| 157 result->set(3, controlToInterpolableValue(item.y2(), isAbsolute, coordinates .currentY)); | 119 result->set(3, controlToInterpolableValue(segment.y2(), isAbsolute, coordina tes.currentY)); |
| 158 result->set(4, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); | 120 result->set(4, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX)); |
| 159 result->set(5, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); | 121 result->set(5, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY)); |
| 160 return result.release(); | 122 return result.release(); |
| 161 } | 123 } |
| 162 | 124 |
| 163 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicFromInterpolableValue(cons t InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordina tes, SVGPathElement* element) | 125 PathSegmentData pathSegCurvetoCubicFromInterpolableValue(const InterpolableValue & value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 164 { | 126 { |
| 165 const InterpolableList& list = toInterpolableList(value); | 127 const InterpolableList& list = toInterpolableList(value); |
| 166 bool isAbsolute = isAbsolutePathSegType(segType); | 128 bool isAbsolute = isAbsolutePathSegType(segType); |
| 167 float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); | 129 PathSegmentData segment; |
| 168 float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); | 130 segment.command = segType; |
| 169 float x2 = controlFromInterpolableValue(list.get(2), isAbsolute, coordinates .currentX); | 131 segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX)); |
| 170 float y2 = controlFromInterpolableValue(list.get(3), isAbsolute, coordinates .currentY); | 132 segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY)); |
| 171 float x = specifiedFromInterpolableValue(list.get(4), isAbsolute, coordinate s.currentX); | 133 segment.point2.setX(controlFromInterpolableValue(list.get(2), isAbsolute, co ordinates.currentX)); |
| 172 float y = specifiedFromInterpolableValue(list.get(5), isAbsolute, coordinate s.currentY); | 134 segment.point2.setY(controlFromInterpolableValue(list.get(3), isAbsolute, co ordinates.currentY)); |
| 173 | 135 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(4), isAbsol ute, coordinates.currentX)); |
| 174 switch (segType) { | 136 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(5), isAbsol ute, coordinates.currentY)); |
| 175 case PathSegCurveToCubicAbs: | 137 return segment; |
| 176 return SVGPathSegCurvetoCubicAbs::create(element, x, y, x1, y1, x2, y2); | |
| 177 case PathSegCurveToCubicRel: | |
| 178 return SVGPathSegCurvetoCubicRel::create(element, x, y, x1, y1, x2, y2); | |
| 179 default: | |
| 180 ASSERT_NOT_REACHED(); | |
| 181 return nullptr; | |
| 182 } | |
| 183 } | 138 } |
| 184 | 139 |
| 185 PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const S VGPathSegCurvetoQuadratic& item, SubPathCoordinates& coordinates) | 140 PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates) |
| 186 { | 141 { |
| 187 bool isAbsolute = isAbsolutePathSegType(item); | 142 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 188 OwnPtr<InterpolableList> result = InterpolableList::create(4); | 143 OwnPtr<InterpolableList> result = InterpolableList::create(4); |
| 189 result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates .currentX)); | 144 result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordina tes.currentX)); |
| 190 result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates .currentY)); | 145 result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordina tes.currentY)); |
| 191 result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); | 146 result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX)); |
| 192 result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); | 147 result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY)); |
| 193 return result.release(); | 148 return result.release(); |
| 194 } | 149 } |
| 195 | 150 |
| 196 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoQuadraticFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) | 151 PathSegmentData pathSegCurvetoQuadraticFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 197 { | 152 { |
| 198 const InterpolableList& list = toInterpolableList(value); | 153 const InterpolableList& list = toInterpolableList(value); |
| 199 bool isAbsolute = isAbsolutePathSegType(segType); | 154 bool isAbsolute = isAbsolutePathSegType(segType); |
| 200 float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); | 155 PathSegmentData segment; |
| 201 float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); | 156 segment.command = segType; |
| 202 float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinate s.currentX); | 157 segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX)); |
| 203 float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinate s.currentY); | 158 segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY)); |
| 204 switch (segType) { | 159 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsol ute, coordinates.currentX)); |
| 205 case PathSegCurveToQuadraticAbs: | 160 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsol ute, coordinates.currentY)); |
| 206 return SVGPathSegCurvetoQuadraticAbs::create(element, x, y, x1, y1); | 161 return segment; |
| 207 case PathSegCurveToQuadraticRel: | |
| 208 return SVGPathSegCurvetoQuadraticRel::create(element, x, y, x1, y1); | |
| 209 default: | |
| 210 ASSERT_NOT_REACHED(); | |
| 211 return nullptr; | |
| 212 } | |
| 213 } | 162 } |
| 214 | 163 |
| 215 PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const SVGPathSegArc& item, SubPathCoordinates& coordinates) | 164 PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const PathSegmentDat a& segment, SubPathCoordinates& coordinates) |
| 216 { | 165 { |
| 217 bool isAbsolute = isAbsolutePathSegType(item); | 166 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 218 OwnPtr<InterpolableList> result = InterpolableList::create(7); | 167 OwnPtr<InterpolableList> result = InterpolableList::create(7); |
| 219 result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); | 168 result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX)); |
| 220 result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); | 169 result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY)); |
| 221 result->set(2, InterpolableNumber::create(item.r1())); | 170 result->set(2, InterpolableNumber::create(segment.r1())); |
| 222 result->set(3, InterpolableNumber::create(item.r2())); | 171 result->set(3, InterpolableNumber::create(segment.r2())); |
| 223 result->set(4, InterpolableNumber::create(item.angle())); | 172 result->set(4, InterpolableNumber::create(segment.arcAngle())); |
| 224 result->set(5, InterpolableBool::create(item.largeArcFlag())); | 173 result->set(5, InterpolableBool::create(segment.largeArcFlag())); |
| 225 result->set(6, InterpolableBool::create(item.sweepFlag())); | 174 result->set(6, InterpolableBool::create(segment.sweepFlag())); |
| 226 return result.release(); | 175 return result.release(); |
| 227 } | 176 } |
| 228 | 177 |
| 229 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegArcFromInterpolableValue(const Interpo lableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGP athElement* element) | 178 PathSegmentData pathSegArcFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 230 { | 179 { |
| 231 const InterpolableList& list = toInterpolableList(value); | 180 const InterpolableList& list = toInterpolableList(value); |
| 232 bool isAbsolute = isAbsolutePathSegType(segType); | 181 bool isAbsolute = isAbsolutePathSegType(segType); |
| 233 float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinate s.currentX); | 182 PathSegmentData segment; |
| 234 float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinate s.currentY); | 183 segment.command = segType; |
| 235 float r1 = toInterpolableNumber(list.get(2))->value(); | 184 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsol ute, coordinates.currentX)); |
| 236 float r2 = toInterpolableNumber(list.get(3))->value(); | 185 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsol ute, coordinates.currentY)); |
| 237 float angle = toInterpolableNumber(list.get(4))->value(); | 186 segment.point1.setX(toInterpolableNumber(list.get(2))->value()); |
| 238 bool largeArcFlag = toInterpolableBool(list.get(5))->value(); | 187 segment.point1.setY(toInterpolableNumber(list.get(3))->value()); |
| 239 bool sweepFlag = toInterpolableBool(list.get(6))->value(); | 188 segment.point2.setX(toInterpolableNumber(list.get(4))->value()); |
|
pdr.
2015/10/23 04:40:55
WDYT about making the re-use of point1 and point2
fs
2015/10/23 09:12:33
It has crossed my mind, but I think I'll punt on t
fs
2015/10/23 11:40:55
I ended up folding it in. Fun game: Find the 4 cha
| |
| 240 switch (segType) { | 189 segment.arcLarge = toInterpolableBool(list.get(5))->value(); |
| 241 case PathSegArcAbs: | 190 segment.arcSweep = toInterpolableBool(list.get(6))->value(); |
| 242 return SVGPathSegArcAbs::create(element, x, y, r1, r2, angle, largeArcFl ag, sweepFlag); | 191 return segment; |
| 243 case PathSegArcRel: | |
| 244 return SVGPathSegArcRel::create(element, x, y, r1, r2, angle, largeArcFl ag, sweepFlag); | |
| 245 default: | |
| 246 ASSERT_NOT_REACHED(); | |
| 247 return nullptr; | |
| 248 } | |
| 249 } | 192 } |
| 250 | 193 |
| 251 PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const S VGPathSegLinetoHorizontal& item, SubPathCoordinates& coordinates) | 194 PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates) |
| 252 { | 195 { |
| 253 bool isAbsolute = isAbsolutePathSegType(item); | 196 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 254 return specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.curren tX); | 197 return specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.cur rentX); |
| 255 } | 198 } |
| 256 | 199 |
| 257 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoHorizontalFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) | 200 PathSegmentData pathSegLinetoHorizontalFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 258 { | 201 { |
| 259 bool isAbsolute = isAbsolutePathSegType(segType); | 202 bool isAbsolute = isAbsolutePathSegType(segType); |
| 260 float x = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.cur rentX); | 203 PathSegmentData segment; |
| 261 | 204 segment.command = segType; |
| 262 switch (segType) { | 205 segment.targetPoint.setX(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentX)); |
| 263 case PathSegLineToHorizontalAbs: | 206 return segment; |
| 264 return SVGPathSegLinetoHorizontalAbs::create(element, x); | |
| 265 case PathSegLineToHorizontalRel: | |
| 266 return SVGPathSegLinetoHorizontalRel::create(element, x); | |
| 267 default: | |
| 268 ASSERT_NOT_REACHED(); | |
| 269 return nullptr; | |
| 270 } | |
| 271 } | 207 } |
| 272 | 208 |
| 273 PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const SVG PathSegLinetoVertical& item, SubPathCoordinates& coordinates) | 209 PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const Pat hSegmentData& segment, SubPathCoordinates& coordinates) |
| 274 { | 210 { |
| 275 bool isAbsolute = isAbsolutePathSegType(item); | 211 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 276 return specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.curren tY); | 212 return specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.cur rentY); |
| 277 } | 213 } |
| 278 | 214 |
| 279 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoVerticalFromInterpolableValue(co nst InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordi nates, SVGPathElement* element) | 215 PathSegmentData pathSegLinetoVerticalFromInterpolableValue(const InterpolableVal ue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 280 { | 216 { |
| 281 bool isAbsolute = isAbsolutePathSegType(segType); | 217 bool isAbsolute = isAbsolutePathSegType(segType); |
| 282 float y = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.cur rentY); | 218 PathSegmentData segment; |
| 283 | 219 segment.command = segType; |
| 284 switch (segType) { | 220 segment.targetPoint.setY(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentY)); |
| 285 case PathSegLineToVerticalAbs: | 221 return segment; |
| 286 return SVGPathSegLinetoVerticalAbs::create(element, y); | |
| 287 case PathSegLineToVerticalRel: | |
| 288 return SVGPathSegLinetoVerticalRel::create(element, y); | |
| 289 default: | |
| 290 ASSERT_NOT_REACHED(); | |
| 291 return nullptr; | |
| 292 } | |
| 293 } | 222 } |
| 294 | 223 |
| 295 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const SVGPathSegCurvetoCubicSmooth& item, SubPathCoordinates& coordinates) | 224 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates) |
| 296 { | 225 { |
| 297 bool isAbsolute = isAbsolutePathSegType(item); | 226 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 298 OwnPtr<InterpolableList> result = InterpolableList::create(4); | 227 OwnPtr<InterpolableList> result = InterpolableList::create(4); |
| 299 result->set(0, controlToInterpolableValue(item.x2(), isAbsolute, coordinates .currentX)); | 228 result->set(0, controlToInterpolableValue(segment.x2(), isAbsolute, coordina tes.currentX)); |
| 300 result->set(1, controlToInterpolableValue(item.y2(), isAbsolute, coordinates .currentY)); | 229 result->set(1, controlToInterpolableValue(segment.y2(), isAbsolute, coordina tes.currentY)); |
| 301 result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); | 230 result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX)); |
| 302 result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); | 231 result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY)); |
| 303 return result.release(); | 232 return result.release(); |
| 304 } | 233 } |
| 305 | 234 |
| 306 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicSmoothFromInterpolableValu e(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& co ordinates, SVGPathElement* element) | 235 PathSegmentData pathSegCurvetoCubicSmoothFromInterpolableValue(const Interpolabl eValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates) |
| 307 { | 236 { |
| 308 const InterpolableList& list = toInterpolableList(value); | 237 const InterpolableList& list = toInterpolableList(value); |
| 309 bool isAbsolute = isAbsolutePathSegType(segType); | 238 bool isAbsolute = isAbsolutePathSegType(segType); |
| 310 float x2 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); | 239 PathSegmentData segment; |
| 311 float y2 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); | 240 segment.command = segType; |
| 312 float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinate s.currentX); | 241 segment.point2.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX)); |
| 313 float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinate s.currentY); | 242 segment.point2.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY)); |
| 314 switch (segType) { | 243 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsol ute, coordinates.currentX)); |
| 315 case PathSegCurveToCubicSmoothAbs: | 244 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsol ute, coordinates.currentY)); |
| 316 return SVGPathSegCurvetoCubicSmoothAbs::create(element, x, y, x2, y2); | 245 return segment; |
| 317 case PathSegCurveToCubicSmoothRel: | |
| 318 return SVGPathSegCurvetoCubicSmoothRel::create(element, x, y, x2, y2); | |
| 319 default: | |
| 320 ASSERT_NOT_REACHED(); | |
| 321 return nullptr; | |
| 322 } | |
| 323 } | 246 } |
| 324 | 247 |
| 325 PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const SVGPathSeg& item, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType) | 248 PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType) |
| 326 { | 249 { |
| 327 SVGPathSegType segType = static_cast<SVGPathSegType>(item.pathSegType()); | 250 if (ptrSegType) |
| 251 *ptrSegType = segment.command; | |
| 328 | 252 |
| 329 if (ptrSegType) | 253 switch (segment.command) { |
| 330 *ptrSegType = segType; | |
| 331 | |
| 332 switch (segType) { | |
| 333 case PathSegClosePath: | 254 case PathSegClosePath: |
| 334 return pathSegClosePathToInterpolableValue(item, coordinates); | 255 return pathSegClosePathToInterpolableValue(segment, coordinates); |
| 335 | 256 |
| 336 case PathSegMoveToAbs: | 257 case PathSegMoveToAbs: |
| 337 case PathSegMoveToRel: | 258 case PathSegMoveToRel: |
| 338 case PathSegLineToAbs: | 259 case PathSegLineToAbs: |
| 339 case PathSegLineToRel: | 260 case PathSegLineToRel: |
| 340 case PathSegCurveToQuadraticSmoothAbs: | 261 case PathSegCurveToQuadraticSmoothAbs: |
| 341 case PathSegCurveToQuadraticSmoothRel: | 262 case PathSegCurveToQuadraticSmoothRel: |
| 342 return pathSegSingleCoordinateToInterpolableValue(static_cast<const SVGP athSegSingleCoordinate&>(item), coordinates); | 263 return pathSegSingleCoordinateToInterpolableValue(segment, coordinates); |
| 343 | 264 |
| 344 case PathSegCurveToCubicAbs: | 265 case PathSegCurveToCubicAbs: |
| 345 case PathSegCurveToCubicRel: | 266 case PathSegCurveToCubicRel: |
| 346 return pathSegCurvetoCubicToInterpolableValue(static_cast<const SVGPathS egCurvetoCubic&>(item), coordinates); | 267 return pathSegCurvetoCubicToInterpolableValue(segment, coordinates); |
| 347 | 268 |
| 348 case PathSegCurveToQuadraticAbs: | 269 case PathSegCurveToQuadraticAbs: |
| 349 case PathSegCurveToQuadraticRel: | 270 case PathSegCurveToQuadraticRel: |
| 350 return pathSegCurvetoQuadraticToInterpolableValue(static_cast<const SVGP athSegCurvetoQuadratic&>(item), coordinates); | 271 return pathSegCurvetoQuadraticToInterpolableValue(segment, coordinates); |
| 351 | 272 |
| 352 case PathSegArcAbs: | 273 case PathSegArcAbs: |
| 353 case PathSegArcRel: | 274 case PathSegArcRel: |
| 354 return pathSegArcToInterpolableValue(static_cast<const SVGPathSegArc&>(i tem), coordinates); | 275 return pathSegArcToInterpolableValue(segment, coordinates); |
| 355 | 276 |
| 356 case PathSegLineToHorizontalAbs: | 277 case PathSegLineToHorizontalAbs: |
| 357 case PathSegLineToHorizontalRel: | 278 case PathSegLineToHorizontalRel: |
| 358 return pathSegLinetoHorizontalToInterpolableValue(static_cast<const SVGP athSegLinetoHorizontal&>(item), coordinates); | 279 return pathSegLinetoHorizontalToInterpolableValue(segment, coordinates); |
| 359 | 280 |
| 360 case PathSegLineToVerticalAbs: | 281 case PathSegLineToVerticalAbs: |
| 361 case PathSegLineToVerticalRel: | 282 case PathSegLineToVerticalRel: |
| 362 return pathSegLinetoVerticalToInterpolableValue(static_cast<const SVGPat hSegLinetoVertical&>(item), coordinates); | 283 return pathSegLinetoVerticalToInterpolableValue(segment, coordinates); |
| 363 | 284 |
| 364 case PathSegCurveToCubicSmoothAbs: | 285 case PathSegCurveToCubicSmoothAbs: |
| 365 case PathSegCurveToCubicSmoothRel: | 286 case PathSegCurveToCubicSmoothRel: |
| 366 return pathSegCurvetoCubicSmoothToInterpolableValue(static_cast<const SV GPathSegCurvetoCubicSmooth&>(item), coordinates); | 287 return pathSegCurvetoCubicSmoothToInterpolableValue(segment, coordinates ); |
| 367 | 288 |
| 368 case PathSegUnknown: | 289 case PathSegUnknown: |
| 369 ASSERT_NOT_REACHED(); | 290 ASSERT_NOT_REACHED(); |
| 370 } | 291 } |
| 371 ASSERT_NOT_REACHED(); | 292 ASSERT_NOT_REACHED(); |
| 372 return nullptr; | 293 return nullptr; |
| 373 } | 294 } |
| 374 | 295 |
| 375 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegFromInterpolableValue(const Interpolab leValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPath Element* element) | 296 PathSegmentData pathSegFromInterpolableValue(const InterpolableValue& value, SVG PathSegType segType, SubPathCoordinates& coordinates) |
| 376 { | 297 { |
| 377 switch (segType) { | 298 switch (segType) { |
| 378 case PathSegClosePath: | 299 case PathSegClosePath: |
| 379 return pathSegClosePathFromInterpolableValue(value, segType, coordinates , element); | 300 return pathSegClosePathFromInterpolableValue(value, segType, coordinates ); |
| 380 | 301 |
| 381 case PathSegMoveToAbs: | 302 case PathSegMoveToAbs: |
| 382 case PathSegMoveToRel: | 303 case PathSegMoveToRel: |
| 383 case PathSegLineToAbs: | 304 case PathSegLineToAbs: |
| 384 case PathSegLineToRel: | 305 case PathSegLineToRel: |
| 385 case PathSegCurveToQuadraticSmoothAbs: | 306 case PathSegCurveToQuadraticSmoothAbs: |
| 386 case PathSegCurveToQuadraticSmoothRel: | 307 case PathSegCurveToQuadraticSmoothRel: |
| 387 return pathSegSingleCoordinateFromInterpolableValue(value, segType, coor dinates, element); | 308 return pathSegSingleCoordinateFromInterpolableValue(value, segType, coor dinates); |
| 388 | 309 |
| 389 case PathSegCurveToCubicAbs: | 310 case PathSegCurveToCubicAbs: |
| 390 case PathSegCurveToCubicRel: | 311 case PathSegCurveToCubicRel: |
| 391 return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordina tes, element); | 312 return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordina tes); |
| 392 | 313 |
| 393 case PathSegCurveToQuadraticAbs: | 314 case PathSegCurveToQuadraticAbs: |
| 394 case PathSegCurveToQuadraticRel: | 315 case PathSegCurveToQuadraticRel: |
| 395 return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coor dinates, element); | 316 return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coor dinates); |
| 396 | 317 |
| 397 case PathSegArcAbs: | 318 case PathSegArcAbs: |
| 398 case PathSegArcRel: | 319 case PathSegArcRel: |
| 399 return pathSegArcFromInterpolableValue(value, segType, coordinates, elem ent); | 320 return pathSegArcFromInterpolableValue(value, segType, coordinates); |
| 400 | 321 |
| 401 case PathSegLineToHorizontalAbs: | 322 case PathSegLineToHorizontalAbs: |
| 402 case PathSegLineToHorizontalRel: | 323 case PathSegLineToHorizontalRel: |
| 403 return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coor dinates, element); | 324 return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coor dinates); |
| 404 | 325 |
| 405 case PathSegLineToVerticalAbs: | 326 case PathSegLineToVerticalAbs: |
| 406 case PathSegLineToVerticalRel: | 327 case PathSegLineToVerticalRel: |
| 407 return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordi nates, element); | 328 return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordi nates); |
| 408 | 329 |
| 409 case PathSegCurveToCubicSmoothAbs: | 330 case PathSegCurveToCubicSmoothAbs: |
| 410 case PathSegCurveToCubicSmoothRel: | 331 case PathSegCurveToCubicSmoothRel: |
| 411 return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, co ordinates, element); | 332 return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, co ordinates); |
| 412 | 333 |
| 413 case PathSegUnknown: | 334 case PathSegUnknown: |
| 414 ASSERT_NOT_REACHED(); | 335 ASSERT_NOT_REACHED(); |
| 415 } | 336 } |
| 416 ASSERT_NOT_REACHED(); | 337 ASSERT_NOT_REACHED(); |
| 417 return nullptr; | 338 return PathSegmentData(); |
| 339 } | |
| 340 | |
| 341 class InterpolablePathSource : public SVGPathSource { | |
| 342 public: | |
| 343 InterpolablePathSource(const InterpolableList& listValue, const Vector<SVGPa thSegType>& pathSegTypes) | |
| 344 : m_currentIndex(0) | |
| 345 , m_list(listValue) | |
| 346 , m_segmentTypes(pathSegTypes) | |
| 347 { | |
| 348 ASSERT(m_list.length() == m_segmentTypes.size()); | |
| 349 } | |
| 350 | |
| 351 private: | |
| 352 bool hasMoreData() const override; | |
| 353 SVGPathSegType peekSegmentType() override; | |
| 354 PathSegmentData parseSegment() override; | |
| 355 | |
| 356 SubPathCoordinates m_normalizationState; | |
| 357 size_t m_currentIndex; | |
| 358 const InterpolableList& m_list; | |
| 359 const Vector<SVGPathSegType>& m_segmentTypes; | |
| 360 }; | |
| 361 | |
| 362 bool InterpolablePathSource::hasMoreData() const | |
| 363 { | |
| 364 return m_currentIndex < m_list.length(); | |
| 365 } | |
| 366 | |
| 367 SVGPathSegType InterpolablePathSource::peekSegmentType() | |
| 368 { | |
| 369 ASSERT(hasMoreData()); | |
| 370 return m_segmentTypes.at(m_currentIndex); | |
| 371 } | |
| 372 | |
| 373 PathSegmentData InterpolablePathSource::parseSegment() | |
| 374 { | |
| 375 PathSegmentData segment = pathSegFromInterpolableValue(*m_list.get(m_current Index), m_segmentTypes.at(m_currentIndex), m_normalizationState); | |
| 376 ++m_currentIndex; | |
| 377 return segment; | |
| 378 } | |
| 379 | |
| 380 size_t countPathCommands(const SVGPathByteStream& path) | |
| 381 { | |
| 382 size_t count = 0; | |
| 383 SVGPathByteStreamSource pathSource(path); | |
| 384 while (pathSource.hasMoreData()) { | |
| 385 pathSource.parseSegment(); | |
| 386 ++count; | |
| 387 } | |
| 388 return count; | |
| 418 } | 389 } |
| 419 | 390 |
| 420 } // namespace | 391 } // namespace |
| 421 | 392 |
| 422 PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa se* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) | 393 PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa se* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) |
| 423 { | 394 { |
| 424 ASSERT(start->type() == SVGPathSegList::classType()); | 395 ASSERT(start->type() == SVGPath::classType()); |
| 425 ASSERT(end->type() == SVGPathSegList::classType()); | 396 ASSERT(end->type() == SVGPath::classType()); |
| 426 | 397 |
| 427 SVGPathSegList* startList = static_cast<SVGPathSegList*>(start); | 398 const SVGPathByteStream& startPath = static_cast<SVGPath*>(start)->byteStrea m(); |
| 428 SVGPathSegList* endList = static_cast<SVGPathSegList*>(end); | 399 const SVGPathByteStream& endPath = static_cast<SVGPath*>(end)->byteStream(); |
| 429 size_t length = startList->length(); | 400 |
| 430 if (length != endList->length()) | 401 if (startPath.size() != endPath.size()) |
| 431 return nullptr; | 402 return nullptr; |
| 432 | 403 |
| 404 size_t length = countPathCommands(startPath); | |
| 405 | |
| 406 SVGPathByteStreamSource startPathSource(startPath); | |
| 407 SVGPathByteStreamSource endPathSource(endPath); | |
| 408 | |
| 433 Vector<SVGPathSegType> pathSegTypes(length); | 409 Vector<SVGPathSegType> pathSegTypes(length); |
| 434 OwnPtr<InterpolableList> startValue = InterpolableList::create(length); | 410 OwnPtr<InterpolableList> startValue = InterpolableList::create(length); |
| 435 OwnPtr<InterpolableList> endValue = InterpolableList::create(length); | 411 OwnPtr<InterpolableList> endValue = InterpolableList::create(length); |
| 436 SubPathCoordinates startCoordinates; | 412 SubPathCoordinates startCoordinates; |
| 437 SubPathCoordinates endCoordinates; | 413 SubPathCoordinates endCoordinates; |
| 438 for (size_t i = 0; i < length; i++) { | 414 size_t i = 0; |
| 439 if (absolutePathSegType(*startList->at(i)) != absolutePathSegType(*endLi st->at(i))) | 415 while (startPathSource.hasMoreData()) { |
| 416 if (toAbsolutePathSegType(startPathSource.peekSegmentType()) != toAbsolu tePathSegType(endPathSource.peekSegmentType())) | |
| 440 return nullptr; | 417 return nullptr; |
| 441 | 418 |
| 442 // Like Firefox SMIL, we use the final path seg type. | 419 // Like Firefox SMIL, we use the final path seg type. |
| 443 startValue->set(i, pathSegToInterpolableValue(*startList->at(i), startCo ordinates, nullptr)); | 420 const PathSegmentData startSeg = startPathSource.parseSegment(); |
| 444 endValue->set(i, pathSegToInterpolableValue(*endList->at(i), endCoordina tes, &pathSegTypes.at(i))); | 421 startValue->set(i, pathSegToInterpolableValue(startSeg, startCoordinates , nullptr)); |
| 422 | |
| 423 const PathSegmentData endSeg = endPathSource.parseSegment(); | |
| 424 endValue->set(i, pathSegToInterpolableValue(endSeg, endCoordinates, &pat hSegTypes.at(i))); | |
| 425 | |
| 426 ++i; | |
| 445 } | 427 } |
| 428 ASSERT(!endPathSource.hasMoreData()); | |
| 429 ASSERT(i == length); | |
| 446 | 430 |
| 447 return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.rele ase(), attribute, pathSegTypes)); | 431 return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.rele ase(), attribute, pathSegTypes)); |
| 448 } | 432 } |
| 449 | 433 |
| 450 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableVa lue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes, SVGPathElement* element) | 434 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableVa lue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes) |
| 451 { | 435 { |
| 452 const InterpolableList& listValue = toInterpolableList(value); | 436 RefPtrWillBeRawPtr<SVGPath> result = SVGPath::create(); |
| 453 RefPtrWillBeRawPtr<SVGPathSegList> result = SVGPathSegList::create(element); | 437 InterpolablePathSource source(toInterpolableList(value), pathSegTypes); |
| 454 SubPathCoordinates coordinates; | 438 SVGPathByteStreamBuilder builder(result->mutableByteStream()); |
| 455 for (size_t i = 0; i < listValue.length(); i++) | 439 SVGPathParser parser(&source, &builder); |
| 456 result->append(pathSegFromInterpolableValue(*listValue.get(i), pathSegTy pes.at(i), coordinates, element)); | 440 parser.parsePathDataFromSource(UnalteredParsing, false); |
| 457 return result.release(); | 441 return result.release(); |
| 458 } | 442 } |
| 459 | 443 |
| 460 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue( SVGElement& element) const | 444 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue( SVGElement&) const |
| 461 { | 445 { |
| 462 return fromInterpolableValue(*m_cachedValue, m_pathSegTypes, toSVGPathElemen t(&element)); | 446 return fromInterpolableValue(*m_cachedValue, m_pathSegTypes); |
| 463 } | 447 } |
| 464 | 448 |
| 465 } | 449 } |
| OLD | NEW |