Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/rendering/style/RenderStyleConstants.h"
34 #include "platform/Length.h"
35 #include "platform/LengthSize.h"
36 #include "platform/graphics/GraphicsTypes.h"
37 #include "wtf/RefCounted.h"
38 #include "wtf/RefPtr.h"
39 #include "wtf/Vector.h"
40
41 namespace blink {
42
43 class FloatRect;
44 class FloatSize;
45 class Path;
46
47 class BasicShape : public RefCounted<BasicShape> {
48 public:
49     virtual ~BasicShape() { }
50
51     enum Type {
52         BasicShapeEllipseType,
53         BasicShapePolygonType,
54         BasicShapeCircleType,
55         BasicShapeInsetType
56     };
57
58     bool canBlend(const BasicShape*) const;
59     bool isSameType(const BasicShape& other) const { return type() == other.type(); }
60
61     virtual void path(Path&, const FloatRect&) = 0;
62     virtual WindRule windRule() const { return RULE_NONZERO; }
63     virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const = 0;
64     virtual bool operator==(const BasicShape&) const = 0;
65
66     virtual Type type() const = 0;
67
68 protected:
69     BasicShape()
70     {
71     }
72
73 };
74
75 #define DEFINE_BASICSHAPE_TYPE_CASTS(thisType) \
76     DEFINE_TYPE_CASTS(thisType, BasicShape, value, value->type() == BasicShape::thisType##Type, value.type() == BasicShape::thisType##Type)
77
78 class BasicShapeCenterCoordinate {
79 public:
80     enum Direction {
81         TopLeft,
82         BottomRight
83     };
84
85     BasicShapeCenterCoordinate(Direction direction = TopLeft, const Length& length = Length(0, Fixed))
86         : m_direction(direction)
87         , m_length(length)
88         , m_computedLength(direction == TopLeft ? length : length.subtractFromOneHundredPercent())
89     {
90     }
91
92     BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other)
93         : m_direction(other.direction())
94         , m_length(other.length())
95         , m_computedLength(other.m_computedLength)
96     {
97     }
98
99     bool operator==(const BasicShapeCenterCoordinate& other) const { return m_direction == other.m_direction && m_length == other.m_length && m_computedLength == other.m_computedLength; }
100
101     Direction direction() const { return m_direction; }
102     const Length& length() const { return m_length; }
103     const Length& computedLength() const { return m_computedLength; }
104
105     BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
106     {
107         return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress, ValueRangeAll));
108     }
109
110 private:
111     Direction m_direction;
112     Length m_length;
113     Length m_computedLength;
114 };
115
116 class BasicShapeRadius {
117 public:
118     enum Type {
119         Value,
120         ClosestSide,
121         FarthestSide
122     };
123     BasicShapeRadius() : m_value(Undefined), m_type(ClosestSide) { }
124     explicit BasicShapeRadius(const Length& v) : m_value(v), m_type(Value) { }
125     explicit BasicShapeRadius(Type t) : m_value(Undefined), m_type(t) { }
126     BasicShapeRadius(const BasicShapeRadius& other) : m_value(other.value()), m_type(other.type()) { }
127     bool operator==(const BasicShapeRadius& other) const { return m_type == other.m_type && m_value == other.m_value; }
128
129     const Length& value() const { return m_value; }
130     Type type() const { return m_type; }
131
132     bool canBlend(const BasicShapeRadius& other) const
133     {
134         // FIXME determine how to interpolate between keywords. See issue 330248.
135         return m_type == Value && other.type() == Value;
136     }
137
138     BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const
139     {
140         if (m_type != Value || other.type() != Value)
141             return BasicShapeRadius(other);
142
143         return BasicShapeRadius(m_value.blend(other.value(), progress, ValueRangeNonNegative));
144     }
145
146 private:
147     Length m_value;
148     Type m_type;
149
150 };
151
152 class BasicShapeCircle FINAL : public BasicShape {
153 public:
154     static PassRefPtr<BasicShapeCircle> create() { return adoptRef(new BasicShapeCircle); }
155
156     const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
157     const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
158     const BasicShapeRadius& radius() const { return m_radius; }
159
160     float floatValueForRadiusInBox(FloatSize) const;
161     void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = centerX; }
162     void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = centerY; }
163     void setRadius(BasicShapeRadius radius) { m_radius = radius; }
164
165     virtual void path(Path&, const FloatRect&) OVERRIDE;
166     virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
167     virtual bool operator==(const BasicShape&) const OVERRIDE;
168
169     virtual Type type() const OVERRIDE { return BasicShapeCircleType; }
170 private:
171     BasicShapeCircle() { }
172
173     BasicShapeCenterCoordinate m_centerX;
174     BasicShapeCenterCoordinate m_centerY;
175     BasicShapeRadius m_radius;
176 };
177
178 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeCircle);
179
180 class BasicShapeEllipse FINAL : public BasicShape {
181 public:
182     static PassRefPtr<BasicShapeEllipse> create() { return adoptRef(new BasicShapeEllipse); }
183
184     const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
185     const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
186     const BasicShapeRadius& radiusX() const { return m_radiusX; }
187     const BasicShapeRadius& radiusY() const { return m_radiusY; }
188     float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const;
189
190     void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = centerX; }
191     void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = centerY; }
192     void setRadiusX(BasicShapeRadius radiusX) { m_radiusX = radiusX; }
193     void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = radiusY; }
194
195     virtual void path(Path&, const FloatRect&) OVERRIDE;
196     virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
197     virtual bool operator==(const BasicShape&) const OVERRIDE;
198
199     virtual Type type() const OVERRIDE { return BasicShapeEllipseType; }
200 private:
201     BasicShapeEllipse() { }
202
203     BasicShapeCenterCoordinate m_centerX;
204     BasicShapeCenterCoordinate m_centerY;
205     BasicShapeRadius m_radiusX;
206     BasicShapeRadius m_radiusY;
207 };
208
209 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeEllipse);
210
211 class BasicShapePolygon FINAL : public BasicShape {
212 public:
213     static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); }
214
215     const Vector<Length>& values() const { return m_values; }
216     Length getXAt(unsigned i) const { return m_values.at(2 * i); }
217     Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); }
218
219     void setWindRule(WindRule windRule) { m_windRule = windRule; }
220     void appendPoint(const Length& x, const Length& y) { m_values.append(x); m_values.append(y); }
221
222     virtual void path(Path&, const FloatRect&) OVERRIDE;
223     virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
224     virtual bool operator==(const BasicShape&) const OVERRIDE;
225
226     virtual WindRule windRule() const OVERRIDE { return m_windRule; }
227
228     virtual Type type() const OVERRIDE { return BasicShapePolygonType; }
229 private:
230     BasicShapePolygon()
231         : m_windRule(RULE_NONZERO)
232     { }
233
234     WindRule m_windRule;
235     Vector<Length> m_values;
236 };
237
238 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapePolygon);
239
240 class BasicShapeInset : public BasicShape {
241 public:
242     static PassRefPtr<BasicShapeInset> create() { return adoptRef(new BasicShapeInset); }
243
244     const Length& top() const { return m_top; }
245     const Length& right() const { return m_right; }
246     const Length& bottom() const { return m_bottom; }
247     const Length& left() const { return m_left; }
248
249     const LengthSize& topLeftRadius() const { return m_topLeftRadius; }
250     const LengthSize& topRightRadius() const { return m_topRightRadius; }
251     const LengthSize& bottomRightRadius() const { return m_bottomRightRadius; }
252     const LengthSize& bottomLeftRadius() const { return m_bottomLeftRadius; }
253
254     void setTop(const Length& top) { m_top = top; }
255     void setRight(const Length& right) { m_right = right; }
256     void setBottom(const Length& bottom) { m_bottom = bottom; }
257     void setLeft(const Length& left) { m_left = left; }
258
259     void setTopLeftRadius(const LengthSize& radius) { m_topLeftRadius = radius; }
260     void setTopRightRadius(const LengthSize& radius) { m_topRightRadius = radius; }
261     void setBottomRightRadius(const LengthSize& radius) { m_bottomRightRadius = radius; }
262     void setBottomLeftRadius(const LengthSize& radius) { m_bottomLeftRadius = radius; }
263
264     virtual void path(Path&, const FloatRect&) OVERRIDE;
265     virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
266     virtual bool operator==(const BasicShape&) const OVERRIDE;
267
268     virtual Type type() const OVERRIDE { return BasicShapeInsetType; }
269 private:
270     BasicShapeInset() { }
271
272     Length m_right;
273     Length m_top;
274     Length m_bottom;
275     Length m_left;
276
277     LengthSize m_topLeftRadius;
278     LengthSize m_topRightRadius;
279     LengthSize m_bottomRightRadius;
280     LengthSize m_bottomLeftRadius;
281 };
282
283 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeInset);
284
285 }
286 #endif