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