5 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include <dali/public-api/math/math-utils.h>
31 * @addtogroup dali_core_math
36 * @brief Template class to create and operate on rectangles.
40 template< typename T = float >
61 * @param[in] x X coordinate (or left)
62 * @param[in] y Y coordinate (or right)
63 * @param[in] width Width (or bottom)
64 * @param[in] height Height (or top)
66 Rect(T x, T y, T width, T height)
75 * @brief Conversion constructor from Vector4.
78 * @param[in] vec4 Vector4 to convert from
80 Rect( const Vector4& vec4 )
89 * @brief Copy constructor.
92 * @param[in] rhs The original object
94 Rect(const Rect<T>& rhs)
103 * @brief Copy assignment operator.
106 * @param[in] rhs The original object
107 * @return Reference to this
109 Rect<T>& operator= (const Rect<T>& rhs)
123 * @brief Move constructor.
126 * @param[in] rhs The original object
128 Rect<T>( Rect<T>&& rhs )
137 * @brief Move assignment operator.
140 * @param[in] rhs The original object
141 * @return Reference to this
143 Rect<T>& operator=( Rect<T>&& rhs )
157 * @brief Assignment operator.
160 * @param[in] vec4 The Vector4 to assign
161 * @return Reference to this
163 Rect<T>& operator= (const Vector4& vec4)
174 * @brief Assignment from individual values.
177 * @param[in] newX X coordinate
178 * @param[in] newY Y coordinate
179 * @param[in] newWidth Width
180 * @param[in] newHeight Height
182 void Set(T newX, T newY, T newWidth, T newHeight)
191 * @brief Determines whether or not this Rectangle is empty.
194 * @return True if width or height are zero
203 * @brief Determines whether or not this Rectangle is valid.
206 * @return True if width and height are not negative
210 return !(width < 0 || height < 0);
214 * @brief Gets the left of the rectangle.
217 * @return The left edge of the rectangle
224 * @brief Gets the right of the rectangle.
227 * @return The right edge of the rectangle
235 * @brief Gets the top of the rectangle.
238 * @return The top of the rectangle
246 * @brief Gets the bottom of the rectangle.
249 * @return The bottom of the rectangle
257 * @brief Gets the area of the rectangle.
260 * @return The area of the rectangle
264 return width * height;
268 * @brief Determines whether or not this rectangle and the specified rectangle intersect.
271 * @param[in] other The other rectangle to test against this rectangle
272 * @return True if the rectangles intersect
274 bool Intersects(const Rect<T>& other) const
276 return (other.x + other.width) > x && other.x < (x + width) &&
277 (other.y + other.height) > y && other.y < (y + height);
281 * @brief Intersects this rectangle and the specified rectangle.
282 * The result of the intersection is stored in this rectangle.
285 * @param[in] rect The other rectangle to intersect with
286 * @return True if the rectangles intersect
288 bool Intersect(const Rect<T>& rect)
290 const int left = std::max(rect.x, x);
291 const int top = std::max(rect.y, y);
292 const int right = std::min(rect.x + rect.width, x + width);
293 const int bottom = std::min(rect.y + rect.height, y + height);
295 const int width = right - left;
296 const int height = bottom - top;
297 if (!(width < 0 || height < 0))
302 this->height = height;
310 * @brief Merges this rectangle and the specified rectangle.
311 * The result of the merge is stored in this rectangle.
314 * @param[in] rect The other rectangle to merge with
316 void Merge(const Rect<T>& rect)
318 const int left = std::min(rect.x, x);
319 const int top = std::min(rect.y, y);
320 const int right = std::max(rect.x + rect.width, x + width);
321 const int bottom = std::max(rect.y + rect.height, y + height);
324 width = right - left;
325 height = bottom - top;
329 * @brief Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards.
330 * If dx is negative, then the sides are moved outwards.
331 * The result of the inset is stored in this rectangle.
334 void Inset(T dx, T dy)
336 const int left = x - dx;
337 const int top = y - dy;
338 const int right = x + width + dx;
339 const int bottom = y + height + dy;
342 width = right - left;
343 height = bottom - top;
347 * @brief Determines whether or not this Rectangle contains the specified rectangle.
350 * @param[in] other The other rectangle to test against this rectangle
351 * @return True if the specified rectangle is contained
353 bool Contains(const Rect<T>& other) const
355 return other.x >= x && (other.x + other.width) <= (x + width) &&
356 other.y >= y && (other.y + other.height) <= (y + height);
363 T x; ///< X position of the rectangle
364 T left; ///< The left value
369 T y; ///< Y position of the rectangle
370 T right; ///< The right value
375 T width; ///< width of the rectangle
376 T bottom; ///< The bottom value
381 T height; ///< height of the rectangle
382 T top; ///< The top value
387 * @brief Equality operator.
390 * @param[in] lhs First operand
391 * @param[in] rhs Second operand
392 * @return True if boxes are exactly same
394 template< typename T >
395 inline bool operator==( const Rect<T>& lhs, const Rect<T>& rhs )
397 return ( lhs.x == rhs.x )&&
399 ( lhs.width == rhs.width )&&
400 ( lhs.height == rhs.height );
404 * @brief Inequality operator.
407 * @param[in] lhs The first rectangle
408 * @param[in] rhs The second rectangle
409 * @return True if rectangles are not identical
411 template< typename T >
412 inline bool operator!=( const Rect<T>& lhs, const Rect<T>& rhs )
414 return !(lhs == rhs);
418 * @brief Equality operator specialization for float.
421 * @param[in] lhs The first rectangle
422 * @param[in] rhs The second rectangle
423 * @return True if rectangles are exactly same
426 inline bool operator==( const Rect<float>& lhs, const Rect<float>& rhs )
428 return ( fabsf( lhs.x - rhs.x ) < GetRangedEpsilon(lhs.x, rhs.x) )&&
429 ( fabsf( lhs.y - rhs.y ) < GetRangedEpsilon(lhs.y, rhs.y) )&&
430 ( fabsf( lhs.width - rhs.width ) < GetRangedEpsilon(lhs.width, rhs.width) )&&
431 ( fabsf( lhs.height - rhs.height ) < GetRangedEpsilon(lhs.height, rhs.height) );
435 * @brief IsEmpty specialization for float.
438 * @return True if the rectangle has zero size
441 inline bool Rect<float>::IsEmpty() const
443 return (fabsf(width) <= GetRangedEpsilon(width, width)
445 fabsf(height) <= GetRangedEpsilon(height, height));
449 * @brief Converts the value of the rectangle into a string and insert in to an output stream.
452 * @param[in] stream The output stream operator
453 * @param[in] rectangle the rectangle to output
454 * @return The output stream operator
456 template< typename T >
457 inline std::ostream& operator<< (std::ostream& stream, const Rect<T>& rectangle)
459 return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
467 #endif // DALI_RECT_H