Rect.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #pragma once
  2. #include "Point.h"
  3. #include "Size.h"
  4. #include <AK/AKString.h>
  5. struct WSAPI_Rect;
  6. class Rect {
  7. public:
  8. Rect() { }
  9. Rect(int x, int y, int width, int height)
  10. : m_location(x, y)
  11. , m_size(width, height)
  12. {
  13. }
  14. Rect(const Point& location, const Size& size)
  15. : m_location(location)
  16. , m_size(size)
  17. {
  18. }
  19. Rect(const Rect& other)
  20. : m_location(other.m_location)
  21. , m_size(other.m_size)
  22. {
  23. }
  24. Rect(const WSAPI_Rect&);
  25. bool is_null() const
  26. {
  27. return width() == 0 && height() == 0;
  28. }
  29. bool is_empty() const
  30. {
  31. return width() <= 0 || height() <= 0;
  32. }
  33. void move_by(int dx, int dy)
  34. {
  35. m_location.move_by(dx, dy);
  36. }
  37. void move_by(const Point& delta)
  38. {
  39. m_location.move_by(delta);
  40. }
  41. Point center() const
  42. {
  43. return { x() + width() / 2, y() + height() / 2 };
  44. }
  45. void set_location(const Point& location)
  46. {
  47. m_location = location;
  48. }
  49. void set_size(const Size& size)
  50. {
  51. m_size = size;
  52. }
  53. void inflate(int w, int h)
  54. {
  55. set_x(x() - w / 2);
  56. set_width(width() + w);
  57. set_y(y() - h / 2);
  58. set_height(height() + h);
  59. }
  60. void shrink(int w, int h)
  61. {
  62. set_x(x() + w / 2);
  63. set_width(width() - w);
  64. set_y(y() + h / 2);
  65. set_height(height() - h);
  66. }
  67. Rect shrunken(int w, int h) const
  68. {
  69. Rect rect = *this;
  70. rect.shrink(w, h);
  71. return rect;
  72. }
  73. Rect inflated(int w, int h) const
  74. {
  75. Rect rect = *this;
  76. rect.inflate(w, h);
  77. return rect;
  78. }
  79. Rect translated(int dx, int dy) const
  80. {
  81. Rect rect = *this;
  82. rect.move_by(dx, dy);
  83. return rect;
  84. }
  85. Rect translated(const Point& delta) const
  86. {
  87. Rect rect = *this;
  88. rect.move_by(delta);
  89. return rect;
  90. }
  91. bool contains(int x, int y) const
  92. {
  93. return x >= m_location.x() && x <= right() && y >= m_location.y() && y <= bottom();
  94. }
  95. bool contains(const Point& point) const
  96. {
  97. return contains(point.x(), point.y());
  98. }
  99. bool contains(const Rect& other) const
  100. {
  101. return left() <= other.left()
  102. && right() >= other.right()
  103. && top() <= other.top()
  104. && bottom() >= other.bottom();
  105. }
  106. int left() const { return x(); }
  107. int right() const { return x() + width() - 1; }
  108. int top() const { return y(); }
  109. int bottom() const { return y() + height() - 1; }
  110. void set_left(int left)
  111. {
  112. set_x(left);
  113. }
  114. void set_top(int top)
  115. {
  116. set_y(top);
  117. }
  118. void set_right(int right)
  119. {
  120. set_width(right - x() + 1);
  121. }
  122. void set_bottom(int bottom)
  123. {
  124. set_height(bottom - y() + 1);
  125. }
  126. bool intersects(const Rect& other) const
  127. {
  128. return left() <= other.right()
  129. && other.left() <= right()
  130. && top() <= other.bottom()
  131. && other.top() <= bottom();
  132. }
  133. int x() const { return location().x(); }
  134. int y() const { return location().y(); }
  135. int width() const { return m_size.width(); }
  136. int height() const { return m_size.height(); }
  137. void set_x(int x) { m_location.set_x(x); }
  138. void set_y(int y) { m_location.set_y(y); }
  139. void set_width(int width) { m_size.set_width(width); }
  140. void set_height(int height) { m_size.set_height(height); }
  141. Point location() const { return m_location; }
  142. Size size() const { return m_size; }
  143. Vector<Rect> shatter(const Rect& hammer) const;
  144. operator WSAPI_Rect() const;
  145. bool operator==(const Rect& other) const
  146. {
  147. return m_location == other.m_location
  148. && m_size == other.m_size;
  149. }
  150. void intersect(const Rect&);
  151. static Rect intersection(const Rect& a, const Rect& b)
  152. {
  153. Rect r(a);
  154. r.intersect(b);
  155. return r;
  156. }
  157. Rect united(const Rect&) const;
  158. String to_string() const { return String::format("[%d,%d %dx%d]", x(), y(), width(), height()); }
  159. private:
  160. Point m_location;
  161. Size m_size;
  162. };
  163. inline void Point::constrain(const Rect& rect)
  164. {
  165. if (x() < rect.left())
  166. set_x(rect.left());
  167. else if (x() > rect.right())
  168. set_x(rect.right());
  169. if (y() < rect.top())
  170. set_y(rect.top());
  171. else if (y() > rect.bottom())
  172. set_y(rect.bottom());
  173. }