rect_conversions.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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
  3. // found in the LICENSE file.
  4. #include "ui/gfx/geometry/rect_conversions.h"
  5. #include <algorithm>
  6. #include <cmath>
  7. #include "base/check.h"
  8. #include "base/numerics/safe_conversions.h"
  9. namespace gfx {
  10. namespace {
  11. int FloorIgnoringError(float f, float error) {
  12. int rounded = base::ClampRound(f);
  13. return std::abs(rounded - f) < error ? rounded : base::ClampFloor(f);
  14. }
  15. int CeilIgnoringError(float f, float error) {
  16. int rounded = base::ClampRound(f);
  17. return std::abs(rounded - f) < error ? rounded : base::ClampCeil(f);
  18. }
  19. } // anonymous namespace
  20. Rect ToEnclosingRect(const RectF& r) {
  21. int left = base::ClampFloor(r.x());
  22. int right = r.width() ? base::ClampCeil(r.right()) : left;
  23. int top = base::ClampFloor(r.y());
  24. int bottom = r.height() ? base::ClampCeil(r.bottom()) : top;
  25. Rect result;
  26. result.SetByBounds(left, top, right, bottom);
  27. return result;
  28. }
  29. Rect ToEnclosingRectIgnoringError(const RectF& r, float error) {
  30. int left = FloorIgnoringError(r.x(), error);
  31. int right = r.width() ? CeilIgnoringError(r.right(), error) : left;
  32. int top = FloorIgnoringError(r.y(), error);
  33. int bottom = r.height() ? CeilIgnoringError(r.bottom(), error) : top;
  34. Rect result;
  35. result.SetByBounds(left, top, right, bottom);
  36. return result;
  37. }
  38. Rect ToEnclosedRect(const RectF& rect) {
  39. Rect result;
  40. result.SetByBounds(base::ClampCeil(rect.x()), base::ClampCeil(rect.y()),
  41. base::ClampFloor(rect.right()),
  42. base::ClampFloor(rect.bottom()));
  43. return result;
  44. }
  45. Rect ToEnclosedRectIgnoringError(const RectF& r, float error) {
  46. int left = CeilIgnoringError(r.x(), error);
  47. int right = r.width() ? FloorIgnoringError(r.right(), error) : left;
  48. int top = CeilIgnoringError(r.y(), error);
  49. int bottom = r.height() ? FloorIgnoringError(r.bottom(), error) : top;
  50. Rect result;
  51. result.SetByBounds(left, top, right, bottom);
  52. return result;
  53. }
  54. Rect ToNearestRect(const RectF& rect) {
  55. float float_min_x = rect.x();
  56. float float_min_y = rect.y();
  57. float float_max_x = rect.right();
  58. float float_max_y = rect.bottom();
  59. int min_x = base::ClampRound(float_min_x);
  60. int min_y = base::ClampRound(float_min_y);
  61. int max_x = base::ClampRound(float_max_x);
  62. int max_y = base::ClampRound(float_max_y);
  63. // If these DCHECKs fail, you're using the wrong method, consider using
  64. // ToEnclosingRect or ToEnclosedRect instead.
  65. DCHECK(std::abs(min_x - float_min_x) < 0.01f);
  66. DCHECK(std::abs(min_y - float_min_y) < 0.01f);
  67. DCHECK(std::abs(max_x - float_max_x) < 0.01f);
  68. DCHECK(std::abs(max_y - float_max_y) < 0.01f);
  69. Rect result;
  70. result.SetByBounds(min_x, min_y, max_x, max_y);
  71. return result;
  72. }
  73. bool IsNearestRectWithinDistance(const gfx::RectF& rect, float distance) {
  74. float float_min_x = rect.x();
  75. float float_min_y = rect.y();
  76. float float_max_x = rect.right();
  77. float float_max_y = rect.bottom();
  78. int min_x = base::ClampRound(float_min_x);
  79. int min_y = base::ClampRound(float_min_y);
  80. int max_x = base::ClampRound(float_max_x);
  81. int max_y = base::ClampRound(float_max_y);
  82. return (std::abs(min_x - float_min_x) < distance) &&
  83. (std::abs(min_y - float_min_y) < distance) &&
  84. (std::abs(max_x - float_max_x) < distance) &&
  85. (std::abs(max_y - float_max_y) < distance);
  86. }
  87. gfx::Rect ToRoundedRect(const gfx::RectF& rect) {
  88. int left = base::ClampRound(rect.x());
  89. int top = base::ClampRound(rect.y());
  90. int right = base::ClampRound(rect.right());
  91. int bottom = base::ClampRound(rect.bottom());
  92. gfx::Rect result;
  93. result.SetByBounds(left, top, right, bottom);
  94. return result;
  95. }
  96. Rect ToFlooredRectDeprecated(const RectF& rect) {
  97. return Rect(base::ClampFloor(rect.x()), base::ClampFloor(rect.y()),
  98. base::ClampFloor(rect.width()), base::ClampFloor(rect.height()));
  99. }
  100. } // namespace gfx