5 static void mul_xcoords(void)
9 for(i
= 0; i
<= numpoints
; i
++)
11 points
[i
][0] *= X_FRACTION
;
15 static void div_xcoords(void)
19 for(i
= 0; i
<= numpoints
; i
++)
21 points
[i
][0] /= X_FRACTION
;
25 void LineInTmpRas(struct RastPort
* rp
,
26 struct Rectangle
* bounds
,
31 struct GfxBase
* GfxBase
);
53 UWORD
Include (UWORD lastused
,
55 struct BoundLine
* AreaBound
,
59 while (lastused
< lastindex
&&
60 VctTbl
[AreaBound
[lastused
+1].StartIndex
+1] == scan
)
63 kprintf("including new one! ");
64 kprintf("(%d,%d)-(%d,%d)\n",VctTbl[AreaBound[lastused+1].StartIndex],
65 VctTbl[AreaBound[lastused+1].StartIndex+1],
66 VctTbl[AreaBound[lastused+1].EndIndex],
67 VctTbl[AreaBound[lastused+1].EndIndex]);
74 void FillScan(UWORD StartIndex
,
76 struct BoundLine
* AreaBound
,
79 struct Rectangle
* bounds
,
81 struct GfxBase
* GfxBase
)
87 /* simply draw a line */
88 while (FALSE
== AreaBound
[i
].Valid
)
91 if (i
> EndIndex
) return;
94 x1
=(AreaBound
[i
].RightX
+ X_FRACTION
/ 2) / X_FRACTION
;
96 x1
=AreaBound
[i
].RightX
+1;
99 while (FALSE
== AreaBound
[i
+1].Valid
)
102 if (i
> EndIndex
) return;
105 if (x1
<= AreaBound
[i
+1].LeftX
-1)
112 AreaBound
[i
+1].LeftX
/ X_FRACTION
,
114 AreaBound
[i
+1].LeftX
-1,
125 void XSort(UWORD StartIndex
,
127 struct BoundLine
* AreaBound
)
129 /* a simple bubble sort */
130 struct BoundLine tmpAreaBound
;
131 int i
= StartIndex
+1;
133 //kprintf("%d,%d\n",StartIndex,EndIndex);
135 //kprintf("%d ",AreaBound[StartIndex].LeftX);
137 while (i
<= EndIndex
)
139 if (AreaBound
[i
].LeftX
< AreaBound
[i
-1].LeftX
)
141 /* The one at index i needs to go more to smaller indices */
143 //kprintf("sorting!!\n");
144 tmpAreaBound
= AreaBound
[i
];
147 AreaBound
[i2
] = AreaBound
[i2
-1];
149 if (i2
== StartIndex
||
150 AreaBound
[i2
-1].LeftX
<= tmpAreaBound
.LeftX
)
152 AreaBound
[i2
] = tmpAreaBound
;
158 //kprintf("%d ",AreaBound[i].LeftX);
165 UWORD
UpdateXValues(UWORD StartIndex
,
168 struct BoundLine
* AreaBound
,
172 BOOL foundvalid
= FALSE
;
174 while (i
<= EndIndex
)
176 /* Test whether this one is still to be considered */
178 if ( VctTbl
[AreaBound
[i
].EndIndex
+1] <= scan
||
179 AreaBound
[i
].Valid
== FALSE
)
182 if (AreaBound[i].Valid == FALSE)
183 kprintf ("already marked as invalid! ");
185 kprintf("marking %d as anvalid! ",i);
186 kprintf("(%d,%d)-(%d,%d)\n",VctTbl[AreaBound[i].StartIndex],
187 VctTbl[AreaBound[i].StartIndex+1],
188 VctTbl[AreaBound[i].EndIndex],
189 VctTbl[AreaBound[i].EndIndex+1]);
191 AreaBound
[i
].Valid
= FALSE
;
192 if (FALSE
== foundvalid
)
195 /* It is still to be considered!! */
197 /* calculate the new x-coordinates for the new line */
198 if (0 == AreaBound
[i
].DeltaX
)
200 /* a vertical line !!! easy!! */
205 AreaBound
[i
].RightX
+= AreaBound
[i
].NRightX
;
206 AreaBound
[i
].LeftX
+= AreaBound
[i
].NLeftX
;
207 AreaBound
[i
].NRightX
= 0;
208 AreaBound
[i
].NLeftX
= 0;
210 * If we're moving more in the horizontal
211 * than in the vertical, then the line
212 * has a pure horizontal component which I
213 * must take care of by not painting over it.
214 * This means that on a y coordinate the line
215 * can go from the LeftX to the RightX.
217 if (1 == AreaBound
[i
].horiz
) {
219 * More towards the horizontal than down
221 if (AreaBound
[i
].s1
> 0) {
222 AreaBound
[i
].LeftX
= AreaBound
[i
].RightX
;
224 AreaBound
[i
].RightX
= AreaBound
[i
].LeftX
;
230 if (AreaBound
[i
].Count
<= 0) {
231 AreaBound
[i
].Count
+= AreaBound
[i
].incrE
;
232 if (1 == AreaBound
[i
].t
) {
233 if (AreaBound
[i
].s1
> 0) {
237 AreaBound
[i
].RightX
++;
242 AreaBound
[i
].LeftX
--;
246 * Going to next Y coordinate
251 AreaBound
[i
].Count
+= AreaBound
[i
].incrNE
;
253 * Going to next Y coordinate
255 if (AreaBound
[i
].s1
> 0) {
259 AreaBound
[i
].NRightX
= 1;
264 AreaBound
[i
].NLeftX
= -1;
271 * If we're going more vertical than horizontal
272 * then the left and right are always the same.
274 if (0 == AreaBound
[i
].horiz
) {
275 if (AreaBound
[i
].s1
> 0) {
277 AreaBound[i].RightX += AreaBound[i].NRightX;
278 AreaBound[i].NRightX = 0;
280 AreaBound
[i
].LeftX
= AreaBound
[i
].RightX
;
283 AreaBound[i].LeftX += AreaBound[i].NLeftX;
284 AreaBound[i].NLeftX = 0;
286 AreaBound
[i
].RightX
= AreaBound
[i
].LeftX
;
296 /* functions for filling of the RastPort */
297 BOOL
areafillpolygon(struct RastPort
* rp
,
298 struct Rectangle
* bounds
,
302 struct GfxBase
* GfxBase
)
309 UWORD LastEdge
= last_idx
- first_idx
+ 1; // needed later on. Don't change!!
311 struct AreaInfo
* areainfo
= rp
->AreaInfo
;
312 UWORD
* StartVctTbl
= &areainfo
->VctrTbl
[first_idx
* 2];
314 UWORD
* StartVctTbl
= (UWORD
*)points
;
318 struct BoundLine tmpAreaBound
;
319 struct BoundLine
* AreaBound
=
320 (struct BoundLine
*) AllocMem(sizeof(struct BoundLine
) * LastEdge
,
323 if (NULL
== AreaBound
)
330 /* first clear the buffer of the temporary rastport as far as necessary */
332 memset(rp
->TmpRas
->RasPtr
,
334 BytesPerRow
* (bounds
->MaxY
- bounds
->MinY
+ 1));
338 kprintf("first: %d, last: %d\n",first_idx
,last_idx
);
339 kprintf("(%d,%d)-(%d,%d)\n",bounds
->MinX
,bounds
->MinY
,
340 bounds
->MaxX
,bounds
->MaxY
);
341 kprintf("width: %d, bytesperrow: %d\n",bounds
->MaxX
- bounds
->MinX
+ 1,
345 /* I need a list of sorted indices that represent the lines of the
346 ** polygon. Horizontal lines don't go into that list!!!
347 ** The lines are sorted by their start-y coordinates.
353 /* process all points of the polygon */
354 while (c
< (LastEdge
-1)*2)
357 /* is the next one starting point of a horizontal line??? If yes,
360 //kprintf("current idx for y: %d, next idx for y: %d\n",c+1,c+3);
362 if (StartVctTbl
[c
+1] == StartVctTbl
[c
+3])
364 //kprintf("Found horizontal Line!!\n");
369 /* which coordinate of this line has the lower y value */
370 if (StartVctTbl
[c
+1] < StartVctTbl
[c
+3])
372 tmpAreaBound
.StartIndex
= c
;
373 tmpAreaBound
.EndIndex
= c
+2;
374 ymin
= StartVctTbl
[c
+1];
378 tmpAreaBound
.StartIndex
= c
+2;
379 tmpAreaBound
.EndIndex
= c
;
380 ymin
= StartVctTbl
[c
+3];
385 kprintf("line: (%d,%d)-(%d,%d) ",StartVctTbl
[c
],
389 kprintf("miny: %d\n",ymin
);
393 ** search for the place where to put this entry into the sorted
394 ** (increasing start y-coordinates) list
401 //kprintf("ymin: %d< %d?\n",ymin,StartVctTbl[AreaBound[i2].StartIndex+1]);
403 if (ymin
< StartVctTbl
[AreaBound
[i2
].StartIndex
+1])
406 /* found the place! */
410 //kprintf("moving!\n");
412 AreaBound
[i3
].StartIndex
= AreaBound
[i3
-1].StartIndex
;
413 AreaBound
[i3
].EndIndex
= AreaBound
[i3
-1].EndIndex
;
416 AreaBound
[i2
].StartIndex
= tmpAreaBound
.StartIndex
;
417 AreaBound
[i2
].EndIndex
= tmpAreaBound
.EndIndex
;
424 //kprintf("at end!\n");
426 AreaBound
[i
+1].StartIndex
= tmpAreaBound
.StartIndex
;
427 AreaBound
[i
+1].EndIndex
= tmpAreaBound
.EndIndex
;
432 else /* first one to insert into list */
434 AreaBound
[0].StartIndex
= tmpAreaBound
.StartIndex
;
435 AreaBound
[0].EndIndex
= tmpAreaBound
.EndIndex
;
447 while (i2
<= LastIndex
)
450 kprintf("%d.: index %d (%d,%d)-(%d,%d)\n",i2
,AreaBound
[i2
].StartIndex
,
451 StartVctTbl
[AreaBound
[i2
].StartIndex
],
452 StartVctTbl
[AreaBound
[i2
].StartIndex
+1],
453 StartVctTbl
[AreaBound
[i2
].EndIndex
],
454 StartVctTbl
[AreaBound
[i2
].EndIndex
+1]);
461 while (i
<= LastIndex
)
463 int StartIndex
= AreaBound
[i
].StartIndex
;
464 int EndIndex
= AreaBound
[i
].EndIndex
;
466 if ((StartVctTbl
[EndIndex
] - StartVctTbl
[StartIndex
]) > 0) {
469 AreaBound
[i
].s1
= -1;
472 AreaBound
[i
].DeltaX
= abs(StartVctTbl
[EndIndex
] -
473 StartVctTbl
[StartIndex
]);
475 AreaBound
[i
].DeltaY
= abs(StartVctTbl
[EndIndex
+1] -
476 StartVctTbl
[StartIndex
+1]);
478 if (AreaBound
[i
].DeltaX
> AreaBound
[i
].DeltaY
) {
479 AreaBound
[i
].horiz
= 1;
483 if (AreaBound
[i
].DeltaX
< AreaBound
[i
].DeltaY
) {
484 WORD d
= AreaBound
[i
].DeltaX
;
485 AreaBound
[i
].DeltaX
= AreaBound
[i
].DeltaY
;
486 AreaBound
[i
].DeltaY
= d
;
492 AreaBound
[i
].Count
= (AreaBound
[i
].DeltaY
* 2) - AreaBound
[i
].DeltaX
;
493 AreaBound
[i
].incrE
= AreaBound
[i
].DeltaY
* 2;
494 AreaBound
[i
].incrNE
= (AreaBound
[i
].DeltaY
- AreaBound
[i
].DeltaX
) * 2;
496 AreaBound
[i
].LeftX
= AreaBound
[i
].RightX
= StartVctTbl
[StartIndex
];
497 AreaBound
[i
].Valid
= TRUE
;
501 /* indexlist now contains i+1 indices into the vector table.
502 Either the coordinate at the index as declared in the indexlist
503 contains the lower y value or the following coordinate */
510 EndEdge
= Include(1, LastIndex
, AreaBound
, scan
, StartVctTbl
);
511 StartEdge
= UpdateXValues(StartEdge
, EndEdge
, scan
, AreaBound
, StartVctTbl
);
513 while (scan
< bounds
->MaxY
)
515 XSort(StartEdge
, EndEdge
, AreaBound
);
517 if (scan
> bounds
->MinY
)
529 kprintf("scanline: %d StartEdge: %d, EndEdge: %d\n",scan
,StartEdge
,EndEdge
);
535 if (TRUE
== AreaBound
[x
].Valid
)
537 kprintf("(%d,%d)-(%d,%d) currently at: Left: %d Right: %d\n",
538 StartVctTbl
[AreaBound
[x
].StartIndex
],
539 StartVctTbl
[AreaBound
[x
].StartIndex
+1],
540 StartVctTbl
[AreaBound
[x
].EndIndex
],
541 StartVctTbl
[AreaBound
[x
].EndIndex
+1],
543 AreaBound
[x
].RightX
);
546 kprintf("invalid\n");
553 EndEdge
= Include(EndEdge
, LastIndex
, AreaBound
, scan
, StartVctTbl
);
554 StartEdge
= UpdateXValues(StartEdge
, EndEdge
, scan
, AreaBound
, StartVctTbl
);
556 // kprintf("StartEdge: %d, EndEdge: %d\n",StartEdge,EndEdge);
560 FreeMem( AreaBound
, sizeof(struct BoundLine
) * LastEdge
);
575 if (rp
->Flags
& AREAOUTLINE
)
577 SetAPen(rp
, GetOutlinePen(rp
));
580 Move(rp
, points
[0][0], points
[0][1]);
581 PolyDraw(rp
, numpoints
+ 1, (UWORD
*)points
);
587 void LineInTmpRas(struct RastPort
* rp
,
588 struct Rectangle
* bounds
,
593 struct GfxBase
* GfxBase
)
599 UWORD
* RasPtr
= (WORD
*)rp
->TmpRas
->RasPtr
;
602 //kprintf("(%d/%d) to (%d/%d)\n",xleft,y,xright,y);
604 /* adjust the coordinates */
605 xleft
-= bounds
->MinX
;
606 xright
-= bounds
->MinX
;
609 //kprintf("line from %d to %d y = %d\n",xleft,xright,y);
611 if (xleft
> xright
) return;
613 an algorithm that tries to minimize the number of accesses to the
617 /* Fill the first word */
620 /* determine the number of pixels to set at the beginning */
621 NumPixels
= xright
- xleft
+ 1;
625 /* create enough pixels */
626 PixelMask
>>= (NumPixels
- 1);
628 index
= (y
* (BytesPerRow
>> 1)) + (xleft
>> 4);
629 /* Adjust the pixelmask so we hit the very first pixel */
630 PixelMask2
= PixelMask
& 0xffff;
631 if (0 != (shift
= (xleft
& 0x0f))) {
632 PixelMask2
>>= shift
;
635 #if (AROS_BIG_ENDIAN == 0)
636 /* Endianess conversion*/
637 PixelMask2
= PixelMask2
<< 8 | PixelMask2
>> 8;
639 RasPtr
[index
] |= PixelMask2
;
640 //kprintf("%x (left)\n",PixelMask2);
644 xleft
= xleft
+ (16 - shift
);
646 if ((xright
- xleft
) < 16)
649 /* fill the middle with 0xffff's */
650 while ((xleft
+ 15) < xright
)
652 RasPtr
[index
] = (WORD
)0xffff;
661 /* Create enough pixels - one pixel is already there! */
662 if (0 != (shift
= (xright
- xleft
+ 0))) {
666 PixelMask2
= PixelMask
& 0xffff;
668 #if (AROS_BIG_ENDIAN == 0)
669 /* Endianess conversion*/
670 PixelMask2
= PixelMask2
<< 8 | PixelMask2
>> 8;
673 RasPtr
[index
] |= PixelMask2
;
674 //kprintf("%x (right)\n",PixelMask2);
680 void MyFillPolygon(struct RastPort
*rp
, WORD points
[][2], WORD numpoints
)
682 struct Rectangle bounds
;
686 points
[numpoints
][0] = points
[0][0];
687 points
[numpoints
][1] = points
[0][1];
689 bounds
.MinX
= bounds
.MinY
= 32767;
690 bounds
.MaxX
= bounds
.MaxY
= -32768;
692 for(i
= 0; i
<= numpoints
; i
++)
694 if (points
[i
][0] < bounds
.MinX
) bounds
.MinX
= points
[i
][0];
695 if (points
[i
][1] < bounds
.MinY
) bounds
.MinY
= points
[i
][1];
696 if (points
[i
][0] > bounds
.MaxX
) bounds
.MaxX
= points
[i
][0];
697 if (points
[i
][1] > bounds
.MaxY
) bounds
.MaxY
= points
[i
][1];
700 bpr
= (((bounds
.MaxX
- bounds
.MinX
+ 1) + 15) & ~15) / 8;
702 kprintf("Myfillpolygon: bpr %d bounds %d,%d - %d,%d\n",
703 bpr
, bounds
.MinX
, bounds
.MinY
, bounds
.MaxX
, bounds
.MaxY
);
705 areafillpolygon(rp
, &bounds
, 0, numpoints
, bpr
, GfxBase
);