| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2013 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 12 matching lines...) Expand all Loading... |
| 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| 27 * OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 */ | 28 */ |
| 29 | 29 |
| 30 #include "config.h" | 30 #include "config.h" |
| 31 #include "platform/geometry/FloatRoundedRect.h" | 31 #include "platform/geometry/FloatRoundedRect.h" |
| 32 | 32 |
| 33 #include "platform/geometry/FloatQuad.h" |
| 34 |
| 33 #include <algorithm> | 35 #include <algorithm> |
| 34 | 36 |
| 35 namespace blink { | 37 namespace blink { |
| 36 | 38 |
| 37 FloatRoundedRect::FloatRoundedRect(float x, float y, float width, float height) | 39 FloatRoundedRect::FloatRoundedRect(float x, float y, float width, float height) |
| 38 : m_rect(x, y, width, height) | 40 : m_rect(x, y, width, height) |
| 39 { | 41 { |
| 40 } | 42 } |
| 41 | 43 |
| 42 FloatRoundedRect::FloatRoundedRect(const FloatRect& rect, const Radii& radii) | 44 FloatRoundedRect::FloatRoundedRect(const FloatRect& rect, const Radii& radii) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 m_bottomRight.setHeight(std::max<float>(0, m_bottomRight.height() + bott
omWidth)); | 98 m_bottomRight.setHeight(std::max<float>(0, m_bottomRight.height() + bott
omWidth)); |
| 97 } | 99 } |
| 98 } | 100 } |
| 99 | 101 |
| 100 static inline float cornerRectIntercept(float y, const FloatRect& cornerRect) | 102 static inline float cornerRectIntercept(float y, const FloatRect& cornerRect) |
| 101 { | 103 { |
| 102 ASSERT(cornerRect.height() > 0); | 104 ASSERT(cornerRect.height() > 0); |
| 103 return cornerRect.width() * sqrt(1 - (y * y) / (cornerRect.height() * corner
Rect.height())); | 105 return cornerRect.width() * sqrt(1 - (y * y) / (cornerRect.height() * corner
Rect.height())); |
| 104 } | 106 } |
| 105 | 107 |
| 108 FloatRect FloatRoundedRect::radiusCenterRect() const |
| 109 { |
| 110 ASSERT(isRenderable()); |
| 111 int minX = m_rect.x() + std::max(m_radii.topLeft().width(), m_radii.bottomLe
ft().width()); |
| 112 int minY = m_rect.y() + std::max(m_radii.topLeft().height(), m_radii.topRigh
t().height()); |
| 113 int maxX = m_rect.maxX() - std::max(m_radii.topRight().width(), m_radii.bott
omRight().width()); |
| 114 int maxY = m_rect.maxY() - std::max(m_radii.bottomLeft().height(), m_radii.b
ottomRight().height()); |
| 115 return FloatRect(minX, minY, maxX - minX, maxY - minY); |
| 116 } |
| 117 |
| 106 bool FloatRoundedRect::xInterceptsAtY(float y, float& minXIntercept, float& maxX
Intercept) const | 118 bool FloatRoundedRect::xInterceptsAtY(float y, float& minXIntercept, float& maxX
Intercept) const |
| 107 { | 119 { |
| 108 if (y < rect().y() || y > rect().maxY()) | 120 if (y < rect().y() || y > rect().maxY()) |
| 109 return false; | 121 return false; |
| 110 | 122 |
| 111 if (!isRounded()) { | 123 if (!isRounded()) { |
| 112 minXIntercept = rect().x(); | 124 minXIntercept = rect().x(); |
| 113 maxXIntercept = rect().maxX(); | 125 maxXIntercept = rect().maxX(); |
| 114 return true; | 126 return true; |
| 115 } | 127 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 130 if (!topRightRect.isEmpty() && y >= topRightRect.y() && y <= topRightRect.ma
xY()) | 142 if (!topRightRect.isEmpty() && y >= topRightRect.y() && y <= topRightRect.ma
xY()) |
| 131 maxXIntercept = topRightRect.x() + cornerRectIntercept(topRightRect.maxY
() - y, topRightRect); | 143 maxXIntercept = topRightRect.x() + cornerRectIntercept(topRightRect.maxY
() - y, topRightRect); |
| 132 else if (!bottomRightRect.isEmpty() && y >= bottomRightRect.y() && y <= bott
omRightRect.maxY()) | 144 else if (!bottomRightRect.isEmpty() && y >= bottomRightRect.y() && y <= bott
omRightRect.maxY()) |
| 133 maxXIntercept = bottomRightRect.x() + cornerRectIntercept(y - bottomRigh
tRect.y(), bottomRightRect); | 145 maxXIntercept = bottomRightRect.x() + cornerRectIntercept(y - bottomRigh
tRect.y(), bottomRightRect); |
| 134 else | 146 else |
| 135 maxXIntercept = m_rect.maxX(); | 147 maxXIntercept = m_rect.maxX(); |
| 136 | 148 |
| 137 return true; | 149 return true; |
| 138 } | 150 } |
| 139 | 151 |
| 152 void FloatRoundedRect::inflateWithRadii(int size) |
| 153 { |
| 154 FloatRect old = m_rect; |
| 155 |
| 156 m_rect.inflate(size); |
| 157 // Considering the inflation factor of shorter size to scale the radii seems
appropriate here |
| 158 float factor; |
| 159 if (m_rect.width() < m_rect.height()) |
| 160 factor = old.width() ? (float)m_rect.width() / old.width() : int(0); |
| 161 else |
| 162 factor = old.height() ? (float)m_rect.height() / old.height() : int(0); |
| 163 |
| 164 m_radii.scale(factor); |
| 165 } |
| 166 |
| 167 bool FloatRoundedRect::intersectsQuad(const FloatQuad& quad) const |
| 168 { |
| 169 if (!quad.intersectsRect(m_rect)) |
| 170 return false; |
| 171 |
| 172 const FloatSize& topLeft = m_radii.topLeft(); |
| 173 if (!topLeft.isEmpty()) { |
| 174 FloatRect rect(m_rect.x(), m_rect.y(), topLeft.width(), topLeft.height()
); |
| 175 if (quad.intersectsRect(rect)) { |
| 176 FloatPoint center(m_rect.x() + topLeft.width(), m_rect.y() + topLeft
.height()); |
| 177 FloatSize size(topLeft.width(), topLeft.height()); |
| 178 if (!quad.intersectsEllipse(center, size)) |
| 179 return false; |
| 180 } |
| 181 } |
| 182 |
| 183 const FloatSize& topRight = m_radii.topRight(); |
| 184 if (!topRight.isEmpty()) { |
| 185 FloatRect rect(m_rect.maxX() - topRight.width(), m_rect.y(), topRight.wi
dth(), topRight.height()); |
| 186 if (quad.intersectsRect(rect)) { |
| 187 FloatPoint center(m_rect.maxX() - topRight.width(), m_rect.y() + top
Right.height()); |
| 188 FloatSize size(topRight.width(), topRight.height()); |
| 189 if (!quad.intersectsEllipse(center, size)) |
| 190 return false; |
| 191 } |
| 192 } |
| 193 |
| 194 const FloatSize& bottomLeft = m_radii.bottomLeft(); |
| 195 if (!bottomLeft.isEmpty()) { |
| 196 FloatRect rect(m_rect.x(), m_rect.maxY() - bottomLeft.height(), bottomLe
ft.width(), bottomLeft.height()); |
| 197 if (quad.intersectsRect(rect)) { |
| 198 FloatPoint center(m_rect.x() + bottomLeft.width(), m_rect.maxY() - b
ottomLeft.height()); |
| 199 FloatSize size(bottomLeft.width(), bottomLeft.height()); |
| 200 if (!quad.intersectsEllipse(center, size)) |
| 201 return false; |
| 202 } |
| 203 } |
| 204 |
| 205 const FloatSize& bottomRight = m_radii.bottomRight(); |
| 206 if (!bottomRight.isEmpty()) { |
| 207 FloatRect rect(m_rect.maxX() - bottomRight.width(), m_rect.maxY() - bott
omRight.height(), bottomRight.width(), bottomRight.height()); |
| 208 if (quad.intersectsRect(rect)) { |
| 209 FloatPoint center(m_rect.maxX() - bottomRight.width(), m_rect.maxY()
- bottomRight.height()); |
| 210 FloatSize size(bottomRight.width(), bottomRight.height()); |
| 211 if (!quad.intersectsEllipse(center, size)) |
| 212 return false; |
| 213 } |
| 214 } |
| 215 |
| 216 return true; |
| 217 } |
| 218 |
| 219 void FloatRoundedRect::Radii::includeLogicalEdges(const FloatRoundedRect::Radii&
edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRight
Edge) |
| 220 { |
| 221 if (includeLogicalLeftEdge) { |
| 222 if (isHorizontal) |
| 223 m_bottomLeft = edges.bottomLeft(); |
| 224 else |
| 225 m_topRight = edges.topRight(); |
| 226 m_topLeft = edges.topLeft(); |
| 227 } |
| 228 |
| 229 if (includeLogicalRightEdge) { |
| 230 if (isHorizontal) |
| 231 m_topRight = edges.topRight(); |
| 232 else |
| 233 m_bottomLeft = edges.bottomLeft(); |
| 234 m_bottomRight = edges.bottomRight(); |
| 235 } |
| 236 } |
| 237 |
| 238 void FloatRoundedRect::includeLogicalEdges(const Radii& edges, bool isHorizontal
, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) |
| 239 { |
| 240 m_radii.includeLogicalEdges(edges, isHorizontal, includeLogicalLeftEdge, inc
ludeLogicalRightEdge); |
| 241 } |
| 242 |
| 243 bool FloatRoundedRect::isRenderable() const |
| 244 { |
| 245 // FIXME: remove the 0.0001 slop once this class is converted to layout unit
s. |
| 246 return m_radii.topLeft().width() + m_radii.topRight().width() <= m_rect.widt
h() + 0.0001 |
| 247 && m_radii.bottomLeft().width() + m_radii.bottomRight().width() <= m_rec
t.width() + 0.0001 |
| 248 && m_radii.topLeft().height() + m_radii.bottomLeft().height() <= m_rect.
height() + 0.0001 |
| 249 && m_radii.topRight().height() + m_radii.bottomRight().height() <= m_rec
t.height() + 0.0001; |
| 250 } |
| 251 |
| 252 void FloatRoundedRect::adjustRadii() |
| 253 { |
| 254 float maxRadiusWidth = std::max(m_radii.topLeft().width() + m_radii.topRight
().width(), m_radii.bottomLeft().width() + m_radii.bottomRight().width()); |
| 255 float maxRadiusHeight = std::max(m_radii.topLeft().height() + m_radii.bottom
Left().height(), m_radii.topRight().height() + m_radii.bottomRight().height()); |
| 256 |
| 257 if (maxRadiusWidth <= 0 || maxRadiusHeight <= 0) { |
| 258 m_radii.scale(0.0f); |
| 259 return; |
| 260 } |
| 261 float widthRatio = static_cast<float>(m_rect.width()) / maxRadiusWidth; |
| 262 float heightRatio = static_cast<float>(m_rect.height()) / maxRadiusHeight; |
| 263 m_radii.scale(widthRatio < heightRatio ? widthRatio : heightRatio); |
| 264 } |
| 265 |
| 266 |
| 140 } // namespace blink | 267 } // namespace blink |
| OLD | NEW |