1// SuperTux
2// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmail.com>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#ifndef HEADER_SUPERTUX_MATH_RECT_HPP
18#define HEADER_SUPERTUX_MATH_RECT_HPP
19
20#include <iosfwd>
21
22#include <algorithm>
23#include <tuple>
24#include <SDL.h>
25
26#include "math/size.hpp"
27
28class Rectf;
29
30class Rect final
31{
32public:
33 int left;
34 int top;
35 int right;
36 int bottom;
37
38public:
39 static Rect from_center(int center_x, int center_y, int width, int height)
40 {
41 return Rect(center_x - width / 2,
42 center_y - height / 2,
43 center_x + width / 2,
44 center_y + height / 2);
45 }
46
47public:
48 Rect() :
49 left(0),
50 top(0),
51 right(0),
52 bottom(0)
53 {}
54
55 Rect(const Rect& rhs) = default;
56 Rect& operator=(const Rect& rhs) = default;
57
58 Rect(int left_, int top_, int right_, int bottom_) :
59 left(left_),
60 top(top_),
61 right(right_),
62 bottom(bottom_)
63 {}
64
65 Rect(int left_, int top_, const Size& size) :
66 left(left_),
67 top(top_),
68 right(left_ + size.width),
69 bottom(top_ + size.height)
70 {}
71
72 Rect(const SDL_Rect& rect) :
73 left(rect.x),
74 top(rect.y),
75 right(rect.x + rect.w),
76 bottom(rect.y + rect.h)
77 {}
78
79 explicit Rect(const Rectf& other);
80
81 bool operator==(const Rect& other) const
82 {
83 return (left == other.left &&
84 top == other.top &&
85 right == other.right &&
86 bottom == other.bottom);
87 }
88
89 bool contains(int x, int y) const
90 {
91 return (left <= x && x < right &&
92 top <= y && y < bottom);
93 }
94
95 bool contains(const Rect& other) const
96 {
97 return (left <= other.left && other.right <= right &&
98 top <= other.top && other.bottom <= bottom);
99 }
100
101 int get_width() const { return right - left; }
102 int get_height() const { return bottom - top; }
103 Size get_size() const { return Size(right - left, bottom - top); }
104 int get_area() const { return get_width() * get_height(); }
105
106 bool empty() const
107 {
108 return (get_width() <= 0 ||
109 get_height() <= 0);
110 }
111
112 bool valid() const
113 {
114 return left <= right && top <= bottom;
115 }
116
117 Rect normalized() const
118 {
119 return Rect(std::min(left, right),
120 std::min(top, bottom),
121 std::max(left, right),
122 std::max(top, bottom));
123 }
124
125 Rect moved(int x, int y) const
126 {
127 return Rect(left + x,
128 top + y,
129 right + x,
130 bottom + y);
131 }
132
133 Rect grown(int border) const
134 {
135 return Rect(left - border,
136 top - border,
137 right + border,
138 bottom + border);
139 }
140
141 SDL_Rect to_sdl() const
142 {
143 return {left, top, get_width(), get_height()};
144 }
145
146 bool operator<(const Rect& other) const {
147 return std::tie(left, top, right, bottom) < std::tie(other.left, other.top, other.right, other.bottom);
148 }
149};
150
151std::ostream& operator<<(std::ostream& out, const Rect& rect);
152
153#endif
154
155/* EOF */
156