Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / animation / DoubleStyleInterpolation.cpp
blob668ab32d12cbf2e7b75f19313f992243d1817c96
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
3 // found in the LICENSE file.
5 #include "config.h"
6 #include "core/animation/DoubleStyleInterpolation.h"
8 #include "core/css/CSSValueList.h"
9 #include "core/css/resolver/StyleBuilder.h"
10 #include "core/style/ComputedStyleConstants.h"
12 namespace blink {
14 bool DoubleStyleInterpolation::canCreateFrom(const CSSValue& value)
16 return value.isPrimitiveValue() && (toCSSPrimitiveValue(value).isNumber() || toCSSPrimitiveValue(value).isAngle());
19 PassOwnPtr<InterpolableValue> DoubleStyleInterpolation::doubleToInterpolableValue(const CSSValue& value)
21 ASSERT(canCreateFrom(value));
22 const CSSPrimitiveValue& primitive = toCSSPrimitiveValue(value);
23 if (primitive.isNumber())
24 return InterpolableNumber::create(primitive.getDoubleValue());
25 if (primitive.isAngle())
26 return InterpolableNumber::create(primitive.computeDegrees());
27 ASSERT_NOT_REACHED();
28 return nullptr;
31 static double clampToRange(double value, InterpolationRange clamp)
33 switch (clamp) {
34 case RangeAll:
35 // Do nothing
36 return value;
37 case RangeZeroToOne:
38 return clampTo<float>(value, 0, 1);
39 case RangeOpacityFIXME:
40 return clampTo<float>(value, 0, nextafterf(1, 0));
41 case RangeFloor:
42 return floor(value);
43 case RangeRound:
44 return round(value);
45 case RangeRoundGreaterThanOrEqualToOne:
46 return clampTo<float>(round(value), 1);
47 case RangeGreaterThanOrEqualToOne:
48 return clampTo<float>(value, 1);
49 case RangeNonNegative:
50 return clampTo<float>(value, 0);
51 default:
52 ASSERT_NOT_REACHED();
53 return value;
57 PassRefPtrWillBeRawPtr<CSSValue> DoubleStyleInterpolation::interpolableValueToDouble(const InterpolableValue* value, bool isNumber, InterpolationRange clamp)
59 ASSERT(value->isNumber());
60 double doubleValue = clampToRange(toInterpolableNumber(value)->value(), clamp);
62 if (isNumber)
63 return CSSPrimitiveValue::create(doubleValue, CSSPrimitiveValue::UnitType::Number);
64 return CSSPrimitiveValue::create(doubleValue, CSSPrimitiveValue::UnitType::Degrees);
67 void DoubleStyleInterpolation::apply(StyleResolverState& state) const
69 if (m_id != CSSPropertyMotionRotation) {
70 StyleBuilder::applyProperty(m_id, state, interpolableValueToDouble(m_cachedValue.get(), m_isNumber, m_clamp).get());
71 return;
74 StyleBuilder::applyProperty(m_id, state, interpolableValueToMotionRotation(m_cachedValue.get(), m_flag).get());
77 PassOwnPtr<InterpolableValue> DoubleStyleInterpolation::toInterpolableValue(const CSSValue& value, CSSPropertyID property)
79 ASSERT(canCreateFrom(value));
80 return doubleToInterpolableValue(value);
83 PassRefPtrWillBeRawPtr<CSSValue> DoubleStyleInterpolation::fromInterpolableValue(const InterpolableValue& value, InterpolationRange range)
85 return interpolableValueToDouble(&value, true, range);
88 namespace {
90 bool extractMotionRotation(const CSSValue& value, float* rotation, MotionRotationType* rotationType)
92 *rotation = 0;
93 *rotationType = MotionRotationFixed;
95 if (!value.isValueList())
96 return false;
97 const CSSValueList& list = toCSSValueList(value);
99 int len = list.length();
100 for (int i = 0; i < len; i++) {
101 const CSSValue* item = list.item(i);
102 if (!item->isPrimitiveValue())
103 return false;
104 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
105 if (primitiveValue->getValueID() == CSSValueAuto) {
106 *rotationType = MotionRotationAuto;
107 } else if (primitiveValue->getValueID() == CSSValueReverse) {
108 *rotationType = MotionRotationAuto;
109 *rotation += 180;
110 } else if (primitiveValue->isAngle()) {
111 *rotation += primitiveValue->computeDegrees();
112 } else {
113 return false;
116 return true;
119 } // namespace
121 PassRefPtrWillBeRawPtr<CSSValue> DoubleStyleInterpolation::interpolableValueToMotionRotation(InterpolableValue* value, bool flag)
123 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
124 if (flag)
125 list->append(CSSPrimitiveValue::createIdentifier(CSSValueAuto));
126 ASSERT(value->isNumber());
127 list->append(CSSPrimitiveValue::create(toInterpolableNumber(value)->value(), CSSPrimitiveValue::UnitType::Degrees));
128 return list.release();
131 PassOwnPtr<InterpolableValue> DoubleStyleInterpolation::motionRotationToInterpolableValue(const CSSValue& value)
133 float rotation;
134 MotionRotationType rotationType;
135 extractMotionRotation(value, &rotation, &rotationType);
137 return InterpolableNumber::create(rotation);
140 PassRefPtr<DoubleStyleInterpolation> DoubleStyleInterpolation::maybeCreateFromMotionRotation(const CSSValue& start, const CSSValue& end, CSSPropertyID id)
142 float startRotation, endRotation;
143 MotionRotationType startRotationType, endRotationType;
145 if (!extractMotionRotation(start, &startRotation, &startRotationType)
146 || !extractMotionRotation(end, &endRotation, &endRotationType)
147 || startRotationType != endRotationType)
148 return nullptr;
150 return adoptRef(new DoubleStyleInterpolation(
151 motionRotationToInterpolableValue(start),
152 motionRotationToInterpolableValue(end),
153 id, true, InterpolationRange::RangeAll, startRotationType == MotionRotationAuto));