Merge "Fix for N_SE-34569" 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 && GetCompositeMode() != COMPOSITE_MODE_SRC_OVER)
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 && alphaConstant >= 255)
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 && GetCompositeMode() != COMPOSITE_MODE_SRC_OVER);
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 && GetCompositeMode() != COMPOSITE_MODE_SRC_OVER)
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 && alphaConstant >= 255)
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 && GetCompositeMode() != COMPOSITE_MODE_SRC_OVER)
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 #if 1
1822                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1823                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(outRect.x, outRect.y, outRect.w, outRect.h);
1824
1825                                 if (copyOnly)
1826                                 {
1827                                         pass = _Pixman::ScalePixmapOpCopy(dstImage, srcImage, GetDrawingQuality());
1828                                 }
1829                                 else
1830                                 {
1831                                         if (alphaConstant < 255)
1832                                         {
1833                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1834
1835                                                 if (modifiedSrcImage != null)
1836                                                 {
1837                                                         pass = _Pixman::ScalePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode());
1838                                                 }
1839                                         }
1840
1841                                         if (!pass)
1842                                         {
1843                                                 pass = _Pixman::ScalePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode());
1844                                         }
1845                                 }
1846 #else
1847                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1848
1849                                 if (copyOnly)
1850                                 {
1851                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(outRect.x, outRect.y, outRect.w, outRect.h);
1852
1853                                         pass = _Pixman::ScalePixmapOpCopy(dstImage, srcImage, GetDrawingQuality());
1854                                 }
1855                                 else
1856                                 {
1857                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1858
1859                                         if  (alphaConstant < 255)
1860                                         {
1861                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
1862
1863                                                 if (modifiedSrcImage != null)
1864                                                 {
1865                                                         pass = _Pixman::ScalePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height);
1866                                                 }
1867                                         }
1868
1869                                         if (!pass)
1870                                         {
1871                                                 pass = _Pixman::ScalePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height);
1872                                         }
1873                                 }
1874 #endif
1875                         }
1876
1877                         if (!pass && alphaConstant >= 255)
1878                         {
1879                                 unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1880
1881                                 _Util::Pixmap srcImage(srcRect.width, srcRect.height, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1882                                 _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1883
1884                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1885                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1886
1887                                 if (copyOnly)
1888                                 {
1889                                         pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1890                                 }
1891                                 else
1892                                 {
1893                                         pass = Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, destRect.width, destRect.height, srcImage, _ConvertParam<_Effect::Rop>(this->__blendOption));
1894                                 }
1895                         }
1896
1897                 }
1898
1899         }
1900
1901         if (!pass)
1902         {
1903                 _Util::Pixmap tmpImage(destRect.width, destRect.height, srcBitmap.GetBitsPerPixel());
1904
1905                 // copies the source bitmap to the scaled bitmap
1906                 {
1907                         // ykahn, 2011/10/11 patched
1908                         {
1909                                 _ApplySrcBitmapAttrib(tmpImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1910
1911                                 if (tmpImage.depth == 16)
1912                                 {
1913                                         if (tmpImage.enableColorKey)
1914                                         {
1915                                                 typedef unsigned short Pixel;
1916
1917                                                 Pixel colorKey = (Pixel) tmpImage.colorKey;
1918                                                 Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1919                                                 Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1920
1921                                                 while (pDest < pDestEnd)
1922                                                 {
1923                                                         *pDest++ = colorKey;
1924                                                 }
1925                                         }
1926                                         else
1927                                         {
1928                                         }
1929                                 }
1930                                 else if (tmpImage.depth == 32)
1931                                 {
1932                                         typedef unsigned long Pixel;
1933
1934                                         Pixel fillColor = 0;
1935                                         Pixel* pDest = (Pixel*) tmpImage.pBitmap;
1936                                         Pixel* pDestEnd = pDest + (tmpImage.bytesPerLine * tmpImage.height / (tmpImage.depth / 8));
1937
1938                                         while (pDest < pDestEnd)
1939                                         {
1940                                                 *pDest++ = fillColor;
1941                                         }
1942                                 }
1943                         }
1944
1945                         bool scaled = false;
1946
1947                         {
1948                                 _Util::LockManager srcLock(srcBitmap);
1949                                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
1950
1951                                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
1952
1953                                 {
1954                                         unsigned char* pPixels = (unsigned char*) srcBufferInfo.pPixels + srcRect.y * srcBufferInfo.pitch + srcRect.x * (srcBufferInfo.bitsPerPixel / 8);
1955
1956                                         _Util::Pixmap srcImage(srcRect.width, srcRect.height, srcBufferInfo.bitsPerPixel, (void*) pPixels, srcBufferInfo.pitch);
1957                                         _ApplySrcBitmapAttrib(srcImage, srcBitmap, srcBitmap.__isOpaqueAllOver);
1958
1959                                         scaled = Tizen::Graphics::_Effect::ScaleImage(tmpImage, 0, 0, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1960                                 }
1961                         }
1962
1963                         SysTryReturnResult(NID_GRP, scaled, E_INVALID_ARG, "The source bitmap is invalid.\n");
1964                 }
1965
1966                 {
1967                         _Util::LockManager dstLock(*this);
1968                         SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
1969
1970                         const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
1971
1972                         {
1973                                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1974                                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1975
1976                                 pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, destRect.x - clipRect.x, destRect.y - clipRect.y, tmpImage, alphaConstant);
1977                         }
1978                 }
1979         }
1980
1981         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
1982
1983         return E_SUCCESS;
1984 }
1985
1986 result
1987 _Canvas::DrawBitmap(const _Util::Point<double>& pointD, const _Bitmap& bitmap, FlipDirection dir)
1988 {
1989         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
1990
1991         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
1992
1993         Rectangle clipRect;
1994
1995         this->__GetClipBounds(clipRect);
1996
1997         {
1998                 _Util::Point<int> point =
1999                 {
2000                         _DoubleToIntForPos(pointD.x),
2001                         _DoubleToIntForPos(pointD.y)
2002                 };
2003
2004                 _Util::Pixmap* pFlippedImage = 0;
2005
2006                 {
2007                         _Util::LockManager srcLock(bitmap);
2008                         SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
2009
2010                         const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
2011
2012                         Tizen::Graphics::_Effect::Flip flip = (dir == FLIP_DIRECTION_HORIZONTAL) ? Tizen::Graphics::_Effect::FLIP_HORIZONTAL : Tizen::Graphics::_Effect::FLIP_VERTICAL;
2013
2014                         {
2015                                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
2016
2017                                 pFlippedImage = Tizen::Graphics::_Effect::GetFlippedImage(srcImage, flip);
2018                         }
2019                 }
2020
2021                 SysTryReturnResult(NID_GRP, pFlippedImage, E_INVALID_ARG, "The source bitmap is invalid.\n");
2022
2023                 _ApplySrcBitmapAttrib(*pFlippedImage, bitmap, bitmap.__isOpaqueAllOver);
2024
2025                 std::auto_ptr<_Util::Pixmap> autoReleasingImage(pFlippedImage);
2026
2027                 {
2028                         bool pass = false;
2029
2030                         if (!this->__useStableRenderer && pFlippedImage->depth == 32)
2031                         {
2032                                 _Util::LockManager dstLock(*this);
2033                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.");
2034
2035                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2036
2037                                 {
2038                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2039                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2040
2041                                         if  (alphaConstant < 255)
2042                                         {
2043                                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(pFlippedImage->GetAlphaAttenuatedPixmap(alphaConstant));
2044
2045                                                 if (modifiedSrcImage != null)
2046                                                 {
2047                                                         pass = _Pixman::CopyPixmap(dstImage, *modifiedSrcImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
2048                                                 }
2049                                         }
2050
2051                                         if (!pass)
2052                                         {
2053                                                 pass = _Pixman::CopyPixmap(dstImage, *pFlippedImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y);
2054                                         }
2055                                 }
2056                         }
2057
2058                         if (!pass)
2059                         {
2060                                 _Util::LockManager dstLock(*this);
2061                                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
2062
2063                                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2064
2065                                 {
2066                                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2067                                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2068
2069                                         pass = Tizen::Graphics::_Effect::DrawImageWithAlpha(dstImage, point.x - clipRect.x, point.y - clipRect.y, *pFlippedImage, alphaConstant);
2070                                 }
2071                         }
2072
2073                         SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
2074                 }
2075
2076                 return E_SUCCESS;
2077         }
2078 }
2079
2080 result
2081 _Canvas::DrawBitmap(const _Util::Point<double>& pointD, const _Bitmap& bitmap, const _Util::Point<double>& pivotD, double degreeD)
2082 {
2083         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2084
2085         Rectangle clipRect;
2086
2087         this->__GetClipBounds(clipRect);
2088
2089         int alphaConstant = this->_GetAlphaAttenuation(bitmap);
2090
2091         if (!this->__useStableRenderer && bitmap.GetBitsPerPixel() == 32)
2092         {
2093                 bool pass = false;
2094
2095                 _Util::LockManager srcLock(bitmap);
2096                 _Util::LockManager dstLock(*this);
2097
2098                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.");
2099                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.");
2100
2101                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
2102                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2103
2104                 {
2105                         _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
2106                         _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
2107
2108                         _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2109                         _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2110
2111                         if  (alphaConstant < 255)
2112                         {
2113                                 std::unique_ptr<_Util::Pixmap> modifiedSrcImage(srcImage.GetAlphaAttenuatedPixmap(alphaConstant));
2114
2115                                 if (modifiedSrcImage != null)
2116                                 {
2117                                         pass = _Pixman::RotatePixmap(dstImage, *modifiedSrcImage.get(), GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y, degreeD, pivotD.x, pivotD.y);
2118                                 }
2119                         }
2120
2121                         if (!pass)
2122                         {
2123                                 pass = _Pixman::RotatePixmap(dstImage, srcImage, GetDrawingQuality(), GetCompositeMode(), pointD.x - clipRect.x, pointD.y - clipRect.y, degreeD, pivotD.x, pivotD.y);
2124                         }
2125
2126                 }
2127
2128                 if (pass)
2129                 {
2130                         return E_SUCCESS;
2131                 }
2132         }
2133
2134 /*
2135     if (alphaConstant >= 255)
2136     {
2137         return pCanvasInterface->DrawBitmap(point.x, point.y, *((IBitmapPi*)*(IBitmapPi**)bitmap.__pImpl), pivot.x, pivot.y, degree);
2138     }
2139     else
2140 */
2141         {
2142                 _Util::LockManager srcLock(bitmap);
2143                 _Util::LockManager dstLock(*this);
2144
2145                 SysTryReturnResult(NID_GRP, srcLock.IsValid(), E_OPERATION_FAILED, "The source bitmap cannot be locked.\n");
2146                 SysTryReturnResult(NID_GRP, dstLock.IsValid(), E_OPERATION_FAILED, "The canvas cannot be locked.\n");
2147
2148                 const BufferInfo& srcBufferInfo = srcLock.GetBufferInfo();
2149                 const BufferInfo& dstBufferInfo = dstLock.GetBufferInfo();
2150
2151                 _Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
2152                 _Util::Pixmap dstImageUnclipped(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
2153                 _Util::Pixmap dstImage = dstImageUnclipped.GetSubBitmap(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
2154
2155                 _ApplySrcBitmapAttrib(srcImage, bitmap, bitmap.__isOpaqueAllOver);
2156
2157                 _Util::Point<int> point =
2158                 {
2159                         _DoubleToIntForPos(pointD.x),
2160                         _DoubleToIntForPos(pointD.y)
2161                 };
2162
2163                 Tizen::Graphics::_Effect::RotateDesc rotateDesc = { _DoubleToIntForRound(degreeD), _DoubleToIntForPos(pivotD.x), _DoubleToIntForPos(pivotD.y) };
2164
2165                 bool pass = Tizen::Graphics::_Effect::RotateImage(dstImage, point.x - clipRect.x, point.y - clipRect.y, srcImage, rotateDesc, alphaConstant);
2166
2167                 SysTryReturnResult(NID_GRP, pass, E_INVALID_ARG, "The source bitmap is invalid.\n");
2168
2169                 return E_SUCCESS;
2170         }
2171 }
2172
2173 result
2174 _Canvas::DrawNinePatchedBitmap(const Rectangle& rect, const _Bitmap& bitmap)
2175 {
2176         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2177
2178         // down-scales the source bitmap
2179         if (rect.width < bitmap.GetWidth() - 2 || rect.height < bitmap.GetHeight() - 2)
2180         {
2181 #if 1
2182                 int dstW = rect.width;
2183                 int dstH = rect.height;
2184                 int srcW = bitmap.GetWidth() - 2;
2185                 int srcH = bitmap.GetHeight() - 2;
2186
2187                 if (dstW <= 0 || dstH <= 0)
2188                 {
2189                         return E_SUCCESS;
2190                 }
2191
2192                 if (dstW * srcH < dstH * srcW)
2193                 {
2194                         // fit to width
2195                         dstW = srcW;
2196                         dstH = dstH * srcW / dstW;
2197                 }
2198                 else
2199                 {
2200                         // fit to height
2201                         dstW = dstW * srcH / dstH;
2202                         dstH = srcH;
2203                 }
2204
2205                 result r;
2206
2207                 {
2208                         const int PADDING = 1;
2209
2210                         _Bitmap expandedBitmap;
2211
2212                         r = expandedBitmap.Construct(Dimension(dstW + PADDING * 2, dstH + PADDING * 2), BITMAP_PIXEL_FORMAT_ARGB8888);
2213
2214                         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2215
2216                         _Util::LockManager dstBitmap(expandedBitmap);
2217
2218                         {
2219                                 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
2220
2221                                 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
2222
2223                                 _Canvas expandedCanvas;
2224
2225                                 r = expandedCanvas.Construct(dstBufferInfo);
2226
2227                                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2228
2229                                 expandedCanvas.SetDrawingQuality(BITMAP_DRAWING_QUALITY_HIGH);
2230                                 expandedCanvas.SetCompositeMode(COMPOSITE_MODE_SRC);
2231
2232                                 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
2233
2234                                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2235
2236                                 r = _Util::GetPatchList(boundsList, Rectangle(PADDING, PADDING, dstBufferInfo.width - PADDING * 2, dstBufferInfo.height - PADDING * 2), bitmap);
2237
2238                                 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
2239
2240                                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2241
2242                                 int alphaConstant = bitmap.GetAlphaConstant();
2243                                 const_cast<_Bitmap*>(&bitmap)->SetAlphaConstant(255);
2244
2245                                 while (iter != boundsList.End())
2246                                 {
2247                                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2248                                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2249
2250                                         expandedCanvas.DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect, true);
2251
2252                                         ++iter;
2253                                 }
2254
2255                                 const_cast<_Bitmap*>(&bitmap)->SetAlphaConstant(alphaConstant);
2256                                 expandedBitmap.SetAlphaConstant(alphaConstant);
2257                         }
2258
2259                         // not <- PADDING * 2>
2260                         Tizen::Graphics::Rectangle srcRect(PADDING, PADDING, expandedBitmap.GetWidth() - PADDING, expandedBitmap.GetHeight() - PADDING);
2261
2262                         return this->DrawBitmap(_Util::Convert<Rectangle, _Util::Rectangle<double> >(rect), expandedBitmap, _Util::Convert<Rectangle, _Util::Rectangle<double> >(srcRect));
2263                 }
2264
2265 #else // old spec.
2266                 Tizen::Graphics::Rectangle srcRect(1, 1, bitmap.GetWidth() - 2, bitmap.GetHeight() - 2);
2267
2268                 return this->DrawBitmap(rect, bitmap, srcRect);
2269 #endif
2270         }
2271
2272         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2273
2274         result r = _Util::GetPatchList(boundsList, rect, bitmap);
2275
2276         if (r == E_SUCCESS)
2277         {
2278                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2279
2280                 while (iter != boundsList.End())
2281                 {
2282                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2283                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2284
2285                         DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2286
2287                         ++iter;
2288                 }
2289         }
2290
2291         return r;
2292 }
2293
2294 result
2295 _Canvas::DrawNineTiledBitmap(const Rectangle& rect, const _Bitmap& bitmap)
2296 {
2297         SysTryReturnResult(NID_GRP, &bitmap && bitmap.IsValid(), E_INVALID_ARG, "The source bitmap is invalid.\n");
2298
2299         // down-scales the source bitmap
2300         if (rect.width < bitmap.GetWidth() - 2 || rect.height < bitmap.GetHeight() - 2)
2301         {
2302                 return this->DrawNinePatchedBitmap(rect, bitmap);
2303         }
2304
2305         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
2306
2307         result r = _Util::GetPatchList(boundsList, rect, bitmap);
2308
2309         if (r == E_SUCCESS)
2310         {
2311                 // This block is slow and not optimized.
2312                 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
2313
2314                 while (iter != boundsList.End())
2315                 {
2316                         Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
2317                         Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
2318
2319                         if (iter->first.w == iter->second.w && iter->first.h == iter->second.h)
2320                         {
2321                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2322                         }
2323                         else
2324                         {
2325                                 for (int y = iter->first.y; y < iter->first.y + iter->first.h; y += iter->second.h)
2326                                 {
2327                                         if (y + iter->second.h <= iter->first.y + iter->first.h)
2328                                         {
2329                                                 for (int x = iter->first.x; x < iter->first.x + iter->first.w; x += iter->second.w)
2330                                                 {
2331                                                         if (x + iter->second.w <= iter->first.x + iter->first.w)
2332                                                         {
2333                                                                 Rectangle destRect(x, y, iter->second.w, iter->second.h);
2334                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2335                                                         }
2336                                                         else
2337                                                         {
2338                                                                 // right side clipping
2339                                                                 int w = iter->first.x + iter->first.w - x;
2340
2341                                                                 Rectangle destRect(x, y, w, iter->second.h);
2342                                                                 Rectangle sourRect(iter->second.x, iter->second.y, w, iter->second.h);
2343
2344                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2345                                                         }
2346                                                 }
2347                                         }
2348                                         else
2349                                         {
2350                                                 // bottom side clipping
2351                                                 int h = iter->first.y + iter->first.h - y;
2352
2353                                                 for (int x = iter->first.x; x < iter->first.x + iter->first.w; x += iter->second.w)
2354                                                 {
2355                                                         if (x + iter->second.w <= iter->first.x + iter->first.w)
2356                                                         {
2357                                                                 Rectangle destRect(x, y, iter->second.w, h);
2358                                                                 Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, h);
2359                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2360                                                         }
2361                                                         else
2362                                                         {
2363                                                                 // right-bottom side clipping
2364                                                                 int w = iter->first.x + iter->first.w - x;
2365
2366                                                                 Rectangle destRect(x, y, w, h);
2367                                                                 Rectangle sourRect(iter->second.x, iter->second.y, w, h);
2368
2369                                                                 DrawBitmapForNinePatchedBitmap(destRect, bitmap, sourRect);
2370                                                         }
2371                                                 }
2372                                         }
2373                                 }
2374                         }
2375
2376                         ++iter;
2377                 }
2378         }
2379
2380         return r;
2381 }
2382
2383 result
2384 _Canvas::DrawEllipse(const _Util::Rectangle<int>& bounds)
2385 {
2386         _Util::Rectangle<double> doubleBounds =
2387         {
2388                 double(bounds.x),
2389                 double(bounds.y),
2390                 double(bounds.w),
2391                 double(bounds.h)
2392         };
2393
2394         return this->DrawEllipse(doubleBounds);
2395 }
2396
2397 result
2398 _Canvas::DrawEllipse(const _Util::Rectangle<double>& bounds)
2399 {
2400         if ((bounds.w <= 0.0) || (bounds.h <= 0.0))
2401         {
2402                 return E_SUCCESS;
2403         }
2404
2405         // this->__lineWidth is always greater than 0
2406
2407         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2408
2409         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2410
2411         bool shouldWorkAround = !__IsInClipBounds(bounds) && (this->__dashData.pattern.Size() == 0);
2412
2413         if (!shouldWorkAround && pCairo && pCairo->pCairo)
2414         {
2415                 SET_CAIRO_ALL_PROPERTIES;
2416
2417                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2418                 {
2419                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds);
2420                 }
2421                 else
2422                 {
2423                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds);
2424                 }
2425
2426                 RESET_CAIRO_ALL_PROPERTIES;
2427
2428                 return E_SUCCESS;
2429         }
2430         else if (shouldWorkAround && pCairo && pCairo->pCairo)
2431         {
2432                 SET_CAIRO_ALL_PROPERTIES;
2433
2434                 double pattern = (bounds.w + bounds.h) * 2.0;
2435                 _Cairo::SetDash(pCairo->pCairo, &pattern, 1, 0);
2436
2437                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2438                 {
2439                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, bounds);
2440                 }
2441                 else
2442                 {
2443                         _Cairo::DrawEllipse(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, bounds);
2444                 }
2445
2446                 RESET_CAIRO_ALL_PROPERTIES;
2447
2448                 return E_SUCCESS;
2449         }
2450         else
2451         {
2452                 _CanvasEllipse ellipse;
2453                 _GpBufferInfo info;
2454
2455                 memset(&info, 0, sizeof(info));
2456
2457                 SystemPixel* pBufferAddr = null;
2458                 int bufferPitch = 0;
2459
2460                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2461
2462                 info.width = __pScratchPad->GetWidth();
2463                 info.height = __pScratchPad->GetHeight();
2464                 info.bitsPerPixel = 32;
2465                 info.pixelPerLine = bufferPitch;
2466                 info.pPixels = (void*) pBufferAddr;
2467                 info.color32 = composedColor;
2468                 info.isClipBoundsSet = this->__isClipBoundsSet;
2469                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2470
2471                 ellipse.SetLineWidth(this->__lineWidth.asInteger);
2472
2473                 return ellipse.DrawEllipse(int(bounds.x), int(bounds.y), int(bounds.w), int(bounds.h), info);
2474         }
2475 }
2476
2477 result
2478 _Canvas::DrawLine(const _Util::Point<int>& point1, const _Util::Point<int>& point2)
2479 {
2480         _Util::Point<double> doublePoint1 =
2481         {
2482                 double(point1.x),
2483                 double(point1.y)
2484         };
2485
2486         _Util::Point<double> doublePoint2 =
2487         {
2488                 double(point2.x),
2489                 double(point2.y)
2490         };
2491
2492         return this->DrawLine(doublePoint1, doublePoint2);
2493 }
2494
2495 result
2496 _Canvas::DrawLine(const _Util::Point<double>& point1, const _Util::Point<double>& point2)
2497 {
2498         // this->__lineWidth is always greater than 0
2499
2500         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2501
2502         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2503
2504         if (pCairo && pCairo->pCairo)
2505         {
2506                 _Util::Point<double> point[] =
2507                 {
2508                         { point1.x, point1.y },
2509                         { point2.x, point2.y }
2510                 };
2511
2512                 SET_CAIRO_ALL_PROPERTIES;
2513
2514                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2515                 {
2516                         _Cairo::Drawline(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, point, 2);
2517                 }
2518                 else
2519                 {
2520                         _Cairo::Drawline(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, point, 2);
2521                 }
2522
2523                 RESET_CAIRO_ALL_PROPERTIES;
2524
2525                 return E_SUCCESS;
2526         }
2527         else
2528         {
2529                 _CanvasLine line;
2530                 _GpBufferInfo info;
2531
2532                 _GpPoint startPt =
2533                 {
2534                         int(point1.x),
2535                         int(point1.y)
2536                 };
2537
2538                 _GpPoint endPt =
2539                 {
2540                         int(point2.x),
2541                         int(point2.y)
2542                 };
2543
2544                 memset(&info, 0, sizeof(info));
2545
2546                 SystemPixel* pBufferAddr = null;
2547                 int bufferPitch = 0;
2548
2549                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2550
2551                 info.width = __pScratchPad->GetWidth();
2552                 info.height = __pScratchPad->GetHeight();
2553                 info.bitsPerPixel = 32;
2554                 info.pixelPerLine = bufferPitch;
2555                 info.pPixels = (void*) pBufferAddr;
2556                 info.color32 = composedColor;
2557                 info.isClipBoundsSet = this->__isClipBoundsSet;
2558                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2559
2560                 line.SetLineWidth(this->__lineWidth.asInteger);
2561
2562                 if (this->__lineWidth.asInteger == 1)
2563                 {
2564                         if ((startPt.x == endPt.x) && (startPt.y == endPt.y))
2565                         {
2566                                 this->SetPixel(point1);
2567                                 return E_SUCCESS;
2568                         }
2569                 }
2570
2571                 return line.DrawLine(startPt, endPt, info);
2572         }
2573 }
2574
2575 result
2576 _Canvas::DrawPolygon(const _Util::Point<double>* pPoints, unsigned int pointCount)
2577 {
2578         // this->__lineWidth is always greater than 0
2579
2580         if (pointCount == 1)
2581         {
2582                 return this->SetPixel(pPoints[0]);
2583         }
2584
2585         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2586
2587         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2588
2589         if (pCairo && pCairo->pCairo)
2590         {
2591                 SET_CAIRO_ALL_PROPERTIES;
2592
2593                 _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, pPoints, pointCount);
2594
2595                 RESET_CAIRO_ALL_PROPERTIES;
2596
2597                 return E_SUCCESS;
2598         }
2599         else
2600         {
2601                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
2602
2603                 _GpPoint* pTempPoints = tempPoints.get();
2604
2605                 if (pTempPoints == null)
2606                 {
2607                         return E_SYSTEM;
2608                 }
2609
2610                 for (unsigned int i = 0; i < pointCount; i++)
2611                 {
2612                         pTempPoints[i].x = int(pPoints[i].x);
2613                         pTempPoints[i].y = int(pPoints[i].y);
2614                 }
2615
2616                 _CanvasLine line;
2617                 _GpBufferInfo info;
2618
2619                 memset(&info, 0, sizeof(info));
2620
2621                 SystemPixel* pBufferAddr = null;
2622                 int bufferPitch = 0;
2623
2624                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2625
2626                 info.width = __pScratchPad->GetWidth();
2627                 info.height = __pScratchPad->GetHeight();
2628                 info.bitsPerPixel = 32;
2629                 info.pixelPerLine = bufferPitch;
2630                 info.pPixels = (void*) pBufferAddr;
2631                 info.color32 = composedColor;
2632                 info.isClipBoundsSet = this->__isClipBoundsSet;
2633                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2634
2635                 line.SetLineWidth(this->__lineWidth.asInteger);
2636
2637                 result r = line.DrawPolygon(int(pointCount), pTempPoints, info);
2638
2639                 return r;
2640         }
2641 }
2642
2643 result
2644 _Canvas::DrawPolyline(const _Util::Point<double>* pPoints, unsigned int pointCount)
2645 {
2646         // this->__lineWidth is always greater than 0
2647
2648         if (pointCount == 1)
2649         {
2650                 return this->SetPixel(pPoints[0]);
2651         }
2652
2653         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2654
2655         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2656
2657         if (pCairo && pCairo->pCairo)
2658         {
2659                 SET_CAIRO_ALL_PROPERTIES;
2660
2661                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2662                 {
2663                         _Cairo::DrawPolyline(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, pPoints, pointCount);
2664                 }
2665                 else
2666                 {
2667                         _Cairo::DrawPolyline(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, pPoints, pointCount);
2668                 }
2669
2670                 RESET_CAIRO_ALL_PROPERTIES;
2671
2672                 return E_SUCCESS;
2673         }
2674         else
2675         {
2676                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
2677
2678                 _GpPoint* pTempPoints = tempPoints.get();
2679
2680                 if (pTempPoints == null)
2681                 {
2682                         return E_SYSTEM;
2683                 }
2684
2685                 for (unsigned int i = 0; i < pointCount; i++)
2686                 {
2687                         pTempPoints[i].x = int(pPoints[i].x);
2688                         pTempPoints[i].y = int(pPoints[i].y);
2689                 }
2690
2691                 _CanvasLine line;
2692                 _GpBufferInfo info;
2693
2694                 memset(&info, 0, sizeof(info));
2695
2696                 SystemPixel* pBufferAddr = null;
2697                 int bufferPitch = 0;
2698
2699                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2700
2701                 info.width = __pScratchPad->GetWidth();
2702                 info.height = __pScratchPad->GetHeight();
2703                 info.bitsPerPixel = 32;
2704                 info.pixelPerLine = bufferPitch;
2705                 info.pPixels = (void*) pBufferAddr;
2706                 info.color32 = composedColor;
2707                 info.isClipBoundsSet = this->__isClipBoundsSet;
2708                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2709
2710                 line.SetLineWidth(this->__lineWidth.asInteger);
2711
2712                 result r = line.DrawPolyLine(int(pointCount), pTempPoints, info);
2713
2714                 return r;
2715         }
2716 }
2717
2718 result
2719 _Canvas::DrawRectangle(const _Util::Rectangle<int>& rect)
2720 {
2721         _Util::Rectangle<double> doubleRect =
2722         {
2723                 double(rect.x),
2724                 double(rect.y),
2725                 double(rect.w),
2726                 double(rect.h)
2727         };
2728
2729         return this->DrawRectangle(doubleRect);
2730 }
2731
2732 result
2733 _Canvas::DrawRectangle(const _Util::Rectangle<double>& rectangle)
2734 {
2735         if ((rectangle.w <= 0.0) || (rectangle.h <= 0.0))
2736         {
2737                 return E_SUCCESS;
2738         }
2739
2740         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2741
2742         bool tryToDrawWithCairo = (__lineWidth.applied == _Util::ScalarHolder::AS_DOUBLE || __lineWidth.asInteger > 1 || __dashData.pattern.Size() > 0);
2743
2744         if (tryToDrawWithCairo)
2745         {
2746                 _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2747
2748                 if (pCairo && pCairo->pCairo)
2749                 {
2750                         SET_CAIRO_ALL_PROPERTIES;
2751
2752                         if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2753                         {
2754                                 _Cairo::DrawRectangle(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, rectangle);
2755                         }
2756                         else
2757                         {
2758                                 _Cairo::DrawRectangle(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, rectangle);
2759                         }
2760
2761                         RESET_CAIRO_ALL_PROPERTIES;
2762
2763                         return E_SUCCESS;
2764                 }
2765         }
2766
2767         // falls through legacy drawing solution
2768
2769         int x1 = static_cast<int>(rectangle.x);
2770         int y1 = static_cast<int>(rectangle.y);
2771         int x2 = x1 + static_cast<int>(rectangle.w) - 1;
2772         int y2 = y1 + static_cast<int>(rectangle.h) - 1;
2773
2774         if (this->__lineWidth.asInteger == 1)
2775         {
2776                 if (!this->__isClipBoundsSet)
2777                 {
2778                         __pScratchPad->RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
2779
2780                         if (x2 > x1 && y2 > y1)
2781                         {
2782                                 __pScratchPad->FillRect(x1, y1, x2 - x1, 1, composedColor);
2783                                 __pScratchPad->FillRect(x2, y1, 1, y2 - y1, composedColor);
2784
2785                                 __pScratchPad->FillRect(x1 + 1, y2, x2 - x1, 1, composedColor);
2786                                 __pScratchPad->FillRect(x1, y1 + 1, 1, y2 - y1, composedColor);
2787                         }
2788                         else
2789                         {
2790                                 __pScratchPad->FillRect(x1, y1, static_cast<int>(rectangle.w), static_cast<int>(rectangle.h), composedColor);
2791                         }
2792
2793                         __pScratchPad->RegisterFillRect(null);
2794                 }
2795                 else
2796                 {
2797                         _Util::Rectangle<int> clip = { this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height };
2798
2799                         if (x2 > x1 && y2 > y1)
2800                         {
2801                                 _Util::Rectangle<int> rect1 = { x1, y1, x2 - x1, 1 };
2802                                 _Util::Rectangle<int> rect2 = { x2, y1, 1, y2 - y1 };
2803                                 _Util::Rectangle<int> rect3 = { x1 + 1, y2, x2 - x1, 1 };
2804                                 _Util::Rectangle<int> rect4 = { x1, y1 + 1, 1, y2 - y1 };
2805
2806                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect1, clip);
2807                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect2, clip);
2808                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect3, clip);
2809                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect4, clip);
2810                         }
2811                         else
2812                         {
2813                                 _Util::Rectangle<int> rect1 = { x1, y1, static_cast<int>(rectangle.w), static_cast<int>(rectangle.h) };
2814
2815                                 _FillRectangleWithClip(__pScratchPad, composedColor, rect1, clip);
2816                         }
2817                 }
2818
2819                 return E_SUCCESS;
2820         }
2821         else if (this->__lineWidth.asInteger > 1)
2822         {
2823                 _GpPoint tempPoints[4] =
2824                 {
2825                         { x1, y1 },
2826                         { x2, y1 },
2827                         { x2, y2 },
2828                         { x1, y2 }
2829                 };
2830
2831                 _CanvasLine line;
2832                 _GpBufferInfo info;
2833
2834                 memset(&info, 0, sizeof(info));
2835
2836                 SystemPixel* pBufferAddr = null;
2837                 int bufferPitch = 0;
2838
2839                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2840
2841                 info.width = __pScratchPad->GetWidth();
2842                 info.height = __pScratchPad->GetHeight();
2843                 info.bitsPerPixel = 32;
2844                 info.pixelPerLine = bufferPitch;
2845                 info.pPixels = (void*) pBufferAddr;
2846                 info.color32 = composedColor;
2847                 info.isClipBoundsSet = this->__isClipBoundsSet;
2848                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2849
2850                 line.SetLineWidth(this->__lineWidth.asInteger);
2851
2852                 result r = line.DrawPolygon(4, tempPoints, info);
2853
2854                 return r;
2855         }
2856
2857         // this->__lineWidth is always greater than 0
2858         return E_SUCCESS;
2859 }
2860
2861 result
2862 _Canvas::DrawRoundRectangle(const _Util::Rectangle<int>& rect, const _Util::Dimension<int>& arcDim)
2863 {
2864         _Util::Rectangle<double> doubleRect =
2865         {
2866                 double(rect.x),
2867                 double(rect.y),
2868                 double(rect.w),
2869                 double(rect.h)
2870         };
2871
2872         _Util::Dimension<double> doubleArcDim =
2873         {
2874                 double(rect.w),
2875                 double(rect.h)
2876         };
2877
2878         return this->DrawRoundRectangle(doubleRect, doubleArcDim);
2879 }
2880
2881 result
2882 _Canvas::DrawRoundRectangle(const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
2883 {
2884         if ((rect.w <= 0.0) || (rect.h <= 0))
2885         {
2886                 return E_SUCCESS;
2887         }
2888
2889         if ((int(arcDim.w) == 0) || (int(arcDim.h) == 0))
2890         {
2891                 return this->DrawRectangle(rect);
2892         }
2893
2894         _Util::Dimension<double> revisedArcDim =
2895         {
2896                 (arcDim.w <= rect.w / 2.0) ? arcDim.w : rect.w / 2.0,
2897                 (arcDim.h <= rect.h / 2.0) ? arcDim.h : rect.h / 2.0
2898         };
2899
2900         // this->__lineWidth is always greater than 0
2901
2902         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2903
2904         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2905
2906         if (pCairo && pCairo->pCairo)
2907         {
2908                 SET_CAIRO_ALL_PROPERTIES;
2909
2910                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2911                 {
2912                         _Cairo::DrawRoundRectangle(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, rect, revisedArcDim);
2913                 }
2914                 else
2915                 {
2916                         _Cairo::DrawRoundRectangle(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, rect, revisedArcDim);
2917                 }
2918
2919                 RESET_CAIRO_ALL_PROPERTIES;
2920
2921                 return E_SUCCESS;
2922         }
2923         else
2924         {
2925                 _CanvasRoundRect roundRect;
2926                 _GpBufferInfo info;
2927
2928                 memset(&info, 0, sizeof(info));
2929
2930                 SystemPixel* pBufferAddr = null;
2931                 int bufferPitch = 0;
2932
2933                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2934
2935                 info.width = __pScratchPad->GetWidth();
2936                 info.height = __pScratchPad->GetHeight();
2937                 info.bitsPerPixel = 32;
2938                 info.pixelPerLine = bufferPitch;
2939                 info.pPixels = (void*) pBufferAddr;
2940                 info.color32 = composedColor;
2941                 info.isClipBoundsSet = this->__isClipBoundsSet;
2942                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
2943
2944                 roundRect.SetLineWidth(this->__lineWidth.asInteger);
2945
2946                 return roundRect.DrawRoundRect(int(rect.x), int(rect.y), int(rect.w), int(rect.h), int(revisedArcDim.w), int(revisedArcDim.h), info);
2947         }
2948 }
2949
2950 result
2951 _Canvas::DrawTriangle(const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
2952 {
2953         // this->__lineWidth is always greater than 0
2954
2955         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
2956
2957         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
2958
2959         if (pCairo && pCairo->pCairo)
2960         {
2961                 _Util::Point<double> point[] =
2962                 {
2963                         { point1.x, point1.y },
2964                         { point2.x, point2.y },
2965                         { point3.x, point3.y }
2966                 };
2967
2968                 SET_CAIRO_ALL_PROPERTIES;
2969
2970                 if (__lineWidth.applied != _Util::ScalarHolder::AS_INTEGER)
2971                 {
2972                         _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asDouble, composedColor, point, 3);
2973                 }
2974                 else
2975                 {
2976                         _Cairo::DrawPolygon(pCairo->pCairo, this->__lineWidth.asInteger, composedColor, point, 3);
2977                 }
2978
2979                 RESET_CAIRO_ALL_PROPERTIES;
2980
2981                 return E_SUCCESS;
2982         }
2983         else
2984         {
2985                 _CanvasTriangle triangle;
2986                 _GpBufferInfo info;
2987
2988                 memset(&info, 0, sizeof(info));
2989
2990                 SystemPixel* pBufferAddr = null;
2991                 int bufferPitch = 0;
2992
2993                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
2994
2995                 info.width = __pScratchPad->GetWidth();
2996                 info.height = __pScratchPad->GetHeight();
2997                 info.bitsPerPixel = 32;
2998                 info.pixelPerLine = bufferPitch;
2999                 info.pPixels = (void*) pBufferAddr;
3000                 info.color32 = composedColor;
3001                 info.isClipBoundsSet = this->__isClipBoundsSet;
3002                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3003
3004                 triangle.SetLineWidth(this->__lineWidth.asInteger);
3005
3006                 _GpPoint p1 = { int(point1.x), int(point1.y) };
3007                 _GpPoint p2 = { int(point2.x), int(point2.y) };
3008                 _GpPoint p3 = { int(point3.x), int(point3.y) };
3009
3010                 return triangle.DrawTriangle(p1, p2, p3, info);
3011         }
3012 }
3013
3014 result
3015 _Canvas::FillTriangle(const Color& color, const _Util::Point<int>& point1, const _Util::Point<int>& point2, const _Util::Point<int>& point3)
3016 {
3017         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3018
3019         _Util::Point<double> doublePoint1 =
3020         {
3021                 double(point1.x),
3022                 double(point1.y)
3023         };
3024
3025         _Util::Point<double> doublePoint2 =
3026         {
3027                 double(point1.x),
3028                 double(point1.y)
3029         };
3030
3031         _Util::Point<double> doublePoint3 =
3032         {
3033                 double(point1.x),
3034                 double(point1.y)
3035         };
3036
3037         return this->__FillTriangle(composedColor, doublePoint1, doublePoint2, doublePoint3);
3038 }
3039
3040 result
3041 _Canvas::FillTriangle(const Color& color, const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
3042 {
3043         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3044
3045         return this->__FillTriangle(composedColor, point1, point2, point3);
3046 }
3047
3048 result
3049 _Canvas::__FillTriangle(unsigned long composedColor, const _Util::Point<double>& point1, const _Util::Point<double>& point2, const _Util::Point<double>& point3)
3050 {
3051         // this->__lineWidth is always greater than 0
3052
3053         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3054
3055         if (pCairo && pCairo->pCairo)
3056         {
3057                 _Util::Point<double> point[] =
3058                 {
3059                         { point1.x, point1.y },
3060                         { point2.x, point2.y },
3061                         { point3.x, point3.y }
3062                 };
3063
3064                 SET_CAIRO_FILL_PROPERTIES;
3065
3066                 _Cairo::FillPolygon(pCairo->pCairo, composedColor, point, 3);
3067
3068                 RESET_CAIRO_FILL_PROPERTIES;
3069
3070                 return E_SUCCESS;
3071         }
3072         else
3073         {
3074                 _CanvasTriangle triangle;
3075                 _GpBufferInfo info;
3076
3077                 memset(&info, 0, sizeof(info));
3078
3079                 SystemPixel* pBufferAddr = null;
3080                 int bufferPitch = 0;
3081
3082                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3083
3084                 info.width = __pScratchPad->GetWidth();
3085                 info.height = __pScratchPad->GetHeight();
3086                 info.bitsPerPixel = 32;
3087                 info.pixelPerLine = bufferPitch;
3088                 info.pPixels = (void*) pBufferAddr;
3089                 info.color32 = composedColor;
3090                 info.isClipBoundsSet = this->__isClipBoundsSet;
3091                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3092
3093                 triangle.SetLineWidth(this->__lineWidth.asInteger);
3094
3095                 return triangle.FillTriangle(int(point1.x), int(point1.y), int(point2.x), int(point2.y), int(point3.x), int(point3.y), info);
3096         }
3097 }
3098
3099 result
3100 _Canvas::__FillEllipse(unsigned long composedColor, const _Util::Rectangle<double>& bounds)
3101 {
3102         if ((bounds.w <= 0.0) || (bounds.h <= 0.0))
3103         {
3104                 return E_SUCCESS;
3105         }
3106
3107         // this->__lineWidth is always greater than 0
3108
3109         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3110
3111         if (pCairo && pCairo->pCairo)
3112         {
3113                 SET_CAIRO_FILL_PROPERTIES;
3114
3115                 _Cairo::FillEllipse(pCairo->pCairo, composedColor, bounds);
3116
3117                 RESET_CAIRO_FILL_PROPERTIES;
3118
3119                 return E_SUCCESS;
3120         }
3121         else
3122         {
3123                 _CanvasEllipse ellipse;
3124                 _GpBufferInfo info;
3125
3126                 memset(&info, 0, sizeof(info));
3127
3128                 SystemPixel* pBufferAddr = null;
3129                 int bufferPitch = 0;
3130
3131                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3132
3133                 info.width = __pScratchPad->GetWidth();
3134                 info.height = __pScratchPad->GetHeight();
3135                 info.bitsPerPixel = 32;
3136                 info.pixelPerLine = bufferPitch;
3137                 info.pPixels = (void*) pBufferAddr;
3138                 info.color32 = composedColor;
3139                 info.isClipBoundsSet = this->__isClipBoundsSet;
3140                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3141
3142                 ellipse.SetLineWidth(this->__lineWidth.asInteger);
3143
3144                 return ellipse.FillElliepse(int(bounds.x), int(bounds.y), int(bounds.w), int(bounds.h), info);
3145         }
3146 }
3147
3148 result
3149 _Canvas::FillEllipse(const Color& color, const _Util::Rectangle<int>& bounds)
3150 {
3151         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3152
3153         _Util::Rectangle<double> doubleBounds =
3154         {
3155                 double(bounds.x),
3156                 double(bounds.y),
3157                 double(bounds.w),
3158                 double(bounds.h)
3159         };
3160
3161         return this->__FillEllipse(composedColor, doubleBounds);
3162 }
3163
3164 result
3165 _Canvas::FillEllipse(const Color& color, const _Util::Rectangle<double>& bounds)
3166 {
3167         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3168
3169         return this->__FillEllipse(composedColor, bounds);
3170 }
3171
3172 result
3173 _Canvas::FillPolygon(const Color& color, const _Util::Point<double>* pPoints, unsigned int pointCount)
3174 {
3175         //
3176         // Implementation of this method in API versions prior to 2.0 has the following issue:
3177         //
3178         // -# If there are 4 input points and conditions below is satisfied, the drawing result does not match the expected behavior. @n
3179         //
3180         //   "point[0].x == point[3].x && point[1].x == point[2].x && point[0].y == point[1].y && point[2].y == point[3].y"
3181         //
3182         // there are 4 cases can be occurred.
3183         //
3184         // [case1] (p[0]->x > p[1]->x && p[0]->y > p[3]->y)
3185         //
3186         //              p2________p3
3187         //              |         |
3188         //              |         |
3189         //              |         |     <--- expected result
3190         //              |         |
3191         //              p1--------p0_________
3192         //                                 |         |
3193         //                                 |         |
3194         //                                 |         |   <--- wrong result
3195         //                                 |         |
3196         //                                  ---------
3197         //
3198         // [case2] (p[0]->x < p[1]->x && p[0]->y > p[3]->y)
3199         //
3200         //              p3________p2
3201         //              |         |
3202         //              |         |
3203         //              |         |   <--- expected result
3204         //              |         |
3205         //              p0--------p1
3206         //              |         |
3207         //              |         |
3208         //              |         |   <--- wrong result
3209         //              |         |
3210         //               ---------
3211         //
3212         // [case3] (p[0]->x < p[1]->x && p[0]->y < p[3]->y)
3213         //
3214         //              p0________p1
3215         //              |         |
3216         //              |         |
3217         //              |         |   <--- no problem.
3218         //              |         |
3219         //              p3--------p2
3220         //
3221         //
3222         // [case4] (p[0]->x > p[1]->x && p[0]->y < p[3]->y)
3223         //
3224         //              p1________p0________
3225         //              |         |         |
3226         //              |         |         |
3227         //              |         |         |    <--- wrong result
3228         //              |         |         |
3229         //              p2--------p3--------
3230         //                 ^
3231         //             |
3232         //              -- expected result
3233         //
3234         // The issue mentioned above is resolved in API version 2.0, So, check the SDK version and emulate problem before step forward furthermore.
3235         //
3236         // CR approved, no. EP-47D6817268074396919211307C39CA55
3237         //
3238
3239         // this->__lineWidth is always greater than 0
3240
3241         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3242
3243         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3244
3245         if (pCairo && pCairo->pCairo)
3246         {
3247                 SET_CAIRO_FILL_PROPERTIES;
3248
3249                 _Cairo::FillPolygon(pCairo->pCairo, composedColor, pPoints, pointCount);
3250
3251                 RESET_CAIRO_FILL_PROPERTIES;
3252
3253                 return E_SUCCESS;
3254         }
3255         else
3256         {
3257                 _CanvasFillPolygon polygon;
3258                 _GpBufferInfo info;
3259
3260                 memset(&info, 0, sizeof(info));
3261
3262                 SystemPixel* pBufferAddr = null;
3263                 int bufferPitch = 0;
3264
3265                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3266
3267                 info.width = __pScratchPad->GetWidth();
3268                 info.height = __pScratchPad->GetHeight();
3269                 info.bitsPerPixel = 32;
3270                 info.pixelPerLine = bufferPitch;
3271                 info.pPixels = (void*) pBufferAddr;
3272                 info.color32 = composedColor;
3273                 info.isClipBoundsSet = this->__isClipBoundsSet;
3274                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3275
3276                 polygon.SetLineWidth(this->__lineWidth.asInteger);
3277
3278                 std::unique_ptr<_GpPoint[]> tempPoints(new (std::nothrow) _GpPoint[pointCount]);
3279
3280                 _GpPoint* pTempPoints = tempPoints.get();
3281
3282                 if (pTempPoints == null)
3283                 {
3284                         return E_SYSTEM;
3285                 }
3286
3287                 for (unsigned int i = 0; i < pointCount; i++)
3288                 {
3289                         pTempPoints[i].x = int(pPoints[i].x);
3290                         pTempPoints[i].y = int(pPoints[i].y);
3291                 }
3292
3293                 result r = polygon.FillPolygon(int(pointCount), pTempPoints, info);
3294
3295                 return r;
3296         }
3297 }
3298
3299 result
3300 _Canvas::__FillRectangle(unsigned long composedColor, const _Util::Rectangle<double>& rectangle)
3301 {
3302         if ((rectangle.w <= 0.0) || (rectangle.h <= 0.0))
3303         {
3304                 return E_SUCCESS;
3305         }
3306
3307         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3308
3309         if (pCairo && pCairo->pCairo)
3310         {
3311                 SET_CAIRO_FILL_PROPERTIES;
3312
3313                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, rectangle);
3314
3315                 RESET_CAIRO_FILL_PROPERTIES;
3316
3317                 return E_SUCCESS;
3318         }
3319         else
3320         {
3321                 _Util::Rectangle<int> rect =
3322                 {
3323                         static_cast<int>(rectangle.x),
3324                         static_cast<int>(rectangle.y),
3325                         static_cast<int>(rectangle.w),
3326                         static_cast<int>(rectangle.h)
3327                 };
3328
3329                 if (this->__isClipBoundsSet)
3330                 {
3331                         int x1 = rect.x;
3332                         int y1 = rect.y;
3333                         int x2 = x1 + rect.w;
3334                         int y2 = y1 + rect.h;
3335
3336                         x1 = (x1 >= this->__clipBounds.x) ? x1 : this->__clipBounds.x;
3337                         y1 = (y1 >= this->__clipBounds.y) ? y1 : this->__clipBounds.y;
3338
3339                         x2 = (x2 <= this->__clipBounds.x + this->__clipBounds.width) ? x2 : this->__clipBounds.x + this->__clipBounds.width;
3340                         y2 = (y2 <= this->__clipBounds.y + this->__clipBounds.height) ? y2 : this->__clipBounds.y + this->__clipBounds.height;
3341
3342                         rect.x = x1;
3343                         rect.y = y1;
3344                         rect.w = x2 - x1;
3345                         rect.h = y2 - y1;
3346                 }
3347
3348                 if (rect.w > 0 && rect.h > 0)
3349                 {
3350                         // alpha-fill-rect() applied
3351                         __pScratchPad->RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
3352                         __pScratchPad->FillRect(rect.x, rect.y, rect.w, rect.h, composedColor);
3353                         __pScratchPad->RegisterFillRect(null);
3354                 }
3355         }
3356
3357         return E_SUCCESS;
3358 }
3359
3360 result
3361 _Canvas::FillRectangle(const Color& color, const Rectangle& rect)
3362 {
3363         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3364
3365         return this->__FillRectangle(composedColor, _Util::Convert<Rectangle, _Util::Rectangle<double> >(rect));
3366 }
3367
3368 result
3369 _Canvas::FillRectangle(const Color& color, const _Util::Rectangle<int>& rect)
3370 {
3371         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3372
3373         _Util::Rectangle<double> doubleRect =
3374         {
3375                 double(rect.x),
3376                 double(rect.y),
3377                 double(rect.w),
3378                 double(rect.h)
3379         };
3380
3381         return this->__FillRectangle(composedColor, doubleRect);
3382 }
3383
3384 result
3385 _Canvas::FillRectangle(const Color& color, const _Util::Rectangle<double>& rect)
3386 {
3387         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3388
3389         return this->__FillRectangle(composedColor, rect);
3390 }
3391
3392 result
3393 _Canvas::FillRoundRectangle(const Color& color, const _Util::Rectangle<int>& rect, const _Util::Dimension<int>& arcDim)
3394 {
3395         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3396
3397         _Util::Rectangle<double> doubleRect =
3398         {
3399                 double(rect.x),
3400                 double(rect.y),
3401                 double(rect.w),
3402                 double(rect.h)
3403         };
3404
3405         _Util::Dimension<double> doubleArcDim =
3406         {
3407                 double(rect.w),
3408                 double(rect.h)
3409         };
3410
3411         return this->__FillRoundRectangle(composedColor, doubleRect, doubleArcDim);
3412 }
3413
3414 result
3415 _Canvas::FillRoundRectangle(const Color& color, const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
3416 {
3417         unsigned long composedColor = _ComposeColor(color.GetRGB32(), this->__fgOpacity);
3418
3419         return this->__FillRoundRectangle(composedColor, rect, arcDim);
3420 }
3421
3422 result
3423 _Canvas::__FillRoundRectangle(unsigned long composedColor, const _Util::Rectangle<double>& rect, const _Util::Dimension<double>& arcDim)
3424 {
3425         if ((rect.w <= 0.0) || (rect.h <= 0.0))
3426         {
3427                 return E_SUCCESS;
3428         }
3429
3430         if ((int(arcDim.w) <= 0) || (int(arcDim.h) <= 0))
3431         {
3432                 return this->__FillRectangle(composedColor, rect);
3433         }
3434
3435         _Util::Dimension<double> revisedArcDim =
3436         {
3437                 (arcDim.w <= rect.w / 2.0) ? arcDim.w : rect.w / 2.0,
3438                 (arcDim.h <= rect.h / 2.0) ? arcDim.h : rect.h / 2.0
3439         };
3440
3441         // this->__lineWidth is always greater than 0
3442
3443         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3444
3445         if (pCairo && pCairo->pCairo)
3446         {
3447                 SET_CAIRO_FILL_PROPERTIES;
3448
3449                 _Cairo::FillRoundRectangle(pCairo->pCairo, composedColor, rect, revisedArcDim);
3450
3451                 RESET_CAIRO_FILL_PROPERTIES;
3452
3453                 return E_SUCCESS;
3454         }
3455         else
3456         {
3457                 _CanvasRoundRect roundRect;
3458                 _GpBufferInfo info;
3459
3460                 memset(&info, 0, sizeof(info));
3461
3462                 SystemPixel* pBufferAddr = null;
3463                 int bufferPitch = 0;
3464
3465                 __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3466
3467                 info.width = __pScratchPad->GetWidth();
3468                 info.height = __pScratchPad->GetHeight();
3469                 info.bitsPerPixel = 32;
3470                 info.pixelPerLine = bufferPitch;
3471                 info.pPixels = (void*) pBufferAddr;
3472                 info.color32 = composedColor;
3473                 info.isClipBoundsSet = this->__isClipBoundsSet;
3474                 info.clipBounds.SetBounds(this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height);
3475
3476                 roundRect.SetLineWidth(this->__lineWidth.asInteger);
3477
3478                 return roundRect.FillRoundRectangle(int(rect.x), int(rect.y), int(rect.w), int(rect.h), int(revisedArcDim.w), int(revisedArcDim.h), info);
3479         }
3480 }
3481
3482 result
3483 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text)
3484 {
3485         return _Font::DrawText(*this, point, text, 0, text.GetLength());
3486 }
3487
3488 result
3489 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text, int startIndex, int length)
3490 {
3491         return _Font::DrawText(*this, point, text, startIndex, length);
3492 }
3493
3494 result
3495 _Canvas::DrawText(const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
3496 {
3497         return _Font::DrawText(*this, point, text, startIndex, length, outlineColor);
3498 }
3499
3500 Rectangle
3501 _Canvas::GetBounds(void) const
3502 {
3503         Rectangle rect(this->__xBufferPos, this->__yBufferPos, __pScratchPad->GetWidth(), __pScratchPad->GetHeight());
3504
3505         if (this->__windowHandle != INVALID_HANDLE)
3506         {
3507                 rect.x = 0;
3508                 rect.y = 0;
3509         }
3510
3511         return rect;
3512 }
3513
3514 LineStyle
3515 _Canvas::GetLineStyle() const
3516 {
3517         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_STYLE_MAX, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3518
3519         return this->__lineStyle;
3520 }
3521
3522 int
3523 _Canvas::GetLineWidth() const
3524 {
3525         SysTryReturn(NID_GRP, this && this->__pSurface, -1, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3526
3527         return this->__lineWidth.asInteger;
3528 }
3529
3530 LineCapStyle
3531 _Canvas::GetLineCapStyle() const
3532 {
3533         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_CAP_STYLE_ROUND, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3534
3535         return this->__lineCapStyle;
3536 }
3537
3538 LineJoinStyle
3539 _Canvas::GetLineJoinStyle() const
3540 {
3541         SysTryReturn(NID_GRP, this && this->__pSurface, LINE_JOIN_STYLE_ROUND, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3542
3543         return this->__lineJoinStyle;
3544 }
3545
3546 result
3547 _Canvas::SetLineStyle(LineStyle style)
3548 {
3549         this->__lineStyle = style;
3550
3551         return E_SUCCESS;
3552 }
3553
3554 result
3555 _Canvas::SetLineWidth(int width, float widthAsFloat)
3556 {
3557         SysTryReturnResult(NID_GRP, width > 0 || widthAsFloat >= 0.0f, E_OUT_OF_RANGE, "The given line width(%d) is out of range.\n", width);
3558
3559         this->__lineWidth = width;
3560         this->__lineWidth.asDouble = double(widthAsFloat);
3561
3562         return E_SUCCESS;
3563 }
3564
3565 result
3566 _Canvas::SetLineWidth(float width)
3567 {
3568         SysTryReturnResult(NID_GRP, width > 0.0f, E_OUT_OF_RANGE, "The given line width(%f) is out of range.\n", width);
3569
3570         this->__lineWidth = width;
3571
3572         return E_SUCCESS;
3573 }
3574
3575 result
3576 _Canvas::SetLineCapStyle(LineCapStyle lineCapStyle)
3577 {
3578         this->__lineCapStyle = lineCapStyle;
3579
3580         return E_SUCCESS;
3581 }
3582
3583 result
3584 _Canvas::SetLineJoinStyle(LineJoinStyle lineJoinStyle)
3585 {
3586         this->__lineJoinStyle = lineJoinStyle;
3587
3588         return E_SUCCESS;
3589 }
3590
3591 result
3592 _Canvas::SetDashPattern(const Tizen::Graphics::_Util::AccumList<double>& dashValueList, double offset)
3593 {
3594         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3595
3596         {
3597                 Tizen::Graphics::_Util::AccumList<double> listSwap;
3598                 this->__dashData.pattern.Swap(listSwap);
3599
3600                 this->__dashData.offset = 0.0;
3601         }
3602
3603         {
3604                 Tizen::Graphics::_Util::AccumList<double>::ConstIterator dashIterator = dashValueList.Begin();
3605
3606                 for (; dashIterator != dashValueList.End(); dashIterator++)
3607                 {
3608                         this->__dashData.pattern.Push(*dashIterator);
3609                 }
3610
3611                 this->__dashData.offset = offset;
3612         }
3613
3614         return E_SUCCESS;
3615 }
3616
3617 void
3618 _Canvas::SetDrawingQuality(BitmapDrawingQuality quality)
3619 {
3620         // 'quality' is verified in _CanvasImpl::SetDrawingQuality()
3621         this->__bitmapDrawingQuality = quality;
3622 }
3623
3624 BitmapDrawingQuality
3625 _Canvas::GetDrawingQuality(void) const
3626 {
3627         return this->__bitmapDrawingQuality;
3628 }
3629
3630 void
3631 _Canvas::SetCompositeMode(CompositeMode compositeMode)
3632 {
3633         // 'blendingMode' is verified in _CanvasImpl::SetBlendingMode()
3634         this->__compositeMode = compositeMode;
3635 }
3636
3637 CompositeMode
3638 _Canvas::GetCompositeMode(void) const
3639 {
3640         return this->__compositeMode;
3641 }
3642
3643 result
3644 _Canvas::GetPixel(const Point& point, Color& color) const
3645 {
3646         Point pos(point.x, point.y);
3647
3648         // [ykahn 2011.06.27] revise the value of 'point' if it goes out-of-range
3649         {
3650                 Rectangle rtCanvas = _GetBoundsRel(*this);
3651
3652                 SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_OUT_OF_RANGE, "Cannot get the bounds of the canvas.\n");
3653
3654                 if (pos.x >= rtCanvas.width && rtCanvas.width >= 1)
3655                 {
3656                         pos.x = rtCanvas.width - 1;
3657                 }
3658
3659                 if (pos.y >= rtCanvas.height && rtCanvas.height >= 1)
3660                 {
3661                         pos.y = rtCanvas.height - 1;
3662                 }
3663         }
3664
3665         {
3666                 result r = E_OUT_OF_RANGE;
3667
3668                 Rectangle rect = this->GetBounds();
3669
3670                 rect.x = 0;
3671                 rect.y = 0;
3672
3673                 if ((point.x >= rect.x && point.x < rect.x + rect.width) && (point.y >= rect.y && point.y < rect.y + rect.height))
3674                 {
3675                         BufferInfo info;
3676
3677                         (const_cast<_Canvas*>(this))->Lock(info);
3678
3679                         if (info.bitsPerPixel == 32)
3680                         {
3681                                 unsigned long* pDest32 = (unsigned long*) info.pPixels;
3682                                 long pitch = info.pitch / 4;
3683
3684                                 color.SetRGB32(pDest32[pitch * point.y + point.x], true);
3685
3686                                 r = E_SUCCESS;
3687                         }
3688                         else if (info.bitsPerPixel == 16)
3689                         {
3690                                 unsigned short* pDest16 = (unsigned short*) info.pPixels;
3691                                 long pitch = info.pitch / 2;
3692
3693                                 unsigned short color16 = pDest16[pitch * point.y + point.x];
3694
3695                                 unsigned long r = (color16 & 0xF800) >> 8;
3696                                 unsigned long g = (color16 & 0x07E0) >> 3;
3697                                 unsigned long b = (color16 & 0x001F) << 3;
3698
3699                                 r += (r >> 5);
3700                                 g += (g >> 6);
3701                                 b += (b >> 5);
3702
3703                                 unsigned long color32 = 0xFF000000 | (r << 16) | (g << 8) | (b);
3704
3705                                 color.SetRGB32(color32, true);
3706
3707                                 r = E_SUCCESS;
3708                         }
3709
3710                         (const_cast<_Canvas*>(this))->Unlock();
3711                 }
3712
3713                 return r;
3714         }
3715 }
3716
3717 result
3718 _Canvas::SetPixel(const _Util::Point<int>& point)
3719 {
3720         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
3721
3722         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3723
3724         if (pCairo && pCairo->pCairo)
3725         {
3726                  _Util::Rectangle<double> rectangle = {double(point.x), double(point.y), 1.0, 1.0};
3727
3728                 SET_CAIRO_FILL_PROPERTIES;
3729
3730                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, rectangle);
3731
3732                 RESET_CAIRO_FILL_PROPERTIES;
3733
3734                 return E_SUCCESS;
3735         }
3736
3737         if (!this->__isClipBoundsSet)
3738         {
3739                 __pScratchPad->FillRect(point.x, point.y, 1, 1, composedColor);
3740         }
3741         else
3742         {
3743                 _Util::Rectangle<int> rect = { point.x, point.y, 1, 1 };
3744                 _Util::Rectangle<int> clip = { this->__clipBounds.x, this->__clipBounds.y, this->__clipBounds.width, this->__clipBounds.height };
3745
3746                 _FillRectangleWithClip(__pScratchPad, composedColor, rect, clip);
3747         }
3748
3749         return E_SUCCESS;
3750 }
3751
3752 result
3753 _Canvas::SetPixel(const _Util::Point<double>& point)
3754 {
3755         _Util::Rectangle<double> doubleRect =
3756         {
3757                 point.x,
3758                 point.y,
3759                 1.0,
3760                 1.0
3761         };
3762
3763         unsigned long composedColor = _ComposeColor(this->__fgColor, this->__fgOpacity);
3764
3765         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
3766
3767         if (pCairo && pCairo->pCairo)
3768         {
3769                 SET_CAIRO_FILL_PROPERTIES;
3770
3771                 _Cairo::FillRectangle(pCairo->pCairo, composedColor, doubleRect);
3772
3773                 RESET_CAIRO_FILL_PROPERTIES;
3774
3775                 return E_SUCCESS;
3776         }
3777
3778         this->__FillRectangle(composedColor, doubleRect);
3779
3780         return E_SUCCESS;
3781 }
3782
3783 result
3784 _Canvas::Show()
3785 {
3786         int bufferWidth = __pSurface->GetWidth();
3787         int bufferHeight = __pSurface->GetHeight();
3788         int bufferPpl = __pSurface->GetPitch();
3789
3790         // cannot use 'if (__pSurface->GetHandle())'
3791         if (this->__windowHandle != INVALID_HANDLE)
3792         {
3793 #if 0
3794                 evas_object_image_pixels_dirty_set((Evas_Object*) this->__windowHandle, true);
3795 #else
3796                 Evas_Object* pSourceObject = _GetWindowSourceObject(this->__windowHandle);
3797                 evas_object_image_data_set(pSourceObject, evas_object_image_data_get(pSourceObject, EINA_TRUE));
3798                 evas_object_image_data_update_add(pSourceObject, 0, 0, bufferWidth, bufferHeight);
3799 #endif
3800
3801                 evas_object_show((Evas_Object*) this->__windowHandle);
3802
3803                 _FlushCanvas();
3804         }
3805         else
3806         {
3807                 SysTryReturnResult(NID_GRP, Tizen::App::_AppInfo::IsOspCompat(), E_UNSUPPORTED_OPERATION, "This method is unsupported in Tizen.");
3808
3809                 _CanvasShowFromMemory(this->__xBufferPos, this->__yBufferPos, 0, 0, bufferWidth, bufferHeight, __pBuffer, bufferWidth, bufferHeight, 32, bufferPpl * 4);
3810         }
3811
3812         return E_SUCCESS;
3813 }
3814
3815 result
3816 _Canvas::Show(const Rectangle& rect)
3817 {
3818         if ((rect.width == 0) || (rect.height == 0))
3819         {
3820                 return E_SUCCESS;
3821         }
3822
3823         if (this->__windowHandle != INVALID_HANDLE)
3824         {
3825                 int x1 = rect.x;
3826                 int x2 = rect.x + rect.width;
3827                 int y1 = rect.y;
3828                 int y2 = rect.y + rect.height;
3829
3830                 if (x1 + 1 < x2)
3831                 {
3832                         x1++;
3833                 }
3834
3835                 if (x2 - 1 > x1)
3836                 {
3837                         x2--;
3838                 }
3839
3840                 if (y1 + 1 < y2)
3841                 {
3842                         y1++;
3843                 }
3844
3845                 if (y2 - 1 > y1)
3846                 {
3847                         y2--;
3848                 }
3849
3850 #if 0
3851                 evas_object_image_pixels_dirty_set((Evas_Object*) this->__windowHandle, true);
3852                 // 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)
3853                 evas_object_image_data_update_add((Evas_Object*) this->__windowHandle, x1, y1, x2 - x1, y2 - y1);
3854 #else
3855                 Evas_Object* pSourceObject = _GetWindowSourceObject(this->__windowHandle);
3856                 evas_object_image_data_set(pSourceObject, evas_object_image_data_get(pSourceObject, EINA_TRUE));
3857                 evas_object_image_data_update_add(pSourceObject, x1, y1, x2 - x1, y2 - y1);
3858 #endif
3859
3860                 evas_object_show((Evas_Object*) this->__windowHandle);
3861
3862                 _FlushCanvas();
3863         }
3864         else
3865         {
3866                 SysTryReturnResult(NID_GRP, Tizen::App::_AppInfo::IsOspCompat(), E_UNSUPPORTED_OPERATION, "This method is unsupported in Tizen.");
3867
3868                 int bufferWidth = __pSurface->GetWidth();
3869                 int bufferHeight = __pSurface->GetHeight();
3870                 int bufferPpl = __pSurface->GetPitch();
3871
3872                 _CanvasShowFromMemory(this->__xBufferPos + rect.x, this->__yBufferPos + rect.y, rect.x, rect.y, rect.width, rect.height, __pBuffer, bufferWidth, bufferHeight, 32, bufferPpl * 4);
3873         }
3874
3875         return E_SUCCESS;
3876 }
3877
3878 result
3879 _Canvas::SetFont(const _Font& font)
3880 {
3881         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.");
3882
3883         // weak reference
3884         this->__pFont = const_cast<_Font*>(&font);
3885
3886         return E_SUCCESS;
3887 }
3888
3889 result
3890 _Canvas::SetPriorityFont(const _Font& font)
3891 {
3892         SysTryReturn(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.");
3893
3894         // weak reference
3895         this->__pPriorityFont = const_cast<_Font*>(&font);
3896
3897         return E_SUCCESS;
3898 }
3899
3900 void
3901 _Canvas::ResetPriorityFont(void)
3902 {
3903         // nullify weak reference
3904         this->__pPriorityFont = null;
3905 }
3906
3907 result
3908 _Canvas::SetClipBounds(const Rectangle& rect)
3909 {
3910         if (__pScratchPad == null)
3911         {
3912                 return E_SYSTEM;
3913         }
3914
3915         int x1 = rect.x;
3916         int y1 = rect.y;
3917         int x2 = x1 + rect.width;
3918         int y2 = y1 + rect.height;
3919
3920         x1 = (x1 > 0) ? x1 : 0;
3921         y1 = (y1 > 0) ? y1 : 0;
3922         x2 = (x2 < __pScratchPad->GetWidth()) ? x2 : __pScratchPad->GetWidth();
3923         y2 = (y2 < __pScratchPad->GetHeight()) ? y2 : __pScratchPad->GetHeight();
3924
3925         x2 = (x1 > x2) ? x1 : x2;
3926         y2 = (y1 > y2) ? y1 : y2;
3927
3928         if (x1 == 0 && y1 == 0 && x2 == __pScratchPad->GetWidth() && y2 == __pScratchPad->GetHeight())
3929         {
3930                 this->__isClipBoundsSet = false;
3931         }
3932         else
3933         {
3934                 this->__isClipBoundsSet = true;
3935         }
3936
3937         this->__clipBounds.SetBounds(x1, y1, x2 - x1, y2 - y1);
3938
3939         return E_SUCCESS;
3940 }
3941
3942 Rectangle
3943 _Canvas::GetClipBounds(void) const
3944 {
3945         Rectangle rect;
3946
3947         SysTryReturn(NID_GRP, this && this->__pSurface, rect, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
3948
3949         this->__GetClipBounds(rect);
3950
3951         return rect;
3952 }
3953
3954 result
3955 _Canvas::Lock(BufferInfo& info, long timeout)
3956 {
3957         if (__pScratchPad == null)
3958         {
3959                 return E_SYSTEM;
3960         }
3961
3962         if (_BufferInfoImpl::GetInstance(info) != null)
3963         {
3964                 _BufferInfoImpl::GetInstance(info)->SetHandle(_BufferInfoImpl::HANDLE_TYPE_NONE, 0);
3965         }
3966
3967         SystemPixel* pBufferAddr = null;
3968         int bufferPitch = 0;
3969
3970         __pScratchPad->GetBuffer(pBufferAddr, bufferPitch);
3971
3972         info.width = __pScratchPad->GetWidth();
3973         info.height = __pScratchPad->GetHeight();
3974         info.pitch = bufferPitch * sizeof(_SystemPixel);
3975         info.bitsPerPixel = sizeof(_SystemPixel) * 8;
3976         info.pixelFormat = PIXEL_FORMAT_ARGB8888;
3977         info.pPixels = (void*) pBufferAddr;
3978         //info.__handle   = INVALID_HANDLE;
3979
3980         return E_SUCCESS;
3981 }
3982
3983 result
3984 _Canvas::Unlock()
3985 {
3986         return E_SUCCESS;
3987 }
3988
3989 void
3990 _Canvas::SetForegroundColor(const Color& fgColor)
3991 {
3992         this->__fgColorNative = fgColor;
3993         this->__ComposeFgColor();
3994 }
3995
3996 Color
3997 _Canvas::GetForegroundColor(void)
3998 {
3999         return Color(this->__fgColor);
4000 }
4001
4002 void
4003 _Canvas::SetBackgroundColor(const Color& bgColor)
4004 {
4005         this->__bgColorNative = bgColor;
4006         this->__ComposeBgColor();
4007 }
4008
4009 Color
4010 _Canvas::GetBackgroundColor(void)
4011 {
4012         return Color(this->__bgColor);
4013 }
4014
4015 void
4016 _Canvas::SetForegroundOpacity(int level)
4017 {
4018         SysTryReturnVoidResult(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4019
4020         if (level < 0)
4021         {
4022                 level = 0;
4023         }
4024
4025         if (level > 255)
4026         {
4027                 level = 255;
4028         }
4029
4030         this->__fgOpacity = level;
4031         this->__ComposeFgColor();
4032 }
4033
4034 int
4035 _Canvas::GetForegroundOpacity(void)
4036 {
4037         SysTryReturn(NID_GRP, this && this->__pSurface, 255, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4038
4039         return this->__fgOpacity;
4040 }
4041
4042 void
4043 _Canvas::SetBackgroundOpacity(int level)
4044 {
4045         SysTryReturnVoidResult(NID_GRP, this && this->__pSurface, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4046
4047         if (level < 0)
4048         {
4049                 level = 0;
4050         }
4051
4052         if (level > 255)
4053         {
4054                 level = 255;
4055         }
4056
4057         this->__bgOpacity = level;
4058         this->__ComposeBgColor();
4059 }
4060
4061 int
4062 _Canvas::GetBackgroundOpacity(void)
4063 {
4064         SysTryReturn(NID_GRP, this && this->__pSurface, 255, E_OPERATION_FAILED, "[E_OPERATION_FAILED] This instance is not constructed yet.\n");
4065
4066         return this->__bgOpacity;
4067 }
4068
4069 result
4070 _Canvas::SetPosition(int x, int y)
4071 {
4072         SysTryReturnResult(NID_GRP, this->__windowHandle == INVALID_HANDLE, E_UNSUPPORTED_OPERATION, "Window canvas does not support moving the position.\n");
4073
4074         __xBufferPos = x;
4075         __yBufferPos = y;
4076
4077         return E_SUCCESS;
4078 }
4079
4080 void
4081 _Canvas::SetAntialiasingEnabled(bool enable)
4082 {
4083         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
4084
4085         if (pCairo && pCairo->pCairo)
4086         {
4087                 if (enable)
4088                 {
4089                         cairo_set_antialias(pCairo->pCairo, CAIRO_ANTIALIAS_DEFAULT);
4090                 }
4091                 else
4092                 {
4093                         cairo_set_antialias(pCairo->pCairo, CAIRO_ANTIALIAS_NONE);
4094                 }
4095         }
4096 }
4097
4098 bool
4099 _Canvas::IsAntialiasingEnabled(void) const
4100 {
4101         _NativeGfxEngine* pCairo = static_cast<_NativeGfxEngine*>(_pNativeGfxEngine);
4102
4103         if (pCairo && pCairo->pCairo)
4104         {
4105                 return (cairo_get_antialias(pCairo->pCairo) == CAIRO_ANTIALIAS_DEFAULT);
4106         }
4107
4108         return false;
4109 }
4110
4111 _Canvas*
4112 _Canvas::GetInstance(_CanvasImpl& canvas)
4113 {
4114         return (&canvas != null) ? canvas._pNativeCanvas : null;
4115 }
4116
4117 const _Canvas*
4118 _Canvas::GetInstance(const _CanvasImpl& canvas)
4119 {
4120         return (&canvas != null) ? canvas._pNativeCanvas : null;
4121 }
4122
4123 bool
4124 _Canvas::_IsWindowCanvas(void) const
4125 {
4126         if (!(this && this->__pSurface))
4127         {
4128                 return false;
4129         }
4130
4131         return (this->__windowHandle != INVALID_HANDLE);
4132 }
4133
4134 result
4135 _Canvas::_SetPosition(int x, int y)
4136 {
4137         if (!(this && this->__pSurface))
4138         {
4139                 return E_OPERATION_FAILED;
4140         }
4141
4142         if (this->__windowHandle != INVALID_HANDLE)
4143         {
4144                 return E_UNSUPPORTED_OPERATION;
4145         }
4146
4147         //?? what is this function ?
4148         __xBufferPos = x;
4149         __yBufferPos = y;
4150
4151         return E_SUCCESS;
4152 }
4153
4154 int
4155 _Canvas::_GetAlphaAttenuation(const _Bitmap& bitmap) const
4156 {
4157         // 'bitmap' and 'this' are always valid.
4158
4159         int alphaConstant = bitmap.GetAlphaConstant();
4160
4161         alphaConstant = (alphaConstant > 255) ? 255 : alphaConstant;
4162         alphaConstant = (alphaConstant < 0) ? 0 : alphaConstant;
4163
4164         int fgOpacity = this->__fgOpacity;
4165
4166         if (fgOpacity > 0 && fgOpacity < 255)
4167         {
4168                 fgOpacity += (fgOpacity >> 7);
4169                 alphaConstant = (alphaConstant * fgOpacity) >> 8;
4170         }
4171
4172         return alphaConstant;
4173 }
4174
4175 void
4176 _Canvas::_SetBlendOption(_Canvas::BlendOption blendOption)
4177 {
4178         if (!(this && this->__pSurface))
4179         {
4180                 return;
4181         }
4182
4183         if (blendOption < BLEND_MIN || blendOption >= BLEND_MAX)
4184         {
4185                 return;
4186         }
4187
4188         this->__blendOption = blendOption;
4189 }
4190
4191 _Canvas::BlendOption
4192 _Canvas::_GetBlendOption(void) const
4193 {
4194         if (!(this && this->__pSurface))
4195         {
4196                 // default
4197                 return BLEND_ALPHABLEND;
4198         }
4199
4200         return this->__blendOption;
4201 }
4202
4203 void
4204 _Canvas::__InitFgBgColorFromTheme(void)
4205 {
4206         __fgColorNative = (_GetDefaultForegroundColor) ? _GetDefaultForegroundColor() : Color(0xFF000000);
4207         __bgColorNative = (_GetDefaultBackgroundColor) ? _GetDefaultBackgroundColor() : Color(0xFFFFFFFF);
4208
4209         this->__ComposeFgColor();
4210         this->__ComposeBgColor();
4211 }
4212
4213 void
4214 _Canvas::__ComposeFgColor(void)
4215 {
4216         this->__fgColor = _ComposeColor(this->__fgColorNative.GetRGB32(), this->__fgOpacity);
4217 }
4218
4219 void
4220 _Canvas::__ComposeBgColor(void)
4221 {
4222         this->__bgColor = _ComposeColor(this->__bgColorNative.GetRGB32(), this->__bgOpacity);
4223 }
4224
4225 void
4226 _Canvas::__GetClipBounds(Rectangle& rect) const
4227 {
4228         if (this->__isClipBoundsSet)
4229         {
4230                 rect = this->__clipBounds;
4231         }
4232         else
4233         {
4234                 rect = Rectangle(0, 0, __pScratchPad->GetWidth(), __pScratchPad->GetHeight());
4235         }
4236 }
4237
4238 result
4239 _Canvas::__Copy(const Point& destPoint, const _Canvas& srcCanvas, const Rectangle& srcRect)
4240 {
4241         const _Canvas* pSrcCanvas = &srcCanvas;
4242
4243         Rectangle clippedSrcRect(srcRect);
4244
4245         if (_ClipRectangle(clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height, 0, 0, pSrcCanvas->__pScratchPad->GetWidth(), pSrcCanvas->__pScratchPad->GetHeight()) == CLIP_REJECT)
4246         {
4247                 return E_SUCCESS;
4248         }
4249
4250         __pScratchPad->BitBlt(destPoint.x, destPoint.y, pSrcCanvas->__pScratchPad, clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height);
4251
4252         return E_SUCCESS;
4253 }
4254
4255 result
4256 _Canvas::__Copy(const Rectangle& destRect, const _Canvas& srcCanvas, const Rectangle& srcRect)
4257 {
4258         const _Canvas* pSrcCanvas = &srcCanvas;
4259
4260         Rectangle clippedSrcRect(srcRect);
4261
4262         if (_ClipRectangle(clippedSrcRect.x, clippedSrcRect.y, clippedSrcRect.width, clippedSrcRect.height, 0, 0, pSrcCanvas->__pScratchPad->GetWidth(), pSrcCanvas->__pScratchPad->GetHeight()) == CLIP_REJECT)
4263         {
4264                 return E_SUCCESS;
4265         }
4266
4267         {
4268                 SystemPixel* pSrcAddr = null;
4269                 int srcPitch = 0;
4270
4271                 pSrcCanvas->__pScratchPad->GetBuffer(pSrcAddr, srcPitch);
4272                 pSrcAddr += srcPitch * clippedSrcRect.y + clippedSrcRect.x;
4273
4274                 SystemPixel* pDstAddr = null;
4275                 int dstPitch = 0;
4276
4277                 __pScratchPad->GetBuffer(pDstAddr, dstPitch);
4278
4279                 _Util::Pixmap srcImageEx(clippedSrcRect.width, clippedSrcRect.height, sizeof(SystemPixel) * 8, pSrcAddr, srcPitch * sizeof(SystemPixel));
4280                 _Util::Pixmap dstImageEx(__pScratchPad->GetWidth(), __pScratchPad->GetHeight(), sizeof(SystemPixel) * 8, pDstAddr, dstPitch * sizeof(SystemPixel));
4281
4282                 Tizen::Graphics::_Effect::ScaleImage(dstImageEx, destRect.x, destRect.y, destRect.width, destRect.height, srcImageEx);
4283         }
4284
4285         return E_SUCCESS;
4286 }
4287
4288 bool
4289 _Canvas::__IsInClipBounds(const _Util::Rectangle<double>& bounds)
4290 {
4291         int x1 = 0;
4292         int y1 = 0;
4293         int x2 = x1 + this->GetBounds().width;
4294         int y2 = y1 + this->GetBounds().height;
4295
4296         if (this->__isClipBoundsSet)
4297         {
4298                 x1 = (this->__clipBounds.x > x1) ? this->__clipBounds.x : x1;
4299                 y1 = (this->__clipBounds.y > y1) ? this->__clipBounds.y : y1;
4300                 x2 = (this->__clipBounds.x + this->__clipBounds.width < x2) ? this->__clipBounds.x + this->__clipBounds.width : x2;
4301                 y2 = (this->__clipBounds.y + this->__clipBounds.height < y2) ? this->__clipBounds.y + this->__clipBounds.height : y2;
4302         }
4303
4304         return ((bounds.x >= x1) && (bounds.y >= y1) && (bounds.x + bounds.w <= x2) && (bounds.y + bounds.h <= y2));
4305 }
4306
4307 }} // Tizen::Graphics
4308