89e815c18ba7947a5e2820ab880b4ef10890a9b1
[platform/core/uifw/dali-core.git] / dali / public-api / math / rect.h
1 #ifndef __DALI_RECT_H__
2 #define __DALI_RECT_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <math.h>
23 #include <ostream>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/math/math-utils.h>
27
28 namespace Dali
29 {
30
31 /**
32  * @brief Template class to create and operate on rectangles.
33  */
34 template< typename T = float >
35 struct Rect
36 {
37 // Methods
38
39   /**
40    * @brief Constructor.
41    */
42   Rect()
43   : x(0),
44     y(0),
45     width(0),
46     height(0)
47   {
48   }
49
50   /**
51    * @brief Constructor.
52    *
53    * @param [in] x       x coordinate
54    * @param [in] y       y coordinate
55    * @param [in] width   width
56    * @param [in] height  height
57    */
58   Rect(T x, T y, T width, T height)
59   : x(x),
60     y(y),
61     width(width),
62     height(height)
63   {
64   }
65
66   /**
67    * @brief Copy constructor.
68    *
69    * @param [in] rhs  The original object
70    */
71   Rect(const Rect<T>& rhs)
72   {
73     x = rhs.x;
74     y = rhs.y;
75     width = rhs.width;
76     height = rhs.height;
77   }
78
79   /**
80    * @brief Assignment operator.
81    *
82    * @param [in] rhs  The original object
83    * @return reference to this
84    */
85   Rect<T>& operator= (const Rect<T>& rhs)
86   {
87     if (this != &rhs)
88     {
89       x = rhs.x;
90       y = rhs.y;
91       width = rhs.width;
92       height = rhs.height;
93     }
94
95     return *this;
96   }
97
98   /**
99    * @brief Assignment from individual values.
100    *
101    * @param[in] newX      x coordinate
102    * @param[in] newY      y coordinate
103    * @param[in] newWidth  width
104    * @param[in] newHeight height
105    */
106   void Set(T newX, T newY, T newWidth, T newHeight)
107   {
108     x = newX;
109     y = newY;
110     width = newWidth;
111     height = newHeight;
112   }
113
114   /**
115    * @brief Determines whether or not this Rectangle is empty.
116    *
117    * @return true if width or height are zero
118    */
119   bool IsEmpty() const
120   {
121     return width  == 0 ||
122       height == 0;
123   }
124
125   /**
126    * @brief Get the left of the rectangle.
127    *
128    * @return The left edge of the rectangle
129    */
130   T Left() const
131   {
132     return x;
133   }
134   /**
135    * @brief Get the right of the rectangle.
136    *
137    * @return The right edge of the rectangle
138    */
139   T Right() const
140   {
141     return x + width;
142   }
143
144   /**
145    * @brief Get the top of the rectangle.
146    *
147    * @return The top of the rectangle
148    */
149   T Top() const
150   {
151     return y;
152   }
153
154   /**
155    * @brief Get the bottom of the rectangle.
156    *
157    * @return The bottom of the rectangle
158    */
159   T Bottom() const
160   {
161     return y + height;
162   }
163
164   /**
165    * @brief Get the area of the rectangle.
166    *
167    * @return The area of the rectangle
168    */
169   T Area() const
170   {
171     return width * height;
172   }
173
174   /**
175    * @brief Determines whether or not this rectangle and the specified rectangle intersect.
176    *
177    * @param[in] other  The other rectangle to test against this rectangle
178    * @return           true if the rectangles intersect
179    */
180   bool Intersects(const Rect<T>& other) const
181   {
182     return (other.x + other.width)  > x           &&
183       other.x                 < (x + width) &&
184                                 (other.y + other.height) > y           &&
185       other.y                 < (y + height);
186   }
187
188   /**
189    * @brief Determines whether or not this Rectangle contains the specified rectangle.
190    *
191    * @param[in] other  The other rectangle to test against this rectangle
192    * @return           true if the specified rectangle is contained
193    */
194   bool Contains(const Rect<T>& other) const
195   {
196     return other.x                  >= x           &&
197       (other.x + other.width)  <= (x + width) &&
198       other.y                  >= y           &&
199       (other.y + other.height) <= (y + height);
200   }
201
202 public:   // Data
203
204   T x;      ///< X position of the rectangle
205   T y;      ///< Y position of the rectangle
206   T width;  ///< width of the rectangle
207   T height; ///< height of the rectangle
208 };
209
210 /**
211  * @brief Equality operator.
212  *
213  * @param[in] lhs First operand
214  * @param[in] rhs Second operand
215  * @return true if boxes are exactly same
216  */
217 template< typename T >
218 inline bool operator==( const Rect<T>& lhs, const Rect<T>& rhs )
219 {
220   return ( lhs.x == rhs.x )&&
221     ( lhs.y == rhs.y )&&
222     ( lhs.width == rhs.width )&&
223     ( lhs.height == rhs.height );
224 }
225
226 /**
227  * @brief Inequality operator.
228  *
229  * @param[in] lhs The first rectangle
230  * @param[in] rhs The second rectangle
231  * @return true if rectangles are not identical
232  */
233 template< typename T >
234 inline bool operator!=( const Rect<T>& lhs, const Rect<T>& rhs )
235 {
236   return !(lhs == rhs);
237 }
238
239 /**
240  * @brief Equality operator specialization for float.
241  *
242  * @param[in] lhs The first rectangle
243  * @param[in] rhs The second rectangle
244  * @return true if rectangles are exactly same
245  */
246 template<>
247 inline bool operator==( const Rect<float>& lhs, const Rect<float>& rhs )
248 {
249   return ( fabsf( lhs.x - rhs.x ) < GetRangedEpsilon(lhs.x, rhs.x) )&&
250     ( fabsf( lhs.y - rhs.y ) < GetRangedEpsilon(lhs.y, rhs.y) )&&
251     ( fabsf( lhs.width - rhs.width ) < GetRangedEpsilon(lhs.width, rhs.width) )&&
252     ( fabsf( lhs.height - rhs.height ) < GetRangedEpsilon(lhs.height, rhs.height) );
253 }
254
255 /**
256  * @brief IsEmpty specialization for float.
257  *
258  * @return true if the rectangle has zero size.
259  */
260 template<>
261 inline bool Rect<float>::IsEmpty() const
262 {
263   return (fabsf(width)  <= GetRangedEpsilon(width, width)
264           ||
265           fabsf(height) <= GetRangedEpsilon(height, height));
266 }
267
268 /**
269  * @brief Convert the value of the rectangle into a string and insert in to an output stream.
270  *
271  * @param [in] stream The output stream operator.
272  * @param [in] rectangle the rectangle to output
273  * @return The output stream operator.
274  */
275 inline std::ostream& operator<< (std::ostream& stream, const Rect<int>& rectangle)
276 {
277   return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
278 }
279
280 /**
281  * @brief Convert the value of the rectangle into a string and insert in to an output stream.
282  *
283  * @param [in] stream The output stream operator.
284  * @param [in] rectangle the rectangle to output
285  * @return The output stream operator.
286  */
287 inline std::ostream& operator<< (std::ostream& stream, const Rect<unsigned int>& rectangle)
288 {
289   return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
290 }
291
292 /**
293  * @brief Convert the value of the rectangle into a string and insert in to an output stream.
294  *
295  * @param [in] stream The output stream operator.
296  * @param [in] rectangle the rectangle to output
297  * @return The output stream operator.
298  */
299 inline std::ostream& operator<< (std::ostream& stream, const Rect<float>& rectangle)
300 {
301   return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
302 }
303
304
305
306 } // namespace Dali
307
308 #endif // __DALI_RECT_H__