blob: 355f077f9c8a22218ea5159f96f5b3e5cacba813 [file] [log] [blame]
// 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/CSSFontSizeInterpolationType.h"
#include "core/animation/LengthInterpolationFunctions.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/resolver/StyleResolverState.h"
#include "platform/LengthFunctions.h"
#include "platform/fonts/FontDescription.h"
#include "wtf/PtrUtil.h"
#include <memory>
namespace blink {
namespace {
class IsMonospaceChecker : public InterpolationType::ConversionChecker {
public:
static std::unique_ptr<IsMonospaceChecker> create(bool isMonospace) {
return WTF::wrapUnique(new IsMonospaceChecker(isMonospace));
}
private:
IsMonospaceChecker(bool isMonospace) : m_isMonospace(isMonospace) {}
bool isValid(const InterpolationEnvironment& environment,
const InterpolationValue&) const final {
return m_isMonospace ==
environment.state().style()->getFontDescription().isMonospace();
}
const bool m_isMonospace;
};
class InheritedFontSizeChecker : public InterpolationType::ConversionChecker {
public:
static std::unique_ptr<InheritedFontSizeChecker> create(
const FontDescription::Size& inheritedFontSize) {
return WTF::wrapUnique(new InheritedFontSizeChecker(inheritedFontSize));
}
private:
InheritedFontSizeChecker(const FontDescription::Size& inheritedFontSize)
: m_inheritedFontSize(inheritedFontSize.value) {}
bool isValid(const InterpolationEnvironment& environment,
const InterpolationValue&) const final {
return m_inheritedFontSize ==
environment.state().parentFontDescription().getSize().value;
}
const float m_inheritedFontSize;
};
InterpolationValue convertFontSize(float size) {
return InterpolationValue(
LengthInterpolationFunctions::createInterpolablePixels(size));
}
InterpolationValue maybeConvertKeyword(
CSSValueID valueID,
const StyleResolverState& state,
InterpolationType::ConversionCheckers& conversionCheckers) {
if (FontSize::isValidValueID(valueID)) {
bool isMonospace = state.style()->getFontDescription().isMonospace();
conversionCheckers.push_back(IsMonospaceChecker::create(isMonospace));
return convertFontSize(state.fontBuilder().fontSizeForKeyword(
FontSize::keywordSize(valueID), isMonospace));
}
if (valueID != CSSValueSmaller && valueID != CSSValueLarger)
return nullptr;
const FontDescription::Size& inheritedFontSize =
state.parentFontDescription().getSize();
conversionCheckers.push_back(
InheritedFontSizeChecker::create(inheritedFontSize));
if (valueID == CSSValueSmaller)
return convertFontSize(
FontDescription::smallerSize(inheritedFontSize).value);
return convertFontSize(FontDescription::largerSize(inheritedFontSize).value);
}
} // namespace
InterpolationValue CSSFontSizeInterpolationType::maybeConvertNeutral(
const InterpolationValue&,
ConversionCheckers&) const {
return InterpolationValue(
LengthInterpolationFunctions::createNeutralInterpolableValue());
}
InterpolationValue CSSFontSizeInterpolationType::maybeConvertInitial(
const StyleResolverState& state,
ConversionCheckers& conversionCheckers) const {
return maybeConvertKeyword(FontSize::initialValueID(), state,
conversionCheckers);
}
InterpolationValue CSSFontSizeInterpolationType::maybeConvertInherit(
const StyleResolverState& state,
ConversionCheckers& conversionCheckers) const {
const FontDescription::Size& inheritedFontSize =
state.parentFontDescription().getSize();
conversionCheckers.push_back(
InheritedFontSizeChecker::create(inheritedFontSize));
return convertFontSize(inheritedFontSize.value);
}
InterpolationValue CSSFontSizeInterpolationType::maybeConvertValue(
const CSSValue& value,
const StyleResolverState* state,
ConversionCheckers& conversionCheckers) const {
std::unique_ptr<InterpolableValue> result =
LengthInterpolationFunctions::maybeConvertCSSValue(value)
.interpolableValue;
if (result)
return InterpolationValue(std::move(result));
if (!value.isIdentifierValue())
return nullptr;
DCHECK(state);
return maybeConvertKeyword(toCSSIdentifierValue(value).getValueID(), *state,
conversionCheckers);
}
InterpolationValue
CSSFontSizeInterpolationType::maybeConvertStandardPropertyUnderlyingValue(
const ComputedStyle& style) const {
return convertFontSize(style.specifiedFontSize());
}
void CSSFontSizeInterpolationType::applyStandardPropertyValue(
const InterpolableValue& interpolableValue,
const NonInterpolableValue*,
StyleResolverState& state) const {
const FontDescription& parentFont = state.parentFontDescription();
Length fontSizeLength = LengthInterpolationFunctions::createLength(
interpolableValue, nullptr, state.fontSizeConversionData(),
ValueRangeNonNegative);
float fontSize =
floatValueForLength(fontSizeLength, parentFont.getSize().value);
state.fontBuilder().setSize(FontDescription::Size(
0, fontSize,
!fontSizeLength.isPercentOrCalc() || parentFont.isAbsoluteSize()));
}
} // namespace blink