1/*
2 * Copyright (C) 2011 Adobe Systems Incorporated. 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
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#pragma once
31
32#include "WindRule.h"
33#include <wtf/RefPtr.h>
34#include <wtf/TypeCasts.h>
35#include <wtf/Vector.h>
36#include <wtf/text/WTFString.h>
37
38namespace WebCore {
39
40class CSSPrimitiveValue;
41class SVGPathByteStream;
42
43class CSSBasicShape : public RefCounted<CSSBasicShape> {
44public:
45 enum Type {
46 CSSBasicShapePolygonType,
47 CSSBasicShapeCircleType,
48 CSSBasicShapeEllipseType,
49 CSSBasicShapeInsetType,
50 CSSBasicShapePathType
51 };
52
53 virtual Type type() const = 0;
54 virtual String cssText() const = 0;
55 virtual bool equals(const CSSBasicShape&) const = 0;
56
57public:
58 virtual ~CSSBasicShape() = default;
59
60protected:
61 CSSBasicShape() = default;
62 RefPtr<CSSPrimitiveValue> m_referenceBox;
63};
64
65class CSSBasicShapeInset final : public CSSBasicShape {
66public:
67 static Ref<CSSBasicShapeInset> create() { return adoptRef(*new CSSBasicShapeInset); }
68
69 CSSPrimitiveValue* top() const { return m_top.get(); }
70 CSSPrimitiveValue* right() const { return m_right.get(); }
71 CSSPrimitiveValue* bottom() const { return m_bottom.get(); }
72 CSSPrimitiveValue* left() const { return m_left.get(); }
73
74 CSSPrimitiveValue* topLeftRadius() const { return m_topLeftRadius.get(); }
75 CSSPrimitiveValue* topRightRadius() const { return m_topRightRadius.get(); }
76 CSSPrimitiveValue* bottomRightRadius() const { return m_bottomRightRadius.get(); }
77 CSSPrimitiveValue* bottomLeftRadius() const { return m_bottomLeftRadius.get(); }
78
79 void setTop(Ref<CSSPrimitiveValue>&& top) { m_top = WTFMove(top); }
80 void setRight(Ref<CSSPrimitiveValue>&& right) { m_right = WTFMove(right); }
81 void setBottom(Ref<CSSPrimitiveValue>&& bottom) { m_bottom = WTFMove(bottom); }
82 void setLeft(Ref<CSSPrimitiveValue>&& left) { m_left = WTFMove(left); }
83
84 void updateShapeSize4Values(Ref<CSSPrimitiveValue>&& top, Ref<CSSPrimitiveValue>&& right, Ref<CSSPrimitiveValue>&& bottom, Ref<CSSPrimitiveValue>&& left)
85 {
86 setTop(WTFMove(top));
87 setRight(WTFMove(right));
88 setBottom(WTFMove(bottom));
89 setLeft(WTFMove(left));
90 }
91
92 void updateShapeSize1Value(Ref<CSSPrimitiveValue>&& value1)
93 {
94 updateShapeSize4Values(value1.copyRef(), value1.copyRef(), value1.copyRef(), value1.copyRef());
95 }
96
97 void updateShapeSize2Values(Ref<CSSPrimitiveValue>&& value1, Ref<CSSPrimitiveValue>&& value2)
98 {
99 updateShapeSize4Values(value1.copyRef(), value2.copyRef(), value1.copyRef(), value2.copyRef());
100 }
101
102 void updateShapeSize3Values(Ref<CSSPrimitiveValue>&& value1, Ref<CSSPrimitiveValue>&& value2, Ref<CSSPrimitiveValue>&& value3)
103 {
104 updateShapeSize4Values(WTFMove(value1), value2.copyRef(), WTFMove(value3), value2.copyRef());
105 }
106
107 void setTopLeftRadius(RefPtr<CSSPrimitiveValue>&& radius) { m_topLeftRadius = WTFMove(radius); }
108 void setTopRightRadius(RefPtr<CSSPrimitiveValue>&& radius) { m_topRightRadius = WTFMove(radius); }
109 void setBottomRightRadius(RefPtr<CSSPrimitiveValue>&& radius) { m_bottomRightRadius = WTFMove(radius); }
110 void setBottomLeftRadius(RefPtr<CSSPrimitiveValue>&& radius) { m_bottomLeftRadius = WTFMove(radius); }
111
112private:
113 CSSBasicShapeInset() = default;
114
115 Type type() const final { return CSSBasicShapeInsetType; }
116 String cssText() const final;
117 bool equals(const CSSBasicShape&) const final;
118
119 RefPtr<CSSPrimitiveValue> m_top;
120 RefPtr<CSSPrimitiveValue> m_right;
121 RefPtr<CSSPrimitiveValue> m_bottom;
122 RefPtr<CSSPrimitiveValue> m_left;
123
124 RefPtr<CSSPrimitiveValue> m_topLeftRadius;
125 RefPtr<CSSPrimitiveValue> m_topRightRadius;
126 RefPtr<CSSPrimitiveValue> m_bottomRightRadius;
127 RefPtr<CSSPrimitiveValue> m_bottomLeftRadius;
128};
129
130class CSSBasicShapeCircle final : public CSSBasicShape {
131public:
132 static Ref<CSSBasicShapeCircle> create() { return adoptRef(*new CSSBasicShapeCircle); }
133
134 CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
135 CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
136 CSSPrimitiveValue* radius() const { return m_radius.get(); }
137
138 void setCenterX(Ref<CSSPrimitiveValue>&& centerX) { m_centerX = WTFMove(centerX); }
139 void setCenterY(Ref<CSSPrimitiveValue>&& centerY) { m_centerY = WTFMove(centerY); }
140 void setRadius(Ref<CSSPrimitiveValue>&& radius) { m_radius = WTFMove(radius); }
141
142private:
143 CSSBasicShapeCircle() = default;
144
145 Type type() const final { return CSSBasicShapeCircleType; }
146 String cssText() const final;
147 bool equals(const CSSBasicShape&) const final;
148
149 RefPtr<CSSPrimitiveValue> m_centerX;
150 RefPtr<CSSPrimitiveValue> m_centerY;
151 RefPtr<CSSPrimitiveValue> m_radius;
152};
153
154class CSSBasicShapeEllipse final : public CSSBasicShape {
155public:
156 static Ref<CSSBasicShapeEllipse> create() { return adoptRef(*new CSSBasicShapeEllipse); }
157
158 CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
159 CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
160 CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
161 CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
162
163 void setCenterX(Ref<CSSPrimitiveValue>&& centerX) { m_centerX = WTFMove(centerX); }
164 void setCenterY(Ref<CSSPrimitiveValue>&& centerY) { m_centerY = WTFMove(centerY); }
165 void setRadiusX(Ref<CSSPrimitiveValue>&& radiusX) { m_radiusX = WTFMove(radiusX); }
166 void setRadiusY(Ref<CSSPrimitiveValue>&& radiusY) { m_radiusY = WTFMove(radiusY); }
167
168private:
169 CSSBasicShapeEllipse() = default;
170
171 Type type() const final { return CSSBasicShapeEllipseType; }
172 String cssText() const final;
173 bool equals(const CSSBasicShape&) const final;
174
175 RefPtr<CSSPrimitiveValue> m_centerX;
176 RefPtr<CSSPrimitiveValue> m_centerY;
177 RefPtr<CSSPrimitiveValue> m_radiusX;
178 RefPtr<CSSPrimitiveValue> m_radiusY;
179};
180
181class CSSBasicShapePolygon final : public CSSBasicShape {
182public:
183 static Ref<CSSBasicShapePolygon> create() { return adoptRef(*new CSSBasicShapePolygon); }
184
185 void appendPoint(Ref<CSSPrimitiveValue>&& x, Ref<CSSPrimitiveValue>&& y)
186 {
187 m_values.append(WTFMove(x));
188 m_values.append(WTFMove(y));
189 }
190
191 const Vector<Ref<CSSPrimitiveValue>>& values() const { return m_values; }
192
193 void setWindRule(WindRule rule) { m_windRule = rule; }
194 WindRule windRule() const { return m_windRule; }
195
196private:
197 CSSBasicShapePolygon()
198 : m_windRule(WindRule::NonZero)
199 {
200 }
201
202 Type type() const final { return CSSBasicShapePolygonType; }
203 String cssText() const final;
204 bool equals(const CSSBasicShape&) const final;
205
206 Vector<Ref<CSSPrimitiveValue>> m_values;
207 WindRule m_windRule;
208};
209
210class CSSBasicShapePath final : public CSSBasicShape {
211public:
212 static Ref<CSSBasicShapePath> create(std::unique_ptr<SVGPathByteStream>&& pathData)
213 {
214 return adoptRef(*new CSSBasicShapePath(WTFMove(pathData)));
215 }
216
217 const SVGPathByteStream& pathData() const
218 {
219 return *m_byteStream;
220 }
221
222 void setWindRule(WindRule rule) { m_windRule = rule; }
223 WindRule windRule() const { return m_windRule; }
224
225private:
226 CSSBasicShapePath(std::unique_ptr<SVGPathByteStream>&&);
227
228 Type type() const final { return CSSBasicShapePathType; }
229 String cssText() const final;
230 bool equals(const CSSBasicShape&) const final;
231
232 std::unique_ptr<SVGPathByteStream> m_byteStream;
233 WindRule m_windRule { WindRule::NonZero };
234};
235
236} // namespace WebCore
237
238#define SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(ToValueTypeName) \
239SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
240 static bool isType(const WebCore::CSSBasicShape& basicShape) { return basicShape.type() == WebCore::CSSBasicShape::ToValueTypeName##Type; } \
241SPECIALIZE_TYPE_TRAITS_END()
242
243SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeInset)
244SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeCircle)
245SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeEllipse)
246SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapePolygon)
247SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapePath)
248