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 
42 template<typename T>
43 class BasicRect
44 {
45  public:
46  explicit BasicRect( const BasicPoint<T>& p = BasicPoint<T>(0, 0),
47  const BasicSize<T>& s = BasicSize<T>(0, 0) )
48  : _p(p)
49  , _s(s)
50  {
51  }
52 
53  explicit BasicRect(const BasicSize<T>& s)
54  : _p()
55  , _s(s)
56  {
57  }
58 
59  BasicRect(const BasicPoint<T>& p1, const BasicPoint<T>& p2)
60  : _p(p1)
61  , _s( p2.x() - p1.x() + 1, p2.y() - p1.y() + 1 )
62  {
63  }
64 
65  BasicRect(const T left, const T right, const T top, const T bottom)
66  {
67  set( left, right, top, bottom );
68  }
69 
70  BasicRect(const BasicRect<T>& val)
71  : _p(val._p)
72  , _s(val._s)
73  {
74  }
75 
76  bool isNull() const
77  {
78  return (_s.width() == 0 || _s.height() == 0 );
79  }
80 
81  void clear()
82  {
83  _p.set(0, 0);
84  _s.set(0, 0);
85  }
86 
87  void set(const BasicPoint<T>& p, const BasicSize<T>& s)
88  {
89  _p = p;
90  _s = s;
91  }
92 
93  void set(const BasicPoint<T>& p1, const BasicPoint<T>& p2)
94  {
95  this->setOrigin( p1 );
96  this->setWidth(p2.x() - p1.x() + 1);
97  this->setHeight(p2.y() - p1.y() + 1);
98  }
99 
100  void set(const T left, const T right, const T top, const T bottom)
101  {
102  _p = BasicPoint<T>( left, top );
103  _s = BasicSize<T>( right - left + 1 , bottom - top + 1);
104  }
105 
106  void setOrigin(const BasicPoint<T>& p)
107  {
108  _p = p;
109  }
110 
111  void setSize(const BasicSize<T>& s)
112  {
113  _s = s;
114  }
115 
116  void setWidth(T w)
117  {
118  _s.setWidth(w);
119  }
120 
121  void setHeight(T h)
122  {
123  _s.setHeight(h);
124  }
125 
126  T x() const
127  {
128  return _p.x();
129  }
130 
131  T y() const
132  {
133  return _p.y();
134  }
135 
136  const BasicSize<T>& size() const
137  {
138  return _s;
139  }
140 
141  T width() const
142  {
143  return _s.width();
144  }
145 
146  T height() const
147  {
148  return _s.height();
149  }
150 
151  T left() const
152  {
153  return _p.x();
154  }
155 
156  T top() const
157  {
158  return _p.y();
159  }
160 
161  T right() const
162  {
163  return _p.x() + _s.width() - 1;
164  }
165 
166  T bottom() const
167  {
168  return _p.y() + _s.height() - 1;
169  }
170 
171  const BasicPoint<T>& topLeft() const
172  {
173  return _p;
174  }
175 
176  const BasicPoint<T> topRight() const
177  {
178  return BasicPoint<T>(this->x() + this->width() -1 , this->y());
179  }
180 
181  const BasicPoint<T> bottomLeft() const
182  {
183  return BasicPoint<T>(this->x(), this->y() + this->height() -1);
184  }
185 
186  const BasicPoint<T> bottomRight() const
187  {
188  return BasicPoint<T>(this->x() + this->width() -1,
189  this->y() + this->height() - 1);
190  }
191 
192  bool operator==(const BasicRect& other) const
193  {
194  return _p == other._p && _s == other._s;
195  }
196 
197  bool operator!=(const BasicRect& other) const
198  {
199  return _p != other._p || _s != other._s;
200  }
201 
202  void unify(const BasicRect<T>& rect)
203  {
204  if( rect.isNull() )
205  return;
206 
207  if( this->isNull() )
208  {
209  _p = rect._p;
210  _s = rect._s;
211  return;
212  }
213 
214  const T l = std::min( this->left(), rect.left() );
215  const T t = std::min( this->top(), rect.top() );
216  const T r = std::max( this->right(), rect.right() );
217  const T b = std::max( this->bottom(), rect.bottom() );
218 
219  set(l, r, t, b);
220  }
221 
222  BasicRect<T> intersect(const BasicRect<T>& rect) const
223  {
224  const T l = std::max( this->left(), rect.left() );
225  const T t = std::max( this->top(), rect.top() );
226  const T r = std::min( this->right(), rect.right() );
227  const T b = std::min( this->bottom(), rect.bottom() );
228 
229  return r >= l && b >= t ? BasicRect<T>(l, r, t, b)
230  : BasicRect<T>();
231  }
232 
233  bool contains(const BasicPoint<T>& p) const
234  {
235  return p.x() >= _p.x() &&
236  p.x() < _p.x() + _s.width() &&
237  p.y() >= _p.y() &&
238  p.y() < _p.y() + _s.height();
239  }
240 
241  protected:
242  BasicPoint<T> _p;
243  BasicSize<T> _s;
244 };
245 
246 typedef BasicRect<Pt::ssize_t> Rect;
247 typedef BasicRect<double> RectF;
248 
249 inline Rect round(const RectF& r)
250 {
251  return Rect( round(r.topLeft()),
252  round(r.size()) );
253 }
254 
255 } // namespace
256 
257 } // namespace
258 
259 #endif