ScummVM API documentation
rect.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef COMMON_RECT_H
23 #define COMMON_RECT_H
24 
25 #include "common/scummsys.h"
26 #include "common/util.h"
27 #include "common/debug.h"
28 #include "common/str.h"
29 
30 #define PRINT_RECT(x) (x).left,(x).top,(x).right,(x).bottom
31 
32 namespace Common {
33 
46 template<typename T, typename ConcretePoint>
47 struct PointBase {
48  T x;
49  T y;
51  constexpr PointBase() : x(0), y(0) {}
52 
56  constexpr PointBase(T x1, T y1) : x(x1), y(y1) {}
60  bool operator==(const ConcretePoint &p) const { return x == p.x && y == p.y; }
64  bool operator!=(const ConcretePoint &p) const { return x != p.x || y != p.y; }
68  ConcretePoint operator+(const ConcretePoint &delta) const { return ConcretePoint(x + delta.x, y + delta.y); }
72  ConcretePoint operator-(const ConcretePoint &delta) const { return ConcretePoint(x - delta.x, y - delta.y); }
76  ConcretePoint operator/(int divisor) const { return ConcretePoint(x / divisor, y / divisor); }
80  ConcretePoint operator*(int multiplier) const { return ConcretePoint(x * multiplier, y * multiplier); }
84  ConcretePoint operator/(double divisor) const { return ConcretePoint((T)(x / divisor), (T)(y / divisor)); }
88  ConcretePoint operator*(double multiplier) const { return ConcretePoint((T)(x * multiplier), (T)(y * multiplier)); }
89 
93  void operator+=(const ConcretePoint &delta) {
94  x += delta.x;
95  y += delta.y;
96  }
97 
101  void operator-=(const ConcretePoint &delta) {
102  x -= delta.x;
103  y -= delta.y;
104  }
105 
112  uint sqrDist(const ConcretePoint &p) const {
113  int diffx = ABS(p.x - x);
114  if (diffx >= 0x1000)
115  return 0xFFFFFF;
116 
117  int diffy = ABS(p.y - y);
118  if (diffy >= 0x1000)
119  return 0xFFFFFF;
120 
121  return uint(diffx * diffx + diffy * diffy);
122  }
123 
127  String toString() const {
128  return String::format("%d, %d", x, y);
129  }
130 };
131 
135 #define BEGIN_POINT_TYPE(T, Point) \
136  struct Point : public PointBase<T, Point> {
137 #define END_POINT_TYPE(T, Point) \
138  constexpr Point() : PointBase() {} \
139  constexpr Point(T x1, T y1) : PointBase(x1, y1) {} \
140  }; \
141  static inline Point operator*(int multiplier, const Point &p) { return Point(p.x * multiplier, p.y * multiplier); } \
142  static inline Point operator*(double multiplier, const Point &p) { return Point((T)(p.x * multiplier), (T)(p.y * multiplier)); }
143 
145 END_POINT_TYPE(int16, Point)
147  constexpr Point32(const Point &o) : PointBase(o.x, o.y) {}
148 END_POINT_TYPE(int32, Point32)
149 
150 
168 template<typename T, typename ConcreteRect, typename ConcretePoint>
169 struct RectBase {
170  T top, left;
171  T bottom, right;
173  constexpr RectBase() : top(0), left(0), bottom(0), right(0) {}
177  constexpr RectBase(T w, T h) : top(0), left(0), bottom(h), right(w) {}
185  RectBase(const ConcretePoint &topLeft, const ConcretePoint &bottomRight) : top(topLeft.y), left(topLeft.x), bottom(bottomRight.y), right(bottomRight.x) {
186  assert(isValidRect());
187  }
192  constexpr RectBase(const ConcretePoint &topLeft, T w, T h) : top(topLeft.y), left(topLeft.x), bottom(topLeft.y + h), right(topLeft.x + w) {
193  }
200  RectBase(T x1, T y1, T x2, T y2) : top(y1), left(x1), bottom(y2), right(x2) {
201  assert(isValidRect());
202  }
208  bool operator==(const ConcreteRect &rhs) const { return equals(rhs); }
214  bool operator!=(const ConcreteRect &rhs) const { return !equals(rhs); }
215 
216  ConcretePoint origin() const { return ConcretePoint(left, top); }
217  T width() const { return right - left; }
218  T height() const { return bottom - top; }
220  void setWidth(T aWidth) {
221  right = left + aWidth;
222  }
223 
224  void setHeight(T aHeight) {
225  bottom = top + aHeight;
226  }
227 
231  void setRect(T newLeft, T newTop, T newRight, T newBottom) {
232  left = newLeft;
233  top = newTop;
234  right = newRight;
235  bottom = newBottom;
236  }
237 
246  bool contains(T x, T y) const {
247  return (left <= x) && (x < right) && (top <= y) && (y < bottom);
248  }
249 
257  bool contains(const ConcretePoint &p) const {
258  return contains(p.x, p.y);
259  }
260 
268  bool contains(const ConcreteRect &r) const {
269  return (left <= r.left) && (r.right <= right) && (top <= r.top) && (r.bottom <= bottom);
270  }
271 
279  bool equals(const ConcreteRect &r) const {
280  return (left == r.left) && (right == r.right) && (top == r.top) && (bottom == r.bottom);
281  }
282 
291  bool intersects(const ConcreteRect &r) const {
292  return (left < r.right) && (r.left < right) && (top < r.bottom) && (r.top < bottom);
293  }
294 
302  ConcreteRect findIntersectingRect(const ConcreteRect &r) const {
303  if (!intersects(r))
304  return ConcreteRect();
305 
306  return ConcreteRect(MAX(r.left, left), MAX(r.top, top), MIN(r.right, right), MIN(r.bottom, bottom));
307  }
308 
314  void extend(const ConcreteRect &r) {
315  left = MIN(left, r.left);
316  right = MAX(right, r.right);
317  top = MIN(top, r.top);
318  bottom = MAX(bottom, r.bottom);
319  }
320 
326  void grow(T offset) {
327  top -= offset;
328  left -= offset;
329  bottom += offset;
330  right += offset;
331  }
332 
336  void clip(const ConcreteRect &r) {
337  assert(isValidRect());
338  assert(r.isValidRect());
339 
340  if (top < r.top) top = r.top;
341  else if (top > r.bottom) top = r.bottom;
342 
343  if (left < r.left) left = r.left;
344  else if (left > r.right) left = r.right;
345 
346  if (bottom > r.bottom) bottom = r.bottom;
347  else if (bottom < r.top) bottom = r.top;
348 
349  if (right > r.right) right = r.right;
350  else if (right < r.left) right = r.left;
351  }
352 
356  void clip(T maxw, T maxh) {
357  clip(ConcreteRect(0, 0, maxw, maxh));
358  }
359 
363  void setEmpty() {
364  left = right = top = bottom = 0;
365  }
366 
373  bool isEmpty() const {
374  return (left >= right || top >= bottom);
375  }
376 
380  bool isValidRect() const {
381  return (left <= right && top <= bottom);
382  }
383 
387  void moveTo(T x, T y) {
388  bottom += y - top;
389  right += x - left;
390  top = y;
391  left = x;
392  }
393 
397  void translate(T dx, T dy) {
398  left += dx; right += dx;
399  top += dy; bottom += dy;
400  }
401 
405  void moveTo(const ConcretePoint &p) {
406  moveTo(p.x, p.y);
407  }
408 
414  bool constrain(const ConcreteRect &o) {
415  return o.constrain(left, top, width(), height());
416  }
417 
423  bool constrain(T &x, T &y, T w, T h) const {
424  if (w > width() || h > height()) {
425  return false;
426  }
427 
428  if (x < left) {
429  x = left;
430  } else if (x > right - w) { // x + w > right
431  x = right - w;
432  }
433  if (y < top) {
434  y = top;
435  } else if (y > bottom - h) { // y + h > bottom
436  y = bottom - h;
437  }
438 
439  return true;
440  }
441 
445  void debugPrint(int debuglevel = 0, const char *caption = "Rect:") const {
446  debug(debuglevel, "%s %d, %d, %d, %d", caption, left, top, right, bottom);
447  }
448 
452  void debugPrintC(int debuglevel, uint32 debugChannel, const char *caption = "Rect:") const {
453  debugC(debuglevel, debugChannel, "%s %d, %d, %d, %d", caption, left, top, right, bottom);
454  }
455 
459  String toString() const {
460  return String::format("%d, %d, %d, %d", left, top, right, bottom);
461  }
462 
467  static ConcreteRect center(T cx, T cy, T w, T h) {
468  T x = cx - w / 2, y = cy - h / 2;
469  return ConcreteRect(x, y, x + w, y + h);
470  }
471 
476  ConcretePoint center() const {
477  return ConcretePoint((left + right) / 2, (bottom + top) / 2);
478  }
479 
488  static bool getBlitRect(ConcretePoint &dst, ConcreteRect &rect, const ConcreteRect &clip) {
489  if (dst.x < clip.left) {
490  rect.left += clip.left - dst.x;
491  dst.x = clip.left;
492  }
493 
494  if (dst.y < clip.top) {
495  rect.top += clip.top - dst.y;
496  dst.y = clip.top;
497  }
498 
499  int right = dst.x + rect.right;
500  if (right > clip.right)
501  rect.right -= right - clip.right;
502 
503  int bottom = dst.y + rect.bottom;
504  if (bottom > clip.bottom)
505  rect.bottom -= bottom - clip.bottom;
506  return !rect.isEmpty();
507  }
508 };
509 
513 #define BEGIN_RECT_TYPE(T, Rect, Point) \
514  struct Rect : public RectBase<T, Rect, Point> {
515 
516 #define END_RECT_TYPE(T, Rect, Point) \
517  constexpr Rect() : RectBase() {} \
518  constexpr Rect(T w, T h) : RectBase(w, h) {} \
519  Rect(const Point &topLeft, const Point &bottomRight) : RectBase(topLeft, bottomRight) {} \
520  constexpr Rect(const Point &topLeft, T w, T h) : RectBase(topLeft, w, h) {} \
521  Rect(T x1, T y1, T x2, T y2) : RectBase(x1, y1, x2, y2) {} \
522  };
523 
525 END_RECT_TYPE(int16, Rect, Point)
527 END_RECT_TYPE(int32, Rect32, Point32)
530 } // End of namespace Common
531 
532 #endif
ConcretePoint operator*(int multiplier) const
Definition: rect.h:80
constexpr RectBase(const ConcretePoint &topLeft, T w, T h)
Definition: rect.h:192
void debugPrint(int debuglevel=0, const char *caption="Rect:") const
Definition: rect.h:445
Definition: rect.h:526
Definition: str.h:59
ConcretePoint origin() const
Definition: rect.h:216
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
#define BEGIN_RECT_TYPE(T, Rect, Point)
Definition: rect.h:513
T left
Definition: rect.h:170
bool operator==(const ConcretePoint &p) const
Definition: rect.h:60
ConcretePoint center() const
Definition: rect.h:476
String toString() const
Definition: rect.h:459
void grow(T offset)
Definition: rect.h:326
void translate(T dx, T dy)
Definition: rect.h:397
ConcreteRect findIntersectingRect(const ConcreteRect &r) const
Definition: rect.h:302
Definition: rect.h:524
static bool getBlitRect(ConcretePoint &dst, ConcreteRect &rect, const ConcreteRect &clip)
Definition: rect.h:488
void setHeight(T aHeight)
Definition: rect.h:224
Definition: rect.h:47
void setWidth(T aWidth)
Definition: rect.h:220
bool intersects(const ConcreteRect &r) const
Definition: rect.h:291
T width() const
Definition: rect.h:217
void void void void void debugC(int level, uint32 debugChannel, MSVC_PRINTF const char *s,...) GCC_PRINTF(3
void moveTo(const ConcretePoint &p)
Definition: rect.h:405
ConcretePoint operator/(int divisor) const
Definition: rect.h:76
void operator+=(const ConcretePoint &delta)
Definition: rect.h:93
bool operator==(const ConcreteRect &rhs) const
Definition: rect.h:208
constexpr PointBase(T x1, T y1)
Definition: rect.h:56
String toString() const
Definition: rect.h:127
RectBase(T x1, T y1, T x2, T y2)
Definition: rect.h:200
bool operator!=(const ConcreteRect &rhs) const
Definition: rect.h:214
Definition: rect.h:169
T height() const
Definition: rect.h:218
ConcretePoint operator+(const ConcretePoint &delta) const
Definition: rect.h:68
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
T right
Definition: rect.h:171
void clip(const ConcreteRect &r)
Definition: rect.h:336
uint sqrDist(const ConcretePoint &p) const
Definition: rect.h:112
T y
Definition: rect.h:49
ConcretePoint operator-(const ConcretePoint &delta) const
Definition: rect.h:72
Definition: algorithm.h:29
T x
Definition: rect.h:48
bool isEmpty() const
Definition: rect.h:373
Definition: rect.h:144
bool equals(const ConcreteRect &r) const
Definition: rect.h:279
Definition: rect.h:146
void setRect(T newLeft, T newTop, T newRight, T newBottom)
Definition: rect.h:231
bool contains(const ConcreteRect &r) const
Definition: rect.h:268
bool contains(T x, T y) const
Definition: rect.h:246
#define BEGIN_POINT_TYPE(T, Point)
Definition: rect.h:135
RectBase(const ConcretePoint &topLeft, const ConcretePoint &bottomRight)
Definition: rect.h:185
ConcretePoint operator*(double multiplier) const
Definition: rect.h:88
bool contains(const ConcretePoint &p) const
Definition: rect.h:257
T MIN(T a, T b)
Definition: util.h:61
T MAX(T a, T b)
Definition: util.h:64
bool constrain(const ConcreteRect &o)
Definition: rect.h:414
void debugPrintC(int debuglevel, uint32 debugChannel, const char *caption="Rect:") const
Definition: rect.h:452
void extend(const ConcreteRect &r)
Definition: rect.h:314
T ABS(T x)
Definition: util.h:58
bool operator!=(const ConcretePoint &p) const
Definition: rect.h:64
bool constrain(T &x, T &y, T w, T h) const
Definition: rect.h:423
ConcretePoint operator/(double divisor) const
Definition: rect.h:84
constexpr RectBase(T w, T h)
Definition: rect.h:177
bool isValidRect() const
Definition: rect.h:380
static ConcreteRect center(T cx, T cy, T w, T h)
Definition: rect.h:467
void operator-=(const ConcretePoint &delta)
Definition: rect.h:101
void setEmpty()
Definition: rect.h:363
void moveTo(T x, T y)
Definition: rect.h:387
void clip(T maxw, T maxh)
Definition: rect.h:356