Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / FGrp_CanvasGpArc.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_CanvasGpArc.cpp
20  * @brief       This is the implementation file for _CanvasArc class.
21  *
22  */
23
24 #include <new>
25 #include <cstring>
26 #include <cmath>
27
28 #include <FBaseSysLog.h>
29 #include "FGrp_CanvasGpPrimitive.h"
30
31
32 using namespace Tizen::Base;
33 using namespace Tizen::Graphics;
34
35 namespace // unnamed
36 {
37
38 const int _ARC_DELTA_SOLID_LINE = 4;
39 const int _ARC_DELTA_DOT_LINE = 1;
40 const int _MAX_ARC_OUTLINE_POINTS = 20000;
41 const int _MAX_STACK_COUNT = 200;
42
43 const float _SINE_TABLE[] = // 91 items
44 {
45         (float) 0.000000, (float) 0.017452, (float) 0.034899, (float) 0.052336, (float) 0.069756,
46         (float) 0.087156, (float) 0.104528, (float) 0.121869, (float) 0.139173, (float) 0.156434,
47         (float) 0.173648, (float) 0.190809, (float) 0.207912, (float) 0.224951, (float) 0.241922,
48         (float) 0.258819, (float) 0.275637, (float) 0.292372, (float) 0.309017, (float) 0.325568,
49         (float) 0.342020, (float) 0.358368, (float) 0.374607, (float) 0.390731, (float) 0.406737,
50         (float) 0.422618, (float) 0.438371, (float) 0.453990, (float) 0.469471, (float) 0.484810,
51         (float) 0.500000, (float) 0.515038, (float) 0.529919, (float) 0.544639, (float) 0.559193,
52         (float) 0.573576, (float) 0.587785, (float) 0.601815, (float) 0.615661, (float) 0.629320,
53         (float) 0.642788, (float) 0.656059, (float) 0.669131, (float) 0.681998, (float) 0.694658,
54         (float) 0.707107, (float) 0.719340, (float) 0.731354, (float) 0.743145, (float) 0.754709,
55         (float) 0.766044, (float) 0.777146, (float) 0.788011, (float) 0.798635, (float) 0.809017,
56         (float) 0.819152, (float) 0.829037, (float) 0.838670, (float) 0.848048, (float) 0.857167,
57         (float) 0.866025, (float) 0.874620, (float) 0.882948, (float) 0.891006, (float) 0.898794,
58         (float) 0.906308, (float) 0.913545, (float) 0.920505, (float) 0.927184, (float) 0.933580,
59         (float) 0.939693, (float) 0.945518, (float) 0.951056, (float) 0.956305, (float) 0.961262,
60         (float) 0.965926, (float) 0.970296, (float) 0.974370, (float) 0.978148, (float) 0.981627,
61         (float) 0.984808, (float) 0.987688, (float) 0.990268, (float) 0.992546, (float) 0.994522,
62         (float) 0.996195, (float) 0.997564, (float) 0.998630, (float) 0.999391, (float) 0.999848,
63         (float) 1.000000
64 };
65
66 }
67
68 namespace Tizen { namespace Graphics
69 {
70
71 bool
72 _CanvasArc::SetLineWidth(int lineWidth)
73 {
74         __lineWidth = lineWidth;
75
76         return true;
77 }
78
79 int
80 _CanvasArc::GetLineWidth(void) const
81 {
82         return __lineWidth;
83 }
84
85 result
86 _CanvasArc::DrawArc(int rectX, int rectY, int rectW, int rectH, int startAngle, int endAngle, ArcStyle arcType, const _GpBufferInfo& bufInfo)
87 {
88         int x;
89         int y;
90         int x1;
91         int y1;
92         int theta;
93         int centerX;
94         int centerY;
95         int radiusX;
96         int radiusY;
97         int halfLineW;
98         int preX = -1000;
99         int preY = -1000;
100
101         bool isEllipse = false;
102         bool isClipped = true;
103
104         _GpPoint* pPoints = null;
105
106         int pixelCount;
107
108         _CanvasEllipse ellipse;
109         _CanvasLine line;
110
111         if (rectW < 1 || rectH < 1)
112         {
113                 return E_SUCCESS;
114         }
115
116         if (startAngle < 0 || endAngle < 0)
117         {
118                 return E_SYSTEM;
119         }
120
121         if (arcType < ARC_STYLE_ONLY || arcType > ARC_STYLE_FILLED_CHORD)
122         {
123                 return E_SYSTEM;
124         }
125
126         ellipse.SetLineWidth(__lineWidth);
127         line.SetLineWidth(__lineWidth);
128
129         if (rectW == 1 && rectH == 1)
130         {
131                 return (line._DrawPixelWithClipping(rectX, rectY, bufInfo) == GP_RESULT_FAIL ? E_SYSTEM : E_SUCCESS);
132         }
133
134         if ((bufInfo.bitsPerPixel == 32 && (bufInfo.color32 & 0xFF000000) != 0xFF000000) || (rectW > 1200) || (rectH > 1200))
135         {
136                 switch (arcType)
137                 {
138                 case ARC_STYLE_ONLY:
139                 case ARC_STYLE_PIE:
140                 case ARC_STYLE_CHORD:
141                         return __Draw32BitArc(rectX, rectY, rectW, rectH, startAngle, endAngle, arcType, bufInfo) ? E_SUCCESS : E_SYSTEM;
142                 case ARC_STYLE_FILLED_PIE:
143                 case ARC_STYLE_FILLED_CHORD:
144 //                      ret =  __WmDraw32BitsFilledArc(gc, rectX, rectY, rectW, rectH, startAngle, endAngle, arcType);
145                         break;
146                 default:
147                         break;
148                 }
149         }
150
151         if (startAngle == endAngle)
152         {
153                 if (arcType == ARC_STYLE_FILLED_CHORD)
154                 {
155                         // Even width, height
156                         if (rectW % 2 == 0)
157                         {
158                                 rectW--;
159                         }
160
161                         if (rectH % 2 == 0)
162                         {
163                                 rectH--;
164                         }
165
166                         // Radius
167                         radiusX = rectW >> 1;
168                         radiusY = rectH >> 1;
169
170                         // Center
171                         centerX = rectX + radiusX;
172                         centerY = rectY + radiusY;
173
174                         x = (int) (radiusX * __Cosine(startAngle) + 0.5);
175                         y = (int) (radiusY * __Sine(startAngle) + 0.5);
176
177                         return (line._DrawPixelWithClipping(centerX + x, centerY + y, bufInfo) == GP_RESULT_FAIL ? E_SYSTEM : E_SUCCESS);
178                 }
179         }
180         else if (GP_ABS(endAngle - startAngle) % 360 == 0)
181         {
182                 isEllipse = true;
183         }
184
185         pPoints = new (std::nothrow) _GpPoint[_MAX_ARC_OUTLINE_POINTS];
186
187         if (pPoints == null)
188         {
189                 SysLog(NID_GRP, "DrawArc: Memory allocation is failed!\n");
190
191                 return E_SYSTEM;
192         }
193
194         memset(pPoints, 0, sizeof(pPoints[0]) * _MAX_ARC_OUTLINE_POINTS);
195
196         // Swap angle
197         if (startAngle > endAngle)
198         {
199                 GP_SWAP(startAngle, endAngle);
200         }
201
202         // Get line width
203         halfLineW = (__lineWidth + 1) >> 1;
204
205         if (line._IsInClipRect(rectX - halfLineW, rectY - halfLineW, rectW + (halfLineW << 1), rectH + (halfLineW << 1), bufInfo))
206         {
207                 isClipped = false;
208                 line._SetNotClipFunction(true);
209         }
210
211         // Even width, height
212         if (rectW % 2 == 0)
213         {
214                 rectW--;
215         }
216
217         if (rectH % 2 == 0)
218         {
219                 rectH--;
220         }
221
222         // Radius
223         radiusX = rectW >> 1;
224         radiusY = rectH >> 1;
225
226         // Center
227         centerX = rectX + radiusX;
228         centerY = rectY + radiusY;
229
230         if (arcType == ARC_STYLE_FILLED_PIE || arcType == ARC_STYLE_FILLED_CHORD)
231         {
232                 pixelCount = 0;
233         }
234
235         __GetArcVertices(radiusX, radiusY, startAngle, &x, &y);
236
237         preX = x;
238         preY = y;
239
240         if (arcType >= ARC_STYLE_ONLY && arcType <= ARC_STYLE_CHORD)
241         {
242                 if (__lineWidth > 1)
243                 {
244                         int halfLineW = __lineWidth >> 1;
245
246                         for (theta = startAngle; theta <= endAngle; theta += _ARC_DELTA_SOLID_LINE)
247                         {
248                                 if (theta + _ARC_DELTA_SOLID_LINE >= endAngle)
249                                 {
250                                         theta = endAngle;
251                                 }
252
253                                 __GetArcVertices(radiusX, radiusY, theta, &x, &y);
254
255                                 if (GP_ABS(x - preX) >= 2 || GP_ABS(y - preY) >= 2)
256                                 {
257                                         _GpPoint startPoint = { centerX + preX, centerY - preY };
258                                         _GpPoint endPoint = { centerX + x, centerY - y };
259
260                                         line.DrawLine(startPoint, endPoint, bufInfo);
261                                 }
262                                 else
263                                 {
264                                         ellipse.FillElliepse(centerX + x - halfLineW, centerY - y - halfLineW, __lineWidth, __lineWidth, bufInfo);
265                                 }
266
267                                 preX = x;
268                                 preY = y;
269                         }
270
271                         if (theta < endAngle + _ARC_DELTA_SOLID_LINE)
272                         {
273                                 __GetArcVertices(radiusX, radiusY, theta, &x, &y);
274
275                                 if (GP_ABS(x - preX) >= 2 || GP_ABS(y - preY) >= 2)
276                                 {
277                                         _GpPoint startPoint = { centerX + preX, centerY - preY };
278                                         _GpPoint endPoint = { centerX + x, centerY - y };
279
280                                         line.DrawLine(startPoint, endPoint, bufInfo);
281                                 }
282                                 else
283                                 {
284                                         ellipse.FillElliepse(centerX + x - halfLineW, centerY - y - halfLineW, __lineWidth, __lineWidth, bufInfo);
285                                 }
286                         }
287                 }
288                 else
289                 {
290                         for (theta = startAngle; theta <= endAngle; theta += _ARC_DELTA_SOLID_LINE)
291                         {
292                                 if (theta + _ARC_DELTA_SOLID_LINE >= endAngle)
293                                 {
294                                         theta = endAngle;
295                                 }
296
297                                 __GetArcVertices(radiusX, radiusY, theta, &x, &y);
298
299                                 _GpPoint tempPoint1 = { centerX + preX, centerY - preY };
300                                 _GpPoint tempPoint2 = { centerX + x, centerY - y };
301
302                                 line._DrawUnitLineSlant(tempPoint1, tempPoint2, bufInfo);
303
304                                 preX = x;
305                                 preY = y;
306                         }
307
308                         if (theta < endAngle + _ARC_DELTA_SOLID_LINE)
309                         {
310                                 __GetArcVertices(radiusX, radiusY, endAngle, &x, &y);
311
312                                 _GpPoint tempPoint1 = { centerX + preX, centerY - preY };
313                                 _GpPoint tempPoint2 = { centerX + x, centerY - y };
314
315                                 line._DrawUnitLineSlant(tempPoint1, tempPoint2, bufInfo);
316                         }
317                 }
318         }
319         else
320         {
321                 for (theta = startAngle; theta <= endAngle; theta += _ARC_DELTA_SOLID_LINE)
322                 {
323                         if (theta + _ARC_DELTA_SOLID_LINE >= endAngle)
324                         {
325                                 theta = endAngle;
326                         }
327
328                         __GetArcVertices(radiusX, radiusY, theta, &x, &y);
329                         __SaveLine(centerX + preX, centerY - preY, centerX + x, centerY - y, pPoints, &pixelCount);
330                         preX = x;
331                         preY = y;
332
333                 }
334
335                 if (theta < endAngle + _ARC_DELTA_SOLID_LINE)
336                 {
337                         __GetArcVertices(radiusX, radiusY, endAngle, &x, &y);
338                         __SaveLine(centerX + preX, centerY - preY, centerX + x, centerY - y, pPoints, &pixelCount);
339                 }
340         }
341
342         switch (arcType)
343         {
344         case ARC_STYLE_FILLED_PIE:
345                 if (isEllipse == null)
346                 {
347                         __GetArcVertices(radiusX, radiusY, startAngle, &x, &y);
348                         __SaveLine(centerX, centerY, centerX + x, centerY - y, pPoints, &pixelCount);
349
350                         __GetArcVertices(radiusX, radiusY, endAngle, &x, &y);
351                         __SaveLine(centerX, centerY, centerX + x, centerY - y, pPoints, &pixelCount);
352                 }
353                 __FillArcWithEvenOdd(pPoints, pixelCount, isClipped, bufInfo);
354                 break;
355
356         case ARC_STYLE_PIE:
357                 if (isEllipse == null)
358                 {
359                         _GpPoint startPoint = { centerX, centerY };
360
361                         {
362                                 __GetArcVertices(radiusX, radiusY, startAngle, &x, &y);
363
364                                 _GpPoint endPoint = { centerX + x, centerY - y };
365
366                                 if (__lineWidth > 1)
367                                 {
368                                         line.DrawLine(startPoint, endPoint, bufInfo);
369                                 }
370                                 else
371                                 {
372                                         line._DrawUnitLineSlant(startPoint, endPoint, bufInfo);
373                                 }
374                         }
375
376                         {
377                                 __GetArcVertices(radiusX, radiusY, endAngle, &x, &y);
378
379                                 _GpPoint endPoint = { centerX + x, centerY - y };
380
381                                 if (__lineWidth > 1)
382                                 {
383                                         line.DrawLine(startPoint, endPoint, bufInfo);
384                                 }
385                                 else
386                                 {
387                                         line._DrawUnitLineSlant(startPoint, endPoint, bufInfo);
388                                 }
389                         }
390
391                 }
392                 break;
393
394         case ARC_STYLE_FILLED_CHORD:
395                 if (isEllipse == null)
396                 {
397                         __GetArcVertices(radiusX, radiusY, startAngle, &x, &y);
398                         __GetArcVertices(radiusX, radiusY, endAngle, &x1, &y1);
399
400                         __SaveLine(centerX + x, centerY - y, centerX + x1, centerY - y1, pPoints, &pixelCount);
401                 }
402                 __FillArcWithEvenOdd(pPoints, pixelCount, isClipped, bufInfo);
403                 break;
404
405         case ARC_STYLE_CHORD:
406                 if (isEllipse == null)
407                 {
408                         __GetArcVertices(radiusX, radiusY, startAngle, &x, &y);
409                         __GetArcVertices(radiusX, radiusY, endAngle, &x1, &y1);
410
411                         _GpPoint startPoint = { centerX + x, centerY - y };
412                         _GpPoint endPoint = { centerX + x1, centerY - y1 };
413
414                         if (__lineWidth > 1)
415                         {
416                                 line.DrawLine(startPoint, endPoint, bufInfo);
417                         }
418                         else
419                         {
420                                 line._DrawUnitLineSlant(startPoint, endPoint, bufInfo);
421                         }
422                 }
423                 break;
424
425         default:
426                 // Skip
427                 break;
428         }
429
430         if (arcType == ARC_STYLE_FILLED_PIE || arcType == ARC_STYLE_FILLED_CHORD)
431         {
432                 pixelCount = 0;
433         }
434
435         delete[] pPoints;
436
437         return E_SUCCESS;
438 }
439
440 bool
441 _CanvasArc::__GetArcVertices(int radiusX, int radiusY, int theta, int* pX, int* pY) const
442 {
443         float degree;
444         float r;
445         float t1x;
446         float t1y;
447         float sinR;
448         float cosR;
449         float t2x;
450         float t2y;
451         _CanvasLine line;
452
453         degree = (float) theta;
454
455         r = (float) atan2(radiusX * sin(_GP_DEGREE2RADIAN(degree)), radiusY * cos(_GP_DEGREE2RADIAN(degree)));
456
457         while (r < 0)
458         {
459                 r = r + 2 * _PI;
460         }
461
462         sinR = (float) sin(r);
463         cosR = (float) cos(r);
464
465         t1x = radiusX * cosR;
466         t1y = radiusY * sinR;
467
468         line._Rotate2DPoint(t1x, t1y, 0, &t2x, &t2y);
469
470         *pX = (int) t2x;
471         *pY = (int) t2y;
472
473         return true;
474 }
475
476 float
477 _CanvasArc::__Sine(int degree) const
478 {
479         degree %= 360;
480
481         if (degree <= 90)
482         {
483                 return _SINE_TABLE[degree];
484         }
485         else if (degree <= 180)
486         {
487                 return _SINE_TABLE[180 - degree];
488         }
489         else if (degree <= 270)
490         {
491                 return -_SINE_TABLE[degree - 180];
492         }
493         else
494         {
495                 return -_SINE_TABLE[360 - degree];
496         }
497 }
498
499 float
500 _CanvasArc::__Cosine(int degree) const
501 {
502         return __Sine(degree + 90);
503 }
504
505 bool
506 _CanvasArc::__SaveLine(int x1, int y1, int x2, int y2, _GpPoint* pPoints, int* pPixelCount) const
507 {
508         if ((x1 == x2) && (y1 == y2))
509         {
510                 return true;
511         }
512         else if (y1 == y2)
513         {
514                 return true; // Horizontal Line
515         }
516         else
517         {
518                 register int x;
519                 register int y;
520                 int iy1;
521                 int iy2;
522                 int startY;
523                 int endY;
524                 int incdec;
525                 long tmpX;
526                 long dx;
527                 long dy;
528                 int pointCount;
529
530                 iy1 = y1;
531                 iy2 = y2;
532
533                 if (y1 < y2)
534                 {
535                         startY = iy1;
536                         endY = iy2 - 1;
537                         incdec = 1;
538                 }
539                 else
540                 {
541                         startY = iy1 - 1;
542                         endY = iy2;
543                         incdec = -1;
544                 }
545                 dx = x2 - x1;
546                 dy = y2 - y1;
547
548                 // Get point count
549                 pointCount = *pPixelCount;
550
551                 if (dx == 0)
552                 {
553                         for (y = startY; y != endY + incdec; y += incdec)
554                         {
555                                 if (pointCount < _MAX_ARC_OUTLINE_POINTS)
556                                 {
557                                         pPoints[pointCount].x = x1;
558                                         pPoints[pointCount].y = y;
559                                         pointCount++;
560                                 }
561                                 else
562                                 {
563                                         SysLog(NID_GRP, "__SaveLine: buffer overflow!\n");
564                                         return false;
565                                 }
566                         }
567                 }
568                 else
569                 {
570                         for (y = startY; y != endY + incdec; y += incdec)
571                         {
572                                 tmpX = ((y - y1) * dx) / dy;
573                                 x = x1 + tmpX;
574
575                                 if (pointCount < _MAX_ARC_OUTLINE_POINTS)
576                                 {
577                                         pPoints[pointCount].x = x;
578                                         pPoints[pointCount].y = y;
579                                         pointCount++;
580                                 }
581                                 else
582                                 {
583                                         SysLog(NID_GRP, "__SaveLine: buffer overflow!\n");
584                                         return false;
585                                 }
586                         }
587                 }
588                 *pPixelCount = pointCount;
589         }
590
591         return true;
592 }
593
594 bool
595 _CanvasArc::__FillArcWithEvenOdd(_GpPoint* pPoints, int pixelCount, bool clip, const _GpBufferInfo& bufInfo) const
596 {
597         int i;
598         int x1;
599         int y1;
600         int x2;
601         int y2;
602         int clipX = 0;
603         int clipY = 0;
604         int clipEndX = 0;
605         int clipEndY = 0;
606         _CanvasLine line;
607
608         if (pPoints == null)
609         {
610                 return true;
611         }
612
613         if (pixelCount <= 1)
614         {
615                 return true;
616         }
617
618         line.SetLineWidth(__lineWidth);
619
620         if (clip)
621         {
622                 if (bufInfo.isClipBoundsSet)
623                 {
624                         clipX = bufInfo.clipBounds.x;
625                         clipY = bufInfo.clipBounds.y;
626                         clipEndX = clipX + bufInfo.clipBounds.width - 1;
627                         clipEndY = clipY + bufInfo.clipBounds.height - 1;
628                 }
629                 else
630                 {
631                         clipX = 0;
632                         clipY = 0;
633                         clipEndX = bufInfo.width - 1;
634                         clipEndY = bufInfo.height - 1;
635                 }
636         }
637
638         // Sort points
639         __QuickSort(pPoints, 0, pixelCount - 1);
640
641         // Filling
642         for (i = 0; i < pixelCount - 1; )
643         {
644                 x1 = pPoints[i].x;
645                 y1 = pPoints[i].y;
646                 x2 = pPoints[i + 1].x;
647                 y2 = pPoints[i + 1].y;
648
649                 if (y1 == y2)
650                 {
651                         if (x1 == x2)
652                         {
653                                 if (clip)
654                                 {
655                                         if (x1 < clipX || x1 > clipEndX)
656                                         {
657                                                 goto CLIP_EXIT;
658                                         }
659
660                                         if (y1 < clipY || y1 > clipEndY)
661                                         {
662                                                 goto CLIP_EXIT;
663                                         }
664                                 }
665
666                                 line._DrawPixel(x1, y1, bufInfo);
667                         }
668                         else
669                         {
670                                 //  Swapping
671                                 if (x1 > x2)
672                                 {
673                                         GP_SWAP(x1, x2);
674                                 }
675
676                                 if (clip)
677                                 {
678                                         if (y1 < clipY || y1 > clipEndY)
679                                         {
680                                                 goto CLIP_EXIT;
681                                         }
682
683                                         if (x2 < clipX || x1 > clipEndX)
684                                         {
685                                                 goto CLIP_EXIT;
686                                         }
687
688                                         if (x1 < clipX)
689                                         {
690                                                 x1 = clipX;
691                                         }
692
693                                         if (x2 > clipEndX)
694                                         {
695                                                 x2 = clipEndX;
696                                         }
697                                 }
698
699                                 // draw primitive line
700                                 line._DrawUnitLineHorizontal(x1, x2, y1, bufInfo);
701                         }
702 CLIP_EXIT:
703                         i += 2;
704                 }
705                 else // Exception handling
706                 {
707                         i++;
708                 }
709         }
710
711         return true;
712 }
713
714 void
715 _CanvasArc::__QuickSort(_GpPoint* pPoints, int left, int right) const
716 {
717         GpArcStack stack[_MAX_STACK_COUNT];
718         _GpPoint tmp;
719         _GpPoint pivot;
720         GpArcDiffResult result;
721         register int i;
722         register int j;
723         register int top = 1;
724
725         // Check parameter
726         if (pPoints == null)
727         {
728                 return;
729         }
730
731         // init stack
732         stack[0].left = -1;
733         stack[0].right = -1;
734
735         stack[top].left = left;
736         stack[top].right = right;
737         do
738         {
739                 left = stack[top].left;
740
741                 if (left < 0)
742                 {
743                         break;
744                 }
745
746                 right = stack[top--].right;
747
748                 if (right < 0)
749                 {
750                         break;
751                 }
752
753                 do
754                 {
755                         i = left;
756                         j = right;
757                         pivot = pPoints[((left + right) >> 1)];
758                         do
759                         {
760                                 while (true)
761                                 {
762                                         if (pPoints[i].y > pivot.y)
763                                         {
764                                                 result = DIFF_RESULT_GREAT;
765                                         }
766                                         else if (pPoints[i].y == pivot.y)
767                                         {
768                                                 if (pPoints[i].x > pivot.x)
769                                                 {
770                                                         result = DIFF_RESULT_GREAT;
771                                                 }
772                                                 else if (pPoints[i].x == pivot.x)
773                                                 {
774                                                         result = DIFF_RESULT_EQUAL;
775                                                 }
776                                                 else
777                                                 {
778                                                         result = DIFF_RESULT_LITTLE;
779                                                 }
780                                         }
781                                         else
782                                         {
783                                                 result = DIFF_RESULT_LITTLE;
784                                         }
785
786                                         if (result == DIFF_RESULT_LITTLE)
787                                         {
788                                                 i++;
789                                         }
790                                         else
791                                         {
792                                                 break;
793                                         }
794                                 }
795
796                                 while (true)
797                                 {
798                                         if (pPoints[j].y > pivot.y)
799                                         {
800                                                 result = DIFF_RESULT_GREAT;
801                                         }
802                                         else if (pPoints[j].y == pivot.y)
803                                         {
804                                                 if (pPoints[j].x > pivot.x)
805                                                 {
806                                                         result = DIFF_RESULT_GREAT;
807                                                 }
808                                                 else if (pPoints[j].x == pivot.x)
809                                                 {
810                                                         result = DIFF_RESULT_EQUAL;
811                                                 }
812                                                 else
813                                                 {
814                                                         result = DIFF_RESULT_LITTLE;
815                                                 }
816                                         }
817                                         else
818                                         {
819                                                 result = DIFF_RESULT_LITTLE;
820                                         }
821
822                                         if (result == DIFF_RESULT_GREAT)
823                                         {
824                                                 j--;
825                                         }
826                                         else
827                                         {
828                                                 break;
829                                         }
830                                 }
831
832                                 if (i <= j)
833                                 {
834                                         tmp = pPoints[i];
835                                         pPoints[i] = pPoints[j];
836                                         pPoints[j] = tmp;
837                                         i++;
838                                         j--;
839                                 }
840                         }
841                         while (i <= j);
842
843                         if (j - left < right - i)
844                         {
845                                 if (i < right)
846                                 {
847                                         if (top >= _MAX_STACK_COUNT - 1)
848                                         {
849                                                 return;
850                                         }
851
852                                         stack[++top].left = i;
853                                         stack[top].right = right;
854                                 }
855                                 right = j;
856                         }
857                         else
858                         {
859                                 if (left < j)
860                                 {
861                                         if (top >= _MAX_STACK_COUNT - 1)
862                                         {
863                                                 return;
864                                         }
865
866                                         stack[++top].left = left;
867                                         stack[top].right = j;
868                                 }
869                                 left = i;
870                         }
871                 }
872                 while (left < right);
873         }
874         while (top != -1);
875 }
876
877
878 bool
879 _CanvasArc::__Draw32BitArc(int rectX, int rectY, int rectW, int rectH, int d0, int d1, ArcStyle arcType, const _GpBufferInfo& bufInfo)
880 {
881         int dx;
882         int dy;
883         float rx;
884         float ry;
885         float centerX;
886         float centerY;
887         int cx;
888         int cy;
889
890         if ((rectW <= 0) || (rectH <= 0))
891         {
892                 return true;
893         }
894
895         if ((d0 % 360 == d1 % 360) && (d1 - d0 != 360))
896         {
897                 return true;
898         }
899
900         dx = (rectW + 1) % 2;
901         dy = (rectH + 1) % 2;
902
903         rx = (float) (rectW / 2 - dx);
904         ry = (float) (rectH / 2 - dy);
905
906         if (dx)
907         {
908                 rx += 0.5f;
909         }
910
911         if (dy)
912         {
913                 ry += 0.5f;
914         }
915
916         centerX = (float) (rectX) + rx;
917         centerY = (float) (rectY) + ry;
918
919         cx = (int) (centerX);
920         cy = (int) (centerY);
921
922         if (__lineWidth < 2)
923         {
924                 _GpFloatPoint* pEllipsePoint = null;
925                 int n;
926                 int i;
927                 _GpPoint* pPoints = null;
928                 bool isConnected = false;
929                 _CanvasLine line;
930
931                 n = line._MakeEllipseArcPointArray(&pEllipsePoint, null, centerX, centerY, rx, ry, d0, d1, 0);
932
933                 if (n < 2)
934                 {
935                         SysLog(NID_GRP, "__Draw32BitArc: _MakeEllipseArcPointArray is failed!\n");
936
937                         if (pEllipsePoint)
938                         {
939                                 delete[] pEllipsePoint;
940                         }
941
942                         return false;
943                 }
944
945                 pPoints = new (std::nothrow) _GpPoint[n + 1];
946
947                 if (pPoints == null)
948                 {
949                         SysLog(NID_GRP, "__Draw32BitArc: Memory allocation is failed!\n");
950
951                         if (pEllipsePoint)
952                         {
953                                 delete[] pEllipsePoint;
954                         }
955
956                         return false;
957                 }
958
959                 for (i = 0; i < n; i++)
960                 {
961                         pPoints[i].x = (int) pEllipsePoint[i].fx;
962                         pPoints[i].y = (int) pEllipsePoint[i].fy;
963                 }
964
965                 pPoints[n].x = 0;
966                 pPoints[n].y = 0;
967
968                 switch (arcType)
969                 {
970                 case ARC_STYLE_ONLY:
971                         break;
972                 case ARC_STYLE_CHORD:
973                         isConnected = true;
974                         break;
975                 case ARC_STYLE_PIE:
976                         isConnected = true;
977                         pPoints[n].x = cx;
978                         pPoints[n].y = cy;
979                         n++;
980                         break;
981                 default:
982                         SysLog(NID_GRP, "__Draw32BitArc: Invalid arc [%d]type - 1!\n", arcType);
983                         delete[] pEllipsePoint;
984                         delete[] pPoints;
985
986                         return false;
987                 }
988
989                 line._DrawPolyLine(n, pPoints, isConnected, bufInfo);
990
991                 delete[] pEllipsePoint;
992                 delete[] pPoints;
993
994                 return true;
995         }
996         else
997         {
998                 switch (arcType)
999                 {
1000                 case ARC_STYLE_ONLY:
1001                         if (!__DrawThickContinuousArc(cx, cy, rectW / 2, rectH / 2, d0, d1, bufInfo))
1002                         {
1003                                 SysLog(NID_GRP, "__Draw32BitArc: __DrawThickContinuousArc is failed!\n");
1004
1005                                 return false;
1006                         }
1007                         break;
1008                 case ARC_STYLE_PIE:
1009                         if (!__DrawThickContinuousPie(cx, cy, rectW / 2, rectH / 2, d0, d1, bufInfo))
1010                         {
1011                                 SysLog(NID_GRP, "__Draw32BitArc: __DrawThickContinuousPie is failed!\n");
1012
1013                                 return false;
1014                         }
1015                         break;
1016                 case ARC_STYLE_CHORD:
1017                         if (!__DrawThickContinuousChord(cx, cy, rectW / 2, rectH / 2, d0, d1, bufInfo))
1018                         {
1019                                 SysLog(NID_GRP, "__Draw32BitArc: __DrawThickContinuousChord is failed!\n");
1020
1021                                 return false;
1022                         }
1023                         break;
1024                 default:
1025                         SysLog(NID_GRP, "__Draw32BitArc: Invalid arc [%d]type - 2!\n", arcType);
1026
1027                         return false;
1028                 }
1029         }
1030
1031         return true;
1032 }
1033
1034 bool
1035 _CanvasArc::__DrawThickContinuousArc(int cx, int cy, int halfW, int halfH, int d0, int d1, const _GpBufferInfo& bufInfo) const
1036 {
1037         int ellipsePointCount;
1038         int i;
1039         bool result;
1040         _GpFloatPoint* pEllipsePoint = null;
1041         _GpFloatPoint* pEpNormal = null;
1042         float wl;
1043         float wr;
1044         _GpPolygon* pPolygon = null;
1045         _GpPoint* pTempPoints = null;
1046         _GpVertex* pVertex = null;
1047         _CanvasLine line;
1048
1049         float radiusX = (float) halfW;
1050         float radiusY = (float) halfH;
1051
1052         float centerX = (float) cx;
1053         float centerY = (float) cy;
1054
1055         line.SetLineWidth(__lineWidth);
1056         ellipsePointCount = line._MakeEllipseArcPointArray(&pEllipsePoint, &pEpNormal, centerX, centerY, radiusX, radiusY, d0, d1, 0);
1057
1058         if (ellipsePointCount < 2 || pEllipsePoint == null || pEpNormal == null)
1059         {
1060                 SysLog(NID_GRP, "__DrawThickContinuousArc: _MakeEllipseArcPointArray is failed!\n");
1061
1062                 delete[] pEllipsePoint;
1063                 delete[] pEpNormal;
1064
1065                 return false;
1066         }
1067
1068         _CalcLeftRightWidth(&wl, &wr);
1069
1070         pPolygon = new (std::nothrow) _GpPolygon;
1071
1072         if (pPolygon == null)
1073         {
1074                 SysLog(NID_GRP, "__DrawThickContinuousArc: _CreatePolygon is failed!\n");
1075
1076                 delete[] pEllipsePoint;
1077                 delete[] pEpNormal;
1078
1079                 return false;
1080         }
1081
1082         if (!line._PatchRoundCap(pPolygon, (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy, pEpNormal[0].fy, -pEpNormal[0].fx, true))
1083         {
1084                 SysLog(NID_GRP, "__DrawThickContinuousArc: _PatchRoundCap is failed - 1!\n");
1085
1086                 line._FreePolygon(pPolygon);
1087
1088                 delete[] pEllipsePoint;
1089                 delete[] pEpNormal;
1090
1091                 return false;
1092         }
1093
1094         for (i = 0; i < ellipsePointCount; i++)
1095         {
1096                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx - (pEpNormal[i].fx * wl)), (int) (pEllipsePoint[i].fy - (pEpNormal[i].fy * wl)), 0);
1097
1098                 if (!result)
1099                 {
1100                         SysLog(NID_GRP, "__DrawThickContinuousArc: _AddPolygonVertex is failed - 1!\n");
1101                         line._FreePolygon(pPolygon);
1102
1103                         delete[] pEllipsePoint;
1104                         delete[] pEpNormal;
1105
1106                         return false;
1107                 }
1108
1109                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx + (pEpNormal[i].fx * wr)), (int) (pEllipsePoint[i].fy + (pEpNormal[i].fy * wr)), 1);
1110
1111                 if (!result)
1112                 {
1113                         SysLog(NID_GRP, "__DrawThickContinuousArc: _AddPolygonVertex is failed - 1!\n");
1114                         line._FreePolygon(pPolygon);
1115
1116                         delete[] pEllipsePoint;
1117                         delete[] pEpNormal;
1118
1119                         return false;
1120                 }
1121         }
1122
1123         i = ellipsePointCount - 1;
1124
1125         if (!line._PatchRoundCap(pPolygon, (int) pEllipsePoint[i].fx, (int) pEllipsePoint[i].fy, pEpNormal[i].fy, -pEpNormal[i].fx, false))
1126         {
1127                 SysLog(NID_GRP, "__DrawThickContinuousArc: _PatchRoundCap is failed - 2!\n");
1128                 line._FreePolygon(pPolygon);
1129
1130                 delete[] pEllipsePoint;
1131                 delete[] pEpNormal;
1132
1133                 return false;
1134         }
1135
1136         //release memory
1137         delete[] pEllipsePoint;
1138         pEllipsePoint = null;
1139
1140         delete[] pEpNormal;
1141         pEpNormal = null;
1142
1143         pTempPoints = new (std::nothrow) _GpPoint[pPolygon->n];
1144
1145         if (pTempPoints == null)
1146         {
1147                 SysLog(NID_GRP, "__DrawThickContinuousArc: Memory allocation is failed - 2!\n");
1148                 line._FreePolygon(pPolygon);
1149
1150                 return false;
1151         }
1152
1153         for (i = 0, pVertex = pPolygon->pFirst; pVertex != null; i++, pVertex = pVertex->pNext)
1154         {
1155                 pTempPoints[i] = pVertex->point;
1156         }
1157
1158         line._FillPolygon(pPolygon->n, pTempPoints, false, bufInfo);
1159
1160         line._FreePolygon(pPolygon);
1161
1162         delete[] pTempPoints;
1163
1164         return true;
1165 }
1166
1167 bool
1168 _CanvasArc::__DrawThickContinuousPie(int cx, int cy, int halfW, int halfH, int d0, int d1, const _GpBufferInfo& bufInfo) const
1169 {
1170         int ellipsePointCount;
1171         int i;
1172         int result;
1173         _GpFloatPoint* pEllipsePoint = null;
1174         _GpFloatPoint* pEpNormal = null;
1175         float wl;
1176         float wr;
1177         float ox;
1178         float oy;
1179         float qx;
1180         float qy;
1181         _GpPolygon* pPolygon = null;
1182         _GpVertex* pVertex = null;
1183         _GpPoint* pTempPoints = null;
1184         _CanvasLine line;
1185
1186         float radiusX = (float) halfW;
1187         float radiusY = (float) halfH;
1188
1189         float centerX = (float) cx;
1190         float centerY = (float) cy;
1191
1192         line.SetLineWidth(__lineWidth);
1193         ellipsePointCount = line._MakeEllipseArcPointArray(&pEllipsePoint, &pEpNormal, centerX, centerY, radiusX, radiusY, d0, d1, 0);
1194
1195         if (ellipsePointCount < 2 || pEllipsePoint == null || pEpNormal == null)
1196         {
1197                 SysLog(NID_GRP, "__DrawThickContinuousPie: _MakeEllipseArcPointArray is failed!\n");
1198
1199                 delete[] pEllipsePoint;
1200                 delete[] pEpNormal;
1201
1202                 return false;
1203         }
1204
1205         _CalcLeftRightWidth(&wl, &wr);
1206
1207         pPolygon = new (std::nothrow) _GpPolygon;
1208
1209         if (pPolygon == null)
1210         {
1211                 SysLog(NID_GRP, "__DrawThickContinuousPie: _CreatePolygon is failed!\n");
1212
1213                 delete[] pEllipsePoint;
1214                 delete[] pEpNormal;
1215
1216                 return false;
1217         }
1218
1219         if (!line._PatchRoundCap(pPolygon, (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy, pEpNormal[0].fy, -pEpNormal[0].fx, true))
1220         {
1221                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchRoundCap is failed - 1!\n");
1222
1223                 line._FreePolygon(pPolygon);
1224
1225                 delete[] pEllipsePoint;
1226                 delete[] pEpNormal;
1227
1228                 return false;
1229         }
1230
1231         for (i = 0; i < ellipsePointCount; i++)
1232         {
1233                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx - (pEpNormal[i].fx * wl)), (int) (pEllipsePoint[i].fy - (pEpNormal[i].fy * wl)), 0);
1234
1235                 if (!result)
1236                 {
1237                         SysLog(NID_GRP, "__DrawThickContinuousPie: _AddPolygonVertex is failed - 1!\n");
1238
1239                         line._FreePolygon(pPolygon);
1240
1241                         delete[] pEllipsePoint;
1242                         delete[] pEpNormal;
1243
1244                         return false;
1245                 }
1246
1247                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx + (pEpNormal[i].fx * wr)), (int) (pEllipsePoint[i].fy + (pEpNormal[i].fy * wr)), 1);
1248
1249                 if (!result)
1250                 {
1251                         SysLog(NID_GRP, "__DrawThickContinuousPie: _AddPolygonVertex is failed - 2!\n");
1252
1253                         line._FreePolygon(pPolygon);
1254
1255                         delete[] pEllipsePoint;
1256                         delete[] pEpNormal;
1257
1258                         return false;
1259                 }
1260         }
1261
1262         i = ellipsePointCount - 1;
1263
1264         _GpPoint pt1 = { (int) pEllipsePoint[i].fx, (int) pEllipsePoint[i].fy };
1265         _GpPoint pt2 = { cx, cy };
1266
1267         line._GetOrientationUnitVector(pt1, pt2, &ox, &oy);
1268
1269         result = line._PatchJoint(pPolygon, (int) pEllipsePoint[i].fx, (int) pEllipsePoint[i].fy, pEpNormal[i].fy, -pEpNormal[i].fx, ox, oy);
1270
1271         if (!result)
1272         {
1273                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchJoint is failed -1!\n");
1274
1275                 line._FreePolygon(pPolygon);
1276
1277                 delete[] pEllipsePoint;
1278                 delete[] pEpNormal;
1279
1280                 return false;
1281         }
1282
1283         pt1.x = (int) pEllipsePoint[i].fx;
1284         pt1.y = (int) pEllipsePoint[i].fy;
1285         pt2.x = cx;
1286         pt2.y = cy;
1287
1288         result = line._PatchThickContinuousLine(pPolygon, pt1, pt2, ox, oy, 0, 0);
1289
1290         if (!result)
1291         {
1292                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchThickContinuousLine is failed -1!\n");
1293
1294                 line._FreePolygon(pPolygon);
1295
1296                 delete[] pEllipsePoint;
1297                 delete[] pEpNormal;
1298
1299                 return false;
1300         }
1301
1302         pt1.x = cx;
1303         pt1.y = cy;
1304         pt2.x = (int) pEllipsePoint[0].fx;
1305         pt2.y = (int) pEllipsePoint[0].fy;
1306
1307         line._GetOrientationUnitVector(pt1, pt2, &qx, &qy);
1308
1309         result = line._PatchJoint(pPolygon, cx, cy, ox, oy, qx, qy);
1310
1311         if (!result)
1312         {
1313                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchJoint is failed-2!\n");
1314
1315                 line._FreePolygon(pPolygon);
1316
1317                 delete[] pEllipsePoint;
1318                 delete[] pEpNormal;
1319
1320                 return false;
1321         }
1322
1323         pt1.x = cx;
1324         pt1.y = cy;
1325         pt2.x = (int) pEllipsePoint[0].fx;
1326         pt2.y = (int) pEllipsePoint[0].fy;
1327
1328         result = line._PatchThickContinuousLine(pPolygon, pt1, pt2, qx, qy, 0, 0);
1329
1330         if (!result)
1331         {
1332                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchThickContinuousLine is failed-2!\n");
1333
1334                 line._FreePolygon(pPolygon);
1335
1336                 delete[] pEllipsePoint;
1337                 delete[] pEpNormal;
1338
1339                 return false;
1340         }
1341
1342         result = line._PatchJoint(pPolygon, (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy, qx, qy, pEpNormal[0].fy, -pEpNormal[0].fx);
1343
1344         if (!result)
1345         {
1346                 SysLog(NID_GRP, "__DrawThickContinuousPie: _PatchJoint is failed-3!\n");
1347
1348                 line._FreePolygon(pPolygon);
1349
1350                 delete[] pEllipsePoint;
1351                 delete[] pEpNormal;
1352
1353                 return false;
1354         }
1355
1356         result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[0].fx + (pEpNormal[0].fx * wl)), (int) (pEllipsePoint[0].fy + (pEpNormal[0].fy * wl)), 0);
1357
1358         if (!result)
1359         {
1360                 SysLog(NID_GRP, "__DrawThickContinuousPie: _AddPolygonVertex is failed - 3!\n");
1361
1362                 line._FreePolygon(pPolygon);
1363
1364                 delete[] pEllipsePoint;
1365                 delete[] pEpNormal;
1366
1367                 return false;
1368         }
1369
1370         result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[0].fx + (pEpNormal[0].fx * wr)), (int) (pEllipsePoint[0].fy + (pEpNormal[0].fy * wr)), 1);
1371
1372         if (!result)
1373         {
1374                 SysLog(NID_GRP, "__DrawThickContinuousPie: _AddPolygonVertex is failed - 4!\n");
1375
1376                 line._FreePolygon(pPolygon);
1377
1378                 delete[] pEllipsePoint;
1379                 delete[] pEpNormal;
1380
1381                 return false;
1382         }
1383
1384         delete[] pEllipsePoint;
1385         pEllipsePoint = null;
1386
1387         delete[] pEpNormal;
1388         pEpNormal = null;
1389
1390         pTempPoints = new (std::nothrow) _GpPoint[pPolygon->n];
1391
1392         if (pTempPoints == null)
1393         {
1394                 SysLog(NID_GRP, "__DrawThickContinuousPie: Memory allocation is failed - 2!\n");
1395                 line._FreePolygon(pPolygon);
1396                 return false;
1397         }
1398
1399         for (i = 0, pVertex = pPolygon->pFirst; pVertex != null; i++, pVertex = pVertex->pNext)
1400         {
1401                 pTempPoints[i].x = pVertex->point.x;
1402                 pTempPoints[i].y = pVertex->point.y;
1403         }
1404
1405         line._FillPolygon(pPolygon->n, pTempPoints, false, bufInfo);
1406
1407         line._FreePolygon(pPolygon);
1408
1409         delete[] pTempPoints;
1410
1411         return true;
1412 }
1413
1414 bool
1415 _CanvasArc::__DrawThickContinuousChord(int cx, int cy, int halfW, int halfH, int d0, int d1, const _GpBufferInfo& bufInfo) const
1416 {
1417         int ellipsePointCount;
1418         int i;
1419         _GpFloatPoint* pEllipsePoint = null;
1420         _GpFloatPoint* pEpNormal = null;
1421         float wl;
1422         float wr;
1423         float ox;
1424         float oy;
1425         _GpPolygon* pPolygon = null;
1426         _GpPoint* pTempPoints = null;
1427         _GpVertex* pVertex = null;
1428         _CanvasLine line;
1429
1430         bool result = true;
1431
1432         float radiusX = (float) halfW;
1433         float radiusY = (float) halfH;
1434
1435         float centerX = (float) cx;
1436         float centerY = (float) cy;
1437
1438         line.SetLineWidth(__lineWidth);
1439         ellipsePointCount = line._MakeEllipseArcPointArray(&pEllipsePoint, &pEpNormal, centerX, centerY, radiusX, radiusY, d0, d1, 0);
1440
1441         if (ellipsePointCount < 2 || pEllipsePoint == null || pEpNormal == null)
1442         {
1443                 SysLog(NID_GRP, "__DrawThickContinuousChord: _MakeEllipseArcPointArray is failed!\n");
1444
1445                 delete[] pEllipsePoint;
1446                 delete[] pEpNormal;
1447
1448                 return false;
1449         }
1450
1451         _CalcLeftRightWidth(&wl, &wr);
1452
1453         pPolygon = new (std::nothrow) _GpPolygon;
1454
1455         if (pPolygon == null)
1456         {
1457                 SysLog(NID_GRP, "__DrawThickContinuousChord: _CreatePolygon is failed!\n");
1458
1459                 delete[] pEllipsePoint;
1460                 delete[] pEpNormal;
1461
1462                 return false;
1463         }
1464
1465         if (!line._PatchRoundCap(pPolygon, (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy, pEpNormal[0].fy, -pEpNormal[0].fx, true))
1466         {
1467                 SysLog(NID_GRP, "__DrawThickContinuousChord: _PatchRoundCap is failed - 1!\n");
1468
1469                 line._FreePolygon(pPolygon);
1470
1471                 delete[] pEllipsePoint;
1472                 delete[] pEpNormal;
1473
1474                 return false;
1475         }
1476
1477         for (i = 0; i < ellipsePointCount; i++)
1478         {
1479                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx - (pEpNormal[i].fx * wl)), (int) (pEllipsePoint[i].fy - (pEpNormal[i].fy * wl)), 0);
1480
1481                 if (!result)
1482                 {
1483                         SysLog(NID_GRP, "__DrawThickContinuousChord: _AddPolygonVertex is failed - 1!\n");
1484
1485                         line._FreePolygon(pPolygon);
1486
1487                         delete[] pEllipsePoint;
1488                         delete[] pEpNormal;
1489
1490                         return false;
1491                 }
1492
1493                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx + (pEpNormal[i].fx * wr)), (int) (pEllipsePoint[i].fy + (pEpNormal[i].fy * wr)), 1);
1494
1495                 if (!result)
1496                 {
1497                         SysLog(NID_GRP, "__DrawThickContinuousChord: _AddPolygonVertex is failed - 1!\n");
1498
1499                         line._FreePolygon(pPolygon);
1500
1501                         delete[] pEllipsePoint;
1502                         delete[] pEpNormal;
1503
1504                         return false;
1505                 }
1506         }
1507
1508         if ((d0 % 360) != (d1 % 360))
1509         {
1510                 i = ellipsePointCount - 1;
1511
1512                 _GpPoint pt1 = { (int) pEllipsePoint[i].fx, (int) pEllipsePoint[i].fy };
1513                 _GpPoint pt2 = { (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy };
1514
1515                 line._GetOrientationUnitVector(pt1, pt2, &ox, &oy);
1516
1517                 result = line._PatchJoint(pPolygon, (int) pEllipsePoint[i].fx, (int) pEllipsePoint[i].fy, pEpNormal[i].fy, -pEpNormal[i].fx, ox, oy);
1518
1519                 if (!result)
1520                 {
1521                         SysLog(NID_GRP, "__DrawThickContinuousChord: _PatchJoint is failed - 1!\n");
1522
1523                         line._FreePolygon(pPolygon);
1524
1525                         delete[] pEllipsePoint;
1526                         delete[] pEpNormal;
1527
1528                         return false;
1529                 }
1530
1531                 pt1.x = (int) pEllipsePoint[i].fx;
1532                 pt1.y = (int) pEllipsePoint[i].fy;
1533                 pt2.x = (int) pEllipsePoint[0].fx;
1534                 pt2.y = (int) pEllipsePoint[0].fy;
1535
1536                 result = line._PatchThickContinuousLine(pPolygon, pt1, pt2, ox, oy, 0, 0);
1537
1538                 if (!result)
1539                 {
1540                         SysLog(NID_GRP, "__DrawThickContinuousChord: _PatchJoint is failed - 1!\n");
1541
1542                         line._FreePolygon(pPolygon);
1543
1544                         delete[] pEllipsePoint;
1545                         delete[] pEpNormal;
1546
1547                         return false;
1548                 }
1549
1550                 result = line._PatchJoint(pPolygon, (int) pEllipsePoint[0].fx, (int) pEllipsePoint[0].fy, ox, oy, pEpNormal[0].fy, -pEpNormal[0].fx);
1551
1552                 if (!result)
1553                 {
1554                         SysLog(NID_GRP, "__DrawThickContinuousChord: _PatchJoint is failed - 2!\n");
1555
1556                         line._FreePolygon(pPolygon);
1557
1558                         delete[] pEllipsePoint;
1559                         delete[] pEpNormal;
1560
1561                         return false;
1562                 }
1563
1564                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[0].fx + (pEpNormal[0].fx * wl)), (int) (pEllipsePoint[0].fy + (pEpNormal[0].fy * wl)), 0);
1565
1566                 if (!result)
1567                 {
1568                         SysLog(NID_GRP, "__DrawThickContinuousChord: _AddPolygonVertex is failed - 2!\n");
1569
1570                         line._FreePolygon(pPolygon);
1571
1572                         delete[] pEllipsePoint;
1573                         delete[] pEpNormal;
1574
1575                         return false;
1576                 }
1577
1578                 result = line._AddPolygonVertex(pPolygon, (int) (pEllipsePoint[0].fx + (pEpNormal[0].fx * wr)), (int) (pEllipsePoint[0].fy + (pEpNormal[0].fy * wr)), 1);
1579
1580                 if (!result)
1581                 {
1582                         SysLog(NID_GRP, "__DrawThickContinuousChord: _AddPolygonVertex is failed - 3!\n");
1583
1584                         line._FreePolygon(pPolygon);
1585
1586                         delete[] pEllipsePoint;
1587                         delete[] pEpNormal;
1588
1589                         return false;
1590                 }
1591         }
1592
1593         delete[] pEllipsePoint;
1594         pEllipsePoint = null;
1595
1596         delete[] pEpNormal;
1597         pEpNormal = null;
1598
1599         pTempPoints = new (std::nothrow) _GpPoint[pPolygon->n];
1600
1601         if (pTempPoints == null)
1602         {
1603                 SysLog(NID_GRP, "__DrawThickContinuousChord:  Memory allocation is failed!\n");
1604                 line._FreePolygon(pPolygon);
1605
1606                 return false;
1607         }
1608
1609         for (i = 0, pVertex = pPolygon->pFirst; pVertex != null; i++, pVertex = pVertex->pNext)
1610         {
1611                 pTempPoints[i].x = pVertex->point.x;
1612                 pTempPoints[i].y = pVertex->point.y;
1613         }
1614
1615         line._FillPolygon(pPolygon->n, pTempPoints, false, bufInfo);
1616
1617         line._FreePolygon(pPolygon);
1618
1619         delete[] pTempPoints;
1620
1621         return true;
1622 }
1623
1624 void
1625 _CanvasArc::_CalcLeftRightWidth(float* pWidthLeft, float* pWidthRight) const
1626 {
1627         if (__lineWidth % 2 == 0)
1628         {
1629                 *pWidthRight = __lineWidth / 2.0f;
1630                 *pWidthLeft = *pWidthRight - 1.0f;
1631         }
1632         else
1633         {
1634                 *pWidthLeft = *pWidthRight = (__lineWidth - 1) / 2.0f;
1635         }
1636
1637         return;
1638 }
1639
1640 }} // Tizen::Graphics