Chromium Code Reviews| Index: ui/gfx/geometry/rect.cc |
| diff --git a/ui/gfx/geometry/rect.cc b/ui/gfx/geometry/rect.cc |
| index f3c47b2b378e9b0bd8087330560a4b7541e6384d..852b49b01ee5877707d149164bc39a1ada58593c 100644 |
| --- a/ui/gfx/geometry/rect.cc |
| +++ b/ui/gfx/geometry/rect.cc |
| @@ -60,6 +60,49 @@ void AdjustAlongAxis(int dst_origin, int dst_size, int* origin, int* size) { |
| namespace gfx { |
| +// This is the per-axis heuristic for picking the most useful origin and |
| +// width/height to represent the input range. |
| +static void SaturatedClampRange(int min, int max, int* origin, int* span) { |
| + if (max < min) { |
| + *span = 0; |
| + *origin = min; |
| + return; |
| + } |
| + |
| + *span = base::SaturatedSubtraction(max, min); |
| + |
| + int span_loss = base::SaturatedSubtraction(max, min + *span); |
| + |
| + // If the desired width is within the limits of ints, we can just |
| + // use the simple computations to represent the range precisely. |
| + if (span_loss == 0) { |
| + *origin = min; |
| + return; |
| + } |
| + |
| + // Now we have to approximate. If one of min or max is close enough |
| + // to zero we choose to make sure it is represented precisely. |
| + // The other side is probably practically "infinite", so we move it. |
| + if (base::SaturatedAbsolute(max) < std::numeric_limits<int>::max() / 2) { |
| + *origin = max - *span; |
| + } else if (base::SaturatedAbsolute(min) < |
| + std::numeric_limits<int>::max() / 2) { |
| + *origin = min; |
| + } else { |
| + // both are big, so keep the center. |
| + *origin = min + span_loss / 2; |
| + } |
| +} |
| + |
| +void Rect::SetByBounds(int left, int right, int top, int bottom) { |
| + int x, y; |
| + int width, height; |
| + SaturatedClampRange(left, right, &x, &width); |
| + SaturatedClampRange(top, bottom, &y, &height); |
| + origin_.SetPoint(x, y); |
| + size_.SetSize(width, height); |
| +} |
| + |
| void Rect::Inset(const Insets& insets) { |
| Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); |
| } |
| @@ -128,19 +171,21 @@ bool Rect::Intersects(const Rect& rect) const { |
| void Rect::Intersect(const Rect& rect) { |
| if (IsEmpty() || rect.IsEmpty()) { |
| - SetRect(0, 0, 0, 0); |
| + SetRect(0, 0, 0, 0); // Throw away empty position. |
|
danakj
2017/03/28 20:40:34
nit: Throws
Peter Mayo
2017/03/29 18:49:25
Done.
|
| return; |
| } |
| - int rx = std::max(x(), rect.x()); |
| - int ry = std::max(y(), rect.y()); |
| - int rr = std::min(right(), rect.right()); |
| - int rb = std::min(bottom(), rect.bottom()); |
| + int leftCoordinate = std::max(x(), rect.x()); |
|
danakj
2017/03/28 20:40:34
chromium style please. also just "left" "top" etc
Peter Mayo
2017/03/29 18:49:25
right and bottom are ambiguous with the this-> met
|
| + int topCoordinate = std::max(y(), rect.y()); |
| + int rightCoordinate = std::min(right(), rect.right()); |
| + int bottomCoordinate = std::min(bottom(), rect.bottom()); |
| - if (rx >= rr || ry >= rb) |
| - rx = ry = rr = rb = 0; // non-intersecting |
| + if (leftCoordinate >= rightCoordinate || topCoordinate >= bottomCoordinate) { |
| + SetRect(0, 0, 0, 0); // Throw away empty position. |
|
danakj
2017/03/28 20:40:34
nit: Throws
Peter Mayo
2017/03/29 18:49:25
Done.
|
| + return; |
| + } |
| - SetRect(rx, ry, rr - rx, rb - ry); |
| + SetByBounds(leftCoordinate, rightCoordinate, topCoordinate, bottomCoordinate); |
| } |
| void Rect::Union(const Rect& rect) { |
| @@ -151,14 +196,8 @@ void Rect::Union(const Rect& rect) { |
| if (rect.IsEmpty()) |
| return; |
| - int rx = std::min(x(), rect.x()); |
| - int ry = std::min(y(), rect.y()); |
| - int rr = std::max(right(), rect.right()); |
| - int rb = std::max(bottom(), rect.bottom()); |
| - |
| - // Subtracting to get width/height might overflow integers, so clamp them. |
| - SetRect(rx, ry, base::SaturatedSubtraction(rr, rx), |
| - base::SaturatedSubtraction(rb, ry)); |
| + SetByBounds(std::min(x(), rect.x()), std::max(right(), rect.right()), |
| + std::min(y(), rect.y()), std::max(bottom(), rect.bottom())); |
| } |
| void Rect::Subtract(const Rect& rect) { |
| @@ -189,7 +228,7 @@ void Rect::Subtract(const Rect& rect) { |
| rb = rect.y(); |
| } |
| } |
| - SetRect(rx, ry, rr - rx, rb - ry); |
| + SetByBounds(rx, rr, ry, rb); |
| } |
| void Rect::AdjustToFit(const Rect& rect) { |
| @@ -292,11 +331,10 @@ Rect SubtractRects(const Rect& a, const Rect& b) { |
| } |
| Rect BoundingRect(const Point& p1, const Point& p2) { |
| - int rx = std::min(p1.x(), p2.x()); |
| - int ry = std::min(p1.y(), p2.y()); |
| - int rr = std::max(p1.x(), p2.x()); |
| - int rb = std::max(p1.y(), p2.y()); |
| - return Rect(rx, ry, rr - rx, rb - ry); |
| + Rect result; |
| + result.SetByBounds(std::min(p1.x(), p2.x()), std::max(p1.x(), p2.x()), |
| + std::min(p1.y(), p2.y()), std::max(p1.y(), p2.y())); |
| + return result; |
| } |
| } // namespace gfx |