Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / rendering / style / BasicShapes.h
1 /*
2  * Copyright (C) 2012 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 #ifndef BasicShapes_h
31 #define BasicShapes_h
32
33 #include "Length.h"
34 #include "LengthSize.h"
35 #include "RenderStyleConstants.h"
36 #include "WindRule.h"
37 #include <wtf/RefCounted.h>
38 #include <wtf/RefPtr.h>
39 #include <wtf/TypeCasts.h>
40 #include <wtf/Vector.h>
41
42 namespace WebCore {
43
44 class FloatRect;
45 class Path;
46 class RenderBox;
47 class SVGPathByteStream;
48
49 class BasicShape : public RefCounted<BasicShape> {
50 public:
51     virtual ~BasicShape() { }
52
53     enum Type {
54         BasicShapePolygonType,
55         BasicShapePathType,
56         BasicShapeCircleType,
57         BasicShapeEllipseType,
58         BasicShapeInsetType
59     };
60
61     virtual Type type() const = 0;
62
63     virtual void path(Path&, const FloatRect&) = 0;
64     virtual WindRule windRule() const { return RULE_NONZERO; }
65
66     virtual bool canBlend(const BasicShape&) const = 0;
67     virtual Ref<BasicShape> blend(const BasicShape&, double) const = 0;
68
69     virtual bool operator==(const BasicShape&) const = 0;
70 };
71
72 class BasicShapeCenterCoordinate {
73 public:
74     enum Direction {
75         TopLeft,
76         BottomRight
77     };
78
79     BasicShapeCenterCoordinate()
80         : m_direction(TopLeft)
81         , m_length(Undefined)
82     {
83         updateComputedLength();
84     }
85
86     BasicShapeCenterCoordinate(Direction direction, Length length)
87         : m_direction(direction)
88         , m_length(length)
89     {
90         updateComputedLength();
91     }
92
93     BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other)
94         : m_direction(other.direction())
95         , m_length(other.length())
96         , m_computedLength(other.m_computedLength)
97     {
98     }
99
100     Direction direction() const { return m_direction; }
101     const Length& length() const { return m_length; }
102     const Length& computedLength() const { return m_computedLength; }
103
104     BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
105     {
106         return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress));
107     }
108     
109     bool operator==(const BasicShapeCenterCoordinate& other) const
110     {
111         return m_direction == other.m_direction
112             && m_length == other.m_length
113             && m_computedLength == other.m_computedLength;
114     }
115
116 private:
117     void updateComputedLength();
118
119     Direction m_direction;
120     Length m_length;
121     Length m_computedLength;
122 };
123
124 class BasicShapeRadius {
125 public:
126     enum Type {
127         Value,
128         ClosestSide,
129         FarthestSide
130     };
131     BasicShapeRadius()
132         : m_value(Undefined),
133         m_type(ClosestSide)
134     { }
135
136     explicit BasicShapeRadius(Length v)
137         : m_value(v)
138         , m_type(Value)
139     { }
140     explicit BasicShapeRadius(Type t)
141         : m_value(Undefined)
142         , m_type(t)
143     { }
144     BasicShapeRadius(const BasicShapeRadius& other)
145         : m_value(other.value())
146         , m_type(other.type())
147     { }
148
149     const Length& value() const { return m_value; }
150     Type type() const { return m_type; }
151
152     bool canBlend(const BasicShapeRadius& other) const
153     {
154         // FIXME determine how to interpolate between keywords. See bug 125108.
155         return m_type == Value && other.type() == Value;
156     }
157
158     BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const
159     {
160         if (m_type != Value || other.type() != Value)
161             return BasicShapeRadius(other);
162
163         return BasicShapeRadius(m_value.blend(other.value(), progress));
164     }
165     
166     bool operator==(const BasicShapeRadius& other) const
167     {
168         return m_value == other.m_value && m_type == other.m_type;
169     }
170
171 private:
172     Length m_value;
173     Type m_type;
174
175 };
176
177 class BasicShapeCircle final : public BasicShape {
178 public:
179     static Ref<BasicShapeCircle> create() { return adoptRef(*new BasicShapeCircle); }
180
181     const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
182     const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
183     const BasicShapeRadius& radius() const { return m_radius; }
184     float floatValueForRadiusInBox(float boxWidth, float boxHeight) const;
185
186     void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = WTFMove(centerX); }
187     void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = WTFMove(centerY); }
188     void setRadius(BasicShapeRadius radius) { m_radius = WTFMove(radius); }
189
190 private:
191     BasicShapeCircle() = default;
192
193     virtual Type type() const override { return BasicShapeCircleType; }
194
195     virtual void path(Path&, const FloatRect&) override;
196
197     virtual bool canBlend(const BasicShape&) const override;
198     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
199
200     virtual bool operator==(const BasicShape&) const override;
201
202     BasicShapeCenterCoordinate m_centerX;
203     BasicShapeCenterCoordinate m_centerY;
204     BasicShapeRadius m_radius;
205 };
206
207 class BasicShapeEllipse final : public BasicShape {
208 public:
209     static Ref<BasicShapeEllipse> create() { return adoptRef(*new BasicShapeEllipse); }
210
211     const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
212     const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
213     const BasicShapeRadius& radiusX() const { return m_radiusX; }
214     const BasicShapeRadius& radiusY() const { return m_radiusY; }
215     float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const;
216
217     void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = WTFMove(centerX); }
218     void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = WTFMove(centerY); }
219     void setRadiusX(BasicShapeRadius radiusX) { m_radiusX = WTFMove(radiusX); }
220     void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = WTFMove(radiusY); }
221
222 private:
223     BasicShapeEllipse() = default;
224
225     virtual Type type() const override { return BasicShapeEllipseType; }
226
227     virtual void path(Path&, const FloatRect&) override;
228
229     virtual bool canBlend(const BasicShape&) const override;
230     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
231
232     virtual bool operator==(const BasicShape&) const override;
233
234     BasicShapeCenterCoordinate m_centerX;
235     BasicShapeCenterCoordinate m_centerY;
236     BasicShapeRadius m_radiusX;
237     BasicShapeRadius m_radiusY;
238 };
239
240 class BasicShapePolygon final : public BasicShape {
241 public:
242     static Ref<BasicShapePolygon> create() { return adoptRef(*new BasicShapePolygon); }
243
244     const Vector<Length>& values() const { return m_values; }
245     const Length& getXAt(unsigned i) const { return m_values[2 * i]; }
246     const Length& getYAt(unsigned i) const { return m_values[2 * i + 1]; }
247
248     void setWindRule(WindRule windRule) { m_windRule = windRule; }
249     void appendPoint(Length x, Length y) { m_values.append(WTFMove(x)); m_values.append(WTFMove(y)); }
250
251     virtual WindRule windRule() const override { return m_windRule; }
252
253 private:
254     BasicShapePolygon() = default;
255
256     virtual Type type() const override { return BasicShapePolygonType; }
257
258     virtual void path(Path&, const FloatRect&) override;
259
260     virtual bool canBlend(const BasicShape&) const override;
261     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
262
263     virtual bool operator==(const BasicShape&) const override;
264
265     WindRule m_windRule { RULE_NONZERO };
266     Vector<Length> m_values;
267 };
268
269 class BasicShapePath final : public BasicShape {
270 public:
271     static Ref<BasicShapePath> create(std::unique_ptr<SVGPathByteStream>&& byteStream)
272     {
273         return adoptRef(*new BasicShapePath(WTFMove(byteStream)));
274     }
275
276     void setWindRule(WindRule windRule) { m_windRule = windRule; }
277     virtual WindRule windRule() const override { return m_windRule; }
278
279     const SVGPathByteStream* pathData() const { return m_byteStream.get(); }
280
281 private:
282     BasicShapePath(std::unique_ptr<SVGPathByteStream>&&);
283
284     virtual Type type() const override { return BasicShapePathType; }
285
286     virtual void path(Path&, const FloatRect&) override;
287
288     virtual bool canBlend(const BasicShape&) const override;
289     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
290
291     virtual bool operator==(const BasicShape&) const override;
292
293     std::unique_ptr<SVGPathByteStream> m_byteStream;
294     WindRule m_windRule { RULE_NONZERO };
295 };
296
297 class BasicShapeInset final : public BasicShape {
298 public:
299     static Ref<BasicShapeInset> create() { return adoptRef(*new BasicShapeInset); }
300
301     const Length& top() const { return m_top; }
302     const Length& right() const { return m_right; }
303     const Length& bottom() const { return m_bottom; }
304     const Length& left() const { return m_left; }
305
306     const LengthSize& topLeftRadius() const { return m_topLeftRadius; }
307     const LengthSize& topRightRadius() const { return m_topRightRadius; }
308     const LengthSize& bottomRightRadius() const { return m_bottomRightRadius; }
309     const LengthSize& bottomLeftRadius() const { return m_bottomLeftRadius; }
310
311     void setTop(Length top) { m_top = WTFMove(top); }
312     void setRight(Length right) { m_right = WTFMove(right); }
313     void setBottom(Length bottom) { m_bottom = WTFMove(bottom); }
314     void setLeft(Length left) { m_left = WTFMove(left); }
315
316     void setTopLeftRadius(LengthSize radius) { m_topLeftRadius = WTFMove(radius); }
317     void setTopRightRadius(LengthSize radius) { m_topRightRadius = WTFMove(radius); }
318     void setBottomRightRadius(LengthSize radius) { m_bottomRightRadius = WTFMove(radius); }
319     void setBottomLeftRadius(LengthSize radius) { m_bottomLeftRadius = WTFMove(radius); }
320
321 private:
322     BasicShapeInset() = default;
323
324     virtual Type type() const override { return BasicShapeInsetType; }
325
326     virtual void path(Path&, const FloatRect&) override;
327
328     virtual bool canBlend(const BasicShape&) const override;
329     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
330
331     virtual bool operator==(const BasicShape&) const override;
332
333     Length m_right;
334     Length m_top;
335     Length m_bottom;
336     Length m_left;
337
338     LengthSize m_topLeftRadius;
339     LengthSize m_topRightRadius;
340     LengthSize m_bottomRightRadius;
341     LengthSize m_bottomLeftRadius;
342 };
343
344 } // namespace WebCore
345
346 #define SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(ToValueTypeName, predicate) \
347 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
348     static bool isType(const WebCore::BasicShape& basicShape) { return basicShape.type() == WebCore::predicate; } \
349 SPECIALIZE_TYPE_TRAITS_END()
350
351 SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeCircle, BasicShape::BasicShapeCircleType)
352 SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeEllipse, BasicShape::BasicShapeEllipseType)
353 SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePolygon, BasicShape::BasicShapePolygonType)
354 SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePath, BasicShape::BasicShapePathType)
355 SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeInset, BasicShape::BasicShapeInsetType)
356
357 #endif // BasicShapes_h