1/*
2 * Copyright (C) 2011, 2012 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#pragma once
32
33#include "CSSPrimitiveValue.h"
34#include "CSSPropertyNames.h"
35#include "CalculationValue.h"
36
37namespace WebCore {
38
39class CSSParserTokenRange;
40class CSSToLengthConversionData;
41class RenderStyle;
42
43enum class CalculationCategory : uint8_t {
44 Number = 0,
45 Length,
46 Percent,
47 PercentNumber,
48 PercentLength,
49 Angle,
50 Time,
51 Frequency,
52 Other
53};
54
55class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> {
56public:
57 enum Type {
58 CssCalcPrimitiveValue = 1,
59 CssCalcOperation
60 };
61
62 virtual ~CSSCalcExpressionNode() = default;
63 virtual bool isZero() const = 0;
64 virtual std::unique_ptr<CalcExpressionNode> createCalcExpression(const CSSToLengthConversionData&) const = 0;
65 virtual double doubleValue() const = 0;
66 virtual double computeLengthPx(const CSSToLengthConversionData&) const = 0;
67 virtual String customCSSText() const = 0;
68 virtual bool equals(const CSSCalcExpressionNode& other) const { return m_category == other.m_category && m_isInteger == other.m_isInteger; }
69 virtual Type type() const = 0;
70 virtual CSSPrimitiveValue::UnitType primitiveType() const = 0;
71
72 virtual void collectDirectComputationalDependencies(HashSet<CSSPropertyID>&) const = 0;
73 virtual void collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>&) const = 0;
74
75 CalculationCategory category() const { return m_category; }
76 bool isInteger() const { return m_isInteger; }
77
78protected:
79 CSSCalcExpressionNode(CalculationCategory category, bool isInteger)
80 : m_category(category)
81 , m_isInteger(isInteger)
82 {
83 }
84
85private:
86 CalculationCategory m_category;
87 bool m_isInteger;
88};
89
90class CSSCalcValue final : public CSSValue {
91public:
92 static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange);
93
94 static RefPtr<CSSCalcValue> create(const CalculationValue&, const RenderStyle&);
95
96 CalculationCategory category() const { return m_expression->category(); }
97 bool isInt() const { return m_expression->isInteger(); }
98 double doubleValue() const;
99 bool isPositive() const { return m_expression->doubleValue() > 0; }
100 bool isNegative() const { return m_expression->doubleValue() < 0; }
101 double computeLengthPx(const CSSToLengthConversionData&) const;
102 unsigned short primitiveType() const { return m_expression->primitiveType(); }
103
104 Ref<CalculationValue> createCalculationValue(const CSSToLengthConversionData&) const;
105 void setPermittedValueRange(ValueRange);
106
107 void collectDirectComputationalDependencies(HashSet<CSSPropertyID>&) const;
108 void collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>&) const;
109
110 String customCSSText() const;
111 bool equals(const CSSCalcValue&) const;
112
113private:
114 CSSCalcValue(Ref<CSSCalcExpressionNode>&&, bool shouldClampToNonNegative);
115
116 double clampToPermittedRange(double) const;
117
118 const Ref<CSSCalcExpressionNode> m_expression;
119 bool m_shouldClampToNonNegative;
120};
121
122inline CSSCalcValue::CSSCalcValue(Ref<CSSCalcExpressionNode>&& expression, bool shouldClampToNonNegative)
123 : CSSValue(CalculationClass)
124 , m_expression(WTFMove(expression))
125 , m_shouldClampToNonNegative(shouldClampToNonNegative)
126{
127}
128
129inline Ref<CalculationValue> CSSCalcValue::createCalculationValue(const CSSToLengthConversionData& conversionData) const
130{
131 return CalculationValue::create(m_expression->createCalcExpression(conversionData),
132 m_shouldClampToNonNegative ? ValueRangeNonNegative : ValueRangeAll);
133}
134
135inline void CSSCalcValue::setPermittedValueRange(ValueRange range)
136{
137 m_shouldClampToNonNegative = range != ValueRangeAll;
138}
139
140inline void CSSCalcValue::collectDirectComputationalDependencies(HashSet<CSSPropertyID>& values) const
141{
142 m_expression->collectDirectComputationalDependencies(values);
143}
144
145inline void CSSCalcValue::collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>& values) const
146{
147 m_expression->collectDirectRootComputationalDependencies(values);
148}
149
150} // namespace WebCore
151
152SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSCalcValue, isCalcValue())
153