summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 01:38:04 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 01:38:04 +0000
commitcf82dc7f6cc5b87b13c55e8d65ad93cd5fd4ed82 (patch)
treeeba3c4af5cd405b990351b733012d35734e6bb14 /ui
parent1d09e0bced4d3d89d633ca078964e4e332dcedb9 (diff)
downloadchromium_src-cf82dc7f6cc5b87b13c55e8d65ad93cd5fd4ed82.zip
chromium_src-cf82dc7f6cc5b87b13c55e8d65ad93cd5fd4ed82.tar.gz
chromium_src-cf82dc7f6cc5b87b13c55e8d65ad93cd5fd4ed82.tar.bz2
ui: Add a BoundingRect method
This method gives a Rect whose position and size are determined by two input points. BUG=147395 R=sky Review URL: https://codereview.chromium.org/11318015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165279 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/rect.cc10
-rw-r--r--ui/gfx/rect.h8
-rw-r--r--ui/gfx/rect_f.cc10
-rw-r--r--ui/gfx/rect_f.h8
-rw-r--r--ui/gfx/rect_unittest.cc65
5 files changed, 101 insertions, 0 deletions
diff --git a/ui/gfx/rect.cc b/ui/gfx/rect.cc
index b01d60c..dec2407 100644
--- a/ui/gfx/rect.cc
+++ b/ui/gfx/rect.cc
@@ -4,6 +4,8 @@
#include "ui/gfx/rect.h"
+#include <cmath>
+
#if defined(OS_WIN)
#include <windows.h>
#elif defined(TOOLKIT_GTK)
@@ -106,4 +108,12 @@ Rect SubtractRects(const Rect& a, const Rect& b) {
return result;
}
+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);
+}
+
} // namespace gfx
diff --git a/ui/gfx/rect.h b/ui/gfx/rect.h
index 9138f46..5479d2e 100644
--- a/ui/gfx/rect.h
+++ b/ui/gfx/rect.h
@@ -81,6 +81,14 @@ UI_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
UI_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
UI_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
+// Constructs a rectangle with |p1| and |p2| as opposite corners.
+//
+// This could also be thought of as "the smallest rect that contains both
+// points", except that we consider points on the right/bottom edges of the
+// rect to be outside the rect. So technically one or both points will not be
+// contained within the rect, because they will appear on one of these edges.
+UI_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
+
#if !defined(COMPILER_MSVC)
extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
#endif
diff --git a/ui/gfx/rect_f.cc b/ui/gfx/rect_f.cc
index f011d71..9e4dbd18 100644
--- a/ui/gfx/rect_f.cc
+++ b/ui/gfx/rect_f.cc
@@ -4,6 +4,8 @@
#include "ui/gfx/rect_f.h"
+#include <cmath>
+
#include "base/logging.h"
#include "base/stringprintf.h"
#include "ui/gfx/insets_f.h"
@@ -67,4 +69,12 @@ RectF ScaleRect(const RectF& r, float x_scale, float y_scale) {
return result;
}
+RectF BoundingRect(const PointF& p1, const PointF& p2) {
+ float rx = std::min(p1.x(), p2.x());
+ float ry = std::min(p1.y(), p2.y());
+ float rr = std::max(p1.x(), p2.x());
+ float rb = std::max(p1.y(), p2.y());
+ return RectF(rx, ry, rr - rx, rb - ry);
+}
+
} // namespace gfx
diff --git a/ui/gfx/rect_f.h b/ui/gfx/rect_f.h
index db00324..499c9be 100644
--- a/ui/gfx/rect_f.h
+++ b/ui/gfx/rect_f.h
@@ -60,6 +60,14 @@ inline RectF ScaleRect(const RectF& r, float scale) {
return ScaleRect(r, scale, scale);
}
+// Constructs a rectangle with |p1| and |p2| as opposite corners.
+//
+// This could also be thought of as "the smallest rect that contains both
+// points", except that we consider points on the right/bottom edges of the
+// rect to be outside the rect. So technically one or both points will not be
+// contained within the rect, because they will appear on one of these edges.
+UI_EXPORT RectF BoundingRect(const PointF& p1, const PointF& p2);
+
#if !defined(COMPILER_MSVC)
extern template class RectBase<RectF, PointF, SizeF, InsetsF, Vector2dF, float>;
#endif
diff --git a/ui/gfx/rect_unittest.cc b/ui/gfx/rect_unittest.cc
index b83d8a4..1f31ae26 100644
--- a/ui/gfx/rect_unittest.cc
+++ b/ui/gfx/rect_unittest.cc
@@ -606,4 +606,69 @@ TEST(RectTest, ToRectF) {
EXPECT_EQ(b, a);
}
+TEST(RectTest, BoundingRect) {
+ struct {
+ gfx::Point a;
+ gfx::Point b;
+ gfx::Rect expected;
+ } int_tests[] = {
+ // If point B dominates A, then A should be the origin.
+ { gfx::Point(4, 6), gfx::Point(4, 6), gfx::Rect(4, 6, 0, 0) },
+ { gfx::Point(4, 6), gfx::Point(8, 6), gfx::Rect(4, 6, 4, 0) },
+ { gfx::Point(4, 6), gfx::Point(4, 9), gfx::Rect(4, 6, 0, 3) },
+ { gfx::Point(4, 6), gfx::Point(8, 9), gfx::Rect(4, 6, 4, 3) },
+ // If point A dominates B, then B should be the origin.
+ { gfx::Point(4, 6), gfx::Point(4, 6), gfx::Rect(4, 6, 0, 0) },
+ { gfx::Point(8, 6), gfx::Point(4, 6), gfx::Rect(4, 6, 4, 0) },
+ { gfx::Point(4, 9), gfx::Point(4, 6), gfx::Rect(4, 6, 0, 3) },
+ { gfx::Point(8, 9), gfx::Point(4, 6), gfx::Rect(4, 6, 4, 3) },
+ // If neither point dominates, then the origin is a combination of the two.
+ { gfx::Point(4, 6), gfx::Point(6, 4), gfx::Rect(4, 4, 2, 2) },
+ { gfx::Point(-4, -6), gfx::Point(-6, -4), gfx::Rect(-6, -6, 2, 2) },
+ { gfx::Point(-4, 6), gfx::Point(6, -4), gfx::Rect(-4, -4, 10, 10) },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(int_tests); ++i) {
+ gfx::Rect actual = BoundingRect(int_tests[i].a, int_tests[i].b);
+ EXPECT_EQ(int_tests[i].expected.ToString(), actual.ToString());
+ }
+
+ struct {
+ gfx::PointF a;
+ gfx::PointF b;
+ gfx::RectF expected;
+ } float_tests[] = {
+ // If point B dominates A, then A should be the origin.
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(4.2f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 0, 0) },
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(8.5f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 4.3f, 0) },
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(4.2f, 9.3f),
+ gfx::RectF(4.2f, 6.8f, 0, 2.5f) },
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(8.5f, 9.3f),
+ gfx::RectF(4.2f, 6.8f, 4.3f, 2.5f) },
+ // If point A dominates B, then B should be the origin.
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(4.2f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 0, 0) },
+ { gfx::PointF(8.5f, 6.8f), gfx::PointF(4.2f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 4.3f, 0) },
+ { gfx::PointF(4.2f, 9.3f), gfx::PointF(4.2f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 0, 2.5f) },
+ { gfx::PointF(8.5f, 9.3f), gfx::PointF(4.2f, 6.8f),
+ gfx::RectF(4.2f, 6.8f, 4.3f, 2.5f) },
+ // If neither point dominates, then the origin is a combination of the two.
+ { gfx::PointF(4.2f, 6.8f), gfx::PointF(6.8f, 4.2f),
+ gfx::RectF(4.2f, 4.2f, 2.6f, 2.6f) },
+ { gfx::PointF(-4.2f, -6.8f), gfx::PointF(-6.8f, -4.2f),
+ gfx::RectF(-6.8f, -6.8f, 2.6f, 2.6f) },
+ { gfx::PointF(-4.2f, 6.8f), gfx::PointF(6.8f, -4.2f),
+ gfx::RectF(-4.2f, -4.2f, 11.0f, 11.0f) }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i) {
+ gfx::RectF actual = BoundingRect(float_tests[i].a, float_tests[i].b);
+ EXPECT_EQ(float_tests[i].expected.ToString(), actual.ToString());
+ }
+}
+
} // namespace ui