Otclient  14/8/2020
rect.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef RECT_H
24 #define RECT_H
25 
26 #include "../stdext/types.h"
27 #include "../const.h"
28 #include <sstream>
29 
30 template<class T>
31 class TPoint;
32 
33 template<class T>
34 class TSize;
35 
36 template<class T>
37 class TRect
38 {
39 public:
40  TRect() : x1(0), y1(0), x2(-1), y2(-1) { }
41  TRect(T x, T y, T width, T height) : x1(x), y1(y), x2(x+width-1), y2(y+height-1) { }
42  TRect(const TPoint<T>& topLeft, const TPoint<T>& bottomRight) : x1(topLeft.x), y1(topLeft.y), x2(bottomRight.x), y2(bottomRight.y) { }
43  TRect(const TRect<T>& other) : x1(other.x1), y1(other.y1), x2(other.x2), y2(other.y2) { }
44  TRect(T x, T y, const TSize<T>& size) : x1(x), y1(y), x2(x+size.width()-1), y2(y+size.height()-1) { }
45  TRect(const TPoint<T>& topLeft, const TSize<T>& size) : x1(topLeft.x), y1(topLeft.y), x2(x1+size.width()-1), y2(y1+size.height()-1) { }
46  TRect(const TPoint<T>& topLeft, int width, int height) : x1(topLeft.x), y1(topLeft.y), x2(x1+width-1), y2(y1+height-1) { }
47 
48  bool isNull() const { return x2 == x1 - 1 && y2 == y1 - 1; }
49  bool isEmpty() const { return x1 > x2 || y1 > y2; }
50  bool isValid() const { return x1 <= x2 && y1 <= y2; }
51 
52  T left() const { return x1; }
53  T top() const { return y1; }
54  T right() const { return x2; }
55  T bottom() const { return y2; }
56  T horizontalCenter() const { return x1 + (x2 - x1)/2; }
57  T verticalCenter() const { return y1 + (y2 - y1)/2; }
58  T x() const { return x1; }
59  T y() const { return y1; }
60  TPoint<T> topLeft() const { return TPoint<T>(x1, y1); }
61  TPoint<T> bottomRight() const { return TPoint<T>(x2, y2); }
62  TPoint<T> topRight() const { return TPoint<T>(x2, y1); }
63  TPoint<T> bottomLeft() const { return TPoint<T>(x1, y2); }
64  TPoint<T> topCenter() const { return TPoint<T>((x1+x2)/2, y1); }
65  TPoint<T> bottomCenter() const { return TPoint<T>((x1+x2)/2, y2); }
66  TPoint<T> centerLeft() const { return TPoint<T>(x1, (y1+y2)/2); }
67  TPoint<T> centerRight() const { return TPoint<T>(x2, (y1+y2)/2); }
68  TPoint<T> center() const { return TPoint<T>((x1+x2)/2, (y1+y2)/2); }
69  T width() const { return x2 - x1 + 1; }
70  T height() const { return y2 - y1 + 1; }
71  TSize<T> size() const { return TSize<T>(width(), height()); }
72  void reset() { x1 = y1 = 0; x2 = y2 = -1; }
73  void clear() { x2 = x1 - 1; y2 = y1 - 1; }
74 
75  void setLeft(T pos) { x1 = pos; }
76  void setTop(T pos) { y1 = pos; }
77  void setRight(T pos) { x2 = pos; }
78  void setBottom(T pos) { y2 = pos; }
79  void setX(T x) { x1 = x; }
80  void setY(T y) { y1 = y; }
81  void setTopLeft(const TPoint<T> &p) { x1 = p.x; y1 = p.y; }
82  void setBottomRight(const TPoint<T> &p) { x2 = p.x; y2 = p.y; }
83  void setTopRight(const TPoint<T> &p) { x2 = p.x; y1 = p.y; }
84  void setBottomLeft(const TPoint<T> &p) { x1 = p.x; y2 = p.y; }
85  void setWidth(T width) { x2 = x1 + width - 1; }
86  void setHeight(T height) { y2 = y1 + height- 1; }
87  void setSize(const TSize<T>& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; }
88  void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); }
89  void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; }
90 
91  void expandLeft(T add) { x1 -= add; }
92  void expandTop(T add) { y1 -= add; }
93  void expandRight(T add) { x2 += add; }
94  void expandBottom(T add) { y2 += add; }
95  void expand(T top, T right, T bottom, T left) { x1 -= left; y1 -= top; x2 += right; y2 += bottom; }
96  void expand(T add) { x1 -= add; y1 -= add; x2 += add; y2 += add; }
97 
98  void translate(T x, T y) { x1 += x; y1 += y; x2 += x; y2 += y; }
99  void translate(const TPoint<T> &p) { x1 += p.x; y1 += p.y; x2 += p.x; y2 += p.y; }
100  void resize(const TSize<T>& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; }
101  void resize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; }
102  void move(T x, T y) { x2 += x - x1; y2 += y - y1; x1 = x; y1 = y; }
103  void move(const TPoint<T> &p) { x2 += p.x - x1; y2 += p.y - y1; x1 = p.x; y1 = p.y; }
104  void moveLeft(T pos) { x2 += (pos - x1); x1 = pos; }
105  void moveTop(T pos) { y2 += (pos - y1); y1 = pos; }
106  void moveRight(T pos) { x1 += (pos - x2); x2 = pos; }
107  void moveBottom(T pos) { y1 += (pos - y2); y2 = pos; }
108  void moveTopLeft(const TPoint<T> &p) { moveLeft(p.x); moveTop(p.y); }
109  void moveBottomRight(const TPoint<T> &p) { moveRight(p.x); moveBottom(p.y); }
110  void moveTopRight(const TPoint<T> &p) { moveRight(p.x); moveTop(p.y); }
111  void moveBottomLeft(const TPoint<T> &p) { moveLeft(p.x); moveBottom(p.y); }
116 
117  TRect<T> translated(int x, int y) const { return TRect<T>(TPoint<T>(x1 + x, y1 + y), TPoint<T>(x2 + x, y2 + y)); }
118  TRect<T> translated(const TPoint<T> &p) const { return TRect<T>(TPoint<T>(x1 + p.x, y1 + p.y), TPoint<T>(x2 + p.x, y2 + p.y)); }
119 
120  TRect<T> expanded(T add) const { return TRect<T>(TPoint<T>(x1 - add, y1 - add), TPoint<T>(x2 + add, y2 + add)); }
121 
122  void moveCenter(const TPoint<T> &p) {
123  T w = x2 - x1;
124  T h = y2 - y1;
125  x1 = p.x - w/2;
126  y1 = p.y - h/2;
127  x2 = x1 + w;
128  y2 = y1 + h;
129  }
131  T w = x2 - x1;
132  x1 = x - w/2;
133  x2 = x1 + w;
134  }
136  T h = y2 - y1;
137  y1 = y - h/2;
138  y2 = y1 + h;
139  }
140 
141  bool contains(const TPoint<T> &p, bool insideOnly = false) const {
142  T l, r;
143  if(x2 < x1 - 1) {
144  l = x2;
145  r = x1;
146  } else {
147  l = x1;
148  r = x2;
149  }
150  if(insideOnly) {
151  if(p.x <= l || p.x >= r)
152  return false;
153  } else {
154  if(p.x < l || p.x > r)
155  return false;
156  }
157  T t, b;
158  if(y2 < y1 - 1) {
159  t = y2;
160  b = y1;
161  } else {
162  t = y1;
163  b = y2;
164  }
165  if(insideOnly) {
166  if(p.y <= t || p.y >= b)
167  return false;
168  } else {
169  if(p.y < t || p.y > b)
170  return false;
171  }
172  return true;
173  }
174 
175  bool contains(const TRect<T> &r, bool insideOnly = false) const {
176  if(contains(r.topLeft(), insideOnly) && contains(r.bottomRight(), insideOnly))
177  return true;
178  return false;
179  }
180 
181  bool intersects(const TRect<T> &r) const {
182  if(isNull() || r.isNull())
183  return false;
184 
185  int l1 = x1;
186  int r1 = x1;
187  if(x2 - x1 + 1 < 0)
188  l1 = x2;
189  else
190  r1 = x2;
191 
192  int l2 = r.x1;
193  int r2 = r.x1;
194  if(r.x2 - r.x1 + 1 < 0)
195  l2 = r.x2;
196  else
197  r2 = r.x2;
198 
199  if(l1 > r2 || l2 > r1)
200  return false;
201 
202  int t1 = y1;
203  int b1 = y1;
204  if(y2 - y1 + 1 < 0)
205  t1 = y2;
206  else
207  b1 = y2;
208 
209  int t2 = r.y1;
210  int b2 = r.y1;
211  if(r.y2 - r.y1 + 1 < 0)
212  t2 = r.y2;
213  else
214  b2 = r.y2;
215 
216  if(t1 > b2 || t2 > b1)
217  return false;
218 
219  return true;
220  }
221 
222  TRect<T> united(const TRect<T> &r) const {
223  TRect<T> tmp;
224  tmp.x1 = std::min<T>(x1, r.x1);
225  tmp.x2 = std::max<T>(x2, r.x2);
226  tmp.y1 = std::min<T>(y1, r.y1);
227  tmp.y2 = std::max<T>(y2, r.y2);
228  return tmp;
229  }
230 
231  TRect<T> intersection(const TRect<T> &r) const {
232  if(isNull())
233  return r;
234  if(r.isNull())
235  return *this;
236 
237  int l1 = x1;
238  int r1 = x1;
239  if(x2 - x1 + 1 < 0)
240  l1 = x2;
241  else
242  r1 = x2;
243 
244  int l2 = r.x1;
245  int r2 = r.x1;
246  if(r.x2 - r.x1 + 1 < 0)
247  l2 = r.x2;
248  else
249  r2 = r.x2;
250 
251  int t1 = y1;
252  int b1 = y1;
253  if(y2 - y1 + 1 < 0)
254  t1 = y2;
255  else
256  b1 = y2;
257 
258  int t2 = r.y1;
259  int b2 = r.y1;
260  if(r.y2 - r.y1 + 1 < 0)
261  t2 = r.y2;
262  else
263  b2 = r.y2;
264 
265  TRect<T> tmp;
266  tmp.x1 = std::max<int>(l1, l2);
267  tmp.x2 = std::min<int>(r1, r2);
268  tmp.y1 = std::max<int>(t1, t2);
269  tmp.y2 = std::min<int>(b1, b2);
270  return tmp;
271  }
272 
273  void bind(const TRect<T> &r) {
274  if(isNull() || r.isNull())
275  return;
276 
277  if(right() > r.right())
278  moveRight(r.right());
279  if(bottom() > r.bottom())
280  moveBottom(r.bottom());
281  if(left() < r.left())
282  moveLeft(r.left());
283  if(top() < r.top())
284  moveTop(r.top());
285  }
286 
287  void alignIn(const TRect<T> &r, Fw::AlignmentFlag align) {
288  if(align == Fw::AlignTopLeft)
289  moveTopLeft(r.topLeft());
290  else if(align == Fw::AlignTopRight)
291  moveTopRight(r.topRight());
292  else if(align == Fw::AlignTopCenter)
294  else if(align == Fw::AlignBottomLeft)
296  else if(align == Fw::AlignBottomRight)
298  else if(align == Fw::AlignBottomCenter)
300  else if(align == Fw::AlignLeftCenter)
302  else if(align == Fw::AlignCenter)
303  moveCenter(r.center());
304  else if(align == Fw::AlignRightCenter)
306  }
307 
308  TRect<T>& operator=(const TRect<T>& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; }
309  bool operator==(const TRect<T>& other) const { return (x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2); }
310  bool operator!=(const TRect<T>& other) const { return (x1 != other.x1 || y1 != other.y1 || x2 != other.x2 || y2 != other.y2); }
311 
312  TRect<T>& operator|=(const TRect<T>& other) { *this = united(other); return *this; }
313  TRect<T>& operator&=(const TRect<T>& other) { *this = intersection(other); return *this; }
314 
315 private:
316  T x1, y1, x2, y2;
317 };
318 
319 typedef TRect<int> Rect;
321 
322 template<class T>
323 std::ostream& operator<<(std::ostream& out, const TRect<T>& rect)
324 {
325  out << rect.left() << " " << rect.top() << " " << rect.width() << " " << rect.height();
326  return out;
327 }
328 
329 template<class T>
330 std::istream& operator>>(std::istream& in, TRect<T>& rect)
331 {
332  T x, y , w, h;
333  in >> x >> y >> w >> h;
334  rect.setRect(x,y,w,h);
335  return in;
336 }
337 
338 #endif
TRect::contains
bool contains(const TPoint< T > &p, bool insideOnly=false) const
Definition: rect.h:141
TRect::moveRight
void moveRight(T pos)
Definition: rect.h:106
TRect::bottomLeft
TPoint< T > bottomLeft() const
Definition: rect.h:63
TRect::resize
void resize(const TSize< T > &size)
Definition: rect.h:100
TRect::moveHorizontalCenter
void moveHorizontalCenter(T x)
Definition: rect.h:130
TRect::expandTop
void expandTop(T add)
Definition: rect.h:92
TRect::moveTopLeft
void moveTopLeft(const TPoint< T > &p)
Definition: rect.h:108
Fw::AlignBottomCenter
@ AlignBottomCenter
Definition: const.h:207
TPoint::y
T y
Definition: point.h:83
TRect::TRect
TRect(const TPoint< T > &topLeft, int width, int height)
Definition: rect.h:46
TRect::move
void move(const TPoint< T > &p)
Definition: rect.h:103
TRect::centerLeft
TPoint< T > centerLeft() const
Definition: rect.h:66
TRect
Definition: rect.h:37
TRect::x
T x() const
Definition: rect.h:58
Fw::AlignCenter
@ AlignCenter
Definition: const.h:208
TRect::verticalCenter
T verticalCenter() const
Definition: rect.h:57
TRect::TRect
TRect()
Definition: rect.h:40
Fw::AlignBottomRight
@ AlignBottomRight
Definition: const.h:203
TRect::centerRight
TPoint< T > centerRight() const
Definition: rect.h:67
TRect::moveLeft
void moveLeft(T pos)
Definition: rect.h:104
TRect::moveCenterLeft
void moveCenterLeft(const TPoint< T > &p)
Definition: rect.h:114
Fw::AlignTopLeft
@ AlignTopLeft
Definition: const.h:200
TRect::moveBottomRight
void moveBottomRight(const TPoint< T > &p)
Definition: rect.h:109
TRect::left
T left() const
Definition: rect.h:52
TRect::bind
void bind(const TRect< T > &r)
Definition: rect.h:273
TRect::alignIn
void alignIn(const TRect< T > &r, Fw::AlignmentFlag align)
Definition: rect.h:287
TRect::isEmpty
bool isEmpty() const
Definition: rect.h:49
TRect::setTop
void setTop(T pos)
Definition: rect.h:76
TRect::moveBottomCenter
void moveBottomCenter(const TPoint< T > &p)
Definition: rect.h:113
TRect::setY
void setY(T y)
Definition: rect.h:80
TRect::bottom
T bottom() const
Definition: rect.h:55
TRect::moveBottom
void moveBottom(T pos)
Definition: rect.h:107
TRect::operator==
bool operator==(const TRect< T > &other) const
Definition: rect.h:309
TRect::setLeft
void setLeft(T pos)
Definition: rect.h:75
TRect::topRight
TPoint< T > topRight() const
Definition: rect.h:62
Fw::AlignBottomLeft
@ AlignBottomLeft
Definition: const.h:202
TRect::moveTopCenter
void moveTopCenter(const TPoint< T > &p)
Definition: rect.h:112
operator<<
std::ostream & operator<<(std::ostream &out, const TRect< T > &rect)
Definition: rect.h:323
TRect::reset
void reset()
Definition: rect.h:72
TRect::expandLeft
void expandLeft(T add)
Definition: rect.h:91
TRect::translated
TRect< T > translated(int x, int y) const
Definition: rect.h:117
TRect::setBottomLeft
void setBottomLeft(const TPoint< T > &p)
Definition: rect.h:84
Fw::AlignTopCenter
@ AlignTopCenter
Definition: const.h:206
TRect::setRight
void setRight(T pos)
Definition: rect.h:77
TRect::topLeft
TPoint< T > topLeft() const
Definition: rect.h:60
TRect::TRect
TRect(const TPoint< T > &topLeft, const TSize< T > &size)
Definition: rect.h:45
TRect::translated
TRect< T > translated(const TPoint< T > &p) const
Definition: rect.h:118
TRect::expandRight
void expandRight(T add)
Definition: rect.h:93
TRect::setX
void setX(T x)
Definition: rect.h:79
TRect::setTopLeft
void setTopLeft(const TPoint< T > &p)
Definition: rect.h:81
TRect::expand
void expand(T top, T right, T bottom, T left)
Definition: rect.h:95
TRect::horizontalCenter
T horizontalCenter() const
Definition: rect.h:56
TRect::setCoords
void setCoords(int left, int top, int right, int bottom)
Definition: rect.h:89
TRect::united
TRect< T > united(const TRect< T > &r) const
Definition: rect.h:222
TRect::operator!=
bool operator!=(const TRect< T > &other) const
Definition: rect.h:310
TRect::operator|=
TRect< T > & operator|=(const TRect< T > &other)
Definition: rect.h:312
TRect::operator&=
TRect< T > & operator&=(const TRect< T > &other)
Definition: rect.h:313
TRect::TRect
TRect(const TPoint< T > &topLeft, const TPoint< T > &bottomRight)
Definition: rect.h:42
TRect::y
T y() const
Definition: rect.h:59
TRect::expanded
TRect< T > expanded(T add) const
Definition: rect.h:120
TPoint::x
T x
Definition: point.h:83
TRect::moveCenter
void moveCenter(const TPoint< T > &p)
Definition: rect.h:122
RectF
TRect< float > RectF
Definition: rect.h:320
TRect::TRect
TRect(T x, T y, T width, T height)
Definition: rect.h:41
TRect::translate
void translate(const TPoint< T > &p)
Definition: rect.h:99
TRect::expand
void expand(T add)
Definition: rect.h:96
Fw::AlignmentFlag
AlignmentFlag
Definition: const.h:192
Rect
TRect< int > Rect
Definition: rect.h:319
Fw::AlignLeftCenter
@ AlignLeftCenter
Definition: const.h:204
TRect::move
void move(T x, T y)
Definition: rect.h:102
TRect::resize
void resize(T width, T height)
Definition: rect.h:101
TRect::moveVerticalCenter
void moveVerticalCenter(T y)
Definition: rect.h:135
TRect::setSize
void setSize(const TSize< T > &size)
Definition: rect.h:87
TRect::right
T right() const
Definition: rect.h:54
operator>>
std::istream & operator>>(std::istream &in, TRect< T > &rect)
Definition: rect.h:330
TRect::isValid
bool isValid() const
Definition: rect.h:50
TRect::setHeight
void setHeight(T height)
Definition: rect.h:86
TRect::isNull
bool isNull() const
Definition: rect.h:48
TRect::intersects
bool intersects(const TRect< T > &r) const
Definition: rect.h:181
TRect::expandBottom
void expandBottom(T add)
Definition: rect.h:94
TRect::TRect
TRect(const TRect< T > &other)
Definition: rect.h:43
TRect::TRect
TRect(T x, T y, const TSize< T > &size)
Definition: rect.h:44
Fw::AlignTopRight
@ AlignTopRight
Definition: const.h:201
TRect::height
T height() const
Definition: rect.h:70
TRect::moveTop
void moveTop(T pos)
Definition: rect.h:105
TRect::intersection
TRect< T > intersection(const TRect< T > &r) const
Definition: rect.h:231
TRect::moveCenterRight
void moveCenterRight(const TPoint< T > &p)
Definition: rect.h:115
TRect::top
T top() const
Definition: rect.h:53
TRect::operator=
TRect< T > & operator=(const TRect< T > &other)
Definition: rect.h:308
TRect::bottomRight
TPoint< T > bottomRight() const
Definition: rect.h:61
TPoint
Definition: point.h:34
TRect::contains
bool contains(const TRect< T > &r, bool insideOnly=false) const
Definition: rect.h:175
TRect::size
TSize< T > size() const
Definition: rect.h:71
TRect::setRect
void setRect(T x, T y, T width, T height)
Definition: rect.h:88
TRect::clear
void clear()
Definition: rect.h:73
TRect::setWidth
void setWidth(T width)
Definition: rect.h:85
TRect::width
T width() const
Definition: rect.h:69
TRect::center
TPoint< T > center() const
Definition: rect.h:68
TRect::setTopRight
void setTopRight(const TPoint< T > &p)
Definition: rect.h:83
TRect::moveBottomLeft
void moveBottomLeft(const TPoint< T > &p)
Definition: rect.h:111
TRect::bottomCenter
TPoint< T > bottomCenter() const
Definition: rect.h:65
TSize
Definition: point.h:31
TRect::topCenter
TPoint< T > topCenter() const
Definition: rect.h:64
Fw::AlignRightCenter
@ AlignRightCenter
Definition: const.h:205
TRect::moveTopRight
void moveTopRight(const TPoint< T > &p)
Definition: rect.h:110
TRect::setBottomRight
void setBottomRight(const TPoint< T > &p)
Definition: rect.h:82
TRect::translate
void translate(T x, T y)
Definition: rect.h:98
TRect::setBottom
void setBottom(T pos)
Definition: rect.h:78