Merge "Fix for Issue TDIS-4794" into tizen_2.1
[platform/framework/native/uifw.git] / src / graphics / FGrp_Canvas.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_Canvas.cpp
20  * @brief       This is the implementation file for _Canvas class.
21  *
22  */
23
24 #include <new>
25 #include <memory>
26
27 #include <cstdio>
28 #include <cmath>
29
30 #include <unique_ptr.h>
31
32 #include <Evas.h>
33
34 #include <FGrpBufferInfo.h>
35
36 #include <FBaseInternalTypes.h>
37 #include <FApp_AppInfo.h>
38
39 #include <FBaseSysLog.h>
40
41 #include "FGrp_BufferInfoImpl.h"
42 #include "FGrp_Callback.h"
43 #include "FGrp_Canvas.h"
44 #include "FGrp_CanvasGpPrimitive.h"
45 #include "FGrp_CanvasRasterOp.h"
46 #include "FGrp_Bitmap.h"
47 #include "FGrp_Font.h"
48 #include "FGrp_Screen.h"
49 #include "FGrp_ResUtil.h"
50 #include "FGrp_CanvasCairo.h"
51 #include "FGrp_CanvasPixman.h"
52 #include "util/FGrp_Util.h"
53 #include "effect/FGrp_Effect.h"
54
55 ////////////////////////////////////////////////////////////////////////////////
56
57 #if !defined(M_PI)
58 #define M_PI 3.14159265358979323846
59 #endif
60
61 #define USE_CAIRO
62
63 ////////////////////////////////////////////////////////////////////////////////
64
65 #define SET_CAIRO_ALL_PROPERTIES \
66         _Cairo::SetComposite(pCairo->pCairo, _ConvertParam<cairo_operator_t>(this->__compositeMode)); \
67         _Cairo::SetDash(pCairo->pCairo, this->__dashData.pattern.Begin(), int(this->__dashData.pattern.Size()), this->__dashData.offset); \
68         _Cairo::SetLineCap(pCairo->pCairo, _ConvertParam<cairo_line_cap_t>(this->__lineCapStyle)); \
69         _Cairo::SetLineJoin(pCairo->pCairo, _ConvertParam<cairo_line_join_t>(this->__lineJoinStyle)); \
70         if (this->__isClipBoundsSet) \
71         { \
72                 _Cairo::SetClip(pCairo->pCairo, this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height); \
73         }
74
75 #define RESET_CAIRO_ALL_PROPERTIES \
76         _Cairo::ResetComposite(pCairo->pCairo); \
77         _Cairo::ResetDash(pCairo->pCairo); \
78         _Cairo::ResetLineCap(pCairo->pCairo); \
79         _Cairo::ResetLineJoin(pCairo->pCairo); \
80         if (this->__isClipBoundsSet) \
81         { \
82                 _Cairo::ResetClip(pCairo->pCairo); \
83         }
84
85 #define SET_CAIRO_FILL_PROPERTIES \
86         _Cairo::SetComposite(pCairo->pCairo, _ConvertParam<cairo_operator_t>(this->__compositeMode)); \
87         if (this->__isClipBoundsSet) \
88         { \
89                 _Cairo::SetClip(pCairo->pCairo, this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height); \
90         }
91
92 #define RESET_CAIRO_FILL_PROPERTIES \
93         _Cairo::ResetComposite(pCairo->pCairo); \
94         if (this->__isClipBoundsSet) \
95         { \
96                 _Cairo::ResetClip(pCairo->pCairo); \
97         }
98
99
100
101 ////////////////////////////////////////////////////////////////////////////////
102
103 using namespace Tizen::Base;
104 using namespace Tizen::Base::Collection;
105 using namespace Tizen::Base::Utility;
106
107 ////////////////////////////////////////////////////////////////////////////////
108 // internal utility
109
110 namespace
111 {
112
113 template<typename Dest, typename Sour>
114 Dest _ConvertParam(Sour val);
115
116 template<>
117 Tizen::Graphics::_Effect::Rop
118 _ConvertParam(Tizen::Graphics::_Canvas::BlendOption blendOption)
119 {
120         switch (blendOption)
121         {
122         case Tizen::Graphics::_Canvas::BLEND_COPY:
123                 return Tizen::Graphics::_Effect::ROP_COPY;
124         case Tizen::Graphics::_Canvas::BLEND_ALPHABLEND:
125                 return Tizen::Graphics::_Effect::ROP_ALPHABLEND;
126         default:
127                 return Tizen::Graphics::_Effect::ROP_ALPHABLEND;
128         }
129 }
130
131 template<>
132 cairo_operator_t
133 _ConvertParam(Tizen::Graphics::CompositeMode compositeMode)
134 {
135         switch (compositeMode)
136         {
137         case Tizen::Graphics::COMPOSITE_MODE_CLEAR:
138                 return CAIRO_OPERATOR_CLEAR;
139         case Tizen::Graphics::COMPOSITE_MODE_SRC:
140                 return CAIRO_OPERATOR_SOURCE;
141         case Tizen::Graphics::COMPOSITE_MODE_DST:
142                 return CAIRO_OPERATOR_DEST;
143         case Tizen::Graphics::COMPOSITE_MODE_SRC_OVER:
144                 return CAIRO_OPERATOR_OVER;
145         case Tizen::Graphics::COMPOSITE_MODE_DST_OVER:
146                 return CAIRO_OPERATOR_DEST_OVER;
147         case Tizen::Graphics::COMPOSITE_MODE_SRC_IN:
148                 return CAIRO_OPERATOR_IN;
149         case Tizen::Graphics::COMPOSITE_MODE_DST_IN:
150                 return CAIRO_OPERATOR_DEST_IN;
151         case Tizen::Graphics::COMPOSITE_MODE_SRC_OUT:
152                 return CAIRO_OPERATOR_OUT;
153         case Tizen::Graphics::COMPOSITE_MODE_DST_OUT:
154                 return CAIRO_OPERATOR_DEST_OUT;
155         case Tizen::Graphics::COMPOSITE_MODE_SRC_ATOP:
156                 return CAIRO_OPERATOR_ATOP;
157         case Tizen::Graphics::COMPOSITE_MODE_DST_ATOP:
158                 return CAIRO_OPERATOR_DEST_ATOP;
159         case Tizen::Graphics::COMPOSITE_MODE_DST_XOR:
160                 return CAIRO_OPERATOR_XOR;
161         case Tizen::Graphics::COMPOSITE_MODE_ADD:
162                 return CAIRO_OPERATOR_ADD;
163         case Tizen::Graphics::COMPOSITE_MODE_SATURATE:
164                 return CAIRO_OPERATOR_SATURATE;
165         case Tizen::Graphics::COMPOSITE_MODE_MULTIPLY:
166                 return CAIRO_OPERATOR_MULTIPLY;
167         case Tizen::Graphics::COMPOSITE_MODE_SCREEN:
168                 return CAIRO_OPERATOR_SCREEN;
169         case Tizen::Graphics::COMPOSITE_MODE_OVERLAY:
170                 return CAIRO_OPERATOR_OVERLAY;
171         case Tizen::Graphics::COMPOSITE_MODE_DARKEN:
172                 return CAIRO_OPERATOR_DARKEN;
173         case Tizen::Graphics::COMPOSITE_MODE_LIGHTEN:
174                 return CAIRO_OPERATOR_LIGHTEN;
175         default:
176                 return CAIRO_OPERATOR_OVER;
177         }
178 }
179
180 template<>
181 cairo_line_cap_t
182 _ConvertParam(Tizen::Graphics::LineCapStyle lineCapStyle)
183 {
184         switch (lineCapStyle)
185         {
186         case Tizen::Graphics::LINE_CAP_STYLE_BUTT:
187                 return CAIRO_LINE_CAP_BUTT;
188         case Tizen::Graphics::LINE_CAP_STYLE_ROUND:
189                 return CAIRO_LINE_CAP_ROUND;
190         case Tizen::Graphics::LINE_CAP_STYLE_SQUARE:
191                 return CAIRO_LINE_CAP_SQUARE;
192         default:
193                 return CAIRO_LINE_CAP_ROUND;
194         }
195 }
196
197 template<>
198 cairo_line_join_t
199 _ConvertParam(Tizen::Graphics::LineJoinStyle lineJoinStyle)
200 {
201         switch (lineJoinStyle)
202         {
203         case Tizen::Graphics::LINE_JOIN_STYLE_BEVEL:
204                 return CAIRO_LINE_JOIN_BEVEL;
205         case Tizen::Graphics::LINE_JOIN_STYLE_ROUND:
206                 return CAIRO_LINE_JOIN_ROUND;
207         case Tizen::Graphics::LINE_JOIN_STYLE_MITER:
208                 return CAIRO_LINE_JOIN_MITER;
209         default:
210                 return CAIRO_LINE_JOIN_ROUND;
211         }
212 }
213
214 inline unsigned short
215 _ConvertRGB888ToRGB565(unsigned char red, unsigned char green, unsigned char blue)
216 {
217         typedef unsigned short ColorType;
218
219         return (ColorType(red >> 3) << 11) | (ColorType(green >> 2) << 5) | ColorType(blue >> 3);
220 }
221
222 Evas_Object*
223 _GetWindowSourceObject(Handle handle)
224 {
225         Evas_Object* pSourceObject = evas_object_image_source_get((Evas_Object*) handle);
226
227         return (pSourceObject) ? pSourceObject : (Evas_Object*) handle;
228 }
229
230 int
231 _GetWindowWidth(Handle handle)
232 {
233         int width = 0;
234         int height = 0;
235
236         evas_object_image_size_get(_GetWindowSourceObject(handle), &width, &height);
237
238         return width;
239 }
240
241 int
242 _GetWindowHeight(Handle handle)
243 {
244         int width = 0;
245         int height = 0;
246
247         evas_object_image_size_get(_GetWindowSourceObject(handle), &width, &height);
248
249         return height;
250 }
251
252 ///////////////////////////////////////////////
253 // class _GenericBufferFrameBuffer
254
255 template<typename Pixel>
256 class _GenericBufferFrameBuffer
257         : public Tizen::Graphics::_Util::GenericBufferBase<Pixel>
258 {
259 public:
260         _GenericBufferFrameBuffer(Handle handle, int _width, int _height)
261         {
262                 this->__pAssociatedBuffer = this->_pBuffer = (Pixel*) evas_object_image_data_get(_GetWindowSourceObject(handle), EINA_TRUE);
263
264                 int pitch = evas_object_image_stride_get(_GetWindowSourceObject(handle)) / int(sizeof(Pixel));
265                 pitch = (pitch) ? pitch : _width;
266
267                 if (this->_pBuffer == null)
268                 {
269                         SysLog(NID_GRP, "[] evas_object_image_data_get(%d) failed!", handle);
270                 }
271
272                 this->_pitch = pitch;
273                 this->_padding = this->_pitch - _width;
274                 this->_rect.x = 0;
275                 this->_rect.y = 0;
276                 this->_rect.w = _width;
277                 this->_rect.h = _height;
278                 this->_pHandle = reinterpret_cast<void*>(handle);
279
280                 this->__associatedHandle = handle;
281                 this->__hasOwnership = false;
282         }
283
284         _GenericBufferFrameBuffer(Handle handle, int _x, int _y, int _width, int _height, int pitch)
285         {
286                 this->__pAssociatedBuffer = this->_pBuffer = (Pixel*) evas_object_image_data_get(_GetWindowSourceObject(handle), EINA_TRUE);
287
288                 if (pitch == 0)
289                 {
290                         pitch = evas_object_image_stride_get(_GetWindowSourceObject(handle)) / int(sizeof(Pixel));
291                         pitch = (pitch) ? pitch : _GetWindowWidth(handle);
292                 }
293
294                 if (this->_pBuffer == null)
295                 {
296                         SysLog(NID_GRP, "[] evas_object_image_data_get(%d) failed!", handle);
297                 }
298
299                 this->_pBuffer += (_y * pitch + _x);
300
301                 this->_pitch = pitch;
302                 this->_padding = this->_pitch - _width;
303                 this->_rect.x = _x;
304                 this->_rect.y = _y;
305                 this->_rect.w = _width;
306                 this->_rect.h = _height;
307                 this->_pHandle = reinterpret_cast<void*>(handle);
308
309                 this->__associatedHandle = handle;
310                 this->__hasOwnership = false;
311         }
312
313         _GenericBufferFrameBuffer(int width, int height)
314                 : __pAssociatedBuffer(0)
315         {
316                 this->_pBuffer = new (std::nothrow) Pixel[width * height];
317
318                 if (this->_pBuffer == null)
319                 {
320                         width = 0;
321                         height = 0;
322                 }
323
324                 this->_pitch = width;
325                 this->_padding = this->_pitch - width;
326                 this->_rect.x = 0;
327                 this->_rect.y = 0;
328                 this->_rect.w = width;
329                 this->_rect.h = height;
330                 this->_pHandle = 0;
331
332                 this->__associatedHandle = 0;
333                 this->__hasOwnership = (this->_pBuffer != null);
334         }
335
336         _GenericBufferFrameBuffer(Pixel* pBuffer, int width, int height, int pitch)
337                 : __pAssociatedBuffer(0)
338         {
339                 this->_pBuffer = pBuffer;
340
341                 this->_pitch = pitch;
342                 this->_padding = this->_pitch - width;
343                 this->_rect.x = 0;
344                 this->_rect.y = 0;
345                 this->_rect.w = width;
346                 this->_rect.h = height;
347                 this->_pHandle = 0;
348
349                 this->__associatedHandle = 0;
350                 this->__hasOwnership = false;
351         }
352
353         virtual ~_GenericBufferFrameBuffer(void)
354         {
355                 if (this->__associatedHandle != 0 && this->__pAssociatedBuffer != null)
356                 {
357                         evas_object_image_data_set(_GetWindowSourceObject(this->__associatedHandle), this->__pAssociatedBuffer);
358                 }
359
360                 if (this->__hasOwnership)
361                 {
362                         delete[] this->_pBuffer;
363                         this->_pBuffer = 0;
364                 }
365         }
366
367 private:
368         _GenericBufferFrameBuffer(const _GenericBufferFrameBuffer&);
369         _GenericBufferFrameBuffer& operator =(const _GenericBufferFrameBuffer&);
370
371         void* __pAssociatedBuffer;
372         Handle __associatedHandle;
373         bool __hasOwnership;
374
375 };
376
377 }
378
379
380 namespace
381 {
382
383 enum _ClipResult
384 {
385         CLIP_REJECT, // Clipped rejected
386         CLIP_CLIPPED, // Clipped accepted
387         CLIP_ACCEPT // Accepted
388 };
389
390 _ClipResult
391 _ClipRectangle(int& srcX, int& srcY, int& srcW, int& srcH, int clipX, int clipY, int clipW, int clipH)
392 {
393         if (clipW <= 0 || clipH <= 0)
394         {
395                 return CLIP_REJECT;
396         }
397
398         _ClipResult returnValue = CLIP_ACCEPT;
399
400         int srcEndX = srcX + srcW - 1;
401         int srcEndY = srcY + srcH - 1;
402         int clipEndX = clipX + clipW - 1;
403         int clipEndY = clipY + clipH - 1;
404
405         if (srcX > clipEndX || srcEndX < clipX)
406         {
407                 return CLIP_REJECT;
408         }
409
410         if (srcY > clipEndY || srcEndY < clipY)
411         {
412                 return CLIP_REJECT;
413         }
414
415         if (srcX < clipX)
416         {
417                 srcX = clipX;
418
419                 returnValue = CLIP_CLIPPED;
420         }
421
422         if (srcEndX > clipEndX)
423         {
424                 srcEndX = clipEndX;
425
426                 returnValue = CLIP_CLIPPED;
427         }
428
429         if (srcY < clipY)
430         {
431                 srcY = clipY;
432
433                 returnValue = CLIP_CLIPPED;
434         }
435
436         if (srcEndY > clipEndY)
437         {
438                 srcEndY = clipEndY;
439
440                 returnValue = CLIP_CLIPPED;
441         }
442
443         srcW = srcEndX - srcX + 1;
444         srcH = srcEndY - srcY + 1;
445
446         return returnValue;
447 }
448
449 unsigned long
450 _ComposeColor(unsigned long color32, int opacity)
451 {
452         unsigned char alpha = (unsigned char) (((color32) >> 24));
453         unsigned char red = (unsigned char) (((color32) >> 16));
454         unsigned char green = (unsigned char) (((color32) >> 8));
455         unsigned char blue = (unsigned char) ((color32));
456
457         alpha = (unsigned char) ((alpha * opacity + 255) >> 8);
458         red = (unsigned char) ((red * opacity + 255) >> 8);
459         green = (unsigned char) ((green * opacity + 255) >> 8);
460         blue = (unsigned char) ((blue * opacity + 255) >> 8);
461
462         return (unsigned long) (((unsigned long) (alpha) << 24) | ((unsigned long) (red) << 16) | ((unsigned long) (green) << 8) | (unsigned long) (blue));
463 }
464
465 template<typename Pixel>
466 void
467 _ClearRectangleWithClip(Tizen::Graphics::_Util::ScratchPad<Pixel>* pScratchPad, Pixel color, const Tizen::Graphics::_Util::Rectangle<int>& rect, const Tizen::Graphics::_Util::Rectangle<int>& clip)
468 {
469         if (pScratchPad == null)
470         {
471                 return;
472         }
473
474         // clipping
475         int x1 = rect.x;
476         int y1 = rect.y;
477         int x2 = x1 + rect.w;
478         int y2 = y1 + rect.h;
479
480         x1 = (x1 >= clip.x) ? x1 : clip.x;
481         y1 = (y1 >= clip.y) ? y1 : clip.y;
482
483         x2 = (x2 <= clip.x + clip.w) ? x2 : clip.x + clip.w;
484         y2 = (y2 <= clip.y + clip.h) ? y2 : clip.y + clip.h;
485
486         if ((x2 - x1) > 0 && (y2 - y1) > 0)
487         {
488                 pScratchPad->FillRect(x1, y1, x2 - x1, y2 - y1, color);
489         }
490 }
491
492 template<typename Pixel>
493 void
494 _FillRectangleWithClip(Tizen::Graphics::_Util::ScratchPad<Pixel>* pScratchPad, Pixel color, const Tizen::Graphics::_Util::Rectangle<int>& rect, const Tizen::Graphics::_Util::Rectangle<int>& clip)
495 {
496         if (pScratchPad == null)
497         {
498                 return;
499         }
500
501         // alpha-fill-rect() applied
502         pScratchPad->RegisterFillRect(Tizen::Graphics::_RasterOp::FnFillRectAlpha32Bit);
503         _ClearRectangleWithClip(pScratchPad, color, rect, clip);
504         pScratchPad->RegisterFillRect(null);
505 }
506
507 }
508
509 namespace
510 {
511
512 typedef Tizen::Graphics::_Canvas::SystemPixel _SystemPixel;
513 typedef Tizen::Graphics::_Util::ScratchPad<_SystemPixel> _ScratchPad32;
514
515 static std::unique_ptr<_SystemPixel[]> _systemFontBuffer;
516 static std::auto_ptr<_ScratchPad32> _systemFont;
517
518 }
519
520 ////////////////////////////////////////////////////////////////////////////////
521 // Tizen::Graphics::_Canvas
522
523 namespace Tizen { namespace Graphics
524 {
525
526 bool _CanvasShowFromMemory(int xDest, int yDest, int xSour, int ySour, int wSour, int hSour, void* pMemory, int width, int height, int depth, int bytesPerLine);
527 void _FlushCanvas(void);
528
529 namespace
530 {
531
532 void
533 _ApplySrcBitmapAttrib(_Util::Pixmap& srcImage, const _Bitmap& bitmap, long isOpaque)
534 {
535         Color maskingColor;
536
537         if (bitmap.GetBitsPerPixel() == 16)
538         {
539                 if (bitmap.GetMaskingColor(maskingColor) == E_SUCCESS)
540                 {
541                         srcImage.enableColorKey = 1;
542                         srcImage.colorKey = _ConvertRGB888ToRGB565(maskingColor.GetRed(), maskingColor.GetGreen(), maskingColor.GetBlue());
543                 }
544         }
545
546         srcImage.isOpaque = isOpaque;
547         srcImage.isPremultiplied = bitmap.IsPremultiplied();
548 }
549
550 // retrieving bounds rectangle which has (0,0,w,h).
551 Rectangle
552 _GetBoundsRel(const _Canvas& canvas)
553 {
554         Rectangle rect = canvas.GetBounds();
555         rect.x = 0;
556         rect.y = 0;
557
558         return rect;
559 }
560 }
561
562 void
563 _FillRectangleWithClip32(_Util::ScratchPad<unsigned long>* pScratchPad, unsigned long color, const _Util::Rectangle<int>& rect, const _Util::Rectangle<int>& clip)
564 {
565         _FillRectangleWithClip(pScratchPad, color, rect, clip);
566 }
567
568 struct _NativeGfxEngine
569 {
570         cairo_t* pCairo;
571         cairo_surface_t* pCairoSurface;
572
573         _NativeGfxEngine()
574                 : pCairo(0)
575                 , pCairoSurface(0)
576         {
577         }
578         ~_NativeGfxEngine()
579         {
580                 if (pCairo)
581                 {
582                         cairo_destroy(pCairo);
583                 }
584
585                 if (pCairoSurface)
586                 {
587                         cairo_surface_destroy(pCairoSurface);
588                 }
589         }
590 };
591
592
593 _Canvas::_Canvas(void)
594         : _pNativeGfxEngine(static_cast<void*>(new (std::nothrow)_NativeGfxEngine))
595         , __pParent(0)
596         , __pFont(0)
597         , __pPriorityFont(0)
598         , __windowHandle(INVALID_HANDLE)
599         , __blendOption(Tizen::Graphics::_Canvas::BLEND_ALPHABLEND)
600         , __pSurface(0)
601         , __pScratchPad(0)
602         , __xBufferPos(0)
603         , __yBufferPos(0)
604         , __pBuffer(0)
605         , __fgColor(0xFFFFFFFF)
606         , __bgColor(0x00000000)
607         , __fgOpacity(255)
608         , __bgOpacity(255)
609         , __lineWidth(1)
610         , __lineStyle(LINE_STYLE_SOLID)
611         , __lineCapStyle(LINE_CAP_STYLE_ROUND)
612         , __lineJoinStyle(LINE_JOIN_STYLE_ROUND)
613         , __isClipBoundsSet(false)
614         , __textOrigin(TEXT_ORIGIN_LEFT_TOP)
615         , __applyEmoji(true)
616         , __bitmapDrawingQuality(BITMAP_DRAWING_QUALITY_LOW)
617         , __compositeMode(COMPOSITE_MODE_SRC_OVER)
618         , __useStableRenderer(false)
619 {
620         __fgColorNative = Color(__fgColor);
621         __bgColorNative = Color(__bgColor);
622
623         __dashData.offset = 0;
624
625         __ComposeFgColor();
626         __ComposeBgColor();
627 }
628
629 _Canvas::~_Canvas(void)
630 {
631         delete __pScratchPad;
632         delete __pSurface;
633
634         if (_pNativeGfxEngine)
635         {
636                 delete static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
637         }
638 }
639
640 result
641 _Canvas::Construct(void)
642 {
643         return this->Construct(Rectangle(0, 0, _Screen::GetWidth(), _Screen::GetHeight()));
644 }
645
646 result
647 _Canvas::Construct(const Rectangle& rect)
648 {
649         result r = E_SUCCESS;
650
651         _GenericBufferFrameBuffer<SystemPixel>* pTemp = new (std::nothrow) _GenericBufferFrameBuffer<SystemPixel>(rect.width, rect.height);
652
653         SysTryReturnResult(NID_GRP, pTemp, E_OUT_OF_MEMORY, " _GenericBufferFrameBuffer<> cannot be allocated.");
654
655         this->__pSurface = new (std::nothrow) _Util::GenericBuffer<SystemPixel>(pTemp);
656
657         SysTryCatch(NID_GRP, this->__pSurface, delete pTemp;
658                            r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] _Util::GenericBuffer<> cannot be allocated.");
659
660         this->__pBuffer = (unsigned long*) __pSurface->GetBufferAddr();
661         this->__pScratchPad = new (std::nothrow) _Util::ScratchPad<SystemPixel>(__pBuffer, rect.width, rect.height, rect.width);
662
663         SysTryCatch(NID_GRP, this->__pScratchPad, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] _Util::ScratchPad<> cannot be allocated.");
664
665         this->__pScratchPad->FillRect(0, 0, this->__pScratchPad->GetWidth(), this->__pScratchPad->GetHeight(), 0x00000000);
666
667         this->__xBufferPos = rect.x;
668         this->__yBufferPos = rect.y;
669
670 #if defined(USE_CAIRO)
671         {
672                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
673
674                 if (pCairo)
675                 {
676                         pCairo->pCairoSurface = cairo_image_surface_create_for_data((unsigned char*) this->__pBuffer, CAIRO_FORMAT_ARGB32, rect.width, rect.height, rect.width * 4);
677                         pCairo->pCairo = cairo_create(pCairo->pCairoSurface);
678                 }
679         }
680 #endif
681
682         __InitFgBgColorFromTheme();
683
684         return E_SUCCESS;
685
686 CATCH:
687         delete this->__pScratchPad;
688         this->__pScratchPad = null;
689
690         delete this->__pSurface;
691         this->__pSurface = null;
692
693         return r;
694 }
695
696 result
697 _Canvas::Construct(Handle windowHandle)
698 {
699         return this->Construct(windowHandle, Rectangle(0, 0, _GetWindowWidth(windowHandle), _GetWindowHeight(windowHandle)));
700 }
701
702 result
703 _Canvas::Construct(Handle windowHandle, const Rectangle& rect)
704 {
705         SysTryReturnResult(NID_GRP, rect.width >= 0 && rect.height >= 0, E_OUT_OF_RANGE, "The given rectangle(width:%d,height:%d) is out of range.\n", rect.width, rect.height);
706
707         result r = E_SUCCESS;
708
709         int x1 = rect.x;
710         int y1 = rect.y;
711         int x2 = x1 + rect.width;
712         int y2 = y1 + rect.height;
713
714         if (x1 < 0)
715         {
716                 x1 = 0;
717         }
718
719         if (y1 < 0)
720         {
721                 y1 = 0;
722         }
723
724         if (x2 > _GetWindowWidth(windowHandle))
725         {
726                 x2 = _GetWindowWidth(windowHandle);
727         }
728
729         if (y2 > _GetWindowHeight(windowHandle))
730         {
731                 y2 = _GetWindowHeight(windowHandle);
732         }
733
734         SysTryReturnResult(NID_GRP, (x2 - x1 >= 0) && (y2 - y1 >= 0), E_OUT_OF_RANGE, "The given rectangle(x1:%d,y1:%d,x2:%d,y2:%d) is out of range.", x1, y1, x2, y2);
735
736         int bufferWidth = x2 - x1;
737         int bufferHeight = y2 - y1;
738         int sourcePitch = 0;
739
740         _GenericBufferFrameBuffer<SystemPixel>* pTemp = new (std::nothrow) _GenericBufferFrameBuffer<SystemPixel>(windowHandle, x1, y1, bufferWidth, bufferHeight, 0);
741
742         SysTryReturnResult(NID_GRP, pTemp, E_OUT_OF_MEMORY, "_GenericBufferFrameBuffer<> cannot be allocated.");
743
744         SysTryCatch(NID_GRP, !(pTemp->GetBufferAddr() == null && bufferWidth > 0 && bufferHeight > 0), delete pTemp; r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The associated Evas buffer is NULL.");
745
746         this->__pSurface = new (std::nothrow) _Util::GenericBuffer<SystemPixel>(pTemp);
747
748         SysTryCatch(NID_GRP, this->__pSurface, delete pTemp; r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] _Util::GenericBuffer<> cannot be allocated.");
749
750         this->__pBuffer = (unsigned long*) __pSurface->GetBufferAddr();
751         sourcePitch = __pSurface->GetPitch();
752
753         this->__pScratchPad = new (std::nothrow) _Util::ScratchPad<SystemPixel>(__pBuffer, bufferWidth, bufferHeight, sourcePitch);
754
755         SysTryCatch(NID_GRP, this->__pScratchPad, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] _Util::ScratchPad<> cannot be allocated.");
756
757         this->__windowHandle = windowHandle;
758
759         this->__xBufferPos = x1;
760         this->__yBufferPos = y1;
761
762 #if defined(USE_CAIRO)
763         {
764                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
765
766                 if (pCairo)
767                 {
768                         pCairo->pCairoSurface = cairo_image_surface_create_for_data((unsigned char*) this->__pBuffer, CAIRO_FORMAT_ARGB32, bufferWidth, bufferHeight, sourcePitch * 4);
769                         pCairo->pCairo = cairo_create(pCairo->pCairoSurface);
770                 }
771         }
772 #endif
773
774         __InitFgBgColorFromTheme();
775
776         return E_SUCCESS;
777
778 CATCH:
779         delete this->__pScratchPad;
780         this->__pScratchPad = null;
781
782         delete this->__pSurface;
783         this->__pSurface = null;
784
785         return r;
786 }
787
788 result
789 _Canvas::Construct(_Canvas* pSourceCanvas, const Rectangle& subRegion)
790 {
791         SysTryReturnResult(NID_GRP, pSourceCanvas, E_INVALID_ARG, "The source canvas is invalid");
792
793         SysTryReturnResult(NID_GRP, pSourceCanvas->IsValid(), E_INVALID_ARG, "The source canvas is invalid");
794
795         result r = E_SUCCESS;
796
797         int x1 = subRegion.x;
798         int y1 = subRegion.y;
799         int x2 = x1 + subRegion.width;
800         int y2 = y1 + subRegion.height;
801
802         if (x1 < 0)
803         {
804                 x1 = 0;
805         }
806
807         if (y1 < 0)
808         {
809                 y1 = 0;
810         }
811
812         if (x2 > pSourceCanvas->GetBounds().width)
813         {
814                 x2 = pSourceCanvas->GetBounds().width;
815         }
816
817         if (y2 > pSourceCanvas->GetBounds().height)
818         {
819                 y2 = pSourceCanvas->GetBounds().height;
820         }
821
822         SysTryReturnResult(NID_GRP, (x2 - x1 > 0) && (y2 - y1 > 0), E_OUT_OF_RANGE, "The given rectangle(x1:%d,y1:%d,x2:%d,y2:%d) is out of range.", subRegion.x, subRegion.y, subRegion.width, subRegion.height);
823
824         int bufferWidth = x2 - x1;
825         int bufferHeight = y2 - y1;
826
827         int sourcePitch = pSourceCanvas->__pSurface->GetPitch();
828
829         if (pSourceCanvas->__windowHandle != INVALID_HANDLE)
830         {
831                 _GenericBufferFrameBuffer<SystemPixel>* pTemp = new (std::nothrow) _GenericBufferFrameBuffer<SystemPixel>(pSourceCanvas->__windowHandle, x1, y1, bufferWidth, bufferHeight, sourcePitch);
832
833                 SysTryReturnResult(NID_GRP, pTemp, E_OUT_OF_MEMORY, "_GenericBufferFrameBuffer<> cannot be allocated.");
834
835                 if (pTemp->GetBufferAddr() == null && bufferWidth > 0 && bufferHeight > 0)
836                 {
837                         delete pTemp;
838                         SysTryReturnResult(NID_GRP, false, E_SYSTEM, "The associated Evas buffer is NULL.");
839                 }
840
841                 this->__pSurface = new (std::nothrow) _Util::GenericBuffer<SystemPixel>(pTemp);
842
843                 if (this->__pSurface == null)
844                 {
845                         delete pTemp;
846                         SysTryReturnResult(NID_GRP, false, E_OUT_OF_MEMORY, "_Util::GenericBuffer<> cannot be allocated.");
847                 }
848         }
849         else
850         {
851                 SystemPixel* pBuffer = pSourceCanvas->__pSurface->GetBufferAddr();
852                 pBuffer += y1 * sourcePitch + x1;
853
854                 _GenericBufferFrameBuffer<SystemPixel>* pTemp = new (std::nothrow) _GenericBufferFrameBuffer<SystemPixel>(pBuffer, bufferWidth, bufferHeight, sourcePitch);
855
856                 SysTryReturnResult(NID_GRP, pTemp, E_OUT_OF_MEMORY, "_GenericBufferFrameBuffer<> cannot be allocated.");
857
858                 this->__pSurface = new (std::nothrow) _Util::GenericBuffer<SystemPixel>(pTemp);
859
860                 if (this->__pSurface == null)
861                 {
862                         delete pTemp;
863                         SysTryReturnResult(NID_GRP, false, E_OUT_OF_MEMORY, "_Util::GenericBuffer<> cannot be allocated.");
864                 }
865         }
866
867         this->__pBuffer = (unsigned long*) __pSurface->GetBufferAddr();
868         this->__pScratchPad = new (std::nothrow) _Util::ScratchPad<SystemPixel>(__pBuffer, bufferWidth, bufferHeight, sourcePitch);
869
870         SysTryCatch(NID_GRP, this->__pScratchPad, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] _Util::ScratchPad<> cannot be allocated.");
871
872         this->__pParent = pSourceCanvas;
873         this->__xBufferPos = x1;
874         this->__yBufferPos = y1;
875
876         // duplicate
877         // must re-assign by _CanvasImpl::GetSubCanvasN()
878         this->__pFont = pSourceCanvas->__pFont;
879
880         this->__pPriorityFont = pSourceCanvas->__pPriorityFont;
881
882         // copy directly
883         this->__windowHandle = pSourceCanvas->__windowHandle;
884         this->__blendOption = pSourceCanvas->__blendOption;
885         this->__fgColor = pSourceCanvas->__fgColor;
886         this->__bgColor = pSourceCanvas->__bgColor;
887         this->__fgColorNative = pSourceCanvas->__fgColorNative;
888         this->__bgColorNative = pSourceCanvas->__bgColorNative;
889         this->__fgOpacity = pSourceCanvas->__fgOpacity;
890         this->__bgOpacity = pSourceCanvas->__bgOpacity;
891         this->__lineWidth = pSourceCanvas->__lineWidth;
892         this->__lineStyle = pSourceCanvas->__lineStyle;
893
894         // copy exception
895         this->__isClipBoundsSet = false;
896         this->__clipBounds = Rectangle(0, 0, bufferWidth, bufferHeight);
897
898 #if defined(USE_CAIRO)
899         {
900                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
901
902                 if (pCairo)
903                 {
904                         pCairo->pCairoSurface = cairo_image_surface_create_for_data((unsigned char*) this->__pBuffer, CAIRO_FORMAT_ARGB32, bufferWidth, bufferHeight, sourcePitch * 4);
905                         pCairo->pCairo = cairo_create(pCairo->pCairoSurface);
906                 }
907         }
908 #endif
909
910         return E_SUCCESS;
911
912 CATCH:
913         delete this->__pScratchPad;
914         this->__pScratchPad = null;
915
916         delete this->__pSurface;
917         this->__pSurface = null;
918
919         return r;
920 }
921
922 result
923 _Canvas::Construct(const BufferInfo& bufferInfo)
924 {
925         // all parameters checked
926
927         result r = E_SUCCESS;
928
929         _GenericBufferFrameBuffer<SystemPixel>* pTemp = new (std::nothrow) _GenericBufferFrameBuffer<SystemPixel>(static_cast<SystemPixel*>(bufferInfo.pPixels), bufferInfo.width, bufferInfo.height, bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel);
930
931         SysTryReturnResult(NID_GRP
932                 , pTemp
933                 , E_OUT_OF_MEMORY
934                 , " _GenericBufferFrameBuffer<> cannot be allocated.");
935
936         this->__pSurface = new (std::nothrow) _Util::GenericBuffer<SystemPixel>(pTemp);
937
938         SysTryCatch(NID_GRP
939                 , this->__pSurface
940                 , delete pTemp; r = E_OUT_OF_MEMORY
941                 , E_OUT_OF_MEMORY
942                 , "[E_OUT_OF_MEMORY] _Util::GenericBuffer<> cannot be allocated.");
943
944         this->__pBuffer = (unsigned long*) __pSurface->GetBufferAddr();
945         this->__pScratchPad = new (std::nothrow) _Util::ScratchPad<SystemPixel>(__pBuffer, bufferInfo.width, bufferInfo.height, bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel);
946
947         SysTryCatch(NID_GRP
948                 , this->__pScratchPad
949                 , r = E_OUT_OF_MEMORY
950                 , E_OUT_OF_MEMORY
951                 , "[E_OUT_OF_MEMORY] _Util::ScratchPad<> cannot be allocated.");
952
953         this->__xBufferPos = 0;
954         this->__yBufferPos = 0;
955
956 #if defined(USE_CAIRO)
957         {
958                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
959
960                 if (pCairo)
961                 {
962                         pCairo->pCairoSurface = cairo_image_surface_create_for_data((unsigned char*) this->__pBuffer, CAIRO_FORMAT_ARGB32, bufferInfo.width, bufferInfo.height, bufferInfo.pitch);
963                         pCairo->pCairo = cairo_create(pCairo->pCairoSurface);
964                 }
965         }
966 #endif
967
968         __InitFgBgColorFromTheme();
969
970         return E_SUCCESS;
971
972 CATCH:
973         delete this->__pScratchPad;
974         this->__pScratchPad = null;
975
976         delete this->__pSurface;
977         this->__pSurface = null;
978
979         return r;
980 }
981
982 bool
983 _Canvas::IsValid() const
984 {
985         return (this && this->__pSurface);
986 }
987
988 result
989 _Canvas::Clear(void)
990 {
991         if (this->__isClipBoundsSet)
992         {
993                 _Util::Rectangle<int> clip =
994                 {
995                         this->__clipBounds.x,
996                         this->__clipBounds.y,
997                         this->__clipBounds.width,
998                         this->__clipBounds.height
999                 };
1000
1001                 _Util::Rectangle<int> rect =
1002                 {
1003                         0,
1004                         0,
1005                         __pScratchPad->GetWidth(),
1006                         __pScratchPad->GetHeight()
1007                 };
1008
1009                 _ClearRectangleWithClip(__pScratchPad, __bgColor, rect, clip);
1010         }
1011         else
1012         {
1013                 __pScratchPad->FillRect(0, 0, __pScratchPad->GetWidth(), __pScratchPad->GetHeight(), __bgColor);
1014         }
1015
1016         return E_SUCCESS;
1017 }
1018
1019 result
1020 _Canvas::Clear(const Rectangle& rect)
1021 {
1022         if ((rect.width == 0) || (rect.height == 0))
1023         {
1024                 return E_SUCCESS;
1025         }
1026
1027         if (this->__isClipBoundsSet)
1028         {
1029                 _Util::Rectangle<int> clip =
1030                 {
1031                         this->__clipBounds.x,
1032                         this->__clipBounds.y,
1033                         this->__clipBounds.width,
1034                         this->__clipBounds.height
1035                 };
1036
1037                 _Util::Rectangle<int> rect1 =
1038                 {
1039                         rect.x,
1040                         rect.y,
1041                         rect.width,
1042                         rect.height
1043                 };
1044
1045                 _ClearRectangleWithClip(__pScratchPad, __bgColor, rect1, clip);
1046         }
1047         else
1048         {
1049                 __pScratchPad->FillRect(rect.x, rect.y, rect.width, rect.height, __bgColor);
1050         }
1051
1052         return E_SUCCESS;
1053 }
1054
1055 result
1056 _Canvas::Copy(const Point& destPoint, const _Canvas& canvas, const Rectangle& srcRect)
1057 {
1058         // special case
1059         if (srcRect.width == 0 || srcRect.height == 0)
1060         {
1061                 return E_SUCCESS;
1062         }
1063
1064         return this->__Copy(destPoint, canvas, srcRect);
1065 }
1066
1067 result
1068 _Canvas::Copy(const Rectangle& destRect, const _Canvas& canvas, const Rectangle& srcRect)
1069 {
1070         // special case
1071         if (srcRect.width == 0 || srcRect.height == 0 || destRect.width == 0 || destRect.height == 0)
1072         {
1073                 return E_SUCCESS;
1074         }
1075
1076         return this->__Copy(destRect, canvas, srcRect);
1077 }
1078
1079 result
1080 _Canvas::Copy(const Point& destPoint, const _Canvas& canvas, const Rectangle& srcRect, CompositeMode compositeMode)
1081 {
1082         _Util::LockManager srcLock(canvas);
1083         _Util::LockManager dstLock(*this);
1084
1085         SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source canvas cannot be locked.");
1086         SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked");
1087
1088         const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1089         const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1090
1091         {
1092                 _Util::Pixmap srcImageUnclipped(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1093                 _Util::Pixmap srcImage = srcImageUnclipped.GetSubBitmap(srcRect.x, srcRect.y, srcRect.width, srcRect.height);
1094
1095                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1096                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(destPoint.x, destPoint.y, srcRect.width, srcRect.height);
1097
1098                 _Pixman::CopyPixmap(dstImage, srcImage, GetDrawingQuality(), compositeMode);
1099         }
1100
1101         return E_SUCCESS;
1102 }
1103
1104 result
1105 _Canvas::CopyReverse(const Point& destPoint, const _Canvas& srcCanvas, const Rectangle& srcRect)
1106 {
1107         // special case
1108         if (srcRect.width == 0 || srcRect.height == 0)
1109         {
1110                 return E_SUCCESS;
1111         }
1112
1113         if (__pScratchPad == null)
1114         {
1115                 return E_SYSTEM;
1116         }
1117
1118         const _Canvas* pSrcCanvas = &srcCanvas;
1119
1120         if (pSrcCanvas == null)
1121         {
1122                 return E_SYSTEM;
1123         }
1124
1125         if (pSrcCanvas->__pScratchPad == null)
1126         {
1127                 return E_SYSTEM;
1128         }
1129
1130         Rectangle clippedSrcRect(srcRect);
1131
1132         if (_ClipRectangle(clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height, 0, 0, pSrcCanvas->__pScratchPad->GetWidth(), pSrcCanvas->__pScratchPad->GetHeight()) == CLIP_REJECT)
1133         {
1134                 return E_SYSTEM;
1135         }
1136
1137         __pScratchPad->RegisterBitBlt(_RasterOp::FnBitBlt32BitCopyReverse);
1138         __pScratchPad->BitBlt(destPoint.x, destPoint.y, pSrcCanvas->__pScratchPad, clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height);
1139         __pScratchPad->RegisterBitBlt(null);
1140
1141         return E_SUCCESS;
1142 }
1143
1144 namespace
1145 {
1146
1147 // spec. from SDK 1.0
1148
1149 template<typename T>
1150 void
1151 _ReviseAngle(T& startAngle, T& endAngle)
1152 {
1153         T zeroPi = T(0);
1154         T twoPi = T(360);
1155
1156         {
1157                 // startAngle = startAngle % twoPi;
1158                 int mod = int(startAngle / twoPi);
1159                 startAngle = startAngle - twoPi * mod;
1160
1161                 //endAngle = endAngle % twoPi;
1162                 mod = int(endAngle / twoPi);
1163                 endAngle = endAngle - twoPi * mod;
1164         }
1165
1166         if (startAngle < zeroPi || endAngle < zeroPi)
1167         {
1168                 startAngle += twoPi;
1169                 endAngle += twoPi;
1170         }
1171
1172         if (startAngle > endAngle)
1173         {
1174                 endAngle += twoPi;
1175         }
1176 }
1177
1178 }
1179
1180 result
1181 _Canvas::DrawArc(const _Util::Rectangle<double>& bounds, double startAngle, double endAngle, ArcStyle arcStyle)
1182 {
1183         if ((bounds.w <= 0.0) || (bounds.h <= 0.0))
1184         {
1185                 return E_SUCCESS;
1186         }
1187
1188         // this->__lineWidth is always greater than 0
1189
1190         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
1191
1192         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
1193
1194         if (pCairo && pCairo->pCairo)
1195         {
1196                 SET_CAIRO_ALL_PROPERTIES;
1197
1198                 double startDstAngle = (180.0 / M_PI) * atan2(sin(startAngle*M_PI / 180.0) * bounds.w / bounds.h, cos(startAngle * M_PI / 180.0));
1199                 double endDstAngle = (180.0 / M_PI) * atan2(sin(endAngle * M_PI / 180.0) * bounds.w / bounds.h, cos(endAngle * M_PI / 180.0));
1200
1201                 startDstAngle += (abs(startAngle - startDstAngle) <= 90.0) ? 0.0 : (startDstAngle < 0.0 && startAngle >= 0.0) ? 360.0 : (startDstAngle >= 0.0 && startAngle < 0.0) ? -360.0 : 0.0;
1202                 endDstAngle += (abs(endAngle - endDstAngle) <= 90.0) ? 0.0 : (endDstAngle < 0.0 && endAngle >= 0.0) ? 360.0 : (endDstAngle >= 0.0 && endAngle < 0.0) ? -360.0 : 0.0;
1203
1204                 _ReviseAngle(startDstAngle, endDstAngle);
1205
1206                 switch (arcStyle)
1207                 {
1208                 case ARC_STYLE_ONLY:
1209                         if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
1210                         {
1211                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_ARC);
1212                         }
1213                         else
1214                         {
1215                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_ARC);
1216                         }
1217                         break;
1218
1219                 case ARC_STYLE_PIE:
1220                         if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
1221                         {
1222                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_PIE);
1223                         }
1224                         else
1225                         {
1226                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_PIE);
1227                         }
1228                         break;
1229
1230                 case ARC_STYLE_CHORD:
1231                         if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
1232                         {
1233                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_CHORD);
1234                         }
1235                         else
1236                         {
1237                                 _Cairo::DrawArc(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::DRAW_ARC_STYLE_CHORD);
1238                         }
1239                         break;
1240
1241                 case ARC_STYLE_FILLED_PIE:
1242                         _Cairo::FillArc(pCairo->pCairo, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::FILL_ARC_STYLE_PIE);
1243                         break;
1244
1245                 case ARC_STYLE_FILLED_CHORD:
1246                         _Cairo::FillArc(pCairo->pCairo, composedColor, bounds, startDstAngle, endDstAngle, _Cairo::FILL_ARC_STYLE_CHORD);
1247                         break;
1248
1249                 default:
1250                         return E_SYSTEM;
1251                 }
1252
1253                 RESET_CAIRO_ALL_PROPERTIES;
1254
1255                 return E_SUCCESS;
1256         }
1257         else
1258         {
1259                 _CanvasArc arc;
1260                 _GpBufferInfo info;
1261
1262                 memset(&info, 0, sizeof(info));
1263
1264                 SystemPixel* pBufferAddr = null;
1265                 int bufferPitch = 0;
1266
1267                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
1268
1269                 info.width = __pScratchPad->GetWidth();
1270                 info.height = __pScratchPad->GetHeight();
1271                 info.bitsPerPixel = 32;
1272                 info.pixelPerLine = bufferPitch;
1273                 info.pPixels = (void*) pBufferAddr;
1274                 info.color32 = composedColor;
1275                 info.isClipBoundsSet = this->__isClipBoundsSet;
1276                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
1277
1278                 arc.SetLineWidth(this->__lineWidth.asInteger);
1279
1280                 _ReviseAngle(startAngle, endAngle);
1281
1282                 return arc.DrawArc(int(bounds.x), int(bounds.y), int(bounds.w), int(bounds.h), int(startAngle), int(endAngle), arcStyle, info);
1283         }
1284 }
1285
1286 result
1287 _Canvas::DrawBitmap(const _Util::Rectangle<double>& rectD, const _Bitmap& bitmap)
1288 {
1289         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1290
1291         if (rectD.w <= 0 || rectD.h <= 0)
1292         {
1293                 return E_SUCCESS;
1294         }
1295
1296         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
1297
1298         Rectangle clipRect;
1299
1300         this->__GetClipBounds(clipRect);
1301
1302         _Util::Rectangle<int> rect =
1303         {
1304                 _DoubleToIntForPos(rectD.x),
1305                 _DoubleToIntForPos(rectD.y),
1306                 _DoubleToIntForSize(rectD.w),
1307                 _DoubleToIntForSize(rectD.h)
1308         };
1309
1310         {
1311                 bool pass = false;
1312
1313                 _Util::LockManager srcLock(bitmap);
1314                 _Util::LockManager dstLock(*this);
1315
1316                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1317                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1318
1319                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1320                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1321
1322                 {
1323                         if (!this->__useStableRenderer && srcBufferInfo.bitsPerPixel == 32)
1324                         {
1325                                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1326                                 _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1327
1328                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1329                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1330
1331                                 if  (alphaConstant < 255)
1332                                 {
1333                                         std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1334
1335                                         if (modifiedSrcImage != null)
1336                                         {
1337                                                 pass = _Pixman::ScalePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), rectD.x - clipRect.x, rectD.y - clipRect.y, rectD.w, rectD.h);
1338                                         }
1339                                 }
1340
1341                                 if (!pass)
1342                                 {
1343                                         pass = _Pixman::ScalePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), rectD.x - clipRect.x, rectD.y - clipRect.y, rectD.w, rectD.h);
1344                                 }
1345
1346                         }
1347
1348                         if (!pass)
1349                         {
1350                                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1351                                 _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1352
1353                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1354                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1355
1356                                 pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, rect.x - clipRect.x, rect.y - clipRect.y, rect.w, rect.h, srcImage, _ConvertParam<_Effect::Rop>(this->__blendOption));
1357                         }
1358
1359                 }
1360
1361                 if (pass)
1362                 {
1363                         return E_SUCCESS;
1364                 }
1365         }
1366
1367         {
1368                 _Util::Pixmap tmpImage(rect.w, rect.h, bitmap.GetBitsPerPixel());
1369
1370                 // copies the source bitmap to the scaled bitmap
1371                 {
1372                         // ykahn, 2011/10/11 patched
1373                         {
1374                                 _ApplySrcBitmapAttrib(tmpImage, bitmap, bitmap.__isOpaqueAllOver);
1375
1376                                 if (tmpImage.depth == 16)
1377                                 {
1378                                         if (tmpImage.enableColorKey)
1379                                         {
1380                                                 typedef unsigned short Pixel;
1381
1382                                                 Pixel colorKey = (Pixel) tmpImage.colorKey;
1383                                                 Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1384                                                 Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1385
1386                                                 while (pDest < pDestEnd)
1387                                                 {
1388                                                         *pDest++ = colorKey;
1389                                                 }
1390                                         }
1391                                         else
1392                                         {
1393                                                 ;
1394                                         }
1395                                 }
1396                                 else if (tmpImage.depth == 32)
1397                                 {
1398                                         typedef unsigned long Pixel;
1399
1400                                         Pixel fillColor = 0;
1401                                         Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1402                                         Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1403
1404                                         while (pDest < pDestEnd)
1405                                         {
1406                                                 *pDest++ = fillColor;
1407                                         }
1408                                 }
1409                         }
1410
1411                         bool pass = false;
1412
1413                         {
1414                                 _Util::LockManager srcLock(bitmap);
1415                                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1416
1417                                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1418
1419                                 {
1420                                         _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1421                                         _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1422
1423                                         pass = Tizen::Graphics::_Effect::ScaleImage(tmpImage, 0, 0, rect.w, rect.h, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1424                                 }
1425                         }
1426
1427                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1428                 }
1429
1430                 {
1431                         bool pass = false;
1432
1433                         {
1434                                 _Util::LockManager dstLock(*this);
1435                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1436
1437                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1438
1439                                 {
1440                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1441                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1442
1443                                         pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, rect.x - clipRect.x, rect.y - clipRect.y, tmpImage, alphaConstant);
1444                                 }
1445                         }
1446
1447                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1448                 }
1449
1450                 return E_SUCCESS;
1451         }
1452 }
1453
1454 result
1455 _Canvas::DrawBitmap(const _Util::Point<double>& pointD, const _Bitmap& bitmap)
1456 {
1457         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1458
1459         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
1460
1461         {
1462                 Rectangle clipRect;
1463
1464                 this->__GetClipBounds(clipRect);
1465
1466                 bool pass = false;
1467
1468                 {
1469                         _Util::Point<int> point =
1470                         {
1471                                 _DoubleToIntForPos(pointD.x),
1472                                 _DoubleToIntForPos(pointD.y)
1473                         };
1474
1475                         _Util::LockManager srcLock(bitmap);
1476                         _Util::LockManager dstLock(*this);
1477
1478                         SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1479                         SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1480
1481                         const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1482                         const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1483
1484                         {
1485                                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1486                                 _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1487
1488                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1489                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1490
1491                                 if (srcBufferInfo.pixelFormat == PIXEL_FORMAT_RGB565 && srcImage.enableColorKey == 0 && dstBufferInfo.pixelFormat == PIXEL_FORMAT_ARGB8888 && !this->__isClipBoundsSet)
1492                                 {
1493                                         pixman_image_t* pPixmanSrc = pixman_image_create_bits(PIXMAN_r5g6b5, srcBufferInfo.width, srcBufferInfo.height, (uint32_t*)srcBufferInfo.pPixels, srcBufferInfo.pitch);
1494                                         pixman_image_t* pPixmanDst = pixman_image_create_bits(PIXMAN_a8r8g8b8, dstBufferInfo.width, dstBufferInfo.height, (uint32_t*)dstBufferInfo.pPixels, dstBufferInfo.pitch);
1495
1496                                         if (pPixmanSrc && pPixmanDst)
1497                                         {
1498                                                 pixman_image_composite32(PIXMAN_OP_SRC, pPixmanSrc, NULL, pPixmanDst, 0, 0, 0, 0, point.x, point.y, srcBufferInfo.width, srcBufferInfo.height);
1499                                                 pass = true;
1500                                         }
1501
1502                                         if (pPixmanDst)
1503                                         {
1504                                                 pixman_image_unref(pPixmanDst);
1505                                         }
1506
1507                                         if (pPixmanSrc)
1508                                         {
1509                                                 pixman_image_unref(pPixmanSrc);
1510                                         }
1511                                 }
1512                         }
1513                         {
1514                                 bool isPixmanSupported = (!this->__useStableRenderer);
1515
1516                                 if (isPixmanSupported)
1517                                 {
1518                                         Color color;
1519
1520                                         isPixmanSupported = !((bitmap.GetBitsPerPixel() == 16) && (bitmap.GetMaskingColor(color) == E_SUCCESS));
1521                                 }
1522
1523                                 if (isPixmanSupported)
1524                                 {
1525                                         _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1526                                         _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1527
1528                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1529                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1530
1531                                         if  (alphaConstant < 255)
1532                                         {
1533                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1534
1535                                                 if (modifiedSrcImage != null)
1536                                                 {
1537                                                         pass = _Pixman::CopyPixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
1538                                                 }
1539                                         }
1540
1541                                         if (!pass)
1542                                         {
1543                                                 pass = _Pixman::CopyPixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
1544                                         }
1545                                 }
1546
1547                                 if (!pass)
1548                                 {
1549                                         _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1550                                         _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
1551
1552                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1553                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1554
1555                                         pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, point.x - clipRect.x, point.y - clipRect.y, srcImage, alphaConstant);
1556                                 }
1557                         }
1558                 }
1559
1560                 SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1561
1562                 return E_SUCCESS;
1563         }
1564 }
1565
1566 result
1567 _Canvas::DrawBitmap(const _Util::Rectangle<double>& destRectD, const _Bitmap& srcBitmap, const _Util::Rectangle<double>& srcRectD)
1568 {
1569         SysTryReturnResult(NID_GRP, &srcBitmap && srcBitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1570
1571         if (srcRectD.w == 0 || srcRectD.h == 0)
1572         {
1573                 return E_SUCCESS;
1574         }
1575
1576         if (destRectD.w == 0 || destRectD.h == 0)
1577         {
1578                 return E_SUCCESS;
1579         }
1580
1581         int alphaConstant = this->_GetAlphaAttenuation(srcBitmap);
1582
1583         Rectangle clipRect;
1584
1585         this->__GetClipBounds(clipRect);
1586
1587         _Util::Rectangle<int> destRect =
1588         {
1589                 _DoubleToIntForPos(destRectD.x),
1590                 _DoubleToIntForPos(destRectD.y),
1591                 _DoubleToIntForSize(destRectD.w),
1592                 _DoubleToIntForSize(destRectD.h)
1593         };
1594
1595         _Util::Rectangle<int> srcRect =
1596         {
1597                 _DoubleToIntForPos(srcRectD.x),
1598                 _DoubleToIntForPos(srcRectD.y),
1599                 _DoubleToIntForSize(srcRectD.w),
1600                 _DoubleToIntForSize(srcRectD.h)
1601         };
1602
1603         {
1604                 bool pass = false;
1605
1606                 _Util::LockManager srcLock(srcBitmap);
1607                 _Util::LockManager dstLock(*this);
1608
1609                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1610                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1611
1612                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1613                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1614
1615                 {
1616                         if (!this->__useStableRenderer && srcBufferInfo.bitsPerPixel == 32)
1617                         {
1618                                 _Util::Rectangle<int> srcBounds =
1619                                 {
1620                                         int(Math::Floor(srcRect.x)),
1621                                         int(Math::Floor(srcRect.y)),
1622                                         int(Math::Ceiling(srcRect.x + srcRect.w) - Math::Floor(srcRect.x)),
1623                                         int(Math::Ceiling(srcRect.y + srcRect.h) - Math::Floor(srcRect.y))
1624                                 };
1625
1626                                 _Util::Pixmap srcImageUnclipped(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1627                                 _Util::Pixmap srcImage = srcImageUnclipped.GetSubBitmap(srcBounds.x, srcBounds.y, srcBounds.w, srcBounds.h);
1628                                 _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1629
1630                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1631                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1632
1633                                 if  (alphaConstant < 255)
1634                                 {
1635                                         std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1636
1637                                         if (modifiedSrcImage != null)
1638                                         {
1639                                                 pass = _Pixman::ScalePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), destRectD.x - clipRect.x, destRectD.y - clipRect.y, destRectD.w, destRectD.h);
1640                                         }
1641                                 }
1642
1643                                 if (!pass)
1644                                 {
1645                                         pass = _Pixman::ScalePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), destRectD.x - clipRect.x, destRectD.y - clipRect.y, destRectD.w, destRectD.h);
1646                                 }
1647                         }
1648
1649                         if (!pass)
1650                         {
1651                                 unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1652
1653                                 _Util::Pixmap srcImage(srcRect.w, srcRect.h, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1654                                 _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1655
1656                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1657                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1658
1659                                 pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.w, destRect.h, srcImage, _ConvertParam<_Effect::Rop>(this->__blendOption));
1660                         }
1661
1662                 }
1663
1664                 if(pass)
1665                 {
1666                         return E_SUCCESS;
1667                 }
1668         }
1669
1670         {
1671                 _Util::Pixmap tmpImage(destRect.w, destRect.h, srcBitmap.GetBitsPerPixel());
1672
1673                 // copies the source bitmap to the scaled bitmap
1674                 {
1675                         // ykahn, 2011/10/11 patched
1676                         {
1677                                 _ApplySrcBitmapAttrib(tmpImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1678
1679                                 if (tmpImage.depth == 16)
1680                                 {
1681                                         if (tmpImage.enableColorKey)
1682                                         {
1683                                                 typedef unsigned short Pixel;
1684
1685                                                 Pixel colorKey = (Pixel) tmpImage.colorKey;
1686                                                 Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1687                                                 Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1688
1689                                                 while (pDest < pDestEnd)
1690                                                 {
1691                                                         *pDest++ = colorKey;
1692                                                 }
1693                                         }
1694                                         else
1695                                         {
1696                                         }
1697                                 }
1698                                 else if (tmpImage.depth == 32)
1699                                 {
1700                                         typedef unsigned long Pixel;
1701
1702                                         Pixel fillColor = 0;
1703                                         Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1704                                         Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1705
1706                                         while (pDest < pDestEnd)
1707                                         {
1708                                                 *pDest++ = fillColor;
1709                                         }
1710                                 }
1711                         }
1712
1713                         bool pass = false;
1714
1715                         {
1716                                 _Util::LockManager srcLock(srcBitmap);
1717                                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1718
1719                                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1720
1721                                 {
1722                                         unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1723
1724                                         _Util::Pixmap srcImage(srcRect.w, srcRect.h, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1725                                         _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1726
1727                                         pass = Tizen::Graphics::_Effect::ScaleImage(tmpImage, 0, 0, destRect.w, destRect.h, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1728                                 }
1729                         }
1730
1731                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1732                 }
1733
1734                 {
1735                         bool pass = false;
1736
1737                         {
1738                                 _Util::LockManager dstLock(*this);
1739                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1740
1741                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1742
1743                                 {
1744                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1745                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1746
1747                                         pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, tmpImage, alphaConstant);
1748                                 }
1749                         }
1750
1751                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1752                 }
1753
1754                 return E_SUCCESS;
1755         }
1756 }
1757
1758 result
1759 _Canvas::DrawBitmapForNinePatchedBitmap(const Rectangle& destRect, const _Bitmap& srcBitmap, const Rectangle& srcRect, bool copyOnly)
1760 {
1761         SysTryReturnResult(NID_GRP, &srcBitmap && srcBitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1762
1763         if (srcRect.width == 0 || srcRect.height == 0)
1764         {
1765                 return E_SUCCESS;
1766         }
1767
1768         if (destRect.width == 0 || destRect.height == 0)
1769         {
1770                 return E_SUCCESS;
1771         }
1772
1773         int alphaConstant = this->_GetAlphaAttenuation(srcBitmap);
1774
1775         Rectangle clipRect;
1776
1777         this->__GetClipBounds(clipRect);
1778
1779         bool pass = false;
1780
1781         {
1782                 _Util::LockManager srcLock(srcBitmap);
1783                 _Util::LockManager dstLock(*this);
1784
1785                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1786                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1787
1788                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1789                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1790
1791                 {
1792                         if (srcBufferInfo.bitsPerPixel == 32)
1793                         {
1794                                 _Util::Rectangle<int> outRect = { 0, 0, -1, -1 };
1795                                 _Util::Rectangle<int> dstRect = { destRect.x, destRect.y, destRect.width, destRect.height };
1796                                 _Util::Rectangle<int> tgtRect = { clipRect.x, clipRect.y, clipRect.width, clipRect.height };
1797
1798                                 _Util::IntersectRect(outRect, tgtRect, dstRect);
1799
1800                                 // assert(destRect.width > 0 && destRect.height > 0);
1801
1802                                 _Util::Bounds<int> outBounds = { outRect.x, outRect.y, outRect.x + outRect.w, outRect.y + outRect.h };
1803                                 _Util::Bounds<int> dstBounds = { dstRect.x, dstRect.y, dstRect.x + dstRect.w, dstRect.y + dstRect.h };
1804                                 _Util::Bounds<int> srcBounds =
1805                                 {
1806                                         srcRect.x + (outBounds.x1 - dstBounds.x1) * srcRect.width / (dstBounds.x2 - dstBounds.x1),
1807                                         srcRect.y + (outBounds.y1 - dstBounds.y1) * srcRect.height / (dstBounds.y2 - dstBounds.y1),
1808                                         (srcRect.x + srcRect.width) + (outBounds.x2 - dstBounds.x2) * srcRect.width / (dstBounds.x2 - dstBounds.x1),
1809                                         (srcRect.y + srcRect.height) + (outBounds.y2 - dstBounds.y2) * srcRect.height / (dstBounds.y2 - dstBounds.y1),
1810                                 };
1811
1812                                 srcBounds.x1 = (srcBounds.x1 >= srcRect.x) ? srcBounds.x1 : srcRect.x;
1813                                 srcBounds.y1 = (srcBounds.y1 >= srcRect.y) ? srcBounds.y1 : srcRect.y;
1814                                 srcBounds.x2 = (srcBounds.x2 <= (srcRect.x + srcRect.width)) ? srcBounds.x2 : (srcRect.x + srcRect.width);
1815                                 srcBounds.y2 = (srcBounds.y2 <= (srcRect.y + srcRect.height)) ? srcBounds.y2 : (srcRect.y + srcRect.height);
1816
1817                                 _Util::Pixmap srcImageUnclipped(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1818                                 _Util::Pixmap srcImage = srcImageUnclipped.GetSubBitmap(srcBounds.x1, srcBounds.y1, srcBounds.x2 - srcBounds.x1, srcBounds.y2 - srcBounds.y1);
1819                                 _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1820
1821                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1822                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(outRect.x, outRect.y, outRect.w, outRect.h);
1823
1824                                 if (copyOnly)
1825                                 {
1826                                         pass = _Pixman::ScalePixmapOpCopy(dstImage, srcImage, GetDrawingQuality());
1827                                 }
1828                                 else
1829                                 {
1830                                         if (alphaConstant < 255)
1831                                         {
1832                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1833
1834                                                 if (modifiedSrcImage != null)
1835                                                 {
1836                                                         pass = _Pixman::ScalePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode());
1837                                                 }
1838                                         }
1839
1840                                         if (!pass)
1841                                         {
1842                                                 pass = _Pixman::ScalePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode());
1843                                         }
1844                                 }
1845                         }
1846
1847                         if (!pass)
1848                         {
1849                                 unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1850
1851                                 _Util::Pixmap srcImage(srcRect.width, srcRect.height, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1852                                 _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1853
1854                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1855                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1856
1857                                 if (copyOnly)
1858                                 {
1859                                         pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1860                                 }
1861                                 else
1862                                 {
1863                                         pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height, srcImage, _ConvertParam<_Effect::Rop>(this->__blendOption));
1864                                 }
1865                         }
1866
1867                 }
1868
1869         }
1870
1871         if (!pass)
1872         {
1873                 _Util::Pixmap tmpImage(destRect.width, destRect.height, srcBitmap.GetBitsPerPixel());
1874
1875                 // copies the source bitmap to the scaled bitmap
1876                 {
1877                         // ykahn, 2011/10/11 patched
1878                         {
1879                                 _ApplySrcBitmapAttrib(tmpImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1880
1881                                 if (tmpImage.depth == 16)
1882                                 {
1883                                         if (tmpImage.enableColorKey)
1884                                         {
1885                                                 typedef unsigned short Pixel;
1886
1887                                                 Pixel colorKey = (Pixel) tmpImage.colorKey;
1888                                                 Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1889                                                 Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1890
1891                                                 while (pDest < pDestEnd)
1892                                                 {
1893                                                         *pDest++ = colorKey;
1894                                                 }
1895                                         }
1896                                         else
1897                                         {
1898                                         }
1899                                 }
1900                                 else if (tmpImage.depth == 32)
1901                                 {
1902                                         typedef unsigned long Pixel;
1903
1904                                         Pixel fillColor = 0;
1905                                         Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1906                                         Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1907
1908                                         while (pDest < pDestEnd)
1909                                         {
1910                                                 *pDest++ = fillColor;
1911                                         }
1912                                 }
1913                         }
1914
1915                         bool scaled = false;
1916
1917                         {
1918                                 _Util::LockManager srcLock(srcBitmap);
1919                                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1920
1921                                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1922
1923                                 {
1924                                         unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1925
1926                                         _Util::Pixmap srcImage(srcRect.width, srcRect.height, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1927                                         _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1928
1929                                         scaled = Tizen::Graphics::_Effect::ScaleImage(tmpImage, 0, 0, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1930                                 }
1931                         }
1932
1933                         SysTryReturnResult(NID_GRP, scaled, E_INVALID_ARG, "The source bitmap is invalid.\n");
1934                 }
1935
1936                 {
1937                         _Util::LockManager dstLock(*this);
1938                         SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1939
1940                         const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1941
1942                         {
1943                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1944                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1945
1946                                 pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, tmpImage, alphaConstant);
1947                         }
1948                 }
1949         }
1950
1951         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1952
1953         return E_SUCCESS;
1954 }
1955
1956 result
1957 _Canvas::DrawBitmap(const _Util::Point<double>& pointD, const _Bitmap& bitmap, FlipDirection dir)
1958 {
1959         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1960
1961         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
1962
1963         Rectangle clipRect;
1964
1965         this->__GetClipBounds(clipRect);
1966
1967         {
1968                 _Util::Point<int> point =
1969                 {
1970                         _DoubleToIntForPos(pointD.x),
1971                         _DoubleToIntForPos(pointD.y)
1972                 };
1973
1974                 _Util::Pixmap* pFlippedImage = 0;
1975
1976                 {
1977                         _Util::LockManager srcLock(bitmap);
1978                         SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1979
1980                         const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1981
1982                         Tizen::Graphics::_Effect::Flip flip = (dir == FLIP_DIRECTION_HORIZONTAL) ? Tizen::Graphics::_Effect::FLIP_HORIZONTAL : Tizen::Graphics::_Effect::FLIP_VERTICAL;
1983
1984                         {
1985                                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1986
1987                                 pFlippedImage = Tizen::Graphics::_Effect::GetFlippedImage(srcImage, flip);
1988                         }
1989                 }
1990
1991                 SysTryReturnResult(NID_GRP, pFlippedImage, E_INVALID_ARG, "The source bitmap is invalid.\n");
1992
1993                 _ApplySrcBitmapAttrib(*pFlippedImage, bitmap, bitmap.__isOpaqueAllOver);
1994
1995                 std::auto_ptr<_Util::Pixmap> autoReleasingImage(pFlippedImage);
1996
1997                 {
1998                         bool pass = false;
1999
2000                         if (!this->__useStableRenderer && pFlippedImage->depth == 32)
2001                         {
2002                                 _Util::LockManager dstLock(*this);
2003                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.");
2004
2005                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2006
2007                                 {
2008                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2009                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2010
2011                                         if  (alphaConstant < 255)
2012                                         {
2013                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(pFlippedImage->GetAlphaAttenuatedPixmap(alphaConstant));
2014
2015                                                 if (modifiedSrcImage != null)
2016                                                 {
2017                                                         pass = _Pixman::CopyPixmap(dstImage, *modifiedSrcImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
2018                                                 }
2019                                         }
2020
2021                                         if (!pass)
2022                                         {
2023                                                 pass = _Pixman::CopyPixmap(dstImage, *pFlippedImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
2024                                         }
2025                                 }
2026                         }
2027
2028                         if(!pass)
2029                         {
2030                                 _Util::LockManager dstLock(*this);
2031                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
2032
2033                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2034
2035                                 {
2036                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2037                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2038
2039                                         pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, point.x - clipRect.x, point.y - clipRect.y, *pFlippedImage, alphaConstant);
2040                                 }
2041                         }
2042
2043                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
2044                 }
2045
2046                 return E_SUCCESS;
2047         }
2048 }
2049
2050 result
2051 _Canvas::DrawBitmap(const _Util::Point<double>& pointD, const _Bitmap& bitmap, const _Util::Point<double>& pivotD, double degreeD)
2052 {
2053         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2054
2055         Rectangle clipRect;
2056
2057         this->__GetClipBounds(clipRect);
2058
2059         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
2060
2061         if (!this->__useStableRenderer && bitmap.GetBitsPerPixel() == 32)
2062         {
2063                 bool pass = false;
2064
2065                 _Util::LockManager srcLock(bitmap);
2066                 _Util::LockManager dstLock(*this);
2067
2068                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.");
2069                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.");
2070
2071                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
2072                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2073
2074                 {
2075                         _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
2076                         _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
2077
2078                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2079                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2080
2081                         if  (alphaConstant < 255)
2082                         {
2083                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
2084
2085                                 if (modifiedSrcImage != null)
2086                                 {
2087                                         pass = _Pixman::RotatePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y, degreeD, pivotD.x, pivotD.y);
2088                                 }
2089                         }
2090
2091                         if (!pass)
2092                         {
2093                                 pass = _Pixman::RotatePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y, degreeD, pivotD.x, pivotD.y);
2094                         }
2095
2096                 }
2097
2098                 if (pass)
2099                 {
2100                         return E_SUCCESS;
2101                 }
2102         }
2103
2104 /*
2105     if (alphaConstant >= 255)
2106     {
2107         return pCanvasInterface->DrawBitmap(point.x, point.y, *((IBitmapPi*)*(IBitmapPi**)bitmap.__pImpl), pivot.x, pivot.y, degree);
2108     }
2109     else
2110 */
2111         {
2112                 _Util::LockManager srcLock(bitmap);
2113                 _Util::LockManager dstLock(*this);
2114
2115                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
2116                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
2117
2118                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
2119                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2120
2121                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
2122                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2123                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2124
2125                 _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
2126
2127                 _Util::Point<int> point =
2128                 {
2129                         _DoubleToIntForPos(pointD.x),
2130                         _DoubleToIntForPos(pointD.y)
2131                 };
2132
2133                 Tizen::Graphics::_Effect::RotateDesc rotateDesc = { _DoubleToIntForRound(degreeD), _DoubleToIntForPos(pivotD.x), _DoubleToIntForPos(pivotD.y) };
2134
2135                 bool pass = Tizen::Graphics::_Effect::RotateImage(dstImage, point.x - clipRect.x, point.y - clipRect.y, srcImage, rotateDesc, alphaConstant);
2136
2137                 SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
2138
2139                 return E_SUCCESS;
2140         }
2141 }
2142
2143 result
2144 _Canvas::DrawNinePatchedBitmap(const Rectangle& rect, const _Bitmap& bitmap)
2145 {
2146         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2147
2148         // down-scales the source bitmap
2149         if (rect.width < bitmap.GetWidth() - 2 || rect.height < bitmap.GetHeight() - 2)
2150         {
2151 #if 1
2152                 int dstW = rect.width;
2153                 int dstH = rect.height;
2154                 int srcW = bitmap.GetWidth() - 2;
2155                 int srcH = bitmap.GetHeight() - 2;
2156
2157                 if (dstW <= 0 || dstH <= 0)
2158                 {
2159                         return E_SUCCESS;
2160                 }
2161
2162                 if (dstW * srcH < dstH * srcW)
2163                 {
2164                         // fit to width
2165                         dstW = srcW;
2166                         dstH = dstH * srcW / dstW;
2167                 }
2168                 else
2169                 {
2170                         // fit to height
2171                         dstW = dstW * srcH / dstH;
2172                         dstH = srcH;
2173                 }
2174
2175                 result r;
2176
2177                 {
2178                         const int PADDING = 1;
2179
2180                         _Bitmap expandedBitmap;
2181
2182                         r = expandedBitmap.Construct(Dimension(dstW + PADDING * 2, dstH + PADDING * 2), BITMAP_PIXEL_FORMAT_ARGB8888);
2183
2184                         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2185
2186                         _Util::LockManager dstBitmap(expandedBitmap);
2187
2188                         {
2189                                 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
2190
2191                                 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
2192
2193                                 _Canvas expandedCanvas;
2194
2195                                 r = expandedCanvas.Construct(dstBufferInfo);
2196
2197                                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2198
2199                                 expandedCanvas.SetDrawingQuality(BITMAP_DRAWING_QUALITY_HIGH);
2200                                 expandedCanvas.SetCompositeMode(COMPOSITE_MODE_SRC);
2201
2202                                 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
2203
2204                                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2205
2206                                 r = _Util::GetPatchList(boundsList, Rectangle(PADDING, PADDING, dstBufferInfo.width - PADDING * 2, dstBufferInfo.height - PADDING * 2), bitmap);
2207
2208                                 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
2209
2210                                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2211
2212                                 int alphaConstant = bitmap.GetAlphaConstant();
2213                                 const_cast<_Bitmap*>(&bitmap)->SetAlphaConstant(255);
2214
2215                                 while (iter != boundsList.End())
2216                                 {
2217                                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2218                                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2219
2220                                         expandedCanvas.DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect, true);
2221
2222                                         ++iter;
2223                                 }
2224
2225                                 const_cast<_Bitmap*>(&bitmap)->SetAlphaConstant(alphaConstant);
2226                                 expandedBitmap.SetAlphaConstant(alphaConstant);
2227                         }
2228
2229                         // not <- PADDING * 2>
2230                         Tizen::Graphics::Rectangle srcRect(PADDING, PADDING, expandedBitmap.GetWidth() - PADDING, expandedBitmap.GetHeight() - PADDING);
2231
2232                         return this->DrawBitmap(_Util::Convert<Rectangle, _Util::Rectangle<double> >(rect), expandedBitmap, _Util::Convert<Rectangle, _Util::Rectangle<double> >(srcRect));
2233                 }
2234
2235 #else // old spec.
2236                 Tizen::Graphics::Rectangle srcRect(1, 1, bitmap.GetWidth() - 2, bitmap.GetHeight() - 2);
2237
2238                 return this->DrawBitmap(rect, bitmap, srcRect);
2239 #endif
2240         }
2241
2242         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2243
2244         result r = _Util::GetPatchList(boundsList, rect, bitmap);
2245
2246         if (r == E_SUCCESS)
2247         {
2248                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2249
2250                 while (iter != boundsList.End())
2251                 {
2252                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2253                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2254
2255                         DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2256
2257                         ++iter;
2258                 }
2259         }
2260
2261         return r;
2262 }
2263
2264 result
2265 _Canvas::DrawNineTiledBitmap(const Rectangle& rect, const _Bitmap& bitmap)
2266 {
2267         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2268
2269         // down-scales the source bitmap
2270         if (rect.width < bitmap.GetWidth() - 2 || rect.height < bitmap.GetHeight() - 2)
2271         {
2272                 return this->DrawNinePatchedBitmap(rect, bitmap);
2273         }
2274
2275         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2276
2277         result r = _Util::GetPatchList(boundsList, rect, bitmap);
2278
2279         if (r == E_SUCCESS)
2280         {
2281                 // This block is slow and not optimized.
2282                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2283
2284                 while (iter != boundsList.End())
2285                 {
2286                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2287                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2288
2289                         if (iter->first.w == iter->second.w && iter->first.h == iter->second.h)
2290                         {
2291                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2292                         }
2293                         else
2294                         {
2295                                 for (int y = iter->first.y; y < iter->first.y + iter->first.h; y += iter->second.h)
2296                                 {
2297                                         if (y + iter->second.h <= iter->first.y + iter->first.h)
2298                                         {
2299                                                 for (int x = iter->first.x; x < iter->first.x + iter->first.w; x += iter->second.w)
2300                                                 {
2301                                                         if (x + iter->second.w <= iter->first.x + iter->first.w)
2302                                                         {
2303                                                                 Rectangle destRect(x, y, iter->second.w, iter->second.h);
2304                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2305                                                         }
2306                                                         else
2307                                                         {
2308                                                                 // right side clipping
2309                                                                 int w = iter->first.x + iter->first.w - x;
2310
2311                                                                 Rectangle destRect(x, y, w, iter->second.h);
2312                                                                 Rectangle sourRect(iter->second.x, iter->second.y, w, iter->second.h);
2313
2314                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2315                                                         }
2316                                                 }
2317                                         }
2318                                         else
2319                                         {
2320                                                 // bottom side clipping
2321                                                 int h = iter->first.y + iter->first.h - y;
2322
2323                                                 for (int x = iter->first.x; x < iter->first.x + iter->first.w; x += iter->second.w)
2324                                                 {
2325                                                         if (x + iter->second.w <= iter->first.x + iter->first.w)
2326                                                         {
2327                                                                 Rectangle destRect(x, y, iter->second.w, h);
2328                                                                 Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, h);
2329                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2330                                                         }
2331                                                         else
2332                                                         {
2333                                                                 // right-bottom side clipping
2334                                                                 int w = iter->first.x + iter->first.w - x;
2335
2336                                                                 Rectangle destRect(x, y, w, h);
2337                                                                 Rectangle sourRect(iter->second.x, iter->second.y, w, h);
2338
2339                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2340                                                         }
2341                                                 }
2342                                         }
2343                                 }
2344                         }
2345
2346                         ++iter;
2347                 }
2348         }
2349
2350         return r;
2351 }
2352
2353 result
2354 _Canvas::DrawEllipse(const _Util::Rectangle<int>& bounds)
2355 {
2356         _Util::Rectangle<double> doubleBounds =
2357         {
2358                 double(bounds.x),
2359                 double(bounds.y),
2360                 double(bounds.w),
2361                 double(bounds.h)
2362         };
2363
2364         return this->DrawEllipse(doubleBounds);
2365 }
2366
2367 result
2368 _Canvas::DrawEllipse(const _Util::Rectangle<double>& bounds)
2369 {
2370         if ((bounds.w <= 0.0) || (bounds.h <= 0.0))
2371         {
2372                 return E_SUCCESS;
2373         }
2374
2375         // this->__lineWidth is always greater than 0
2376
2377         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2378
2379         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2380
2381         bool shouldWorkAround = !__IsInClipBounds(bounds) && (this->__dashData.pattern.Size() == 0);
2382
2383         if (!shouldWorkAround && pCairo && pCairo->pCairo)
2384         {
2385                 SET_CAIRO_ALL_PROPERTIES;
2386
2387                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2388                 {
2389                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds);
2390                 }
2391                 else
2392                 {
2393                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds);
2394                 }
2395
2396                 RESET_CAIRO_ALL_PROPERTIES;
2397
2398                 return E_SUCCESS;
2399         }
2400         else if (shouldWorkAround && pCairo && pCairo->pCairo)
2401         {
2402                 SET_CAIRO_ALL_PROPERTIES;
2403
2404                 double pattern = (bounds.w + bounds.h) * 2.0;
2405                 _Cairo::SetDash(pCairo->pCairo, &pattern, 1, 0);
2406
2407                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2408                 {
2409                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds);
2410                 }
2411                 else
2412                 {
2413                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds);
2414                 }
2415
2416                 RESET_CAIRO_ALL_PROPERTIES;
2417
2418                 return E_SUCCESS;
2419         }
2420         else
2421         {
2422                 _CanvasEllipse ellipse;
2423                 _GpBufferInfo info;
2424
2425                 memset(&info, 0, sizeof(info));
2426
2427                 SystemPixel* pBufferAddr = null;
2428                 int bufferPitch = 0;
2429
2430                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2431
2432                 info.width = __pScratchPad->GetWidth();
2433                 info.height = __pScratchPad->GetHeight();
2434                 info.bitsPerPixel = 32;
2435                 info.pixelPerLine = bufferPitch;
2436                 info.pPixels = (void*) pBufferAddr;
2437                 info.color32 = composedColor;
2438                 info.isClipBoundsSet = this->__isClipBoundsSet;
2439                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2440
2441                 ellipse.SetLineWidth(this->__lineWidth.asInteger);
2442
2443                 return ellipse.DrawEllipse(int(bounds.x), int(bounds.y), int(bounds.w), int(bounds.h), info);
2444         }
2445 }
2446
2447 result
2448 _Canvas::DrawLine(const _Util::Point<int>& point1, const _Util::Point<int>& point2)
2449 {
2450         _Util::Point<double> doublePoint1 =
2451         {
2452                 double(point1.x),
2453                 double(point1.y)
2454         };
2455
2456         _Util::Point<double> doublePoint2 =
2457         {
2458                 double(point2.x),
2459                 double(point2.y)
2460         };
2461
2462         return this->DrawLine(doublePoint1, doublePoint2);
2463 }
2464
2465 result
2466 _Canvas::DrawLine(const _Util::Point<double>& point1, const _Util::Point<double>& point2)
2467 {
2468         // this->__lineWidth is always greater than 0
2469
2470         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2471
2472         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2473
2474         if (pCairo && pCairo->pCairo)
2475         {
2476                 _Util::Point<double> point[] =
2477                 {
2478                         { point1.x, point1.y },
2479                         { point2.x, point2.y }
2480                 };
2481
2482                 SET_CAIRO_ALL_PROPERTIES;
2483
2484                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2485                 {
2486                         _Cairo::Drawline(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, point, 2);
2487                 }
2488                 else
2489                 {
2490                         _Cairo::Drawline(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, point, 2);
2491                 }
2492
2493                 RESET_CAIRO_ALL_PROPERTIES;
2494
2495                 return E_SUCCESS;
2496         }
2497         else
2498         {
2499                 _CanvasLine line;
2500                 _GpBufferInfo info;
2501
2502                 _GpPoint startPt =
2503                 {
2504                         int(point1.x),
2505                         int(point1.y)
2506                 };
2507
2508                 _GpPoint endPt =
2509                 {
2510                         int(point2.x),
2511                         int(point2.y)
2512                 };
2513
2514                 memset(&info, 0, sizeof(info));
2515
2516                 SystemPixel* pBufferAddr = null;
2517                 int bufferPitch = 0;
2518
2519                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2520
2521                 info.width = __pScratchPad->GetWidth();
2522                 info.height = __pScratchPad->GetHeight();
2523                 info.bitsPerPixel = 32;
2524                 info.pixelPerLine = bufferPitch;
2525                 info.pPixels = (void*) pBufferAddr;
2526                 info.color32 = composedColor;
2527                 info.isClipBoundsSet = this->__isClipBoundsSet;
2528                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2529
2530                 line.SetLineWidth(this->__lineWidth.asInteger);
2531
2532                 if (this->__lineWidth.asInteger == 1)
2533                 {
2534                         if ((startPt.x == endPt.x) && (startPt.y == endPt.y))
2535                         {
2536                                 this->SetPixel(point1);
2537                                 return E_SUCCESS;
2538                         }
2539                 }
2540
2541                 return line.DrawLine(startPt, endPt, info);
2542         }
2543 }
2544
2545 result
2546 _Canvas::DrawPolygon(const _Util::Point<double>* pPoints, unsigned int pointCount)
2547 {
2548         // this->__lineWidth is always greater than 0
2549
2550         if (pointCount == 1)
2551         {
2552                 return this->SetPixel(pPoints[0]);
2553         }
2554
2555         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2556
2557         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2558
2559         if (pCairo && pCairo->pCairo)
2560         {
2561                 SET_CAIRO_ALL_PROPERTIES;
2562
2563                 _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, pPoints, pointCount);
2564
2565                 RESET_CAIRO_ALL_PROPERTIES;
2566
2567                 return E_SUCCESS;
2568         }
2569         else
2570         {
2571                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
2572
2573                 _GpPoint* pTempPoints = tempPoints.get();
2574
2575                 if (pTempPoints == null)
2576                 {
2577                         return E_SYSTEM;
2578                 }
2579
2580                 for (unsigned int i = 0; i < pointCount; i++)
2581                 {
2582                         pTempPoints[i].x = int(pPoints[i].x);
2583                         pTempPoints[i].y = int(pPoints[i].y);
2584                 }
2585
2586                 _CanvasLine line;
2587                 _GpBufferInfo info;
2588
2589                 memset(&info, 0, sizeof(info));
2590
2591                 SystemPixel* pBufferAddr = null;
2592                 int bufferPitch = 0;
2593
2594                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2595
2596                 info.width = __pScratchPad->GetWidth();
2597                 info.height = __pScratchPad->GetHeight();
2598                 info.bitsPerPixel = 32;
2599                 info.pixelPerLine = bufferPitch;
2600                 info.pPixels = (void*) pBufferAddr;
2601                 info.color32 = composedColor;
2602                 info.isClipBoundsSet = this->__isClipBoundsSet;
2603                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2604
2605                 line.SetLineWidth(this->__lineWidth.asInteger);
2606
2607                 result r = line.DrawPolygon(int(pointCount), pTempPoints, info);
2608
2609                 return r;
2610         }
2611 }
2612
2613 result
2614 _Canvas::DrawPolyline(const _Util::Point<double>* pPoints, unsigned int pointCount)
2615 {
2616         // this->__lineWidth is always greater than 0
2617
2618         if (pointCount == 1)
2619         {
2620                 return this->SetPixel(pPoints[0]);
2621         }
2622
2623         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2624
2625         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2626
2627         if (pCairo && pCairo->pCairo)
2628         {
2629                 SET_CAIRO_ALL_PROPERTIES;
2630
2631                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2632                 {
2633                         _Cairo::DrawPolyline(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, pPoints, pointCount);
2634                 }
2635                 else
2636                 {
2637                         _Cairo::DrawPolyline(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, pPoints, pointCount);
2638                 }
2639
2640                 RESET_CAIRO_ALL_PROPERTIES;
2641
2642                 return E_SUCCESS;
2643         }
2644         else
2645         {
2646                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
2647
2648                 _GpPoint* pTempPoints = tempPoints.get();
2649
2650                 if (pTempPoints == null)
2651                 {
2652                         return E_SYSTEM;
2653                 }
2654
2655                 for (unsigned int i = 0; i < pointCount; i++)
2656                 {
2657                         pTempPoints[i].x = int(pPoints[i].x);
2658                         pTempPoints[i].y = int(pPoints[i].y);
2659                 }
2660
2661                 _CanvasLine line;
2662                 _GpBufferInfo info;
2663
2664                 memset(&info, 0, sizeof(info));
2665
2666                 SystemPixel* pBufferAddr = null;
2667                 int bufferPitch = 0;
2668
2669                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2670
2671                 info.width = __pScratchPad->GetWidth();
2672                 info.height = __pScratchPad->GetHeight();
2673                 info.bitsPerPixel = 32;
2674                 info.pixelPerLine = bufferPitch;
2675                 info.pPixels = (void*) pBufferAddr;
2676                 info.color32 = composedColor;
2677                 info.isClipBoundsSet = this->__isClipBoundsSet;
2678                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2679
2680                 line.SetLineWidth(this->__lineWidth.asInteger);
2681
2682                 result r = line.DrawPolyLine(int(pointCount), pTempPoints, info);
2683
2684                 return r;
2685         }
2686 }
2687
2688 result
2689 _Canvas::DrawRectangle(const _Util::Rectangle<int>& rect)
2690 {
2691         _Util::Rectangle<double> doubleRect =
2692         {
2693                 double(rect.x),
2694                 double(rect.y),
2695                 double(rect.w),
2696                 double(rect.h)
2697         };
2698
2699         return this->DrawRectangle(doubleRect);
2700 }
2701
2702 result
2703 _Canvas::DrawRectangle(const _Util::Rectangle<double>& rectangle)
2704 {
2705         if ((rectangle.w <= 0.0) || (rectangle.h <= 0.0))
2706         {
2707                 return E_SUCCESS;
2708         }
2709
2710         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2711
2712         bool tryToDrawWithCairo = (__lineWidth.applied == _Util::ScalarHolder::AS_DOUBLE || __lineWidth.asInteger > 1 || __dashData.pattern.Size() > 0);
2713
2714         if (tryToDrawWithCairo)
2715         {
2716                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2717
2718                 if (pCairo && pCairo->pCairo)
2719                 {
2720                         SET_CAIRO_ALL_PROPERTIES;
2721
2722                         if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2723                         {
2724                                 _Cairo::DrawRectangle(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, rectangle);
2725                         }
2726                         else
2727                         {
2728                                 _Cairo::DrawRectangle(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, rectangle);
2729                         }
2730
2731                         RESET_CAIRO_ALL_PROPERTIES;
2732
2733                         return E_SUCCESS;
2734                 }
2735         }
2736
2737         // falls through legacy drawing solution
2738
2739         int x1 = static_cast<int>(rectangle.x);
2740         int y1 = static_cast<int>(rectangle.y);
2741         int x2 = x1 + static_cast<int>(rectangle.w) - 1;
2742         int y2 = y1 + static_cast<int>(rectangle.h) - 1;
2743
2744         if (this->__lineWidth.asInteger == 1)
2745         {
2746                 if (!this->__isClipBoundsSet)
2747                 {
2748                         __pScratchPad->RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
2749
2750                         if (x2 > x1 && y2 > y1)
2751                         {
2752                                 __pScratchPad->FillRect(x1, y1, x2 - x1, 1, composedColor);
2753                                 __pScratchPad->FillRect(x2, y1, 1, y2 - y1, composedColor);
2754
2755                                 __pScratchPad->FillRect(x1 + 1, y2, x2 - x1, 1, composedColor);
2756                                 __pScratchPad->FillRect(x1, y1 + 1, 1, y2 - y1, composedColor);
2757                         }
2758                         else
2759                         {
2760                                 __pScratchPad->FillRect(x1, y1, static_cast<int>(rectangle.w), static_cast<int>(rectangle.h), composedColor);
2761                         }
2762
2763                         __pScratchPad->RegisterFillRect(null);
2764                 }
2765                 else
2766                 {
2767                         _Util::Rectangle<int> clip = { this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height };
2768
2769                         if (x2 > x1 && y2 > y1)
2770                         {
2771                                 _Util::Rectangle<int> rect1 = { x1, y1, x2 - x1, 1 };
2772                                 _Util::Rectangle<int> rect2 = { x2, y1, 1, y2 - y1 };
2773                                 _Util::Rectangle<int> rect3 = { x1 + 1, y2, x2 - x1, 1 };
2774                                 _Util::Rectangle<int> rect4 = { x1, y1 + 1, 1, y2 - y1 };
2775
2776                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect1, clip);
2777                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect2, clip);
2778                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect3, clip);
2779                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect4, clip);
2780                         }
2781                         else
2782                         {
2783                                 _Util::Rectangle<int> rect1 = { x1, y1, static_cast<int>(rectangle.w), static_cast<int>(rectangle.h) };
2784
2785                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect1, clip);
2786                         }
2787                 }
2788
2789                 return E_SUCCESS;
2790         }
2791         else if (this->__lineWidth.asInteger > 1)
2792         {
2793                 _GpPoint tempPoints[4] =
2794                 {
2795                         { x1, y1 },
2796                         { x2, y1 },
2797                         { x2, y2 },
2798                         { x1, y2 }
2799                 };
2800
2801                 _CanvasLine line;
2802                 _GpBufferInfo info;
2803
2804                 memset(&info, 0, sizeof(info));
2805
2806                 SystemPixel* pBufferAddr = null;
2807                 int bufferPitch = 0;
2808
2809                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2810
2811                 info.width = __pScratchPad->GetWidth();
2812                 info.height = __pScratchPad->GetHeight();
2813                 info.bitsPerPixel = 32;
2814                 info.pixelPerLine = bufferPitch;
2815                 info.pPixels = (void*) pBufferAddr;
2816                 info.color32 = composedColor;
2817                 info.isClipBoundsSet = this->__isClipBoundsSet;
2818                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2819
2820                 line.SetLineWidth(this->__lineWidth.asInteger);
2821
2822                 result r = line.DrawPolygon(4, tempPoints, info);
2823
2824                 return r;
2825         }
2826
2827         // this->__lineWidth is always greater than 0
2828         return E_SUCCESS;
2829 }
2830
2831 result
2832 _Canvas::DrawRoundRectangle(const _Util::Rectangle<int>& rect, const _Util::Dimension<int>& arcDim)
2833 {
2834         _Util::Rectangle<double> doubleRect =
2835         {
2836                 double(rect.x),
2837                 double(rect.y),
2838                 double(rect.w),
2839                 double(rect.h)
2840         };
2841
2842         _Util::Dimension<double> doubleArcDim =
2843         {
2844                 double(rect.w),
2845                 double(rect.h)
2846         };
2847
2848         return this->DrawRoundRectangle(doubleRect, doubleArcDim);
2849 }
2850
2851 result
2852 _Canvas::DrawRoundRectangle(const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
2853 {
2854         if ((rect.w <= 0.0) || (rect.h <= 0))
2855         {
2856                 return E_SUCCESS;
2857         }
2858
2859         if ((int(arcDim.w) == 0) || (int(arcDim.h) == 0))
2860         {
2861                 return this->DrawRectangle(rect);
2862         }
2863
2864         _Util::Dimension<double> revisedArcDim =
2865         {
2866                 (arcDim.w <= rect.w / 2.0) ? arcDim.w : rect.w / 2.0,
2867                 (arcDim.h <= rect.h / 2.0) ? arcDim.h : rect.h / 2.0
2868         };
2869
2870         // this->__lineWidth is always greater than 0
2871
2872         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2873
2874         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2875
2876         if (pCairo && pCairo->pCairo)
2877         {
2878                 SET_CAIRO_ALL_PROPERTIES;
2879
2880                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2881                 {
2882                         _Cairo::DrawRoundRectangle(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, rect, revisedArcDim);
2883                 }
2884                 else
2885                 {
2886                         _Cairo::DrawRoundRectangle(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, rect, revisedArcDim);
2887                 }
2888
2889                 RESET_CAIRO_ALL_PROPERTIES;
2890
2891                 return E_SUCCESS;
2892         }
2893         else
2894         {
2895                 _CanvasRoundRect roundRect;
2896                 _GpBufferInfo info;
2897
2898                 memset(&info, 0, sizeof(info));
2899
2900                 SystemPixel* pBufferAddr = null;
2901                 int bufferPitch = 0;
2902
2903                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2904
2905                 info.width = __pScratchPad->GetWidth();
2906                 info.height = __pScratchPad->GetHeight();
2907                 info.bitsPerPixel = 32;
2908                 info.pixelPerLine = bufferPitch;
2909                 info.pPixels = (void*) pBufferAddr;
2910                 info.color32 = composedColor;
2911                 info.isClipBoundsSet = this->__isClipBoundsSet;
2912                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2913
2914                 roundRect.SetLineWidth(this->__lineWidth.asInteger);
2915
2916                 return roundRect.DrawRoundRect(int(rect.x), int(rect.y), int(rect.w), int(rect.h), int(revisedArcDim.w), int(revisedArcDim.h), info);
2917         }
2918 }
2919
2920 result
2921 _Canvas::DrawTriangle(const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
2922 {
2923         // this->__lineWidth is always greater than 0
2924
2925         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2926
2927         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2928
2929         if (pCairo && pCairo->pCairo)
2930         {
2931                 _Util::Point<double> point[] =
2932                 {
2933                         { point1.x, point1.y },
2934                         { point2.x, point2.y },
2935                         { point3.x, point3.y }
2936                 };
2937
2938                 SET_CAIRO_ALL_PROPERTIES;
2939
2940                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2941                 {
2942                         _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, point, 3);
2943                 }
2944                 else
2945                 {
2946                         _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, point, 3);
2947                 }
2948
2949                 RESET_CAIRO_ALL_PROPERTIES;
2950
2951                 return E_SUCCESS;
2952         }
2953         else
2954         {
2955                 _CanvasTriangle triangle;
2956                 _GpBufferInfo info;
2957
2958                 memset(&info, 0, sizeof(info));
2959
2960                 SystemPixel* pBufferAddr = null;
2961                 int bufferPitch = 0;
2962
2963                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2964
2965                 info.width = __pScratchPad->GetWidth();
2966                 info.height = __pScratchPad->GetHeight();
2967                 info.bitsPerPixel = 32;
2968                 info.pixelPerLine = bufferPitch;
2969                 info.pPixels = (void*) pBufferAddr;
2970                 info.color32 = composedColor;
2971                 info.isClipBoundsSet = this->__isClipBoundsSet;
2972                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2973
2974                 triangle.SetLineWidth(this->__lineWidth.asInteger);
2975
2976                 _GpPoint p1 = { int(point1.x), int(point1.y) };
2977                 _GpPoint p2 = { int(point2.x), int(point2.y) };
2978                 _GpPoint p3 = { int(point3.x), int(point3.y) };
2979
2980                 return triangle.DrawTriangle(p1, p2, p3, info);
2981         }
2982 }
2983
2984 result
2985 _Canvas::FillTriangle(const Color& color, const _Util::Point<int>& point1, const _Util::Point<int>& point2, const _Util::Point<int>& point3)
2986 {
2987         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
2988
2989         _Util::Point<double> doublePoint1 =
2990         {
2991                 double(point1.x),
2992                 double(point1.y)
2993         };
2994
2995         _Util::Point<double> doublePoint2 =
2996         {
2997                 double(point1.x),
2998                 double(point1.y)
2999         };
3000
3001         _Util::Point<double> doublePoint3 =
3002         {
3003                 double(point1.x),
3004                 double(point1.y)
3005         };
3006
3007         return this->__FillTriangle(composedColor, doublePoint1, doublePoint2, doublePoint3);
3008 }
3009
3010 result
3011 _Canvas::FillTriangle(const Color& color, const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
3012 {
3013         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3014
3015         return this->__FillTriangle(composedColor, point1, point2, point3);
3016 }
3017
3018 result
3019 _Canvas::__FillTriangle(unsigned long composedColor, const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
3020 {
3021         // this->__lineWidth is always greater than 0
3022
3023         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3024
3025         if (pCairo && pCairo->pCairo)
3026         {
3027                 _Util::Point<double> point[] =
3028                 {
3029                         { point1.x, point1.y },
3030                         { point2.x, point2.y },
3031                         { point3.x, point3.y }
3032                 };
3033
3034                 SET_CAIRO_FILL_PROPERTIES;
3035
3036                 _Cairo::FillPolygon(pCairo->pCairo, composedColor, point, 3);
3037
3038                 RESET_CAIRO_FILL_PROPERTIES;
3039
3040                 return E_SUCCESS;
3041         }
3042         else
3043         {
3044                 _CanvasTriangle triangle;
3045                 _GpBufferInfo info;
3046
3047                 memset(&info, 0, sizeof(info));
3048
3049                 SystemPixel* pBufferAddr = null;
3050                 int bufferPitch = 0;
3051
3052                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3053
3054                 info.width = __pScratchPad->GetWidth();
3055                 info.height = __pScratchPad->GetHeight();
3056                 info.bitsPerPixel = 32;
3057                 info.pixelPerLine = bufferPitch;
3058                 info.pPixels = (void*) pBufferAddr;
3059                 info.color32 = composedColor;
3060                 info.isClipBoundsSet = this->__isClipBoundsSet;
3061                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3062
3063                 triangle.SetLineWidth(this->__lineWidth.asInteger);
3064
3065                 return triangle.FillTriangle(int(point1.x), int(point1.y), int(point2.x), int(point2.y), int(point3.x), int(point3.y), info);
3066         }
3067 }
3068
3069 result
3070 _Canvas::__FillEllipse(unsigned long composedColor, const _Util::Rectangle<double>& bounds)
3071 {
3072         if ((bounds.w <= 0.0) || (bounds.h <= 0.0))
3073         {
3074                 return E_SUCCESS;
3075         }
3076
3077         // this->__lineWidth is always greater than 0
3078
3079         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3080
3081         if (pCairo && pCairo->pCairo)
3082         {
3083                 SET_CAIRO_FILL_PROPERTIES;
3084
3085                 _Cairo::FillEllipse(pCairo->pCairo, composedColor, bounds);
3086
3087                 RESET_CAIRO_FILL_PROPERTIES;
3088
3089                 return E_SUCCESS;
3090         }
3091         else
3092         {
3093                 _CanvasEllipse ellipse;
3094                 _GpBufferInfo info;
3095
3096                 memset(&info, 0, sizeof(info));
3097
3098                 SystemPixel* pBufferAddr = null;
3099                 int bufferPitch = 0;
3100
3101                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3102
3103                 info.width = __pScratchPad->GetWidth();
3104                 info.height = __pScratchPad->GetHeight();
3105                 info.bitsPerPixel = 32;
3106                 info.pixelPerLine = bufferPitch;
3107                 info.pPixels = (void*) pBufferAddr;
3108                 info.color32 = composedColor;
3109                 info.isClipBoundsSet = this->__isClipBoundsSet;
3110                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3111
3112                 ellipse.SetLineWidth(this->__lineWidth.asInteger);
3113
3114                 return ellipse.FillElliepse(int(bounds.x), int(bounds.y), int(bounds.w), int(bounds.h), info);
3115         }
3116 }
3117
3118 result
3119 _Canvas::FillEllipse(const Color& color, const _Util::Rectangle<int>& bounds)
3120 {
3121         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3122
3123         _Util::Rectangle<double> doubleBounds =
3124         {
3125                 double(bounds.x),
3126                 double(bounds.y),
3127                 double(bounds.w),
3128                 double(bounds.h)
3129         };
3130
3131         return this->__FillEllipse(composedColor, doubleBounds);
3132 }
3133
3134 result
3135 _Canvas::FillEllipse(const Color& color, const _Util::Rectangle<double>& bounds)
3136 {
3137         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3138
3139         return this->__FillEllipse(composedColor, bounds);
3140 }
3141
3142 result
3143 _Canvas::FillPolygon(const Color& color, const _Util::Point<double>* pPoints, unsigned int pointCount)
3144 {
3145         //
3146         // Implementation of this method in API versions prior to 2.0 has the following issue:
3147         //
3148         // -# If there are 4 input points and conditions below is satisfied, the drawing result does not match the expected behavior. @n
3149         //
3150         //   "point[0].x == point[3].x && point[1].x == point[2].x && point[0].y == point[1].y && point[2].y == point[3].y"
3151         //
3152         // there are 4 cases can be occurred.
3153         //
3154         // [case1] (p[0]->x > p[1]->x && p[0]->y > p[3]->y)
3155         //
3156         //              p2________p3
3157         //              |         |
3158         //              |         |
3159         //              |         |     <--- expected result
3160         //              |         |
3161         //              p1--------p0_________
3162         //                                 |         |
3163         //                                 |         |
3164         //                                 |         |   <--- wrong result
3165         //                                 |         |
3166         //                                  ---------
3167         //
3168         // [case2] (p[0]->x < p[1]->x && p[0]->y > p[3]->y)
3169         //
3170         //              p3________p2
3171         //              |         |
3172         //              |         |
3173         //              |         |   <--- expected result
3174         //              |         |
3175         //              p0--------p1
3176         //              |         |
3177         //              |         |
3178         //              |         |   <--- wrong result
3179         //              |         |
3180         //               ---------
3181         //
3182         // [case3] (p[0]->x < p[1]->x && p[0]->y < p[3]->y)
3183         //
3184         //              p0________p1
3185         //              |         |
3186         //              |         |
3187         //              |         |   <--- no problem.
3188         //              |         |
3189         //              p3--------p2
3190         //
3191         //
3192         // [case4] (p[0]->x > p[1]->x && p[0]->y < p[3]->y)
3193         //
3194         //              p1________p0________
3195         //              |         |         |
3196         //              |         |         |
3197         //              |         |         |    <--- wrong result
3198         //              |         |         |
3199         //              p2--------p3--------
3200         //                 ^
3201         //             |
3202         //              -- expected result
3203         //
3204         // The issue mentioned above is resolved in API version 2.0, So, check the SDK version and emulate problem before step forward furthermore.
3205         //
3206         // CR approved, no. EP-47D6817268074396919211307C39CA55
3207         //
3208
3209         // this->__lineWidth is always greater than 0
3210
3211         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3212
3213         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3214
3215         if (pCairo && pCairo->pCairo)
3216         {
3217                 SET_CAIRO_FILL_PROPERTIES;
3218
3219                 _Cairo::FillPolygon(pCairo->pCairo, composedColor, pPoints, pointCount);
3220
3221                 RESET_CAIRO_FILL_PROPERTIES;
3222
3223                 return E_SUCCESS;
3224         }
3225         else
3226         {
3227                 _CanvasFillPolygon polygon;
3228                 _GpBufferInfo info;
3229
3230                 memset(&info, 0, sizeof(info));
3231
3232                 SystemPixel* pBufferAddr = null;
3233                 int bufferPitch = 0;
3234
3235                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3236
3237                 info.width = __pScratchPad->GetWidth();
3238                 info.height = __pScratchPad->GetHeight();
3239                 info.bitsPerPixel = 32;
3240                 info.pixelPerLine = bufferPitch;
3241                 info.pPixels = (void*) pBufferAddr;
3242                 info.color32 = composedColor;
3243                 info.isClipBoundsSet = this->__isClipBoundsSet;
3244                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3245
3246                 polygon.SetLineWidth(this->__lineWidth.asInteger);
3247
3248                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
3249
3250                 _GpPoint* pTempPoints = tempPoints.get();
3251
3252                 if (pTempPoints == null)
3253                 {
3254                         return E_SYSTEM;
3255                 }
3256
3257                 for (unsigned int i = 0; i < pointCount; i++)
3258                 {
3259                         pTempPoints[i].x = int(pPoints[i].x);
3260                         pTempPoints[i].y = int(pPoints[i].y);
3261                 }
3262
3263                 result r = polygon.FillPolygon(int(pointCount), pTempPoints, info);
3264
3265                 return r;
3266         }
3267 }
3268
3269 result
3270 _Canvas::__FillRectangle(unsigned long composedColor, const _Util::Rectangle<double>& rectangle)
3271 {
3272         if ((rectangle.w <= 0.0) || (rectangle.h <= 0.0))
3273         {
3274                 return E_SUCCESS;
3275         }
3276
3277         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3278
3279         if (pCairo && pCairo->pCairo)
3280         {
3281                 SET_CAIRO_FILL_PROPERTIES;
3282
3283                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, rectangle);
3284
3285                 RESET_CAIRO_FILL_PROPERTIES;
3286
3287                 return E_SUCCESS;
3288         }
3289         else
3290         {
3291                 _Util::Rectangle<int> rect =
3292                 {
3293                         static_cast<int>(rectangle.x),
3294                         static_cast<int>(rectangle.y),
3295                         static_cast<int>(rectangle.w),
3296                         static_cast<int>(rectangle.h)
3297                 };
3298
3299                 if (this->__isClipBoundsSet)
3300                 {
3301                         int x1 = rect.x;
3302                         int y1 = rect.y;
3303                         int x2 = x1 + rect.w;
3304                         int y2 = y1 + rect.h;
3305
3306                         x1 = (x1 >= this->__clipBounds.x) ? x1 : this->__clipBounds.x;
3307                         y1 = (y1 >= this->__clipBounds.y) ? y1 : this->__clipBounds.y;
3308
3309                         x2 = (x2 <= this->__clipBounds.x + this->__clipBounds.width) ? x2 : this->__clipBounds.x + this->__clipBounds.width;
3310                         y2 = (y2 <= this->__clipBounds.y + this->__clipBounds.height) ? y2 : this->__clipBounds.y + this->__clipBounds.height;
3311
3312                         rect.x = x1;
3313                         rect.y = y1;
3314                         rect.w = x2 - x1;
3315                         rect.h = y2 - y1;
3316                 }
3317
3318                 if (rect.w > 0 && rect.h > 0)
3319                 {
3320                         // alpha-fill-rect() applied
3321                         __pScratchPad->RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
3322                         __pScratchPad->FillRect(rect.x, rect.y, rect.w, rect.h, composedColor);
3323                         __pScratchPad->RegisterFillRect(null);
3324                 }
3325         }
3326
3327         return E_SUCCESS;
3328 }
3329
3330 result
3331 _Canvas::FillRectangle(const Color& color, const Rectangle& rect)
3332 {
3333         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3334
3335         return this->__FillRectangle(composedColor, _Util::Convert<Rectangle, _Util::Rectangle<double> >(rect));
3336 }
3337
3338 result
3339 _Canvas::FillRectangle(const Color& color, const _Util::Rectangle<int>& rect)
3340 {
3341         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3342
3343         _Util::Rectangle<double> doubleRect =
3344         {
3345                 double(rect.x),
3346                 double(rect.y),
3347                 double(rect.w),
3348                 double(rect.h)
3349         };
3350
3351         return this->__FillRectangle(composedColor, doubleRect);
3352 }
3353
3354 result
3355 _Canvas::FillRectangle(const Color& color, const _Util::Rectangle<double>& rect)
3356 {
3357         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3358
3359         return this->__FillRectangle(composedColor, rect);
3360 }
3361
3362 result
3363 _Canvas::FillRoundRectangle(const Color& color, const _Util::Rectangle<int>& rect, const _Util::Dimension<int>& arcDim)
3364 {
3365         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3366
3367         _Util::Rectangle<double> doubleRect =
3368         {
3369                 double(rect.x),
3370                 double(rect.y),
3371                 double(rect.w),
3372                 double(rect.h)
3373         };
3374
3375         _Util::Dimension<double> doubleArcDim =
3376         {
3377                 double(rect.w),
3378                 double(rect.h)
3379         };
3380
3381         return this->__FillRoundRectangle(composedColor, doubleRect, doubleArcDim);
3382 }
3383
3384 result
3385 _Canvas::FillRoundRectangle(const Color& color, const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
3386 {
3387         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3388
3389         return this->__FillRoundRectangle(composedColor, rect, arcDim);
3390 }
3391
3392 result
3393 _Canvas::__FillRoundRectangle(unsigned long composedColor, const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
3394 {
3395         if ((rect.w <= 0.0) || (rect.h <= 0.0))
3396         {
3397                 return E_SUCCESS;
3398         }
3399
3400         if ((int(arcDim.w) <= 0) || (int(arcDim.h) <= 0))
3401         {
3402                 return this->__FillRectangle(composedColor, rect);
3403         }
3404
3405         _Util::Dimension<double> revisedArcDim =
3406         {
3407                 (arcDim.w <= rect.w / 2.0) ? arcDim.w : rect.w / 2.0,
3408                 (arcDim.h <= rect.h / 2.0) ? arcDim.h : rect.h / 2.0
3409         };
3410
3411         // this->__lineWidth is always greater than 0
3412
3413         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3414
3415         if (pCairo && pCairo->pCairo)
3416         {
3417                 SET_CAIRO_FILL_PROPERTIES;
3418
3419                 _Cairo::FillRoundRectangle(pCairo->pCairo, composedColor, rect, revisedArcDim);
3420
3421                 RESET_CAIRO_FILL_PROPERTIES;
3422
3423                 return E_SUCCESS;
3424         }
3425         else
3426         {
3427                 _CanvasRoundRect roundRect;
3428                 _GpBufferInfo info;
3429
3430                 memset(&info, 0, sizeof(info));
3431
3432                 SystemPixel* pBufferAddr = null;
3433                 int bufferPitch = 0;
3434
3435                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3436
3437                 info.width = __pScratchPad->GetWidth();
3438                 info.height = __pScratchPad->GetHeight();
3439                 info.bitsPerPixel = 32;
3440                 info.pixelPerLine = bufferPitch;
3441                 info.pPixels = (void*) pBufferAddr;
3442                 info.color32 = composedColor;
3443                 info.isClipBoundsSet = this->__isClipBoundsSet;
3444                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3445
3446                 roundRect.SetLineWidth(this->__lineWidth.asInteger);
3447
3448                 return roundRect.FillRoundRectangle(int(rect.x), int(rect.y), int(rect.w), int(rect.h), int(revisedArcDim.w), int(revisedArcDim.h), info);
3449         }
3450 }
3451
3452 result
3453 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text)
3454 {
3455         return _Font::DrawText(*this, point, text, 0, text.GetLength());
3456 }
3457
3458 result
3459 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text, int startIndex, int length)
3460 {
3461         return _Font::DrawText(*this, point, text, startIndex, length);
3462 }
3463
3464 result
3465 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
3466 {
3467         return _Font::DrawText(*this, point, text, startIndex, length, outlineColor);
3468 }
3469
3470 Rectangle
3471 _Canvas::GetBounds(void) const
3472 {
3473         Rectangle rect(this->__xBufferPos, this->__yBufferPos, __pScratchPad->GetWidth(), __pScratchPad->GetHeight());
3474
3475         if (this->__windowHandle != INVALID_HANDLE)
3476         {
3477                 rect.x = 0;
3478                 rect.y = 0;
3479         }
3480
3481         return rect;
3482 }
3483
3484 LineStyle
3485 _Canvas::GetLineStyle() const
3486 {
3487         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_STYLE_MAX, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3488
3489         return this->__lineStyle;
3490 }
3491
3492 int
3493 _Canvas::GetLineWidth() const
3494 {
3495         SysTryReturn(NID_GRP, this && this->__pSurface, -1, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3496
3497         return this->__lineWidth.asInteger;
3498 }
3499
3500 LineCapStyle
3501 _Canvas::GetLineCapStyle() const
3502 {
3503         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_CAP_STYLE_ROUND, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3504
3505         return this->__lineCapStyle;
3506 }
3507
3508 LineJoinStyle
3509 _Canvas::GetLineJoinStyle() const
3510 {
3511         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_JOIN_STYLE_ROUND, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3512
3513         return this->__lineJoinStyle;
3514 }
3515
3516 result
3517 _Canvas::SetLineStyle(LineStyle style)
3518 {
3519         this->__lineStyle = style;
3520
3521         return E_SUCCESS;
3522 }
3523
3524 result
3525 _Canvas::SetLineWidth(int width, float widthAsFloat)
3526 {
3527         SysTryReturnResult(NID_GRP, width > 0 || widthAsFloat >= 0.0f, E_OUT_OF_RANGE, "The given line width(%d) is out of range.\n", width);
3528
3529         this->__lineWidth = width;
3530         this->__lineWidth.asDouble = double(widthAsFloat);
3531
3532         return E_SUCCESS;
3533 }
3534
3535 result
3536 _Canvas::SetLineWidth(float width)
3537 {
3538         SysTryReturnResult(NID_GRP, width > 0.0f, E_OUT_OF_RANGE, "The given line width(%f) is out of range.\n", width);
3539
3540         this->__lineWidth = width;
3541
3542         return E_SUCCESS;
3543 }
3544
3545 result
3546 _Canvas::SetLineCapStyle(LineCapStyle lineCapStyle)
3547 {
3548         this->__lineCapStyle = lineCapStyle;
3549
3550         return E_SUCCESS;
3551 }
3552
3553 result
3554 _Canvas::SetLineJoinStyle(LineJoinStyle lineJoinStyle)
3555 {
3556         this->__lineJoinStyle = lineJoinStyle;
3557
3558         return E_SUCCESS;
3559 }
3560
3561 result
3562 _Canvas::SetDashPattern(const Tizen::Graphics::_Util::AccumList<double>& dashValueList, double offset)
3563 {
3564         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3565
3566         {
3567                 Tizen::Graphics::_Util::AccumList<double> listSwap;
3568                 this->__dashData.pattern.Swap(listSwap);
3569
3570                 this->__dashData.offset = 0.0;
3571         }
3572
3573         {
3574                 Tizen::Graphics::_Util::AccumList<double>::ConstIterator dashIterator = dashValueList.Begin();
3575
3576                 for (; dashIterator != dashValueList.End(); dashIterator++)
3577                 {
3578                         this->__dashData.pattern.Push(*dashIterator);
3579                 }
3580
3581                 this->__dashData.offset = offset;
3582         }
3583
3584         return E_SUCCESS;
3585 }
3586
3587 void
3588 _Canvas::SetDrawingQuality(BitmapDrawingQuality quality)
3589 {
3590         // 'quality' is verified in _CanvasImpl::SetDrawingQuality()
3591         this->__bitmapDrawingQuality = quality;
3592 }
3593
3594 BitmapDrawingQuality
3595 _Canvas::GetDrawingQuality(void) const
3596 {
3597         return this->__bitmapDrawingQuality;
3598 }
3599
3600 void
3601 _Canvas::SetCompositeMode(CompositeMode compositeMode)
3602 {
3603         // 'blendingMode' is verified in _CanvasImpl::SetBlendingMode()
3604         this->__compositeMode = compositeMode;
3605 }
3606
3607 CompositeMode
3608 _Canvas::GetCompositeMode(void) const
3609 {
3610         return this->__compositeMode;
3611 }
3612
3613 result
3614 _Canvas::GetPixel(const Point& point, Color& color) const
3615 {
3616         Point pos(point.x, point.y);
3617
3618         // [ykahn 2011.06.27] revise the value of 'point' if it goes out-of-range
3619         {
3620                 Rectangle rtCanvas = _GetBoundsRel(*this);
3621
3622                 SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_OUT_OF_RANGE, "Cannot get the bounds of the canvas.\n");
3623
3624                 if (pos.x >= rtCanvas.width && rtCanvas.width >= 1)
3625                 {
3626                         pos.x = rtCanvas.width - 1;
3627                 }
3628
3629                 if (pos.y >= rtCanvas.height && rtCanvas.height >= 1)
3630                 {
3631                         pos.y = rtCanvas.height - 1;
3632                 }
3633         }
3634
3635         {
3636                 result r = E_OUT_OF_RANGE;
3637
3638                 Rectangle rect = this->GetBounds();
3639
3640                 rect.x = 0;
3641                 rect.y = 0;
3642
3643                 if ((point.x >= rect.x && point.x < rect.x + rect.width) && (point.y >= rect.y && point.y < rect.y + rect.height))
3644                 {
3645                         BufferInfo info;
3646
3647                         (const_cast<_Canvas*>(this))->Lock(info);
3648
3649                         if (info.bitsPerPixel == 32)
3650                         {
3651                                 unsigned long* pDest32 = (unsigned long*) info.pPixels;
3652                                 long pitch = info.pitch / 4;
3653
3654                                 color.SetRGB32(pDest32[pitch * point.y + point.x], true);
3655
3656                                 r = E_SUCCESS;
3657                         }
3658                         else if (info.bitsPerPixel == 16)
3659                         {
3660                                 unsigned short* pDest16 = (unsigned short*) info.pPixels;
3661                                 long pitch = info.pitch / 2;
3662
3663                                 unsigned short color16 = pDest16[pitch * point.y + point.x];
3664
3665                                 unsigned long r = (color16 & 0xF800) >> 8;
3666                                 unsigned long g = (color16 & 0x07E0) >> 3;
3667                                 unsigned long b = (color16 & 0x001F) << 3;
3668
3669                                 r += (r >> 5);
3670                                 g += (g >> 6);
3671                                 b += (b >> 5);
3672
3673                                 unsigned long color32 = 0xFF000000 | (r << 16) | (g << 8) | (b);
3674
3675                                 color.SetRGB32(color32, true);
3676
3677                                 r = E_SUCCESS;
3678                         }
3679
3680                         (const_cast<_Canvas*>(this))->Unlock();
3681                 }
3682
3683                 return r;
3684         }
3685 }
3686
3687 result
3688 _Canvas::SetPixel(const _Util::Point<int>& point)
3689 {
3690         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
3691
3692         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3693
3694         if (pCairo && pCairo->pCairo)
3695         {
3696                  _Util::Rectangle<double> rectangle = {double(point.x), double(point.y), 1.0, 1.0};
3697
3698                 SET_CAIRO_FILL_PROPERTIES;
3699
3700                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, rectangle);
3701
3702                 RESET_CAIRO_FILL_PROPERTIES;
3703
3704                 return E_SUCCESS;
3705         }
3706
3707         if (!this->__isClipBoundsSet)
3708         {
3709                 __pScratchPad->FillRect(point.x, point.y, 1, 1, composedColor);
3710         }
3711         else
3712         {
3713                 _Util::Rectangle<int> rect = { point.x, point.y, 1, 1 };
3714                 _Util::Rectangle<int> clip = { this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height };
3715
3716                 _FillRectangleWithClip(__pScratchPad, composedColor, rect, clip);
3717         }
3718
3719         return E_SUCCESS;
3720 }
3721
3722 result
3723 _Canvas::SetPixel(const _Util::Point<double>& point)
3724 {
3725         _Util::Rectangle<double> doubleRect =
3726         {
3727                 point.x,
3728                 point.y,
3729                 1.0,
3730                 1.0
3731         };
3732
3733         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
3734
3735         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3736
3737         if (pCairo && pCairo->pCairo)
3738         {
3739                 SET_CAIRO_FILL_PROPERTIES;
3740
3741                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, doubleRect);
3742
3743                 RESET_CAIRO_FILL_PROPERTIES;
3744
3745                 return E_SUCCESS;
3746         }
3747
3748         this->__FillRectangle(composedColor, doubleRect);
3749
3750         return E_SUCCESS;
3751 }
3752
3753 result
3754 _Canvas::Show()
3755 {
3756         int bufferWidth = __pSurface->GetWidth();
3757         int bufferHeight = __pSurface->GetHeight();
3758         int bufferPpl = __pSurface->GetPitch();
3759
3760         // cannot use 'if (__pSurface->GetHandle())'
3761         if (this->__windowHandle != INVALID_HANDLE)
3762         {
3763 #if 0
3764                 evas_object_image_pixels_dirty_set((Evas_Object*) this->__windowHandle, true);
3765 #else
3766                 Evas_Object* pSourceObject = _GetWindowSourceObject(this->__windowHandle);
3767                 evas_object_image_data_set(pSourceObject, evas_object_image_data_get(pSourceObject, EINA_TRUE));
3768                 evas_object_image_data_update_add(pSourceObject, 0, 0, bufferWidth, bufferHeight);
3769 #endif
3770
3771                 evas_object_show((Evas_Object*) this->__windowHandle);
3772
3773                 _FlushCanvas();
3774         }
3775         else
3776         {
3777                 SysTryReturnResult(NID_GRP, Tizen::App::_AppInfo::IsOspCompat(), E_UNSUPPORTED_OPERATION, "This method is unsupported in Tizen.");
3778
3779                 _CanvasShowFromMemory(this->__xBufferPos, this->__yBufferPos, 0, 0, bufferWidth, bufferHeight, __pBuffer, bufferWidth, bufferHeight, 32, bufferPpl * 4);
3780         }
3781
3782         return E_SUCCESS;
3783 }
3784
3785 result
3786 _Canvas::Show(const Rectangle& rect)
3787 {
3788         if ((rect.width == 0) || (rect.height == 0))
3789         {
3790                 return E_SUCCESS;
3791         }
3792
3793         if (this->__windowHandle != INVALID_HANDLE)
3794         {
3795                 int x1 = rect.x;
3796                 int x2 = rect.x + rect.width;
3797                 int y1 = rect.y;
3798                 int y2 = rect.y + rect.height;
3799
3800                 if (x1 + 1 < x2)
3801                 {
3802                         x1++;
3803                 }
3804
3805                 if (x2 - 1 > x1)
3806                 {
3807                         x2--;
3808                 }
3809
3810                 if (y1 + 1 < y2)
3811                 {
3812                         y1++;
3813                 }
3814
3815                 if (y2 - 1 > y1)
3816                 {
3817                         y2--;
3818                 }
3819
3820 #if 0
3821                 evas_object_image_pixels_dirty_set((Evas_Object*) this->__windowHandle, true);
3822                 // same as evas_object_image_data_update_add((Evas_Object*)this->__windowHandle, rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2), if (width >= 3) and (height >= 3)
3823                 evas_object_image_data_update_add((Evas_Object*) this->__windowHandle, x1, y1, x2 - x1, y2 - y1);
3824 #else
3825                 Evas_Object* pSourceObject = _GetWindowSourceObject(this->__windowHandle);
3826                 evas_object_image_data_set(pSourceObject, evas_object_image_data_get(pSourceObject, EINA_TRUE));
3827                 evas_object_image_data_update_add(pSourceObject, x1, y1, x2 - x1, y2 - y1);
3828 #endif
3829
3830                 evas_object_show((Evas_Object*) this->__windowHandle);
3831
3832                 _FlushCanvas();
3833         }
3834         else
3835         {
3836                 SysTryReturnResult(NID_GRP, Tizen::App::_AppInfo::IsOspCompat(), E_UNSUPPORTED_OPERATION, "This method is unsupported in Tizen.");
3837
3838                 int bufferWidth = __pSurface->GetWidth();
3839                 int bufferHeight = __pSurface->GetHeight();
3840                 int bufferPpl = __pSurface->GetPitch();
3841
3842                 _CanvasShowFromMemory(this->__xBufferPos + rect.x, this->__yBufferPos + rect.y, rect.x, rect.y, rect.width, rect.height, __pBuffer, bufferWidth, bufferHeight, 32, bufferPpl * 4);
3843         }
3844
3845         return E_SUCCESS;
3846 }
3847
3848 result
3849 _Canvas::SetFont(const _Font& font)
3850 {
3851         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.");
3852
3853         // weak reference
3854         this->__pFont = const_cast<_Font*>(&font);
3855
3856         return E_SUCCESS;
3857 }
3858
3859 result
3860 _Canvas::SetPriorityFont(const _Font& font)
3861 {
3862         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.");
3863
3864         // weak reference
3865         this->__pPriorityFont = const_cast<_Font*>(&font);
3866
3867         return E_SUCCESS;
3868 }
3869
3870 void
3871 _Canvas::ResetPriorityFont(void)
3872 {
3873         // nullify weak reference
3874         this->__pPriorityFont = null;
3875 }
3876
3877 result
3878 _Canvas::SetClipBounds(const Rectangle& rect)
3879 {
3880         if (__pScratchPad == null)
3881         {
3882                 return E_SYSTEM;
3883         }
3884
3885         int x1 = rect.x;
3886         int y1 = rect.y;
3887         int x2 = x1 + rect.width;
3888         int y2 = y1 + rect.height;
3889
3890         x1 = (x1 > 0) ? x1 : 0;
3891         y1 = (y1 > 0) ? y1 : 0;
3892         x2 = (x2 < __pScratchPad->GetWidth()) ? x2 : __pScratchPad->GetWidth();
3893         y2 = (y2 < __pScratchPad->GetHeight()) ? y2 : __pScratchPad->GetHeight();
3894
3895         x2 = (x1 > x2) ? x1 : x2;
3896         y2 = (y1 > y2) ? y1 : y2;
3897
3898         if (x1 == 0 && y1 == 0 && x2 == __pScratchPad->GetWidth() && y2 == __pScratchPad->GetHeight())
3899         {
3900                 this->__isClipBoundsSet = false;
3901         }
3902         else
3903         {
3904                 this->__isClipBoundsSet = true;
3905         }
3906
3907         this->__clipBounds.SetBounds(x1, y1, x2 - x1, y2 - y1);
3908
3909         return E_SUCCESS;
3910 }
3911
3912 Rectangle
3913 _Canvas::GetClipBounds(void) const
3914 {
3915         Rectangle rect;
3916
3917         SysTryReturn(NID_GRP, this && this->__pSurface, rect, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3918
3919         this->__GetClipBounds(rect);
3920
3921         return rect;
3922 }
3923
3924 result
3925 _Canvas::Lock(BufferInfo& info, long timeout)
3926 {
3927         if (__pScratchPad == null)
3928         {
3929                 return E_SYSTEM;
3930         }
3931
3932         if (_BufferInfoImpl::GetInstance(info) != null)
3933         {
3934                 _BufferInfoImpl::GetInstance(info)->SetHandle(_BufferInfoImpl::HANDLE_TYPE_NONE, 0);
3935         }
3936
3937         SystemPixel* pBufferAddr = null;
3938         int bufferPitch = 0;
3939
3940         __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3941
3942         info.width = __pScratchPad->GetWidth();
3943         info.height = __pScratchPad->GetHeight();
3944         info.pitch = bufferPitch * sizeof(_SystemPixel);
3945         info.bitsPerPixel = sizeof(_SystemPixel) * 8;
3946         info.pixelFormat = PIXEL_FORMAT_ARGB8888;
3947         info.pPixels = (void*) pBufferAddr;
3948         //info.__handle   = INVALID_HANDLE;
3949
3950         return E_SUCCESS;
3951 }
3952
3953 result
3954 _Canvas::Unlock()
3955 {
3956         return E_SUCCESS;
3957 }
3958
3959 void
3960 _Canvas::SetForegroundColor(const Color& fgColor)
3961 {
3962         this->__fgColorNative = fgColor;
3963         this->__ComposeFgColor();
3964 }
3965
3966 Color
3967 _Canvas::GetForegroundColor(void)
3968 {
3969         return Color(this->__fgColor);
3970 }
3971
3972 void
3973 _Canvas::SetBackgroundColor(const Color& bgColor)
3974 {
3975         this->__bgColorNative = bgColor;
3976         this->__ComposeBgColor();
3977 }
3978
3979 Color
3980 _Canvas::GetBackgroundColor(void)
3981 {
3982         return Color(this->__bgColor);
3983 }
3984
3985 void
3986 _Canvas::SetForegroundOpacity(int level)
3987 {
3988         SysTryReturnVoidResult(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3989
3990         if (level < 0)
3991         {
3992                 level = 0;
3993         }
3994
3995         if (level > 255)
3996         {
3997                 level = 255;
3998         }
3999
4000         this->__fgOpacity = level;
4001         this->__ComposeFgColor();
4002 }
4003
4004 int
4005 _Canvas::GetForegroundOpacity(void)
4006 {
4007         SysTryReturn(NID_GRP, this && this->__pSurface, 255, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4008
4009         return this->__fgOpacity;
4010 }
4011
4012 void
4013 _Canvas::SetBackgroundOpacity(int level)
4014 {
4015         SysTryReturnVoidResult(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4016
4017         if (level < 0)
4018         {
4019                 level = 0;
4020         }
4021
4022         if (level > 255)
4023         {
4024                 level = 255;
4025         }
4026
4027         this->__bgOpacity = level;
4028         this->__ComposeBgColor();
4029 }
4030
4031 int
4032 _Canvas::GetBackgroundOpacity(void)
4033 {
4034         SysTryReturn(NID_GRP, this && this->__pSurface, 255, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4035
4036         return this->__bgOpacity;
4037 }
4038
4039 result
4040 _Canvas::SetPosition(int x, int y)
4041 {
4042         SysTryReturnResult(NID_GRP, this->__windowHandle == INVALID_HANDLE, E_UNSUPPORTED_OPERATION, "Window canvas does not support moving the position.\n");
4043
4044         __xBufferPos = x;
4045         __yBufferPos = y;
4046
4047         return E_SUCCESS;
4048 }
4049
4050 void
4051 _Canvas::SetAntialiasingEnabled(bool enable)
4052 {
4053         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
4054
4055         if (pCairo && pCairo->pCairo)
4056         {
4057                 if (enable)
4058                 {
4059                         cairo_set_antialias(pCairo->pCairo, CAIRO_ANTIALIAS_DEFAULT);
4060                 }
4061                 else
4062                 {
4063                         cairo_set_antialias(pCairo->pCairo, CAIRO_ANTIALIAS_NONE);
4064                 }
4065         }
4066 }
4067
4068 bool
4069 _Canvas::IsAntialiasingEnabled(void) const
4070 {
4071         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
4072
4073         if (pCairo && pCairo->pCairo)
4074         {
4075                 return (cairo_get_antialias(pCairo->pCairo) == CAIRO_ANTIALIAS_DEFAULT);
4076         }
4077
4078         return false;
4079 }
4080
4081 _Canvas*
4082 _Canvas::GetInstance(_CanvasImpl& canvas)
4083 {
4084         return (&canvas != null) ? canvas._pNativeCanvas : null;
4085 }
4086
4087 const _Canvas*
4088 _Canvas::GetInstance(const _CanvasImpl& canvas)
4089 {
4090         return (&canvas != null) ? canvas._pNativeCanvas : null;
4091 }
4092
4093 bool
4094 _Canvas::_IsWindowCanvas(void) const
4095 {
4096         if (!(this && this->__pSurface))
4097         {
4098                 return false;
4099         }
4100
4101         return (this->__windowHandle != INVALID_HANDLE);
4102 }
4103
4104 result
4105 _Canvas::_SetPosition(int x, int y)
4106 {
4107         if (!(this && this->__pSurface))
4108         {
4109                 return E_OPERATION_FAILED;
4110         }
4111
4112         if (this->__windowHandle != INVALID_HANDLE)
4113         {
4114                 return E_UNSUPPORTED_OPERATION;
4115         }
4116
4117         //?? what is this function ?
4118         __xBufferPos = x;
4119         __yBufferPos = y;
4120
4121         return E_SUCCESS;
4122 }
4123
4124 int
4125 _Canvas::_GetAlphaAttenuation(const _Bitmap& bitmap) const
4126 {
4127         // 'bitmap' and 'this' are always valid.
4128
4129         int alphaConstant = bitmap.GetAlphaConstant();
4130
4131         alphaConstant = (alphaConstant > 255) ? 255 : alphaConstant;
4132         alphaConstant = (alphaConstant < 0) ? 0 : alphaConstant;
4133
4134         int fgOpacity = this->__fgOpacity;
4135
4136         if (fgOpacity > 0 && fgOpacity < 255)
4137         {
4138                 fgOpacity += (fgOpacity >> 7);
4139                 alphaConstant = (alphaConstant * fgOpacity) >> 8;
4140         }
4141
4142         return alphaConstant;
4143 }
4144
4145 void
4146 _Canvas::_SetBlendOption(_Canvas::BlendOption blendOption)
4147 {
4148         if (!(this && this->__pSurface))
4149         {
4150                 return;
4151         }
4152
4153         if (blendOption < BLEND_MIN || blendOption >= BLEND_MAX)
4154         {
4155                 return;
4156         }
4157
4158         this->__blendOption = blendOption;
4159 }
4160
4161 _Canvas::BlendOption
4162 _Canvas::_GetBlendOption(void) const
4163 {
4164         if (!(this && this->__pSurface))
4165         {
4166                 // default
4167                 return BLEND_ALPHABLEND;
4168         }
4169
4170         return this->__blendOption;
4171 }
4172
4173 void
4174 _Canvas::__InitFgBgColorFromTheme(void)
4175 {
4176         __fgColorNative = (_GetDefaultForegroundColor) ? _GetDefaultForegroundColor() : Color(0xFF000000);
4177         __bgColorNative = (_GetDefaultBackgroundColor) ? _GetDefaultBackgroundColor() : Color(0xFFFFFFFF);
4178
4179         this->__ComposeFgColor();
4180         this->__ComposeBgColor();
4181 }
4182
4183 void
4184 _Canvas::__ComposeFgColor(void)
4185 {
4186         this->__fgColor = _ComposeColor(this->__fgColorNative.GetRGB32(), this->__fgOpacity);
4187 }
4188
4189 void
4190 _Canvas::__ComposeBgColor(void)
4191 {
4192         this->__bgColor = _ComposeColor(this->__bgColorNative.GetRGB32(), this->__bgOpacity);
4193 }
4194
4195 void
4196 _Canvas::__GetClipBounds(Rectangle& rect) const
4197 {
4198         if (this->__isClipBoundsSet)
4199         {
4200                 rect = this->__clipBounds;
4201         }
4202         else
4203         {
4204                 rect = Rectangle(0, 0, __pScratchPad->GetWidth(), __pScratchPad->GetHeight());
4205         }
4206 }
4207
4208 result
4209 _Canvas::__Copy(const Point& destPoint, const _Canvas& srcCanvas, const Rectangle& srcRect)
4210 {
4211         const _Canvas* pSrcCanvas = &srcCanvas;
4212
4213         Rectangle clippedSrcRect(srcRect);
4214
4215         if (_ClipRectangle(clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height, 0, 0, pSrcCanvas->__pScratchPad->GetWidth(), pSrcCanvas->__pScratchPad->GetHeight()) == CLIP_REJECT)
4216         {
4217                 return E_SUCCESS;
4218         }
4219
4220         __pScratchPad->BitBlt(destPoint.x, destPoint.y, pSrcCanvas->__pScratchPad, clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height);
4221
4222         return E_SUCCESS;
4223 }
4224
4225 result
4226 _Canvas::__Copy(const Rectangle& destRect, const _Canvas& srcCanvas, const Rectangle& srcRect)
4227 {
4228         const _Canvas* pSrcCanvas = &srcCanvas;
4229
4230         Rectangle clippedSrcRect(srcRect);
4231
4232         if (_ClipRectangle(clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height, 0, 0, pSrcCanvas->__pScratchPad->GetWidth(), pSrcCanvas->__pScratchPad->GetHeight()) == CLIP_REJECT)
4233         {
4234                 return E_SUCCESS;
4235         }
4236
4237         {
4238                 SystemPixel* pSrcAddr = null;
4239                 int srcPitch = 0;
4240
4241                 pSrcCanvas->__pScratchPad->GetBuffer(pSrcAddr, srcPitch);
4242                 pSrcAddr += srcPitch * clippedSrcRect.y + clippedSrcRect.x;
4243
4244                 SystemPixel* pDstAddr = null;
4245                 int dstPitch = 0;
4246
4247                 __pScratchPad->GetBuffer(pDstAddr, dstPitch);
4248
4249                 _Util::Pixmap srcImageEx(clippedSrcRect.width, clippedSrcRect.height, sizeof(SystemPixel) * 8, pSrcAddr, srcPitch * sizeof(SystemPixel));
4250                 _Util::Pixmap dstImageEx(__pScratchPad->GetWidth(), __pScratchPad->GetHeight(), sizeof(SystemPixel) * 8, pDstAddr, dstPitch * sizeof(SystemPixel));
4251
4252                 Tizen::Graphics::_Effect::ScaleImage(dstImageEx, destRect.x, destRect.y, destRect.width, destRect.height, srcImageEx);
4253         }
4254
4255         return E_SUCCESS;
4256 }
4257
4258 bool
4259 _Canvas::__IsInClipBounds(const _Util::Rectangle<double>& bounds)
4260 {
4261         int x1 = 0;
4262         int y1 = 0;
4263         int x2 = x1 + this->GetBounds().width;
4264         int y2 = y1 + this->GetBounds().height;
4265
4266         if (this->__isClipBoundsSet)
4267         {
4268                 x1 = (this->__clipBounds.x > x1) ? this->__clipBounds.x : x1;
4269                 y1 = (this->__clipBounds.y > y1) ? this->__clipBounds.y : y1;
4270                 x2 = (this->__clipBounds.x + this->__clipBounds.width < x2) ? this->__clipBounds.x + this->__clipBounds.width : x2;
4271                 y2 = (this->__clipBounds.y + this->__clipBounds.height < y2) ? this->__clipBounds.y + this->__clipBounds.height : y2;
4272         }
4273
4274         return ((bounds.x >= x1) && (bounds.y >= y1) && (bounds.x + bounds.w <= x2) && (bounds.y + bounds.h <= y2));
4275 }
4276
4277 }} // Tizen::Graphics
4278