blob: afbaa5401d4e8f52e60ac0e4b65c5a96ad0c6e69 [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/CSSPaintInterpolationType.h"
#include <memory>
#include "core/CSSPropertyNames.h"
#include "core/animation/CSSColorInterpolationType.h"
#include "core/css/StyleColor.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/style/ComputedStyle.h"
#include "platform/wtf/PtrUtil.h"
namespace blink {
namespace {
static bool GetColorFromPaint(const SVGPaintType type,
const Color color,
StyleColor& result) {
switch (type) {
case SVG_PAINTTYPE_RGBCOLOR:
result = color;
return true;
case SVG_PAINTTYPE_CURRENTCOLOR:
result = StyleColor::CurrentColor();
return true;
default:
return false;
}
}
bool GetColor(const CSSProperty& property,
const ComputedStyle& style,
StyleColor& result) {
switch (property.PropertyID()) {
case CSSPropertyFill:
return GetColorFromPaint(style.SvgStyle().FillPaintType(),
style.SvgStyle().FillPaintColor(), result);
case CSSPropertyStroke:
return GetColorFromPaint(style.SvgStyle().StrokePaintType(),
style.SvgStyle().StrokePaintColor(), result);
default:
NOTREACHED();
return false;
}
}
} // namespace
InterpolationValue CSSPaintInterpolationType::MaybeConvertNeutral(
const InterpolationValue&,
ConversionCheckers&) const {
return InterpolationValue(
CSSColorInterpolationType::CreateInterpolableColor(Color::kTransparent));
}
InterpolationValue CSSPaintInterpolationType::MaybeConvertInitial(
const StyleResolverState&,
ConversionCheckers& conversion_checkers) const {
StyleColor initial_color;
if (!GetColor(CssProperty(), ComputedStyle::InitialStyle(), initial_color))
return nullptr;
return InterpolationValue(
CSSColorInterpolationType::CreateInterpolableColor(initial_color));
}
class InheritedPaintChecker
: public CSSInterpolationType::CSSConversionChecker {
public:
static std::unique_ptr<InheritedPaintChecker> Create(
const CSSProperty& property,
const StyleColor& color) {
return WTF::WrapUnique(new InheritedPaintChecker(property, color));
}
static std::unique_ptr<InheritedPaintChecker> Create(
const CSSProperty& property) {
return WTF::WrapUnique(new InheritedPaintChecker(property));
}
private:
InheritedPaintChecker(const CSSProperty& property)
: property_(property), valid_color_(false) {}
InheritedPaintChecker(const CSSProperty& property, const StyleColor& color)
: property_(property), valid_color_(true), color_(color) {}
bool IsValid(const StyleResolverState& state,
const InterpolationValue& underlying) const final {
StyleColor parent_color;
if (!GetColor(property_, *state.ParentStyle(), parent_color))
return !valid_color_;
return valid_color_ && parent_color == color_;
}
const CSSProperty& property_;
const bool valid_color_;
const StyleColor color_;
};
InterpolationValue CSSPaintInterpolationType::MaybeConvertInherit(
const StyleResolverState& state,
ConversionCheckers& conversion_checkers) const {
if (!state.ParentStyle())
return nullptr;
StyleColor parent_color;
if (!GetColor(CssProperty(), *state.ParentStyle(), parent_color)) {
conversion_checkers.push_back(InheritedPaintChecker::Create(CssProperty()));
return nullptr;
}
conversion_checkers.push_back(
InheritedPaintChecker::Create(CssProperty(), parent_color));
return InterpolationValue(
CSSColorInterpolationType::CreateInterpolableColor(parent_color));
}
InterpolationValue CSSPaintInterpolationType::MaybeConvertValue(
const CSSValue& value,
const StyleResolverState*,
ConversionCheckers&) const {
std::unique_ptr<InterpolableValue> interpolable_color =
CSSColorInterpolationType::MaybeCreateInterpolableColor(value);
if (!interpolable_color)
return nullptr;
return InterpolationValue(std::move(interpolable_color));
}
InterpolationValue
CSSPaintInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
const ComputedStyle& style) const {
// TODO(alancutter): Support capturing and animating with the visited paint
// color.
StyleColor underlying_color;
if (!GetColor(CssProperty(), style, underlying_color))
return nullptr;
return InterpolationValue(
CSSColorInterpolationType::CreateInterpolableColor(underlying_color));
}
void CSSPaintInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_color,
const NonInterpolableValue*,
StyleResolverState& state) const {
Color color = CSSColorInterpolationType::ResolveInterpolableColor(
interpolable_color, state);
switch (CssProperty().PropertyID()) {
case CSSPropertyFill:
state.Style()->AccessSVGStyle().SetFillPaint(SVG_PAINTTYPE_RGBCOLOR,
color, String(), true, true);
break;
case CSSPropertyStroke:
state.Style()->AccessSVGStyle().SetStrokePaint(
SVG_PAINTTYPE_RGBCOLOR, color, String(), true, true);
break;
default:
NOTREACHED();
}
}
} // namespace blink