Merge "Prevents an invalid texture cache being interrogated for a texture. This ...
[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) 2015 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  * @addtogroup dali-core-object
32  * @{
33  */
34
35 /**
36  * @brief Template class to create and operate on rectangles.
37  */
38
39 template< typename T = float >
40 struct Rect
41 {
42 // Methods
43
44   /**
45    * @brief Constructor.
46    */
47   Rect()
48   : x(0),
49     y(0),
50     width(0),
51     height(0)
52   {
53   }
54
55   /**
56    * @brief Constructor.
57    *
58    * @param [in] x       x coordinate (or left)
59    * @param [in] y       y coordinate (or right)
60    * @param [in] width   width (or bottom)
61    * @param [in] height  height (or top)
62    */
63   Rect(T x, T y, T width, T height)
64   : x(x),
65     y(y),
66     width(width),
67     height(height)
68   {
69   }
70
71   /**
72    * @brief Copy constructor.
73    *
74    * @param [in] rhs  The original object
75    */
76   Rect(const Rect<T>& rhs)
77   {
78     x = rhs.x;
79     y = rhs.y;
80     width = rhs.width;
81     height = rhs.height;
82   }
83
84   /**
85    * @brief Assignment operator.
86    *
87    * @param [in] rhs  The original object
88    * @return reference to this
89    */
90   Rect<T>& operator= (const Rect<T>& rhs)
91   {
92     if (this != &rhs)
93     {
94       x = rhs.x;
95       y = rhs.y;
96       width = rhs.width;
97       height = rhs.height;
98     }
99
100     return *this;
101   }
102
103   /**
104    * @brief Assignment from individual values.
105    *
106    * @param[in] newX      x coordinate
107    * @param[in] newY      y coordinate
108    * @param[in] newWidth  width
109    * @param[in] newHeight height
110    */
111   void Set(T newX, T newY, T newWidth, T newHeight)
112   {
113     x = newX;
114     y = newY;
115     width = newWidth;
116     height = newHeight;
117   }
118
119   /**
120    * @brief Determines whether or not this Rectangle is empty.
121    *
122    * @return true if width or height are zero
123    */
124   bool IsEmpty() const
125   {
126     return width  == 0 ||
127       height == 0;
128   }
129
130   /**
131    * @brief Get the left of the rectangle.
132    *
133    * @return The left edge of the rectangle
134    */
135   T Left() const
136   {
137     return x;
138   }
139   /**
140    * @brief Get the right of the rectangle.
141    *
142    * @return The right edge of the rectangle
143    */
144   T Right() const
145   {
146     return x + width;
147   }
148
149   /**
150    * @brief Get the top of the rectangle.
151    *
152    * @return The top of the rectangle
153    */
154   T Top() const
155   {
156     return y;
157   }
158
159   /**
160    * @brief Get the bottom of the rectangle.
161    *
162    * @return The bottom of the rectangle
163    */
164   T Bottom() const
165   {
166     return y + height;
167   }
168
169   /**
170    * @brief Get the area of the rectangle.
171    *
172    * @return The area of the rectangle
173    */
174   T Area() const
175   {
176     return width * height;
177   }
178
179   /**
180    * @brief Determines whether or not this rectangle and the specified rectangle intersect.
181    *
182    * @param[in] other  The other rectangle to test against this rectangle
183    * @return           true if the rectangles intersect
184    */
185   bool Intersects(const Rect<T>& other) const
186   {
187     return (other.x + other.width)  > x           &&
188       other.x                 < (x + width) &&
189                                 (other.y + other.height) > y           &&
190       other.y                 < (y + height);
191   }
192
193   /**
194    * @brief Determines whether or not this Rectangle contains the specified rectangle.
195    *
196    * @param[in] other  The other rectangle to test against this rectangle
197    * @return           true if the specified rectangle is contained
198    */
199   bool Contains(const Rect<T>& other) const
200   {
201     return other.x                  >= x           &&
202       (other.x + other.width)  <= (x + width) &&
203       other.y                  >= y           &&
204       (other.y + other.height) <= (y + height);
205   }
206
207 public:   // Data
208
209   union
210   {
211     T x;      ///< X position of the rectangle
212     T left;   ///< The left value
213   };
214
215   union
216   {
217     T y;      ///< Y position of the rectangle
218     T right;  ///< The right value
219   };
220
221   union
222   {
223     T width;  ///< width of the rectangle
224     T bottom; ///< The bottom value
225   };
226
227   union
228   {
229     T height; ///< height of the rectangle
230     T top;    ///< The top value
231   };
232 };
233
234 /**
235  * @brief Equality operator.
236  *
237  * @param[in] lhs First operand
238  * @param[in] rhs Second operand
239  * @return true if boxes are exactly same
240  */
241 template< typename T >
242 inline bool operator==( const Rect<T>& lhs, const Rect<T>& rhs )
243 {
244   return ( lhs.x == rhs.x )&&
245     ( lhs.y == rhs.y )&&
246     ( lhs.width == rhs.width )&&
247     ( lhs.height == rhs.height );
248 }
249
250 /**
251  * @brief Inequality operator.
252  *
253  * @param[in] lhs The first rectangle
254  * @param[in] rhs The second rectangle
255  * @return true if rectangles are not identical
256  */
257 template< typename T >
258 inline bool operator!=( const Rect<T>& lhs, const Rect<T>& rhs )
259 {
260   return !(lhs == rhs);
261 }
262
263 /**
264  * @brief Equality operator specialization for float.
265  *
266  * @param[in] lhs The first rectangle
267  * @param[in] rhs The second rectangle
268  * @return true if rectangles are exactly same
269  */
270 template<>
271 inline bool operator==( const Rect<float>& lhs, const Rect<float>& rhs )
272 {
273   return ( fabsf( lhs.x - rhs.x ) < GetRangedEpsilon(lhs.x, rhs.x) )&&
274     ( fabsf( lhs.y - rhs.y ) < GetRangedEpsilon(lhs.y, rhs.y) )&&
275     ( fabsf( lhs.width - rhs.width ) < GetRangedEpsilon(lhs.width, rhs.width) )&&
276     ( fabsf( lhs.height - rhs.height ) < GetRangedEpsilon(lhs.height, rhs.height) );
277 }
278
279 /**
280  * @brief IsEmpty specialization for float.
281  *
282  * @return true if the rectangle has zero size.
283  */
284 template<>
285 inline bool Rect<float>::IsEmpty() const
286 {
287   return (fabsf(width)  <= GetRangedEpsilon(width, width)
288           ||
289           fabsf(height) <= GetRangedEpsilon(height, 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 template< typename T >
300 inline std::ostream& operator<< (std::ostream& stream, const Rect<T>& rectangle)
301 {
302   return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
303 }
304
305 /**
306  * @}
307  */
308 } // namespace Dali
309
310 #endif // __DALI_RECT_H__