diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-01 01:38:04 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-01 01:38:04 +0000 |
commit | cf82dc7f6cc5b87b13c55e8d65ad93cd5fd4ed82 (patch) | |
tree | eba3c4af5cd405b990351b733012d35734e6bb14 /ui | |
parent | 1d09e0bced4d3d89d633ca078964e4e332dcedb9 (diff) | |
download | chromium_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.cc | 10 | ||||
-rw-r--r-- | ui/gfx/rect.h | 8 | ||||
-rw-r--r-- | ui/gfx/rect_f.cc | 10 | ||||
-rw-r--r-- | ui/gfx/rect_f.h | 8 | ||||
-rw-r--r-- | ui/gfx/rect_unittest.cc | 65 |
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 |