File: DoubleStyleInterpolation.cpp

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (119 lines) | stat: -rw-r--r-- 4,264 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2014 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 "config.h"
#include "core/animation/DoubleStyleInterpolation.h"

#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/resolver/StyleBuilder.h"

namespace blink {

PassOwnPtrWillBeRawPtr<InterpolableValue> DoubleStyleInterpolation::doubleToInterpolableValue(const CSSValue& value)
{
    ASSERT(canCreateFrom(value));
    const CSSPrimitiveValue& primitive = toCSSPrimitiveValue(value);
    return InterpolableNumber::create(primitive.getDoubleValue());
}

PassRefPtrWillBeRawPtr<CSSValue> DoubleStyleInterpolation::interpolableValueToDouble(InterpolableValue* value, ClampRange clamp)
{
    ASSERT(value->isNumber());
    double doubleValue = toInterpolableNumber(value)->value();
    if (clamp == ClampOpacity) {
        doubleValue = clampTo<float>(doubleValue, 0, nextafterf(1, 0));
    }
    return CSSPrimitiveValue::create(doubleValue, CSSPrimitiveValue::CSS_NUMBER);
}

bool DoubleStyleInterpolation::canCreateFrom(const CSSValue& value)
{
    return value.isPrimitiveValue() && toCSSPrimitiveValue(value).isNumber();
}

void DoubleStyleInterpolation::apply(StyleResolverState& state) const
{
    if (m_id != CSSPropertyMotionRotation) {
        StyleBuilder::applyProperty(m_id, state, interpolableValueToDouble(m_cachedValue.get(), m_clamp).get());
        return;
    }

    StyleBuilder::applyProperty(m_id, state, interpolableValueToMotionRotation(m_cachedValue.get(), m_flag).get());
}

void DoubleStyleInterpolation::trace(Visitor* visitor)
{
    StyleInterpolation::trace(visitor);
}

namespace {

bool extractMotionRotation(const CSSValue& value, float* rotation, MotionRotationType* rotationType)
{
    *rotation = 0;
    *rotationType = MotionRotationFixed;

    if (!value.isValueList())
        return false;
    const CSSValueList& list = toCSSValueList(value);

    int len = list.length();
    for (int i = 0; i < len; i++) {
        const CSSValue* item = list.item(i);
        if (!item->isPrimitiveValue())
            return false;
        const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
        if (primitiveValue->getValueID() == CSSValueAuto) {
            *rotationType = MotionRotationAuto;
        } else if (primitiveValue->getValueID() == CSSValueReverse) {
            *rotationType = MotionRotationAuto;
            *rotation += 180;
        } else if (primitiveValue->isAngle() || primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
            *rotation += primitiveValue->computeDegrees();
        } else {
            return false;
        }
    }
    return true;
}

} // namespace

PassRefPtrWillBeRawPtr<CSSValue> DoubleStyleInterpolation::interpolableValueToMotionRotation(InterpolableValue* value, bool flag)
{
    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
    if (flag)
        list->append(CSSPrimitiveValue::createIdentifier(CSSValueAuto));
    ASSERT(value->isNumber());
    list->append(CSSPrimitiveValue::create(toInterpolableNumber(value)->value(), CSSPrimitiveValue::CSS_DEG));
    return list.release();
}

PassOwnPtrWillBeRawPtr<InterpolableValue> DoubleStyleInterpolation::motionRotationToInterpolableValue(const CSSValue& value)
{
    float rotation;
    MotionRotationType rotationType;
    extractMotionRotation(value, &rotation, &rotationType);

    return InterpolableNumber::create(rotation);
}

PassRefPtrWillBeRawPtr<DoubleStyleInterpolation> DoubleStyleInterpolation::maybeCreateFromMotionRotation(const CSSValue& start, const CSSValue& end, CSSPropertyID id)
{
    float startRotation, endRotation;
    MotionRotationType startRotationType, endRotationType;

    if (!extractMotionRotation(start, &startRotation, &startRotationType)
        || !extractMotionRotation(end, &endRotation, &endRotationType)
        || startRotationType != endRotationType)
        return nullptr;

    return adoptRefWillBeNoop(new DoubleStyleInterpolation(
        motionRotationToInterpolableValue(start),
        motionRotationToInterpolableValue(end),
        id, NoClamp, startRotationType == MotionRotationAuto));
}

}