Index: third_party/WebKit/Source/core/animation/StackableInterpolation.cpp |
diff --git a/third_party/WebKit/Source/core/animation/StackableInterpolation.cpp b/third_party/WebKit/Source/core/animation/StackableInterpolation.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1188be773e4d0e74f7fc3f6d7af4ad822d3b698f |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/animation/StackableInterpolation.cpp |
@@ -0,0 +1,58 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "core/animation/StackableInterpolation.h" |
+ |
+#include "core/animation/InterpolationType.h" |
+#include "core/animation/TypedInterpolationValue.h" |
+#include "core/animation/UnderlyingValueOwner.h" |
+ |
+namespace blink { |
+ |
+void StackableInterpolation::applyStack(const ActiveInterpolations& interpolations, InterpolationEnvironment& environment) |
+{ |
+ DCHECK(!interpolations.isEmpty()); |
+ size_t startingIndex = 0; |
+ |
+ // Compute the underlying value to composite onto. |
+ UnderlyingValueOwner underlyingValueOwner; |
+ const StackableInterpolation& firstInterpolation = toStackableInterpolation(*interpolations.at(startingIndex)); |
+ if (firstInterpolation.dependsOnUnderlyingValue()) { |
+ underlyingValueOwner.set(firstInterpolation.maybeConvertUnderlyingValue(environment)); |
+ } else { |
+ const TypedInterpolationValue* firstValue = firstInterpolation.ensureValidInterpolation(environment, underlyingValueOwner); |
+ // Fast path for replace interpolations that are the only one to apply. |
+ if (interpolations.size() == 1) { |
+ if (firstValue) { |
+ firstInterpolation.setFlagIfInheritUsed(environment); |
+ firstValue->type().apply(firstValue->interpolableValue(), firstValue->getNonInterpolableValue(), environment); |
+ } |
+ return; |
+ } |
+ underlyingValueOwner.set(firstValue); |
+ startingIndex++; |
+ } |
+ |
+ // Composite interpolations onto the underlying value. |
+ bool shouldApply = false; |
+ for (size_t i = startingIndex; i < interpolations.size(); i++) { |
+ const StackableInterpolation& currentInterpolation = toStackableInterpolation(*interpolations.at(i)); |
+ DCHECK(currentInterpolation.dependsOnUnderlyingValue()); |
+ const TypedInterpolationValue* currentValue = currentInterpolation.ensureValidInterpolation(environment, underlyingValueOwner); |
+ if (!currentValue) |
+ continue; |
+ shouldApply = true; |
+ currentInterpolation.setFlagIfInheritUsed(environment); |
+ double underlyingFraction = currentInterpolation.underlyingFraction(); |
+ if (underlyingFraction == 0 || !underlyingValueOwner || underlyingValueOwner.type() != currentValue->type()) |
+ underlyingValueOwner.set(currentValue); |
+ else |
+ currentValue->type().composite(underlyingValueOwner, underlyingFraction, currentValue->value(), currentInterpolation.m_currentFraction); |
+ } |
+ |
+ if (shouldApply && underlyingValueOwner) |
+ underlyingValueOwner.type().apply(*underlyingValueOwner.value().interpolableValue, underlyingValueOwner.value().nonInterpolableValue.get(), environment); |
+} |
+ |
+} // namespace blink |