2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: Graphics function AreaEnd()
8 #include <exec/types.h>
9 #include <graphics/rastport.h>
10 #include "graphics_intern.h"
12 /*****************************************************************************
15 #include <proto/graphics.h>
17 AROS_LH1(LONG
, AreaEnd
,
20 AROS_LHA(struct RastPort
*, rp
, A1
),
23 struct GfxBase
*, GfxBase
, 44, Graphics
)
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.
33 rp - pointer to a valid RastPort structure with a pointer to
34 the previously initialized AreaInfo structure.
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
60 InitArea(), AreaDraw(), AreaEllipse(), AreaCircle()
67 *****************************************************************************/
71 struct AreaInfo
* areainfo
= rp
->AreaInfo
;
73 /* is there anything in the matrix at all ? And do we have a TmpRas in the rastport? */
74 if (areainfo
->Count
&& rp
->TmpRas
)
79 UWORD
* CurVctr
= areainfo
-> VctrTbl
;
80 BYTE
* CurFlag
= areainfo
-> FlagTbl
;
82 UWORD Rem_APen
= GetAPen(rp
);
83 /* I don't know whether this function may corrupt the
84 cursor position of the rastport. So I save it for later.*/
86 UWORD Rem_cp_x
= rp
->cp_x
;
87 UWORD Rem_cp_y
= rp
->cp_y
;
88 /* This rectangle serves as a "frame" for the tmpras for filling */
89 struct Rectangle bounds
;
92 areaclosepolygon(areainfo
);
94 Count
= areainfo
->Count
;
96 //kprintf("%d coord to process\n",Count);
98 /* process the list of vectors */
101 //kprintf("\n******** Flags:%d Coord: (%d,%d)\n",CurFlag[0], CurVctr[0],CurVctr[1]);
104 switch((unsigned char)CurFlag
[0])
106 case AREAINFOFLAG_MOVE
:
107 /* set the graphical cursor to a starting position */
108 Move(rp
, CurVctr
[0], CurVctr
[1]);
110 bounds
.MinX
= CurVctr
[0];
111 bounds
.MaxX
= CurVctr
[0];
112 bounds
.MinY
= CurVctr
[1];
113 bounds
.MaxY
= CurVctr
[1];
115 CurVctr
= &CurVctr
[2];
116 CurFlag
= &CurFlag
[1];
119 case AREAINFOFLAG_CLOSEDRAW
:
120 /* this indicates that this Polygon is closed with this coordinate */
122 * Must draw from lower y's to higher ones otherwise
123 * the fill algo does not work nicely.
126 if (rp
->cp_y
<= CurVctr
[1]) {
127 Draw(rp
, CurVctr
[0], CurVctr
[1]);
131 rp
->cp_x
= CurVctr
[0];
132 rp
->cp_y
= CurVctr
[1];
134 rp
->cp_x
= CurVctr
[0];
135 rp
->cp_y
= CurVctr
[1];
138 CurVctr
= &CurVctr
[2];
139 CurFlag
= &CurFlag
[1];
141 no need to set the bundaries here like in case above as
142 this coord closes the polygon and therefore is the same
143 one as the first coordinate of the polygon.
145 /* check whether there's anything to fill at all. I cannot
146 fill a line (=3 coordinates) */
147 if (first_idx
+2 <= last_idx
)
149 /* BytesPerRow must be a multiple of 2 bytes */
151 BytesPerRow
= bounds
.MaxX
- bounds
.MinX
+ 1;
152 if (0 != (BytesPerRow
& 0x0f ))
153 BytesPerRow
=((BytesPerRow
>> 3) & 0xfffe )+ 2;
155 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
157 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 1))
161 kprintf("first: %d, last: %d\n",first_idx,last_idx);
162 kprintf("(%d,%d)-(%d,%d)\n",bounds.MinX,bounds.MinY,
163 bounds.MaxX,bounds.MaxY);
164 kprintf("width: %d, bytesperrow: %d\n",bounds.MaxX-bounds.MinX+1,
168 if (areafillpolygon(rp
,
176 Blit the area fill pattern through the mask provided
190 if (rp
->Flags
& AREAOUTLINE
)
192 SetAPen(rp
, GetOutlinePen(rp
));
193 PolyDraw(rp
, last_idx
- first_idx
+ 1, &areainfo
->VctrTbl
[first_idx
]);
194 SetAPen(rp
, Rem_APen
);
200 /* set first_idx for a possible next polygon to draw */
201 first_idx
= last_idx
+ 1;
204 case AREAINFOFLAG_DRAW
:
205 /* Draw a line to new position */
208 * Must draw from lower y's to higher ones otherwise
209 * the fill algo does not work nicely.
211 if (rp
->cp_y
<= CurVctr
[1]) {
212 Draw(rp
, CurVctr
[0], CurVctr
[1]);
216 rp
->cp_x
= CurVctr
[0];
217 rp
->cp_y
= CurVctr
[1];
219 rp
->cp_x
= CurVctr
[0];
220 rp
->cp_y
= CurVctr
[1];
223 if (bounds
.MinX
> CurVctr
[0])
224 bounds
.MinX
= CurVctr
[0];
225 if (bounds
.MaxX
< CurVctr
[0])
226 bounds
.MaxX
= CurVctr
[0];
227 if (bounds
.MinY
> CurVctr
[1])
228 bounds
.MinY
= CurVctr
[1];
229 if (bounds
.MaxY
< CurVctr
[1])
230 bounds
.MaxY
= CurVctr
[1];
231 CurVctr
= &CurVctr
[2];
232 CurFlag
= &CurFlag
[1];
235 case AREAINFOFLAG_ELLIPSE
:
236 bounds
.MinX
= CurVctr
[0] - CurVctr
[2];
237 bounds
.MaxX
= CurVctr
[0] + CurVctr
[2];
238 bounds
.MinY
= CurVctr
[1] - CurVctr
[3];
239 bounds
.MaxY
= CurVctr
[1] + CurVctr
[3];
240 BytesPerRow
= bounds
.MaxX
- bounds
.MinX
+ 1;
242 if (0 != (BytesPerRow
& 0x0f ))
243 BytesPerRow
=((BytesPerRow
>> 3) & 0xfffe )+ 2;
245 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
247 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 1))
250 /* Draw an Ellipse and fill it */
251 /* see how the data are stored by the second entry */
252 /* I get cx,cy,cx+a,cy+b*/
254 DrawEllipse(rp
,CurVctr
[0],
259 /* area-fill the ellipse with the pattern given
260 in rp->AreaPtrn , AreaPtSz */
268 Blit the area fill pattern through the mask provided
282 if (rp
->Flags
& AREAOUTLINE
)
284 SetAPen(rp
, GetOutlinePen(rp
));
286 DrawEllipse(rp
,CurVctr
[0],
291 SetAPen(rp
, Rem_APen
);
294 CurVctr
= &CurVctr
[4];
295 CurFlag
= &CurFlag
[2];
297 last_idx
++; /* there were two coords here! */
299 /* set first_idx for a possible next polygon to draw */
300 first_idx
= last_idx
+ 1;
304 /* this is an error */
305 SetAPen(rp
, Rem_APen
);
306 /* also restore old graphics cursor position */
311 } /* switch((unsigned char)CurFlag[0]) */
314 } /* while (Count > 0) */
316 /* restore areainfo structure for a new beginning */
317 areainfo
->VctrPtr
= areainfo
->VctrTbl
;
318 areainfo
->FlagPtr
= areainfo
->FlagTbl
;
321 /* restore old APen */
322 SetAPen(rp
, Rem_APen
);
323 /* also restore old graphics cursor position */
327 } /* if vectorlist is not empty and rastport has a tmpras */