| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2012 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 22 matching lines...) Expand all Loading... |
| 33 #include "wtf/MathExtras.h" | 33 #include "wtf/MathExtras.h" |
| 34 | 34 |
| 35 namespace WebCore { | 35 namespace WebCore { |
| 36 | 36 |
| 37 static inline float ellipseXIntercept(float y, float rx, float ry) | 37 static inline float ellipseXIntercept(float y, float rx, float ry) |
| 38 { | 38 { |
| 39 ASSERT(ry > 0); | 39 ASSERT(ry > 0); |
| 40 return rx * sqrt(1 - (y * y) / (ry * ry)); | 40 return rx * sqrt(1 - (y * y) / (ry * ry)); |
| 41 } | 41 } |
| 42 | 42 |
| 43 static inline float ellipseYIntercept(float x, float rx, float ry) | |
| 44 { | |
| 45 ASSERT(rx > 0); | |
| 46 return ry * sqrt(1 - (x * x) / (rx * rx)); | |
| 47 } | |
| 48 | |
| 49 FloatRect RectangleShape::shapePaddingBounds() const | |
| 50 { | |
| 51 ASSERT(shapePadding() >= 0); | |
| 52 if (!shapePadding() || isEmpty()) | |
| 53 return m_bounds; | |
| 54 | |
| 55 float boundsX = x() + std::min(width() / 2, shapePadding()); | |
| 56 float boundsY = y() + std::min(height() / 2, shapePadding()); | |
| 57 float boundsWidth = std::max(0.0f, width() - shapePadding() * 2); | |
| 58 float boundsHeight = std::max(0.0f, height() - shapePadding() * 2); | |
| 59 | |
| 60 return FloatRect(boundsX, boundsY, boundsWidth, boundsHeight); | |
| 61 } | |
| 62 | |
| 63 FloatRect RectangleShape::shapeMarginBounds() const | 43 FloatRect RectangleShape::shapeMarginBounds() const |
| 64 { | 44 { |
| 65 ASSERT(shapeMargin() >= 0); | 45 ASSERT(shapeMargin() >= 0); |
| 66 if (!shapeMargin()) | 46 if (!shapeMargin()) |
| 67 return m_bounds; | 47 return m_bounds; |
| 68 | 48 |
| 69 float boundsX = x() - shapeMargin(); | 49 float boundsX = x() - shapeMargin(); |
| 70 float boundsY = y() - shapeMargin(); | 50 float boundsY = y() - shapeMargin(); |
| 71 float boundsWidth = width() + shapeMargin() * 2; | 51 float boundsWidth = width() + shapeMargin() * 2; |
| 72 float boundsHeight = height() + shapeMargin() * 2; | 52 float boundsHeight = height() + shapeMargin() * 2; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 101 float yi = y1 - (bounds.maxY() - marginRadiusY); | 81 float yi = y1 - (bounds.maxY() - marginRadiusY); |
| 102 float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY); | 82 float xi = ellipseXIntercept(yi, marginRadiusX, marginRadiusY); |
| 103 x1 = bounds.x() + marginRadiusX - xi; | 83 x1 = bounds.x() + marginRadiusX - xi; |
| 104 x2 = bounds.maxX() - marginRadiusX + xi; | 84 x2 = bounds.maxX() - marginRadiusX + xi; |
| 105 } | 85 } |
| 106 } | 86 } |
| 107 | 87 |
| 108 result.append(LineSegment(x1, x2)); | 88 result.append(LineSegment(x1, x2)); |
| 109 } | 89 } |
| 110 | 90 |
| 111 void RectangleShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logi
calHeight, SegmentList& result) const | |
| 112 { | |
| 113 const FloatRect& bounds = shapePaddingBounds(); | |
| 114 if (bounds.isEmpty()) | |
| 115 return; | |
| 116 | |
| 117 float y1 = logicalTop.toFloat(); | |
| 118 float y2 = (logicalTop + logicalHeight).toFloat(); | |
| 119 | |
| 120 if (y1 < bounds.y() || y2 > bounds.maxY()) | |
| 121 return; | |
| 122 | |
| 123 float x1 = bounds.x(); | |
| 124 float x2 = bounds.maxX(); | |
| 125 | |
| 126 float paddingRadiusX = std::max(0.0f, rx() - shapePadding()); | |
| 127 float paddingRadiusY = std::max(0.0f, ry() - shapePadding()); | |
| 128 | |
| 129 if (paddingRadiusX > 0) { | |
| 130 bool y1InterceptsCorner = y1 < bounds.y() + paddingRadiusY; | |
| 131 bool y2InterceptsCorner = y2 > bounds.maxY() - paddingRadiusY; | |
| 132 float xi = 0; | |
| 133 | |
| 134 if (y1InterceptsCorner && y2InterceptsCorner) { | |
| 135 if (y1 < bounds.height() + 2 * bounds.y() - y2) { | |
| 136 float yi = y1 - bounds.y() - paddingRadiusY; | |
| 137 xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY); | |
| 138 } else { | |
| 139 float yi = y2 - (bounds.maxY() - paddingRadiusY); | |
| 140 xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY); | |
| 141 } | |
| 142 } else if (y1InterceptsCorner) { | |
| 143 float yi = y1 - bounds.y() - paddingRadiusY; | |
| 144 xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY); | |
| 145 } else if (y2InterceptsCorner) { | |
| 146 float yi = y2 - (bounds.maxY() - paddingRadiusY); | |
| 147 xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY); | |
| 148 } | |
| 149 | |
| 150 if (y1InterceptsCorner || y2InterceptsCorner) { | |
| 151 x1 = bounds.x() + paddingRadiusX - xi; | |
| 152 x2 = bounds.maxX() - paddingRadiusX + xi; | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 result.append(LineSegment(x1, x2)); | |
| 157 } | |
| 158 | |
| 159 static FloatPoint cornerInterceptForWidth(float width, float widthAtIntercept, f
loat rx, float ry) | |
| 160 { | |
| 161 float xi = (width - widthAtIntercept) / 2; | |
| 162 float yi = ry - ellipseYIntercept(rx - xi, rx, ry); | |
| 163 return FloatPoint(xi, yi); | |
| 164 } | |
| 165 | |
| 166 bool RectangleShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalInterv
alTop, const FloatSize& minLogicalIntervalSize, LayoutUnit& result) const | |
| 167 { | |
| 168 float minIntervalTop = minLogicalIntervalTop.toFloat(); | |
| 169 float minIntervalHeight = minLogicalIntervalSize.height(); | |
| 170 float minIntervalWidth = minLogicalIntervalSize.width(); | |
| 171 | |
| 172 const FloatRect& bounds = shapePaddingBounds(); | |
| 173 if (bounds.isEmpty() || minIntervalWidth > bounds.width()) | |
| 174 return false; | |
| 175 | |
| 176 // FIXME: Shapes should be made to use LayoutUnits to avoid broken construct
s like this. | |
| 177 float minY = LayoutUnit::fromFloatCeil(std::max(bounds.y(), minIntervalTop))
.toFloat(); | |
| 178 float maxY = minY + minIntervalHeight; | |
| 179 | |
| 180 if (maxY > bounds.maxY()) | |
| 181 return false; | |
| 182 | |
| 183 float paddingRadiusX = std::max(0.0f, rx() - shapePadding()); | |
| 184 float paddingRadiusY = std::max(0.0f, ry() - shapePadding()); | |
| 185 | |
| 186 bool intervalOverlapsMinCorner = minY < bounds.y() + paddingRadiusY; | |
| 187 bool intervalOverlapsMaxCorner = maxY > bounds.maxY() - paddingRadiusY; | |
| 188 | |
| 189 if (!intervalOverlapsMinCorner && !intervalOverlapsMaxCorner) { | |
| 190 result = minY; | |
| 191 return true; | |
| 192 } | |
| 193 | |
| 194 float centerY = bounds.y() + bounds.height() / 2; | |
| 195 bool minCornerDefinesX = fabs(centerY - minY) > fabs(centerY - maxY); | |
| 196 bool intervalFitsWithinCorners = minIntervalWidth + 2 * paddingRadiusX <= bo
unds.width(); | |
| 197 FloatPoint cornerIntercept = cornerInterceptForWidth(bounds.width(), minInte
rvalWidth, paddingRadiusX, paddingRadiusY); | |
| 198 | |
| 199 if (intervalOverlapsMinCorner && (!intervalOverlapsMaxCorner || minCornerDef
inesX)) { | |
| 200 if (intervalFitsWithinCorners || bounds.y() + cornerIntercept.y() < minY
) { | |
| 201 result = minY; | |
| 202 return true; | |
| 203 } | |
| 204 if (minIntervalHeight < bounds.height() - (2 * cornerIntercept.y())) { | |
| 205 result = LayoutUnit::fromFloatCeil(bounds.y() + cornerIntercept.y())
; | |
| 206 return true; | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 if (intervalOverlapsMaxCorner && (!intervalOverlapsMinCorner || !minCornerDe
finesX)) { | |
| 211 if (intervalFitsWithinCorners || minY <= bounds.maxY() - cornerIntercep
t.y() - minIntervalHeight) { | |
| 212 result = minY; | |
| 213 return true; | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 220 } // namespace WebCore | 91 } // namespace WebCore |
| OLD | NEW |