blob: 8ec02075ba587ebda68188e08a874acc22b8499a [file] [log] [blame]
// Copyright 2015 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/SVGNumberListInterpolationType.h"
#include "core/animation/InterpolationEnvironment.h"
#include "core/animation/UnderlyingLengthChecker.h"
#include "core/svg/SVGNumberList.h"
#include <memory>
namespace blink {
InterpolationValue SVGNumberListInterpolationType::maybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversionCheckers) const {
size_t underlyingLength =
UnderlyingLengthChecker::getUnderlyingLength(underlying);
conversionCheckers.push_back(
UnderlyingLengthChecker::create(underlyingLength));
if (underlyingLength == 0)
return nullptr;
std::unique_ptr<InterpolableList> result =
InterpolableList::create(underlyingLength);
for (size_t i = 0; i < underlyingLength; i++)
result->set(i, InterpolableNumber::create(0));
return InterpolationValue(std::move(result));
}
InterpolationValue SVGNumberListInterpolationType::maybeConvertSVGValue(
const SVGPropertyBase& svgValue) const {
if (svgValue.type() != AnimatedNumberList)
return nullptr;
const SVGNumberList& numberList = toSVGNumberList(svgValue);
std::unique_ptr<InterpolableList> result =
InterpolableList::create(numberList.length());
for (size_t i = 0; i < numberList.length(); i++)
result->set(i, InterpolableNumber::create(numberList.at(i)->value()));
return InterpolationValue(std::move(result));
}
PairwiseInterpolationValue SVGNumberListInterpolationType::maybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
size_t startLength = toInterpolableList(*start.interpolableValue).length();
size_t endLength = toInterpolableList(*end.interpolableValue).length();
if (startLength != endLength)
return nullptr;
return InterpolationType::maybeMergeSingles(std::move(start), std::move(end));
}
static void padWithZeroes(std::unique_ptr<InterpolableValue>& listPointer,
size_t paddedLength) {
InterpolableList& list = toInterpolableList(*listPointer);
if (list.length() >= paddedLength)
return;
std::unique_ptr<InterpolableList> result =
InterpolableList::create(paddedLength);
size_t i = 0;
for (; i < list.length(); i++)
result->set(i, std::move(list.getMutable(i)));
for (; i < paddedLength; i++)
result->set(i, InterpolableNumber::create(0));
listPointer = std::move(result);
}
void SVGNumberListInterpolationType::composite(
UnderlyingValueOwner& underlyingValueOwner,
double underlyingFraction,
const InterpolationValue& value,
double interpolationFraction) const {
const InterpolableList& list = toInterpolableList(*value.interpolableValue);
if (toInterpolableList(*underlyingValueOwner.value().interpolableValue)
.length() <= list.length())
padWithZeroes(underlyingValueOwner.mutableValue().interpolableValue,
list.length());
InterpolableList& underlyingList = toInterpolableList(
*underlyingValueOwner.mutableValue().interpolableValue);
DCHECK_GE(underlyingList.length(), list.length());
size_t i = 0;
for (; i < list.length(); i++)
underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction, *list.get(i));
for (; i < underlyingList.length(); i++)
underlyingList.getMutable(i)->scale(underlyingFraction);
}
SVGPropertyBase* SVGNumberListInterpolationType::appliedSVGValue(
const InterpolableValue& interpolableValue,
const NonInterpolableValue*) const {
SVGNumberList* result = SVGNumberList::create();
const InterpolableList& list = toInterpolableList(interpolableValue);
for (size_t i = 0; i < list.length(); i++)
result->append(
SVGNumber::create(toInterpolableNumber(list.get(i))->value()));
return result;
}
} // namespace blink