ead729a65d2e0a6f56c3837ff4e53fe6fed10d02
[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) 2015 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() : mData(0) {}
53
54   /**
55    * @brief Constructor taking separate x and y (width and height) parameters.
56    * @SINCE_1_0.0
57    * @param[in] width The width or X dimension of the tuple. Make sure it is less than 65536,
58    * @param[in] height The height or Y dimension of the tuple. Make sure it is less than 65536,
59    */
60   Uint16Pair( uint32_t width, uint32_t height )
61   {
62     DALI_ASSERT_DEBUG( width < ( 1u << 16 ) && "Width parameter not representable." );
63     DALI_ASSERT_DEBUG( height < ( 1u << 16 ) && "Height parameter not representable." );
64
65     /* Do equivalent of the code below with one aligned memory access:
66      * mComponents[0] = width;
67      * mComponents[1] = height;
68      * Unit tests make sure this is equivalent.
69      **/
70     mData = (height << 16u) + width;
71   }
72
73   /**
74    * @brief Copy constructor.
75    * @SINCE_1_0.0
76    * @param[in] rhs A reference to assign
77    */
78   Uint16Pair( const Uint16Pair& rhs )
79   {
80     mData = rhs.mData;
81   }
82
83   /**
84    * @brief Sets the width.
85    * @SINCE_1_1.13
86    * @param[in] width The x dimension to be stored in this 2-tuple.
87    */
88   void SetWidth( uint16_t width )
89   {
90     mComponents[0] = width;
91   }
92
93   /**
94    * @brief @returns the x dimension stored in this 2-tuple.
95    * @SINCE_1_0.0
96    */
97   uint16_t GetWidth() const
98   {
99     return mComponents[0];
100   }
101
102   /**
103    * @brief Sets the height.
104    * @SINCE_1_1.13
105    * @param[in] height The y dimension to be stored in this 2-tuple.
106    */
107   void SetHeight( uint16_t height )
108   {
109     mComponents[1] = height;
110   }
111
112   /**
113    * @brief Returns the y dimension stored in this 2-tuple.
114    * @SINCE_1_0.0
115    * @return Height
116    */
117   uint16_t GetHeight() const
118   {
119     return mComponents[1];
120   }
121
122   /**
123    * @brief Sets the x dimension (same as width).
124    * @SINCE_1_1.14
125    * @param[in] x The x dimension to be stored in this 2-tuple.
126    */
127   void SetX( uint16_t x )
128   {
129     mComponents[0] = x;
130   }
131
132   /**
133    * @brief Returns the x dimension stored in this 2-tuple.
134    * @SINCE_1_0.0
135    * @return X
136    */
137   uint16_t GetX()  const
138   {
139     return mComponents[0];
140   }
141
142   /**
143    * @brief Sets the y dimension (same as height).
144    * @SINCE_1_1.14
145    * @param[in] y The y dimension to be stored in this 2-tuple.
146    */
147   void SetY( uint16_t y )
148   {
149     mComponents[1] = y;
150   }
151
152   /**
153    * @brief Returns the y dimension stored in this 2-tuple.
154    * @SINCE_1_0.0
155    * @return Y
156    */
157   uint16_t GetY() const
158   {
159     return mComponents[1];
160   }
161
162   /**
163    * @brief Assignment operator.
164    * @SINCE_1_0.0
165    * @param[in] rhs Handle to an object
166    * @return A reference to this
167    */
168   Uint16Pair& operator=( const Uint16Pair& rhs )
169   {
170     if( rhs != *this )
171     {
172       mData = rhs.mData;
173     }
174     return *this;
175   }
176
177   /**
178    * @brief Equality operator.
179    * @SINCE_1_0.0
180    * @param[in] rhs A reference for comparison
181    * @return True if same
182    */
183   bool operator==( const Uint16Pair& rhs ) const
184   {
185     return mData == rhs.mData;
186   }
187
188   /**
189    * @brief Inequality operator.
190    * @SINCE_1_0.0
191    * @param[in] rhs A reference for comparison
192    * @return True if different
193    */
194   bool operator!=( const Uint16Pair& rhs ) const
195   {
196     return mData != rhs.mData;
197   }
198
199   /**
200    * @brief Less than comparison operator for storing in collections (not geometrically
201    * meaningful).
202    * @SINCE_1_0.0
203    * @param[in] rhs A reference for comparison
204    * @return True if less
205    */
206   bool operator<( const Uint16Pair& rhs ) const
207   {
208     return mData < rhs.mData;
209   }
210
211   /**
212    * @brief Greater than comparison operator for storing in collections (not
213    * geometrically meaningful).
214    * @SINCE_1_0.0
215    * @param[in] rhs A reference for comparison
216    * @return True if greater
217    */
218   bool operator>( const Uint16Pair& rhs ) const
219   {
220     return mData > rhs.mData;
221   }
222
223   /**
224    * @brief Create an instance by rounding a floating point vector to closest
225    * integers.
226    *
227    * Uses a template for loose coupling, to save a header include, and allow any
228    * vector type with .x and .y members to be converted.
229    * @SINCE_1_0.0
230    * @param[in] from Floating point vector2
231    * @return Closest integer value.
232    */
233   template<typename FLOAT_VECTOR_N_TYPE>
234   static Uint16Pair FromFloatVec2( const FLOAT_VECTOR_N_TYPE& from )
235   {
236     DALI_ASSERT_DEBUG( from.x + 0.5f < 65536.0f );
237     DALI_ASSERT_DEBUG( from.y + 0.5f < 65536.0f );
238     return Uint16Pair( from.x + 0.5f, from.y + 0.5f );
239   }
240
241   /**
242    * @brief Create an instance by rounding a floating point array to closest
243    * integers.
244    *
245    * Uses a template to allow any vector type with operator [] to be converted
246    * in addition to plain arrays.
247    * @SINCE_1_0.0
248    * @param[in] from Floating point array
249    * @return Closest integer value.
250    */
251   template<typename FLOAT_ARRAY>
252   static Uint16Pair FromFloatArray( const FLOAT_ARRAY& from )
253   {
254     DALI_ASSERT_DEBUG( from[0] + 0.5f < 65536.0f );
255     DALI_ASSERT_DEBUG( from[1] + 0.5f < 65536.0f );
256     return Uint16Pair( from[0] + 0.5f, from[1] + 0.5f );
257   }
258
259 private:
260   union
261   {
262     // Addressable view of X and Y:
263     uint16_t mComponents[2];
264     // Packed view of X and Y to force alignment and allow a faster copy:
265     uint32_t mData;
266   };
267 };
268
269 // Allow Uint16Pair to be treated as a POD type
270 template <> struct TypeTraits< Uint16Pair > : public BasicTypes< Uint16Pair > { enum { IS_TRIVIAL_TYPE = true }; };
271
272 /**
273  * @}
274  */
275 } // namespace Dali
276
277 #endif // __DALI_UINT_16_PAIR_H__