Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Side by Side Diff: third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp

Issue 2844213002: Fix behaviour of shadow interpolation with mismatched list lengths (Closed)
Patch Set: Revert transition test to old behaviour Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/animation/ListInterpolationFunctions.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "core/animation/ListInterpolationFunctions.h" 5 #include "core/animation/ListInterpolationFunctions.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include "core/animation/UnderlyingValueOwner.h" 8 #include "core/animation/UnderlyingValueOwner.h"
9 #include "core/css/CSSValueList.h" 9 #include "core/css/CSSValueList.h"
10 #include "platform/wtf/MathExtras.h" 10 #include "platform/wtf/MathExtras.h"
(...skipping 30 matching lines...) Expand all
41 ToNonInterpolableList(*b.non_interpolable_value); 41 ToNonInterpolableList(*b.non_interpolable_value);
42 42
43 for (size_t i = 0; i < length; i++) { 43 for (size_t i = 0; i < length; i++) {
44 if (!equal_non_interpolable_values(non_interpolable_list_a.Get(i), 44 if (!equal_non_interpolable_values(non_interpolable_list_a.Get(i),
45 non_interpolable_list_b.Get(i))) 45 non_interpolable_list_b.Get(i)))
46 return false; 46 return false;
47 } 47 }
48 return true; 48 return true;
49 } 49 }
50 50
51 static size_t MatchLengths(size_t start_length,
52 size_t end_length,
53 ListInterpolationFunctions::LengthMatchingStrategy
54 length_matching_strategy) {
55 if (length_matching_strategy ==
56 ListInterpolationFunctions::LengthMatchingStrategy::
57 kLowestCommonMultiple) {
58 return lowestCommonMultiple(start_length, end_length);
59 }
60 DCHECK_EQ(length_matching_strategy,
61 ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest);
62 return std::max(start_length, end_length);
63 }
64
51 PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles( 65 PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
52 InterpolationValue&& start, 66 InterpolationValue&& start,
53 InterpolationValue&& end, 67 InterpolationValue&& end,
68 LengthMatchingStrategy length_matching_strategy,
54 MergeSingleItemConversionsCallback merge_single_item_conversions) { 69 MergeSingleItemConversionsCallback merge_single_item_conversions) {
55 size_t start_length = ToInterpolableList(*start.interpolable_value).length(); 70 const size_t start_length =
56 size_t end_length = ToInterpolableList(*end.interpolable_value).length(); 71 ToInterpolableList(*start.interpolable_value).length();
72 const size_t end_length =
73 ToInterpolableList(*end.interpolable_value).length();
57 74
58 if (start_length == 0 && end_length == 0) { 75 if (start_length == 0 && end_length == 0) {
59 return PairwiseInterpolationValue(std::move(start.interpolable_value), 76 return PairwiseInterpolationValue(std::move(start.interpolable_value),
60 std::move(end.interpolable_value), 77 std::move(end.interpolable_value),
61 nullptr); 78 nullptr);
62 } 79 }
63 80
64 if (start_length == 0) { 81 if (start_length == 0) {
65 std::unique_ptr<InterpolableValue> start_interpolable_value = 82 std::unique_ptr<InterpolableValue> start_interpolable_value =
66 end.interpolable_value->CloneAndZero(); 83 end.interpolable_value->CloneAndZero();
67 return PairwiseInterpolationValue(std::move(start_interpolable_value), 84 return PairwiseInterpolationValue(std::move(start_interpolable_value),
68 std::move(end.interpolable_value), 85 std::move(end.interpolable_value),
69 std::move(end.non_interpolable_value)); 86 std::move(end.non_interpolable_value));
70 } 87 }
71 88
72 if (end_length == 0) { 89 if (end_length == 0) {
73 std::unique_ptr<InterpolableValue> end_interpolable_value = 90 std::unique_ptr<InterpolableValue> end_interpolable_value =
74 start.interpolable_value->CloneAndZero(); 91 start.interpolable_value->CloneAndZero();
75 return PairwiseInterpolationValue(std::move(start.interpolable_value), 92 return PairwiseInterpolationValue(std::move(start.interpolable_value),
76 std::move(end_interpolable_value), 93 std::move(end_interpolable_value),
77 std::move(start.non_interpolable_value)); 94 std::move(start.non_interpolable_value));
78 } 95 }
79 96
80 size_t final_length = lowestCommonMultiple(start_length, end_length); 97 const size_t final_length =
98 MatchLengths(start_length, end_length, length_matching_strategy);
81 std::unique_ptr<InterpolableList> result_start_interpolable_list = 99 std::unique_ptr<InterpolableList> result_start_interpolable_list =
82 InterpolableList::Create(final_length); 100 InterpolableList::Create(final_length);
83 std::unique_ptr<InterpolableList> result_end_interpolable_list = 101 std::unique_ptr<InterpolableList> result_end_interpolable_list =
84 InterpolableList::Create(final_length); 102 InterpolableList::Create(final_length);
85 Vector<RefPtr<NonInterpolableValue>> result_non_interpolable_values( 103 Vector<RefPtr<NonInterpolableValue>> result_non_interpolable_values(
86 final_length); 104 final_length);
87 105
88 InterpolableList& start_interpolable_list = 106 InterpolableList& start_interpolable_list =
89 ToInterpolableList(*start.interpolable_value); 107 ToInterpolableList(*start.interpolable_value);
90 InterpolableList& end_interpolable_list = 108 InterpolableList& end_interpolable_list =
91 ToInterpolableList(*end.interpolable_value); 109 ToInterpolableList(*end.interpolable_value);
92 NonInterpolableList& start_non_interpolable_list = 110 NonInterpolableList& start_non_interpolable_list =
93 ToNonInterpolableList(*start.non_interpolable_value); 111 ToNonInterpolableList(*start.non_interpolable_value);
94 NonInterpolableList& end_non_interpolable_list = 112 NonInterpolableList& end_non_interpolable_list =
95 ToNonInterpolableList(*end.non_interpolable_value); 113 ToNonInterpolableList(*end.non_interpolable_value);
96 114
97 for (size_t i = 0; i < final_length; i++) { 115 for (size_t i = 0; i < final_length; i++) {
98 InterpolationValue start( 116 PairwiseInterpolationValue result = nullptr;
99 start_interpolable_list.Get(i % start_length)->Clone(), 117 if (length_matching_strategy ==
100 start_non_interpolable_list.Get(i % start_length)); 118 LengthMatchingStrategy::kLowestCommonMultiple ||
101 InterpolationValue end(end_interpolable_list.Get(i % end_length)->Clone(), 119 (i < start_length && i < end_length)) {
102 end_non_interpolable_list.Get(i % end_length)); 120 InterpolationValue start(
103 PairwiseInterpolationValue result = 121 start_interpolable_list.Get(i % start_length)->Clone(),
104 merge_single_item_conversions(std::move(start), std::move(end)); 122 start_non_interpolable_list.Get(i % start_length));
105 if (!result) 123 InterpolationValue end(end_interpolable_list.Get(i % end_length)->Clone(),
106 return nullptr; 124 end_non_interpolable_list.Get(i % end_length));
107 result_start_interpolable_list->Set( 125 PairwiseInterpolationValue result =
108 i, std::move(result.start_interpolable_value)); 126 merge_single_item_conversions(std::move(start), std::move(end));
109 result_end_interpolable_list->Set(i, 127 if (!result)
110 std::move(result.end_interpolable_value)); 128 return nullptr;
111 result_non_interpolable_values[i] = 129 result_start_interpolable_list->Set(
112 std::move(result.non_interpolable_value); 130 i, std::move(result.start_interpolable_value));
131 result_end_interpolable_list->Set(
132 i, std::move(result.end_interpolable_value));
133 result_non_interpolable_values[i] =
134 std::move(result.non_interpolable_value);
135 } else {
136 DCHECK_EQ(length_matching_strategy,
137 LengthMatchingStrategy::kPadToLargest);
138 if (i < start_length) {
139 result_start_interpolable_list->Set(
140 i, start_interpolable_list.Get(i)->Clone());
141 result_end_interpolable_list->Set(
142 i, start_interpolable_list.Get(i)->CloneAndZero());
143 result_non_interpolable_values[i] = start_non_interpolable_list.Get(i);
144 } else {
145 DCHECK_LT(i, end_length);
146 result_start_interpolable_list->Set(
147 i, end_interpolable_list.Get(i)->CloneAndZero());
148 result_end_interpolable_list->Set(
149 i, end_interpolable_list.Get(i)->Clone());
150 result_non_interpolable_values[i] = end_non_interpolable_list.Get(i);
151 }
152 }
113 } 153 }
114 154
115 return PairwiseInterpolationValue( 155 return PairwiseInterpolationValue(
116 std::move(result_start_interpolable_list), 156 std::move(result_start_interpolable_list),
117 std::move(result_end_interpolable_list), 157 std::move(result_end_interpolable_list),
118 NonInterpolableList::Create(std::move(result_non_interpolable_values))); 158 NonInterpolableList::Create(std::move(result_non_interpolable_values)));
119 } 159 }
120 160
121 static void RepeatToLength(InterpolationValue& value, size_t length) { 161 static void RepeatToLength(InterpolationValue& value, size_t length) {
122 InterpolableList& interpolable_list = 162 InterpolableList& interpolable_list =
(...skipping 14 matching lines...) Expand all
137 ? std::move(interpolable_list.GetMutable(i)) 177 ? std::move(interpolable_list.GetMutable(i))
138 : interpolable_list.Get(i % current_length)->Clone()); 178 : interpolable_list.Get(i % current_length)->Clone());
139 new_non_interpolable_values[i] = 179 new_non_interpolable_values[i] =
140 non_interpolable_list.Get(i % current_length); 180 non_interpolable_list.Get(i % current_length);
141 } 181 }
142 value.interpolable_value = std::move(new_interpolable_list); 182 value.interpolable_value = std::move(new_interpolable_list);
143 value.non_interpolable_value = 183 value.non_interpolable_value =
144 NonInterpolableList::Create(std::move(new_non_interpolable_values)); 184 NonInterpolableList::Create(std::move(new_non_interpolable_values));
145 } 185 }
146 186
187 // This helper function makes value the same length as length_value by
188 // CloneAndZero-ing the additional items from length_value into value.
189 static void PadToSameLength(InterpolationValue& value,
190 const InterpolationValue& length_value) {
191 InterpolableList& interpolable_list =
192 ToInterpolableList(*value.interpolable_value);
193 NonInterpolableList& non_interpolable_list =
194 ToNonInterpolableList(*value.non_interpolable_value);
195 const size_t current_length = interpolable_list.length();
196 InterpolableList& target_interpolable_list =
197 ToInterpolableList(*length_value.interpolable_value);
198 NonInterpolableList& target_non_interpolable_list =
199 ToNonInterpolableList(*length_value.non_interpolable_value);
200 const size_t target_length = target_interpolable_list.length();
201 DCHECK_LT(current_length, target_length);
202 std::unique_ptr<InterpolableList> new_interpolable_list =
203 InterpolableList::Create(target_length);
204 Vector<RefPtr<NonInterpolableValue>> new_non_interpolable_values(
205 target_length);
206 size_t index = 0;
207 for (; index < current_length; index++) {
208 new_interpolable_list->Set(index,
209 std::move(interpolable_list.GetMutable(index)));
210 new_non_interpolable_values[index] = non_interpolable_list.Get(index);
211 }
212 for (; index < target_length; index++) {
213 new_interpolable_list->Set(
214 index, target_interpolable_list.Get(index)->CloneAndZero());
215 new_non_interpolable_values[index] =
216 target_non_interpolable_list.Get(index);
217 }
218 value.interpolable_value = std::move(new_interpolable_list);
219 value.non_interpolable_value =
220 NonInterpolableList::Create(std::move(new_non_interpolable_values));
221 }
222
147 static bool NonInterpolableListsAreCompatible( 223 static bool NonInterpolableListsAreCompatible(
148 const NonInterpolableList& a, 224 const NonInterpolableList& a,
149 const NonInterpolableList& b, 225 const NonInterpolableList& b,
150 size_t length, 226 size_t length,
227 ListInterpolationFunctions::LengthMatchingStrategy length_matching_strategy,
151 ListInterpolationFunctions::NonInterpolableValuesAreCompatibleCallback 228 ListInterpolationFunctions::NonInterpolableValuesAreCompatibleCallback
152 non_interpolable_values_are_compatible) { 229 non_interpolable_values_are_compatible) {
153 for (size_t i = 0; i < length; i++) { 230 for (size_t i = 0; i < length; i++) {
154 if (!non_interpolable_values_are_compatible(a.Get(i % a.length()), 231 if (length_matching_strategy ==
155 b.Get(i % b.length()))) 232 ListInterpolationFunctions::LengthMatchingStrategy::
156 return false; 233 kLowestCommonMultiple ||
234 (i < a.length() && i < b.length())) {
235 if (!non_interpolable_values_are_compatible(a.Get(i % a.length()),
236 b.Get(i % b.length()))) {
237 return false;
238 }
239 }
157 } 240 }
158 return true; 241 return true;
159 } 242 }
160 243
161 void ListInterpolationFunctions::Composite( 244 void ListInterpolationFunctions::Composite(
162 UnderlyingValueOwner& underlying_value_owner, 245 UnderlyingValueOwner& underlying_value_owner,
163 double underlying_fraction, 246 double underlying_fraction,
164 const InterpolationType& type, 247 const InterpolationType& type,
165 const InterpolationValue& value, 248 const InterpolationValue& value,
249 LengthMatchingStrategy length_matching_strategy,
166 NonInterpolableValuesAreCompatibleCallback 250 NonInterpolableValuesAreCompatibleCallback
167 non_interpolable_values_are_compatible, 251 non_interpolable_values_are_compatible,
168 CompositeItemCallback composite_item) { 252 CompositeItemCallback composite_item) {
169 size_t underlying_length = 253 const size_t underlying_length =
170 ToInterpolableList(*underlying_value_owner.Value().interpolable_value) 254 ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
171 .length(); 255 .length();
172 if (underlying_length == 0) { 256 if (underlying_length == 0) {
173 DCHECK(!underlying_value_owner.Value().non_interpolable_value); 257 DCHECK(!underlying_value_owner.Value().non_interpolable_value);
174 underlying_value_owner.Set(type, value); 258 underlying_value_owner.Set(type, value);
175 return; 259 return;
176 } 260 }
177 261
178 const InterpolableList& interpolable_list = 262 const InterpolableList& interpolable_list =
179 ToInterpolableList(*value.interpolable_value); 263 ToInterpolableList(*value.interpolable_value);
180 size_t value_length = interpolable_list.length(); 264 const size_t value_length = interpolable_list.length();
181 if (value_length == 0) { 265 if (value_length == 0) {
182 DCHECK(!value.non_interpolable_value); 266 DCHECK(!value.non_interpolable_value);
183 underlying_value_owner.MutableValue().interpolable_value->Scale( 267 underlying_value_owner.MutableValue().interpolable_value->Scale(
184 underlying_fraction); 268 underlying_fraction);
185 return; 269 return;
186 } 270 }
187 271
188 const NonInterpolableList& non_interpolable_list = 272 const NonInterpolableList& non_interpolable_list =
189 ToNonInterpolableList(*value.non_interpolable_value); 273 ToNonInterpolableList(*value.non_interpolable_value);
190 size_t new_length = lowestCommonMultiple(underlying_length, value_length); 274 const size_t final_length =
275 MatchLengths(underlying_length, value_length, length_matching_strategy);
191 if (!NonInterpolableListsAreCompatible( 276 if (!NonInterpolableListsAreCompatible(
192 ToNonInterpolableList( 277 ToNonInterpolableList(
193 *underlying_value_owner.Value().non_interpolable_value), 278 *underlying_value_owner.Value().non_interpolable_value),
194 non_interpolable_list, new_length, 279 non_interpolable_list, final_length, length_matching_strategy,
195 non_interpolable_values_are_compatible)) { 280 non_interpolable_values_are_compatible)) {
196 underlying_value_owner.Set(type, value); 281 underlying_value_owner.Set(type, value);
197 return; 282 return;
198 } 283 }
199 284
200 InterpolationValue& underlying_value = underlying_value_owner.MutableValue(); 285 InterpolationValue& underlying_value = underlying_value_owner.MutableValue();
201 if (underlying_length < new_length) 286 if (length_matching_strategy ==
202 RepeatToLength(underlying_value, new_length); 287 LengthMatchingStrategy::kLowestCommonMultiple) {
288 if (underlying_length < final_length) {
289 RepeatToLength(underlying_value, final_length);
290 }
291 InterpolableList& underlying_interpolable_list =
292 ToInterpolableList(*underlying_value.interpolable_value);
293 NonInterpolableList& underlying_non_interpolable_list =
294 ToNonInterpolableList(*underlying_value.non_interpolable_value);
203 295
204 InterpolableList& underlying_interpolable_list = 296 for (size_t i = 0; i < final_length; i++) {
205 ToInterpolableList(*underlying_value.interpolable_value); 297 composite_item(underlying_interpolable_list.GetMutable(i),
206 NonInterpolableList& underlying_non_interpolable_list = 298 underlying_non_interpolable_list.GetMutable(i),
207 ToNonInterpolableList(*underlying_value.non_interpolable_value); 299 underlying_fraction,
208 for (size_t i = 0; i < new_length; i++) { 300 *interpolable_list.Get(i % value_length),
209 composite_item(underlying_interpolable_list.GetMutable(i), 301 non_interpolable_list.Get(i % value_length));
210 underlying_non_interpolable_list.GetMutable(i), 302 }
211 underlying_fraction, 303 } else {
212 *interpolable_list.Get(i % value_length), 304 DCHECK_EQ(length_matching_strategy, LengthMatchingStrategy::kPadToLargest);
213 non_interpolable_list.Get(i % value_length)); 305 if (underlying_length < final_length) {
306 DCHECK_EQ(value_length, final_length);
307 PadToSameLength(underlying_value, value);
308 }
309 InterpolableList& underlying_interpolable_list =
310 ToInterpolableList(*underlying_value.interpolable_value);
311 NonInterpolableList& underlying_non_interpolable_list =
312 ToNonInterpolableList(*underlying_value.non_interpolable_value);
313
314 for (size_t i = 0; i < value_length; i++) {
315 composite_item(underlying_interpolable_list.GetMutable(i),
316 underlying_non_interpolable_list.GetMutable(i),
317 underlying_fraction, *interpolable_list.Get(i),
318 non_interpolable_list.Get(i));
319 }
320 for (size_t i = value_length; i < final_length; i++) {
321 underlying_interpolable_list.GetMutable(i)->Scale(underlying_fraction);
322 }
214 } 323 }
215 } 324 }
216 325
217 } // namespace blink 326 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/animation/ListInterpolationFunctions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698