OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above | 8 * 1. Redistributions of source code must retain the above |
9 * copyright notice, this list of conditions and the following | 9 * copyright notice, this list of conditions and the following |
10 * disclaimer. | 10 * disclaimer. |
(...skipping 10 matching lines...) Expand all Loading... | |
21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | 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 | 26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 * SUCH DAMAGE. | 27 * SUCH DAMAGE. |
28 */ | 28 */ |
29 | 29 |
30 #include "config.h" | 30 #include "config.h" |
31 #include "core/rendering/style/BasicShapes.h" | |
31 | 32 |
32 #include "core/rendering/style/BasicShapes.h" | 33 #include "core/css/BasicShapeFunctions.h" |
33 #include "platform/LengthFunctions.h" | 34 #include "platform/LengthFunctions.h" |
34 #include "platform/geometry/FloatRect.h" | 35 #include "platform/geometry/FloatRect.h" |
35 #include "platform/graphics/Path.h" | 36 #include "platform/graphics/Path.h" |
36 | 37 |
37 namespace WebCore { | 38 namespace WebCore { |
38 | 39 |
39 bool BasicShape::canBlend(const BasicShape* other) const | 40 bool BasicShape::canBlend(const BasicShape* other) const |
40 { | 41 { |
41 // FIXME: Support animations between different shapes in the future. | 42 // FIXME: Support animations between different shapes in the future. |
42 if (!other || !isSameType(*other)) | 43 if (!other || !isSameType(*other)) |
43 return false; | 44 return false; |
44 | 45 |
45 // Just polygons with same number of vertices can be animated. | 46 // Just polygons with same number of vertices can be animated. |
46 if (type() == BasicShape::BasicShapePolygonType | 47 if (type() == BasicShape::BasicShapePolygonType |
47 && static_cast<const BasicShapePolygon*>(this)->values().size() != stati c_cast<const BasicShapePolygon*>(other)->values().size()) | 48 && static_cast<const BasicShapePolygon*>(this)->values().size() != stati c_cast<const BasicShapePolygon*>(other)->values().size()) |
48 return false; | 49 return false; |
49 | 50 |
51 // Circles with keywords for radii or center coordinates cannot be animated. | |
52 if (type() == BasicShape::BasicShapeCircleType) { | |
53 const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle* >(this); | |
54 const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle *>(other); | |
eseidel
2014/01/07 19:47:16
How do we know that "other" is OK to static_cast?
| |
55 if (!thisCircle->radius().canBlend(otherCircle->radius()) | |
56 || !thisCircle->centerX().canBlend(otherCircle->centerX()) | |
57 || !thisCircle->centerY().canBlend(otherCircle->centerY())) | |
58 return false; | |
59 } | |
60 | |
50 return true; | 61 return true; |
51 } | 62 } |
52 | 63 |
53 void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox) | 64 void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox) |
54 { | 65 { |
55 ASSERT(path.isEmpty()); | 66 ASSERT(path.isEmpty()); |
56 path.addRoundedRect( | 67 path.addRoundedRect( |
57 FloatRect( | 68 FloatRect( |
58 floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(), | 69 floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(), |
59 floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(), | 70 floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 } | 137 } |
127 | 138 |
128 bool BasicShapeCircle::operator==(const BasicShape& o) const | 139 bool BasicShapeCircle::operator==(const BasicShape& o) const |
129 { | 140 { |
130 if (!isSameType(o)) | 141 if (!isSameType(o)) |
131 return false; | 142 return false; |
132 const BasicShapeCircle& other = toBasicShapeCircle(o); | 143 const BasicShapeCircle& other = toBasicShapeCircle(o); |
133 return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_rad ius == other.m_radius; | 144 return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_rad ius == other.m_radius; |
134 } | 145 } |
135 | 146 |
147 float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight ) const | |
leviw_travelin_and_unemployed
2014/01/07 19:41:34
Why not FloatSize?
| |
148 { | |
149 if (m_radius.type() == BasicShapeRadius::Value) | |
150 return floatValueForLength(m_radius.value(), sqrtf((boxWidth * boxWidth + boxHeight * boxHeight) / 2)); | |
eseidel
2014/01/07 19:47:16
I wonder if we have a hypotenuse() function somewh
leviw_travelin_and_unemployed
2014/01/07 19:51:56
cmath has hypot and hypotf
| |
151 | |
152 float centerX = floatValueForCenterCoordinate(m_centerX, boxWidth); | |
153 float centerY = floatValueForCenterCoordinate(m_centerY, boxHeight); | |
154 | |
155 if (m_radius.type() == BasicShapeRadius::ClosestSide) | |
156 return std::min(std::min(centerX, boxWidth - centerX), std::min(centerY, boxHeight - centerY)); | |
157 | |
158 // If radius.type() == BasicShapeRadius::FarthestSide. | |
159 return std::max(std::max(centerX, boxWidth - centerX), std::max(centerY, box Height - centerY)); | |
160 } | |
161 | |
136 void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) | 162 void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) |
137 { | 163 { |
138 ASSERT(path.isEmpty()); | 164 ASSERT(path.isEmpty()); |
139 // FIXME Complete implementation of path. | 165 float centerX = floatValueForCenterCoordinate(m_centerX, boundingBox.width() ); |
140 // Compute closest-side and farthest-side from boundingBox. | 166 float centerY = floatValueForCenterCoordinate(m_centerY, boundingBox.height( )); |
141 // Compute top, left, bottom, right from boundingBox. | 167 float radius = floatValueForRadiusInBox(boundingBox.width(), boundingBox.hei ght()); |
142 if (m_radius.type() != BasicShapeRadius::Value) | |
143 return; | |
144 if (m_centerX.keyword() != BasicShapeCenterCoordinate::None || m_centerY.key word() != BasicShapeCenterCoordinate::None) | |
145 return; | |
146 | |
147 float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + bounding Box.height() * boundingBox.height()) / 2); | |
148 float centerX = floatValueForLength(m_centerX.length(), boundingBox.width()) ; | |
149 float centerY = floatValueForLength(m_centerY.length(), boundingBox.height() ); | |
150 float radius = floatValueForLength(m_radius.value(), diagonal); | |
151 path.addEllipse(FloatRect( | 168 path.addEllipse(FloatRect( |
152 centerX - radius + boundingBox.x(), | 169 centerX - radius + boundingBox.x(), |
153 centerY - radius + boundingBox.y(), | 170 centerY - radius + boundingBox.y(), |
154 radius * 2, | 171 radius * 2, |
155 radius * 2 | 172 radius * 2 |
156 )); | 173 )); |
157 } | 174 } |
158 | 175 |
159 PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double p rogress) const | 176 PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double p rogress) const |
160 { | 177 { |
161 ASSERT(type() == other->type()); | 178 ASSERT(type() == other->type()); |
162 const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other); | 179 const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other); |
163 RefPtr<BasicShapeCircle> result = BasicShapeCircle::create(); | 180 RefPtr<BasicShapeCircle> result = BasicShapeCircle::create(); |
164 | 181 |
165 if (m_radius.type() != BasicShapeRadius::Value || o->radius().type() != Basi cShapeRadius::Value) { | |
166 result->setCenterX(o->centerX()); | |
167 result->setCenterY(o->centerY()); | |
168 result->setRadius(o->radius()); | |
169 return result; | |
170 } | |
171 | |
172 result->setCenterX(m_centerX.blend(o->centerX(), progress)); | 182 result->setCenterX(m_centerX.blend(o->centerX(), progress)); |
173 result->setCenterY(m_centerY.blend(o->centerY(), progress)); | 183 result->setCenterY(m_centerY.blend(o->centerY(), progress)); |
174 result->setRadius(m_radius.blend(o->radius(), progress)); | 184 result->setRadius(m_radius.blend(o->radius(), progress)); |
175 return result.release(); | 185 return result.release(); |
176 } | 186 } |
177 | 187 |
178 void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) | 188 void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) |
179 { | 189 { |
180 ASSERT(path.isEmpty()); | 190 ASSERT(path.isEmpty()); |
181 float centerX = floatValueForLength(m_centerX, boundingBox.width()); | 191 float centerX = floatValueForLength(m_centerX, boundingBox.width()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 } | 305 } |
296 | 306 |
297 bool BasicShapeInsetRectangle::operator==(const BasicShape& o) const | 307 bool BasicShapeInsetRectangle::operator==(const BasicShape& o) const |
298 { | 308 { |
299 if (!isSameType(o)) | 309 if (!isSameType(o)) |
300 return false; | 310 return false; |
301 const BasicShapeInsetRectangle& other = toBasicShapeInsetRectangle(o); | 311 const BasicShapeInsetRectangle& other = toBasicShapeInsetRectangle(o); |
302 return m_right == other.m_right && m_top == other.m_top && m_bottom == other .m_bottom && m_left == other.m_left && m_cornerRadiusX == other.m_cornerRadiusX && m_cornerRadiusY == other.m_cornerRadiusY; | 312 return m_right == other.m_right && m_top == other.m_top && m_bottom == other .m_bottom && m_left == other.m_left && m_cornerRadiusX == other.m_cornerRadiusX && m_cornerRadiusY == other.m_cornerRadiusY; |
303 } | 313 } |
304 } | 314 } |
OLD | NEW |