-#ifndef __DALI_RECT_H__
-#define __DALI_RECT_H__
+#ifndef DALI_RECT_H
+#define DALI_RECT_H
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
namespace Dali
{
/**
- * @addtogroup dali-core-object
+ * @addtogroup dali_core_math
* @{
*/
/**
* @brief Template class to create and operate on rectangles.
+ * @SINCE_1_0.0
*/
-
-template< typename T = float >
+template<typename T = float>
struct Rect
{
-// Methods
+ // Methods
/**
* @brief Constructor.
+ * @SINCE_1_0.0
*/
Rect()
: x(0),
/**
* @brief Constructor.
*
- * @param [in] x x coordinate (or left)
- * @param [in] y y coordinate (or right)
- * @param [in] width width (or bottom)
- * @param [in] height height (or top)
+ * @SINCE_1_0.0
+ * @param[in] x X coordinate (or left)
+ * @param[in] y Y coordinate (or right)
+ * @param[in] width Width (or bottom)
+ * @param[in] height Height (or top)
*/
Rect(T x, T y, T width, T height)
: x(x),
}
/**
- * @brief Copy constructor.
+ * @brief Conversion constructor from Vector4.
*
- * @param [in] rhs The original object
+ * @SINCE_1_9.14
+ * @param[in] vec4 Vector4 to convert from
*/
- Rect(const Rect<T>& rhs)
+ Rect(const Vector4& vec4)
+ : x(vec4.x),
+ y(vec4.y),
+ width(vec4.z),
+ height(vec4.w)
{
- x = rhs.x;
- y = rhs.y;
- width = rhs.width;
- height = rhs.height;
}
/**
+ * @brief Default copy constructor.
+ *
+ * @SINCE_1_9.27
+ * @param[in] rhs The original object
+ */
+ Rect(const Rect<T>& rhs) = default;
+
+ /**
+ * @brief Default copy assignment operator.
+ *
+ * @SINCE_1_9.27
+ * @param[in] rhs The original object
+ * @return Reference to this
+ */
+ Rect<T>& operator=(const Rect<T>& rhs) = default;
+
+ /**
+ * @brief Default move constructor.
+ *
+ * @SINCE_1_9.27
+ * @param[in] rhs The original object
+ */
+ Rect<T>(Rect<T>&& rhs) noexcept = default;
+
+ /**
+ * @brief Default move assignment operator.
+ *
+ * @SINCE_1_9.27
+ * @param[in] rhs The original object
+ * @return Reference to this
+ */
+ Rect<T>& operator=(Rect<T>&& rhs) noexcept = default;
+
+ /**
* @brief Assignment operator.
*
- * @param [in] rhs The original object
- * @return reference to this
+ * @SINCE_1_9.14
+ * @param[in] vec4 The Vector4 to assign
+ * @return Reference to this
*/
- Rect<T>& operator= (const Rect<T>& rhs)
+ Rect<T>& operator=(const Vector4& vec4)
{
- if (this != &rhs)
- {
- x = rhs.x;
- y = rhs.y;
- width = rhs.width;
- height = rhs.height;
- }
+ x = vec4.x;
+ y = vec4.y;
+ width = vec4.z;
+ height = vec4.w;
return *this;
}
/**
* @brief Assignment from individual values.
*
- * @param[in] newX x coordinate
- * @param[in] newY y coordinate
- * @param[in] newWidth width
- * @param[in] newHeight height
+ * @SINCE_1_0.0
+ * @param[in] newX X coordinate
+ * @param[in] newY Y coordinate
+ * @param[in] newWidth Width
+ * @param[in] newHeight Height
*/
void Set(T newX, T newY, T newWidth, T newHeight)
{
- x = newX;
- y = newY;
- width = newWidth;
+ x = newX;
+ y = newY;
+ width = newWidth;
height = newHeight;
}
/**
* @brief Determines whether or not this Rectangle is empty.
*
- * @return true if width or height are zero
+ * @SINCE_1_0.0
+ * @return True if width or height are zero
*/
bool IsEmpty() const
{
- return width == 0 ||
- height == 0;
+ return width == 0 ||
+ height == 0;
}
/**
- * @brief Get the left of the rectangle.
+ * @brief Determines whether or not this Rectangle is valid.
*
+ * @SINCE_1_9.18
+ * @return True if width and height are not negative
+ */
+ bool IsValid() const
+ {
+ return !(width < 0 || height < 0);
+ }
+
+ /**
+ * @brief Gets the left of the rectangle.
+ *
+ * @SINCE_1_0.0
* @return The left edge of the rectangle
*/
T Left() const
return x;
}
/**
- * @brief Get the right of the rectangle.
+ * @brief Gets the right of the rectangle.
*
+ * @SINCE_1_0.0
* @return The right edge of the rectangle
*/
T Right() const
}
/**
- * @brief Get the top of the rectangle.
+ * @brief Gets the top of the rectangle.
*
+ * @SINCE_1_0.0
* @return The top of the rectangle
*/
T Top() const
}
/**
- * @brief Get the bottom of the rectangle.
+ * @brief Gets the bottom of the rectangle.
*
+ * @SINCE_1_0.0
* @return The bottom of the rectangle
*/
T Bottom() const
}
/**
- * @brief Get the area of the rectangle.
+ * @brief Gets the area of the rectangle.
*
+ * @SINCE_1_0.0
* @return The area of the rectangle
*/
T Area() const
/**
* @brief Determines whether or not this rectangle and the specified rectangle intersect.
*
- * @param[in] other The other rectangle to test against this rectangle
- * @return true if the rectangles intersect
+ * @SINCE_1_0.0
+ * @param[in] other The other rectangle to test against this rectangle
+ * @return True if the rectangles intersect
*/
bool Intersects(const Rect<T>& other) const
{
- return (other.x + other.width) > x &&
- other.x < (x + width) &&
- (other.y + other.height) > y &&
- other.y < (y + height);
+ return (other.x + other.width) > x && other.x < (x + width) &&
+ (other.y + other.height) > y && other.y < (y + height);
+ }
+
+ /**
+ * @brief Intersects this rectangle and the specified rectangle.
+ * The result of the intersection is stored in this rectangle.
+ *
+ * @SINCE_1_9.18
+ * @param[in] rect The other rectangle to intersect with
+ * @return True if the rectangles intersect
+ */
+ bool Intersect(const Rect<T>& rect)
+ {
+ const int left = std::max(rect.x, x);
+ const int top = std::max(rect.y, y);
+ const int right = std::min(rect.x + rect.width, x + width);
+ const int bottom = std::min(rect.y + rect.height, y + height);
+
+ const int width = right - left;
+ const int height = bottom - top;
+ if(!(width < 0 || height < 0))
+ {
+ x = left;
+ y = top;
+ this->width = width;
+ this->height = height;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief Merges this rectangle and the specified rectangle.
+ * The result of the merge is stored in this rectangle.
+ *
+ * @SINCE_1_9.18
+ * @param[in] rect The other rectangle to merge with
+ */
+ void Merge(const Rect<T>& rect)
+ {
+ const int left = std::min(rect.x, x);
+ const int top = std::min(rect.y, y);
+ const int right = std::max(rect.x + rect.width, x + width);
+ const int bottom = std::max(rect.y + rect.height, y + height);
+ x = left;
+ y = top;
+ width = right - left;
+ height = bottom - top;
+ }
+
+ /**
+ * @brief Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards.
+ * If dx is negative, then the sides are moved outwards.
+ * The result of the inset is stored in this rectangle.
+ * @SINCE_1_9.18
+ */
+ void Inset(T dx, T dy)
+ {
+ const int left = x - dx;
+ const int top = y - dy;
+ const int right = x + width + dx;
+ const int bottom = y + height + dy;
+ x = left;
+ y = top;
+ width = right - left;
+ height = bottom - top;
}
/**
* @brief Determines whether or not this Rectangle contains the specified rectangle.
*
- * @param[in] other The other rectangle to test against this rectangle
- * @return true if the specified rectangle is contained
+ * @SINCE_1_0.0
+ * @param[in] other The other rectangle to test against this rectangle
+ * @return True if the specified rectangle is contained
*/
bool Contains(const Rect<T>& other) const
{
- return other.x >= x &&
- (other.x + other.width) <= (x + width) &&
- other.y >= y &&
- (other.y + other.height) <= (y + height);
+ return other.x >= x && (other.x + other.width) <= (x + width) &&
+ other.y >= y && (other.y + other.height) <= (y + height);
}
-public: // Data
-
+public: // Data
union
{
- T x; ///< X position of the rectangle
- T left; ///< The left value
+ T x; ///< X position of the rectangle
+ T left; ///< The left value
};
union
{
- T y; ///< Y position of the rectangle
- T right; ///< The right value
+ T y; ///< Y position of the rectangle
+ T right; ///< The right value
};
union
/**
* @brief Equality operator.
*
+ * @SINCE_1_0.0
* @param[in] lhs First operand
* @param[in] rhs Second operand
- * @return true if boxes are exactly same
+ * @return True if boxes are exactly same
*/
-template< typename T >
-inline bool operator==( const Rect<T>& lhs, const Rect<T>& rhs )
+template<typename T>
+inline bool operator==(const Rect<T>& lhs, const Rect<T>& rhs)
{
- return ( lhs.x == rhs.x )&&
- ( lhs.y == rhs.y )&&
- ( lhs.width == rhs.width )&&
- ( lhs.height == rhs.height );
+ return (lhs.x == rhs.x) &&
+ (lhs.y == rhs.y) &&
+ (lhs.width == rhs.width) &&
+ (lhs.height == rhs.height);
}
/**
* @brief Inequality operator.
*
+ * @SINCE_1_0.0
* @param[in] lhs The first rectangle
* @param[in] rhs The second rectangle
- * @return true if rectangles are not identical
+ * @return True if rectangles are not identical
*/
-template< typename T >
-inline bool operator!=( const Rect<T>& lhs, const Rect<T>& rhs )
+template<typename T>
+inline bool operator!=(const Rect<T>& lhs, const Rect<T>& rhs)
{
return !(lhs == rhs);
}
/**
* @brief Equality operator specialization for float.
*
+ * @SINCE_1_0.0
* @param[in] lhs The first rectangle
* @param[in] rhs The second rectangle
- * @return true if rectangles are exactly same
+ * @return True if rectangles are exactly same
*/
template<>
-inline bool operator==( const Rect<float>& lhs, const Rect<float>& rhs )
+inline bool operator==(const Rect<float>& lhs, const Rect<float>& rhs)
{
- return ( fabsf( lhs.x - rhs.x ) < GetRangedEpsilon(lhs.x, rhs.x) )&&
- ( fabsf( lhs.y - rhs.y ) < GetRangedEpsilon(lhs.y, rhs.y) )&&
- ( fabsf( lhs.width - rhs.width ) < GetRangedEpsilon(lhs.width, rhs.width) )&&
- ( fabsf( lhs.height - rhs.height ) < GetRangedEpsilon(lhs.height, rhs.height) );
+ return (fabsf(lhs.x - rhs.x) < GetRangedEpsilon(lhs.x, rhs.x)) &&
+ (fabsf(lhs.y - rhs.y) < GetRangedEpsilon(lhs.y, rhs.y)) &&
+ (fabsf(lhs.width - rhs.width) < GetRangedEpsilon(lhs.width, rhs.width)) &&
+ (fabsf(lhs.height - rhs.height) < GetRangedEpsilon(lhs.height, rhs.height));
}
/**
* @brief IsEmpty specialization for float.
*
- * @return true if the rectangle has zero size.
+ * @SINCE_1_0.0
+ * @return True if the rectangle has zero size
*/
template<>
inline bool Rect<float>::IsEmpty() const
{
- return (fabsf(width) <= GetRangedEpsilon(width, width)
- ||
+ return (fabsf(width) <= GetRangedEpsilon(width, width) ||
fabsf(height) <= GetRangedEpsilon(height, height));
}
/**
- * @brief Convert the value of the rectangle into a string and insert in to an output stream.
+ * @brief Converts the value of the rectangle into a string and insert in to an output stream.
*
- * @param [in] stream The output stream operator.
- * @param [in] rectangle the rectangle to output
- * @return The output stream operator.
+ * @SINCE_1_0.0
+ * @param[in] stream The output stream operator
+ * @param[in] rectangle the rectangle to output
+ * @return The output stream operator
*/
-template< typename T >
-inline std::ostream& operator<< (std::ostream& stream, const Rect<T>& rectangle)
+template<typename T>
+inline std::ostream& operator<<(std::ostream& stream, const Rect<T>& rectangle)
{
return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
}
*/
} // namespace Dali
-#endif // __DALI_RECT_H__
+#endif // DALI_RECT_H