1/*
2 * Copyright (C) 2003, 2006, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "RoundedIntRect.h"
29
30#include "IntRect.h"
31#include <algorithm>
32
33using namespace std;
34
35namespace WebCore {
36
37bool RoundedIntRect::Radii::isZero() const
38{
39    return m_topLeft.isZero() && m_topRight.isZero() && m_bottomLeft.isZero() && m_bottomRight.isZero();
40}
41
42void RoundedIntRect::Radii::scale(float factor)
43{
44    if (factor == 1)
45        return;
46
47    // If either radius on a corner becomes zero, reset both radii on that corner.
48    m_topLeft.scale(factor);
49    if (!m_topLeft.width() || !m_topLeft.height())
50        m_topLeft = IntSize();
51    m_topRight.scale(factor);
52    if (!m_topRight.width() || !m_topRight.height())
53        m_topRight = IntSize();
54    m_bottomLeft.scale(factor);
55    if (!m_bottomLeft.width() || !m_bottomLeft.height())
56        m_bottomLeft = IntSize();
57    m_bottomRight.scale(factor);
58    if (!m_bottomRight.width() || !m_bottomRight.height())
59        m_bottomRight = IntSize();
60
61}
62
63void RoundedIntRect::Radii::expand(int topWidth, int bottomWidth, int leftWidth, int rightWidth)
64{
65    m_topLeft.setWidth(max(0, m_topLeft.width() + leftWidth));
66    m_topLeft.setHeight(max(0, m_topLeft.height() + topWidth));
67
68    m_topRight.setWidth(max(0, m_topRight.width() + rightWidth));
69    m_topRight.setHeight(max(0, m_topRight.height() + topWidth));
70
71    m_bottomLeft.setWidth(max(0, m_bottomLeft.width() + leftWidth));
72    m_bottomLeft.setHeight(max(0, m_bottomLeft.height() + bottomWidth));
73
74    m_bottomRight.setWidth(max(0, m_bottomRight.width() + rightWidth));
75    m_bottomRight.setHeight(max(0, m_bottomRight.height() + bottomWidth));
76}
77
78void RoundedIntRect::Radii::includeLogicalEdges(const RoundedIntRect::Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
79{
80    if (includeLogicalLeftEdge) {
81        if (isHorizontal)
82            m_bottomLeft = edges.bottomLeft();
83        else
84            m_topRight = edges.topRight();
85        m_topLeft = edges.topLeft();
86    }
87
88    if (includeLogicalRightEdge) {
89        if (isHorizontal)
90            m_topRight = edges.topRight();
91        else
92            m_bottomLeft = edges.bottomLeft();
93        m_bottomRight = edges.bottomRight();
94    }
95}
96
97void RoundedIntRect::Radii::excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge)
98{
99    if (excludeLogicalLeftEdge) {
100        if (isHorizontal)
101            m_bottomLeft = IntSize();
102        else
103            m_topRight = IntSize();
104        m_topLeft = IntSize();
105    }
106
107    if (excludeLogicalRightEdge) {
108        if (isHorizontal)
109            m_topRight = IntSize();
110        else
111            m_bottomLeft = IntSize();
112        m_bottomRight = IntSize();
113    }
114}
115
116RoundedIntRect::RoundedIntRect(int x, int y, int width, int height)
117    : m_rect(x, y, width, height)
118{
119}
120
121RoundedIntRect::RoundedIntRect(const IntRect& rect, const Radii& radii)
122    : m_rect(rect)
123    , m_radii(radii)
124{
125}
126
127RoundedIntRect::RoundedIntRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight)
128    : m_rect(rect)
129    , m_radii(topLeft, topRight, bottomLeft, bottomRight)
130{
131}
132
133void RoundedIntRect::includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
134{
135    m_radii.includeLogicalEdges(edges, isHorizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
136}
137
138void RoundedIntRect::excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge)
139{
140    m_radii.excludeLogicalEdges(isHorizontal, excludeLogicalLeftEdge, excludeLogicalRightEdge);
141}
142
143bool RoundedIntRect::isRenderable() const
144{
145    return m_radii.topLeft().width() + m_radii.topRight().width() <= m_rect.width()
146        && m_radii.bottomLeft().width() + m_radii.bottomRight().width() <= m_rect.width()
147        && m_radii.topLeft().height() + m_radii.topRight().height() <= m_rect.height()
148        && m_radii.bottomLeft().height() + m_radii.bottomRight().height() <= m_rect.height();
149}
150
151} // namespace WebCore
152