Fork for IVI: mesa fixing
[profile/ivi/uifw.git] / src / graphics / FGrp_CanvasGpLine.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_CanvasGpLine.cpp
20  * @brief       This is the implementation file for _CanvasLine class.
21  *
22  */
23
24 #include <new>
25 #include <cstring>
26 #include <cmath>
27
28 #include <FGrpPoint.h>
29
30 #include <FBaseSysLog.h>
31
32 #include "FGrp_CanvasGpPrimitive.h"
33
34
35 using namespace Tizen::Base;
36 using namespace Tizen::Graphics;
37
38
39 namespace Tizen { namespace Graphics
40 {
41
42 bool
43 _CanvasLine::SetLineWidth(int lineWidth)
44 {
45         __lineWidth = lineWidth;
46
47         return true;
48 }
49
50 int
51 _CanvasLine::GetLineWidth(void) const
52 {
53         return __lineWidth;
54 }
55
56 result
57 _CanvasLine::DrawLine(const _GpPoint& startPt, const _GpPoint& endPt, const _GpBufferInfo& bufInfo)
58 {
59         _GpRect rcLine;
60         int halfLineW;
61         _GpResult ret = GP_RESULT_FAIL;
62         bool finalRet = false;
63         bool clip = true;
64
65         halfLineW = __lineWidth >> 1;
66
67         if (startPt.x > endPt.x)
68         {
69                 rcLine.x = endPt.x;
70                 rcLine.width = startPt.x - endPt.x + 1;
71         }
72         else
73         {
74                 rcLine.x = startPt.x;
75                 rcLine.width = endPt.x - startPt.x + 1;
76         }
77
78         if (startPt.y > endPt.y)
79         {
80                 rcLine.y = endPt.y;
81                 rcLine.height = startPt.y - endPt.y + 1;
82         }
83         else
84         {
85                 rcLine.y = startPt.y;
86                 rcLine.height = endPt.y - startPt.y + 1;
87         }
88
89         if (_IsInClipRect(rcLine.x - halfLineW, rcLine.y - halfLineW, rcLine.width + __lineWidth, rcLine.height + __lineWidth, bufInfo))
90         {
91                 _SetNotClipFunction(true);
92                 clip = false;
93         }
94
95         if (__lineWidth == 1)
96         {
97                 if (startPt.x == endPt.x)
98                 {
99                         ret = (this->*pFuncVerticalLine)(startPt.x, startPt.y, endPt.y, bufInfo);
100                 }
101                 else if (startPt.y == endPt.y)
102                 {
103                         ret = (this->*pFuncHorizontalLine)(startPt.x, endPt.x, startPt.y, bufInfo);
104                 }
105                 else
106                 {
107                         ret = _DrawUnitLineSlant(startPt, endPt, bufInfo);
108                 }
109         }
110         else
111         {
112                 if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
113                 {
114                         finalRet = __DrawWideLine(startPt, endPt, bufInfo);
115                 }
116                 else if ((bufInfo.color32 & 0xFF000000) > 0)
117                 {
118                         finalRet = __DrawWideLineWithOpacity32(startPt, endPt, bufInfo);
119                 }
120         }
121
122         if (__lineWidth > 2 && (bufInfo.color32 & 0xFF000000) == 0xFF000000)
123         {
124                 if (__lineWidth > 4)
125                 {
126                         int lineW = __lineWidth;
127
128                         if (lineW % 2 == 0)
129                         {
130                                 halfLineW--;
131                                 lineW--;
132                         }
133
134                         _CanvasEllipse ellipse;
135
136                         ellipse.SetLineWidth(lineW);
137
138                         // Line Round End
139                         if (ellipse.FillElliepse(startPt.x - halfLineW, startPt.y - halfLineW, lineW, lineW, bufInfo) == E_SYSTEM)
140                         {
141                                 SysLog(NID_GRP, "DrawLine: FillElliepse() is failed!\n");
142                                 finalRet = false;
143                         }
144
145                         if (ellipse.FillElliepse(endPt.x - halfLineW, endPt.y - halfLineW, lineW, lineW, bufInfo) == E_SYSTEM)
146                         {
147                                 SysLog(NID_GRP, "DrawLine: FillElliepse() is failed!\n");
148                                 finalRet = false;
149                         }
150                 }
151                 else if (__lineWidth == 4)
152                 {
153                         SetLineWidth(1);
154
155                         (this->*pFuncHorizontalLine)(startPt.x - 1, startPt.x, startPt.y - 2, bufInfo);
156                         (this->*pFuncHorizontalLine)(startPt.x - 2, startPt.x + 1, startPt.y - 1, bufInfo);
157                         (this->*pFuncHorizontalLine)(startPt.x - 2, startPt.x + 1, startPt.y, bufInfo);
158                         (this->*pFuncHorizontalLine)(startPt.x - 1, startPt.x, startPt.y + 1, bufInfo);
159
160                         (this->*pFuncHorizontalLine)(endPt.x - 1, endPt.x, endPt.y - 2, bufInfo);
161                         (this->*pFuncHorizontalLine)(endPt.x - 2, endPt.x + 1, endPt.y - 1, bufInfo);
162                         (this->*pFuncHorizontalLine)(endPt.x - 2, endPt.x + 1, endPt.y, bufInfo);
163                         (this->*pFuncHorizontalLine)(endPt.x - 1, endPt.x, endPt.y + 1, bufInfo);
164
165                         SetLineWidth(4);
166                 }
167                 else    // __lineWidth = 3
168                 {
169                         SetLineWidth(1);
170
171                         (this->*pFuncHorizontalLine)(startPt.x, startPt.x, startPt.y - 1, bufInfo);
172                         (this->*pFuncHorizontalLine)(startPt.x - 1, startPt.x + 1, startPt.y, bufInfo);
173                         (this->*pFuncHorizontalLine)(startPt.x, startPt.x, startPt.y + 1, bufInfo);
174
175                         (this->*pFuncHorizontalLine)(endPt.x, endPt.x, endPt.y - 1, bufInfo);
176                         (this->*pFuncHorizontalLine)(endPt.x - 1, endPt.x + 1, endPt.y, bufInfo);
177                         (this->*pFuncHorizontalLine)(endPt.x, endPt.x, endPt.y + 1, bufInfo);
178
179                         SetLineWidth(3);
180                 }
181         }
182
183         if (!clip)
184         {
185                 _SetClipFunction(true);
186         }
187
188         return ((ret == GP_RESULT_FAIL) && (finalRet == false) ? E_SYSTEM : E_SUCCESS);
189 }
190
191 _GpResult
192 _CanvasLine::_DrawUnitLineVertical(int x, int startY, int endY, const _GpBufferInfo& bufInfo)
193 {
194         Point pt(x, startY);
195
196         if (bufInfo.bitsPerPixel == 32)
197         {
198                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
199
200                 if (pFrmbuf32)
201                 {
202                         if (startY > endY)
203                         {
204                                 GP_SWAP(startY, endY);
205                                 pt.y = startY;
206                         }
207
208                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
209                         {
210                                 while (pt.y < endY)
211                                 {
212                                         pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
213                                         pt.y++;
214                                 }
215                         }
216                         else if ((bufInfo.color32 & 0xFF000000) > 0)
217                         {
218                                 while (pt.y < endY)
219                                 {
220                                         __DrawHorizontalLineWithOpacity32(pt.x, pt.x, pt.y, bufInfo);
221                                         pt.y++;
222                                 }
223                         }
224                 }
225                 else
226                 {
227                         SysLog(NID_GRP, "_DrawUnitLineVertical: pFrmbuf32 is invalid!\n");
228                         return GP_RESULT_FAIL;
229                 }
230         }
231         else
232         {
233                 // To do 16 bpp
234                 SysLog(NID_GRP, "_DrawUnitLineVertical: not support 16 bpp!\n");
235                 return GP_RESULT_FAIL;
236         }
237
238         return GP_RESULT_SUCCESS;
239 }
240
241 _GpResult
242 _CanvasLine::_DrawUnitLineHorizontal(int startX, int endX, int y, const _GpBufferInfo& bufInfo)
243 {
244         Point pt(startX, y);
245
246         if (bufInfo.bitsPerPixel == 32)
247         {
248                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
249
250                 if (pFrmbuf32)
251                 {
252                         if (startX > endX)
253                         {
254                                 GP_SWAP(startX, endX);
255                                 pt.x = startX;
256                         }
257
258                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
259                         {
260                                 while (pt.x <= endX)
261                                 {
262                                         pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
263                                         pt.x++;
264                                 }
265                         }
266                         else if ((bufInfo.color32 & 0xFF000000) > 0)
267                         {
268                                 __DrawHorizontalLineWithOpacity32(pt.x, endX, pt.y, bufInfo);
269                         }
270                 }
271                 else
272                 {
273                         SysLog(NID_GRP, "_DrawUnitLineHorizontal: pFrmbuf32 is null!\n");
274
275                         return GP_RESULT_FAIL;
276                 }
277         }
278         else
279         {
280                 // To do 16 bpp
281                 SysLog(NID_GRP, "_DrawUnitLineHorizontal: not support 16 bpp!\n");
282
283                 return GP_RESULT_FAIL;
284         }
285
286         return GP_RESULT_SUCCESS;
287 }
288
289 _GpResult
290 _CanvasLine::_DrawWideLineVertical(int x, int startY, int endY, const _GpBufferInfo& bufInfo)
291 {
292         int halfLineW;
293         int posX;
294
295         Point pt(x, startY);
296
297         if (bufInfo.bitsPerPixel == 32)
298         {
299                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
300
301                 if (pFrmbuf32)
302                 {
303                         if (startY > endY)
304                         {
305                                 GP_SWAP(startY, endY);
306                                 pt.y = startY;
307                         }
308
309                         halfLineW = __lineWidth >> 1;
310
311                         if (__lineWidth == 1)  //is this part necessary?
312                         {
313                                 if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
314                                 {
315                                         while (pt.y < endY)
316                                         {
317                                                 pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
318                                                 pt.y++;
319                                         }
320                                 }
321                                 else if ((bufInfo.color32 & 0xFF000000) > 0)
322                                 {
323                                         while (pt.y < endY)
324                                         {
325                                                 __DrawHorizontalLineWithOpacity32(pt.x, pt.x, pt.y, bufInfo);
326                                                 pt.y++;
327                                         }
328                                 }
329                         }
330                         else
331                         {
332                                 int realEndX = x + halfLineW;
333
334                                 if (__lineWidth % 2 == 0)
335                                 {
336                                         realEndX--;
337                                 }
338
339                                 if (__lineWidth == 2 && pt.y >= 1)
340                                 {
341                                         pt.y--;
342                                 }
343
344                                 posX = x - halfLineW;
345
346                                 if (x == 0)
347                                 {
348                                         posX = x;
349                                 }
350
351                                 for (; posX <= realEndX; posX++)
352                                 {
353                                         // draw vertical line
354                                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
355                                         {
356                                                 while (pt.y < endY)
357                                                 {
358                                                         pFrmbuf32[bufInfo.pixelPerLine * pt.y + posX] = bufInfo.color32;
359                                                         pt.y++;
360                                                 }
361                                         }
362                                         else if ((bufInfo.color32 & 0xFF000000) > 0)
363                                         {
364                                                 while (pt.y < endY)
365                                                 {
366                                                         __DrawHorizontalLineWithOpacity32(posX, posX, pt.y, bufInfo);
367                                                         pt.y++;
368                                                 }
369                                         }
370
371                                         pt.y = startY;
372                                 }
373                         }
374                 }
375                 else
376                 {
377                         SysLog(NID_GRP, "_DrawWideLineVertical: pFrmbuf32 is invalid!\n");
378
379                         return GP_RESULT_FAIL;
380                 }
381         }
382         else
383         {
384                 // To do 16 bpp
385                 SysLog(NID_GRP, "_DrawWideLineVertical: not support 16 bpp!\n");
386
387                 return GP_RESULT_FAIL;
388         }
389
390         return GP_RESULT_SUCCESS;
391 }
392
393 _GpResult
394 _CanvasLine::_DrawWideLineHorizontal(int startX, int endX, int y, const _GpBufferInfo& bufInfo)
395 {
396         int halfLineW;
397         int posY;
398
399         if (bufInfo.bitsPerPixel == 32)
400         {
401                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
402
403                 if (pFrmbuf32)
404                 {
405                         Point pt(startX, y);
406                         if (startX > endX)
407                         {
408                                 GP_SWAP(startX, endX);
409                                 pt.x = startX;
410                         }
411
412                         //  Calculate half Width of Line
413                         halfLineW = __lineWidth >> 1;
414
415                         if (__lineWidth == 1) // is this part necessary?
416                         {
417                                 // draw primitive line
418                                 if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
419                                 {
420                                         while (pt.x < endX)
421                                         {
422                                                 pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
423                                                 pt.x++;
424                                         }
425                                 }
426                                 else if ((bufInfo.color32 & 0xFF000000) > 0)
427                                 {
428                                         __DrawHorizontalLineWithOpacity32(pt.x, endX, y, bufInfo);
429                                 }
430                         }
431                         else
432                         {
433                                 int realEndY = y + halfLineW;
434
435                                 if (__lineWidth % 2 == 0)
436                                 {
437                                         realEndY--;
438                                 }
439
440                                 if (__lineWidth == 2 && pt.x >= 1)
441                                 {
442                                         pt.x--;
443                                 }
444
445                                 posY = y - halfLineW;
446
447                                 if (y == 0)
448                                 {
449                                         posY = y;
450                                 }
451
452                                 for (; posY <= realEndY; posY++)
453                                 {
454                                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
455                                         {
456                                                 while (pt.x < endX)
457                                                 {
458                                                         pFrmbuf32[bufInfo.pixelPerLine * posY + pt.x] = bufInfo.color32;
459                                                         pt.x++;
460                                                 }
461                                         }
462                                         else if ((bufInfo.color32 & 0xFF000000) > 0)
463                                         {
464                                                 __DrawHorizontalLineWithOpacity32(pt.x, endX, posY, bufInfo);
465                                         }
466
467                                         pt.x = startX;
468                                 }
469                         }
470                 }
471                 else
472                 {
473                         SysLog(NID_GRP, "_DrawWideLineHorizontal: pFrmbuf32 is invalid!\n");
474
475                         return GP_RESULT_FAIL;
476                 }
477         }
478         else
479         {
480                 // To do 16 bpp
481                 SysLog(NID_GRP, "_DrawWideLineHorizontal: not support 16 bpp!\n");
482
483                 return GP_RESULT_FAIL;
484         }
485
486         return GP_RESULT_SUCCESS;
487 }
488
489 _GpResult
490 _CanvasLine::_DrawUnitLineSlant(const _GpPoint& point1, const _GpPoint& point2, const _GpBufferInfo& bufInfo)
491 {
492         int deltaX;
493         int deltaY;
494         int deltaDiff;
495         int inc;
496         int errorInc;
497         int errorIncCount;
498         int absX;
499         int absY;
500
501         if (bufInfo.bitsPerPixel == 32)
502         {
503                 Point startPt(point1.x, point1.y);
504                 Point endPt(point2.x, point2.y);
505
506                 absX = GP_ABS(endPt.x - startPt.x);
507                 absY = GP_ABS(endPt.y - startPt.y);
508
509                 if (absX > absY)
510                 {
511                         if (startPt.x > endPt.x)
512                         {
513                                 GP_SWAP(startPt.x, endPt.x);
514                                 GP_SWAP(startPt.y, endPt.y);
515                         }
516
517                         inc = (endPt.y > startPt.y) ? 1 : -1;
518                         deltaX = endPt.x - startPt.x;
519                         deltaY = GP_ABS(endPt.y - startPt.y);
520                         deltaDiff = (deltaY << 1) - deltaX;
521                         errorInc = (deltaY << 1);
522                         errorIncCount = (deltaY - deltaX) << 1;
523
524                         Point pt(startPt.x, startPt.y);
525
526                         (this->*pFuncSetPixel)(startPt.x, startPt.y, bufInfo);
527
528                         while (pt.x < endPt.x)
529                         {
530                                 pt.x++;
531
532                                 if (deltaDiff > 0)
533                                 {
534                                         pt.y += inc;
535                                         deltaDiff += errorIncCount;
536                                 }
537                                 else
538                                 {
539                                         deltaDiff += errorInc;
540                                 }
541
542                                 (this->*pFuncSetPixel)(pt.x, pt.y, bufInfo);
543                         }
544                 }
545                 else
546                 {
547                         if (startPt.y > endPt.y)
548                         {
549                                 GP_SWAP(startPt.x, endPt.x);
550                                 GP_SWAP(startPt.y, endPt.y);
551                         }
552
553                         inc = (endPt.x > startPt.x) ? 1 : -1;
554                         deltaX = GP_ABS(endPt.x - startPt.x);
555                         deltaY = endPt.y - startPt.y;
556                         deltaDiff = (deltaX << 1) - deltaY;
557                         errorInc = (deltaX << 1);
558                         errorIncCount = (deltaX - deltaY) << 1;
559
560                         Point pt(startPt.x, startPt.y);
561
562                         (this->*pFuncSetPixel)(startPt.x, startPt.y, bufInfo);
563
564                         while (pt.y < endPt.y)
565                         {
566                                 pt.y++;
567
568                                 if (deltaDiff > 0)
569                                 {
570                                         pt.x += inc;
571                                         deltaDiff += errorIncCount;
572                                 }
573                                 else
574                                 {
575                                         deltaDiff += errorInc;
576                                 }
577
578                                 (this->*pFuncSetPixel)(pt.x, pt.y, bufInfo);
579                         }
580                 }
581         }
582         else
583         {
584                 // To do 16 bpp
585                 return GP_RESULT_FAIL;
586         }
587
588         return GP_RESULT_SUCCESS;
589 }
590
591 _GpResult
592 _CanvasLine::_DrawPixel(int x, int y, const _GpBufferInfo& bufInfo)
593 {
594         if (bufInfo.bitsPerPixel == 32)
595         {
596                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
597
598                 if (pFrmbuf32)
599                 {
600                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
601                         {
602                                 pFrmbuf32[bufInfo.pixelPerLine * y + x] = bufInfo.color32;
603                         }
604                         else if ((bufInfo.color32 & 0xFF000000) > 0)
605                         {
606                                 __DrawHorizontalLineWithOpacity32(x, x, y, bufInfo);
607                         }
608                 }
609                 else
610                 {
611                         SysLog(NID_GRP, "_DrawPixel: pFrmbuf32 is null!\n");
612
613                         return GP_RESULT_FAIL;
614                 }
615         }
616         else
617         {
618                 // To do 16 bpp
619                 SysLog(NID_GRP, "_DrawPixel: not support 16 bpp!\n");
620
621                 return GP_RESULT_FAIL;
622         }
623
624         return GP_RESULT_SUCCESS;
625 }
626
627 _GpResult
628 _CanvasLine::_DrawUnitLineVerticalWithClipping(int x, int startY, int endY, const _GpBufferInfo& bufInfo)
629 {
630         Point pt(x, startY);
631
632         if (bufInfo.bitsPerPixel == 32)
633         {
634                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
635
636                 if (pFrmbuf32)
637                 {
638                         if (startY > endY)
639                         {
640                                 GP_SWAP(startY, endY);
641                                 pt.y = startY;
642                         }
643
644                         if (bufInfo.isClipBoundsSet)
645                         {
646                                 if (pt.x < bufInfo.clipBounds.x || pt.x > bufInfo.clipBounds.x + bufInfo.clipBounds.width - 1)
647                                 {
648                                         return GP_RESULT_OUTOFBOUNDS;
649                                 }
650
651                                 if (pt.y > bufInfo.clipBounds.y + bufInfo.clipBounds.height - 1 || endY < bufInfo.clipBounds.y)
652                                 {
653                                         return GP_RESULT_OUTOFBOUNDS;
654                                 }
655
656                                 if (pt.y < bufInfo.clipBounds.y)
657                                 {
658                                         pt.y = bufInfo.clipBounds.y;
659                                 }
660
661                                 if (endY > bufInfo.clipBounds.y + bufInfo.clipBounds.height - 1)
662                                 {
663                                         endY = bufInfo.clipBounds.y + bufInfo.clipBounds.height - 1;
664                                 }
665                         }
666                         else
667                         {
668                                 if (pt.x < 0 || pt.x > bufInfo.width - 1)
669                                 {
670                                         return GP_RESULT_OUTOFBOUNDS;
671                                 }
672
673                                 if (endY < 0 || pt.y > bufInfo.height - 1)
674                                 {
675                                         return GP_RESULT_OUTOFBOUNDS;
676                                 }
677
678                                 if (pt.y < 0)
679                                 {
680                                         pt.y = 0;
681                                 }
682
683                                 if (endY > bufInfo.height - 1)
684                                 {
685                                         endY = bufInfo.height - 1;
686                                 }
687
688                                 if ((endY - pt.y) == 0)
689                                 {
690                                         return GP_RESULT_OUTOFBOUNDS;
691                                 }
692
693                                 if (pt.x == bufInfo.width)
694                                 {
695                                         pt.x--;
696                                 }
697                         }
698
699                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
700                         {
701                                 while (pt.y < endY)
702                                 {
703                                         pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
704                                         pt.y++;
705                                 }
706                         }
707                         else if ((bufInfo.color32 & 0xFF000000) > 0)
708                         {
709                                 while (pt.y < endY)
710                                 {
711                                         __DrawHorizontalLineWithOpacity32(pt.x, pt.x, pt.y, bufInfo);
712                                         pt.y++;
713                                 }
714                         }
715                 }
716                 else
717                 {
718                         SysLog(NID_GRP, "_DrawUnitLineVerticalWithClipping: pFrmbuf32 is invalid!\n");
719
720                         return GP_RESULT_FAIL;
721                 }
722         }
723         else
724         {
725                 // To do 16 bpp
726                 SysLog(NID_GRP, "_DrawUnitLineVerticalWithClipping: not support 16 bpp!\n");
727
728                 return GP_RESULT_FAIL;
729         }
730
731         return GP_RESULT_SUCCESS;
732 }
733
734 _GpResult
735 _CanvasLine::_DrawUnitLineHorizontalWithClipping(int startX, int endX, int y, const _GpBufferInfo& bufInfo)
736 {
737         Point pt(startX, y);
738
739         if (bufInfo.bitsPerPixel == 32)
740         {
741                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
742
743                 if (pFrmbuf32)
744                 {
745                         if (startX > endX)
746                         {
747                                 GP_SWAP(startX, endX);
748                                 pt.x = startX;
749                         }
750
751                         if (bufInfo.isClipBoundsSet)
752                         {
753                                 if (pt.y < bufInfo.clipBounds.y || pt.y > bufInfo.clipBounds.y + bufInfo.clipBounds.height - 1)
754                                 {
755                                         return GP_RESULT_OUTOFBOUNDS;
756                                 }
757
758                                 if (pt.x > bufInfo.clipBounds.x + bufInfo.clipBounds.width - 1 || endX < bufInfo.clipBounds.x)
759                                 {
760                                         return GP_RESULT_OUTOFBOUNDS;
761                                 }
762
763                                 if (pt.x < bufInfo.clipBounds.x)
764                                 {
765                                         pt.x = bufInfo.clipBounds.x;
766                                 }
767
768                                 if (endX > bufInfo.clipBounds.x + bufInfo.clipBounds.width - 1)
769                                 {
770                                         endX = bufInfo.clipBounds.x + bufInfo.clipBounds.width - 1;
771                                 }
772                         }
773                         else
774                         {
775                                 if (pt.y < 0 || pt.y > bufInfo.height - 1)
776                                 {
777                                         return GP_RESULT_OUTOFBOUNDS;
778                                 }
779
780                                 if (endX < 0 || pt.x > bufInfo.width - 1)
781                                 {
782                                         return GP_RESULT_OUTOFBOUNDS;
783                                 }
784
785                                 if (pt.x < 0)
786                                 {
787                                         pt.x = 0;
788                                 }
789
790                                 if (endX > bufInfo.width - 1)
791                                 {
792                                         endX = bufInfo.width - 1;
793                                 }
794
795                                 if ((endX - pt.x) == 0)
796                                 {
797                                         return GP_RESULT_OUTOFBOUNDS;
798                                 }
799
800                                 if (pt.y == bufInfo.height)
801                                 {
802                                         pt.y--;
803                                 }
804                         }
805
806                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
807                         {
808                                 while (pt.x <= endX)
809                                 {
810                                         pFrmbuf32[bufInfo.pixelPerLine * pt.y + pt.x] = bufInfo.color32;
811                                         pt.x++;
812                                 }
813                         }
814                         else if ((bufInfo.color32 & 0xFF000000) > 0)
815                         {
816                                 __DrawHorizontalLineWithOpacity32(pt.x, endX, pt.y, bufInfo);
817                         }
818                 }
819                 else
820                 {
821                         SysLog(NID_GRP, "_DrawUnitLineHorizontalWithClipping: pFrmbuf32 is null!\n");
822
823                         return GP_RESULT_FAIL;
824                 }
825         }
826         else
827         {
828                 // To do 16 bpp
829                 SysLog(NID_GRP, "_DrawUnitLineHorizontalWithClipping: not support 16 bpp!\n");
830
831                 return GP_RESULT_FAIL;
832         }
833
834         return GP_RESULT_SUCCESS;
835 }
836
837 _GpResult
838 _CanvasLine::_DrawWideLineVerticalWithClipping(int x, int startY, int endY, const _GpBufferInfo& bufInfo)
839 {
840         int halfLineW;
841         int posX;
842
843         halfLineW = __lineWidth >> 1;
844
845         if (__lineWidth == 1)
846         {
847                 if (_DrawUnitLineVerticalWithClipping(x, startY, endY, bufInfo) == GP_RESULT_FAIL)
848                 {
849                         SysLog(NID_GRP, "_DrawUnitLineVerticalWithClipping: _DrawUnitLineVerticalWithClipping() is failed!\n");
850
851                         return GP_RESULT_FAIL;
852                 }
853         }
854         else
855         {
856                 int realEndX = x + halfLineW;
857
858                 if (__lineWidth % 2 == 0)
859                 {
860                         realEndX--;
861                 }
862
863 /* bjcho : For fixing y coordinate when the line width is 2 pixel.
864         if (lineW == 2)
865             y1--;
866 */
867
868                 for (posX = x - halfLineW; posX <= realEndX; posX++)
869                 {
870                         if (_DrawUnitLineVerticalWithClipping(posX, startY, endY, bufInfo) == GP_RESULT_FAIL)
871                         {
872                                 SysLog(NID_GRP, "_DrawUnitLineVerticalWithClipping: _DrawUnitLineVerticalWithClipping() is failed!\n");
873
874                                 return GP_RESULT_FAIL;
875                         }
876                 }
877         }
878
879         return GP_RESULT_SUCCESS;
880 }
881
882 _GpResult
883 _CanvasLine::_DrawWideLineHorizontalWithClipping(int startX, int endX, int y, const _GpBufferInfo& bufInfo)
884 {
885         int halfLineW;
886         int posY;
887
888         // Calculate half Width of Line
889         halfLineW = __lineWidth >> 1;
890
891         // Insert Clipping
892         if (__lineWidth == 1)
893         {
894                 if (_DrawUnitLineHorizontalWithClipping(startX, endX, y, bufInfo) == GP_RESULT_FAIL)
895                 {
896                         SysLog(NID_GRP, "_DrawUnitLineHorizontalWithClipping: _DrawUnitLineHorizontalWithClipping() is failed!\n");
897
898                         return GP_RESULT_FAIL;
899                 }
900         }
901         else
902         {
903                 int realEndY = y + halfLineW;
904
905                 if (__lineWidth % 2 == 0)
906                 {
907                         realEndY--;
908                 }
909
910
911                 // if (lineW == 2)
912                 //      x1--;
913
914
915                 for (posY = y - halfLineW; posY <= realEndY; posY++)
916                 {
917                         if (_DrawUnitLineHorizontalWithClipping(startX, endX, posY, bufInfo) == GP_RESULT_FAIL)
918                         {
919                                 SysLog(NID_GRP, "_DrawUnitLineHorizontalWithClipping: _DrawUnitLineHorizontalWithClipping() is failed!\n");
920
921                                 return GP_RESULT_FAIL;
922                         }
923                 }
924         }
925
926         return GP_RESULT_SUCCESS;
927 }
928
929 _GpResult
930 _CanvasLine::_DrawPixelWithClipping(int x, int y, const _GpBufferInfo& bufInfo)
931 {
932         if (bufInfo.bitsPerPixel == 32)
933         {
934                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
935
936                 if (pFrmbuf32)
937                 {
938                         if (bufInfo.isClipBoundsSet)
939                         {
940                                 if (x < bufInfo.clipBounds.x || x >= bufInfo.clipBounds.x + bufInfo.clipBounds.width)
941                                 {
942                                         return GP_RESULT_OUTOFBOUNDS;
943                                 }
944
945                                 if (y < bufInfo.clipBounds.y || y >= bufInfo.clipBounds.y + bufInfo.clipBounds.height)
946                                 {
947                                         return GP_RESULT_OUTOFBOUNDS;
948                                 }
949                         }
950                         else
951                         {
952                                 if (x < 0 || x >= bufInfo.width)
953                                 {
954                                         return GP_RESULT_OUTOFBOUNDS;
955                                 }
956
957                                 if (y < 0 || y >= bufInfo.height)
958                                 {
959                                         return GP_RESULT_OUTOFBOUNDS;
960                                 }
961                         }
962
963                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
964                         {
965                                 pFrmbuf32[bufInfo.pixelPerLine * y + x] = bufInfo.color32;
966                         }
967                         else if ((bufInfo.color32 & 0xFF000000) > 0)
968                         {
969                                 __DrawHorizontalLineWithOpacity32(x, x, y, bufInfo);
970                         }
971                 }
972                 else
973                 {
974                         SysLog(NID_GRP, "_DrawPixelWithClipping: pFrmbuf32 is null!\n");
975
976                         return GP_RESULT_FAIL;
977                 }
978         }
979         else
980         {
981                 // To do 16 bpp
982                 SysLog(NID_GRP, "_DrawPixelWithClipping: not support 16 bpp!\n");
983
984                 return GP_RESULT_FAIL;
985         }
986
987         return GP_RESULT_SUCCESS;
988 }
989
990 bool
991 _CanvasLine::__DrawWideLine(const _GpPoint& startPt, const _GpPoint& endPt, const _GpBufferInfo& bufInfo)
992 {
993         _GpResult result = GP_RESULT_FAIL;
994         bool ret = false;
995         int halfLineW = __lineWidth >> 1;
996
997         if (startPt.x == endPt.x && startPt.y == endPt.y)
998         {
999                 if (bufInfo.bitsPerPixel == 32)
1000                 {
1001                         _CanvasEllipse ellipse;
1002
1003                         ellipse.SetLineWidth(__lineWidth);
1004
1005                         if (ellipse.FillElliepse(startPt.x - halfLineW, startPt.y - halfLineW, __lineWidth, __lineWidth, bufInfo) == E_SUCCESS)
1006                         {
1007                                 ret = true;
1008                         }
1009                 }
1010         }
1011         else
1012         {
1013                 ret = __DrawWideLineWithOpacity32(startPt, endPt, bufInfo);
1014                 //ret = _DrawUnitLineSlant(startPt, endPt, bufInfo); // need to check if slantline drawing is slow..
1015         }
1016
1017         return (result == GP_RESULT_FAIL && ret == false && E_SYSTEM ? false : true);
1018 }
1019
1020 bool
1021 _CanvasLine::__DrawWideLineWithOpacity32(const _GpPoint& startPt, const _GpPoint& endPt, const _GpBufferInfo& bufInfo)
1022 {
1023         bool ret = false;
1024         _GpPoint points[2] =
1025         {
1026                 { startPt.x, startPt.y },
1027                 { endPt.x, endPt.y }
1028         };
1029
1030         ret = __DrawThickContinuousPolyline(2, points, false, bufInfo);
1031
1032         return ret;
1033 }
1034
1035 bool
1036 _CanvasLine::__DrawThickContinuousPolyline(int listCount, _GpPoint* pPoints, bool isConnected, const _GpBufferInfo& bufInfo)
1037 {
1038         int i;
1039         int j;
1040         float connectedX = 0.0f;
1041         float connectedY = 0.0f;
1042         float sox = 0;
1043         float soy = 0;
1044         _GpVertex* pVertex = null;
1045         _GpPoint* pTempPoints = null;
1046         bool ret = false;
1047
1048         if (listCount < 2)
1049         {
1050                 return false;
1051         }
1052
1053         _GpPolygon* pPolygon = new (std::nothrow) _GpPolygon;
1054
1055         if (pPolygon == null)
1056         {
1057                 return false;
1058         }
1059
1060         if (isConnected)
1061         {
1062                 int plx;
1063                 int ply;
1064                 int prx;
1065                 int pry;
1066
1067                 _GetOrientationUnitVector(pPoints[listCount - 1], pPoints[0], &connectedX, &connectedY);
1068
1069                 sox = connectedX;
1070                 soy = connectedY;
1071
1072                 __GetBrushEndPoint(sox, soy, __lineWidth, &plx, &ply, &prx, &pry);
1073
1074                 if (!_AddPolygonVertex(pPolygon, pPoints[0].x + plx, pPoints[0].y + ply, 0))
1075                 {
1076                         _FreePolygon(pPolygon);
1077
1078                         return false;
1079                 }
1080
1081                 if (!_AddPolygonVertex(pPolygon, pPoints[0].x + prx, pPoints[0].y + pry, 1))
1082                 {
1083                         _FreePolygon(pPolygon);
1084
1085                         return false;
1086                 }
1087
1088         }
1089
1090         for (i = 1; i < listCount; i++)
1091         {
1092                 j = i - 1;
1093
1094                 float ox;
1095                 float oy;
1096
1097                 _GetOrientationUnitVector(pPoints[j], pPoints[i], &ox, &oy);
1098
1099                 if (j == 0 && !isConnected)
1100                 {
1101                         if (!_PatchRoundCap(pPolygon, pPoints[0].x, pPoints[0].y, ox, oy, true))
1102                         {
1103                                 _FreePolygon(pPolygon);
1104
1105                                 return false;
1106                         }
1107                 }
1108                 else
1109                 {
1110                         if (!_PatchJoint(pPolygon, pPoints[j].x, pPoints[j].y, connectedX, connectedY, ox, oy))
1111                         {
1112                                 _FreePolygon(pPolygon);
1113
1114                                 return false;
1115                         }
1116                 }
1117
1118                 ret = _PatchThickContinuousLine(pPolygon, pPoints[j], pPoints[i], ox, oy, 0, 0);
1119
1120                 if (!ret)
1121                 {
1122                         _FreePolygon(pPolygon);
1123
1124                         return ret;
1125                 }
1126
1127                 connectedX = ox;
1128                 connectedY = oy;
1129         }
1130
1131         if (isConnected)
1132         {
1133                 if (!_PatchJoint(pPolygon, pPoints[listCount - 1].x, pPoints[listCount - 1].y, connectedX, connectedY, sox, soy))
1134                 {
1135                         _FreePolygon(pPolygon);
1136
1137                         return false;
1138                 }
1139
1140                 if (!_PatchThickContinuousLine(pPolygon, pPoints[listCount - 1], pPoints[0], sox, soy, 0, 0))
1141                 {
1142                         _FreePolygon(pPolygon);
1143
1144                         return false;
1145                 }
1146         }
1147         else
1148         {
1149                 //j = num - 1;
1150                 if (!_PatchRoundCap(pPolygon, pPoints[listCount - 1].x, pPoints[listCount - 1].y, connectedX, connectedY, false))
1151                 {
1152                         _FreePolygon(pPolygon);
1153
1154                         return false;
1155                 }
1156         }
1157
1158         pTempPoints = new (std::nothrow) _GpPoint[pPolygon->n];
1159
1160         if (pTempPoints == null)
1161         {
1162                 _FreePolygon(pPolygon);
1163
1164                 return ret;
1165         }
1166
1167         for (i = 0, pVertex = pPolygon->pFirst; pVertex != null; i++, pVertex = pVertex->pNext)
1168         {
1169                 pTempPoints[i] = pVertex->point;
1170         }
1171
1172         _FillPolygon(pPolygon->n, pTempPoints, false, bufInfo);
1173
1174         _FreePolygon(pPolygon);
1175
1176         delete[] pTempPoints;
1177
1178         return ret;
1179 }
1180
1181 result
1182 _CanvasLine::DrawPolyLine(int ptCount, _GpPoint* pPoints, const _GpBufferInfo& bufInfo)
1183 {
1184         bool ret = false;
1185
1186         if (ptCount < 2)
1187         {
1188                 return E_SYSTEM;
1189         }
1190
1191         ret = _DrawPolyLine(ptCount, pPoints, false, bufInfo);
1192
1193         return (ret ? E_SUCCESS : E_SYSTEM);
1194 }
1195
1196 result
1197 _CanvasLine::DrawPolygon(int ptCount, _GpPoint* pPoints, const _GpBufferInfo& bufInfo)
1198 {
1199         bool ret = false;
1200
1201         if (ptCount < 2)
1202         {
1203                 return E_SYSTEM;
1204         }
1205
1206         ret = _DrawPolyLine(ptCount, pPoints, true, bufInfo);
1207
1208         return (ret ? E_SUCCESS : E_SYSTEM);
1209 }
1210
1211 int
1212 _CanvasLine::__CheckDupVertexForPolygon(int ptCount, _GpPoint* pPoints, bool isConnected) const
1213 {
1214         int i = 0;
1215         int j = 0;
1216
1217         while (j < ptCount - 1)
1218         {
1219                 if (pPoints[j].x == pPoints[j + 1].x && pPoints[j].y == pPoints[j + 1].y)
1220                 {
1221                         ++j;
1222                         continue;
1223                 }
1224
1225                 if (i < j)
1226                 {
1227                         pPoints[i] = pPoints[j];
1228                 }
1229
1230                 ++i;
1231                 ++j;
1232         }
1233
1234         if (isConnected)
1235         {
1236                 if (pPoints[ptCount - 1].x != pPoints[0].x || pPoints[ptCount - 1].y != pPoints[0].y)
1237                 {
1238                         pPoints[i] = pPoints[ptCount - 1];
1239                         ++i;
1240                 }
1241         }
1242         else
1243         {
1244                 pPoints[i] = pPoints[ptCount - 1];
1245                 ++i;
1246         }
1247
1248         return i;
1249 }
1250
1251 void
1252 _CanvasLine::_FreePolygon(_GpPolygon* pPolygon) const
1253 {
1254         _GpVertex* pVertex = null;
1255         _GpVertex* pNext = null;
1256
1257         if (pPolygon == null)
1258         {
1259                 SysLog(NID_GRP, "_FreePolygon: pPolygon is null !\n");
1260
1261                 return;
1262         }
1263
1264         pVertex = pPolygon->pFirst;
1265
1266         while (pVertex != null)
1267         {
1268                 pNext = pVertex->pNext;
1269                 delete pVertex;
1270                 pVertex = pNext;
1271         }
1272
1273         delete pPolygon;
1274
1275         return;
1276 }
1277
1278 bool
1279 _CanvasLine::_FillPolygon(int ptCount, _GpPoint* pPoints, bool isEvenOdd, const _GpBufferInfo& bufInfo)
1280 {
1281         _GpEdgeTable edgeTable;
1282         _GpEdgeTableEntry anEdgeTableEntry;
1283         _GpEdgeTableEntry* pPrevAet = null;
1284         _GpEdgeTableEntry* pAet = null;
1285         _GpEdgeTableEntry* pWete = null;
1286         _GpScanLineListBlock scanLineListBlock;
1287         _GpScanLineList* pScanLineList = null;
1288         _GpEdgeTableEntry* pBufEte = null;
1289         int y;
1290         int stitch = 1;
1291         int fixWAet = 0;
1292
1293         if (pPoints == null)
1294         {
1295                 SysLog(NID_GRP, "_FillPolygon: pPoints is null!\n");
1296
1297                 return false;
1298         }
1299
1300         memset(&edgeTable, 0, sizeof(edgeTable));
1301         memset(&anEdgeTableEntry, 0, sizeof(anEdgeTableEntry));
1302         memset(&scanLineListBlock, 0, sizeof(scanLineListBlock));
1303
1304         pBufEte = new (std::nothrow) _GpEdgeTableEntry[ptCount];
1305
1306         if (pBufEte == null)
1307         {
1308                 return false;
1309         }
1310
1311         if (!_CreateEtAndAet(ptCount, pPoints, &edgeTable, &anEdgeTableEntry, pBufEte, &scanLineListBlock))
1312         {
1313                 delete[] pBufEte;
1314
1315                 return false;
1316         }
1317
1318         pScanLineList = edgeTable.scanLines.pNext;
1319
1320         if (isEvenOdd)
1321         {
1322         }
1323         else
1324         {
1325                 for (y = edgeTable.minY; y < edgeTable.maxY + stitch; y++)
1326                 {
1327                         if (pScanLineList != null && y == pScanLineList->scanLine)
1328                         {
1329                                 _LoadAet(&anEdgeTableEntry, pScanLineList->pEdgeList);
1330                                 _ComputeWaet(&anEdgeTableEntry);
1331                                 pScanLineList = pScanLineList->pNext;
1332                         }
1333
1334                         pPrevAet = &anEdgeTableEntry;
1335                         pAet = anEdgeTableEntry.pNext;
1336                         pWete = pAet;
1337
1338                         while (pAet)
1339                         {
1340                                 if (pWete == pAet)
1341                                 {
1342                                         if (_DrawUnitLineHorizontalWithClipping(pAet->minor, pAet->pWNext->minor + stitch - 1, y, bufInfo) == GP_RESULT_FAIL)
1343                                         {
1344                                                 delete[] pBufEte;
1345                                                 _FreeSllb(scanLineListBlock.pNext);
1346
1347                                                 return false;
1348                                         }
1349
1350                                         pWete = pWete->pWNext;
1351                                         while (pWete != pAet)
1352                                         {
1353                                                 //SysAssert(pAet);
1354                                                 if (pAet == null)
1355                                                 {
1356                                                         break;
1357                                                 }
1358
1359                                                 // 1st
1360                                                 if (pAet->maxY == y)
1361                                                 {
1362                                                         pPrevAet->pNext = pAet->pNext;
1363                                                         pAet = pPrevAet->pNext;
1364                                                         fixWAet = 1;
1365
1366                                                         if (pAet)
1367                                                         {
1368                                                                 pAet->pBack = pPrevAet;
1369                                                         }
1370                                                 }
1371                                                 else
1372                                                 {
1373                                                         if (pAet->gradient1 > 0)
1374                                                         {
1375                                                                 if (pAet->direction > 0)
1376                                                                 {
1377                                                                         pAet->minor += pAet->gradient1;
1378                                                                         pAet->direction += pAet->inc1;
1379                                                                 }
1380                                                                 else
1381                                                                 {
1382                                                                         pAet->minor += pAet->gradient;
1383                                                                         pAet->direction += pAet->inc2;
1384                                                                 }
1385                                                         }
1386                                                         else
1387                                                         {
1388                                                                 if (pAet->direction >= 0)
1389                                                                 {
1390                                                                         pAet->minor += pAet->gradient1;
1391                                                                         pAet->direction += pAet->inc1;
1392                                                                 }
1393                                                                 else
1394                                                                 {
1395                                                                         pAet->minor += pAet->gradient;
1396                                                                         pAet->direction += pAet->inc2;
1397                                                                 }
1398                                                         }
1399                                                         pPrevAet = pAet;
1400                                                         pAet = pAet->pNext;
1401                                                 }
1402                                         }
1403                                         pWete = pWete->pWNext;
1404                                 }
1405
1406                                 //SysAssert(pAet);
1407
1408                                 if (pAet == null)
1409                                 {
1410                                         break;
1411                                 }
1412
1413                                 // 2nd
1414                                 if (pAet->maxY == y)
1415                                 {
1416                                         pPrevAet->pNext = pAet->pNext;
1417                                         pAet = pPrevAet->pNext;
1418                                         fixWAet = 1;
1419                                         if (pAet)
1420                                         {
1421                                                 pAet->pBack = pPrevAet;
1422                                         }
1423                                 }
1424                                 else
1425                                 {
1426                                         if (pAet->gradient1 > 0)
1427                                         {
1428                                                 if (pAet->direction > 0)
1429                                                 {
1430                                                         pAet->minor += pAet->gradient1;
1431                                                         pAet->direction += pAet->inc1;
1432                                                 }
1433                                                 else
1434                                                 {
1435                                                         pAet->minor += pAet->gradient;
1436                                                         pAet->direction += pAet->inc2;
1437                                                 }
1438                                         }
1439                                         else
1440                                         {
1441                                                 if (pAet->direction >= 0)
1442                                                 {
1443                                                         pAet->minor += pAet->gradient1;
1444                                                         pAet->direction += pAet->inc1;
1445                                                 }
1446                                                 else
1447                                                 {
1448                                                         pAet->minor += pAet->gradient;
1449                                                         pAet->direction += pAet->inc2;
1450                                                 }
1451                                         }
1452                                         pPrevAet = pAet;
1453                                         pAet = pAet->pNext;
1454                                 }
1455                         }
1456
1457                         if ((_InsertionSort(&anEdgeTableEntry)) || fixWAet)
1458                         {
1459                                 _ComputeWaet(&anEdgeTableEntry);
1460                                 fixWAet = 0;
1461                         }
1462                 }
1463         }
1464
1465         delete[] pBufEte;
1466         _FreeSllb(scanLineListBlock.pNext);
1467
1468         return true;
1469 }
1470
1471 bool
1472 _CanvasLine::_GetOrientationUnitVector(_GpPoint& startPt, _GpPoint& endPt, float* pOx, float* pOy) const
1473 {
1474         float len;
1475
1476         if (pOx == null || pOy == null)
1477         {
1478                 return false;
1479         }
1480
1481         *pOx = (float) (endPt.x - startPt.x);
1482         *pOy = (float) (endPt.y - startPt.y);
1483
1484         // need to check how to use the math func
1485         len = (float) sqrt((*pOx) * (*pOx) + (*pOy) * (*pOy));
1486
1487         if (len < 1)
1488         {
1489                 return false;
1490         }
1491
1492         *pOx = *pOx / len;
1493         *pOy = *pOy / len;
1494
1495         return true;
1496 }
1497
1498 bool
1499 _CanvasLine::_PatchThickContinuousLine(_GpPolygon* pPolygon, _GpPoint& point1, _GpPoint& point2, float ox1, float oy1, float ox2, float oy2) const
1500 {
1501         int plx;
1502         int ply;
1503         int prx;
1504         int pry;
1505         bool ret = false;
1506
1507         if (pPolygon == null)
1508         {
1509                 return false;
1510         }
1511
1512         __GetBrushEndPoint(ox1, oy1, __lineWidth, &plx, &ply, &prx, &pry);
1513
1514         ret = _AddPolygonVertex(pPolygon, point1.x + plx, point1.y + ply, 0);
1515
1516         if (!ret)
1517         {
1518                 return ret;
1519         }
1520
1521         ret = _AddPolygonVertex(pPolygon, point1.x + prx, point1.y + pry, 1);
1522
1523         if (!ret)
1524         {
1525                 return ret;
1526         }
1527
1528         // if (ox2 != 0 || oy2 != 0)
1529         if ((!_IsEqual(ox2, 0.0f)) || (!_IsEqual(oy2, 0.0f)))
1530         {
1531                 __GetBrushEndPoint(ox2, oy2, __lineWidth, &plx, &ply, &prx, &pry);
1532         }
1533
1534         ret = _AddPolygonVertex(pPolygon, point2.x + plx, point2.y + ply, 0);
1535
1536         if (!ret)
1537         {
1538                 return ret;
1539         }
1540
1541         ret = _AddPolygonVertex(pPolygon, point2.x + prx, point2.y + pry, 1);
1542
1543         if (!ret)
1544         {
1545                 return ret;
1546         }
1547
1548         return true;
1549 }
1550
1551 bool
1552 _CanvasLine::_AddPolygonVertex(_GpPolygon* pPolygon, int x, int y, int pos) const
1553 {
1554         if (pPolygon == null)
1555         {
1556                 return false;
1557         }
1558
1559         _GpVertex* pNewVertex = new (std::nothrow) _GpVertex;
1560
1561         if (pNewVertex == null)
1562         {
1563                 return false;
1564         }
1565
1566         pNewVertex->point.x = x;
1567         pNewVertex->point.y = y;
1568
1569         if (pPolygon->n == 0)
1570         {
1571                 pNewVertex->pNext = null;
1572                 pPolygon->pFirst = pPolygon->pLast = pNewVertex;
1573                 pPolygon->n = 1;
1574
1575                 return true;
1576         }
1577
1578         if (pos == 0)
1579         {
1580                 pNewVertex->pNext = pPolygon->pFirst;
1581                 pPolygon->pFirst = pNewVertex;
1582                 pPolygon->n++;
1583         }
1584         else
1585         {
1586                 pNewVertex->pNext = null;
1587                 pPolygon->pLast->pNext = pNewVertex;
1588                 pPolygon->pLast = pNewVertex;
1589                 pPolygon->n++;
1590         }
1591
1592         return true;
1593 }
1594
1595
1596 void
1597 _CanvasLine::__GetBrushEndPoint(float ox, float oy, int w, int* pLeftX, int* pLeftY, int* pRightX, int* pRightY) const
1598 {
1599         float wl;
1600         float wr;
1601
1602         if (w % 2 == 1)
1603         {
1604                 wl = wr = w / 2.f - 0.001f;
1605         }
1606         else
1607         {
1608                 wl = wr = (w + 1) / 2.f - 0.001f;
1609                 wr -= 1.f;
1610         }
1611
1612         // if (oy == 0.0f && (ox == 1.0f || ox == -1.0f)) // Improve a line-width problem.
1613         if (_IsEqual(oy, 0.0f) && (_IsEqual(ox, 1.0f) || _IsEqual(ox, -1.0f)))
1614         {
1615                 wr += 1.0f; //!!
1616         }
1617
1618         *pLeftX = (int) (wl * oy);
1619         *pLeftY = (int) (-wl * ox);
1620
1621         *pRightX = (int) (-wr * oy);
1622         *pRightY = (int) (wr * ox);
1623
1624         return;
1625 }
1626
1627 bool
1628 _CanvasLine::_CreateEtAndAet(int ptCount, _GpPoint* pPoints, _GpEdgeTable* pEdgeTable, _GpEdgeTableEntry* pEdgeTableEntry, _GpEdgeTableEntry* pEteBuffer, _GpScanLineListBlock* pSllb) const
1629 {
1630         _GpPoint* pTop = null;
1631         _GpPoint* pBottom = null;
1632         _GpPoint* pPrevPoint = null;
1633         _GpPoint* pCurrPoint = null;
1634         int isllb = 0;
1635         int dx;
1636         int dy;
1637         int i;
1638
1639         if (ptCount < 2)
1640         {
1641                 return true;
1642         }
1643
1644         pEdgeTableEntry->pNext = null;
1645         pEdgeTableEntry->pBack = null;
1646         pEdgeTableEntry->pWNext = null;
1647         pEdgeTableEntry->minor = _MIN_INT;
1648
1649         pEdgeTable->scanLines.pNext = null;
1650         pEdgeTable->maxY = _MIN_INT;
1651         pEdgeTable->minY = _MAX_INT;
1652         pSllb->pNext = null;
1653
1654         pPrevPoint = &pPoints[ptCount - 1];
1655
1656         for (i = 0; i < ptCount; i++)
1657         {
1658                 if (pEdgeTable->maxY < pPoints[i].y)
1659                 {
1660                         pEdgeTable->maxY = pPoints[i].y;
1661                 }
1662                 if (pEdgeTable->minY > pPoints[i].y)
1663                 {
1664                         pEdgeTable->minY = pPoints[i].y;
1665                 }
1666         }
1667
1668         while (ptCount--)
1669         {
1670                 pCurrPoint = pPoints++;
1671
1672                 if (pPrevPoint->y > pCurrPoint->y)
1673                 {
1674                         pBottom = pPrevPoint;
1675                         pTop = pCurrPoint;
1676                         pEteBuffer->clockWise = false;
1677                 }
1678                 else
1679                 {
1680                         pBottom = pCurrPoint;
1681                         pTop = pPrevPoint;
1682                         pEteBuffer->clockWise = true;
1683                 }
1684
1685                 if (pBottom->y != pTop->y)
1686                 {
1687                         pEteBuffer->maxY = pBottom->y;
1688
1689                         if (pEteBuffer->maxY <= pEdgeTable->maxY)
1690                         {
1691                                 pEteBuffer->maxY--; // exclude the last scan line
1692                         }
1693
1694                         dy = pBottom->y - pTop->y;
1695                         pEteBuffer->minor = pTop->x;
1696                         dx = pBottom->x - pTop->x;
1697
1698                         if (dx < 0)
1699                         {
1700                                 pEteBuffer->gradient = dx / dy;
1701                                 pEteBuffer->gradient1 = pEteBuffer->gradient - 1;
1702                                 pEteBuffer->inc1 = -2 * dx + 2 * dy * pEteBuffer->gradient1;
1703                                 pEteBuffer->inc2 = -2 * dx + 2 * dy * pEteBuffer->gradient;
1704                                 pEteBuffer->direction = 2 * pEteBuffer->gradient * dy - 2 * dx - dy;
1705                         }
1706                         else
1707                         {
1708                                 pEteBuffer->gradient = dx / dy;
1709                                 pEteBuffer->gradient1 = pEteBuffer->gradient + 1;
1710                                 pEteBuffer->inc1 = 2 * dx - 2 * dy * pEteBuffer->gradient1;
1711                                 pEteBuffer->inc2 = 2 * dx - 2 * dy * pEteBuffer->gradient;
1712                                 pEteBuffer->direction = -2 * pEteBuffer->gradient * dy + 2 * dx - dy;
1713                         }
1714
1715                         if (!__InsertEdge(pEdgeTable, pEteBuffer, pTop->y, &pSllb, &isllb))
1716                         {
1717                                 return false;
1718                         }
1719
1720                         pEteBuffer++;
1721                 }
1722
1723                 pPrevPoint = pCurrPoint;
1724         }
1725
1726         return true;
1727 }
1728
1729 void
1730 _CanvasLine::_FreeSllb(_GpScanLineListBlock* pScanLineListBlock) const
1731 {
1732         _GpScanLineListBlock* pTempSlLb = null;
1733
1734         while (pScanLineListBlock != null)
1735         {
1736                 pTempSlLb = pScanLineListBlock->pNext;
1737                 delete pScanLineListBlock;
1738                 pScanLineListBlock = pTempSlLb;
1739         }
1740
1741         return;
1742 }
1743
1744 void
1745 _CanvasLine::_LoadAet(_GpEdgeTableEntry* pAet, _GpEdgeTableEntry* pEte) const
1746 {
1747         _GpEdgeTableEntry* pPrevAet = null;
1748         _GpEdgeTableEntry* pTempEte = null;
1749
1750         pPrevAet = pAet;
1751         pAet = pAet->pNext;
1752
1753         while (pEte)
1754         {
1755                 while ((pAet) && (pAet->minor < pEte->minor))
1756                 {
1757                         pPrevAet = pAet;
1758                         pAet = pAet->pNext;
1759                 }
1760
1761                 pTempEte = pEte->pNext;
1762                 pEte->pNext = pAet;
1763
1764                 if (pAet)
1765                 {
1766                         pAet->pBack = pEte;
1767                 }
1768
1769                 pEte->pBack = pPrevAet;
1770                 pPrevAet->pNext = pEte;
1771                 pPrevAet = pEte;
1772                 pEte = pTempEte;
1773         }
1774
1775         return;
1776 }
1777
1778 bool
1779 _CanvasLine::_InsertionSort(_GpEdgeTableEntry* pAet) const
1780 {
1781         _GpEdgeTableEntry* pEteChase = null;
1782         _GpEdgeTableEntry* pEteInsert = null;
1783         _GpEdgeTableEntry* pEteChaseBack = null;
1784         bool isChanged = false;
1785
1786         pAet = pAet->pNext;
1787
1788         while (pAet)
1789         {
1790                 pEteInsert = pAet;
1791                 pEteChase = pAet;
1792
1793                 while (pEteChase->pBack->minor > pAet->minor)
1794                 {
1795                         pEteChase = pEteChase->pBack;
1796                 }
1797
1798                 pAet = pAet->pNext;
1799
1800                 if (pEteChase != pEteInsert)
1801                 {
1802                         pEteChaseBack = pEteChase->pBack;
1803                         pEteInsert->pBack->pNext = pAet;
1804
1805                         if (pAet)
1806                         {
1807                                 pAet->pBack = pEteInsert->pBack;
1808                         }
1809
1810                         pEteInsert->pNext = pEteChase;
1811                         pEteChase->pBack->pNext = pEteInsert;
1812                         pEteChase->pBack = pEteInsert;
1813                         pEteInsert->pBack = pEteChaseBack;
1814                         isChanged = true;
1815                 }
1816         }
1817
1818         return isChanged;
1819 }
1820
1821 void
1822 _CanvasLine::_ComputeWaet(_GpEdgeTableEntry* pAet) const
1823 {
1824         _GpEdgeTableEntry* pWete = null;
1825         bool inside = true;
1826         int isInside = 0;
1827
1828         pAet->pWNext = null;
1829         pWete = pAet;
1830         pAet = pAet->pNext;
1831
1832         while (pAet)
1833         {
1834                 if (pAet->clockWise)
1835                 {
1836                         isInside++;
1837                 }
1838                 else
1839                 {
1840                         isInside--;
1841                 }
1842
1843                 if ((!inside && isInside == 0) || (inside && isInside))
1844                 {
1845                         pWete->pWNext = pAet;
1846                         pWete = pAet;
1847                         inside = !inside;
1848                 }
1849
1850                 pAet = pAet->pNext;
1851         }
1852
1853         pWete->pWNext = null;
1854
1855         return;
1856 }
1857
1858 bool
1859 _CanvasLine::__InsertEdge(_GpEdgeTable* pEt, _GpEdgeTableEntry* pEte, int scanLine, _GpScanLineListBlock** pSllb, int* pIsllb) const
1860 {
1861         _GpEdgeTableEntry* pStart = null;
1862         _GpEdgeTableEntry* pPrev = null;
1863         _GpScanLineList* pSll = null;
1864         _GpScanLineList* pPresSll = null;
1865         _GpScanLineListBlock* pTmpSllb = null;
1866
1867         // Check parameter
1868         if (pEt == null || pEte == null || pSllb == null || pIsllb == null)
1869         {
1870                 return false;
1871         }
1872
1873         pPresSll = &pEt->scanLines;
1874         pSll = pPresSll->pNext;
1875
1876         while (pSll != null && (pSll->scanLine < scanLine))
1877         {
1878                 pPresSll = pSll;
1879                 pSll = pSll->pNext;
1880         }
1881
1882         if (pSll == null || pSll->scanLine > scanLine)
1883         {
1884                 if (*pIsllb >= _MAX_SLL_BLOCK)
1885                 {
1886                         pTmpSllb = new (std::nothrow) _GpScanLineListBlock;
1887
1888                         if (pTmpSllb == null)
1889                         {
1890                                 SysLog(NID_GRP, "__InsertEdge : pTmpSllb allcation is failed!\n");
1891                                 // SysSetLastError(WMERR_OUT_OF_MEMORY);
1892                                 return false;
1893                         }
1894
1895                         (*pSllb)->pNext = pTmpSllb;
1896                         pTmpSllb->pNext = null;
1897                         *pSllb = pTmpSllb;
1898                         *pIsllb = 0;
1899                 }
1900
1901                 pSll = &((*pSllb)->scanLineList[(*pIsllb)]);
1902                 (*pIsllb)++;
1903                 pSll->pNext = pPresSll->pNext;
1904                 pSll->pEdgeList = null;
1905                 pPresSll->pNext = pSll;
1906         }
1907
1908         pSll->scanLine = scanLine;
1909
1910         pPrev = null;
1911         pStart = pSll->pEdgeList;
1912
1913         while (pStart != null && pStart->minor < pEte->minor)
1914         {
1915                 pPrev = pStart;
1916                 pStart = pStart->pNext;
1917         }
1918
1919         pEte->pNext = pStart;
1920
1921         if (pPrev != null)
1922         {
1923                 pPrev->pNext = pEte;
1924         }
1925         else
1926         {
1927                 pSll->pEdgeList = pEte;
1928         }
1929
1930         return true;
1931 }
1932
1933 bool
1934 _CanvasLine::_PatchJoint(_GpPolygon* pPolygon, int x, int y, float ox1, float oy1, float ox2, float oy2) const
1935 {
1936         float cross;
1937         int plx1;
1938         int ply1;
1939         int prx1;
1940         int pry1;
1941
1942         int plx2;
1943         int ply2;
1944         int prx2;
1945         int pry2;
1946         int degree0;
1947         int degree1;
1948
1949         cross = ox1 * oy2 - oy1 * ox2;
1950
1951         if ((-0.0001f < cross) && (cross < 0.0001f))
1952         {
1953                 return true;
1954         }
1955
1956         __GetBrushEndPoint(ox1, oy1, __lineWidth, &plx1, &ply1, &prx1, &pry1);
1957         __GetBrushEndPoint(ox2, oy2, __lineWidth, &plx2, &ply2, &prx2, &pry2);
1958
1959         if (cross < 0)
1960         {
1961                 degree0 = (int) (atan2((float) -pry1, (float) prx1) * (180 / _PI));
1962                 degree1 = (int) (atan2((float) -pry2, (float) prx2) * (180 / _PI));
1963         }
1964         else
1965         {
1966                 degree0 = (int) (atan2((float) -ply2, (float) plx2) * (180 / _PI));
1967                 degree1 = (int) (atan2((float) -ply1, (float) plx1) * (180 / _PI));
1968         }
1969
1970         while (degree0 < 0)
1971         {
1972                 degree0 += 360;
1973         }
1974
1975         while (degree0 > 360)
1976         {
1977                 degree0 -= 360;
1978         }
1979
1980         while (degree1 > 360)
1981         {
1982                 degree1 -= 360;
1983         }
1984
1985         while (degree1 < degree0)
1986         {
1987                 degree1 += 360;
1988         }
1989
1990         if (cross < 0)
1991         {
1992                 __PatchArc(pPolygon, (float) x, (float) y, (float) (__lineWidth / 2 - 1), (float) (__lineWidth / 2 - 1), degree0, degree1, 1);
1993         }
1994         else
1995         {
1996                 __PatchArc(pPolygon, (float) x, (float) y, (float) (__lineWidth / 2 - 1), (float) (__lineWidth / 2 - 1), degree0, degree1, 0);
1997         }
1998
1999         return true;
2000 }
2001
2002 bool
2003 _CanvasLine::_PatchRoundCap(_GpPolygon* pPolygon, int x, int y, float ox, float oy, bool isStart) const
2004 {
2005         int degree0;
2006         int degree1;
2007         int d;
2008         float rad;
2009         float fx;
2010         float fy;
2011
2012         d = (int) (atan2(-oy, ox) * (180 / _PI));
2013
2014         if (isStart)
2015         {
2016                 degree0 = d + 90;
2017                 degree1 = d - 90 + 360;
2018         }
2019         else
2020         {
2021                 degree0 = d - 90;
2022                 degree1 = d + 90;
2023         }
2024
2025         rad = __lineWidth / 2.f - 0.5f;
2026
2027         if (__lineWidth % 2 == 0)
2028         {
2029                 fx = x + oy / 2;
2030                 fy = y - ox / 2;
2031         }
2032         else
2033         {
2034                 fx = (float) x;
2035                 fy = (float) y;
2036         }
2037
2038         return __PatchArc(pPolygon, fx, fy, rad, rad, degree0, degree1, 1);
2039 }
2040
2041 bool
2042 _CanvasLine::__PatchArc(_GpPolygon* pPolygon, float x, float y, float w, float h, int degree0, int degree1, int pos) const
2043 {
2044         int n;
2045         int i;
2046         _GpFloatPoint* pEllipsePoint = null;
2047
2048         if ((degree0 % 360 == degree1 % 360) && (degree1 - degree0 != 360))
2049         {
2050                 return true;
2051         }
2052
2053         // if (w == 0.f || h == 0.f)
2054         if (_IsEqual(w, 0.0f) || _IsEqual(h, 0.0f))
2055         {
2056                 return true;
2057         }
2058
2059         n = _MakeEllipseArcPointArray(&pEllipsePoint, null, x, y, w, h, degree0, degree1, 0);
2060
2061         if (pEllipsePoint == null)
2062         {
2063                 return false;
2064         }
2065
2066         if (n < 2)
2067         {
2068                 delete[] pEllipsePoint;
2069
2070                 return false;
2071         }
2072
2073         if (pos == 0)
2074         {
2075                 for (i = n - 1; i >= 0; i--)
2076                 {
2077                         if (!_AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx + 0.5f), (int) (pEllipsePoint[i].fy), 0))
2078                         {
2079                                 delete[] pEllipsePoint;
2080
2081                                 return false;
2082                         }
2083                 }
2084         }
2085         else
2086         {
2087                 for (i = 0; i < n; i++)
2088                 {
2089                         if (!_AddPolygonVertex(pPolygon, (int) (pEllipsePoint[i].fx + 0.5f), (int) (pEllipsePoint[i].fy), 1))
2090                         {
2091                                 delete[] pEllipsePoint;
2092
2093                                 return false;
2094                         }
2095                 }
2096         }
2097
2098         delete[] pEllipsePoint;
2099
2100         return true;
2101 }
2102
2103 int
2104 _CanvasLine::_MakeEllipseArcPointArray(_GpFloatPoint** pPoint, _GpFloatPoint** pNorm, float x, float y, float w, float h, int a1, int a2, int rot) const
2105 {
2106         const float one_deg = 0.01745329251994329576f;
2107
2108         int i;
2109         int pointCount = 0;
2110         float degree1;
2111         float degree2;
2112         float r;
2113         float r1;
2114         float r2;
2115         float t1x;
2116         float t1y;
2117         float len;
2118         float sinR;
2119         float cosR;
2120         float t2x;
2121         float t2y;
2122         bool isEnd;
2123
2124         rot = ((-rot) % 360 + 360) % 360;
2125
2126         degree1 = (float) a1;
2127         degree2 = (float) a2;
2128
2129         r1 = (float) atan2(w * sin(_GP_DEGREE2RADIAN(degree1)), h * cos(_GP_DEGREE2RADIAN(degree1)));
2130         r2 = (float) atan2(w * sin(_GP_DEGREE2RADIAN(degree2)), h * cos(_GP_DEGREE2RADIAN(degree2)));
2131
2132         while (r1 < 0)
2133         {
2134                 r1 = r1 + 2 * _PI;
2135         }
2136
2137         while (r2 - 0.001f <= r1)
2138         {
2139                 r2 = r2 + 2 * _PI;
2140         }
2141
2142         pointCount = (int) ((r2 - r1) / one_deg) + 2;
2143
2144         *pPoint = new (std::nothrow) _GpFloatPoint[pointCount];
2145
2146         if (!*pPoint)
2147         {
2148                 return 0;
2149         }
2150
2151         if (pNorm != null)
2152         {
2153                 *pNorm = new (std::nothrow) _GpFloatPoint[pointCount];
2154
2155                 if (!*pNorm)
2156                 {
2157                         delete[] *pPoint;
2158
2159                         return 0;
2160                 }
2161         }
2162
2163         for (r = r1, i = 0, isEnd = false; i < pointCount; r += one_deg, i++)
2164         {
2165                 if (r > r2)
2166                 {
2167                         r = r2;
2168                         isEnd = true;
2169                 }
2170
2171                 sinR = (float) sin(r);
2172                 cosR = (float) cos(r);
2173
2174                 t1x = w * cosR;
2175                 t1y = -h * sinR;
2176
2177                 _Rotate2DPoint(t1x, t1y, rot, &t2x, &t2y);
2178
2179                 (*pPoint)[i].fx = x + t2x;
2180                 (*pPoint)[i].fy = y + t2y;
2181
2182                 if (pNorm != null)
2183                 {
2184                         t1x = h * cosR;
2185                         t1y = -w * sinR;
2186
2187                         len = (float) sqrt(t1x * t1x + t1y * t1y);
2188
2189                         if (_IsEqual(len, 0.0f))
2190                         {
2191                                 i--;
2192                                 pointCount--;
2193                                 continue;
2194                         }
2195
2196                         t1x = t1x / len;
2197                         t1y = t1y / len;
2198
2199                         _Rotate2DPoint(t1x, t1y, rot, &t2x, &t2y);
2200
2201                         (*pNorm)[i].fx = t2x;
2202                         (*pNorm)[i].fy = t2y;
2203                 }
2204
2205                 if (isEnd)
2206                 {
2207                         pointCount = i + 1;
2208                         break;
2209                 }
2210         }
2211
2212         return pointCount;
2213 }
2214
2215 void
2216 _CanvasLine::_Rotate2DPoint(float x, float y, long rot, float* pRx, float* pRy) const
2217 {
2218         float s;
2219         float c;
2220
2221         s = (float) sin(_GP_DEGREE2RADIAN(float(rot)));
2222         c = (float) cos(_GP_DEGREE2RADIAN(float(rot)));
2223
2224         *pRx = x * c - y * s;
2225         *pRy = y * c + x * s;
2226
2227         return;
2228 }
2229
2230 _GpResult
2231 _CanvasLine::__DrawHorizontalLineWithOpacity32(int startX, int endX, int y, const _GpBufferInfo& bufInfo)
2232 {
2233         register unsigned char dstA;
2234         register unsigned char dstR;
2235         register unsigned char dstG;
2236         register unsigned char dstB;
2237
2238         int frmbufP = bufInfo.pixelPerLine;
2239
2240         // doesn't need to check the validity of bound.. maybe  it's duplicate...
2241         //if (startX > endX)
2242         //      return GP_RESULT_FAIL;
2243
2244         //if (startX < 0 || startX >= frmbufW)
2245         //      return GP_RESULT_OUTOFBOUNDS;
2246
2247         //if (endX < 0 || endX >= frmbufW)
2248         //      return GP_RESULT_OUTOFBOUNDS;
2249
2250         //if (y < 0 || y >= frmbufH)
2251         //      return GP_RESULT_OUTOFBOUNDS;
2252
2253         //if (frmbufW < 1 || frmbufH < 1)
2254         //      return GP_RESULT_FAIL;*/
2255
2256         unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
2257
2258         unsigned char srcA = (unsigned char) ((bufInfo.color32 & 0xFF000000) >> 24);
2259         unsigned char srcR = (unsigned char) ((bufInfo.color32 & 0x00FF0000) >> 16);
2260         unsigned char srcG = (unsigned char) ((bufInfo.color32 & 0x0000FF00) >> 8);
2261         unsigned char srcB = (unsigned char) (bufInfo.color32 & 0x000000FF);
2262         unsigned char oneMinusSrcA = 255 - srcA;
2263
2264         {
2265                 register unsigned long* pOffset32 = (pFrmbuf32 + frmbufP * y + startX);
2266
2267                 for (int i = 0; i < endX - startX + 1; i++)
2268                 {
2269                         dstR = (unsigned char)(*pOffset32 >> 16);
2270                         dstG = (unsigned char)(*pOffset32 >> 8);
2271                         dstB = (unsigned char)(*pOffset32);
2272
2273                         dstR = (unsigned char) ((dstR * oneMinusSrcA + srcR * srcA + 255) >> 8);
2274                         dstG = (unsigned char) ((dstG * oneMinusSrcA + srcG * srcA + 255) >> 8);
2275                         dstB = (unsigned char) ((dstB * oneMinusSrcA + srcB * srcA + 255) >> 8);
2276                         dstA = (((unsigned char)(*pOffset32 >> 24) * oneMinusSrcA + 255) >> 8) + srcA;
2277
2278                         *pOffset32++ = (unsigned long)(((unsigned long)dstA << 24) | ((unsigned long)dstR << 16) | ((unsigned long)dstG << 8) | (unsigned long)(dstB));
2279                 }
2280         }
2281
2282         return GP_RESULT_SUCCESS;
2283 }
2284
2285 bool
2286 _CanvasLine::_IsInClipRect(int rectX, int rectY, int rectW, int rectH, const _GpBufferInfo& bufInfo) const
2287 {
2288         if (rectW <= 0 || rectH <= 0)
2289         {
2290                 return false;
2291         }
2292
2293         if (bufInfo.isClipBoundsSet)
2294         {
2295                 if (rectX >= bufInfo.clipBounds.x && (rectX + rectW) <= (bufInfo.clipBounds.x + bufInfo.clipBounds.width) &&
2296                         rectY >= bufInfo.clipBounds.y && (rectY + rectH) <= (bufInfo.clipBounds.y + bufInfo.clipBounds.height))
2297                 {
2298                         return true;
2299                 }
2300         }
2301         else
2302         {
2303                 if (rectX >= 0 && (rectX + rectW) <= bufInfo.width && rectY >= 0 && (rectY + rectH) <= bufInfo.height)
2304                 {
2305                         return true;
2306                 }
2307         }
2308
2309         return false;
2310 }
2311
2312 bool
2313 _CanvasLine::_SetNotClipFunction(bool isWidelineSet)
2314 {
2315         pFuncSetPixel = &_CanvasLine::_DrawPixel;
2316
2317         if (__lineWidth == 1 || !isWidelineSet)
2318         {
2319                 pFuncHorizontalLine = &_CanvasLine::_DrawUnitLineHorizontal;
2320                 pFuncVerticalLine = &_CanvasLine::_DrawUnitLineVertical;
2321         }
2322         else if (__lineWidth > 1)
2323         {
2324                 pFuncHorizontalLine = &_CanvasLine::_DrawWideLineHorizontal;
2325                 pFuncVerticalLine = &_CanvasLine::_DrawWideLineVertical;
2326         }
2327
2328         return true;
2329 }
2330
2331 bool
2332 _CanvasLine::_SetClipFunction(bool isWidelineSet) const
2333 {
2334         pFuncSetPixel = &_CanvasLine::_DrawPixelWithClipping;
2335
2336         if (__lineWidth == 1 || !isWidelineSet)
2337         {
2338                 pFuncHorizontalLine = &_CanvasLine::_DrawUnitLineHorizontalWithClipping;
2339                 pFuncVerticalLine = &_CanvasLine::_DrawUnitLineVerticalWithClipping;
2340         }
2341         else if (__lineWidth > 1)
2342         {
2343                 pFuncHorizontalLine = &_CanvasLine::_DrawUnitLineHorizontalWithClipping;
2344                 pFuncVerticalLine = &_CanvasLine::_DrawUnitLineVerticalWithClipping;
2345         }
2346
2347         return true;
2348 }
2349
2350 bool
2351 _CanvasLine::_DrawPolyLine(int ptCount, _GpPoint* pPoints, bool isConnected, const _GpBufferInfo& bufInfo)
2352 {
2353         int i = 0;
2354         int j;
2355         bool ret = false;
2356
2357         ptCount = __CheckDupVertexForPolygon(ptCount, pPoints, isConnected);
2358
2359         if (__lineWidth < 2 || (bufInfo.color32 & 0xFF000000) == 0xFF000000)
2360         {
2361                 while (++i < ptCount)
2362                 {
2363                         j = i - 1;
2364
2365                         if (DrawLine(pPoints[j], pPoints[i], bufInfo) == E_SYSTEM)
2366                         {
2367                                 SysLog(NID_GRP, "_DrawPolyLine: DrawLine is failed -1!\n");
2368
2369                                 return false;
2370                         }
2371                 }
2372
2373                 if (isConnected)
2374                 {
2375                         if (DrawLine(pPoints[i-1], pPoints[0], bufInfo) == E_SYSTEM)
2376                         {
2377                                 SysLog(NID_GRP, "_DrawPolyLine: DrawLine is failed -2!\n");
2378
2379                                 return false;
2380                         }
2381                 }
2382
2383                 ret = true;
2384         }
2385         else
2386         {
2387                 ret = __DrawThickContinuousPolyline(ptCount, pPoints, isConnected, bufInfo);
2388         }
2389
2390         return ret;
2391 }
2392
2393 }} // Tizen::Graphics