| 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 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 |
| 148 { |
| 149 if (m_radius.type() == BasicShapeRadius::Value) |
| 150 return floatValueForLength(m_radius.value(), sqrtf((boxWidth * boxWidth
+ boxHeight * boxHeight) / 2)); |
| 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 |