[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
I just committed th attached patch by Erno, from the bug tracker:
http://sourceforge.net/tracker/index.php?func=detail&aid=1692717&group_id=5665&atid=105665
It fixes the long standing issue of polygon() not drawing pixels in the
bottom-most line. Unfortunately, it comes with a performance cost, so if
anyone feels like optimizing it again, that would be nice (myself, I
must admit, I don't know how the polygon() function works, so no idea
where I would even start..).
--
Elias Pschernig
Index: src/polygon.c
===================================================================
--- src/polygon.c (revision 7828)
+++ src/polygon.c (working copy)
@@ -38,16 +38,21 @@
}
edge->top = i1[1];
- edge->bottom = i2[1] - 1;
- edge->dx = ((i2[0] - i1[0]) << POLYGON_FIX_SHIFT) / (i2[1] - i1[1]);
- edge->x = (i1[0] << POLYGON_FIX_SHIFT) + (1<<(POLYGON_FIX_SHIFT-1)) - 1;
+ edge->bottom = i2[1];
+ edge->x = (i1[0] << POLYGON_FIX_SHIFT) + (1<<(POLYGON_FIX_SHIFT-1));
+ if(i2[1] != i1[1])
+ {
+ edge->dx = ((i2[0] - i1[0]) << POLYGON_FIX_SHIFT) / (i2[1] - i1[1]);
+ }
+ else
+ {
+ edge->dx = ((i2[0] - i1[0]) << POLYGON_FIX_SHIFT)<<1;
+ }
+ edge->w = MAX(ABS(edge->dx)-1, 0);
edge->prev = NULL;
edge->next = NULL;
-
if (edge->dx < 0)
- edge->x += MIN(edge->dx+(1<<POLYGON_FIX_SHIFT), 0);
-
- edge->w = MAX(ABS(edge->dx)-(1<<POLYGON_FIX_SHIFT), 0);
+ edge->x += edge->dx/2 ;
}
@@ -61,8 +66,8 @@
POLYGON_EDGE *prev = NULL;
if (sort_by_x) {
- while ((pos) && ((pos->x + (pos->w + pos->dx) / 2) <
- (edge->x + (edge->w + edge->dx) / 2))) {
+ while ((pos) && ((pos->x ) <
+ (edge->x))) {
prev = pos;
pos = pos->next;
}
@@ -132,7 +137,7 @@
i2 = points + (vertices-1) * 2;
for (c=0; c<vertices; c++) {
- if (i1[1] != i2[1]) {
+ {
fill_edge_structure(edge, i1, i2);
if (edge->bottom >= edge->top) {
@@ -170,10 +175,58 @@
/* draw horizontal line segments */
edge = active_edges;
- while ((edge) && (edge->next)) {
- bmp->vtable->hfill(bmp, edge->x>>POLYGON_FIX_SHIFT, c,
- (edge->next->x+edge->next->w)>>POLYGON_FIX_SHIFT, color);
- edge = edge->next->next;
+ int hid = 0;
+ int b1 = 0;
+ int e1 = 0;
+ int up = 0;
+ int draw = 0;
+ int e;
+ while (edge) {
+ e=edge->w;
+ if(edge->bottom != c) {
+ up = 1 - up;
+ }
+ else
+ {
+ e = edge->w >> 1;
+ }
+
+ if(edge->top != c) {
+ }
+ else
+ {
+ e = edge->w >> 1;
+ }
+
+ if( (draw < 1) && ( up >= 1))
+ {
+ b1=(edge->x + e)>> POLYGON_FIX_SHIFT;
+ }
+//filling the polygon
+ else if( (draw >= 1 ) )
+ {
+ e1=(edge->x ) >> POLYGON_FIX_SHIFT;
+ hid=MAX(hid,b1+1);
+
+ if(hid<=e1-1)
+ bmp->vtable->hfill(bmp, hid, c,
+ e1-1, color);
+
+ b1=(edge->x + e)>> POLYGON_FIX_SHIFT;
+
+ }
+//drawing the edge
+
+ hid=MAX(hid,(edge->x) >> POLYGON_FIX_SHIFT);
+ if(hid<=((edge->x+e) >> POLYGON_FIX_SHIFT))
+ {
+ bmp->vtable->hfill(bmp, hid, c,
+ (edge->x+e)>>POLYGON_FIX_SHIFT, color);
+ hid=1+((edge->x+e) >> POLYGON_FIX_SHIFT);
+ }
+
+ edge = edge->next;
+ draw = up;
}
/* update edges, sorting and removing dead ones */
@@ -185,8 +238,16 @@
}
else {
edge->x += edge->dx;
+ if( (edge->top == c) && (edge->dx > 0))
+ {
+ edge->x -= edge->dx/2;
+ }
+ if( (edge->bottom == c+1) && (edge->dx < 0))
+ {
+ edge->x -= edge->dx/2;
+ }
while ((edge->prev) &&
- (edge->x+edge->w/2 < edge->prev->x+edge->prev->w/2)) {
+ (edge->x < edge->prev->x)) {
if (edge->next)
edge->next->prev = edge->prev;
edge->prev->next = edge->next;