Merge "Fixed SizeMode not updating size on renderable in some cases" into tizen
[platform/core/uifw/dali-core.git] / dali / public-api / images / image-attributes.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/public-api/images/image-attributes.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23
24 namespace Dali
25 {
26
27 const ImageAttributes ImageAttributes::DEFAULT_ATTRIBUTES;
28
29 struct ImageAttributes::ImageAttributesImpl
30 {
31   ImageAttributesImpl()
32   :  fieldRadius(4.0f),
33      fieldBorder(4),
34      width(0),
35      height(0),
36      scaling(ShrinkToFit),
37      filtering(Box),
38      pixelformat(Pixel::RGBA8888),
39      mOrientationCorrection(false),
40      isDistanceField(false)
41   {
42   }
43
44   ~ImageAttributesImpl()
45   {
46   }
47
48   ImageAttributesImpl(const ImageAttributesImpl& rhs)
49   : fieldRadius( rhs.fieldRadius ),
50     fieldBorder( rhs.fieldBorder ),
51     width( rhs.width ),
52     height( rhs.height ),
53     scaling( rhs.scaling ),
54     filtering( rhs.filtering ),
55     pixelformat( rhs.pixelformat ),
56     mOrientationCorrection( rhs.mOrientationCorrection ),
57     isDistanceField( rhs.isDistanceField )
58   {
59   }
60
61   ImageAttributesImpl& operator=(const ImageAttributesImpl& rhs)
62   {
63     if (this != &rhs)
64     {
65       width = rhs.width;
66       height = rhs.height;
67       scaling = rhs.scaling;
68       filtering = rhs.filtering;
69
70       pixelformat = rhs.pixelformat;
71       mOrientationCorrection = rhs.mOrientationCorrection;
72       isDistanceField = rhs.isDistanceField;
73       fieldRadius = rhs.fieldRadius;
74       fieldBorder = rhs.fieldBorder;
75     }
76
77     return *this;
78   }
79
80   float         fieldRadius;      ///< The minimum search radius to check for differing pixels
81   int           fieldBorder : 16; ///< The amount of distancefield cells to add around the data (for glow/shadow effects)
82   unsigned int  width : 16;       ///< image width in pixels
83   unsigned int  height : 16;      ///< image height in pixels
84   ScalingMode   scaling : 3;      ///< scaling option, ShrinkToFit is default
85   FilterMode    filtering : 3;    ///< filtering option. Box is the default
86   Pixel::Format pixelformat : 5;  ///< pixel format, default is RGBA8888
87   bool          mOrientationCorrection : 1; ///< If true, image pixels are reordered according to orientation metadata on load.
88   bool          isDistanceField : 1;  ///< true, if the image is a distancefield. Default is false.
89 };
90
91
92 ImageAttributes::ImageAttributes()
93 : impl( new ImageAttributesImpl() )
94 {
95 }
96
97 ImageAttributes::ImageAttributes(const ImageAttributes& rhs)
98 : impl( new ImageAttributesImpl(*rhs.impl) )
99 {
100 }
101
102 ImageAttributes& ImageAttributes::operator=(const ImageAttributes& rhs)
103 {
104   *impl = *rhs.impl;
105
106   return *this;
107 }
108
109 ImageAttributes::~ImageAttributes()
110 {
111   delete impl;
112 }
113
114 void ImageAttributes::SetSize(unsigned int width, unsigned int height)
115 {
116   impl->width = width;
117   impl->height = height;
118 }
119
120 void ImageAttributes::SetSize( const Size& size )
121 {
122   impl->width = size.width;
123   impl->height = size.height;
124 }
125
126 void ImageAttributes::SetPixelFormat(Pixel::Format format)
127 {
128   impl->pixelformat = format;
129 }
130
131 void ImageAttributes::SetScalingMode(ScalingMode scale)
132 {
133   impl->scaling = scale;
134 }
135
136 void ImageAttributes::SetFilterMode( FilterMode filtering )
137 {
138   impl->filtering = filtering;
139 }
140
141 void ImageAttributes::SetOrientationCorrection(const bool enabled)
142 {
143   impl->mOrientationCorrection = enabled;
144 }
145
146 unsigned int ImageAttributes::GetWidth() const
147 {
148   return impl->width;
149 }
150
151 unsigned int ImageAttributes::GetHeight() const
152 {
153   return impl->height;
154 }
155
156 Size ImageAttributes::GetSize() const
157 {
158   return Size(impl->width, impl->height);
159 }
160
161 Pixel::Format ImageAttributes::GetPixelFormat() const
162 {
163   return impl->pixelformat;
164 }
165
166 ImageAttributes::ScalingMode ImageAttributes::GetScalingMode() const
167 {
168   return impl->scaling;
169 }
170
171 ImageAttributes::FilterMode ImageAttributes::GetFilterMode() const
172 {
173   return impl->filtering;
174 }
175
176 bool ImageAttributes::IsDistanceField() const
177 {
178   return impl->isDistanceField;
179 }
180
181 int ImageAttributes::GetFieldBorder() const
182 {
183   return impl->fieldBorder;
184 }
185
186 float ImageAttributes::GetFieldRadius() const
187 {
188   return impl->fieldRadius;
189 }
190
191 bool ImageAttributes::GetOrientationCorrection() const
192 {
193   return impl->mOrientationCorrection;
194 }
195
196 ImageAttributes ImageAttributes::New()
197 {
198   return ImageAttributes();
199 }
200
201 ImageAttributes ImageAttributes::New(unsigned int imageWidth, unsigned int imageHeight, Pixel::Format format)
202 {
203   ImageAttributes attributes;
204   attributes.impl->width = imageWidth;
205   attributes.impl->height = imageHeight;
206   attributes.impl->pixelformat = format;
207   return attributes;
208 }
209
210 ImageAttributes ImageAttributes::NewDistanceField()
211 {
212   ImageAttributes attributes;
213   attributes.impl->isDistanceField = true;
214   attributes.impl->fieldRadius = 4.0f;
215   attributes.impl->fieldBorder = 4;
216   return attributes;
217 }
218
219 ImageAttributes ImageAttributes::NewDistanceField(float fieldRadius, int fieldBorder)
220 {
221   ImageAttributes attributes;
222   attributes.impl->isDistanceField = true;
223   attributes.impl->fieldRadius = fieldRadius;
224   attributes.impl->fieldBorder = fieldBorder;
225   return attributes;
226 }
227
228 /**
229  * Less then comparison operator.
230  * @param [in] a parameter tested
231  * @param [in] b parameter tested
232  */
233 bool operator<(const ImageAttributes& a, const ImageAttributes& b)
234 {
235   // Bail out if one is distance field and the other is not.
236   if (a.impl->isDistanceField != b.impl->isDistanceField)
237   {
238     return a.impl->isDistanceField < b.impl->isDistanceField;
239   }
240
241   if (a.impl->width != b.impl->width)
242   {
243     return a.impl->width < b.impl->width;
244   }
245
246   if (a.impl->height != b.impl->height)
247   {
248     return a.impl->height < b.impl->height;
249   }
250
251   if (a.impl->mOrientationCorrection != b.impl->mOrientationCorrection)
252   {
253     return a.impl->mOrientationCorrection < b.impl->mOrientationCorrection;
254   }
255
256   if (a.impl->pixelformat != b.impl->pixelformat)
257   {
258     return a.impl->pixelformat < b.impl->pixelformat;
259   }
260
261   if (a.impl->scaling != b.impl->scaling)
262   {
263     return a.impl->scaling < b.impl->scaling;
264   }
265
266   if (a.impl->filtering != b.impl->filtering)
267   {
268     return a.impl->filtering < b.impl->filtering;
269   }
270
271   if (a.impl->isDistanceField && b.impl->isDistanceField)
272   {
273     if (fabs(a.impl->fieldRadius - b.impl->fieldRadius) > Math::MACHINE_EPSILON_0)
274     {
275       return a.impl->fieldRadius < b.impl->fieldRadius;
276     }
277
278     if (a.impl->fieldBorder != b.impl->fieldBorder)
279     {
280       return a.impl->fieldBorder < b.impl->fieldBorder;
281     }
282   }
283
284   // they are equal
285   return false;
286 }
287
288 /**
289  * Equal to comparison operator.
290  * @param [in] a parameter tested for equality
291  * @param [in] b parameter tested for equality
292  */
293 bool operator==(const ImageAttributes& a, const ImageAttributes& b)
294 {
295   return a.impl->width                  == b.impl->width       &&
296          a.impl->height                 == b.impl->height      &&
297          a.impl->mOrientationCorrection == b.impl->mOrientationCorrection &&
298          a.impl->pixelformat            == b.impl->pixelformat &&
299          a.impl->scaling                == b.impl->scaling     &&
300          a.impl->filtering              == b.impl->filtering     &&
301          a.impl->isDistanceField  == b.impl->isDistanceField &&
302          fabs(a.impl->fieldRadius -  b.impl->fieldRadius) < Math::MACHINE_EPSILON_0 &&
303          a.impl->fieldBorder      == b.impl->fieldBorder;
304 }
305
306 /**
307  * Not equal to comparison operator.
308  * @param [in] a parameter tested for equality
309  * @param [in] b parameter tested for equality
310  */
311 bool operator!=(const ImageAttributes& a, const ImageAttributes& b)
312 {
313   return !(a == b);
314 }
315
316 } // namespace Dali