2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
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.
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
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"
47 class BasicShape : public RefCounted<BasicShape> {
49 virtual ~BasicShape() { }
52 BasicShapeEllipseType,
53 BasicShapePolygonType,
58 bool canBlend(const BasicShape*) const;
59 bool isSameType(const BasicShape& other) const { return type() == other.type(); }
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;
66 virtual Type type() const = 0;
75 #define DEFINE_BASICSHAPE_TYPE_CASTS(thisType) \
76 DEFINE_TYPE_CASTS(thisType, BasicShape, value, value->type() == BasicShape::thisType##Type, value.type() == BasicShape::thisType##Type)
78 class BasicShapeCenterCoordinate {
85 BasicShapeCenterCoordinate(Direction direction = TopLeft, const Length& length = Length(0, Fixed))
86 : m_direction(direction)
88 , m_computedLength(direction == TopLeft ? length : length.subtractFromOneHundredPercent())
92 BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other)
93 : m_direction(other.direction())
94 , m_length(other.length())
95 , m_computedLength(other.m_computedLength)
99 bool operator==(const BasicShapeCenterCoordinate& other) const { return m_direction == other.m_direction && m_length == other.m_length && m_computedLength == other.m_computedLength; }
101 Direction direction() const { return m_direction; }
102 const Length& length() const { return m_length; }
103 const Length& computedLength() const { return m_computedLength; }
105 BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
107 return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress, ValueRangeAll));
111 Direction m_direction;
113 Length m_computedLength;
116 class BasicShapeRadius {
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; }
129 const Length& value() const { return m_value; }
130 Type type() const { return m_type; }
132 bool canBlend(const BasicShapeRadius& other) const
134 // FIXME determine how to interpolate between keywords. See issue 330248.
135 return m_type == Value && other.type() == Value;
138 BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const
140 if (m_type != Value || other.type() != Value)
141 return BasicShapeRadius(other);
143 return BasicShapeRadius(m_value.blend(other.value(), progress, ValueRangeNonNegative));
152 class BasicShapeCircle FINAL : public BasicShape {
154 static PassRefPtr<BasicShapeCircle> create() { return adoptRef(new BasicShapeCircle); }
156 const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
157 const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
158 const BasicShapeRadius& radius() const { return m_radius; }
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; }
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;
169 virtual Type type() const OVERRIDE { return BasicShapeCircleType; }
171 BasicShapeCircle() { }
173 BasicShapeCenterCoordinate m_centerX;
174 BasicShapeCenterCoordinate m_centerY;
175 BasicShapeRadius m_radius;
178 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeCircle);
180 class BasicShapeEllipse FINAL : public BasicShape {
182 static PassRefPtr<BasicShapeEllipse> create() { return adoptRef(new BasicShapeEllipse); }
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;
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; }
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;
199 virtual Type type() const OVERRIDE { return BasicShapeEllipseType; }
201 BasicShapeEllipse() { }
203 BasicShapeCenterCoordinate m_centerX;
204 BasicShapeCenterCoordinate m_centerY;
205 BasicShapeRadius m_radiusX;
206 BasicShapeRadius m_radiusY;
209 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeEllipse);
211 class BasicShapePolygon FINAL : public BasicShape {
213 static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); }
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); }
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); }
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;
226 virtual WindRule windRule() const OVERRIDE { return m_windRule; }
228 virtual Type type() const OVERRIDE { return BasicShapePolygonType; }
231 : m_windRule(RULE_NONZERO)
235 Vector<Length> m_values;
238 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapePolygon);
240 class BasicShapeInset : public BasicShape {
242 static PassRefPtr<BasicShapeInset> create() { return adoptRef(new BasicShapeInset); }
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; }
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; }
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; }
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; }
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;
268 virtual Type type() const OVERRIDE { return BasicShapeInsetType; }
270 BasicShapeInset() { }
277 LengthSize m_topLeftRadius;
278 LengthSize m_topRightRadius;
279 LengthSize m_bottomRightRadius;
280 LengthSize m_bottomLeftRadius;
283 DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeInset);