| Index: Source/core/animation/LengthStyleInterpolation.cpp
|
| diff --git a/Source/core/animation/LengthStyleInterpolation.cpp b/Source/core/animation/LengthStyleInterpolation.cpp
|
| index 0626c2b0e9adaf0f3de707e8960c297b7cd1a0f0..3be7e24b17fd81b93c1b9cabcfb19277fc01dfdc 100644
|
| --- a/Source/core/animation/LengthStyleInterpolation.cpp
|
| +++ b/Source/core/animation/LengthStyleInterpolation.cpp
|
| @@ -5,8 +5,11 @@
|
| #include "config.h"
|
| #include "core/animation/LengthStyleInterpolation.h"
|
|
|
| +#include "core/animation/css/CSSAnimatableValueFactory.h"
|
| #include "core/css/CSSCalculationValue.h"
|
| #include "core/css/resolver/StyleBuilder.h"
|
| +#include "core/css/resolver/StyleResolverState.h"
|
| +#include "platform/CalculationValue.h"
|
|
|
| namespace blink {
|
|
|
| @@ -52,6 +55,95 @@ PassOwnPtrWillBeRawPtr<InterpolableValue> LengthStyleInterpolation::toInterpolab
|
| return listOfValuesAndTypes.release();
|
| }
|
|
|
| +bool LengthStyleInterpolation::isPixelsOrPercentOnly(const InterpolableValue& value)
|
| +{
|
| + const InterpolableList& types = *toInterpolableList(toInterpolableList(value).get(1));
|
| + bool result = false;
|
| + for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) {
|
| + bool typeIsPresent = toInterpolableNumber(types.get(i))->value();
|
| + if (i == CSSPrimitiveValue::UnitTypePixels)
|
| + result |= typeIsPresent;
|
| + else if (i == CSSPrimitiveValue::UnitTypePercentage)
|
| + result |= typeIsPresent;
|
| + else if (typeIsPresent)
|
| + return false;
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +LengthStyleInterpolation::LengthSetter LengthStyleInterpolation::lengthSetterForProperty(CSSPropertyID property)
|
| +{
|
| + switch (property) {
|
| + case CSSPropertyBottom:
|
| + return &LayoutStyle::setBottom;
|
| + case CSSPropertyFlexBasis:
|
| + return &LayoutStyle::setFlexBasis;
|
| + case CSSPropertyHeight:
|
| + return &LayoutStyle::setHeight;
|
| + case CSSPropertyLeft:
|
| + return &LayoutStyle::setLeft;
|
| + case CSSPropertyLineHeight:
|
| + return &LayoutStyle::setLineHeight;
|
| + case CSSPropertyMarginBottom:
|
| + return &LayoutStyle::setMarginBottom;
|
| + case CSSPropertyMarginLeft:
|
| + return &LayoutStyle::setMarginLeft;
|
| + case CSSPropertyMarginRight:
|
| + return &LayoutStyle::setMarginRight;
|
| + case CSSPropertyMarginTop:
|
| + return &LayoutStyle::setMarginTop;
|
| + case CSSPropertyMaxHeight:
|
| + return &LayoutStyle::setMaxHeight;
|
| + case CSSPropertyMaxWidth:
|
| + return &LayoutStyle::setMaxWidth;
|
| + case CSSPropertyMinHeight:
|
| + return &LayoutStyle::setMinHeight;
|
| + case CSSPropertyMinWidth:
|
| + return &LayoutStyle::setMinWidth;
|
| + case CSSPropertyMotionOffset:
|
| + return &LayoutStyle::setMotionOffset;
|
| + case CSSPropertyPaddingBottom:
|
| + return &LayoutStyle::setPaddingBottom;
|
| + case CSSPropertyPaddingLeft:
|
| + return &LayoutStyle::setPaddingLeft;
|
| + case CSSPropertyPaddingRight:
|
| + return &LayoutStyle::setPaddingRight;
|
| + case CSSPropertyPaddingTop:
|
| + return &LayoutStyle::setPaddingTop;
|
| + case CSSPropertyRight:
|
| + return &LayoutStyle::setRight;
|
| + case CSSPropertyShapeMargin:
|
| + return &LayoutStyle::setShapeMargin;
|
| + case CSSPropertyTop:
|
| + return &LayoutStyle::setTop;
|
| + case CSSPropertyWidth:
|
| + return &LayoutStyle::setWidth;
|
| + // These properties don't have a LayoutStyle setter with the signature void(*)(const Length&).
|
| + case CSSPropertyBaselineShift:
|
| + case CSSPropertyBorderBottomWidth:
|
| + case CSSPropertyBorderLeftWidth:
|
| + case CSSPropertyBorderRightWidth:
|
| + case CSSPropertyBorderTopWidth:
|
| + case CSSPropertyFontSize:
|
| + case CSSPropertyLetterSpacing:
|
| + case CSSPropertyOutlineOffset:
|
| + case CSSPropertyOutlineWidth:
|
| + case CSSPropertyPerspective:
|
| + case CSSPropertyStrokeDashoffset:
|
| + case CSSPropertyVerticalAlign:
|
| + case CSSPropertyWebkitBorderHorizontalSpacing:
|
| + case CSSPropertyWebkitBorderVerticalSpacing:
|
| + case CSSPropertyWebkitColumnGap:
|
| + case CSSPropertyWebkitColumnRuleWidth:
|
| + case CSSPropertyWebkitColumnWidth:
|
| + case CSSPropertyWordSpacing:
|
| + return nullptr;
|
| + default:
|
| + ASSERT_NOT_REACHED();
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| namespace {
|
|
|
| static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType)
|
| @@ -79,6 +171,35 @@ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(Pas
|
| return previous;
|
| }
|
|
|
| +static double clampToRange(double x, ValueRange range)
|
| +{
|
| + return (range == ValueRangeNonNegative && x < 0) ? 0 : x;
|
| +}
|
| +
|
| +static Length lengthFromInterpolableValue(const InterpolableValue& value, InterpolationRange interpolationRange, float zoom)
|
| +{
|
| + const InterpolableList& values = *toInterpolableList(toInterpolableList(value).get(0));
|
| + const InterpolableList& types = *toInterpolableList(toInterpolableList(value).get(1));
|
| + bool hasPixels = toInterpolableNumber(types.get(CSSPrimitiveValue::UnitTypePixels))->value();
|
| + bool hasPercent = toInterpolableNumber(types.get(CSSPrimitiveValue::UnitTypePercentage))->value();
|
| +
|
| + ValueRange range = (interpolationRange == RangeNonNegative) ? ValueRangeNonNegative : ValueRangeAll;
|
| + PixelsAndPercent pixelsAndPercent(0, 0);
|
| + if (hasPixels)
|
| + pixelsAndPercent.pixels = toInterpolableNumber(values.get(CSSPrimitiveValue::UnitTypePixels))->value() * zoom;
|
| + if (hasPercent)
|
| + pixelsAndPercent.percent = toInterpolableNumber(values.get(CSSPrimitiveValue::UnitTypePercentage))->value();
|
| +
|
| + if (hasPixels && hasPercent)
|
| + return Length(CalculationValue::create(pixelsAndPercent, range));
|
| + if (hasPixels)
|
| + return Length(clampToRange(pixelsAndPercent.pixels, range), Fixed);
|
| + if (hasPercent)
|
| + return Length(clampToRange(pixelsAndPercent.percent, range), Percent);
|
| + ASSERT_NOT_REACHED();
|
| + return Length(0, Fixed);
|
| +}
|
| +
|
| }
|
|
|
| PassRefPtrWillBeRawPtr<CSSPrimitiveValue> LengthStyleInterpolation::fromInterpolableValue(const InterpolableValue& value, InterpolationRange range)
|
| @@ -117,7 +238,17 @@ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> LengthStyleInterpolation::fromInterpol
|
|
|
| void LengthStyleInterpolation::apply(StyleResolverState& state) const
|
| {
|
| - StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValue.get(), m_range).get());
|
| + if (m_lengthSetter) {
|
| + (state.style()->*m_lengthSetter)(lengthFromInterpolableValue(*m_cachedValue, m_range, state.style()->effectiveZoom()));
|
| +#if ENABLE(ASSERT)
|
| + RefPtrWillBeRawPtr<AnimatableValue> before = CSSAnimatableValueFactory::create(m_id, *state.style());
|
| + StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValue, m_range).get());
|
| + RefPtrWillBeRawPtr<AnimatableValue> after = CSSAnimatableValueFactory::create(m_id, *state.style());
|
| + ASSERT(before->equals(*after));
|
| +#endif
|
| + } else {
|
| + StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValue, m_range).get());
|
| + }
|
| }
|
|
|
| DEFINE_TRACE(LengthStyleInterpolation)
|
|
|