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 HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 27 * OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "config.h" 31 #include "core/rendering/shapes/RectangleShape.h" 32 33 #include "wtf/MathExtras.h" 34 35 namespace WebCore { 36 37 static inline float ellipseXIntercept(float y, float rx, float ry) 38 { 39 ASSERT(ry > 0); 40 return rx * sqrt(1 - (y * y) / (ry * ry)); 41 } 42 43 FloatRect RectangleShape::shapeMarginBounds() const 44 { 45 ASSERT(shapeMargin() >= 0); 46 if (!shapeMargin()) 47 return m_bounds; 48 49 float boundsX = x() - shapeMargin(); 50 float boundsY = y() - shapeMargin(); 51 float boundsWidth = width() + shapeMargin() * 2; 52 float boundsHeight = height() + shapeMargin() * 2; 53 return FloatRect(boundsX, boundsY, boundsWidth, boundsHeight); 54 } 55 56 void RectangleShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const 57 { 58 const FloatRect& bounds = shapeMarginBounds(); 59 if (bounds.isEmpty()) 60 return; 61 62 float y1 = logicalTop.toFloat(); 63 float y2 = (logicalTop + logicalHeight).toFloat(); 64 65 if (y2 < bounds.y() || y1 >= bounds.maxY()) 66 return; 67 68 float x1 = bounds.x(); 69 float x2 = bounds.maxX(); 70 71 float marginRadiusX = rx() + shapeMargin(); 72 float marginRadiusY = ry() + shapeMargin(); 73 74 if (marginRadiusY > 0) { 75 if (y2 < bounds.y() + marginRadiusY) { 76 float yi = y2 - bounds.y() - marginRadiusY; 77 float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY); 78 x1 = bounds.x() + marginRadiusX - xi; 79 x2 = bounds.maxX() - marginRadiusX + xi; 80 } else if (y1 > bounds.maxY() - marginRadiusY) { 81 float yi = y1 - (bounds.maxY() - marginRadiusY); 82 float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY); 83 x1 = bounds.x() + marginRadiusX - xi; 84 x2 = bounds.maxX() - marginRadiusX + xi; 85 } 86 } 87 88 result.append(LineSegment(x1, x2)); 89 } 90 91 void RectangleShape::buildDisplayPaths(DisplayPaths& paths) const 92 { 93 paths.shape.addRoundedRect(m_bounds, m_radii); 94 if (shapeMargin()) 95 paths.marginShape.addRoundedRect(shapeMarginBounds(), FloatSize(m_radii.width() + shapeMargin(), m_radii.height() + shapeMargin())); 96 } 97 98 } // namespace WebCore 99