Index: ui/gfx/geometry/rect.h |
diff --git a/ui/gfx/geometry/rect.h b/ui/gfx/geometry/rect.h |
index fed202d2bd30b769f91ee041c70224f618495010..3161376d8a4e854acad207ff3b047f29cf3fbed4 100644 |
--- a/ui/gfx/geometry/rect.h |
+++ b/ui/gfx/geometry/rect.h |
@@ -16,8 +16,10 @@ |
#include <iosfwd> |
#include <string> |
+#include "base/numerics/safe_conversions.h" |
#include "ui/gfx/geometry/point.h" |
#include "ui/gfx/geometry/rect_f.h" |
+#include "ui/gfx/geometry/safe_integer_conversions.h" |
danakj
2014/11/03 20:35:26
unused?
Peter Kasting
2014/11/03 22:19:55
Oops, thanks.
|
#include "ui/gfx/geometry/size.h" |
#include "ui/gfx/geometry/vector2d.h" |
@@ -59,7 +61,8 @@ class GFX_EXPORT Rect { |
#endif |
operator RectF() const { |
- return RectF(origin().x(), origin().y(), size().width(), size().height()); |
+ return RectF(static_cast<float>(x()), static_cast<float>(y()), |
+ static_cast<float>(width()), static_cast<float>(height())); |
} |
int x() const { return origin_.x(); } |
@@ -220,10 +223,31 @@ GFX_EXPORT Rect BoundingRect(const Point& p1, const Point& p2); |
inline Rect ScaleToEnclosingRect(const Rect& rect, |
float x_scale, |
float y_scale) { |
- int x = std::floor(rect.x() * x_scale); |
- int y = std::floor(rect.y() * y_scale); |
- int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale); |
- int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale); |
+ // These next functions cast instead of using e.g. ToFlooredInt() because we |
+ // haven't checked to ensure that the clamping behavior of the helper |
+ // functions doesn't degrade performance, and callers shouldn't be passing |
+ // values that cause overflow anyway. |
+ float scaled_x = std::floor(rect.x() * x_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_x)); |
danakj
2014/11/03 20:35:26
nit: it might be easier to read if you just moved
Peter Kasting
2014/11/03 22:19:55
Done.
|
+ int x = static_cast<int>(scaled_x); |
+ float scaled_y = std::floor(rect.y() * y_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_y)); |
+ int y = static_cast<int>(scaled_y); |
+ int r, b; |
+ if (rect.width() == 0) { |
+ r = x; |
+ } else { |
+ float scaled_r = std::ceil(rect.right() * x_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_r)); |
+ r = static_cast<int>(scaled_r); |
+ } |
+ if (rect.height() == 0) { |
+ b = y; |
+ } else { |
+ float scaled_b = std::ceil(rect.bottom() * y_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_b)); |
+ b = static_cast<int>(scaled_b); |
+ } |
return Rect(x, y, r - x, b - y); |
} |
@@ -234,10 +258,27 @@ inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) { |
inline Rect ScaleToEnclosedRect(const Rect& rect, |
float x_scale, |
float y_scale) { |
- int x = std::ceil(rect.x() * x_scale); |
- int y = std::ceil(rect.y() * y_scale); |
- int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale); |
- int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale); |
+ float scaled_x = std::ceil(rect.x() * x_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_x)); |
+ int x = static_cast<int>(scaled_x); |
+ float scaled_y = std::ceil(rect.y() * y_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_y)); |
+ int y = static_cast<int>(scaled_y); |
+ int r, b; |
+ if (rect.width() == 0) { |
+ r = x; |
+ } else { |
+ float scaled_r = std::floor(rect.right() * x_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_r)); |
+ r = static_cast<int>(scaled_r); |
+ } |
+ if (rect.height() == 0) { |
+ b = y; |
+ } else { |
+ float scaled_b = std::floor(rect.bottom() * y_scale); |
+ DCHECK(base::IsValueInRangeForNumericType<int>(scaled_b)); |
+ b = static_cast<int>(scaled_b); |
+ } |
return Rect(x, y, r - x, b - y); |
} |