• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 CalculationValue_h
32 #define CalculationValue_h
33 
34 #include "platform/Length.h"
35 #include "platform/LengthFunctions.h"
36 #include "wtf/OwnPtr.h"
37 #include "wtf/PassOwnPtr.h"
38 #include "wtf/RefCounted.h"
39 #include "wtf/Vector.h"
40 
41 namespace WebCore {
42 
43 enum CalcOperator {
44     CalcAdd = '+',
45     CalcSubtract = '-',
46     CalcMultiply = '*',
47     CalcDivide = '/'
48 };
49 
50 enum CalcExpressionNodeType {
51     CalcExpressionNodeUndefined,
52     CalcExpressionNodeNumber,
53     CalcExpressionNodeLength,
54     CalcExpressionNodeBinaryOperation,
55     CalcExpressionNodeBlendLength,
56 };
57 
58 class PLATFORM_EXPORT CalcExpressionNode {
59     WTF_MAKE_FAST_ALLOCATED;
60 public:
CalcExpressionNode()61     CalcExpressionNode()
62         : m_type(CalcExpressionNodeUndefined)
63     {
64     }
65 
~CalcExpressionNode()66     virtual ~CalcExpressionNode()
67     {
68     }
69 
70     virtual float evaluate(float maxValue) const = 0;
71     virtual bool operator==(const CalcExpressionNode&) const = 0;
72 
type()73     CalcExpressionNodeType type() const { return m_type; }
74 
75 protected:
76     CalcExpressionNodeType m_type;
77 };
78 
79 class PLATFORM_EXPORT CalculationValue : public RefCounted<CalculationValue> {
80 public:
81     static PassRefPtr<CalculationValue> create(PassOwnPtr<CalcExpressionNode> value, ValueRange);
82     float evaluate(float maxValue) const;
83 
84     bool operator==(const CalculationValue& o) const
85     {
86         return *(m_value.get()) == *(o.m_value.get());
87     }
88 
isNonNegative()89     bool isNonNegative() const { return m_isNonNegative; }
expression()90     const CalcExpressionNode* expression() const { return m_value.get(); }
91 
92 private:
CalculationValue(PassOwnPtr<CalcExpressionNode> value,ValueRange range)93     CalculationValue(PassOwnPtr<CalcExpressionNode> value, ValueRange range)
94         : m_value(value)
95         , m_isNonNegative(range == ValueRangeNonNegative)
96     {
97     }
98 
99     OwnPtr<CalcExpressionNode> m_value;
100     bool m_isNonNegative;
101 };
102 
103 class PLATFORM_EXPORT CalcExpressionNumber : public CalcExpressionNode {
104 public:
CalcExpressionNumber(float value)105     explicit CalcExpressionNumber(float value)
106         : m_value(value)
107     {
108         m_type = CalcExpressionNodeNumber;
109     }
110 
111     bool operator==(const CalcExpressionNumber& o) const
112     {
113         return m_value == o.m_value;
114     }
115 
116     virtual bool operator==(const CalcExpressionNode& o) const OVERRIDE
117     {
118         return type() == o.type() && *this == static_cast<const CalcExpressionNumber&>(o);
119     }
120 
evaluate(float)121     virtual float evaluate(float) const OVERRIDE
122     {
123         return m_value;
124     }
125 
value()126     float value() const { return m_value; }
127 
128 private:
129     float m_value;
130 };
131 
toCalcExpressionNumber(const CalcExpressionNode * value)132 inline const CalcExpressionNumber* toCalcExpressionNumber(const CalcExpressionNode* value)
133 {
134     ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeNumber);
135     return static_cast<const CalcExpressionNumber*>(value);
136 }
137 
138 class PLATFORM_EXPORT CalcExpressionLength : public CalcExpressionNode {
139 public:
CalcExpressionLength(Length length)140     explicit CalcExpressionLength(Length length)
141         : m_length(length)
142     {
143         m_type = CalcExpressionNodeLength;
144     }
145 
146     bool operator==(const CalcExpressionLength& o) const
147     {
148         return m_length == o.m_length;
149     }
150 
151     virtual bool operator==(const CalcExpressionNode& o) const OVERRIDE
152     {
153         return type() == o.type() && *this == static_cast<const CalcExpressionLength&>(o);
154     }
155 
evaluate(float maxValue)156     virtual float evaluate(float maxValue) const OVERRIDE
157     {
158         return floatValueForLength(m_length, maxValue);
159     }
160 
length()161     const Length& length() const { return m_length; }
162 
163 private:
164     Length m_length;
165 };
166 
toCalcExpressionLength(const CalcExpressionNode * value)167 inline const CalcExpressionLength* toCalcExpressionLength(const CalcExpressionNode* value)
168 {
169     ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeLength);
170     return static_cast<const CalcExpressionLength*>(value);
171 }
172 
173 class PLATFORM_EXPORT CalcExpressionBinaryOperation : public CalcExpressionNode {
174 public:
CalcExpressionBinaryOperation(PassOwnPtr<CalcExpressionNode> leftSide,PassOwnPtr<CalcExpressionNode> rightSide,CalcOperator op)175     CalcExpressionBinaryOperation(PassOwnPtr<CalcExpressionNode> leftSide, PassOwnPtr<CalcExpressionNode> rightSide, CalcOperator op)
176         : m_leftSide(leftSide)
177         , m_rightSide(rightSide)
178         , m_operator(op)
179     {
180         m_type = CalcExpressionNodeBinaryOperation;
181     }
182 
183     bool operator==(const CalcExpressionBinaryOperation& o) const
184     {
185         return m_operator == o.m_operator && *m_leftSide == *o.m_leftSide && *m_rightSide == *o.m_rightSide;
186     }
187 
188     virtual bool operator==(const CalcExpressionNode& o) const OVERRIDE
189     {
190         return type() == o.type() && *this == static_cast<const CalcExpressionBinaryOperation&>(o);
191     }
192 
193     virtual float evaluate(float) const OVERRIDE;
194 
leftSide()195     const CalcExpressionNode* leftSide() const { return m_leftSide.get(); }
rightSide()196     const CalcExpressionNode* rightSide() const { return m_rightSide.get(); }
getOperator()197     CalcOperator getOperator() const { return m_operator; }
198 
199 private:
200     // Disallow the copy constructor. Resolves Windows link errors.
201     CalcExpressionBinaryOperation(const CalcExpressionBinaryOperation&);
202 
203     OwnPtr<CalcExpressionNode> m_leftSide;
204     OwnPtr<CalcExpressionNode> m_rightSide;
205     CalcOperator m_operator;
206 };
207 
toCalcExpressionBinaryOperation(const CalcExpressionNode * value)208 inline const CalcExpressionBinaryOperation* toCalcExpressionBinaryOperation(const CalcExpressionNode* value)
209 {
210     ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeBinaryOperation);
211     return static_cast<const CalcExpressionBinaryOperation*>(value);
212 }
213 
214 class PLATFORM_EXPORT CalcExpressionBlendLength : public CalcExpressionNode {
215 public:
CalcExpressionBlendLength(Length from,Length to,float progress)216     CalcExpressionBlendLength(Length from, Length to, float progress)
217         : m_from(from)
218         , m_to(to)
219         , m_progress(progress)
220     {
221         m_type = CalcExpressionNodeBlendLength;
222     }
223 
224     bool operator==(const CalcExpressionBlendLength& o) const
225     {
226         return m_progress == o.m_progress && m_from == o.m_from && m_to == o.m_to;
227     }
228 
229     virtual bool operator==(const CalcExpressionNode& o) const OVERRIDE
230     {
231         return type() == o.type() && *this == static_cast<const CalcExpressionBlendLength&>(o);
232     }
233 
evaluate(float maxValue)234     virtual float evaluate(float maxValue) const OVERRIDE
235     {
236         return (1.0f - m_progress) * floatValueForLength(m_from, maxValue) + m_progress * floatValueForLength(m_to, maxValue);
237     }
238 
from()239     const Length& from() const { return m_from; }
to()240     const Length& to() const { return m_to; }
progress()241     float progress() const { return m_progress; }
242 
243 private:
244     Length m_from;
245     Length m_to;
246     float m_progress;
247 };
248 
toCalcExpressionBlendLength(const CalcExpressionNode * value)249 inline const CalcExpressionBlendLength* toCalcExpressionBlendLength(const CalcExpressionNode* value)
250 {
251     ASSERT_WITH_SECURITY_IMPLICATION(!value || value->type() == CalcExpressionNodeBlendLength);
252     return static_cast<const CalcExpressionBlendLength*>(value);
253 }
254 
255 } // namespace WebCore
256 
257 #endif // CalculationValue_h
258