e3d9f4993270f68f7e4958646cd9af90020be84e
[platform/core/uifw/dali-core.git] / dali / public-api / math / uint-16-pair.h
1 #ifndef DALI_UINT_16_PAIR_H
2 #define DALI_UINT_16_PAIR_H
3
4 /*
5  * Copyright (c) 2020 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 <stdint.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/common/type-traits.h>
27
28 namespace Dali
29 {
30 /**
31  * @addtogroup dali_core_math
32  * @{
33  */
34
35 /**
36  * @brief Simple class for passing around pairs of small unsigned integers.
37  *
38  * Use this for integer dimensions and points with limited range such as image
39  * sizes and pixel coordinates where a pair of floating point numbers is
40  * inefficient and illogical (i.e. the data is inherently integer).
41  * One of these can be passed in a single 32 bit integer register on
42  * common architectures.
43  * @SINCE_1_0.0
44  */
45 class Uint16Pair
46 {
47 public:
48   /**
49    * @brief Default constructor for the (0, 0) tuple.
50    * @SINCE_1_0.0
51    */
52   Uint16Pair()
53   : mData(0)
54   {
55   }
56
57   /**
58    * @brief Constructor taking separate x and y (width and height) parameters.
59    * @SINCE_1_0.0
60    * @param[in] width The width or X dimension of the tuple. Make sure it is less than 65536
61    * @param[in] height The height or Y dimension of the tuple. Make sure it is less than 65536
62    */
63   Uint16Pair(uint32_t width, uint32_t height)
64   {
65     DALI_ASSERT_DEBUG(width < (1u << 16) && "Width parameter not representable.");
66     DALI_ASSERT_DEBUG(height < (1u << 16) && "Height parameter not representable.");
67
68     /* Do equivalent of the code below with one aligned memory access:
69      * mComponents[0] = width;
70      * mComponents[1] = height;
71      * Unit tests make sure this is equivalent.
72      **/
73     mData = (height << 16u) + width;
74   }
75
76   /**
77    * @brief Sets the width.
78    * @SINCE_1_1.13
79    * @param[in] width The x dimension to be stored in this 2-tuple
80    */
81   void SetWidth(uint16_t width)
82   {
83     mComponents[0] = width;
84   }
85
86   /**
87    * @brief Get the width.
88    * @SINCE_1_0.0
89    * @return the x dimension stored in this 2-tuple
90    */
91   uint16_t GetWidth() const
92   {
93     return mComponents[0];
94   }
95
96   /**
97    * @brief Sets the height.
98    * @SINCE_1_1.13
99    * @param[in] height The y dimension to be stored in this 2-tuple
100    */
101   void SetHeight(uint16_t height)
102   {
103     mComponents[1] = height;
104   }
105
106   /**
107    * @brief Returns the y dimension stored in this 2-tuple.
108    * @SINCE_1_0.0
109    * @return Height
110    */
111   uint16_t GetHeight() const
112   {
113     return mComponents[1];
114   }
115
116   /**
117    * @brief Sets the x dimension (same as width).
118    * @SINCE_1_1.14
119    * @param[in] x The x dimension to be stored in this 2-tuple
120    */
121   void SetX(uint16_t x)
122   {
123     mComponents[0] = x;
124   }
125
126   /**
127    * @brief Returns the x dimension stored in this 2-tuple.
128    * @SINCE_1_0.0
129    * @return X
130    */
131   uint16_t GetX() const
132   {
133     return mComponents[0];
134   }
135
136   /**
137    * @brief Sets the y dimension (same as height).
138    * @SINCE_1_1.14
139    * @param[in] y The y dimension to be stored in this 2-tuple
140    */
141   void SetY(uint16_t y)
142   {
143     mComponents[1] = y;
144   }
145
146   /**
147    * @brief Returns the y dimension stored in this 2-tuple.
148    * @SINCE_1_0.0
149    * @return Y
150    */
151   uint16_t GetY() const
152   {
153     return mComponents[1];
154   }
155
156   /**
157    * @brief Equality operator.
158    * @SINCE_1_0.0
159    * @param[in] rhs A reference for comparison
160    * @return True if same
161    */
162   bool operator==(const Uint16Pair& rhs) const
163   {
164     return mData == rhs.mData;
165   }
166
167   /**
168    * @brief Inequality operator.
169    * @SINCE_1_0.0
170    * @param[in] rhs A reference for comparison
171    * @return True if different
172    */
173   bool operator!=(const Uint16Pair& rhs) const
174   {
175     return mData != rhs.mData;
176   }
177
178   /**
179    * @brief Less than comparison operator for storing in collections (not geometrically
180    * meaningful).
181    * @SINCE_1_0.0
182    * @param[in] rhs A reference for comparison
183    * @return True if less
184    */
185   bool operator<(const Uint16Pair& rhs) const
186   {
187     return mData < rhs.mData;
188   }
189
190   /**
191    * @brief Greater than comparison operator for storing in collections (not
192    * geometrically meaningful).
193    * @SINCE_1_0.0
194    * @param[in] rhs A reference for comparison
195    * @return True if greater
196    */
197   bool operator>(const Uint16Pair& rhs) const
198   {
199     return mData > rhs.mData;
200   }
201
202   /**
203    * @brief Creates an instance by rounding a floating point vector to closest
204    * integers.
205    *
206    * Uses a template for loose coupling, to save a header include, and allow any
207    * vector type with .x and .y members to be converted.
208    * @SINCE_1_0.0
209    * @param[in] from Floating point vector2
210    * @return Closest integer value
211    */
212   template<typename FLOAT_VECTOR_N_TYPE>
213   static Uint16Pair FromFloatVec2(const FLOAT_VECTOR_N_TYPE& from)
214   {
215     DALI_ASSERT_DEBUG(from.x + 0.5f < 65536.0f);
216     DALI_ASSERT_DEBUG(from.y + 0.5f < 65536.0f);
217     return Uint16Pair(from.x + 0.5f, from.y + 0.5f);
218   }
219
220   /**
221    * @brief Creates an instance by rounding a floating point array to closest
222    * integers.
223    *
224    * Uses a template to allow any vector type with operator [] to be converted
225    * in addition to plain arrays.
226    * @SINCE_1_0.0
227    * @param[in] from Floating point array
228    * @return Closest integer value
229    */
230   template<typename FLOAT_ARRAY>
231   static Uint16Pair FromFloatArray(const FLOAT_ARRAY& from)
232   {
233     DALI_ASSERT_DEBUG(from[0] + 0.5f < 65536.0f);
234     DALI_ASSERT_DEBUG(from[1] + 0.5f < 65536.0f);
235     return Uint16Pair(from[0] + 0.5f, from[1] + 0.5f);
236   }
237
238 public:
239   Uint16Pair(const Uint16Pair&) = default;            ///< Default copy constructor
240   Uint16Pair(Uint16Pair&&)      = default;            ///< Default move constructor
241   Uint16Pair& operator=(const Uint16Pair&) = default; ///< Default copy assignment operator
242   Uint16Pair& operator=(Uint16Pair&&) = default;      ///< Default move assignment operator
243
244 private:
245   union
246   {
247     // Addressable view of X and Y:
248     uint16_t mComponents[2];
249     // Packed view of X and Y to force alignment and allow a faster copy:
250     uint32_t mData;
251   };
252 };
253
254 // Allow Uint16Pair to be treated as a POD type
255 template<>
256 struct TypeTraits<Uint16Pair> : public BasicTypes<Uint16Pair>
257 {
258   enum
259   {
260     IS_TRIVIAL_TYPE = true
261   };
262 };
263
264 /**
265  * @}
266  */
267 } // namespace Dali
268
269 #endif // DALI_UINT_16_PAIR_H