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