[AD] polygon patch

[ 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;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/