Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: ui/gfx/geometry/rect.cc

Issue 2744423002: Handle large rects better. (Closed)
Patch Set: Add ARM code branch Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/geometry/rect.h ('k') | ui/gfx/geometry/rect_conversions.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/geometry/rect.cc
diff --git a/ui/gfx/geometry/rect.cc b/ui/gfx/geometry/rect.cc
index f3c47b2b378e9b0bd8087330560a4b7541e6384d..121cd13d6b14b7e1aba6d9bcf6478b9dce9ddea9 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 cwmost useful origin and
Peter Mayo 2017/03/22 22:40:16 Typo
+// 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());
}
@@ -151,14 +194,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 +226,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 +329,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
« no previous file with comments | « ui/gfx/geometry/rect.h ('k') | ui/gfx/geometry/rect_conversions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698