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() graphics/rastport.h
66 *****************************************************************************/
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
)
78 UWORD
* CurVctr
= areainfo
-> VctrTbl
;
79 BYTE
* CurFlag
= areainfo
-> FlagTbl
;
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 */
100 //kprintf("\n******** Flags:%d Coord: (%d,%d)\n",CurFlag[0], CurVctr[0],CurVctr[1]);
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];
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.
125 if (rp
->cp_y
<= CurVctr
[1]) {
126 Draw(rp
, CurVctr
[0], CurVctr
[1]);
130 rp
->cp_x
= CurVctr
[0];
131 rp
->cp_y
= CurVctr
[1];
133 rp
->cp_x
= CurVctr
[0];
134 rp
->cp_y
= CurVctr
[1];
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;
154 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
156 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 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,
167 if (areafillpolygon(rp
,
175 Blit the area fill pattern through the mask provided
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
);
199 /* set first_idx for a possible next polygon to draw */
200 first_idx
= last_idx
+ 1;
203 case AREAINFOFLAG_DRAW
:
204 /* Draw a line to new position */
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]);
215 rp
->cp_x
= CurVctr
[0];
216 rp
->cp_y
= CurVctr
[1];
218 rp
->cp_x
= CurVctr
[0];
219 rp
->cp_y
= CurVctr
[1];
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];
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;
244 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
246 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 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],
258 /* area-fill the ellipse with the pattern given
259 in rp->AreaPtrn , AreaPtSz */
267 Blit the area fill pattern through the mask provided
281 if (rp
->Flags
& AREAOUTLINE
)
283 SetAPen(rp
, GetOutlinePen(rp
));
285 DrawEllipse(rp
,CurVctr
[0],
290 SetAPen(rp
, Rem_APen
);
293 CurVctr
= &CurVctr
[4];
294 CurFlag
= &CurFlag
[2];
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;
303 /* this is an error */
304 SetAPen(rp
, Rem_APen
);
305 /* also restore old graphics cursor position */
310 } /* switch((unsigned char)CurFlag[0]) */
313 } /* while (Count > 0) */
315 /* restore areainfo structure for a new beginning */
316 areainfo
->VctrPtr
= areainfo
->VctrTbl
;
317 areainfo
->FlagPtr
= areainfo
->FlagTbl
;
320 /* restore old APen */
321 SetAPen(rp
, Rem_APen
);
322 /* also restore old graphics cursor position */
326 } /* if vectorlist is not empty and rastport has a tmpras */