Fixed comparisons against TRUE and FALSE.
[cake.git] / rom / graphics / areaend.c
blobd8998c223032dd577d4805e535e0cb304c419eb0
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function AreaEnd()
6 Lang: english
7 */
8 #include <exec/types.h>
9 #include <graphics/rastport.h>
10 #include "graphics_intern.h"
12 /*****************************************************************************
14 NAME */
15 #include <proto/graphics.h>
17 AROS_LH1(LONG, AreaEnd,
19 /* SYNOPSIS */
20 AROS_LHA(struct RastPort *, rp, A1),
22 /* LOCATION */
23 struct GfxBase *, GfxBase, 44, Graphics)
25 /* FUNCTION
26 Process the filled vector buffer.
27 After the operation the buffer is reinitialized for
28 processing of further Area functions.
29 Makes use of the raster given by the TmpRas structure that
30 is linked to the rastport.
32 INPUTS
33 rp - pointer to a valid RastPort structure with a pointer to
34 the previously initialized AreaInfo structure.
37 RESULT
38 error - 0 for success
39 -1 a error occurred
41 NOTES
43 EXAMPLE
45 BUGS
46 There is still a problem when some polygons are filled that
47 pixels are missing. This could be due to the way lines are
48 drawn. All lines should be drawn from lower
49 y coordinates to higher y coordinates since this is the
50 way the algorithm calculates lines here. For example, it
51 might make a difference whether a line is drawn from lower
52 to higher y coordinates. Examples for two same lines with
53 different layout:
55 **** *****
56 ***** ****
59 SEE ALSO
60 InitArea() AreaDraw() AreaEllipse() AreaCircle() graphics/rastport.h
62 INTERNALS
64 HISTORY
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 struct AreaInfo * areainfo = rp->AreaInfo;
72 /* is there anything in the matrix at all ? And do we have a TmpRas in the rastport? */
73 if (areainfo->Count && rp->TmpRas)
75 WORD first_idx = 0;
76 WORD last_idx = -1;
77 ULONG BytesPerRow;
78 UWORD * CurVctr = areainfo -> VctrTbl;
79 BYTE * CurFlag = areainfo -> FlagTbl;
80 UWORD Count;
81 UWORD Rem_APen = GetAPen(rp);
82 /* I don't know whether this function may corrupt the
83 cursor position of the rastport. So I save it for later.*/
85 UWORD Rem_cp_x = rp->cp_x;
86 UWORD Rem_cp_y = rp->cp_y;
87 /* This rectangle serves as a "frame" for the tmpras for filling */
88 struct Rectangle bounds;
91 areaclosepolygon(areainfo);
93 Count = areainfo->Count;
95 //kprintf("%d coord to process\n",Count);
97 /* process the list of vectors */
98 while (Count > 0)
100 //kprintf("\n******** Flags:%d Coord: (%d,%d)\n",CurFlag[0], CurVctr[0],CurVctr[1]);
102 last_idx ++;
103 switch((unsigned char)CurFlag[0])
105 case AREAINFOFLAG_MOVE:
106 /* set the graphical cursor to a starting position */
107 Move(rp, CurVctr[0], CurVctr[1]);
109 bounds.MinX = CurVctr[0];
110 bounds.MaxX = CurVctr[0];
111 bounds.MinY = CurVctr[1];
112 bounds.MaxY = CurVctr[1];
114 CurVctr = &CurVctr[2];
115 CurFlag = &CurFlag[1];
116 break;
118 case AREAINFOFLAG_CLOSEDRAW:
119 /* this indicates that this Polygon is closed with this coordinate */
121 * Must draw from lower y's to higher ones otherwise
122 * the fill algo does not work nicely.
124 #if 1
125 if (rp->cp_y <= CurVctr[1]) {
126 Draw(rp, CurVctr[0], CurVctr[1]);
127 } else {
128 int _x = rp->cp_x;
129 int _y = rp->cp_y;
130 rp->cp_x = CurVctr[0];
131 rp->cp_y = CurVctr[1];
132 Draw(rp, _x, _y);
133 rp->cp_x = CurVctr[0];
134 rp->cp_y = CurVctr[1];
136 #endif
137 CurVctr = &CurVctr[2];
138 CurFlag = &CurFlag[1];
140 no need to set the bundaries here like in case above as
141 this coord closes the polygon and therefore is the same
142 one as the first coordinate of the polygon.
144 /* check whether there's anything to fill at all. I cannot
145 fill a line (=3 coordinates) */
146 if (first_idx+2 <= last_idx)
148 /* BytesPerRow must be a multiple of 2 bytes */
150 BytesPerRow = bounds.MaxX - bounds.MinX + 1;
151 if (0 != (BytesPerRow & 0x0f ))
152 BytesPerRow =((BytesPerRow >> 3) & 0xfffe )+ 2;
153 else
154 BytesPerRow = (BytesPerRow >> 3) & 0xfffe;
156 if ((ULONG)rp->TmpRas->Size < BytesPerRow * (bounds.MaxY - bounds.MinY + 1))
157 return -1;
160 kprintf("first: %d, last: %d\n",first_idx,last_idx);
161 kprintf("(%d,%d)-(%d,%d)\n",bounds.MinX,bounds.MinY,
162 bounds.MaxX,bounds.MaxY);
163 kprintf("width: %d, bytesperrow: %d\n",bounds.MaxX-bounds.MinX+1,
164 BytesPerRow);
166 #if 1
167 if (areafillpolygon(rp,
168 &bounds,
169 first_idx,
170 last_idx,
171 BytesPerRow,
172 GfxBase))
175 Blit the area fill pattern through the mask provided
176 by rp->TmpRas.
179 BltPattern(
181 rp->TmpRas->RasPtr,
182 bounds.MinX,
183 bounds.MinY,
184 bounds.MaxX,
185 bounds.MaxY,
186 BytesPerRow
189 if (rp->Flags & AREAOUTLINE)
191 SetAPen(rp, GetOutlinePen(rp));
192 PolyDraw(rp, last_idx - first_idx + 1, &areainfo->VctrTbl[first_idx]);
193 SetAPen(rp, Rem_APen);
197 #endif
199 /* set first_idx for a possible next polygon to draw */
200 first_idx = last_idx + 1;
201 break;
203 case AREAINFOFLAG_DRAW:
204 /* Draw a line to new position */
205 #if 1
207 * Must draw from lower y's to higher ones otherwise
208 * the fill algo does not work nicely.
210 if (rp->cp_y <= CurVctr[1]) {
211 Draw(rp, CurVctr[0], CurVctr[1]);
212 } else {
213 int _x = rp->cp_x;
214 int _y = rp->cp_y;
215 rp->cp_x = CurVctr[0];
216 rp->cp_y = CurVctr[1];
217 Draw(rp, _x, _y);
218 rp->cp_x = CurVctr[0];
219 rp->cp_y = CurVctr[1];
221 #endif
222 if (bounds.MinX > CurVctr[0])
223 bounds.MinX = CurVctr[0];
224 if (bounds.MaxX < CurVctr[0])
225 bounds.MaxX = CurVctr[0];
226 if (bounds.MinY > CurVctr[1])
227 bounds.MinY = CurVctr[1];
228 if (bounds.MaxY < CurVctr[1])
229 bounds.MaxY = CurVctr[1];
230 CurVctr = &CurVctr[2];
231 CurFlag = &CurFlag[1];
232 break;
234 case AREAINFOFLAG_ELLIPSE:
235 bounds.MinX = CurVctr[0] - CurVctr[2];
236 bounds.MaxX = CurVctr[0] + CurVctr[2];
237 bounds.MinY = CurVctr[1] - CurVctr[3];
238 bounds.MaxY = CurVctr[1] + CurVctr[3];
239 BytesPerRow = bounds.MaxX - bounds.MinX + 1;
241 if (0 != (BytesPerRow & 0x0f ))
242 BytesPerRow =((BytesPerRow >> 3) & 0xfffe )+ 2;
243 else
244 BytesPerRow = (BytesPerRow >> 3) & 0xfffe;
246 if ((ULONG)rp->TmpRas->Size < BytesPerRow * (bounds.MaxY - bounds.MinY + 1))
247 return -1;
249 /* Draw an Ellipse and fill it */
250 /* see how the data are stored by the second entry */
251 /* I get cx,cy,cx+a,cy+b*/
253 DrawEllipse(rp,CurVctr[0],
254 CurVctr[1],
255 CurVctr[2],
256 CurVctr[3]);
258 /* area-fill the ellipse with the pattern given
259 in rp->AreaPtrn , AreaPtSz */
261 areafillellipse(rp,
262 &bounds,
263 CurVctr,
264 BytesPerRow,
265 GfxBase);
267 Blit the area fill pattern through the mask provided
268 by rp->TmpRas.
271 BltPattern(
273 rp->TmpRas->RasPtr,
274 bounds.MinX,
275 bounds.MinY,
276 bounds.MaxX,
277 bounds.MaxY,
278 BytesPerRow
281 if (rp->Flags & AREAOUTLINE)
283 SetAPen(rp, GetOutlinePen(rp));
285 DrawEllipse(rp,CurVctr[0],
286 CurVctr[1],
287 CurVctr[2],
288 CurVctr[3]);
290 SetAPen(rp, Rem_APen);
293 CurVctr = &CurVctr[4];
294 CurFlag = &CurFlag[2];
295 Count--;
296 last_idx++; /* there were two coords here! */
298 /* set first_idx for a possible next polygon to draw */
299 first_idx = last_idx + 1;
300 break;
302 default:
303 /* this is an error */
304 SetAPen(rp, Rem_APen);
305 /* also restore old graphics cursor position */
306 rp->cp_x = Rem_cp_x;
307 rp->cp_y = Rem_cp_y;
308 return -1;
310 } /* switch((unsigned char)CurFlag[0]) */
311 Count--;
313 } /* while (Count > 0) */
315 /* restore areainfo structure for a new beginning */
316 areainfo->VctrPtr = areainfo->VctrTbl;
317 areainfo->FlagPtr = areainfo->FlagTbl;
318 areainfo->Count = 0;
320 /* restore old APen */
321 SetAPen(rp, Rem_APen);
322 /* also restore old graphics cursor position */
323 rp->cp_x = Rem_cp_x;
324 rp->cp_y = Rem_cp_y;
326 } /* if vectorlist is not empty and rastport has a tmpras */
328 return 0;
330 AROS_LIBFUNC_EXIT
332 } /* AreaEnd */