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
32namespace Common {
33
46template<typename T, typename ConcretePoint>
47struct 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 Common::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
145END_POINT_TYPE(int16, Point)
147 constexpr Point32(const Point &o) : PointBase(o.x, o.y) {}
148END_POINT_TYPE(int32, Point32)
149
150
168template<typename T, typename ConcreteRect, typename ConcretePoint>
169struct 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 extend(const ConcretePoint &p) {
327 left = MIN(left, p.x);
328 right = MAX(right, p.x);
329 top = MIN(top, p.y);
330 bottom = MAX(bottom, p.y);
331 }
332
338 void grow(T offset) {
339 top -= offset;
340 left -= offset;
341 bottom += offset;
342 right += offset;
343 }
344
348 void clip(const ConcreteRect &r) {
349 assert(isValidRect());
350 assert(r.isValidRect());
351
352 if (top < r.top) top = r.top;
353 else if (top > r.bottom) top = r.bottom;
354
355 if (left < r.left) left = r.left;
356 else if (left > r.right) left = r.right;
357
358 if (bottom > r.bottom) bottom = r.bottom;
359 else if (bottom < r.top) bottom = r.top;
360
361 if (right > r.right) right = r.right;
362 else if (right < r.left) right = r.left;
363 }
364
368 void clip(T maxw, T maxh) {
369 clip(ConcreteRect(0, 0, maxw, maxh));
370 }
371
375 void setEmpty() {
376 left = right = top = bottom = 0;
377 }
378
385 bool isEmpty() const {
386 return (left >= right || top >= bottom);
387 }
388
392 bool isValidRect() const {
393 return (left <= right && top <= bottom);
394 }
395
399 void moveTo(T x, T y) {
400 bottom += y - top;
401 right += x - left;
402 top = y;
403 left = x;
404 }
405
409 void translate(T dx, T dy) {
410 left += dx; right += dx;
411 top += dy; bottom += dy;
412 }
413
417 void moveTo(const ConcretePoint &p) {
418 moveTo(p.x, p.y);
419 }
420
426 bool constrain(const ConcreteRect &o) {
427 return o.constrain(left, top, width(), height());
428 }
429
435 bool constrain(T &x, T &y, T w, T h) const {
436 if (w > width() || h > height()) {
437 return false;
438 }
439
440 if (x < left) {
441 x = left;
442 } else if (x > right - w) { // x + w > right
443 x = right - w;
444 }
445 if (y < top) {
446 y = top;
447 } else if (y > bottom - h) { // y + h > bottom
448 y = bottom - h;
449 }
450
451 return true;
452 }
453
457 void debugPrint(int debuglevel = 0, const char *caption = "Rect:") const {
458 debug(debuglevel, "%s %d, %d, %d, %d", caption, left, top, right, bottom);
459 }
460
464 void debugPrintC(int debuglevel, uint32 debugChannel, const char *caption = "Rect:") const {
465 debugC(debuglevel, debugChannel, "%s %d, %d, %d, %d", caption, left, top, right, bottom);
466 }
467
471 String toString() const {
472 return String::format("%d, %d, %d, %d", left, top, right, bottom);
473 }
474
479 static ConcreteRect center(T cx, T cy, T w, T h) {
480 T x = cx - w / 2, y = cy - h / 2;
481 return ConcreteRect(x, y, x + w, y + h);
482 }
483
488 ConcretePoint center() const {
489 return ConcretePoint((left + right) / 2, (bottom + top) / 2);
490 }
491
500 static bool getBlitRect(ConcretePoint &dst, ConcreteRect &rect, const ConcreteRect &clip) {
501 if (dst.x < clip.left) {
502 rect.left += clip.left - dst.x;
503 dst.x = clip.left;
504 }
505
506 if (dst.y < clip.top) {
507 rect.top += clip.top - dst.y;
508 dst.y = clip.top;
509 }
510
511 int right = dst.x + rect.width();
512 if (right > clip.right)
513 rect.right -= right - clip.right;
514
515 int bottom = dst.y + rect.height();
516 if (bottom > clip.bottom)
517 rect.bottom -= bottom - clip.bottom;
518 return !rect.isEmpty();
519 }
520};
521
525#define BEGIN_RECT_TYPE(T, Rect, Point) \
526 struct Rect : public Common::RectBase<T, Rect, Point> {
527
528#define END_RECT_TYPE(T, Rect, Point) \
529 constexpr Rect() : RectBase() {} \
530 constexpr Rect(T w, T h) : RectBase(w, h) {} \
531 Rect(const Point &topLeft, const Point &bottomRight) : RectBase(topLeft, bottomRight) {} \
532 constexpr Rect(const Point &topLeft, T w, T h) : RectBase(topLeft, w, h) {} \
533 Rect(T x1, T y1, T x2, T y2) : RectBase(x1, y1, x2, y2) {} \
534 };
535
537END_RECT_TYPE(int16, Rect, Point)
539END_RECT_TYPE(int32, Rect32, Point32)
542} // End of namespace Common
543
544#endif
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
void void void void void debugC(int level, uint32 debugChannel, MSVC_PRINTF const char *s,...) GCC_PRINTF(3
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
#define BEGIN_RECT_TYPE(T, Rect, Point)
Definition: rect.h:525
#define BEGIN_POINT_TYPE(T, Point)
Definition: rect.h:135
T ABS(T x)
Definition: util.h:60
T MIN(T a, T b)
Definition: util.h:63
T MAX(T a, T b)
Definition: util.h:66
Definition: algorithm.h:29
Definition: rect.h:146
Definition: rect.h:47
ConcretePoint operator*(double multiplier) const
Definition: rect.h:88
void operator-=(const ConcretePoint &delta)
Definition: rect.h:101
uint sqrDist(const ConcretePoint &p) const
Definition: rect.h:112
String toString() const
Definition: rect.h:127
ConcretePoint operator-(const ConcretePoint &delta) const
Definition: rect.h:72
ConcretePoint operator+(const ConcretePoint &delta) const
Definition: rect.h:68
ConcretePoint operator/(double divisor) const
Definition: rect.h:84
ConcretePoint operator/(int divisor) const
Definition: rect.h:76
bool operator==(const ConcretePoint &p) const
Definition: rect.h:60
ConcretePoint operator*(int multiplier) const
Definition: rect.h:80
constexpr PointBase(T x1, T y1)
Definition: rect.h:56
void operator+=(const ConcretePoint &delta)
Definition: rect.h:93
T y
Definition: rect.h:49
T x
Definition: rect.h:48
bool operator!=(const ConcretePoint &p) const
Definition: rect.h:64
Definition: rect.h:144
Definition: rect.h:538
Definition: rect.h:169
bool constrain(T &x, T &y, T w, T h) const
Definition: rect.h:435
bool constrain(const ConcreteRect &o)
Definition: rect.h:426
bool equals(const ConcreteRect &r) const
Definition: rect.h:279
ConcreteRect findIntersectingRect(const ConcreteRect &r) const
Definition: rect.h:302
void setHeight(T aHeight)
Definition: rect.h:224
T right
Definition: rect.h:171
bool contains(const ConcretePoint &p) const
Definition: rect.h:257
constexpr RectBase(const ConcretePoint &topLeft, T w, T h)
Definition: rect.h:192
bool operator!=(const ConcreteRect &rhs) const
Definition: rect.h:214
bool contains(const ConcreteRect &r) const
Definition: rect.h:268
static ConcreteRect center(T cx, T cy, T w, T h)
Definition: rect.h:479
void moveTo(T x, T y)
Definition: rect.h:399
ConcretePoint origin() const
Definition: rect.h:216
void debugPrint(int debuglevel=0, const char *caption="Rect:") const
Definition: rect.h:457
bool intersects(const ConcreteRect &r) const
Definition: rect.h:291
void extend(const ConcreteRect &r)
Definition: rect.h:314
void translate(T dx, T dy)
Definition: rect.h:409
void debugPrintC(int debuglevel, uint32 debugChannel, const char *caption="Rect:") const
Definition: rect.h:464
bool operator==(const ConcreteRect &rhs) const
Definition: rect.h:208
bool isEmpty() const
Definition: rect.h:385
void moveTo(const ConcretePoint &p)
Definition: rect.h:417
void setEmpty()
Definition: rect.h:375
T height() const
Definition: rect.h:218
bool isValidRect() const
Definition: rect.h:392
constexpr RectBase(T w, T h)
Definition: rect.h:177
T left
Definition: rect.h:170
RectBase(const ConcretePoint &topLeft, const ConcretePoint &bottomRight)
Definition: rect.h:185
void grow(T offset)
Definition: rect.h:338
void clip(T maxw, T maxh)
Definition: rect.h:368
bool contains(T x, T y) const
Definition: rect.h:246
static bool getBlitRect(ConcretePoint &dst, ConcreteRect &rect, const ConcreteRect &clip)
Definition: rect.h:500
RectBase(T x1, T y1, T x2, T y2)
Definition: rect.h:200
void clip(const ConcreteRect &r)
Definition: rect.h:348
T width() const
Definition: rect.h:217
void setRect(T newLeft, T newTop, T newRight, T newBottom)
Definition: rect.h:231
void setWidth(T aWidth)
Definition: rect.h:220
String toString() const
Definition: rect.h:471
ConcretePoint center() const
Definition: rect.h:488
void extend(const ConcretePoint &p)
Definition: rect.h:326
Definition: rect.h:536