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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 int ManhattanInternalDistance(const Rect& rect) const; | 199 int ManhattanInternalDistance(const Rect& rect) const; |
200 | 200 |
201 std::string ToString() const; | 201 std::string ToString() const; |
202 | 202 |
203 bool ApproximatelyEqual(const Rect& rect, int tolerance) const; | 203 bool ApproximatelyEqual(const Rect& rect, int tolerance) const; |
204 | 204 |
205 private: | 205 private: |
206 gfx::Point origin_; | 206 gfx::Point origin_; |
207 gfx::Size size_; | 207 gfx::Size size_; |
208 | 208 |
209 static constexpr bool AddWouldOverflow(int a, int b) { | |
210 return a > 0 && b > std::numeric_limits<int>::max() - a; | |
enne (OOO)
2016/09/21 00:48:24
danakj: I feel like these are things I'd want to u
| |
211 } | |
212 static constexpr bool AddWouldUnderflow(int a, int b) { | |
213 return a < 0 && b < std::numeric_limits<int>::min() - a; | |
214 } | |
215 static constexpr bool SubtractWouldOverflow(int a, int b) { | |
216 return b < 0 && a > std::numeric_limits<int>::max() + b; | |
217 } | |
218 static constexpr bool SubtractWouldUnderflow(int a, int b) { | |
219 return b > 0 && a < std::numeric_limits<int>::min() + b; | |
220 } | |
221 | |
222 static constexpr int SafeAdd(int a, int b) { | |
223 return AddWouldOverflow(a, b) | |
224 ? std::numeric_limits<int>::max() | |
225 : AddWouldUnderflow(a, b) ? std::numeric_limits<int>::min() | |
226 : a + b; | |
227 } | |
228 static constexpr int SafeSubtract(int a, int b) { | |
229 return SubtractWouldOverflow(a, b) | |
230 ? std::numeric_limits<int>::max() | |
231 : SubtractWouldUnderflow(a, b) ? std::numeric_limits<int>::min() | |
232 : a - b; | |
233 } | |
234 | |
209 // Clamp the size to avoid integer overflow in bottom() and right(). | 235 // Clamp the size to avoid integer overflow in bottom() and right(). |
210 // There are three conditions to determine whether there is a potential | 236 // This returns the width given an origin and a width. |
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) { | 237 static constexpr int GetClampedValue(int origin, int size) { |
222 return origin > 0 && size > 0 && | 238 return AddWouldOverflow(origin, size) |
223 static_cast<unsigned>(std::numeric_limits<int>::max() - | |
224 origin) < static_cast<unsigned>(size) | |
225 ? std::numeric_limits<int>::max() - origin | 239 ? std::numeric_limits<int>::max() - origin |
226 : size; | 240 : size; |
227 } | 241 } |
242 | |
243 // Returns a clamped width given a right and a left, assuming right > left. | |
244 static constexpr int GetClampedWidthFromExtents(int left, int right) { | |
245 return SubtractWouldOverflow(right, left) ? std::numeric_limits<int>::max() | |
246 : right - left; | |
247 } | |
228 }; | 248 }; |
229 | 249 |
230 inline bool operator==(const Rect& lhs, const Rect& rhs) { | 250 inline bool operator==(const Rect& lhs, const Rect& rhs) { |
231 return lhs.origin() == rhs.origin() && lhs.size() == rhs.size(); | 251 return lhs.origin() == rhs.origin() && lhs.size() == rhs.size(); |
232 } | 252 } |
233 | 253 |
234 inline bool operator!=(const Rect& lhs, const Rect& rhs) { | 254 inline bool operator!=(const Rect& lhs, const Rect& rhs) { |
235 return !(lhs == rhs); | 255 return !(lhs == rhs); |
236 } | 256 } |
237 | 257 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 } | 331 } |
312 | 332 |
313 // This is declared here for use in gtest-based unit tests but is defined in | 333 // This is declared here for use in gtest-based unit tests but is defined in |
314 // the //ui/gfx:test_support target. Depend on that to use this in your unit | 334 // the //ui/gfx:test_support target. Depend on that to use this in your unit |
315 // test. This should not be used in production code - call ToString() instead. | 335 // test. This should not be used in production code - call ToString() instead. |
316 void PrintTo(const Rect& rect, ::std::ostream* os); | 336 void PrintTo(const Rect& rect, ::std::ostream* os); |
317 | 337 |
318 } // namespace gfx | 338 } // namespace gfx |
319 | 339 |
320 #endif // UI_GFX_GEOMETRY_RECT_H_ | 340 #endif // UI_GFX_GEOMETRY_RECT_H_ |
OLD | NEW |