| // 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 "third_party/blink/renderer/core/animation/css_paint_interpolation_type.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/memory/ptr_util.h" |
| #include "third_party/blink/renderer/core/animation/css_color_interpolation_type.h" |
| #include "third_party/blink/renderer/core/css/css_property_names.h" |
| #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" |
| #include "third_party/blink/renderer/core/css/style_color.h" |
| #include "third_party/blink/renderer/core/style/computed_style.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| static bool GetColorFromPaint(const SVGPaint& paint, StyleColor& result) { |
| if (!paint.IsColor()) |
| return false; |
| result = paint.GetColor(); |
| return true; |
| } |
| |
| bool GetColor(const CSSProperty& property, |
| const ComputedStyle& style, |
| StyleColor& result) { |
| switch (property.PropertyID()) { |
| case CSSPropertyID::kFill: |
| return GetColorFromPaint(style.FillPaint(), result); |
| case CSSPropertyID::kStroke: |
| return GetColorFromPaint(style.StrokePaint(), 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: |
| InheritedPaintChecker(const CSSProperty& property) |
| : property_(property), valid_color_(false) {} |
| InheritedPaintChecker(const CSSProperty& property, const StyleColor& color) |
| : property_(property), valid_color_(true), color_(color) {} |
| |
| private: |
| 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( |
| std::make_unique<InheritedPaintChecker>(CssProperty())); |
| return nullptr; |
| } |
| conversion_checkers.push_back( |
| std::make_unique<InheritedPaintChecker>(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 CSSPropertyID::kFill: |
| state.Style()->SetFillPaint(SVGPaint(color)); |
| state.Style()->SetInternalVisitedFillPaint(SVGPaint(color)); |
| break; |
| case CSSPropertyID::kStroke: |
| state.Style()->SetStrokePaint(SVGPaint(color)); |
| state.Style()->SetInternalVisitedStrokePaint(SVGPaint(color)); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| } |
| |
| } // namespace blink |