• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef AnimatableLength_h
32 #define AnimatableLength_h
33 
34 #include "core/animation/AnimatableValue.h"
35 #include "core/css/CSSCalculationValue.h"
36 #include "core/css/CSSPrimitiveValue.h"
37 #include "platform/Length.h"
38 
39 namespace WebCore {
40 
41 enum NumberRange {
42     AllValues,
43     NonNegativeValues,
44 };
45 
46 // Handles animation of CSS length and percentage values including CSS calc.
47 // See primitiveUnitToNumberType() for the list of supported units.
48 // If created from a CSSPrimitiveValue this class will cache it to be returned in toCSSValue().
49 class AnimatableLength : public AnimatableValue {
50 public:
51     enum NumberUnitType {
52         UnitTypeCalc,
53         UnitTypePixels,
54         UnitTypePercentage,
55         UnitTypeFontSize,
56         UnitTypeFontXSize,
57         UnitTypeRootFontSize,
58         UnitTypeViewportWidth,
59         UnitTypeViewportHeight,
60         UnitTypeViewportMin,
61         UnitTypeViewportMax,
62     };
63 
~AnimatableLength()64     virtual ~AnimatableLength() { }
65     static bool canCreateFrom(const CSSValue*);
66     static PassRefPtr<AnimatableLength> create(CSSValue*);
67     static PassRefPtr<AnimatableLength> create(double number, NumberUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue = 0)
68     {
69         return adoptRef(new AnimatableLength(number, unitType, cssPrimitiveValue));
70     }
71     static PassRefPtr<AnimatableLength> create(PassRefPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue = 0)
72     {
73         return adoptRef(new AnimatableLength(calcExpression, cssPrimitiveValue));
74     }
75     PassRefPtr<CSSValue> toCSSValue(NumberRange = AllValues) const;
76     Length toLength(const CSSToLengthConversionData&, NumberRange = AllValues) const;
77 
78 protected:
79     virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
80     virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
81 
82 private:
AnimatableLength(double number,NumberUnitType unitType,CSSPrimitiveValue * cssPrimitiveValue)83     AnimatableLength(double number, NumberUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue)
84         : m_number(number)
85         , m_unitType(unitType)
86         , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
87     {
88         ASSERT(m_unitType != UnitTypeCalc);
89     }
AnimatableLength(PassRefPtr<CSSCalcExpressionNode> calcExpression,CSSPrimitiveValue * cssPrimitiveValue)90     AnimatableLength(PassRefPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue)
91         : m_unitType(UnitTypeCalc)
92         , m_calcExpression(calcExpression)
93         , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
94     {
95         ASSERT(m_calcExpression);
96     }
type()97     virtual AnimatableType type() const OVERRIDE { return TypeLength; }
98     virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
99 
isCalc()100     bool isCalc() const
101     {
102         return m_unitType == UnitTypeCalc;
103     }
104 
isViewportUnit()105     bool isViewportUnit() const
106     {
107         return m_unitType == UnitTypeViewportWidth || m_unitType == UnitTypeViewportHeight || m_unitType == UnitTypeViewportMin || m_unitType == UnitTypeViewportMax;
108     }
109 
create(const AnimatableLength * leftAddend,const AnimatableLength * rightAddend)110     static PassRefPtr<AnimatableLength> create(const AnimatableLength* leftAddend, const AnimatableLength* rightAddend)
111     {
112         ASSERT(leftAddend && rightAddend);
113         return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpressionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd));
114     }
115 
116     PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(NumberRange) const;
117     PassRefPtr<CSSCalcExpressionNode> toCSSCalcExpressionNode() const;
118 
119     PassRefPtr<AnimatableLength> scale(double) const;
clampedNumber(NumberRange range)120     double clampedNumber(NumberRange range) const
121     {
122         ASSERT(!isCalc());
123         return (range == NonNegativeValues && m_number <= 0) ? 0 : m_number;
124     }
125 
126     // Returns true and populates numberType, if primitiveUnit is a primitive length unit. Otherwise, returns false.
127     static bool primitiveUnitToNumberType(unsigned short primitiveUnit, NumberUnitType& numberType);
128 
129     static unsigned short numberTypeToPrimitiveUnit(NumberUnitType numberType);
130 
131     // Zero is effectively unitless, except in the case of percentage.
132     // http://www.w3.org/TR/css3-values/#calc-computed-value
133     // e.g. calc(100% - 100% + 1em) resolves to calc(0% + 1em), not to calc(1em)
isUnitlessZero()134     bool isUnitlessZero() const
135     {
136         return !isCalc() && !m_number && m_unitType != UnitTypePercentage;
137     }
138 
commonUnitType(const AnimatableLength * length)139     NumberUnitType commonUnitType(const AnimatableLength* length) const
140     {
141         if (m_unitType == length->m_unitType)
142             return m_unitType;
143 
144         if (isUnitlessZero())
145             return length->m_unitType;
146         if (length->isUnitlessZero())
147             return m_unitType;
148 
149         return UnitTypeCalc;
150     }
151 
152     double m_number;
153     const NumberUnitType m_unitType;
154 
155     RefPtr<CSSCalcExpressionNode> m_calcExpression;
156 
157     mutable RefPtr<CSSPrimitiveValue> m_cachedCSSPrimitiveValue;
158 
159     friend class AnimationAnimatableLengthTest;
160 };
161 
162 DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableLength, isLength());
163 
164 } // namespace WebCore
165 
166 #endif // AnimatableLength_h
167