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: 61 CalcExpressionNode() 62 : m_type(CalcExpressionNodeUndefined) 63 { 64 } 65 66 virtual ~CalcExpressionNode() 67 { 68 } 69 70 virtual float evaluate(float maxValue) const = 0; 71 virtual bool operator==(const CalcExpressionNode&) const = 0; 72 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 89 bool isNonNegative() const { return m_isNonNegative; } 90 const CalcExpressionNode* expression() const { return m_value.get(); } 91 92 private: 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: 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 121 virtual float evaluate(float) const OVERRIDE 122 { 123 return m_value; 124 } 125 126 float value() const { return m_value; } 127 128 private: 129 float m_value; 130 }; 131 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: 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 156 virtual float evaluate(float maxValue) const OVERRIDE 157 { 158 return floatValueForLength(m_length, maxValue); 159 } 160 161 const Length& length() const { return m_length; } 162 163 private: 164 Length m_length; 165 }; 166 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: 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 195 const CalcExpressionNode* leftSide() const { return m_leftSide.get(); } 196 const CalcExpressionNode* rightSide() const { return m_rightSide.get(); } 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 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: 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 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 239 const Length& from() const { return m_from; } 240 const Length& to() const { return m_to; } 241 float progress() const { return m_progress; } 242 243 private: 244 Length m_from; 245 Length m_to; 246 float m_progress; 247 }; 248 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