Get world scale more faster
[platform/core/uifw/dali-core.git] / dali / public-api / math / rect.h
index 89e815c..de43c91 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_RECT_H__
-#define __DALI_RECT_H__
+#ifndef DALI_RECT_H
+#define DALI_RECT_H
 
 /*
- * Copyright (c) 2014 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_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),
@@ -50,10 +56,11 @@ struct Rect
   /**
    * @brief Constructor.
    *
-   * @param [in] x       x coordinate
-   * @param [in] y       y coordinate
-   * @param [in] width   width
-   * @param [in] height  height
+   * @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),
@@ -64,33 +71,66 @@ struct Rect
   }
 
   /**
-   * @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;
   }
@@ -98,33 +138,47 @@ struct Rect
   /**
    * @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 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 Get the left of the rectangle.
+   * @brief Gets the left of the rectangle.
    *
+   * @SINCE_1_0.0
    * @return The left edge of the rectangle
    */
   T Left() const
@@ -132,8 +186,9 @@ struct Rect
     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
@@ -142,8 +197,9 @@ struct Rect
   }
 
   /**
-   * @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
@@ -152,8 +208,9 @@ struct Rect
   }
 
   /**
-   * @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
@@ -162,8 +219,9 @@ struct Rect
   }
 
   /**
-   * @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
@@ -174,64 +232,148 @@ struct Rect
   /**
    * @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
+  };
+
+  union
+  {
+    T y;     ///< Y position of the rectangle
+    T right; ///< The right value
+  };
 
-  T x;      ///< X position of the rectangle
-  T y;      ///< Y position of the rectangle
-  T width;  ///< width of the rectangle
-  T height; ///< height of the rectangle
+  union
+  {
+    T width;  ///< width of the rectangle
+    T bottom; ///< The bottom value
+  };
+
+  union
+  {
+    T height; ///< height of the rectangle
+    T top;    ///< The top value
+  };
 };
 
 /**
  * @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);
 }
@@ -239,70 +381,50 @@ inline bool operator!=( const Rect<T>& lhs, const Rect<T>& 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.
- *
- * @param [in] stream The output stream operator.
- * @param [in] rectangle the rectangle to output
- * @return The output stream operator.
- */
-inline std::ostream& operator<< (std::ostream& stream, const Rect<int>& rectangle)
-{
-  return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.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
  */
-inline std::ostream& operator<< (std::ostream& stream, const Rect<unsigned int>& 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 << "]";
 }
 
 /**
- * @brief Convert 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.
+ * @}
  */
-inline std::ostream& operator<< (std::ostream& stream, const Rect<float>& rectangle)
-{
-  return stream << "[" << rectangle.x << ", " << rectangle.y << ", " << rectangle.width << ", " << rectangle.height << "]";
-}
-
-
-
 } // namespace Dali
 
-#endif // __DALI_RECT_H__
+#endif // DALI_RECT_H