Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / effect / FGrp_EffectAlpha.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /*
19  * @file        FGrp_EffectAlpha.cpp
20  * @brief       This is the header file for internal utility class.
21  *
22  */
23
24 #include "FGrp_EffectFunc.h"
25 #include "FGrp_Effect.h"
26 #include "../util/FGrp_Util.h"
27
28 using namespace Tizen::Graphics;
29
30
31 ////////////////////////////////////////////////////////////////////////////////
32 // template _BltBlend()
33
34 namespace // unnamed
35 {
36
37 template <typename DestPixel, typename SourPixel>
38 inline void
39 _BltBlend(DestPixel* pDest, int w, int h, int pitch, SourPixel* pSour, int imagePitch, unsigned long opacity,
40                  _Util::ColorKey srcColorKey)
41 {
42         opacity += (opacity >> 7);
43
44         if (!srcColorKey.isValid)
45         {
46                 while (--h >= 0)
47                 {
48                         int copy = w;
49
50                         while (--copy >= 0)
51                         {
52                                 *pDest = _Effect::Func::AlphaBlending<DestPixel, SourPixel>(*pDest, *pSour++, DestPixel(opacity));
53                                 ++pDest;
54                         }
55
56                         pDest += (pitch - w);
57                         pSour += (imagePitch - w);
58                 }
59         }
60         else
61         {
62                 while (--h >= 0)
63                 {
64                         int copy = w;
65
66                         while (--copy >= 0)
67                         {
68                                 if (*pSour != srcColorKey.colorKey)
69                                 {
70                                         *pDest = _Effect::Func::AlphaBlending<DestPixel, SourPixel>(*pDest, *pSour, DestPixel(opacity));
71                                 }
72
73                                 ++pSour;
74                                 ++pDest;
75                         }
76
77                         pDest += (pitch - w);
78                         pSour += (imagePitch - w);
79                 }
80         }
81 }
82
83 template <typename DestPixel, typename SourPixel>
84 inline void
85 _BltCopy(DestPixel* pDest, int w, int h, int pitch, SourPixel* pSour, int imagePitch, _Util::ColorKey srcColorKey)
86 {
87         if (!srcColorKey.isValid)
88         {
89                 while (--h >= 0)
90                 {
91                         _Effect::Func::ConvertColorFormat(pDest, pSour, w);
92
93                         pDest += pitch;
94                         pSour += imagePitch;
95                 }
96         }
97         else
98         {
99                 while (--h >= 0)
100                 {
101                         int copy = w;
102
103                         while (--copy >= 0)
104                         {
105                                 if (*pSour != srcColorKey.colorKey)
106                                 {
107                                         _Effect::Func::ConvertColorFormat(pDest, pSour, 1);
108                                 }
109
110                                 ++pSour;
111                                 ++pDest;
112                         }
113
114                         pDest += (pitch - w);
115                         pSour += (imagePitch - w);
116                 }
117         }
118 }
119
120 ////////////////////////////////////////////////////////////////////////////
121 // static function (callback)
122
123 void
124 _BitbltFast32bitFrom32bit(unsigned long* pDest32, int w, int h, int pitch, unsigned long* pSour32, int imagePitch,
125                                                   unsigned long opacity,
126                                                   _Util::ColorKey srcColorKey)
127 {
128         _BltCopy<unsigned long, unsigned long>(pDest32, w, h, pitch, pSour32, imagePitch, srcColorKey);
129 }
130
131 void
132 _BitbltFast32bitFrom16bit(unsigned long* pDest32, int w, int h, int pitch, unsigned long* pSour32, int imagePitch,
133                                                   unsigned long opacity,
134                                                   _Util::ColorKey srcColorKey)
135 {
136         unsigned short* pSour16 = (unsigned short*) pSour32;
137
138         _BltCopy<unsigned long, unsigned short>(pDest32, w, h, pitch, pSour16, imagePitch, srcColorKey);
139 }
140
141 void
142 _BitbltFast16bitFrom32bit(unsigned short* pDest16, int w, int h, int pitch, unsigned short* pSour16, int imagePitch,
143                                                   unsigned long opacity,
144                                                   _Util::ColorKey srcColorKey)
145 {
146         unsigned long* pSour32 = (unsigned long*) pSour16;
147
148         _BltCopy<unsigned short, unsigned long>(pDest16, w, h, pitch, pSour32, imagePitch, srcColorKey);
149 }
150
151 void
152 _BitbltFast16bitFrom16bit(unsigned short* pDest16, int w, int h, int pitch, unsigned short* pSour16, int imagePitch,
153                                                   unsigned long opacity,
154                                                   _Util::ColorKey srcColorKey)
155 {
156         _BltCopy<unsigned short, unsigned short>(pDest16, w, h, pitch, pSour16, imagePitch, srcColorKey);
157 }
158
159 /////// ------
160
161 void
162 _BitbltAlpha32bitFrom32bit(unsigned long* pDest32, int w, int h, int pitch, unsigned long* pSour32, int imagePitch,
163                                                    unsigned long opacity,
164                                                    _Util::ColorKey srcColorKey)
165 {
166         _BltBlend<unsigned long, unsigned long>(pDest32, w, h, pitch, pSour32, imagePitch, opacity, srcColorKey);
167 }
168
169 void
170 _BitbltAlpha32bitFrom16bit(unsigned long* pDest32, int w, int h, int pitch, unsigned long* pSour32, int imagePitch,
171                                                    unsigned long opacity,
172                                                    _Util::ColorKey srcColorKey)
173 {
174         unsigned short* pSour16 = (unsigned short*) pSour32;
175
176         if (opacity >= 255)
177         {
178                 _BltCopy<unsigned long, unsigned short>(pDest32, w, h, pitch, pSour16, imagePitch, srcColorKey);
179         }
180         else
181         {
182                 _BltBlend<unsigned long, unsigned short>(pDest32, w, h, pitch, pSour16, imagePitch, opacity, srcColorKey);
183         }
184 }
185
186 void
187 _BitbltAlpha16bitFrom32bit(unsigned short* pDest16, int w, int h, int pitch, unsigned short* pSour16, int imagePitch,
188                                                    unsigned long opacity,
189                                                    _Util::ColorKey srcColorKey)
190 {
191         unsigned long* pSour32 = (unsigned long*) pSour16;
192
193         _BltBlend<unsigned short, unsigned long>(pDest16, w, h, pitch, pSour32, imagePitch, opacity, srcColorKey);
194 }
195
196 void
197 _BitbltAlpha16bitFrom16bit(unsigned short* pDest16, int w, int h, int pitch, unsigned short* pSour16, int imagePitch,
198                                                    unsigned long opacity,
199                                                    _Util::ColorKey srcColorKey)
200 {
201         _BltBlend<unsigned short, unsigned short>(pDest16, w, h, pitch, pSour16, imagePitch, opacity, srcColorKey);
202 }
203
204 ////////////////////////////////////////////////////////////////////////////
205 // static function
206
207 bool
208 _DrawImageWithAlpha(const _Util::Pixmap& dstImage, long xDest, long yDest, const _Util::Pixmap& srcImage, long constantAlpha)
209 {
210         _Util::ColorKey srcColorKey;
211
212         if (srcImage.enableColorKey)
213         {
214                 srcColorKey.isValid = true;
215                 srcColorKey.colorKey = srcImage.colorKey;
216         }
217
218         switch (dstImage.depth)
219         {
220         case 32:
221         {
222                 typedef unsigned long Pixel;
223
224                 _Util::ScratchPad<Pixel> dstScratchPad((Pixel*) dstImage.pBitmap, dstImage.width, dstImage.height,
225                                                                                                 dstImage.bytesPerLine / sizeof(Pixel));
226                 _Util::ScratchPad<Pixel> srcScratchPad((Pixel*) srcImage.pBitmap, srcImage.width, srcImage.height,
227                                                                                                 srcImage.bytesPerLine / sizeof(Pixel),
228                                                                                                 srcColorKey);
229
230                 srcScratchPad.SetPitch(srcImage.depth, srcImage.bytesPerLine);
231
232                 if (srcImage.isOpaque && constantAlpha >= 255)
233                 {
234                         dstScratchPad.RegisterBitBlt((srcImage.depth == 32) ? _BitbltFast32bitFrom32bit : _BitbltFast32bitFrom16bit);
235                 }
236                 else
237                 {
238                         dstScratchPad.RegisterBitBlt((srcImage.depth == 32) ? _BitbltAlpha32bitFrom32bit : _BitbltAlpha32bitFrom16bit);
239                 }
240
241                 dstScratchPad.BitBlt(xDest, yDest, &srcScratchPad, 0, 0, srcScratchPad.GetWidth(),
242                                                          srcScratchPad.GetHeight(), constantAlpha);
243         }
244                 break;
245         case 16:
246         {
247                 typedef unsigned short Pixel;
248
249                 _Util::ScratchPad<Pixel> dstScratchPad((Pixel*) dstImage.pBitmap, dstImage.width, dstImage.height,
250                                                                                                 dstImage.bytesPerLine / sizeof(Pixel));
251                 _Util::ScratchPad<Pixel> srcScratchPad((Pixel*) srcImage.pBitmap, srcImage.width, srcImage.height,
252                                                                                                 srcImage.bytesPerLine / sizeof(Pixel),
253                                                                                                 srcColorKey);
254
255                 srcScratchPad.SetPitch(srcImage.depth, srcImage.bytesPerLine);
256
257                 if (srcImage.isOpaque && constantAlpha >= 255)
258                 {
259                         dstScratchPad.RegisterBitBlt((srcImage.depth == 32) ? _BitbltFast16bitFrom32bit : _BitbltFast16bitFrom16bit);
260                 }
261                 else
262                 {
263                         dstScratchPad.RegisterBitBlt((srcImage.depth == 32) ? _BitbltAlpha16bitFrom32bit : _BitbltAlpha16bitFrom16bit);
264                 }
265
266                 dstScratchPad.BitBlt(xDest, yDest, &srcScratchPad, 0, 0, srcScratchPad.GetWidth(),
267                                                          srcScratchPad.GetHeight(), constantAlpha);
268         }
269                 break;
270         default:
271                 // assert(false);
272                 return false;
273         }
274
275         return true;
276 }
277
278 }
279
280 ////////////////////////////////////////////////////////////////////////////////
281 // public
282
283 bool
284 Tizen::Graphics::_Effect::DrawImageWithAlpha(_Util::Pixmap& dstImage, long xDest, long yDest, const _Util::Pixmap& srcImage, long constantAlpha)
285 {
286         // ÁÖ¾îÁø ÆĶó¹ÌÅÍ°¡ À¯È¿ÇÑÁö È®ÀÎÀ» ÇÑ´Ù.
287         {
288                 if ((srcImage.width < 0) || (srcImage.height < 0) || (srcImage.pBitmap == null))
289                 {
290                         return false;
291                 }
292
293                 if ((dstImage.width < 0) || (dstImage.height < 0) || (dstImage.pBitmap == null))
294                 {
295                         return false;
296                 }
297
298                 bool isSuitablePixelDepth =
299                         ((srcImage.depth == 16 || srcImage.depth == 32) && (dstImage.depth == 16 || dstImage.depth == 32));
300
301                 if (!isSuitablePixelDepth)
302                 {
303                         return false;
304                 }
305
306                 if (constantAlpha <= 0)
307                 {
308                         return true;
309                 }
310
311                 if (constantAlpha > 255)
312                 {
313                         constantAlpha = 255;
314                 }
315
316                 if (srcImage.pBitmap == dstImage.pBitmap)
317                 {
318                         return false;
319                 }
320         }
321
322         {
323                 if ((srcImage.width == 0) || (srcImage.height == 0))
324                 {
325                         return true;
326                 }
327
328                 if ((dstImage.width == 0) || (dstImage.height == 0))
329                 {
330                         return true;
331                 }
332
333                 {
334                         _Util::Rectangle<int> dstRect = { 0, 0, dstImage.width, dstImage.height };
335                         _Util::Rectangle<int> tgtRect = { xDest, yDest, srcImage.width, srcImage.height };
336                         _Util::Rectangle<int> outRect;
337
338                         if (!IntersectRect(outRect, tgtRect, dstRect))
339                         {
340                                 return true;
341                         }
342                 }
343         }
344
345         return _DrawImageWithAlpha(dstImage, xDest, yDest, srcImage, constantAlpha);
346 }