Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/animation/LengthStyleInterpolation.h" | 6 #include "core/animation/LengthStyleInterpolation.h" |
| 7 | 7 |
| 8 #include "core/animation/css/CSSAnimatableValueFactory.h" | |
| 8 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
| 9 #include "core/css/resolver/StyleBuilder.h" | 10 #include "core/css/resolver/StyleBuilder.h" |
| 11 #include "core/css/resolver/StyleResolverState.h" | |
| 12 #include "platform/CalculationValue.h" | |
| 10 | 13 |
| 11 namespace blink { | 14 namespace blink { |
| 12 | 15 |
| 13 bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value) | 16 bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value) |
| 14 { | 17 { |
| 15 if (value.isPrimitiveValue()) { | 18 if (value.isPrimitiveValue()) { |
| 16 const CSSPrimitiveValue& primitiveValue = blink::toCSSPrimitiveValue(val ue); | 19 const CSSPrimitiveValue& primitiveValue = blink::toCSSPrimitiveValue(val ue); |
| 17 if (primitiveValue.cssCalcValue()) | 20 if (primitiveValue.cssCalcValue()) |
| 18 return true; | 21 return true; |
| 19 | 22 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 45 listOfValues->set(i, InterpolableNumber::create(arrayOfValues.at(i))); | 48 listOfValues->set(i, InterpolableNumber::create(arrayOfValues.at(i))); |
| 46 listOfTypes->set(i, InterpolableNumber::create(arrayOfTypes.get(i))); | 49 listOfTypes->set(i, InterpolableNumber::create(arrayOfTypes.get(i))); |
| 47 } | 50 } |
| 48 | 51 |
| 49 listOfValuesAndTypes->set(0, listOfValues.release()); | 52 listOfValuesAndTypes->set(0, listOfValues.release()); |
| 50 listOfValuesAndTypes->set(1, listOfTypes.release()); | 53 listOfValuesAndTypes->set(1, listOfTypes.release()); |
| 51 | 54 |
| 52 return listOfValuesAndTypes.release(); | 55 return listOfValuesAndTypes.release(); |
| 53 } | 56 } |
| 54 | 57 |
| 58 bool LengthStyleInterpolation::isPixelsOrPercentOnly(const InterpolableValue& va lue) | |
| 59 { | |
| 60 const InterpolableList& types = *toInterpolableList(toInterpolableList(value ).get(1)); | |
| 61 bool result = false; | |
| 62 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { | |
| 63 bool typeIsPresent = toInterpolableNumber(types.get(i))->value(); | |
| 64 if (i == CSSPrimitiveValue::UnitTypePixels) | |
| 65 result |= typeIsPresent; | |
| 66 else if (i == CSSPrimitiveValue::UnitTypePercentage) | |
| 67 result |= typeIsPresent; | |
| 68 else if (typeIsPresent) | |
| 69 return false; | |
| 70 } | |
| 71 return result; | |
| 72 } | |
| 73 | |
| 74 LengthStyleInterpolation::LengthSetter LengthStyleInterpolation::lengthSetterFor Property(CSSPropertyID property) | |
| 75 { | |
| 76 switch (property) { | |
| 77 case CSSPropertyBottom: | |
| 78 return &LayoutStyle::setBottom; | |
| 79 case CSSPropertyFlexBasis: | |
| 80 return &LayoutStyle::setFlexBasis; | |
| 81 case CSSPropertyHeight: | |
| 82 return &LayoutStyle::setHeight; | |
| 83 case CSSPropertyLeft: | |
| 84 return &LayoutStyle::setLeft; | |
| 85 case CSSPropertyLineHeight: | |
| 86 return &LayoutStyle::setLineHeight; | |
| 87 case CSSPropertyMarginBottom: | |
| 88 return &LayoutStyle::setMarginBottom; | |
| 89 case CSSPropertyMarginLeft: | |
| 90 return &LayoutStyle::setMarginLeft; | |
| 91 case CSSPropertyMarginRight: | |
| 92 return &LayoutStyle::setMarginRight; | |
| 93 case CSSPropertyMarginTop: | |
| 94 return &LayoutStyle::setMarginTop; | |
| 95 case CSSPropertyMaxHeight: | |
| 96 return &LayoutStyle::setMaxHeight; | |
| 97 case CSSPropertyMaxWidth: | |
| 98 return &LayoutStyle::setMaxWidth; | |
| 99 case CSSPropertyMinHeight: | |
| 100 return &LayoutStyle::setMinHeight; | |
| 101 case CSSPropertyMinWidth: | |
| 102 return &LayoutStyle::setMinWidth; | |
| 103 case CSSPropertyMotionOffset: | |
| 104 return &LayoutStyle::setMotionOffset; | |
| 105 case CSSPropertyPaddingBottom: | |
| 106 return &LayoutStyle::setPaddingBottom; | |
| 107 case CSSPropertyPaddingLeft: | |
| 108 return &LayoutStyle::setPaddingLeft; | |
| 109 case CSSPropertyPaddingRight: | |
| 110 return &LayoutStyle::setPaddingRight; | |
| 111 case CSSPropertyPaddingTop: | |
| 112 return &LayoutStyle::setPaddingTop; | |
| 113 case CSSPropertyRight: | |
| 114 return &LayoutStyle::setRight; | |
| 115 case CSSPropertyShapeMargin: | |
| 116 return &LayoutStyle::setShapeMargin; | |
| 117 case CSSPropertyTop: | |
| 118 return &LayoutStyle::setTop; | |
| 119 case CSSPropertyWidth: | |
| 120 return &LayoutStyle::setWidth; | |
| 121 default: | |
| 122 return nullptr; | |
| 123 } | |
| 124 } | |
| 125 | |
| 55 namespace { | 126 namespace { |
| 56 | 127 |
| 57 static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) | 128 static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) |
| 58 { | 129 { |
| 59 return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUni tTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType))) ; | 130 return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUni tTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType))) ; |
| 60 } | 131 } |
| 61 | 132 |
| 62 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(Pas sRefPtrWillBeRawPtr<CSSCalcExpressionNode> previous, const InterpolableList* lis t, size_t position) | 133 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(Pas sRefPtrWillBeRawPtr<CSSCalcExpressionNode> previous, const InterpolableList* lis t, size_t position) |
| 63 { | 134 { |
| 64 const InterpolableList* listOfValues = toInterpolableList(list->get(0)); | 135 const InterpolableList* listOfValues = toInterpolableList(list->get(0)); |
| 65 const InterpolableList* listOfTypes = toInterpolableList(list->get(1)); | 136 const InterpolableList* listOfTypes = toInterpolableList(list->get(1)); |
| 66 while (position != CSSPrimitiveValue::LengthUnitTypeCount) { | 137 while (position != CSSPrimitiveValue::LengthUnitTypeCount) { |
| 67 const InterpolableNumber *subValueType = toInterpolableNumber(listOfType s->get(position)); | 138 const InterpolableNumber *subValueType = toInterpolableNumber(listOfType s->get(position)); |
| 68 if (subValueType->value()) { | 139 if (subValueType->value()) { |
| 69 RefPtrWillBeRawPtr<CSSCalcExpressionNode> next; | 140 RefPtrWillBeRawPtr<CSSCalcExpressionNode> next; |
| 70 double value = toInterpolableNumber(listOfValues->get(position))->va lue(); | 141 double value = toInterpolableNumber(listOfValues->get(position))->va lue(); |
| 71 if (previous) | 142 if (previous) |
| 72 next = CSSCalcValue::createExpressionNode(previous, CSSCalcValue ::createExpressionNode(CSSPrimitiveValue::create(value, toUnitType(position))), CalcAdd); | 143 next = CSSCalcValue::createExpressionNode(previous, CSSCalcValue ::createExpressionNode(CSSPrimitiveValue::create(value, toUnitType(position))), CalcAdd); |
| 73 else | 144 else |
| 74 next = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::cre ate(value, toUnitType(position))); | 145 next = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::cre ate(value, toUnitType(position))); |
| 75 return constructCalcExpression(next, list, position + 1); | 146 return constructCalcExpression(next, list, position + 1); |
| 76 } | 147 } |
| 77 position++; | 148 position++; |
| 78 } | 149 } |
| 79 return previous; | 150 return previous; |
| 80 } | 151 } |
| 81 | 152 |
| 153 static double clampToRange(double x, ValueRange range) | |
| 154 { | |
| 155 return (range == ValueRangeNonNegative && x < 0) ? 0 : x; | |
| 156 } | |
| 157 | |
| 158 static Length lengthFromInterpolableValue(const InterpolableValue& value, Interp olationRange interpolationRange, float zoom) | |
| 159 { | |
| 160 const InterpolableList& values = *toInterpolableList(toInterpolableList(valu e).get(0)); | |
| 161 const InterpolableList& types = *toInterpolableList(toInterpolableList(value ).get(1)); | |
| 162 bool hasPixels = toInterpolableNumber(types.get(CSSPrimitiveValue::UnitTypeP ixels))->value(); | |
| 163 bool hasPercent = toInterpolableNumber(types.get(CSSPrimitiveValue::UnitType Percentage))->value(); | |
| 164 | |
| 165 ValueRange range = (interpolationRange == RangeNonNegative) ? ValueRangeNonN egative : ValueRangeAll; | |
| 166 PixelsAndPercent pixelsAndPercent(0, 0); | |
| 167 if (hasPixels) | |
| 168 pixelsAndPercent.pixels = toInterpolableNumber(values.get(CSSPrimitiveVa lue::UnitTypePixels))->value() * zoom; | |
| 169 if (hasPercent) | |
| 170 pixelsAndPercent.percent = toInterpolableNumber(values.get(CSSPrimitiveV alue::UnitTypePercentage))->value(); | |
| 171 | |
| 172 if (hasPixels && hasPercent) | |
| 173 return Length(CalculationValue::create(pixelsAndPercent, range)); | |
| 174 if (hasPixels) | |
| 175 return Length(clampToRange(pixelsAndPercent.pixels, range), Fixed); | |
| 176 if (hasPercent) | |
| 177 return Length(clampToRange(pixelsAndPercent.percent, range), Percent); | |
| 178 ASSERT_NOT_REACHED(); | |
| 179 return Length(0, Fixed); | |
| 180 } | |
| 181 | |
| 82 } | 182 } |
| 83 | 183 |
| 84 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> LengthStyleInterpolation::fromInterpol ableValue(const InterpolableValue& value, InterpolationRange range) | 184 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> LengthStyleInterpolation::fromInterpol ableValue(const InterpolableValue& value, InterpolationRange range) |
| 85 { | 185 { |
| 86 const InterpolableList* listOfValuesAndTypes = toInterpolableList(&value); | 186 const InterpolableList* listOfValuesAndTypes = toInterpolableList(&value); |
| 87 const InterpolableList* listOfValues = toInterpolableList(listOfValuesAndTyp es->get(0)); | 187 const InterpolableList* listOfValues = toInterpolableList(listOfValuesAndTyp es->get(0)); |
| 88 const InterpolableList* listOfTypes = toInterpolableList(listOfValuesAndType s->get(1)); | 188 const InterpolableList* listOfTypes = toInterpolableList(listOfValuesAndType s->get(1)); |
| 89 unsigned unitTypeCount = 0; | 189 unsigned unitTypeCount = 0; |
| 90 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { | 190 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
| 91 const InterpolableNumber* subType = toInterpolableNumber(listOfTypes->ge t(i)); | 191 const InterpolableNumber* subType = toInterpolableNumber(listOfTypes->ge t(i)); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 110 } | 210 } |
| 111 ASSERT_NOT_REACHED(); | 211 ASSERT_NOT_REACHED(); |
| 112 default: | 212 default: |
| 113 ValueRange valueRange = (range == RangeNonNegative) ? ValueRangeNonNegat ive : ValueRangeAll; | 213 ValueRange valueRange = (range == RangeNonNegative) ? ValueRangeNonNegat ive : ValueRangeAll; |
| 114 return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpre ssion(nullptr, listOfValuesAndTypes, 0), valueRange)); | 214 return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpre ssion(nullptr, listOfValuesAndTypes, 0), valueRange)); |
| 115 } | 215 } |
| 116 } | 216 } |
| 117 | 217 |
| 118 void LengthStyleInterpolation::apply(StyleResolverState& state) const | 218 void LengthStyleInterpolation::apply(StyleResolverState& state) const |
| 119 { | 219 { |
| 120 StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cachedValu e.get(), m_range).get()); | 220 if (m_lengthSetter) { |
| 221 (state.style()->*m_lengthSetter)(lengthFromInterpolableValue(*m_cachedVa lue, m_range, state.style()->effectiveZoom())); | |
| 222 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.
| |
| 223 ASSERT((\ | |
| 224 before = CSSAnimatableValueFactory::create(m_id, *state.style()), \ | |
| 225 StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_ca chedValue, m_range).get()), \ | |
| 226 after = CSSAnimatableValueFactory::create(m_id, *state.style()), \ | |
| 227 before->equals(*after))); | |
| 228 } else { | |
| 229 StyleBuilder::applyProperty(m_id, state, fromInterpolableValue(*m_cached Value, m_range).get()); | |
| 230 } | |
| 121 } | 231 } |
| 122 | 232 |
| 123 DEFINE_TRACE(LengthStyleInterpolation) | 233 DEFINE_TRACE(LengthStyleInterpolation) |
| 124 { | 234 { |
| 125 StyleInterpolation::trace(visitor); | 235 StyleInterpolation::trace(visitor); |
| 126 } | 236 } |
| 127 | 237 |
| 128 } | 238 } |
| OLD | NEW |