15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    copyright notice, this list of conditions and the following
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    disclaimer.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    copyright notice, this list of conditions and the following
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    disclaimer in the documentation and/or other materials
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    provided with the distribution.
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THE POSSIBILITY OF SUCH DAMAGE.
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/rendering/shapes/RectangleShape.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/MathExtras.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline float ellipseXIntercept(float y, float rx, float ry)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(ry > 0);
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return rx * sqrt(1 - (y * y) / (ry * ry));
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)FloatRect RectangleShape::shapeMarginBounds() const
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(shapeMargin() >= 0);
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!shapeMargin())
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return m_bounds;
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float boundsX = x() - shapeMargin();
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float boundsY = y() - shapeMargin();
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float boundsWidth = width() + shapeMargin() * 2;
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float boundsHeight = height() + shapeMargin() * 2;
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return FloatRect(boundsX, boundsY, boundsWidth, boundsHeight);
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
56e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)LineSegment RectangleShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const FloatRect& bounds = shapeMarginBounds();
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (bounds.isEmpty())
60e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return LineSegment();
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float y1 = logicalTop.toFloat();
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    float y2 = (logicalTop + logicalHeight).toFloat();
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (y2 < bounds.y() || y1 >= bounds.maxY())
66e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return LineSegment();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float x1 = bounds.x();
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    float x2 = bounds.maxX();
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float marginRadiusX = rx() + shapeMargin();
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float marginRadiusY = ry() + shapeMargin();
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (marginRadiusY > 0) {
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (y2 < bounds.y() + marginRadiusY) {
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float yi = y2 - bounds.y() - marginRadiusY;
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY);
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            x1 = bounds.x() + marginRadiusX - xi;
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            x2 = bounds.maxX() - marginRadiusX + xi;
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else if (y1 > bounds.maxY() - marginRadiusY) {
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float yi =  y1 - (bounds.maxY() - marginRadiusY);
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY);
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            x1 = bounds.x() + marginRadiusX - xi;
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            x2 = bounds.maxX() - marginRadiusX + xi;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
88e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return LineSegment(x1, x2);
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
91323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void RectangleShape::buildDisplayPaths(DisplayPaths& paths) const
92323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
93323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    paths.shape.addRoundedRect(m_bounds, m_radii);
94323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (shapeMargin())
95323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        paths.marginShape.addRoundedRect(shapeMarginBounds(), FloatSize(m_radii.width() + shapeMargin(), m_radii.height() + shapeMargin()));
96323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
97323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
99