Chromium Code Reviews| 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); |
| } |