Chromium Code Reviews| Index: Source/core/animation/LengthStyleInterpolation.cpp |
| diff --git a/Source/core/animation/LengthStyleInterpolation.cpp b/Source/core/animation/LengthStyleInterpolation.cpp |
| index 0626c2b0e9adaf0f3de707e8960c297b7cd1a0f0..4388de89d8771e39176bee22b77976469f9e3a7f 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,74 @@ 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; |
| + default: |
| + return nullptr; |
| + } |
| +} |
| + |
| namespace { |
| static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) |
| @@ -79,6 +150,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 +217,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())); |
| + RefPtrWillBeRawPtr<AnimatableValue> before, after; |
|
dstockwell
2015/03/09 02:39:25
I think this would be simpler with ENABLE(ASSERT)
alancutter (OOO until 2018)
2015/03/09 03:09:00
Done.
|
| + ASSERT((\ |
| + before = CSSAnimatableValueFactory::create(m_id, *state.style()), \ |
| + StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValue, m_range).get()), \ |
| + after = CSSAnimatableValueFactory::create(m_id, *state.style()), \ |
| + before->equals(*after))); |
| + } else { |
| + StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValue, m_range).get()); |
| + } |
| } |
| DEFINE_TRACE(LengthStyleInterpolation) |