OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "core/animation/SVGPathSegInterpolationFunctions.h" |
| 7 |
| 8 namespace blink { |
| 9 |
| 10 |
| 11 PassOwnPtr<InterpolableNumber> consumeControlAxis(double value, bool isAbsolute,
double currentValue) |
| 12 { |
| 13 return InterpolableNumber::create(isAbsolute ? value : currentValue + value)
; |
| 14 } |
| 15 |
| 16 double consumeInterpolableControlAxis(const InterpolableValue* number, bool isAb
solute, double currentValue) |
| 17 { |
| 18 double value = toInterpolableNumber(number)->value(); |
| 19 return isAbsolute ? value : value - currentValue; |
| 20 } |
| 21 |
| 22 PassOwnPtr<InterpolableNumber> consumeCoordinateAxis(double value, bool isAbsolu
te, double& currentValue) |
| 23 { |
| 24 if (isAbsolute) |
| 25 currentValue = value; |
| 26 else |
| 27 currentValue += value; |
| 28 return InterpolableNumber::create(currentValue); |
| 29 } |
| 30 |
| 31 double consumeInterpolableCoordinateAxis(const InterpolableValue* number, bool i
sAbsolute, double& currentValue) |
| 32 { |
| 33 double previousValue = currentValue; |
| 34 currentValue = toInterpolableNumber(number)->value(); |
| 35 return isAbsolute ? currentValue : currentValue - previousValue; |
| 36 } |
| 37 |
| 38 PassOwnPtr<InterpolableValue> consumeClosePath(const PathSegmentData&, PathCoord
inates& coordinates) |
| 39 { |
| 40 coordinates.currentX = coordinates.initialX; |
| 41 coordinates.currentY = coordinates.initialY; |
| 42 return InterpolableList::create(0); |
| 43 } |
| 44 |
| 45 PathSegmentData consumeInterpolableClosePath(const InterpolableValue&, SVGPathSe
gType segType, PathCoordinates& coordinates) |
| 46 { |
| 47 coordinates.currentX = coordinates.initialX; |
| 48 coordinates.currentY = coordinates.initialY; |
| 49 |
| 50 PathSegmentData segment; |
| 51 segment.command = segType; |
| 52 return segment; |
| 53 } |
| 54 |
| 55 PassOwnPtr<InterpolableValue> consumeSingleCoordinate(const PathSegmentData& seg
ment, PathCoordinates& coordinates) |
| 56 { |
| 57 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 58 OwnPtr<InterpolableList> result = InterpolableList::create(2); |
| 59 result->set(0, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.cu
rrentX)); |
| 60 result->set(1, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.cu
rrentY)); |
| 61 |
| 62 if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) { |
| 63 // Any upcoming 'closepath' commands bring us back to the location we ha
ve just moved to. |
| 64 coordinates.initialX = coordinates.currentX; |
| 65 coordinates.initialY = coordinates.currentY; |
| 66 } |
| 67 |
| 68 return result.release(); |
| 69 } |
| 70 |
| 71 PathSegmentData consumeInterpolableSingleCoordinate(const InterpolableValue& val
ue, SVGPathSegType segType, PathCoordinates& coordinates) |
| 72 { |
| 73 const InterpolableList& list = toInterpolableList(value); |
| 74 bool isAbsolute = isAbsolutePathSegType(segType); |
| 75 PathSegmentData segment; |
| 76 segment.command = segType; |
| 77 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(list.get(0), isAb
solute, coordinates.currentX)); |
| 78 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(list.get(1), isAb
solute, coordinates.currentY)); |
| 79 |
| 80 if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) { |
| 81 // Any upcoming 'closepath' commands bring us back to the location we ha
ve just moved to. |
| 82 coordinates.initialX = coordinates.currentX; |
| 83 coordinates.initialY = coordinates.currentY; |
| 84 } |
| 85 |
| 86 return segment; |
| 87 } |
| 88 |
| 89 PassOwnPtr<InterpolableValue> consumeCurvetoCubic(const PathSegmentData& segment
, PathCoordinates& coordinates) |
| 90 { |
| 91 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 92 OwnPtr<InterpolableList> result = InterpolableList::create(6); |
| 93 result->set(0, consumeControlAxis(segment.x1(), isAbsolute, coordinates.curr
entX)); |
| 94 result->set(1, consumeControlAxis(segment.y1(), isAbsolute, coordinates.curr
entY)); |
| 95 result->set(2, consumeControlAxis(segment.x2(), isAbsolute, coordinates.curr
entX)); |
| 96 result->set(3, consumeControlAxis(segment.y2(), isAbsolute, coordinates.curr
entY)); |
| 97 result->set(4, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.cu
rrentX)); |
| 98 result->set(5, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.cu
rrentY)); |
| 99 return result.release(); |
| 100 } |
| 101 |
| 102 PathSegmentData consumeInterpolableCurvetoCubic(const InterpolableValue& value,
SVGPathSegType segType, PathCoordinates& coordinates) |
| 103 { |
| 104 const InterpolableList& list = toInterpolableList(value); |
| 105 bool isAbsolute = isAbsolutePathSegType(segType); |
| 106 PathSegmentData segment; |
| 107 segment.command = segType; |
| 108 segment.point1.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
coordinates.currentX)); |
| 109 segment.point1.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
coordinates.currentY)); |
| 110 segment.point2.setX(consumeInterpolableControlAxis(list.get(2), isAbsolute,
coordinates.currentX)); |
| 111 segment.point2.setY(consumeInterpolableControlAxis(list.get(3), isAbsolute,
coordinates.currentY)); |
| 112 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(list.get(4), isAb
solute, coordinates.currentX)); |
| 113 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(list.get(5), isAb
solute, coordinates.currentY)); |
| 114 return segment; |
| 115 } |
| 116 |
| 117 PassOwnPtr<InterpolableValue> consumeCurvetoQuadratic(const PathSegmentData& seg
ment, PathCoordinates& coordinates) |
| 118 { |
| 119 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 120 OwnPtr<InterpolableList> result = InterpolableList::create(4); |
| 121 result->set(0, consumeControlAxis(segment.x1(), isAbsolute, coordinates.curr
entX)); |
| 122 result->set(1, consumeControlAxis(segment.y1(), isAbsolute, coordinates.curr
entY)); |
| 123 result->set(2, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.cu
rrentX)); |
| 124 result->set(3, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.cu
rrentY)); |
| 125 return result.release(); |
| 126 } |
| 127 |
| 128 PathSegmentData consumeInterpolableCurvetoQuadratic(const InterpolableValue& val
ue, SVGPathSegType segType, PathCoordinates& coordinates) |
| 129 { |
| 130 const InterpolableList& list = toInterpolableList(value); |
| 131 bool isAbsolute = isAbsolutePathSegType(segType); |
| 132 PathSegmentData segment; |
| 133 segment.command = segType; |
| 134 segment.point1.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
coordinates.currentX)); |
| 135 segment.point1.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
coordinates.currentY)); |
| 136 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(list.get(2), isAb
solute, coordinates.currentX)); |
| 137 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(list.get(3), isAb
solute, coordinates.currentY)); |
| 138 return segment; |
| 139 } |
| 140 |
| 141 PassOwnPtr<InterpolableValue> consumeArc(const PathSegmentData& segment, PathCoo
rdinates& coordinates) |
| 142 { |
| 143 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 144 OwnPtr<InterpolableList> result = InterpolableList::create(7); |
| 145 result->set(0, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.cu
rrentX)); |
| 146 result->set(1, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.cu
rrentY)); |
| 147 result->set(2, InterpolableNumber::create(segment.r1())); |
| 148 result->set(3, InterpolableNumber::create(segment.r2())); |
| 149 result->set(4, InterpolableNumber::create(segment.arcAngle())); |
| 150 result->set(5, InterpolableBool::create(segment.largeArcFlag())); |
| 151 result->set(6, InterpolableBool::create(segment.sweepFlag())); |
| 152 return result.release(); |
| 153 } |
| 154 |
| 155 PathSegmentData consumeInterpolableArc(const InterpolableValue& value, SVGPathSe
gType segType, PathCoordinates& coordinates) |
| 156 { |
| 157 const InterpolableList& list = toInterpolableList(value); |
| 158 bool isAbsolute = isAbsolutePathSegType(segType); |
| 159 PathSegmentData segment; |
| 160 segment.command = segType; |
| 161 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(list.get(0), isAb
solute, coordinates.currentX)); |
| 162 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(list.get(1), isAb
solute, coordinates.currentY)); |
| 163 segment.arcRadii().setX(toInterpolableNumber(list.get(2))->value()); |
| 164 segment.arcRadii().setY(toInterpolableNumber(list.get(3))->value()); |
| 165 segment.setArcAngle(toInterpolableNumber(list.get(4))->value()); |
| 166 segment.arcLarge = toInterpolableBool(list.get(5))->value(); |
| 167 segment.arcSweep = toInterpolableBool(list.get(6))->value(); |
| 168 return segment; |
| 169 } |
| 170 |
| 171 PassOwnPtr<InterpolableValue> consumeLinetoHorizontal(const PathSegmentData& seg
ment, PathCoordinates& coordinates) |
| 172 { |
| 173 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 174 return consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX); |
| 175 } |
| 176 |
| 177 PathSegmentData consumeInterpolableLinetoHorizontal(const InterpolableValue& val
ue, SVGPathSegType segType, PathCoordinates& coordinates) |
| 178 { |
| 179 bool isAbsolute = isAbsolutePathSegType(segType); |
| 180 PathSegmentData segment; |
| 181 segment.command = segType; |
| 182 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(&value, isAbsolut
e, coordinates.currentX)); |
| 183 return segment; |
| 184 } |
| 185 |
| 186 PassOwnPtr<InterpolableValue> consumeLinetoVertical(const PathSegmentData& segme
nt, PathCoordinates& coordinates) |
| 187 { |
| 188 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 189 return consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY); |
| 190 } |
| 191 |
| 192 PathSegmentData consumeInterpolableLinetoVertical(const InterpolableValue& value
, SVGPathSegType segType, PathCoordinates& coordinates) |
| 193 { |
| 194 bool isAbsolute = isAbsolutePathSegType(segType); |
| 195 PathSegmentData segment; |
| 196 segment.command = segType; |
| 197 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(&value, isAbsolut
e, coordinates.currentY)); |
| 198 return segment; |
| 199 } |
| 200 |
| 201 PassOwnPtr<InterpolableValue> consumeCurvetoCubicSmooth(const PathSegmentData& s
egment, PathCoordinates& coordinates) |
| 202 { |
| 203 bool isAbsolute = isAbsolutePathSegType(segment.command); |
| 204 OwnPtr<InterpolableList> result = InterpolableList::create(4); |
| 205 result->set(0, consumeControlAxis(segment.x2(), isAbsolute, coordinates.curr
entX)); |
| 206 result->set(1, consumeControlAxis(segment.y2(), isAbsolute, coordinates.curr
entY)); |
| 207 result->set(2, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.cu
rrentX)); |
| 208 result->set(3, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.cu
rrentY)); |
| 209 return result.release(); |
| 210 } |
| 211 |
| 212 PathSegmentData consumeInterpolableCurvetoCubicSmooth(const InterpolableValue& v
alue, SVGPathSegType segType, PathCoordinates& coordinates) |
| 213 { |
| 214 const InterpolableList& list = toInterpolableList(value); |
| 215 bool isAbsolute = isAbsolutePathSegType(segType); |
| 216 PathSegmentData segment; |
| 217 segment.command = segType; |
| 218 segment.point2.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
coordinates.currentX)); |
| 219 segment.point2.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
coordinates.currentY)); |
| 220 segment.targetPoint.setX(consumeInterpolableCoordinateAxis(list.get(2), isAb
solute, coordinates.currentX)); |
| 221 segment.targetPoint.setY(consumeInterpolableCoordinateAxis(list.get(3), isAb
solute, coordinates.currentY)); |
| 222 return segment; |
| 223 } |
| 224 |
| 225 PassOwnPtr<InterpolableValue> SVGPathSegInterpolationFunctions::consumePathSeg(c
onst PathSegmentData& segment, PathCoordinates& coordinates) |
| 226 { |
| 227 switch (segment.command) { |
| 228 case PathSegClosePath: |
| 229 return consumeClosePath(segment, coordinates); |
| 230 |
| 231 case PathSegMoveToAbs: |
| 232 case PathSegMoveToRel: |
| 233 case PathSegLineToAbs: |
| 234 case PathSegLineToRel: |
| 235 case PathSegCurveToQuadraticSmoothAbs: |
| 236 case PathSegCurveToQuadraticSmoothRel: |
| 237 return consumeSingleCoordinate(segment, coordinates); |
| 238 |
| 239 case PathSegCurveToCubicAbs: |
| 240 case PathSegCurveToCubicRel: |
| 241 return consumeCurvetoCubic(segment, coordinates); |
| 242 |
| 243 case PathSegCurveToQuadraticAbs: |
| 244 case PathSegCurveToQuadraticRel: |
| 245 return consumeCurvetoQuadratic(segment, coordinates); |
| 246 |
| 247 case PathSegArcAbs: |
| 248 case PathSegArcRel: |
| 249 return consumeArc(segment, coordinates); |
| 250 |
| 251 case PathSegLineToHorizontalAbs: |
| 252 case PathSegLineToHorizontalRel: |
| 253 return consumeLinetoHorizontal(segment, coordinates); |
| 254 |
| 255 case PathSegLineToVerticalAbs: |
| 256 case PathSegLineToVerticalRel: |
| 257 return consumeLinetoVertical(segment, coordinates); |
| 258 |
| 259 case PathSegCurveToCubicSmoothAbs: |
| 260 case PathSegCurveToCubicSmoothRel: |
| 261 return consumeCurvetoCubicSmooth(segment, coordinates); |
| 262 |
| 263 case PathSegUnknown: |
| 264 default: |
| 265 ASSERT_NOT_REACHED(); |
| 266 return nullptr; |
| 267 } |
| 268 } |
| 269 |
| 270 PathSegmentData SVGPathSegInterpolationFunctions::consumeInterpolablePathSeg(con
st InterpolableValue& value, SVGPathSegType segType, PathCoordinates& coordinate
s) |
| 271 { |
| 272 switch (segType) { |
| 273 case PathSegClosePath: |
| 274 return consumeInterpolableClosePath(value, segType, coordinates); |
| 275 |
| 276 case PathSegMoveToAbs: |
| 277 case PathSegMoveToRel: |
| 278 case PathSegLineToAbs: |
| 279 case PathSegLineToRel: |
| 280 case PathSegCurveToQuadraticSmoothAbs: |
| 281 case PathSegCurveToQuadraticSmoothRel: |
| 282 return consumeInterpolableSingleCoordinate(value, segType, coordinates); |
| 283 |
| 284 case PathSegCurveToCubicAbs: |
| 285 case PathSegCurveToCubicRel: |
| 286 return consumeInterpolableCurvetoCubic(value, segType, coordinates); |
| 287 |
| 288 case PathSegCurveToQuadraticAbs: |
| 289 case PathSegCurveToQuadraticRel: |
| 290 return consumeInterpolableCurvetoQuadratic(value, segType, coordinates); |
| 291 |
| 292 case PathSegArcAbs: |
| 293 case PathSegArcRel: |
| 294 return consumeInterpolableArc(value, segType, coordinates); |
| 295 |
| 296 case PathSegLineToHorizontalAbs: |
| 297 case PathSegLineToHorizontalRel: |
| 298 return consumeInterpolableLinetoHorizontal(value, segType, coordinates); |
| 299 |
| 300 case PathSegLineToVerticalAbs: |
| 301 case PathSegLineToVerticalRel: |
| 302 return consumeInterpolableLinetoVertical(value, segType, coordinates); |
| 303 |
| 304 case PathSegCurveToCubicSmoothAbs: |
| 305 case PathSegCurveToCubicSmoothRel: |
| 306 return consumeInterpolableCurvetoCubicSmooth(value, segType, coordinates
); |
| 307 |
| 308 case PathSegUnknown: |
| 309 default: |
| 310 ASSERT_NOT_REACHED(); |
| 311 return PathSegmentData(); |
| 312 } |
| 313 } |
| 314 |
| 315 } // namespace blink |
OLD | NEW |