Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / FGrp_CanvasGpFillPolygon.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_CanvasGpFillPolygon.cpp
20  * @brief       This is the implementation file for _CanvasFillPolygon class.
21  *
22  */
23
24 #include <new>
25 #include <cstring>
26
27 #include <FBaseSysLog.h>
28
29 #include "FGrp_CanvasGpPrimitive.h"
30 #include "util/FGrp_UtilScratchpad.h"
31
32
33 using namespace Tizen::Base;
34 using namespace Tizen::Graphics;
35
36 typedef unsigned long SystemPixel;
37
38 namespace Tizen { namespace Graphics
39 {
40
41 bool
42 _CanvasFillPolygon::SetLineWidth(int lineWidth)
43 {
44         __lineWidth = lineWidth;
45         return true;
46 }
47
48 int
49 _CanvasFillPolygon::GetLineWidth(void) const
50 {
51         return __lineWidth;
52 }
53
54 result
55 _CanvasFillPolygon::FillPolygon(int ptCount, _GpPoint* pPoints, const _GpBufferInfo& bufInfo)
56 {
57         _GpEdgeTable et;
58         _GpEdgeTableEntry aet;
59         _GpEdgeTableEntry* pPrevAet = null;
60         _GpEdgeTableEntry* pAetPtr = null;
61         _GpEdgeTableEntry* pWetePtr = null;
62         _GpEdgeTableEntry* pEteBuf = null;
63         _GpScanLineListBlock* pSllb = null;
64         _GpScanLineList* pSll = null;
65         int i;
66         int y;
67         int stitch = 1;
68         int fixWaet = 0;
69         _CanvasLine line;
70         _CanvasTriangle triangle;
71         _GpPoint* pTempPoints = null;
72         bool err = false;
73
74         if (ptCount < 1)
75         {
76                 return E_SYSTEM;
77         }
78
79         line.SetLineWidth(__lineWidth);
80         triangle.SetLineWidth(__lineWidth);
81
82         if (ptCount == 1)
83         {
84                 return (line._DrawPixelWithClipping(pPoints[0].x, pPoints[0].y, bufInfo) == GP_RESULT_FAIL ? E_SYSTEM : E_SUCCESS);
85         }
86         else if (ptCount == 2)
87         {
88                 return line.DrawLine(pPoints[0], pPoints[1], bufInfo);
89         }
90         else if (ptCount == 3)
91         {
92                 return triangle.FillTriangle(pPoints[0].x, pPoints[0].y, pPoints[1].x, pPoints[1].y, pPoints[2].x, pPoints[2].y, bufInfo);
93         }
94         else if (ptCount == 4)
95         {
96                 if (pPoints[0].x == pPoints[3].x && pPoints[1].x == pPoints[2].x && pPoints[0].y == pPoints[1].y && pPoints[2].y == pPoints[3].y)
97                 {
98                         if (bufInfo.bitsPerPixel == 32)
99                         {
100                                 int rectX;
101                                 int rectY;
102
103                                 rectX = GP_MIN(pPoints[0].x, pPoints[1].x);
104                                 rectY = GP_MIN(pPoints[0].y, pPoints[2].y);
105
106                                 _Util::ScratchPad<SystemPixel> rect((unsigned long*) bufInfo.pPixels, bufInfo.width, bufInfo.height, bufInfo.pixelPerLine);
107                                 rect.FillRect(rectX, rectY, GP_ABS(pPoints[1].x - pPoints[0].x) + 1, GP_ABS(pPoints[3].y - pPoints[0].y) + 1, bufInfo.color32);
108                         }
109                         else
110                         {
111                                 // To do 16 bpp
112                                 SysLog(NID_GRP, "FillPolygon: not support 16 bpp -1!\n");
113                                 return E_SYSTEM;
114                         }
115
116                         return E_SUCCESS;
117                 }
118                 else if (pPoints[0].y == pPoints[3].y && pPoints[1].y == pPoints[2].y && pPoints[0].x == pPoints[1].x && pPoints[2].x == pPoints[3].x)
119                 {
120                         if (bufInfo.bitsPerPixel == 32)
121                         {
122                                 int rectX;
123                                 int rectY;
124
125                                 rectX = GP_MIN(pPoints[0].x, pPoints[2].x);
126                                 rectY = GP_MIN(pPoints[0].y, pPoints[1].y);
127
128                                 _Util::ScratchPad<SystemPixel> rect((unsigned long*) bufInfo.pPixels, bufInfo.width, bufInfo.height, bufInfo.pixelPerLine);
129                                 rect.FillRect(rectX, rectY, GP_ABS(pPoints[3].x - pPoints[0].x) + 1, GP_ABS(pPoints[1].y - pPoints[0].y) + 1, bufInfo.color32);
130                         }
131                         else
132                         {
133                                 SysLog(NID_GRP, "FillPolygon: not support 16 bpp -2!\n");
134                                 return E_SYSTEM;
135                         }
136
137                         return E_SUCCESS;
138                 }
139         }
140
141         pEteBuf = new (std::nothrow) _GpEdgeTableEntry[ptCount];
142
143         if (pEteBuf == null)
144         {
145                 SysLog(NID_GRP, "FillPolygon: EteBuf allcation is failed!\n");
146
147                 return E_SYSTEM;
148         }
149
150         pSllb = new (std::nothrow) _GpScanLineListBlock;
151
152         if (pSllb == null)
153         {
154                 delete[] pEteBuf;
155                 SysLog(NID_GRP, "FillPolygon: pSllb allcation is failed!\n");
156
157                 return false;
158         }
159
160         memset(pSllb, 0, sizeof(*pSllb));
161
162         pTempPoints = new (std::nothrow) _GpPoint[ptCount];
163
164         if (pTempPoints == null)
165         {
166                 delete[] pEteBuf;
167
168                 line._FreeSllb(pSllb);
169
170                 return E_SYSTEM;
171         }
172
173         for (i = 0; i < ptCount; i++)
174         {
175                 pTempPoints[i] = pPoints[i];
176         }
177
178         if (line._CreateEtAndAet(ptCount, pTempPoints, &et, &aet, pEteBuf, pSllb) == null)
179         {
180                 delete[] pEteBuf;
181
182                 line._FreeSllb(pSllb);
183                 SysLog(NID_GRP, "FillPolygon: _CreateEtAndAet is failed!\n");
184
185                 delete[] pTempPoints;
186
187                 return E_SYSTEM;
188         }
189
190         pSll = et.scanLines.pNext;
191
192         _GpRect clipRect;
193         if (bufInfo.isClipBoundsSet)
194         {
195                 clipRect = bufInfo.clipBounds;
196         }
197         else
198         {
199                 clipRect.SetBounds(0, 0, bufInfo.width, bufInfo.height);
200         }
201
202         for (y = et.minY; y < et.maxY + stitch; y++)
203         {
204                 if (pSll != null && y == pSll->scanLine)
205                 {
206                         line._LoadAet(&aet, pSll->pEdgeList);
207                         line._ComputeWaet(&aet);
208                         pSll = pSll->pNext;
209                 }
210
211                 pPrevAet = &aet;
212                 pAetPtr = aet.pNext;
213                 pWetePtr = pAetPtr;
214
215                 while (pAetPtr != null)
216                 {
217                         if (pWetePtr == pAetPtr)
218                         {
219                                 {
220                                         int x1 = pAetPtr->minor;
221                                         int x2 = pAetPtr->pWNext->minor + stitch - 1;
222                                         int horY = y;
223                                         int clipEndX;
224
225                                         //if (pGC->bMemGC == null)
226                                         //{
227                                         //      x1   += pGC->rcGC.x;
228                                         //      x2   += pGC->rcGC.x;
229                                         //      horY += pGC->rcGC.y;
230                                         //}
231
232                                         clipEndX = clipRect.x + clipRect.width - 1;
233
234                                         //  Swapping
235                                         if (x1 > x2)
236                                         {
237                                                 GP_SWAP(x1, x2);
238                                         }
239
240                                         if (y < clipRect.y || y > (clipRect.y + clipRect.height - 1))
241                                         {
242                                                 goto CLIP_EXIT;
243                                         }
244
245                                         if (x1 > clipEndX || x2 < clipRect.x)
246                                         {
247                                                 goto CLIP_EXIT;
248                                         }
249
250                                         if (x1 < clipRect.x)
251                                         {
252                                                 x1 = clipRect.x;
253                                         }
254
255                                         if (x2 > clipEndX)
256                                         {
257                                                 x2 = clipEndX;
258                                         }
259
260                                         // draw primitive line
261                                         if ((bufInfo.color32 & 0xFF000000) == 0xFF000000)
262                                         {
263                                                 unsigned long* pFrmbuf32 = (unsigned long*) bufInfo.pPixels;
264                                                 while (x1 <= x2)
265                                                 {
266                                                         pFrmbuf32[bufInfo.pixelPerLine * horY + x1] = bufInfo.color32;
267                                                         x1++;
268                                                 }
269                                         }
270                                         else
271                                         {
272                                                 if (line.__DrawHorizontalLineWithOpacity32(x1, x2, horY, bufInfo) == GP_RESULT_FAIL)
273                                                 {
274                                                         return E_SYSTEM;
275                                                 }
276                                         }
277
278 CLIP_EXIT:
279                                         err = true;
280
281                                 }
282
283                                 pWetePtr = pWetePtr->pWNext;
284                                 while (pWetePtr != pAetPtr)
285                                 {
286                                         if (pAetPtr == null)
287                                         {
288                                                 break;
289                                         }
290
291                                         if (pAetPtr->maxY == y)
292                                         {
293                                                 pPrevAet->pNext = pAetPtr->pNext;
294                                                 pAetPtr = pPrevAet->pNext;
295                                                 fixWaet = 1;
296                                                 if (pAetPtr != null)
297                                                 {
298                                                         pAetPtr->pBack = pPrevAet;
299                                                 }
300                                         }
301                                         else
302                                         {
303                                                 if (pAetPtr->gradient1 > 0)
304                                                 {
305                                                         if (pAetPtr->direction > 0)
306                                                         {
307                                                                 pAetPtr->minor += pAetPtr->gradient1;
308                                                                 pAetPtr->direction += pAetPtr->inc1;
309                                                         }
310                                                         else
311                                                         {
312                                                                 pAetPtr->minor += pAetPtr->gradient;
313                                                                 pAetPtr->direction += pAetPtr->inc2;
314                                                         }
315                                                 }
316                                                 else
317                                                 {
318                                                         if (pAetPtr->direction >= 0)
319                                                         {
320                                                                 pAetPtr->minor += pAetPtr->gradient1;
321                                                                 pAetPtr->direction += pAetPtr->inc1;
322                                                         }
323                                                         else
324                                                         {
325                                                                 pAetPtr->minor += pAetPtr->gradient;
326                                                                 pAetPtr->direction += pAetPtr->inc2;
327                                                         }
328                                                 }
329                                                 pPrevAet = pAetPtr;
330                                                 pAetPtr = pAetPtr->pNext;
331                                         }
332                                 }
333                                 pWetePtr = pWetePtr->pWNext;
334                         }
335
336                         if (pAetPtr == null)
337                         {
338                                 break;
339                         }
340
341                         if (pAetPtr->maxY == y)
342                         {
343                                 pPrevAet->pNext = pAetPtr->pNext;
344                                 pAetPtr = pPrevAet->pNext;
345                                 fixWaet = 1;
346
347                                 if (pAetPtr != null)
348                                 {
349                                         pAetPtr->pBack = pPrevAet;
350                                 }
351                         }
352                         else
353                         {
354                                 if (pAetPtr->gradient1 > 0)
355                                 {
356                                         if (pAetPtr->direction > 0)
357                                         {
358                                                 pAetPtr->minor += pAetPtr->gradient1;
359                                                 pAetPtr->direction += pAetPtr->inc1;
360                                         }
361                                         else
362                                         {
363                                                 pAetPtr->minor += pAetPtr->gradient;
364                                                 pAetPtr->direction += pAetPtr->inc2;
365                                         }
366                                 }
367                                 else
368                                 {
369                                         if (pAetPtr->direction >= 0)
370                                         {
371                                                 pAetPtr->minor += pAetPtr->gradient1;
372                                                 pAetPtr->direction += pAetPtr->inc1;
373                                         }
374                                         else
375                                         {
376                                                 pAetPtr->minor += pAetPtr->gradient;
377                                                 pAetPtr->direction += pAetPtr->inc2;
378                                         }
379                                 }
380
381                                 pPrevAet = pAetPtr;
382                                 pAetPtr = pAetPtr->pNext;
383                         }
384                 }
385
386                 if (line._InsertionSort(&aet) || fixWaet)
387                 {
388                         line._ComputeWaet(&aet);
389                         fixWaet = 0;
390                 }
391         }
392
393         delete[] pTempPoints;
394
395         delete[] pEteBuf;
396
397         line._FreeSllb(pSllb);
398
399         return E_SUCCESS;
400 }
401
402 }} // Tizen::Graphics