OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "core/animation/SizeInterpolationFunctions.h" | |
6 | |
7 #include "core/animation/LengthInterpolationFunctions.h" | |
8 #include "core/animation/UnderlyingValueOwner.h" | |
9 #include "core/css/CSSToLengthConversionData.h" | |
10 #include "core/css/CSSValuePair.h" | |
11 | |
12 namespace blink { | |
13 | |
14 class CSSSizeNonInterpolableValue : public NonInterpolableValue { | |
15 public: | |
16 static PassRefPtr<CSSSizeNonInterpolableValue> create(CSSValueID keyword) | |
17 { | |
18 return adoptRef(new CSSSizeNonInterpolableValue(keyword)); | |
19 } | |
20 | |
21 static PassRefPtr<CSSSizeNonInterpolableValue> create(PassRefPtr<NonInterpol ableValue> lengthNonInterpolableValue) | |
22 { | |
23 return adoptRef(new CSSSizeNonInterpolableValue(lengthNonInterpolableVal ue)); | |
24 } | |
25 | |
26 bool isKeyword() const { return m_keyword != CSSValueInvalid; } | |
27 CSSValueID keyword() const { DCHECK(isKeyword()); return m_keyword; } | |
28 | |
29 const NonInterpolableValue* lengthNonInterpolableValue() const { DCHECK(!isK eyword()); return m_lengthNonInterpolableValue.get(); } | |
30 RefPtr<NonInterpolableValue>& lengthNonInterpolableValue() { DCHECK(!isKeywo rd()); return m_lengthNonInterpolableValue; } | |
31 | |
32 DECLARE_NON_INTERPOLABLE_VALUE_TYPE(); | |
33 | |
34 private: | |
35 CSSSizeNonInterpolableValue(CSSValueID keyword) | |
36 : m_keyword(keyword) | |
37 , m_lengthNonInterpolableValue(nullptr) | |
38 { | |
39 DCHECK_NE(keyword, CSSValueInvalid); | |
40 } | |
41 | |
42 CSSSizeNonInterpolableValue(PassRefPtr<NonInterpolableValue> lengthNonInterp olableValue) | |
43 : m_keyword(CSSValueInvalid) | |
44 , m_lengthNonInterpolableValue(lengthNonInterpolableValue) | |
45 { } | |
Eric Willigers
2016/08/31 01:47:06
DCHECK(m_lengthNonInterpolableValue);
alancutter (OOO until 2018)
2016/09/05 07:44:27
Done.
alancutter (OOO until 2018)
2016/09/06 02:27:31
Whoops, that's actually allowed to be nullptr. Rem
| |
46 | |
47 CSSValueID m_keyword; | |
48 RefPtr<NonInterpolableValue> m_lengthNonInterpolableValue; | |
49 }; | |
50 | |
51 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSSizeNonInterpolableValue); | |
52 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSSizeNonInterpolableValue); | |
53 | |
54 static InterpolationValue convertKeyword(CSSValueID keyword) | |
55 { | |
56 return InterpolationValue(InterpolableList::create(0), CSSSizeNonInterpolabl eValue::create(keyword)); | |
57 } | |
58 | |
59 static InterpolationValue wrapConvertedLength(InterpolationValue&& convertedLeng th) | |
60 { | |
61 if (!convertedLength) | |
62 return nullptr; | |
63 return InterpolationValue( | |
64 std::move(convertedLength.interpolableValue), | |
65 CSSSizeNonInterpolableValue::create(convertedLength.nonInterpolableValue .release())); | |
66 } | |
67 | |
68 InterpolationValue SizeInterpolationFunctions::convertFillSizeSide(const FillSiz e& fillSize, float zoom, bool convertWidth) | |
69 { | |
70 switch (fillSize.type) { | |
71 case SizeLength: { | |
72 const Length& side = convertWidth ? fillSize.size.width() : fillSize.siz e.height(); | |
73 if (side.isAuto()) | |
74 return convertKeyword(CSSValueAuto); | |
75 return wrapConvertedLength(LengthInterpolationFunctions::maybeConvertLen gth(side, zoom)); | |
76 } | |
77 case Contain: | |
78 return convertKeyword(CSSValueContain); | |
79 case Cover: | |
80 return convertKeyword(CSSValueCover); | |
81 case SizeNone: | |
82 default: | |
83 NOTREACHED(); | |
84 return nullptr; | |
85 } | |
86 } | |
87 | |
88 InterpolationValue SizeInterpolationFunctions::maybeConvertCSSSizeSide(const CSS Value& value, bool convertWidth) | |
89 { | |
90 if (value.isValuePair()) { | |
91 const CSSValuePair& pair = toCSSValuePair(value); | |
92 const CSSValue& side = convertWidth ? pair.first() : pair.second(); | |
93 if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).getValueID() == CSSValueAuto) | |
94 return convertKeyword(CSSValueAuto); | |
95 return wrapConvertedLength(LengthInterpolationFunctions::maybeConvertCSS Value(side)); | |
96 } | |
97 | |
98 if (!value.isPrimitiveValue()) | |
99 return nullptr; | |
100 CSSValueID keyword = toCSSPrimitiveValue(value).getValueID(); | |
101 if (keyword) | |
102 return convertKeyword(keyword); | |
103 | |
104 // A single length is equivalent to "<length> auto". | |
105 if (convertWidth) | |
106 return wrapConvertedLength(LengthInterpolationFunctions::maybeConvertCSS Value(value)); | |
107 return convertKeyword(CSSValueAuto); | |
108 } | |
109 | |
110 PairwiseInterpolationValue SizeInterpolationFunctions::maybeMergeSingles(Interpo lationValue&& start, InterpolationValue&& end) | |
111 { | |
112 if (!nonInterpolableValuesAreCompatible(start.nonInterpolableValue.get(), en d.nonInterpolableValue.get())) | |
113 return nullptr; | |
114 return PairwiseInterpolationValue( | |
115 std::move(start.interpolableValue), | |
116 std::move(end.interpolableValue), | |
117 start.nonInterpolableValue.release()); | |
118 } | |
119 | |
120 InterpolationValue SizeInterpolationFunctions::createNeutralValue(const NonInter polableValue* nonInterpolableValue) | |
121 { | |
122 auto& size = toCSSSizeNonInterpolableValue(*nonInterpolableValue); | |
123 if (size.isKeyword()) | |
124 return convertKeyword(size.keyword()); | |
125 return wrapConvertedLength(InterpolationValue(LengthInterpolationFunctions:: createNeutralInterpolableValue())); | |
126 } | |
127 | |
128 bool SizeInterpolationFunctions::nonInterpolableValuesAreCompatible(const NonInt erpolableValue* a, const NonInterpolableValue* b) | |
129 { | |
130 const auto& sizeA = toCSSSizeNonInterpolableValue(*a); | |
131 const auto& sizeB = toCSSSizeNonInterpolableValue(*b); | |
132 if (sizeA.isKeyword() != sizeB.isKeyword()) | |
133 return false; | |
134 if (sizeA.isKeyword()) | |
135 return sizeA.keyword() == sizeB.keyword(); | |
136 return true; | |
137 } | |
138 | |
139 void SizeInterpolationFunctions::composite(std::unique_ptr<InterpolableValue>& u nderlyingInterpolableValue, RefPtr<NonInterpolableValue>& underlyingNonInterpola bleValue, double underlyingFraction, const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue) | |
140 { | |
141 const auto& sizeNonInterpolableValue = toCSSSizeNonInterpolableValue(*nonInt erpolableValue); | |
142 if (sizeNonInterpolableValue.isKeyword()) | |
143 return; | |
144 auto& underlyingSizeNonInterpolableValue = toCSSSizeNonInterpolableValue(*un derlyingNonInterpolableValue); | |
145 LengthInterpolationFunctions::composite( | |
146 underlyingInterpolableValue, | |
147 underlyingSizeNonInterpolableValue.lengthNonInterpolableValue(), | |
148 underlyingFraction, | |
149 interpolableValue, | |
150 sizeNonInterpolableValue.lengthNonInterpolableValue()); | |
151 } | |
152 | |
153 static Length createLength(const InterpolableValue& interpolableValue, const CSS SizeNonInterpolableValue& nonInterpolableValue, const CSSToLengthConversionData& conversionData) | |
154 { | |
155 if (nonInterpolableValue.isKeyword()) { | |
156 DCHECK_EQ(nonInterpolableValue.keyword(), CSSValueAuto); | |
157 return Length(Auto); | |
158 } | |
159 return LengthInterpolationFunctions::createLength(interpolableValue, nonInte rpolableValue.lengthNonInterpolableValue(), conversionData, ValueRangeNonNegativ e); | |
160 } | |
161 | |
162 FillSize SizeInterpolationFunctions::createFillSize(const InterpolableValue& int erpolableValueA, const NonInterpolableValue* nonInterpolableValueA, const Interp olableValue& interpolableValueB, const NonInterpolableValue* nonInterpolableValu eB, const CSSToLengthConversionData& conversionData) | |
163 { | |
164 const auto& sideA = toCSSSizeNonInterpolableValue(*nonInterpolableValueA); | |
165 const auto& sideB = toCSSSizeNonInterpolableValue(*nonInterpolableValueB); | |
166 if (sideA.isKeyword()) { | |
167 switch (sideA.keyword()) { | |
168 case CSSValueCover: | |
169 DCHECK_EQ(sideA.keyword(), sideB.keyword()); | |
170 return FillSize(Cover, LengthSize()); | |
171 case CSSValueContain: | |
172 DCHECK_EQ(sideA.keyword(), sideB.keyword()); | |
173 return FillSize(Contain, LengthSize()); | |
174 case CSSValueAuto: | |
175 break; | |
176 default: | |
177 NOTREACHED(); | |
178 break; | |
179 } | |
180 } | |
181 return FillSize(SizeLength, LengthSize( | |
182 createLength(interpolableValueA, sideA, conversionData), | |
183 createLength(interpolableValueB, sideB, conversionData))); | |
184 } | |
185 | |
186 } // namespace blink | |
OLD | NEW |