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