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