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 "Length.h" 35#include "LengthFunctions.h" 36#include <wtf/OwnPtr.h> 37#include <wtf/PassOwnPtr.h> 38#include <wtf/RefCounted.h> 39#include <wtf/Vector.h> 40 41namespace WebCore { 42 43enum CalcOperator { 44 CalcAdd = '+', 45 CalcSubtract = '-', 46 CalcMultiply = '*', 47 CalcDivide = '/' 48}; 49 50enum CalculationPermittedValueRange { 51 CalculationRangeAll, 52 CalculationRangeNonNegative 53}; 54 55enum CalcExpressionNodeType { 56 CalcExpressionNodeUndefined, 57 CalcExpressionNodeNumber, 58 CalcExpressionNodeLength, 59 CalcExpressionNodeBinaryOperation, 60 CalcExpressionNodeBlendLength, 61}; 62 63class CalcExpressionNode { 64 WTF_MAKE_FAST_ALLOCATED; 65public: 66 CalcExpressionNode() 67 : m_type(CalcExpressionNodeUndefined) 68 { 69 } 70 71 virtual ~CalcExpressionNode() 72 { 73 } 74 75 virtual float evaluate(float maxValue) const = 0; 76 virtual bool operator==(const CalcExpressionNode&) const = 0; 77 78 CalcExpressionNodeType type() const { return m_type; } 79 80protected: 81 CalcExpressionNodeType m_type; 82}; 83 84class CalculationValue : public RefCounted<CalculationValue> { 85public: 86 static PassRefPtr<CalculationValue> create(PassOwnPtr<CalcExpressionNode> value, CalculationPermittedValueRange); 87 float evaluate(float maxValue) const; 88 89 bool operator==(const CalculationValue& o) const 90 { 91 return *(m_value.get()) == *(o.m_value.get()); 92 } 93 94private: 95 CalculationValue(PassOwnPtr<CalcExpressionNode> value, CalculationPermittedValueRange range) 96 : m_value(value) 97 , m_isNonNegative(range == CalculationRangeNonNegative) 98 { 99 } 100 101 OwnPtr<CalcExpressionNode> m_value; 102 bool m_isNonNegative; 103}; 104 105class CalcExpressionNumber : public CalcExpressionNode { 106public: 107 explicit CalcExpressionNumber(float value) 108 : m_value(value) 109 { 110 m_type = CalcExpressionNodeNumber; 111 } 112 113 bool operator==(const CalcExpressionNumber& o) const 114 { 115 return m_value == o.m_value; 116 } 117 118 virtual bool operator==(const CalcExpressionNode& o) const 119 { 120 return type() == o.type() && *this == static_cast<const CalcExpressionNumber&>(o); 121 } 122 123 virtual float evaluate(float) const 124 { 125 return m_value; 126 } 127 128private: 129 float m_value; 130}; 131 132class CalcExpressionLength : public CalcExpressionNode { 133public: 134 explicit CalcExpressionLength(Length length) 135 : m_length(length) 136 { 137 m_type = CalcExpressionNodeLength; 138 } 139 140 bool operator==(const CalcExpressionLength& o) const 141 { 142 return m_length == o.m_length; 143 } 144 145 virtual bool operator==(const CalcExpressionNode& o) const 146 { 147 return type() == o.type() && *this == static_cast<const CalcExpressionLength&>(o); 148 } 149 150 virtual float evaluate(float maxValue) const 151 { 152 return floatValueForLength(m_length, maxValue); 153 } 154 155private: 156 Length m_length; 157}; 158 159class CalcExpressionBinaryOperation : public CalcExpressionNode { 160public: 161 CalcExpressionBinaryOperation(PassOwnPtr<CalcExpressionNode> leftSide, PassOwnPtr<CalcExpressionNode> rightSide, CalcOperator op) 162 : m_leftSide(leftSide) 163 , m_rightSide(rightSide) 164 , m_operator(op) 165 { 166 m_type = CalcExpressionNodeBinaryOperation; 167 } 168 169 bool operator==(const CalcExpressionBinaryOperation& o) const 170 { 171 return m_operator == o.m_operator && *m_leftSide == *o.m_leftSide && *m_rightSide == *o.m_rightSide; 172 } 173 174 virtual bool operator==(const CalcExpressionNode& o) const 175 { 176 return type() == o.type() && *this == static_cast<const CalcExpressionBinaryOperation&>(o); 177 } 178 179 180 virtual float evaluate(float) const; 181 182private: 183 OwnPtr<CalcExpressionNode> m_leftSide; 184 OwnPtr<CalcExpressionNode> m_rightSide; 185 CalcOperator m_operator; 186}; 187 188class CalcExpressionBlendLength : public CalcExpressionNode { 189public: 190 CalcExpressionBlendLength(Length from, Length to, float progress) 191 : m_from(from) 192 , m_to(to) 193 , m_progress(progress) 194 { 195 m_type = CalcExpressionNodeBlendLength; 196 } 197 198 bool operator==(const CalcExpressionBlendLength& o) const 199 { 200 return m_progress == o.m_progress && m_from == o.m_from && m_to == o.m_to; 201 } 202 203 virtual bool operator==(const CalcExpressionNode& o) const 204 { 205 return type() == o.type() && *this == static_cast<const CalcExpressionBlendLength&>(o); 206 } 207 208 virtual float evaluate(float maxValue) const 209 { 210 return (1.0f - m_progress) * floatValueForLength(m_from, maxValue) + m_progress * floatValueForLength(m_to, maxValue); 211 } 212 213private: 214 Length m_from; 215 Length m_to; 216 float m_progress; 217}; 218 219} // namespace WebCore 220 221#endif // CalculationValue_h 222