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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/animation/ListInterpolationFunctions.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp
diff --git a/third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp b/third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp
index 82b26f7cec11992684c1e2908b0a758aa0b42ac0..6f39102e39f4de4f5ac855dcb6028d25c720bfb3 100644
--- a/third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp
+++ b/third_party/WebKit/Source/core/animation/ListInterpolationFunctions.cpp
@@ -48,12 +48,29 @@ bool ListInterpolationFunctions::EqualValues(
return true;
}
+static size_t MatchLengths(size_t start_length,
+ size_t end_length,
+ ListInterpolationFunctions::LengthMatchingStrategy
+ length_matching_strategy) {
+ if (length_matching_strategy ==
+ ListInterpolationFunctions::LengthMatchingStrategy::
+ kLowestCommonMultiple) {
+ return lowestCommonMultiple(start_length, end_length);
+ }
+ DCHECK_EQ(length_matching_strategy,
+ ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest);
+ return std::max(start_length, end_length);
+}
+
PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end,
+ LengthMatchingStrategy length_matching_strategy,
MergeSingleItemConversionsCallback merge_single_item_conversions) {
- size_t start_length = ToInterpolableList(*start.interpolable_value).length();
- size_t end_length = ToInterpolableList(*end.interpolable_value).length();
+ const size_t start_length =
+ ToInterpolableList(*start.interpolable_value).length();
+ const size_t end_length =
+ ToInterpolableList(*end.interpolable_value).length();
if (start_length == 0 && end_length == 0) {
return PairwiseInterpolationValue(std::move(start.interpolable_value),
@@ -77,7 +94,8 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
std::move(start.non_interpolable_value));
}
- size_t final_length = lowestCommonMultiple(start_length, end_length);
+ const size_t final_length =
+ MatchLengths(start_length, end_length, length_matching_strategy);
std::unique_ptr<InterpolableList> result_start_interpolable_list =
InterpolableList::Create(final_length);
std::unique_ptr<InterpolableList> result_end_interpolable_list =
@@ -95,21 +113,43 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
ToNonInterpolableList(*end.non_interpolable_value);
for (size_t i = 0; i < final_length; i++) {
- InterpolationValue start(
- start_interpolable_list.Get(i % start_length)->Clone(),
- start_non_interpolable_list.Get(i % start_length));
- InterpolationValue end(end_interpolable_list.Get(i % end_length)->Clone(),
- end_non_interpolable_list.Get(i % end_length));
- PairwiseInterpolationValue result =
- merge_single_item_conversions(std::move(start), std::move(end));
- if (!result)
- return nullptr;
- result_start_interpolable_list->Set(
- i, std::move(result.start_interpolable_value));
- result_end_interpolable_list->Set(i,
- std::move(result.end_interpolable_value));
- result_non_interpolable_values[i] =
- std::move(result.non_interpolable_value);
+ PairwiseInterpolationValue result = nullptr;
+ if (length_matching_strategy ==
+ LengthMatchingStrategy::kLowestCommonMultiple ||
+ (i < start_length && i < end_length)) {
+ InterpolationValue start(
+ start_interpolable_list.Get(i % start_length)->Clone(),
+ start_non_interpolable_list.Get(i % start_length));
+ InterpolationValue end(end_interpolable_list.Get(i % end_length)->Clone(),
+ end_non_interpolable_list.Get(i % end_length));
+ PairwiseInterpolationValue result =
+ merge_single_item_conversions(std::move(start), std::move(end));
+ if (!result)
+ return nullptr;
+ result_start_interpolable_list->Set(
+ i, std::move(result.start_interpolable_value));
+ result_end_interpolable_list->Set(
+ i, std::move(result.end_interpolable_value));
+ result_non_interpolable_values[i] =
+ std::move(result.non_interpolable_value);
+ } else {
+ DCHECK_EQ(length_matching_strategy,
+ LengthMatchingStrategy::kPadToLargest);
+ if (i < start_length) {
+ result_start_interpolable_list->Set(
+ i, start_interpolable_list.Get(i)->Clone());
+ result_end_interpolable_list->Set(
+ i, start_interpolable_list.Get(i)->CloneAndZero());
+ result_non_interpolable_values[i] = start_non_interpolable_list.Get(i);
+ } else {
+ DCHECK_LT(i, end_length);
+ result_start_interpolable_list->Set(
+ i, end_interpolable_list.Get(i)->CloneAndZero());
+ result_end_interpolable_list->Set(
+ i, end_interpolable_list.Get(i)->Clone());
+ result_non_interpolable_values[i] = end_non_interpolable_list.Get(i);
+ }
+ }
}
return PairwiseInterpolationValue(
@@ -144,16 +184,59 @@ static void RepeatToLength(InterpolationValue& value, size_t length) {
NonInterpolableList::Create(std::move(new_non_interpolable_values));
}
+// This helper function makes value the same length as length_value by
+// CloneAndZero-ing the additional items from length_value into value.
+static void PadToSameLength(InterpolationValue& value,
+ const InterpolationValue& length_value) {
+ InterpolableList& interpolable_list =
+ ToInterpolableList(*value.interpolable_value);
+ NonInterpolableList& non_interpolable_list =
+ ToNonInterpolableList(*value.non_interpolable_value);
+ const size_t current_length = interpolable_list.length();
+ InterpolableList& target_interpolable_list =
+ ToInterpolableList(*length_value.interpolable_value);
+ NonInterpolableList& target_non_interpolable_list =
+ ToNonInterpolableList(*length_value.non_interpolable_value);
+ const size_t target_length = target_interpolable_list.length();
+ DCHECK_LT(current_length, target_length);
+ std::unique_ptr<InterpolableList> new_interpolable_list =
+ InterpolableList::Create(target_length);
+ Vector<RefPtr<NonInterpolableValue>> new_non_interpolable_values(
+ target_length);
+ size_t index = 0;
+ for (; index < current_length; index++) {
+ new_interpolable_list->Set(index,
+ std::move(interpolable_list.GetMutable(index)));
+ new_non_interpolable_values[index] = non_interpolable_list.Get(index);
+ }
+ for (; index < target_length; index++) {
+ new_interpolable_list->Set(
+ index, target_interpolable_list.Get(index)->CloneAndZero());
+ new_non_interpolable_values[index] =
+ target_non_interpolable_list.Get(index);
+ }
+ value.interpolable_value = std::move(new_interpolable_list);
+ value.non_interpolable_value =
+ NonInterpolableList::Create(std::move(new_non_interpolable_values));
+}
+
static bool NonInterpolableListsAreCompatible(
const NonInterpolableList& a,
const NonInterpolableList& b,
size_t length,
+ ListInterpolationFunctions::LengthMatchingStrategy length_matching_strategy,
ListInterpolationFunctions::NonInterpolableValuesAreCompatibleCallback
non_interpolable_values_are_compatible) {
for (size_t i = 0; i < length; i++) {
- if (!non_interpolable_values_are_compatible(a.Get(i % a.length()),
- b.Get(i % b.length())))
- return false;
+ if (length_matching_strategy ==
+ ListInterpolationFunctions::LengthMatchingStrategy::
+ kLowestCommonMultiple ||
+ (i < a.length() && i < b.length())) {
+ if (!non_interpolable_values_are_compatible(a.Get(i % a.length()),
+ b.Get(i % b.length()))) {
+ return false;
+ }
+ }
}
return true;
}
@@ -163,10 +246,11 @@ void ListInterpolationFunctions::Composite(
double underlying_fraction,
const InterpolationType& type,
const InterpolationValue& value,
+ LengthMatchingStrategy length_matching_strategy,
NonInterpolableValuesAreCompatibleCallback
non_interpolable_values_are_compatible,
CompositeItemCallback composite_item) {
- size_t underlying_length =
+ const size_t underlying_length =
ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
.length();
if (underlying_length == 0) {
@@ -177,7 +261,7 @@ void ListInterpolationFunctions::Composite(
const InterpolableList& interpolable_list =
ToInterpolableList(*value.interpolable_value);
- size_t value_length = interpolable_list.length();
+ const size_t value_length = interpolable_list.length();
if (value_length == 0) {
DCHECK(!value.non_interpolable_value);
underlying_value_owner.MutableValue().interpolable_value->Scale(
@@ -187,30 +271,55 @@ void ListInterpolationFunctions::Composite(
const NonInterpolableList& non_interpolable_list =
ToNonInterpolableList(*value.non_interpolable_value);
- size_t new_length = lowestCommonMultiple(underlying_length, value_length);
+ const size_t final_length =
+ MatchLengths(underlying_length, value_length, length_matching_strategy);
if (!NonInterpolableListsAreCompatible(
ToNonInterpolableList(
*underlying_value_owner.Value().non_interpolable_value),
- non_interpolable_list, new_length,
+ non_interpolable_list, final_length, length_matching_strategy,
non_interpolable_values_are_compatible)) {
underlying_value_owner.Set(type, value);
return;
}
InterpolationValue& underlying_value = underlying_value_owner.MutableValue();
- if (underlying_length < new_length)
- RepeatToLength(underlying_value, new_length);
-
- InterpolableList& underlying_interpolable_list =
- ToInterpolableList(*underlying_value.interpolable_value);
- NonInterpolableList& underlying_non_interpolable_list =
- ToNonInterpolableList(*underlying_value.non_interpolable_value);
- for (size_t i = 0; i < new_length; i++) {
- composite_item(underlying_interpolable_list.GetMutable(i),
- underlying_non_interpolable_list.GetMutable(i),
- underlying_fraction,
- *interpolable_list.Get(i % value_length),
- non_interpolable_list.Get(i % value_length));
+ if (length_matching_strategy ==
+ LengthMatchingStrategy::kLowestCommonMultiple) {
+ if (underlying_length < final_length) {
+ RepeatToLength(underlying_value, final_length);
+ }
+ InterpolableList& underlying_interpolable_list =
+ ToInterpolableList(*underlying_value.interpolable_value);
+ NonInterpolableList& underlying_non_interpolable_list =
+ ToNonInterpolableList(*underlying_value.non_interpolable_value);
+
+ for (size_t i = 0; i < final_length; i++) {
+ composite_item(underlying_interpolable_list.GetMutable(i),
+ underlying_non_interpolable_list.GetMutable(i),
+ underlying_fraction,
+ *interpolable_list.Get(i % value_length),
+ non_interpolable_list.Get(i % value_length));
+ }
+ } else {
+ DCHECK_EQ(length_matching_strategy, LengthMatchingStrategy::kPadToLargest);
+ if (underlying_length < final_length) {
+ DCHECK_EQ(value_length, final_length);
+ PadToSameLength(underlying_value, value);
+ }
+ InterpolableList& underlying_interpolable_list =
+ ToInterpolableList(*underlying_value.interpolable_value);
+ NonInterpolableList& underlying_non_interpolable_list =
+ ToNonInterpolableList(*underlying_value.non_interpolable_value);
+
+ for (size_t i = 0; i < value_length; i++) {
+ composite_item(underlying_interpolable_list.GetMutable(i),
+ underlying_non_interpolable_list.GetMutable(i),
+ underlying_fraction, *interpolable_list.Get(i),
+ non_interpolable_list.Get(i));
+ }
+ for (size_t i = value_length; i < final_length; i++) {
+ underlying_interpolable_list.GetMutable(i)->Scale(underlying_fraction);
+ }
}
}
« 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