| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Defines a simple integer rectangle class. The containment semantics | 5 // Defines a simple integer rectangle class. The containment semantics |
| 6 // are array-like; that is, the coordinate (x, y) is considered to be | 6 // are array-like; that is, the coordinate (x, y) is considered to be |
| 7 // contained by the rectangle, but the coordinate (x + width, y) is not. | 7 // contained by the rectangle, but the coordinate (x + width, y) is not. |
| 8 // The class will happily let you create malformed rectangles (that is, | 8 // The class will happily let you create malformed rectangles (that is, |
| 9 // rectangles with negative width and/or height), but there will be assertions | 9 // rectangles with negative width and/or height), but there will be assertions |
| 10 // in the operations (such as Contains()) to complain in this case. | 10 // in the operations (such as Contains()) to complain in this case. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 namespace gfx { | 31 namespace gfx { |
| 32 | 32 |
| 33 class Insets; | 33 class Insets; |
| 34 | 34 |
| 35 class GFX_EXPORT Rect { | 35 class GFX_EXPORT Rect { |
| 36 public: | 36 public: |
| 37 constexpr Rect() = default; | 37 constexpr Rect() = default; |
| 38 constexpr Rect(int width, int height) : size_(width, height) {} | 38 constexpr Rect(int width, int height) : size_(width, height) {} |
| 39 constexpr Rect(int x, int y, int width, int height) | 39 constexpr Rect(int x, int y, int width, int height) |
| 40 : origin_(x, y), size_(width, height) {} | 40 : origin_(x, y), |
| 41 size_(GetClampedValue(x, width), GetClampedValue(y, height)) {} |
| 41 constexpr explicit Rect(const Size& size) : size_(size) {} | 42 constexpr explicit Rect(const Size& size) : size_(size) {} |
| 42 constexpr Rect(const Point& origin, const Size& size) | 43 constexpr Rect(const Point& origin, const Size& size) |
| 43 : origin_(origin), size_(size) {} | 44 : origin_(origin), |
| 45 size_(GetClampedValue(origin.x(), size.width()), |
| 46 GetClampedValue(origin.y(), size.height())) {} |
| 44 | 47 |
| 45 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
| 46 explicit Rect(const RECT& r); | 49 explicit Rect(const RECT& r); |
| 47 #elif defined(OS_MACOSX) | 50 #elif defined(OS_MACOSX) |
| 48 explicit Rect(const CGRect& r); | 51 explicit Rect(const CGRect& r); |
| 49 #endif | 52 #endif |
| 50 | 53 |
| 51 #if defined(OS_WIN) | 54 #if defined(OS_WIN) |
| 52 // Construct an equivalent Win32 RECT object. | 55 // Construct an equivalent Win32 RECT object. |
| 53 RECT ToRECT() const; | 56 RECT ToRECT() const; |
| 54 #elif defined(OS_MACOSX) | 57 #elif defined(OS_MACOSX) |
| 55 // Construct an equivalent CoreGraphics object. | 58 // Construct an equivalent CoreGraphics object. |
| 56 CGRect ToCGRect() const; | 59 CGRect ToCGRect() const; |
| 57 #endif | 60 #endif |
| 58 | 61 |
| 59 constexpr int x() const { return origin_.x(); } | 62 constexpr int x() const { return origin_.x(); } |
| 60 void set_x(int x) { origin_.set_x(x); } | 63 void set_x(int x) { |
| 64 origin_.set_x(x); |
| 65 size_.set_width(GetClampedValue(x, width())); |
| 66 } |
| 61 | 67 |
| 62 constexpr int y() const { return origin_.y(); } | 68 constexpr int y() const { return origin_.y(); } |
| 63 void set_y(int y) { origin_.set_y(y); } | 69 void set_y(int y) { |
| 70 origin_.set_y(y); |
| 71 size_.set_height(GetClampedValue(y, height())); |
| 72 } |
| 64 | 73 |
| 65 constexpr int width() const { return size_.width(); } | 74 constexpr int width() const { return size_.width(); } |
| 66 void set_width(int width) { size_.set_width(width); } | 75 void set_width(int width) { size_.set_width(GetClampedValue(x(), width)); } |
| 67 | 76 |
| 68 constexpr int height() const { return size_.height(); } | 77 constexpr int height() const { return size_.height(); } |
| 69 void set_height(int height) { size_.set_height(height); } | 78 void set_height(int height) { |
| 79 size_.set_height(GetClampedValue(y(), height)); |
| 80 } |
| 70 | 81 |
| 71 constexpr const Point& origin() const { return origin_; } | 82 constexpr const Point& origin() const { return origin_; } |
| 72 void set_origin(const Point& origin) { origin_ = origin; } | 83 void set_origin(const Point& origin) { |
| 84 origin_ = origin; |
| 85 // Ensure that width and height remain valid. |
| 86 set_width(width()); |
| 87 set_height(height()); |
| 88 } |
| 73 | 89 |
| 74 constexpr const Size& size() const { return size_; } | 90 constexpr const Size& size() const { return size_; } |
| 75 void set_size(const Size& size) { size_ = size; } | 91 void set_size(const Size& size) { |
| 92 set_width(size.width()); |
| 93 set_height(size.height()); |
| 94 } |
| 76 | 95 |
| 77 constexpr int right() const { return x() + width(); } | 96 constexpr int right() const { return x() + width(); } |
| 78 constexpr int bottom() const { return y() + height(); } | 97 constexpr int bottom() const { return y() + height(); } |
| 79 | 98 |
| 80 constexpr Point top_right() const { return Point(right(), y()); } | 99 constexpr Point top_right() const { return Point(right(), y()); } |
| 81 constexpr Point bottom_left() const { return Point(x(), bottom()); } | 100 constexpr Point bottom_left() const { return Point(x(), bottom()); } |
| 82 constexpr Point bottom_right() const { return Point(right(), bottom()); } | 101 constexpr Point bottom_right() const { return Point(right(), bottom()); } |
| 83 | 102 |
| 84 Vector2d OffsetFromOrigin() const { return Vector2d(x(), y()); } | 103 Vector2d OffsetFromOrigin() const { return Vector2d(x(), y()); } |
| 85 | 104 |
| 86 void SetRect(int x, int y, int width, int height) { | 105 void SetRect(int x, int y, int width, int height) { |
| 87 origin_.SetPoint(x, y); | 106 origin_.SetPoint(x, y); |
| 88 size_.SetSize(width, height); | 107 // Ensure that width and height remain valid. |
| 108 set_width(width); |
| 109 set_height(height); |
| 89 } | 110 } |
| 90 | 111 |
| 91 // Shrink the rectangle by a horizontal and vertical distance on all sides. | 112 // Shrink the rectangle by a horizontal and vertical distance on all sides. |
| 92 void Inset(int horizontal, int vertical) { | 113 void Inset(int horizontal, int vertical) { |
| 93 Inset(horizontal, vertical, horizontal, vertical); | 114 Inset(horizontal, vertical, horizontal, vertical); |
| 94 } | 115 } |
| 95 | 116 |
| 96 // Shrink the rectangle by the given insets. | 117 // Shrink the rectangle by the given insets. |
| 97 void Inset(const Insets& insets); | 118 void Inset(const Insets& insets); |
| 98 | 119 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 // returns the smallest non-zero value appropriate for int. | 198 // returns the smallest non-zero value appropriate for int. |
| 178 int ManhattanInternalDistance(const Rect& rect) const; | 199 int ManhattanInternalDistance(const Rect& rect) const; |
| 179 | 200 |
| 180 std::string ToString() const; | 201 std::string ToString() const; |
| 181 | 202 |
| 182 bool ApproximatelyEqual(const Rect& rect, int tolerance) const; | 203 bool ApproximatelyEqual(const Rect& rect, int tolerance) const; |
| 183 | 204 |
| 184 private: | 205 private: |
| 185 gfx::Point origin_; | 206 gfx::Point origin_; |
| 186 gfx::Size size_; | 207 gfx::Size size_; |
| 208 |
| 209 // Clamp the size to avoid integer overflow in bottom() and right(). |
| 210 // There are three conditions to determine whether there is a potential |
| 211 // overflow: |
| 212 // 1) Origin > 0: if the origin is a negative value, origin + size will |
| 213 // definitely be less than int_max. |
| 214 // 2) size > 0: if size <= 0, it will be clamped to 0 making x + 0 valid for |
| 215 // all x. |
| 216 // 3) We cast the values to unsigned int because the compiler can optimize |
| 217 // this check away entirely but it is not smart enough to know that it |
| 218 // won't overflow. It can't overflow since origin is positive ensured by |
| 219 // part 1). If size > int_max - origin it will overflow when added to |
| 220 // origin. |
| 221 static constexpr int GetClampedValue(int origin, int size) { |
| 222 return origin > 0 && size > 0 && |
| 223 static_cast<unsigned>(std::numeric_limits<int>::max() - |
| 224 origin) < static_cast<unsigned>(size) |
| 225 ? std::numeric_limits<int>::max() - origin |
| 226 : size; |
| 227 } |
| 187 }; | 228 }; |
| 188 | 229 |
| 189 inline bool operator==(const Rect& lhs, const Rect& rhs) { | 230 inline bool operator==(const Rect& lhs, const Rect& rhs) { |
| 190 return lhs.origin() == rhs.origin() && lhs.size() == rhs.size(); | 231 return lhs.origin() == rhs.origin() && lhs.size() == rhs.size(); |
| 191 } | 232 } |
| 192 | 233 |
| 193 inline bool operator!=(const Rect& lhs, const Rect& rhs) { | 234 inline bool operator!=(const Rect& lhs, const Rect& rhs) { |
| 194 return !(lhs == rhs); | 235 return !(lhs == rhs); |
| 195 } | 236 } |
| 196 | 237 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 } | 311 } |
| 271 | 312 |
| 272 // This is declared here for use in gtest-based unit tests but is defined in | 313 // This is declared here for use in gtest-based unit tests but is defined in |
| 273 // the //ui/gfx:test_support target. Depend on that to use this in your unit | 314 // the //ui/gfx:test_support target. Depend on that to use this in your unit |
| 274 // test. This should not be used in production code - call ToString() instead. | 315 // test. This should not be used in production code - call ToString() instead. |
| 275 void PrintTo(const Rect& rect, ::std::ostream* os); | 316 void PrintTo(const Rect& rect, ::std::ostream* os); |
| 276 | 317 |
| 277 } // namespace gfx | 318 } // namespace gfx |
| 278 | 319 |
| 279 #endif // UI_GFX_GEOMETRY_RECT_H_ | 320 #endif // UI_GFX_GEOMETRY_RECT_H_ |
| OLD | NEW |