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