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 
33 using namespace std;
34 
35 namespace WebCore {
36 
isZero() const37 bool RoundedIntRect::Radii::isZero() const
38 {
39     return m_topLeft.isZero() && m_topRight.isZero() && m_bottomLeft.isZero() && m_bottomRight.isZero();
40 }
41 
scale(float factor)42 void 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 
expand(int topWidth,int bottomWidth,int leftWidth,int rightWidth)63 void 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 
includeLogicalEdges(const RoundedIntRect::Radii & edges,bool isHorizontal,bool includeLogicalLeftEdge,bool includeLogicalRightEdge)78 void 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 
excludeLogicalEdges(bool isHorizontal,bool excludeLogicalLeftEdge,bool excludeLogicalRightEdge)97 void 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 
RoundedIntRect(int x,int y,int width,int height)116 RoundedIntRect::RoundedIntRect(int x, int y, int width, int height)
117     : m_rect(x, y, width, height)
118 {
119 }
120 
RoundedIntRect(const IntRect & rect,const Radii & radii)121 RoundedIntRect::RoundedIntRect(const IntRect& rect, const Radii& radii)
122     : m_rect(rect)
123     , m_radii(radii)
124 {
125 }
126 
RoundedIntRect(const IntRect & rect,const IntSize & topLeft,const IntSize & topRight,const IntSize & bottomLeft,const IntSize & bottomRight)127 RoundedIntRect::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 
includeLogicalEdges(const Radii & edges,bool isHorizontal,bool includeLogicalLeftEdge,bool includeLogicalRightEdge)133 void RoundedIntRect::includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
134 {
135     m_radii.includeLogicalEdges(edges, isHorizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
136 }
137 
excludeLogicalEdges(bool isHorizontal,bool excludeLogicalLeftEdge,bool excludeLogicalRightEdge)138 void RoundedIntRect::excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge)
139 {
140     m_radii.excludeLogicalEdges(isHorizontal, excludeLogicalLeftEdge, excludeLogicalRightEdge);
141 }
142 
isRenderable() const143 bool 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