| 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); |
| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 { | 105 { |
| 95 if (!isSameType(o)) | 106 if (!isSameType(o)) |
| 96 return false; | 107 return false; |
| 97 const DeprecatedBasicShapeCircle& other = toDeprecatedBasicShapeCircle(o); | 108 const DeprecatedBasicShapeCircle& other = toDeprecatedBasicShapeCircle(o); |
| 98 return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_rad
ius == other.m_radius; | 109 return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_rad
ius == other.m_radius; |
| 99 } | 110 } |
| 100 | 111 |
| 101 void DeprecatedBasicShapeCircle::path(Path& path, const FloatRect& boundingBox) | 112 void DeprecatedBasicShapeCircle::path(Path& path, const FloatRect& boundingBox) |
| 102 { | 113 { |
| 103 ASSERT(path.isEmpty()); | 114 ASSERT(path.isEmpty()); |
| 104 float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + bounding
Box.height() * boundingBox.height()) / 2); | 115 float diagonal = hypotf(boundingBox.width(), boundingBox.height()) / sqrtf(2
); |
| 105 float centerX = floatValueForLength(m_centerX, boundingBox.width()); | 116 float centerX = floatValueForLength(m_centerX, boundingBox.width()); |
| 106 float centerY = floatValueForLength(m_centerY, boundingBox.height()); | 117 float centerY = floatValueForLength(m_centerY, boundingBox.height()); |
| 107 float radius = floatValueForLength(m_radius, diagonal); | 118 float radius = floatValueForLength(m_radius, diagonal); |
| 108 path.addEllipse(FloatRect( | 119 path.addEllipse(FloatRect( |
| 109 centerX - radius + boundingBox.x(), | 120 centerX - radius + boundingBox.x(), |
| 110 centerY - radius + boundingBox.y(), | 121 centerY - radius + boundingBox.y(), |
| 111 radius * 2, | 122 radius * 2, |
| 112 radius * 2 | 123 radius * 2 |
| 113 )); | 124 )); |
| 114 } | 125 } |
| (...skipping 11 matching lines...) Expand all 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(FloatSize boxSize) const |
| 148 { |
| 149 if (m_radius.type() == BasicShapeRadius::Value) |
| 150 return floatValueForLength(m_radius.value(), hypotf(boxSize.width(), box
Size.height()) / sqrtf(2)); |
| 151 |
| 152 FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boxS
ize); |
| 153 |
| 154 if (m_radius.type() == BasicShapeRadius::ClosestSide) |
| 155 return std::min(std::min(center.x(), boxSize.width() - center.x()), std:
:min(center.y(), boxSize.height() - center.y())); |
| 156 |
| 157 // If radius.type() == BasicShapeRadius::FarthestSide. |
| 158 return std::max(std::max(center.x(), boxSize.width() - center.x()), std::max
(center.y(), boxSize.height() - center.y())); |
| 159 } |
| 160 |
| 136 void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) | 161 void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox) |
| 137 { | 162 { |
| 138 ASSERT(path.isEmpty()); | 163 ASSERT(path.isEmpty()); |
| 139 // FIXME Complete implementation of path. | 164 FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boun
dingBox.size()); |
| 140 // Compute closest-side and farthest-side from boundingBox. | 165 float radius = floatValueForRadiusInBox(boundingBox.size()); |
| 141 // Compute top, left, bottom, right from boundingBox. | |
| 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( | 166 path.addEllipse(FloatRect( |
| 152 centerX - radius + boundingBox.x(), | 167 center.x() - radius + boundingBox.x(), |
| 153 centerY - radius + boundingBox.y(), | 168 center.y() - radius + boundingBox.y(), |
| 154 radius * 2, | 169 radius * 2, |
| 155 radius * 2 | 170 radius * 2 |
| 156 )); | 171 )); |
| 157 } | 172 } |
| 158 | 173 |
| 159 PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double p
rogress) const | 174 PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double p
rogress) const |
| 160 { | 175 { |
| 161 ASSERT(type() == other->type()); | 176 ASSERT(type() == other->type()); |
| 162 const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other); | 177 const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other); |
| 163 RefPtr<BasicShapeCircle> result = BasicShapeCircle::create(); | 178 RefPtr<BasicShapeCircle> result = BasicShapeCircle::create(); |
| 164 | 179 |
| 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)); | 180 result->setCenterX(m_centerX.blend(o->centerX(), progress)); |
| 173 result->setCenterY(m_centerY.blend(o->centerY(), progress)); | 181 result->setCenterY(m_centerY.blend(o->centerY(), progress)); |
| 174 result->setRadius(m_radius.blend(o->radius(), progress)); | 182 result->setRadius(m_radius.blend(o->radius(), progress)); |
| 175 return result.release(); | 183 return result.release(); |
| 176 } | 184 } |
| 177 | 185 |
| 178 void DeprecatedBasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) | 186 void DeprecatedBasicShapeEllipse::path(Path& path, const FloatRect& boundingBox) |
| 179 { | 187 { |
| 180 ASSERT(path.isEmpty()); | 188 ASSERT(path.isEmpty()); |
| 181 float centerX = floatValueForLength(m_centerX, boundingBox.width()); | 189 float centerX = floatValueForLength(m_centerX, boundingBox.width()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 { | 231 { |
| 224 ASSERT(path.isEmpty()); | 232 ASSERT(path.isEmpty()); |
| 225 // FIXME Complete implementation of path. Bug 124619. | 233 // FIXME Complete implementation of path. Bug 124619. |
| 226 // Compute closest-side and farthest-side from boundingBox. | 234 // Compute closest-side and farthest-side from boundingBox. |
| 227 // Compute top, left, bottom, right from boundingBox. | 235 // Compute top, left, bottom, right from boundingBox. |
| 228 if (m_radiusX.type() != BasicShapeRadius::Value || m_radiusY.type() != Basic
ShapeRadius::Value) | 236 if (m_radiusX.type() != BasicShapeRadius::Value || m_radiusY.type() != Basic
ShapeRadius::Value) |
| 229 return; | 237 return; |
| 230 if (m_centerX.keyword() != BasicShapeCenterCoordinate::None || m_centerY.key
word() != BasicShapeCenterCoordinate::None) | 238 if (m_centerX.keyword() != BasicShapeCenterCoordinate::None || m_centerY.key
word() != BasicShapeCenterCoordinate::None) |
| 231 return; | 239 return; |
| 232 | 240 |
| 233 float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + bounding
Box.height() * boundingBox.height()) / 2); | 241 float diagonal = hypotf(boundingBox.width(), boundingBox.height()) / sqrtf(2
); |
| 234 float centerX = floatValueForLength(m_centerX.length(), boundingBox.width())
; | 242 float centerX = floatValueForLength(m_centerX.length(), boundingBox.width())
; |
| 235 float centerY = floatValueForLength(m_centerY.length(), boundingBox.height()
); | 243 float centerY = floatValueForLength(m_centerY.length(), boundingBox.height()
); |
| 236 float radiusX = floatValueForLength(m_radiusX.value(), diagonal); | 244 float radiusX = floatValueForLength(m_radiusX.value(), diagonal); |
| 237 float radiusY = floatValueForLength(m_radiusY.value(), diagonal); | 245 float radiusY = floatValueForLength(m_radiusY.value(), diagonal); |
| 238 path.addEllipse(FloatRect( | 246 path.addEllipse(FloatRect( |
| 239 centerX - radiusX + boundingBox.x(), | 247 centerX - radiusX + boundingBox.x(), |
| 240 centerY - radiusY + boundingBox.y(), | 248 centerY - radiusY + boundingBox.y(), |
| 241 radiusX * 2, | 249 radiusX * 2, |
| 242 radiusY * 2 | 250 radiusY * 2 |
| 243 )); | 251 )); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 357 } |
| 350 | 358 |
| 351 bool BasicShapeInsetRectangle::operator==(const BasicShape& o) const | 359 bool BasicShapeInsetRectangle::operator==(const BasicShape& o) const |
| 352 { | 360 { |
| 353 if (!isSameType(o)) | 361 if (!isSameType(o)) |
| 354 return false; | 362 return false; |
| 355 const BasicShapeInsetRectangle& other = toBasicShapeInsetRectangle(o); | 363 const BasicShapeInsetRectangle& other = toBasicShapeInsetRectangle(o); |
| 356 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; | 364 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; |
| 357 } | 365 } |
| 358 } | 366 } |
| OLD | NEW |