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 | |
38 | namespace WebCore { |
39 | |
40 | class CSSPrimitiveValue; |
41 | class SVGPathByteStream; |
42 | |
43 | class CSSBasicShape : public RefCounted<CSSBasicShape> { |
44 | public: |
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 | |
57 | public: |
58 | virtual ~CSSBasicShape() = default; |
59 | |
60 | protected: |
61 | CSSBasicShape() = default; |
62 | RefPtr<CSSPrimitiveValue> m_referenceBox; |
63 | }; |
64 | |
65 | class CSSBasicShapeInset final : public CSSBasicShape { |
66 | public: |
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 | |
112 | private: |
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 | |
130 | class CSSBasicShapeCircle final : public CSSBasicShape { |
131 | public: |
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 | |
142 | private: |
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 | |
154 | class CSSBasicShapeEllipse final : public CSSBasicShape { |
155 | public: |
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 | |
168 | private: |
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 | |
181 | class CSSBasicShapePolygon final : public CSSBasicShape { |
182 | public: |
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 | |
196 | private: |
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 | |
210 | class CSSBasicShapePath final : public CSSBasicShape { |
211 | public: |
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 | |
225 | private: |
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) \ |
239 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ |
240 | static bool isType(const WebCore::CSSBasicShape& basicShape) { return basicShape.type() == WebCore::CSSBasicShape::ToValueTypeName##Type; } \ |
241 | SPECIALIZE_TYPE_TRAITS_END() |
242 | |
243 | SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeInset) |
244 | SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeCircle) |
245 | SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapeEllipse) |
246 | SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapePolygon) |
247 | SPECIALIZE_TYPE_TRAITS_CSS_BASIC_SHAPES(CSSBasicShapePath) |
248 | |