2 Copyright © 1995-2013, 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 UWORD Rem_Flags
= rp
->Flags
;
84 /* I don't know whether this function may corrupt the
85 cursor position of the rastport. So I save it for later.*/
87 UWORD Rem_cp_x
= rp
->cp_x
;
88 UWORD Rem_cp_y
= rp
->cp_y
;
89 /* This rectangle serves as a "frame" for the tmpras for filling */
90 struct Rectangle bounds
;
93 areaclosepolygon(areainfo
);
95 Count
= areainfo
->Count
;
97 //kprintf("%d coord to process\n",Count);
99 /* process the list of vectors */
102 //kprintf("\n******** Flags:%d Coord: (%d,%d)\n",CurFlag[0], CurVctr[0],CurVctr[1]);
105 switch((unsigned char)CurFlag
[0])
107 case AREAINFOFLAG_MOVE
:
108 /* set the graphical cursor to a starting position */
109 Move(rp
, CurVctr
[0], CurVctr
[1]);
111 bounds
.MinX
= CurVctr
[0];
112 bounds
.MaxX
= CurVctr
[0];
113 bounds
.MinY
= CurVctr
[1];
114 bounds
.MaxY
= CurVctr
[1];
116 CurVctr
= &CurVctr
[2];
117 CurFlag
= &CurFlag
[1];
120 case AREAINFOFLAG_CLOSEDRAW
:
121 /* this indicates that this Polygon is closed with this coordinate */
123 * Must draw from lower y's to higher ones otherwise
124 * the fill algo does not work nicely.
127 if (rp
->cp_y
<= CurVctr
[1]) {
128 Draw(rp
, CurVctr
[0], CurVctr
[1]);
132 rp
->cp_x
= CurVctr
[0];
133 rp
->cp_y
= CurVctr
[1];
135 rp
->cp_x
= CurVctr
[0];
136 rp
->cp_y
= CurVctr
[1];
139 CurVctr
= &CurVctr
[2];
140 CurFlag
= &CurFlag
[1];
142 no need to set the boundaries here like in case above as
143 this coord closes the polygon and therefore is the same
144 one as the first coordinate of the polygon.
146 /* check whether there's anything to fill at all. I cannot
147 fill a line (=3 coordinates) */
148 if (first_idx
+2 <= last_idx
)
150 /* BytesPerRow must be a multiple of 2 bytes */
152 BytesPerRow
= bounds
.MaxX
- bounds
.MinX
+ 1;
153 if (0 != (BytesPerRow
& 0x0f ))
154 BytesPerRow
=((BytesPerRow
>> 3) & 0xfffe )+ 2;
156 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
158 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 1))
162 kprintf("first: %d, last: %d\n",first_idx,last_idx);
163 kprintf("(%d,%d)-(%d,%d)\n",bounds.MinX,bounds.MinY,
164 bounds.MaxX,bounds.MaxY);
165 kprintf("width: %d, bytesperrow: %d\n",bounds.MaxX-bounds.MinX+1,
169 if (areafillpolygon(rp
,
177 Blit the area fill pattern through the mask provided
191 if (rp
->Flags
& AREAOUTLINE
)
193 SetAPen(rp
, GetOutlinePen(rp
));
194 PolyDraw(rp
, last_idx
- first_idx
+ 1, &areainfo
->VctrTbl
[first_idx
* 2]);
195 SetAPen(rp
, Rem_APen
);
196 rp
->Flags
= Rem_Flags
;
202 /* set first_idx for a possible next polygon to draw */
203 first_idx
= last_idx
+ 1;
206 case AREAINFOFLAG_DRAW
:
207 /* Draw a line to new position */
210 * Must draw from lower y's to higher ones otherwise
211 * the fill algo does not work nicely.
213 if (rp
->cp_y
<= CurVctr
[1]) {
214 Draw(rp
, CurVctr
[0], CurVctr
[1]);
218 rp
->cp_x
= CurVctr
[0];
219 rp
->cp_y
= CurVctr
[1];
221 rp
->cp_x
= CurVctr
[0];
222 rp
->cp_y
= CurVctr
[1];
225 if (bounds
.MinX
> CurVctr
[0])
226 bounds
.MinX
= CurVctr
[0];
227 if (bounds
.MaxX
< CurVctr
[0])
228 bounds
.MaxX
= CurVctr
[0];
229 if (bounds
.MinY
> CurVctr
[1])
230 bounds
.MinY
= CurVctr
[1];
231 if (bounds
.MaxY
< CurVctr
[1])
232 bounds
.MaxY
= CurVctr
[1];
233 CurVctr
= &CurVctr
[2];
234 CurFlag
= &CurFlag
[1];
237 case AREAINFOFLAG_ELLIPSE
:
238 bounds
.MinX
= CurVctr
[0] - CurVctr
[2];
239 bounds
.MaxX
= CurVctr
[0] + CurVctr
[2];
240 bounds
.MinY
= CurVctr
[1] - CurVctr
[3];
241 bounds
.MaxY
= CurVctr
[1] + CurVctr
[3];
242 BytesPerRow
= bounds
.MaxX
- bounds
.MinX
+ 1;
244 if (0 != (BytesPerRow
& 0x0f ))
245 BytesPerRow
=((BytesPerRow
>> 3) & 0xfffe )+ 2;
247 BytesPerRow
= (BytesPerRow
>> 3) & 0xfffe;
249 if ((ULONG
)rp
->TmpRas
->Size
< BytesPerRow
* (bounds
.MaxY
- bounds
.MinY
+ 1))
252 /* Draw an Ellipse and fill it */
253 /* see how the data are stored by the second entry */
254 /* I get cx,cy,cx+a,cy+b*/
256 DrawEllipse(rp
,CurVctr
[0],
261 /* area-fill the ellipse with the pattern given
262 in rp->AreaPtrn , AreaPtSz */
270 Blit the area fill pattern through the mask provided
284 if (rp
->Flags
& AREAOUTLINE
)
286 SetAPen(rp
, GetOutlinePen(rp
));
288 DrawEllipse(rp
,CurVctr
[0],
293 SetAPen(rp
, Rem_APen
);
294 rp
->Flags
= Rem_Flags
;
297 CurVctr
= &CurVctr
[4];
298 CurFlag
= &CurFlag
[2];
300 last_idx
++; /* there were two coords here! */
302 /* set first_idx for a possible next polygon to draw */
303 first_idx
= last_idx
+ 1;
307 /* this is an error */
308 SetAPen(rp
, Rem_APen
);
309 rp
->Flags
= Rem_Flags
;
311 /* also restore old graphics cursor position */
316 } /* switch((unsigned char)CurFlag[0]) */
319 } /* while (Count > 0) */
321 /* restore areainfo structure for a new beginning */
322 areainfo
->VctrPtr
= areainfo
->VctrTbl
;
323 areainfo
->FlagPtr
= areainfo
->FlagTbl
;
326 /* restore old graphics cursor position */
330 } /* if vectorlist is not empty and rastport has a tmpras */