2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
19 * @file FGrp_CanvasPixman.cpp
20 * @brief This is the implementation file for the pixman solution.
28 #include "FGrp_CanvasPixman.h"
29 #include "util/FGrp_UtilTemplate.h"
32 namespace Tizen { namespace Graphics
39 AutoDeletor<pixman_image_t>::~AutoDeletor(void)
43 pixman_image_unref(__pPtr);
52 pixman_op_t GetRop(Tizen::Graphics::CompositeMode compositeMode)
54 switch (compositeMode)
56 case COMPOSITE_MODE_CLEAR:
57 return PIXMAN_OP_CLEAR;
58 case COMPOSITE_MODE_SRC:
60 case COMPOSITE_MODE_DST:
62 case COMPOSITE_MODE_SRC_OVER:
63 return PIXMAN_OP_OVER;
64 case COMPOSITE_MODE_DST_OVER:
65 return PIXMAN_OP_OVER_REVERSE;
66 case COMPOSITE_MODE_SRC_IN:
68 case COMPOSITE_MODE_DST_IN:
69 return PIXMAN_OP_IN_REVERSE;
70 case COMPOSITE_MODE_SRC_OUT:
72 case COMPOSITE_MODE_DST_OUT:
73 return PIXMAN_OP_OUT_REVERSE;
74 case COMPOSITE_MODE_SRC_ATOP:
75 return PIXMAN_OP_ATOP;
76 case COMPOSITE_MODE_DST_ATOP:
77 return PIXMAN_OP_ATOP_REVERSE;
78 case COMPOSITE_MODE_DST_XOR:
80 case COMPOSITE_MODE_ADD:
82 case COMPOSITE_MODE_SATURATE:
83 return PIXMAN_OP_SATURATE;
84 case COMPOSITE_MODE_MULTIPLY:
85 return PIXMAN_OP_MULTIPLY;
86 case COMPOSITE_MODE_SCREEN:
87 return PIXMAN_OP_SCREEN;
88 case COMPOSITE_MODE_OVERLAY:
89 return PIXMAN_OP_OVERLAY;
90 case COMPOSITE_MODE_DARKEN:
91 return PIXMAN_OP_DARKEN;
92 case COMPOSITE_MODE_LIGHTEN:
93 return PIXMAN_OP_LIGHTEN;
99 pixman_filter_t GetFilter(BitmapDrawingQuality drawingQuality)
101 switch (drawingQuality)
103 case Tizen::Graphics::BITMAP_DRAWING_QUALITY_HIGH:
104 return PIXMAN_FILTER_BEST;
105 case Tizen::Graphics::BITMAP_DRAWING_QUALITY_MID:
106 return PIXMAN_FILTER_GOOD;
108 return PIXMAN_FILTER_FAST;
112 pixman_filter_t GetFilter(BitmapScalingQuality scalingQuality)
114 switch (scalingQuality)
116 case Tizen::Graphics::BITMAP_SCALING_QUALITY_HIGH:
117 return PIXMAN_FILTER_BEST;
118 case Tizen::Graphics::BITMAP_SCALING_QUALITY_MID:
119 return PIXMAN_FILTER_GOOD;
121 return PIXMAN_FILTER_FAST;
125 pixman_transform_t GetTransform(int xDest, int yDest, double degree, int xPivot, int yPivot)
127 pixman_transform_t transform;
129 double c = cos(degree * 3.141592 / 180.0);
130 double s = sin(degree * 3.141592 / 180.0);
132 pixman_transform_init_identity(&transform);
134 pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(-xDest), pixman_int_to_fixed(-yDest));
135 pixman_transform_rotate(&transform, NULL, pixman_double_to_fixed(c), pixman_double_to_fixed(s));
136 pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(xPivot), pixman_int_to_fixed(yPivot));
141 pixman_transform_t GetTransform(double xDest, double yDest, double degree, double xPivot, double yPivot)
143 pixman_transform_t transform;
145 double c = cos(degree * 3.141592 / 180.0);
146 double s = sin(degree * 3.141592 / 180.0);
148 pixman_transform_init_identity(&transform);
150 pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(-xDest), pixman_double_to_fixed(-yDest));
151 pixman_transform_rotate(&transform, NULL, pixman_double_to_fixed(c), pixman_double_to_fixed(s));
152 pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(xPivot), pixman_double_to_fixed(yPivot));
157 pixman_transform_t GetTransform(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
159 pixman_transform_t transform;
161 pixman_transform_init_scale(&transform, 65536 * srcWidth / dstWidth, 65536 * srcHeight / dstHeight);
166 pixman_transform_t GetTransform(int srcWidth, int srcHeight, double xDest, double yDest, double wDest, double hDest)
168 pixman_transform_t transform;
170 pixman_transform_init_identity(&transform);
172 pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(-xDest), pixman_double_to_fixed(-yDest));
173 pixman_transform_scale(&transform, NULL, 65536 * srcWidth / wDest, 65536 * srcHeight / hDest);
178 bool ResizePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, pixman_filter_t filter)
180 Tizen::Graphics::_Util::AutoDeletor<pixman_image_t> pPixmanDst;
182 switch (dstImage.depth)
185 pPixmanDst.Bind(pixman_image_create_bits(PIXMAN_r5g6b5, dstImage.width, dstImage.height, (uint32_t*)dstImage.pBitmap, dstImage.bytesPerLine));
188 pPixmanDst.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, dstImage.width, dstImage.height, (uint32_t*)dstImage.pBitmap, dstImage.bytesPerLine));
196 Tizen::Graphics::_Util::AutoDeletor<pixman_image_t> pPixmanSrc;
198 switch (srcImage.depth)
201 // color key is not supporting
202 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_r5g6b5, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
205 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
213 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(srcImage.width, srcImage.height, dstImage.width, dstImage.height);
215 pixman_image_set_transform(pPixmanSrc, &transform);
217 pixman_image_set_filter(pPixmanSrc, filter, NULL, 0);
219 pixman_image_set_repeat(pPixmanSrc, PIXMAN_REPEAT_REFLECT);
221 pixman_image_composite32(PIXMAN_OP_SRC, pPixmanSrc, 0, pPixmanDst, 0, 0, 0, 0, 0, 0, dstImage.width, dstImage.height);
230 bool CompositePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, int rop, pixman_filter_t filter, pixman_transform_t transform, pixman_repeat_t repeatMethod)
232 Tizen::Graphics::_Util::AutoDeletor<pixman_image_t> pPixmanDst;
234 switch (dstImage.depth)
237 pPixmanDst.Bind(pixman_image_create_bits(PIXMAN_r5g6b5, dstImage.width, dstImage.height, (uint32_t*)dstImage.pBitmap, dstImage.bytesPerLine));
240 pPixmanDst.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, dstImage.width, dstImage.height, (uint32_t*)dstImage.pBitmap, dstImage.bytesPerLine));
248 std::auto_ptr<Tizen::Graphics::_Util::Pixmap> premultipliedSrcImage;
250 Tizen::Graphics::_Util::AutoDeletor<pixman_image_t> pPixmanMsk;
251 Tizen::Graphics::_Util::AutoDeletor<pixman_image_t> pPixmanSrc;
253 switch (srcImage.depth)
256 // color key is not supporting
257 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_r5g6b5, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
260 if (srcImage.isPremultiplied || rop == PIXMAN_OP_COPY)
262 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
267 bool isInternalSolutionEnable = !((dstImage.width == srcImage.width) && (dstImage.height == srcImage.height) && pixman_transform_is_identity(&transform));
269 if (isInternalSolutionEnable)
271 premultipliedSrcImage.reset(srcImage.GetPremultipliedPixmap());
273 if (premultipliedSrcImage.get())
275 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, premultipliedSrcImage->width, premultipliedSrcImage->height, (uint32_t*)premultipliedSrcImage->pBitmap, premultipliedSrcImage->bytesPerLine));
282 // slow but it does not create additional buffer
283 pPixmanSrc.Bind(pixman_image_create_bits(PIXMAN_x8r8g8b8, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
284 pPixmanMsk.Bind(pixman_image_create_bits(PIXMAN_a8r8g8b8, srcImage.width, srcImage.height, (uint32_t*)srcImage.pBitmap, srcImage.bytesPerLine));
286 if (pPixmanMsk == null)
299 pixman_image_set_transform(pPixmanSrc, &transform);
303 pixman_image_set_transform(pPixmanMsk, &transform);
306 pixman_image_set_filter(pPixmanSrc, filter, NULL, 0);
307 pixman_image_set_repeat(pPixmanSrc, repeatMethod);
309 if (rop == PIXMAN_OP_COPY)
314 pixman_image_composite32(pixman_op_t(rop), pPixmanSrc, pPixmanMsk, pPixmanDst, 0, 0, 0, 0, 0, 0, dstImage.width, dstImage.height);
323 bool ResizePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapScalingQuality scalingQuality)
325 if (dstImage.width <= 0 || dstImage.height <= 0)
330 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(scalingQuality);
332 return ResizePixmap(dstImage, srcImage, filter);
335 bool CopyPixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality, Tizen::Graphics::CompositeMode compositeMode)
337 if (dstImage.width <= 0 || dstImage.height <= 0)
342 pixman_op_t rop = Tizen::Graphics::_Pixman::GetRop(compositeMode);
344 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
346 pixman_transform_t transform;
347 pixman_transform_init_identity(&transform);
349 return CompositePixmap(dstImage, srcImage, rop, filter, transform, PIXMAN_REPEAT_NONE);
352 bool CopyPixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality, Tizen::Graphics::CompositeMode compositeMode, double xDest, double yDest)
354 if (dstImage.width <= 0 || dstImage.height <= 0)
359 pixman_op_t rop = Tizen::Graphics::_Pixman::GetRop(compositeMode);
361 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
366 case PIXMAN_OP_IN_REVERSE:
368 case PIXMAN_OP_ATOP_REVERSE:
370 pixman_transform_t transform;
371 pixman_transform_init_identity(&transform);
372 pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(-(xDest - 0.5)), pixman_double_to_fixed(-(yDest - 0.5)));
374 return CompositePixmap(dstImage, srcImage, rop, filter, transform, PIXMAN_REPEAT_NONE);
378 int dstX1 = int(floor(xDest));
379 int dstX2 = int(ceil(xDest + srcImage.width));
380 int dstY1 = int(floor(yDest));
381 int dstY2 = int(ceil(yDest + srcImage.height));
383 Tizen::Graphics::_Util::Pixmap dstImageSub = dstImage.GetSubBitmap(dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1);
384 Tizen::Graphics::_Util::Pixmap srcImageSub = srcImage.GetSubBitmap((dstX1 >= 0) ? 0 : -dstX1, (dstY1 >= 0) ? 0 : -dstY1, srcImage.width, srcImage.height);
386 pixman_transform_t transform;
387 pixman_transform_init_identity(&transform);
388 pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(dstX1 -(xDest - 0.5)), pixman_double_to_fixed(dstY1 -(yDest - 0.5)));
389 return CompositePixmap(dstImageSub, srcImageSub, rop, filter, transform, PIXMAN_REPEAT_NONE);
394 bool ScalePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality, Tizen::Graphics::CompositeMode compositeMode)
396 if (dstImage.width <= 0 || dstImage.height <= 0)
401 if (dstImage.width == srcImage.width && dstImage.height == srcImage.height)
403 return CopyPixmap(dstImage, srcImage, drawingQuality, compositeMode);
406 pixman_op_t rop = Tizen::Graphics::_Pixman::GetRop(compositeMode);
407 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
408 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(srcImage.width, srcImage.height, dstImage.width, dstImage.height);
410 return CompositePixmap(dstImage, srcImage, rop, filter, transform, PIXMAN_REPEAT_NORMAL);
413 bool ScalePixmapOpCopy(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality)
415 if (dstImage.width <= 0 || dstImage.height <= 0)
420 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
421 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(srcImage.width, srcImage.height, dstImage.width, dstImage.height);
423 return CompositePixmap(dstImage, srcImage, PIXMAN_OP_COPY, filter, transform, PIXMAN_REPEAT_NORMAL);
426 bool ScalePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality, Tizen::Graphics::CompositeMode compositeMode, double xDest, double yDest, double wDest, double hDest)
428 if (dstImage.width <= 0 || dstImage.height <= 0)
433 pixman_op_t rop = Tizen::Graphics::_Pixman::GetRop(compositeMode);
434 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
439 case PIXMAN_OP_IN_REVERSE:
441 case PIXMAN_OP_ATOP_REVERSE:
443 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(srcImage.width, srcImage.height, xDest - 0.5, yDest - 0.5, wDest, hDest);
445 return CompositePixmap(dstImage, srcImage, rop, filter, transform, PIXMAN_REPEAT_NONE);
449 int dstX1 = int(floor(xDest));
450 int dstY1 = int(floor(yDest));
451 int dstX2 = int(ceil(xDest + wDest));
452 int dstY2 = int(ceil(yDest + hDest));
454 Tizen::Graphics::_Util::Pixmap dstImageSub = dstImage.GetSubBitmap(dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1);
455 Tizen::Graphics::_Util::Pixmap srcImageSub = srcImage.GetSubBitmap((dstX1 >= 0) ? 0 : int(-dstX1 * srcImage.width / wDest), (dstY1 >= 0) ? 0 : int(-dstY1 * srcImage.height / hDest), srcImage.width, srcImage.height);
457 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(srcImage.width, srcImage.height, (xDest - 0.5) - dstX1, (yDest - 0.5) - dstY1, wDest, hDest);
459 return CompositePixmap(dstImageSub, srcImageSub, rop, filter, transform, PIXMAN_REPEAT_NONE);
464 bool RotatePixmap(Tizen::Graphics::_Util::Pixmap& dstImage, const Tizen::Graphics::_Util::Pixmap& srcImage, Tizen::Graphics::BitmapDrawingQuality drawingQuality, Tizen::Graphics::CompositeMode compositeMode, double xDest, double yDest, double degree, double xPivot, double yPivot)
466 if (dstImage.width <= 0 || dstImage.height <= 0)
471 pixman_op_t rop = Tizen::Graphics::_Pixman::GetRop(compositeMode);
472 pixman_filter_t filter = Tizen::Graphics::_Pixman::GetFilter(drawingQuality);
473 pixman_transform_t transform = Tizen::Graphics::_Pixman::GetTransform(xDest, yDest, degree, xPivot, yPivot);
475 return CompositePixmap(dstImage, srcImage, rop, filter, transform, PIXMAN_REPEAT_NONE);
480 }} // Tizen::Graphics