| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "core/animation/SVGPathInterpolationType.h" | 5 #include "core/animation/PathInterpolationFunctions.h" |
| 6 | 6 |
| 7 #include "core/animation/InterpolatedSVGPathSource.h" | 7 #include "core/animation/InterpolatedSVGPathSource.h" |
| 8 #include "core/animation/InterpolationEnvironment.h" | 8 #include "core/animation/InterpolationEnvironment.h" |
| 9 #include "core/animation/SVGPathSegInterpolationFunctions.h" | 9 #include "core/animation/SVGPathSegInterpolationFunctions.h" |
| 10 #include "core/css/CSSPathValue.h" |
| 10 #include "core/svg/SVGPath.h" | 11 #include "core/svg/SVGPath.h" |
| 11 #include "core/svg/SVGPathByteStreamBuilder.h" | 12 #include "core/svg/SVGPathByteStreamBuilder.h" |
| 12 #include "core/svg/SVGPathByteStreamSource.h" | 13 #include "core/svg/SVGPathByteStreamSource.h" |
| 13 #include "core/svg/SVGPathParser.h" | 14 #include "core/svg/SVGPathParser.h" |
| 14 | 15 |
| 15 namespace blink { | 16 namespace blink { |
| 16 | 17 |
| 17 class SVGPathNonInterpolableValue : public NonInterpolableValue { | 18 class SVGPathNonInterpolableValue : public NonInterpolableValue { |
| 18 public: | 19 public: |
| 19 virtual ~SVGPathNonInterpolableValue() {} | 20 virtual ~SVGPathNonInterpolableValue() {} |
| (...skipping 18 matching lines...) Expand all Loading... |
| 38 | 39 |
| 39 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGPathNonInterpolableValue); | 40 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGPathNonInterpolableValue); |
| 40 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGPathNonInterpolableValue); | 41 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGPathNonInterpolableValue); |
| 41 | 42 |
| 42 enum PathComponentIndex { | 43 enum PathComponentIndex { |
| 43 PathArgsIndex, | 44 PathArgsIndex, |
| 44 PathNeutralIndex, | 45 PathNeutralIndex, |
| 45 PathComponentIndexCount, | 46 PathComponentIndexCount, |
| 46 }; | 47 }; |
| 47 | 48 |
| 48 PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertSVGValue(co
nst SVGPropertyBase& svgValue) const | 49 PassOwnPtr<InterpolationValue> PathInterpolationFunctions::convertValue(const In
terpolationType& type, const SVGPathByteStream& byteStream) |
| 49 { | 50 { |
| 50 if (svgValue.type() != AnimatedPath) | 51 SVGPathByteStreamSource pathSource(byteStream); |
| 51 return nullptr; | |
| 52 | |
| 53 SVGPathByteStreamSource pathSource(toSVGPath(svgValue).byteStream()); | |
| 54 size_t length = 0; | 52 size_t length = 0; |
| 55 PathCoordinates currentCoordinates; | 53 PathCoordinates currentCoordinates; |
| 56 Vector<OwnPtr<InterpolableValue>> interpolablePathSegs; | 54 Vector<OwnPtr<InterpolableValue>> interpolablePathSegs; |
| 57 Vector<SVGPathSegType> pathSegTypes; | 55 Vector<SVGPathSegType> pathSegTypes; |
| 58 | 56 |
| 59 while (pathSource.hasMoreData()) { | 57 while (pathSource.hasMoreData()) { |
| 60 const PathSegmentData segment = pathSource.parseSegment(); | 58 const PathSegmentData segment = pathSource.parseSegment(); |
| 61 interpolablePathSegs.append(SVGPathSegInterpolationFunctions::consumePat
hSeg(segment, currentCoordinates)); | 59 interpolablePathSegs.append(SVGPathSegInterpolationFunctions::consumePat
hSeg(segment, currentCoordinates)); |
| 62 pathSegTypes.append(segment.command); | 60 pathSegTypes.append(segment.command); |
| 63 length++; | 61 length++; |
| 64 } | 62 } |
| 65 | 63 |
| 66 OwnPtr<InterpolableList> pathArgs = InterpolableList::create(length); | 64 OwnPtr<InterpolableList> pathArgs = InterpolableList::create(length); |
| 67 for (size_t i = 0; i < interpolablePathSegs.size(); i++) | 65 for (size_t i = 0; i < interpolablePathSegs.size(); i++) |
| 68 pathArgs->set(i, interpolablePathSegs[i].release()); | 66 pathArgs->set(i, interpolablePathSegs[i].release()); |
| 69 | 67 |
| 70 OwnPtr<InterpolableList> result = InterpolableList::create(PathComponentInde
xCount); | 68 OwnPtr<InterpolableList> result = InterpolableList::create(PathComponentInde
xCount); |
| 71 result->set(PathArgsIndex, pathArgs.release()); | 69 result->set(PathArgsIndex, pathArgs.release()); |
| 72 result->set(PathNeutralIndex, InterpolableNumber::create(0)); | 70 result->set(PathNeutralIndex, InterpolableNumber::create(0)); |
| 73 | 71 |
| 74 return InterpolationValue::create(*this, result.release(), SVGPathNonInterpo
lableValue::create(pathSegTypes)); | 72 return InterpolationValue::create(type, result.release(), SVGPathNonInterpol
ableValue::create(pathSegTypes)); |
| 75 } | 73 } |
| 76 | 74 |
| 77 class UnderlyingPathSegTypesChecker : public InterpolationType::ConversionChecke
r { | 75 class UnderlyingPathSegTypesChecker : public InterpolationType::ConversionChecke
r { |
| 78 public: | 76 public: |
| 79 ~UnderlyingPathSegTypesChecker() final {} | 77 ~UnderlyingPathSegTypesChecker() final {} |
| 80 | 78 |
| 81 static PassOwnPtr<UnderlyingPathSegTypesChecker> create(const InterpolationT
ype& type, const UnderlyingValue& underlyingValue) | 79 static PassOwnPtr<UnderlyingPathSegTypesChecker> create(const InterpolationT
ype& type, const UnderlyingValue& underlyingValue) |
| 82 { | 80 { |
| 83 return adoptPtr(new UnderlyingPathSegTypesChecker(type, getPathSegTypes(
underlyingValue))); | 81 return adoptPtr(new UnderlyingPathSegTypesChecker(type, getPathSegTypes(
underlyingValue))); |
| 84 } | 82 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 95 } | 93 } |
| 96 | 94 |
| 97 bool isValid(const InterpolationEnvironment&, const UnderlyingValue& underly
ingValue) const final | 95 bool isValid(const InterpolationEnvironment&, const UnderlyingValue& underly
ingValue) const final |
| 98 { | 96 { |
| 99 return m_pathSegTypes == getPathSegTypes(underlyingValue); | 97 return m_pathSegTypes == getPathSegTypes(underlyingValue); |
| 100 } | 98 } |
| 101 | 99 |
| 102 Vector<SVGPathSegType> m_pathSegTypes; | 100 Vector<SVGPathSegType> m_pathSegTypes; |
| 103 }; | 101 }; |
| 104 | 102 |
| 105 PassOwnPtr<InterpolationValue> SVGPathInterpolationType::maybeConvertNeutral(con
st UnderlyingValue& underlyingValue, ConversionCheckers& conversionCheckers) con
st | 103 PassOwnPtr<InterpolationValue> PathInterpolationFunctions::maybeConvertNeutral(c
onst InterpolationType& type, const UnderlyingValue& underlyingValue, Interpolat
ionType::ConversionCheckers& conversionCheckers) |
| 106 { | 104 { |
| 107 conversionCheckers.append(UnderlyingPathSegTypesChecker::create(*this, under
lyingValue)); | 105 conversionCheckers.append(UnderlyingPathSegTypesChecker::create(type, underl
yingValue)); |
| 108 OwnPtr<InterpolableList> result = InterpolableList::create(PathComponentInde
xCount); | 106 OwnPtr<InterpolableList> result = InterpolableList::create(PathComponentInde
xCount); |
| 109 result->set(PathArgsIndex, toInterpolableList(underlyingValue->interpolableV
alue()).get(PathArgsIndex)->cloneAndZero()); | 107 result->set(PathArgsIndex, toInterpolableList(underlyingValue->interpolableV
alue()).get(PathArgsIndex)->cloneAndZero()); |
| 110 result->set(PathNeutralIndex, InterpolableNumber::create(1)); | 108 result->set(PathNeutralIndex, InterpolableNumber::create(1)); |
| 111 return InterpolationValue::create(*this, result.release(), | 109 return InterpolationValue::create(type, result.release(), |
| 112 const_cast<NonInterpolableValue*>(underlyingValue->nonInterpolableValue(
))); // Take ref. | 110 const_cast<NonInterpolableValue*>(underlyingValue->nonInterpolableValue(
))); // Take ref. |
| 113 } | 111 } |
| 114 | 112 |
| 115 static bool pathSegTypesMatch(const Vector<SVGPathSegType>& a, const Vector<SVGP
athSegType>& b) | 113 static bool pathSegTypesMatch(const Vector<SVGPathSegType>& a, const Vector<SVGP
athSegType>& b) |
| 116 { | 114 { |
| 117 if (a.size() != b.size()) | 115 if (a.size() != b.size()) |
| 118 return false; | 116 return false; |
| 119 | 117 |
| 120 for (size_t i = 0; i < a.size(); i++) { | 118 for (size_t i = 0; i < a.size(); i++) { |
| 121 if (toAbsolutePathSegType(a[i]) != toAbsolutePathSegType(b[i])) | 119 if (toAbsolutePathSegType(a[i]) != toAbsolutePathSegType(b[i])) |
| 122 return false; | 120 return false; |
| 123 } | 121 } |
| 124 | 122 |
| 125 return true; | 123 return true; |
| 126 } | 124 } |
| 127 | 125 |
| 128 PassOwnPtr<PairwisePrimitiveInterpolation> SVGPathInterpolationType::mergeSingle
Conversions(InterpolationValue& startValue, InterpolationValue& endValue) const | 126 PassOwnPtr<PairwisePrimitiveInterpolation> PathInterpolationFunctions::mergeSing
leConversions(const InterpolationType& type, InterpolationValue& startValue, Int
erpolationValue& endValue) |
| 129 { | 127 { |
| 130 const Vector<SVGPathSegType>& startTypes = toSVGPathNonInterpolableValue(sta
rtValue.nonInterpolableValue())->pathSegTypes(); | 128 const Vector<SVGPathSegType>& startTypes = toSVGPathNonInterpolableValue(sta
rtValue.nonInterpolableValue())->pathSegTypes(); |
| 131 const Vector<SVGPathSegType>& endTypes = toSVGPathNonInterpolableValue(endVa
lue.nonInterpolableValue())->pathSegTypes(); | 129 const Vector<SVGPathSegType>& endTypes = toSVGPathNonInterpolableValue(endVa
lue.nonInterpolableValue())->pathSegTypes(); |
| 132 if (!pathSegTypesMatch(startTypes, endTypes)) | 130 if (!pathSegTypesMatch(startTypes, endTypes)) |
| 133 return nullptr; | 131 return nullptr; |
| 134 | 132 |
| 135 return PairwisePrimitiveInterpolation::create(*this, | 133 return PairwisePrimitiveInterpolation::create(type, |
| 136 startValue.mutableComponent().interpolableValue.release(), | 134 startValue.mutableComponent().interpolableValue.release(), |
| 137 endValue.mutableComponent().interpolableValue.release(), | 135 endValue.mutableComponent().interpolableValue.release(), |
| 138 const_cast<NonInterpolableValue*>(endValue.nonInterpolableValue())); //
Take ref. | 136 const_cast<NonInterpolableValue*>(endValue.nonInterpolableValue())); //
Take ref. |
| 139 } | 137 } |
| 140 | 138 |
| 141 void SVGPathInterpolationType::composite(UnderlyingValue& underlyingValue, doubl
e underlyingFraction, const InterpolationValue& value) const | 139 void PathInterpolationFunctions::composite(UnderlyingValue& underlyingValue, dou
ble underlyingFraction, const InterpolationValue& value) |
| 142 { | 140 { |
| 143 const InterpolableList& list = toInterpolableList(value.interpolableValue())
; | 141 const InterpolableList& list = toInterpolableList(value.interpolableValue())
; |
| 144 double neutralComponent = toInterpolableNumber(list.get(PathNeutralIndex))->
value(); | 142 double neutralComponent = toInterpolableNumber(list.get(PathNeutralIndex))->
value(); |
| 145 | 143 |
| 146 if (neutralComponent == 0) { | 144 if (neutralComponent == 0) { |
| 147 underlyingValue.set(&value); | 145 underlyingValue.set(&value); |
| 148 return; | 146 return; |
| 149 } | 147 } |
| 150 | 148 |
| 151 ASSERT(pathSegTypesMatch( | 149 ASSERT(pathSegTypesMatch( |
| 152 toSVGPathNonInterpolableValue(underlyingValue->nonInterpolableValue())->
pathSegTypes(), | 150 toSVGPathNonInterpolableValue(underlyingValue->nonInterpolableValue())->
pathSegTypes(), |
| 153 toSVGPathNonInterpolableValue(value.nonInterpolableValue())->pathSegType
s())); | 151 toSVGPathNonInterpolableValue(value.nonInterpolableValue())->pathSegType
s())); |
| 154 underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(neutralCom
ponent, value.interpolableValue()); | 152 underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(neutralCom
ponent, value.interpolableValue()); |
| 155 underlyingValue.mutableComponent().nonInterpolableValue = const_cast<NonInte
rpolableValue*>(value.nonInterpolableValue()); // Take ref. | 153 underlyingValue.mutableComponent().nonInterpolableValue = const_cast<NonInte
rpolableValue*>(value.nonInterpolableValue()); // Take ref. |
| 156 } | 154 } |
| 157 | 155 |
| 158 PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPathInterpolationType::appliedSVGValu
e(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInt
erpolableValue) const | 156 PassRefPtr<SVGPathByteStream> PathInterpolationFunctions::appliedValue(const Int
erpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableVa
lue) |
| 159 { | 157 { |
| 160 RefPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create(); | 158 RefPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create(); |
| 161 InterpolatedSVGPathSource source( | 159 InterpolatedSVGPathSource source( |
| 162 toInterpolableList(*toInterpolableList(interpolableValue).get(PathArgsIn
dex)), | 160 toInterpolableList(*toInterpolableList(interpolableValue).get(PathArgsIn
dex)), |
| 163 toSVGPathNonInterpolableValue(nonInterpolableValue)->pathSegTypes()); | 161 toSVGPathNonInterpolableValue(nonInterpolableValue)->pathSegTypes()); |
| 164 SVGPathByteStreamBuilder builder(*pathByteStream); | 162 SVGPathByteStreamBuilder builder(*pathByteStream); |
| 165 SVGPathParser(&source, &builder).parsePathDataFromSource(UnalteredParsing, f
alse); | 163 SVGPathParser(&source, &builder).parsePathDataFromSource(UnalteredParsing, f
alse); |
| 166 return SVGPath::create(CSSPathValue::create(pathByteStream.release())); | 164 return pathByteStream.release(); |
| 167 } | 165 } |
| 168 | 166 |
| 169 } // namespace blink | 167 } // namespace blink |
| OLD | NEW |