Rect.h
1 /* Copyright (C) 2006-2015 Laurentiu-Gheorghe Crisan
2  * Copyright (C) 2006-2015 Marc Boris Duerner
3  * Copyright (C) 2010 Aloysius Indrayanto
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * As a special exception, you may use this file as part of a free
11  * software library without restriction. Specifically, if other files
12  * instantiate templates or use macros or inline functions from this
13  * file, or you compile this file and link it with other files to
14  * produce an executable, this file does not by itself cause the
15  * resulting executable to be covered by the GNU General Public
16  * License. This exception does not however invalidate any other
17  * reasons why the executable file might be covered by the GNU Library
18  * General Public License.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28  * MA 02110-1301 USA
29  */
30 
31 #ifndef PT_GFX_RECT_H
32 #define PT_GFX_RECT_H
33 
34 #include <Pt/Gfx/Point.h>
35 #include <Pt/Gfx/Size.h>
36 #include <algorithm>
37 
38 namespace Pt {
39 
40 namespace Gfx {
41 
44 class Rect
45 {
46  public:
47  explicit Rect(const Point& p = Point(0, 0),
48  const Size& s = Size(0, 0))
49  : _p(p)
50  , _s(s)
51  {
52  }
53 
54  explicit Rect(const Size& s)
55  : _p()
56  , _s(s)
57  {
58  }
59 
60  Rect(Float width, Float height)
61  : _p()
62  , _s(width, height)
63  {
64  }
65 
66  Rect(const Point& p1, const Point& p2)
67  : _p(p1)
68  , _s(p2.x() - p1.x(), p2.y() - p1.y())
69  {
70  }
71 
72  Rect(Float left, Float right, Float top, Float bottom)
73  {
74  set(left, right, top, bottom);
75  }
76 
77  Rect(const Rect& val)
78  : _p(val._p)
79  , _s(val._s)
80  {
81  }
82 
83  bool isNull() const
84  {
85  return (_s.width() == 0 || _s.height() == 0);
86  }
87 
88  void clear()
89  {
90  _p.clear();
91  _s.clear();
92  }
93 
94  void set(const Point& p, const Size& s)
95  {
96  _p = p;
97  _s = s;
98  }
99 
100  void set(const Point& p1, const Point& p2)
101  {
102  this->setOrigin(p1);
103  this->setWidth(p2.x() - p1.x());
104  this->setHeight(p2.y() - p1.y());
105  }
106 
107  void set(Float width, Float height)
108  {
109  _p.clear();
110  _s.set(width, height);
111  }
112 
113  void set(Float left, Float right, Float top, Float bottom)
114  {
115  _p = Point(left, top);
116  _s = Size(right - left, bottom - top);
117  }
118 
119  const Point& origin() const
120  {
121  return _p;
122  }
123 
124  void setOrigin(const Point& p)
125  {
126  _p = p;
127  }
128 
129  void setSize(const Size& s)
130  {
131  _s = s;
132  }
133 
134  void setWidth(Float w)
135  {
136  _s.setWidth(w);
137  }
138 
139  void setHeight(Float h)
140  {
141  _s.setHeight(h);
142  }
143 
144  Float x() const
145  {
146  return _p.x();
147  }
148 
149  Float y() const
150  {
151  return _p.y();
152  }
153 
154  const Size& size() const
155  {
156  return _s;
157  }
158 
159  Float width() const
160  {
161  return _s.width();
162  }
163 
164  Float height() const
165  {
166  return _s.height();
167  }
168 
169  Float left() const
170  {
171  return _p.x();
172  }
173 
174  Float top() const
175  {
176  return _p.y();
177  }
178 
179  Float right() const
180  {
181  return _p.x() + _s.width();
182  }
183 
184  Float bottom() const
185  {
186  return _p.y() + _s.height();
187  }
188 
189  const Point& topLeft() const
190  {
191  return _p;
192  }
193 
194  Point topRight() const
195  {
196  return Point(this->x() + this->width(), this->y());
197  }
198 
199  Point bottomLeft() const
200  {
201  return Point(this->x(), this->y() + this->height());
202  }
203 
204  Point bottomRight() const
205  {
206  return Point(this->x() + this->width(),
207  this->y() + this->height());
208  }
209 
210  bool operator==(const Rect& other) const
211  {
212  return _p == other._p && _s == other._s;
213  }
214 
215  bool operator!=(const Rect& other) const
216  {
217  return _p != other._p || _s != other._s;
218  }
219 
220  void shift(Float dx, Float dy)
221  {
222  _p.addX(dx);
223  _p.addY(dy);
224  }
225 
226  void expand(Float dw, Float dh)
227  {
228  _s.addWidth(dw);
229  _s.addHeight(dh);
230  }
231 
232  void shrink(Float dw, Float dh)
233  {
234  _s.addWidth(-dw);
235  _s.addHeight(-dh);
236  }
237 
238  void unify(const Rect& rect)
239  {
240  if(rect.isNull())
241  return;
242 
243  if(this->isNull())
244  {
245  _p = rect._p;
246  _s = rect._s;
247  return;
248  }
249 
250  const Float l = std::min(this->left(), rect.left());
251  const Float t = std::min(this->top(), rect.top());
252  const Float r = std::max(this->right(), rect.right());
253  const Float b = std::max(this->bottom(), rect.bottom());
254 
255  set(l, r, t, b);
256  }
257 
258  Rect intersect(const Rect& rect) const
259  {
260  const Float l = std::max(this->left(), rect.left());
261  const Float t = std::max(this->top(), rect.top());
262  const Float r = std::min(this->right(), rect.right());
263  const Float b = std::min(this->bottom(), rect.bottom());
264 
265  return r >= l && b >= t ? Rect(l, r, t, b)
266  : Rect();
267  }
268 
269  bool contains(const Point& p) const
270  {
271  return p.x() >= _p.x() &&
272  p.x() < _p.x() + _s.width() &&
273  p.y() >= _p.y() &&
274  p.y() < _p.y() + _s.height();
275  }
276 
277  private:
278  Point _p;
279  Size _s;
280 };
281 
282 typedef Rect RectF;
283 
286 class RectI
287 {
288  public:
289  explicit RectI(const PointI& p = PointI(0, 0),
290  const SizeI& s = SizeI(0, 0))
291  : _p(p)
292  , _s(s)
293  {
294  }
295 
296  explicit RectI(const SizeI& s)
297  : _p()
298  , _s(s)
299  {
300  }
301 
302  RectI(Int width, Int height)
303  : _p()
304  , _s(width, height)
305  {
306  }
307 
308  RectI(const PointI& p1, const PointI& p2)
309  : _p(p1)
310  , _s(p2.x() - p1.x(), p2.y() - p1.y())
311  {
312  }
313 
314  RectI(Int left, Int right, Int top, Int bottom)
315  {
316  set(left, right, top, bottom);
317  }
318 
319  RectI(const RectI& val)
320  : _p(val._p)
321  , _s(val._s)
322  {
323  }
324 
325  bool isNull() const
326  {
327  return (_s.width() == 0 || _s.height() == 0);
328  }
329 
330  void clear()
331  {
332  _p.clear();
333  _s.clear();
334  }
335 
336  void set(const PointI& p, const SizeI& s)
337  {
338  _p = p;
339  _s = s;
340  }
341 
342  void set(const PointI& p1, const PointI& p2)
343  {
344  this->setOrigin(p1);
345  this->setWidth(p2.x() - p1.x());
346  this->setHeight(p2.y() - p1.y());
347  }
348 
349  void set(Int width, Int height)
350  {
351  _p.clear();
352  _s.set(width, height);
353  }
354 
355  void set(Int left, Int right, Int top, Int bottom)
356  {
357  _p = PointI(left, top);
358  _s = SizeI(right - left, bottom - top);
359  }
360 
361  const PointI& origin() const
362  {
363  return _p;
364  }
365 
366  void setOrigin(const PointI& p)
367  {
368  _p = p;
369  }
370 
371  void setSize(const SizeI& s)
372  {
373  _s = s;
374  }
375 
376  void setWidth(Int w)
377  {
378  _s.setWidth(w);
379  }
380 
381  void setHeight(Int h)
382  {
383  _s.setHeight(h);
384  }
385 
386  Int x() const
387  {
388  return _p.x();
389  }
390 
391  Int y() const
392  {
393  return _p.y();
394  }
395 
396  const SizeI& size() const
397  {
398  return _s;
399  }
400 
401  Int width() const
402  {
403  return _s.width();
404  }
405 
406  Int height() const
407  {
408  return _s.height();
409  }
410 
411  Int left() const
412  {
413  return _p.x();
414  }
415 
416  Int top() const
417  {
418  return _p.y();
419  }
420 
421  Int right() const
422  {
423  return _p.x() + _s.width();
424  }
425 
426  Int bottom() const
427  {
428  return _p.y() + _s.height();
429  }
430 
431  const PointI& topLeft() const
432  {
433  return _p;
434  }
435 
436  PointI topRight() const
437  {
438  return PointI(this->x() + this->width(), this->y());
439  }
440 
441  PointI bottomLeft() const
442  {
443  return PointI(this->x(), this->y() + this->height());
444  }
445 
446  PointI bottomRight() const
447  {
448  return PointI(this->x() + this->width(),
449  this->y() + this->height());
450  }
451 
452  bool operator==(const RectI& other) const
453  {
454  return _p == other._p && _s == other._s;
455  }
456 
457  bool operator!=(const RectI& other) const
458  {
459  return _p != other._p || _s != other._s;
460  }
461 
462  void shift(Int dx, Int dy)
463  {
464  _p.addX(dx);
465  _p.addY(dy);
466  }
467 
468  void expand(Int dw, Int dh)
469  {
470  _s.addWidth(dw);
471  _s.addHeight(dh);
472  }
473 
474  void shrink(Int dw, Int dh)
475  {
476  _s.addWidth(-dw);
477  _s.addHeight(-dh);
478  }
479 
480  void unify(const RectI& rect)
481  {
482  if(rect.isNull())
483  return;
484 
485  if(this->isNull())
486  {
487  _p = rect._p;
488  _s = rect._s;
489  return;
490  }
491 
492  const Int l = std::min(this->left(), rect.left());
493  const Int t = std::min(this->top(), rect.top());
494  const Int r = std::max(this->right(), rect.right());
495  const Int b = std::max(this->bottom(), rect.bottom());
496 
497  set(l, r, t, b);
498  }
499 
500  RectI intersect(const RectI& rect) const
501  {
502  const Int l = std::max(this->left(), rect.left());
503  const Int t = std::max(this->top(), rect.top());
504  const Int r = std::min(this->right(), rect.right());
505  const Int b = std::min(this->bottom(), rect.bottom());
506 
507  return r >= l && b >= t ? RectI(l, r, t, b)
508  : RectI();
509  }
510 
511  bool contains(const PointI& p) const
512  {
513  return p.x() >= _p.x() &&
514  p.x() < _p.x() + _s.width() &&
515  p.y() >= _p.y() &&
516  p.y() < _p.y() + _s.height();
517  }
518 
519  private:
520  PointI _p;
521  SizeI _s;
522 };
523 
524 } // namespace
525 
526 } // namespace
527 
528 #endif
Core module.
Definition: pt-gfx-images.dox:14
Size with integer width and height.
Definition: Size.h:211
Size with floating-point width and height.
Definition: Size.h:45
Point with floating-point X and Y coordinates.
Definition: Point.h:45
Point with integer X and Y coordinates.
Definition: Point.h:203
Rect with floating-point coordinates.
Definition: Rect.h:45
Rect with integer coordinates.
Definition: Rect.h:287