diff --git a/src/modules/Image/polyfill.c b/src/modules/Image/polyfill.c
index 9e1a2c2fa1c8b377555c0c59ebfde831033c694f..dac374ff6dacce292133a2056aa4155371e80407 100644
--- a/src/modules/Image/polyfill.c
+++ b/src/modules/Image/polyfill.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: polyfill.c,v 1.20 1998/04/08 15:41:21 mirar Exp $");
+RCSID("$Id: polyfill.c,v 1.21 1998/04/09 02:00:23 mirar Exp $");
 
 /* Prototypes are needed for these */
 extern double floor(double);
@@ -27,12 +27,12 @@ extern double floor(double);
 #define THIS ((struct image *)(fp->current_storage))
 #define THISOBJ (fp->current_object)
 
-#undef POLYDEBUG
+#define POLYDEBUG
 
 /*
 **! module Image
 **! note
-**!	$Id: polyfill.c,v 1.20 1998/04/08 15:41:21 mirar Exp $
+**!	$Id: polyfill.c,v 1.21 1998/04/09 02:00:23 mirar Exp $
 **! class image
 */
 
@@ -58,11 +58,11 @@ extern double floor(double);
 **! see also: setcolor
 */
 
-struct vertex_list
+struct line_list
 {
    struct vertex *above,*below;
    float dx,dy;
-   struct vertex_list *next;
+   struct line_list *next;
    float xmin,xmax,yxmin,yxmax; /* temporary storage */
 };
 
@@ -70,7 +70,7 @@ struct vertex
 {
    float x,y;
    struct vertex *next;    /* total list, sorted downwards */
-   struct vertex_list *below,*above; /* childs */
+   struct line_list *below,*above; /* childs */
    int done;
 };
 
@@ -85,6 +85,8 @@ struct vertex *vertex_new(float x,float y,struct vertex **top)
        (*top)->x==x && (*top)->y==y) return *top; /* found one */
 
    c=malloc(sizeof(struct vertex));
+fprintf(stderr,"alloc %lx\n",c);
+   if (!c) return NULL;
    c->x=x;
    c->y=y;
    c->next=*top;
@@ -98,12 +100,14 @@ struct vertex *vertex_new(float x,float y,struct vertex **top)
 static void vertex_connect(struct vertex *above,
 			   struct vertex *below)
 {
-   struct vertex_list *c,*d;
+   struct line_list *c,*d;
    float diff;
 
    if (below==above) return;
 
-   c = malloc(sizeof(struct vertex_list));
+   c = malloc(sizeof(struct line_list));
+fprintf(stderr,"alloc con: %lx %lx<->%lx\n",c,above,below);
+   if (!c) return;
    c->above = above; c->below = below;
    c->next = above->below;
    if (((diff = (below->y - above->y)) < 1.0e-10) &&
@@ -118,7 +122,8 @@ static void vertex_connect(struct vertex *above,
      c->dy = (below->y - above->y)/diff;
    above->below = c;
 
-   d = malloc(sizeof(struct vertex_list));
+   d = malloc(sizeof(struct line_list));
+fprintf(stderr,"alloc con: %lx %lx<->%lx\n",d,above,below);
    d->above = above; d->below = below;
    d->next = below->above;
    d->dx = c->dx;
@@ -126,7 +131,7 @@ static void vertex_connect(struct vertex *above,
    below->above = d;
 }
 
-static INLINE float vertex_xmax(struct vertex_list *v,float yp,float *ydest)
+static INLINE float line_xmax(struct line_list *v,float yp,float *ydest)
 {
    if (v->dx>0.0) {
       if (v->below->y>yp+1.0+1e-10)
@@ -144,7 +149,7 @@ static INLINE float vertex_xmax(struct vertex_list *v,float yp,float *ydest)
       return (*ydest=v->below->y),v->below->x;
 }
 
-static INLINE float vertex_xmin(struct vertex_list *v,float yp,float *ydest)
+static INLINE float line_xmin(struct line_list *v,float yp,float *ydest)
 {
    if (v->dx<0.0) {
       if (v->below->y>yp+1.0+1e-10)
@@ -162,29 +167,27 @@ static INLINE float vertex_xmin(struct vertex_list *v,float yp,float *ydest)
       return (*ydest=v->above->y),v->above->x;
 }
 
-static void add_vertices(struct vertex_list **first,
-			 struct vertex_list *what,
+static void add_vertices(struct line_list **first,
+			 struct line_list *what,
 			 float yp)
 {
-   struct vertex_list **ins,*c;
-
-   c=*first;
-   while (c)
-   {
-      c->xmin=vertex_xmin(c,yp,&c->yxmin);
-      c->xmax=vertex_xmax(c,yp,&c->yxmax);
-      c=c->next;
-   }
+   struct line_list **ins,*c;
+#ifdef POLYDEBUG
+   char *why="unknown";
+#define BECAUSE(X) (why=(X))
+#else
+#define BECAUSE(X)
+#endif
 
    while (what)
    {
-      what->xmin=vertex_xmin(what,yp,&what->yxmin);
-      what->xmax=vertex_xmax(what,yp,&what->yxmax);
+      what->xmin=line_xmin(what,yp,&what->yxmin);
+      what->xmax=line_xmax(what,yp,&what->yxmax);
 
       ins=first;
 
 #ifdef POLYDEBUG
-   fprintf(stderr,"insert %g,%g - %g,%g  %g,%g - %g,%g\n",
+   fprintf(stderr,"  insert %g,%g - %g,%g  %g,%g - %g,%g\n",
 	  what->above->x,what->above->y,
 	  what->below->x,what->below->y,
 	  what->xmin,what->yxmin,
@@ -203,25 +206,39 @@ static void add_vertices(struct vertex_list **first,
       while (*ins)
       {
 	 /* case: -what-> <-ins- */
-	 if ((*ins)->xmin>=what->xmax)  break; /* place left of */
+	 BECAUSE("what is left of ins");
+	 if ((*ins)->xmin>=what->xmax)  
+	    break; /* place left of */
 
 	 /* case: -what-    */
 	 /*          <-ins- */
 	 if ((*ins)->xmin>what->xmin)
-	    { if ((*ins)->yxmin>VY(what,(*ins)->xmin)) break; }
+	 { 
+	    BECAUSE("ins is below (right) what");
+	    if ((*ins)->yxmin>VY(what,(*ins)->xmin)) break; 
+	 }
 	 /* case:   <-what-    */
 	 /*       -ins-        */
 	 else 
-	    { if (VY((*ins),what->xmin)>what->yxmin) break; }
+	 {
+	    BECAUSE("what is above ins (left)");
+	    if (VY((*ins),what->xmin)>what->yxmin) break; 
+	 }
 
 	 /* case: -what->    */
 	 /*           -ins-  */
 	 if ((*ins)->xmax>what->xmax)
-	    { if (VY((*ins),what->xmax)>what->yxmax) break; }
+	 { 
+	    BECAUSE("what is above ins (right)");
+	    if (VY((*ins),what->xmax)>what->yxmax) break; 
+	 }
 	 /* case:    -what-    */
 	 /*       -ins->       */
 	 else 
-	    { if ((*ins)->yxmax>VY(what,(*ins)->xmax)) break; }
+	 {
+	    BECAUSE("ins is below (left) what");
+	    if ((*ins)->yxmax>VY(what,(*ins)->xmax)) break; 
+	 }
 
 	 ins=&((*ins)->next);
       }
@@ -229,15 +246,17 @@ static void add_vertices(struct vertex_list **first,
 
 #ifdef POLYDEBUG
       if (*ins)
-	 fprintf(stderr," before %g,%g - %g,%g  %g,%g - %g,%g\n",
+	 fprintf(stderr,"     before %g,%g - %g,%g  %g,%g - %g,%g because %s\n",
 		 (*ins)->above->x,(*ins)->above->y,
 		 (*ins)->below->x,(*ins)->below->y,
 		 (*ins)->xmin,(*ins)->yxmin,
-		 (*ins)->xmax,(*ins)->yxmax);
+		 (*ins)->xmax,(*ins)->yxmax,
+		 why);
 #endif
 
 
-      c=malloc(sizeof(struct vertex_list));
+      c=malloc(sizeof(struct line_list));
+fprintf(stderr,"alloc %lx %lx<->%lx\n",c,what->above,what->below);
       *c=*what;
       c->next=*ins;
       *ins=c;
@@ -246,524 +265,324 @@ static void add_vertices(struct vertex_list **first,
    }
 }
 
-static void sub_vertices(struct vertex_list **first,
+static void sub_vertices(struct line_list **first,
 			 struct vertex *below,
 			 float yp)
 {
-   struct vertex_list **ins,*c;
+   struct line_list **ins,*c;
 
    ins=first;
 
 #ifdef POLYDEBUG
-   fprintf(stderr,"remove %lx %g,%g\n",below,below->x,below->y);
+   fprintf(stderr,"  remove %lx <-%g,%g\n",below,below->x,below->y);
 #endif
 
    while (*ins)
    {
       if ((*ins)->below==below) 
       {
+#ifdef POLYDEBUG
+	 fprintf(stderr,"   removing %lx,[%g,%g-%g,%g] %lx,%lx \n",
+		 *ins,
+		 (*ins)->above->x,(*ins)->above->y,
+		 (*ins)->below->x,(*ins)->below->y,
+		 (*ins)->above,(*ins)->below);
+#endif
 	 c=*ins;
 	 *ins=(*ins)->next;
 	 free(c);
       }
       else 
       { 
-#ifdef POLYDEBUG
-	 fprintf(stderr,"%g,%g-%g,%g %lx,%lx\n",
-		 (*ins)->above->x,(*ins)->above->y,
-		 (*ins)->below->x,(*ins)->below->y,
-		 (*ins)->above,(*ins)->below);
-#endif
 	 ins=&((*ins)->next);
       }
    }
 }
 
-static void polyfill_row_fill(float *buf,
-			      float xmin,float xmax)
+static INLINE void polyfill_row_add(float *buf,
+				    float xmin,float xmax,
+				    float add)
 {
    int i;
    int xmin_i = (int)floor(xmin);
    int xmax_i = (int)floor(xmax);
    if (xmax_i<0) return;
    if (xmin_i == xmax_i)
-      buf[xmin_i] += xmax-xmin;
+      buf[xmin_i] += (xmax-xmin)*add;
    else if (xmin_i>=0)
    {
-      buf[xmin_i] += 1-(xmin-((float)xmin_i));
-      for (i=xmin_i+1; i<xmax_i; i++) buf[i]=1.0;
-      buf[xmax_i] += xmax-((float)xmax_i);
+      buf[xmin_i] += (1-(xmin-((float)xmin_i)))*add;
+      for (i=xmin_i+1; i<xmax_i; i++) buf[i]+=add;
+      buf[xmax_i] += add*(xmax-((float)xmax_i));
    }
    else
    {
-      for (i=0; i<xmax_i; i++) buf[i]=1.0;
-      buf[xmax_i] += xmax-((float)xmax_i);
+      for (i=0; i<xmax_i; i++) buf[i]+=add;
+      buf[xmax_i] += add*(xmax-((float)xmax_i));
    }
 }
 
-static int polyfill_row_vertices(float *buf,
-				 struct vertex_list *v1,
-				 struct vertex_list *v2,
-				 float xmin,
-				 float xmax,
-				 float yp,
-				 int fill)
+static INLINE void polyfill_slant_add(float *buf,
+				      float xmin,float xmax,
+				      float lot,
+				      float y1,
+				      float dy)
 {
-   struct vertex_list *v;
-   int xofill=1;
-   int xmax_i, xmin_i;
-   float x;
+   int i;
+   int xmin_i = (int)floor(xmin);
+   int xmax_i = (int)floor(xmax);
+   if (xmax_i<0) return;
+   if (xmin_i == xmax_i)
+      buf[xmin_i] += (xmax-xmin)*(y1+dy*(xmax-xmin)/2)*lot;
+   else if (xmin_i>=0)
+   {
+      buf[xmin_i] += 
+	 lot*(y1+dy*(1-(xmin-((float)xmin_i)))/2)*(1-(xmin-((float)xmin_i)));
+      y1+=dy*(1-(xmin-((float)xmin_i)));
+      for (i=xmin_i+1; i<xmax_i; i++) 
+	 buf[i]+=lot*(y1+dy/2),y1+=dy;
+      buf[xmax_i] += 
+	 lot*(y1+dy*(xmax-((float)xmax_i))/2)*(xmax-((float)xmax_i));
+   }
+   else
+   {
+      y1+=dy*(0.0-xmin);
+      for (i=0; i<xmax_i; i++) 
+	 buf[i]+=lot*(y1+dy/2),y1+=dy;
+      buf[xmax_i] += 
+	 lot*(y1+dy*(xmax-((float)xmax_i))/2)*(xmax-((float)xmax_i));
+   }
+}
+
+static int polyfill_event(float xmin,
+			  float xmax,
+			  struct line_list **pll,
+			  int tog,
+			  float yp,
+			  float *buf)
+{
+   struct line_list *c;
+   struct line_list *ll=*pll;
+   int mtog;
 
 #ifdef POLYDEBUG
-   int i;
-   fprintf(stderr,"aa %g..%g fill %d\n",xmin,xmax,fill);
+   fprintf(stderr,"  event %g,%g - %g,%g tog=%d\n",xmin,yp,xmax,yp+1.0,tog);
 #endif
-   xmax_i = (int)floor(xmax);
-   xmin_i = (int)floor(xmin);
 
-   fill=fill?-1:1;
-   
-#if 1
-   v=v1;
-   while (v)
+   /* toggle for lines ended at xmin,yp */
+   c=ll;
+   while (c)
    {
-      if (v->xmin==xmin && v->yxmin==yp && v->above->y<yp 
-	  && v->xmin<xmax && v->xmax>xmin)
+      if ( (c->above->y < yp) &&
+	   ( (c->xmax==xmin && c->yxmax==yp) ||
+	     (c->xmin==xmin && c->yxmin==yp) ) )
       {
-	 fill=-fill;
 #ifdef POLYDEBUG
-	 fprintf(stderr,"aa toggle fill: %d->%d on %g,%g-%g,%g\n",
-		 -fill,fill,v->xmin,v->yxmin,v->xmax,v->yxmax);
+	 fprintf(stderr,"    toggle for %g,%g - %g,%g [%g,%g - %g,%g]\n",
+		 c->xmin,c->yxmin,c->xmax,c->yxmax,
+		 c->above->x,c->above->y,c->below->x,c->below->y);
 #endif
+	 tog=!tog;
       }
-      v=v->next;
+      c=c->next;
    }
-#endif
-
-   if (fill<0) polyfill_row_fill(buf,xmin,xmax);
 
-   v=v1;
-   while (v!=v2)
+   /* sanity check */
+   c=ll;
+   while (c && c->next)
    {
-#ifdef POLYDEBUG
-      fprintf(stderr,"aa << %g,%g-%g,%g %g,%g-%g,%g fill=%d xofill=%d xmin=%g xmax=%g xmin_i=%d xmax_i=%d\n",
-	      v->above->x,v->above->y,
-	      v->below->x,v->below->y,
-	      v->xmin,v->yxmin,
-	      v->xmax,v->yxmax,
-	      fill,xofill,
-	      xmin,xmax,xmin_i,xmax_i);
-#endif
-
-      if (xmin!=xmax && v->xmin<xmax && v->xmax>xmin) 
+      if (c->xmin > c->next->xmax ||
+	  ( c->xmin!=c->xmax &&
+	    c->next->xmin!=c->next->xmax &&
+	    c->xmax>=xmin &&
+	    c->xmin<=xmin &&
+	    c->next->xmax>=xmin &&
+	    c->next->xmin<=xmin &&
+	    (VY(c,xmin)>VY(c->next,xmin) ||
+	     VY(c,xmax)>VY(c->next,xmax))) )
       {
+	 struct line_list *l1;
+	 /* resort */
 #ifdef POLYDEBUG
-#define CALC_AREA(FILL,X,Y1,Y2,YP) \
-	      (fprintf(stderr," [area: %d*%g*%g y1=%g y2=%g yp=%g]\n", FILL,X,( 1-0.5*(Y1+Y2)+YP ),Y1,Y2,YP), \
-		    ((FILL)*(X)*( 1.0-0.5*((Y1)+(Y2))+(YP) )))
-#else
-#define CALC_AREA(FILL,X,Y1,Y2,YP) \
-		    ((FILL)*(X)*( 1.0-0.5*((Y1)+(Y2))+(YP) ))
+	 fprintf(stderr,"  !!! resort !!!\n");
 #endif
+	 l1=NULL;
+	 add_vertices(&l1,ll,yp);
 
-
-			 
-	 if (xmin_i == xmax_i)
-	    buf[xmin_i]+=
-	       CALC_AREA(fill*xofill,(xmax-xmin), VY(v,xmin),VY(v,xmax),yp);
-	 else
+	 while ((c=*pll))
 	 {
-	   int xx;
-	    buf[xmin_i]+=
-	       CALC_AREA(xofill*fill, (1+((float)xmin_i)-xmin),
-			 VY(v,xmin),VY(v,1+((float)xmin_i)), yp);
-
-	    for (x=(float)(xx=1+xmin_i); xx<xmax_i; xx++, x+=1.0)
-	       buf[xx] +=
-		  CALC_AREA(fill*xofill,1.0, VY(v,x),VY(v,x+1.0),yp);
-
-#if 0
-	    fprintf(stderr,"buf[%d] = %g", xmax_i, buf[xmax_i]);
-	    fflush(stderr);
-#endif
-	    buf[xmax_i] +=
-	       CALC_AREA(fill*xofill, xmax-((float)xmax_i), 
-			 VY(v,xmax),VY(v,((float)xmax_i)),yp);
-#if 0
-	    fprintf(stderr," ok\n");
-#endif
+	    *pll=c->next;
+	    free(c);
 	 }
-#ifdef POLYDEBUG
-	 fprintf(stderr,"aa ");
-	 for (i=0; i<10; i++) fprintf(stderr,"%5.3f,",buf[i]);
-	 fprintf(stderr,"\n");
-#endif
-      }
 
-      if (v->xmin<=xmin && v->xmax>=xmax) 
-	 xofill=-xofill;
+	 ll=*pll=l1;
 
-      v=v->next;
-   }
-#ifdef POLYDEBUG
-   if (fill<0) fprintf(stderr,"aa fill is on\n");
-#endif
-   return fill<0;
-}
-
-static int toggle_fill(struct vertex_list *v1,
-		       float xmin,float xmax,
-		       float yp,int fill)
-{
-   struct vertex_list *v;
-   v=v1;
-#ifdef POLYDEBUG
-   fprintf(stderr,"try toggle %g..%g\n",xmin,xmax);
-#endif
-   while (v) 
-   {
-      if (v->above->y<yp-1e-10 && 
-	  ( (v->xmin==xmin && v->yxmin<=yp+1e-10) 
-	    || (v->xmax==xmin && v->yxmax<=yp+1e-10)
-	    || (v->xmax==xmax && v->xmin<=xmin && v->yxmax<=yp+1e-10)))
-      {
-	 fill=!fill;
-#ifdef POLYDEBUG
-	 fprintf(stderr," toggle fill %d=>%d on %g,%g-%g,%g\n",
-		 !fill,fill,v->xmin,v->yxmin,v->xmax,v->yxmax);
-#endif
+	 break;
       }
-      
-#ifdef POLYDEBUG
-      else fprintf(stderr," dont toggle fill %d=>%d on %g,%g-%g,%g (%g<%g) (%d%d%d)\n",
-		   fill,fill,v->xmin,v->yxmin,v->xmax,v->yxmax,
-		   v->above->y,yp-1e-10,
-		   v->xmax==xmax,v->yxmax==yp+1,v->above->y<yp-1e-10);
-#endif
-
-      v=v->next;
+      c=c->next;
    }
-   return fill;
-}
 
-static void polyfill_row(struct image *img,
-			 float *buf,
-			 struct vertex_list **vertices,
-			 float yp,
-			 int *pixmin,int *pixmax)
-{
-   struct vertex_list *v,*v1;
-   float xmax,xmin,nxmax,rxmax,yl,xl;
-   int fill=0,i;
-   int ixmin,ixmax;
-
-   xmin=1e10;
-   xmax=-1e10;
-   rxmax=0;
-
-   v=*vertices;
-   while (v)
+   /* paint if needed */
+   if (tog)
    {
-      v->xmin=vertex_xmin(v,yp,&v->yxmin);
-      v->xmax=vertex_xmax(v,yp,&v->yxmax);
-      if (v->xmin<xmin) xmin=v->xmin;
-      if (v->xmax>xmax) xmax=v->xmax;
-      v=v->next;
+#ifdef POLYDEBUG
+	 fprintf(stderr,"  fill %g..%g with 1.0\n",xmin,xmax);
+#endif	 
+      polyfill_row_add(buf,xmin,xmax,1.0);
    }
 
-   *pixmin=ixmin=floor(xmin);
-   *pixmax=ixmax=ceil(xmax);
-
-   rxmax=xmax;
-   if (rxmax>img->xsize) rxmax=img->xsize;
+   /* loop over events */
+   mtog=tog;
+   c=ll;
 
-   if (ixmin<0)
+   while (c)
    {
-      *pixmin=ixmin=xmin=0;
-      v=*vertices;
-      while (v)
+      if (c->xmin<=xmin && c->xmax>=xmax)
       {
-	 if (v->xmin<0 && v->yxmin==yp) fill=!fill;
-	 if (v->xmax<0 && v->yxmax==yp) fill=!fill;
-	 v=v->next;
+	 float y1=VY(c,xmin);
+#ifdef POLYDEBUG
+	 float y2=VY(c,xmax);
+	 fprintf(stderr,"  use line %g,%g - %g,%g [%g,%g - %g,%g] : %g,%g - %g,%g = %+g\n",
+		 c->xmin,c->yxmin,c->xmax,c->yxmax,
+		 c->above->x,c->above->y,c->below->x,c->below->y,
+		 xmin,y1,xmax,y2,(tog?-1.0:1.0)*((y1+y2)/2.0-yp));
+#endif	 
+	 polyfill_slant_add(buf,xmin,xmax,(tog?-1.0:1.0),(yp+1)-y1,-c->dy);
+	 tog=!tog;
       }
+      if (c->xmin>xmax) break; /* skip the rest */
+      c=c->next;
    }
-   else if (ixmin>=img->xsize) { *pixmax=ixmin; return; } 
-   if (ixmax>=img->xsize) *pixmax=ixmax=img->xsize;
-   else if (ixmax<0) { *pixmax=ixmin; return; } 
+   
 
-   for (i=ixmin; i<=ixmax; i++) buf[i]=0.0;
+   return mtog;
+}
 
-   v=*vertices;
-   nxmax=xmax=v->xmax;
-   v1=v;
+static void polyfill_some(struct image *img,
+			  struct vertex *v,
+			  float *buf)
+{
+   struct line_list *ll=NULL;
+   int y=0;
+   float ixmax=(float)img->xsize;
+   struct vertex *to_add=v,*to_loose=v;
+   /* beat row for row */
    
-   v1=v=*vertices;
+   if (y+1.0+1e-10<v->y) 
+      y=(int)v->y;
 
-#ifdef POLYDEBUG
-   while (v)
-      fprintf(stderr," >> %g,%g-%g,%g  %g,%g-%g,%g\n",
-	     v->above->x,v->above->y,
-	     v->below->x,v->below->y,
-	     v->xmin,v->yxmin,
-	     v->xmax,v->yxmax),v=v->next;
-
-   v=*vertices;
-#endif
-
-   for (;;)
+   while (y<img->ysize && (to_loose||to_add) )
    {
-#ifdef POLYDEBUG
-      fprintf(stderr,">>>again...xmin=%g xmax=%g nxmax=%g\n",
-		xmin,xmax,nxmax);
+      float yp=y;
+      struct line_list *c;
+      float xmin,xmax;
+      int tog=0;
+      int i;
+      rgb_group *d;
+
+#ifdef POLYDEBUG      
+      fprintf(stderr,"line %d..%d\n",y,y+1);
 #endif
 
-      if (!v1) break; /* sanity check */
-
-      /* get next start or end */
-
-      v=v1;
-      nxmax=0;
-      xmax=v->xmax;
-      while (v)
+      /* update values for current lines */
+      c=ll;
+      while (c)
       {
-#ifdef POLYDEBUG
-	 fprintf(stderr," ++ %g,%g-%g,%g  %g,%g-%g,%g  xmin=%g xmax=%g nxmax=%g -> ",
-	     v->above->x,v->above->y,
-	     v->below->x,v->below->y,
-	     v->xmin,v->yxmin,
-	     v->xmax,v->yxmax,xmin,xmax,nxmax);
-#endif
-	 if (v->xmin>xmin && v->xmin<xmax) 
-	    xmax=v->xmin;
-	 if (v->xmax>xmin && v->xmax<xmax) 
-	    xmax=v->xmax;
-	 if (v->xmin<=xmax && v->xmax>nxmax) nxmax=v->xmax;
-#ifdef POLYDEBUG
-	 fprintf(stderr,"xmin=%g xmax=%g nxmax=%g\n",
-		 xmin,xmax,nxmax);
-#endif
-
-	 v=v->next;
+	 c->xmin=line_xmin(c,yp,&c->yxmin);
+	 c->xmax=line_xmax(c,yp,&c->yxmax);
+	 c=c->next;
       }
 
-#ifdef POLYDEBUG
-      fprintf(stderr,"    xmax=%g nxmax=%g xmin=%g xmax=%g ixmax=%d fill=%d\n",
-	      xmax,nxmax,xmin,xmax,ixmax,fill);
-#endif      
-
-      if (xmax>ixmax) xmax=ixmax;
-
-#ifdef POLYDEBUG
-      fprintf(stderr,"--> xmax=%g nxmax=%g xmin=%g xmax=%g ixmax=%d fill=%d\n",
-	      xmax,nxmax,xmin,xmax,ixmax,fill);
-
-      fprintf(stderr,"--- %g..%g --------------------------------------\n",
-	      xmin,xmax);
-#endif
-      
-      /* sort sanity check (needed, since sort is based on one line) */
-
-      v=v1;
-      yl=0;
-      xl=0;
-      while (v)
+      /* add any new vertices */
+      while (to_add && to_add->y<yp+1.0)
       {
-	 if (v->xmax>=xmin && v->xmin<=xmin)
-	 {
-	    float y=VY(v,xmin);
-	    if (y<yl) 
-	    {
-resort:
-	       /* resort */
-#ifdef POLYDEBUG
-	       fprintf(stderr,"!!! resort !!!\n");
-#endif
-	       v1=NULL;
-	       add_vertices(&v1,*vertices,yp);
-
-	       while ((v=*vertices))
-	       {
-		  *vertices=v->next;
-		  free(v);
-	       }
-
-	       *vertices=v1;
-
-	       /* forget the already done stuff */
-
-	       while (v1 && v1->xmax<xmin) v1=v1->next;
-
-	       break;
-	    }
-	    yl=y;
-	 }
-	 if (xl>v->xmax) goto resort;
-	 xl=v->xmin;
-	 v=v->next;
+	 struct vertex *vx=to_add;
+	 to_add=to_add->next;
+	 add_vertices(&ll,vx->below,yp);
       }
 
-      if (xmin!=nxmax)
-	polyfill_row_vertices(buf,v1,v,xmin,xmax,yp,fill);
-      
-      fill=toggle_fill(v1,xmin,xmax,yp,fill);
-
-#ifdef POLYEDEBUG
-      fprintf(stderr,"v1=%lx xmax=%g nxmax=%g xmax==nxmax:%d\n",
-	      (unsigned long)v1,xmax,nxmax,xmax==nxmax);
-#endif
-
-      /* skip uninteresting, ends < v->xmin */
-      while (v1 && v1->xmax<=xmax && v1->xmin<xmax) v1=v1->next;
-      if (!v1) break;
-
-      if (v1 && xmax==nxmax && xmax<rxmax) /* jump */
+#ifdef POLYDEBUG      
+      c=ll;
+      while (c)
       {
-	 float xminf=rxmax;
-	 v=v1;
-	 while (v)
-	 {
-	    if (v->xmax>nxmax && v->xmin<xminf) xminf=v->xmin;
-	    v=v->next;
-	 }
-	 if (xmin!=xmax) fill=toggle_fill(v1,xmax,xminf,yp,fill);
-#ifdef POLYDEBUG
-	 fprintf(stderr,"aa jump %g..%g fill %d\n",
-		 nxmax,xminf,fill);
-#endif
-	 if (fill) 
-	    polyfill_row_fill(buf,xmax,xminf);
-	 if (xminf==ixmax) break;
-
-	 xmin=xminf;
+	 fprintf(stderr,"  line %g,%g - %g,%g [%g,%g - %g,%g]\n",
+		 c->xmin,c->yxmin,c->xmax,c->yxmax,
+		 c->above->x,c->above->y,c->below->x,c->below->y);
+	 c=c->next;
       }
-      else xmin=xmax;
-
-      if (xmin>=rxmax) break;
-
-      /* skip uninteresting, ends < v->xmin */
-      while (v1 && v1->xmax==xmax) v1=v1->next;
-      if (!v1) break;
-
-
-   }
-
-#ifdef POLYDEBUG
-   fprintf(stderr,"== ");
-   for (i=0; i<10; i++) fprintf(stderr,"%5.3f,",buf[i]);
-   fprintf(stderr,"\n");
-#endif
-}
-
-static void polyfill_some(struct image *img,
-			  struct vertex *top)
-{
-   struct vertex_list *vertices;
-   struct vertex *next,*nextb;
-   float yp;
-   int i;
-
-   rgb_group *dest=img->img,rgb=img->rgb;
-   float *buf=(float *)alloca(sizeof(float)*(img->xsize+1));
-
-   if (!buf) error("out of stack, typ\n");
-   for (i=0; i<img->xsize+1; i++) buf[i]=0.0;
-
-#ifdef POLYDEBUG
-   next=top;
-   while (next)
-   {
-      fprintf(stderr,"%lx %g,%g\n",(unsigned long)next,next->x,next->y);
-      next=next->next;
-   }
-#endif
-
-
-   nextb=next=top;
-
-   yp=floor(top->y);
-   vertices=NULL;
-
-   if (yp>0) dest+=((int)yp)*img->xsize;
-
-   while (next)
-   {
-#ifdef POLYDEBUG
-      struct vertex_list *v1;
-fprintf(stderr,"\n\nrow y=%g..%g\n",yp,yp+1);
+      
 #endif
 
-/* add new vertices if any */
-
-      while (next && next->y<=yp+1.0-1e-10)
+      if (!ll)
       {
-	 add_vertices(&vertices,next->below,yp);
-	 next=next->next;
+	 y++;
+	 continue;
       }
 
-/* POLYDEBUG */
+      /* begin with zeros */
+      for (i=0; i<img->xsize; i++) buf[i]=0.0;
 
-#ifdef POLYDEBUG
-      fprintf(stderr,"vertices:\n");
-      v1=vertices;
-      while (v1)
+      /* loop through all horisontal events */
+      xmin=ll->xmin-1.0;
+      while (xmin<ixmax)
       {
-	 fprintf(stderr," (%g,%g)-(%g,%g) at ",
-		v1->above->x,v1->above->y,
-		v1->below->x,v1->below->y);
-	 if (v1->above->y>yp)
-	    fprintf(stderr,"(%g,%g), ",v1->above->x,v1->above->y);
-	 else
-	    fprintf(stderr,"(%g,%g), ",v1->above->x+v1->dx*(yp-v1->above->y),yp);
-
-	 if (v1->below->y<yp+1.0)
-	    fprintf(stderr,"(%g,%g)\n",v1->below->x,v1->below->y);
-	 else
-	    fprintf(stderr,"(%g,%g)\n",v1->above->x+v1->dx*(1+yp-v1->above->y),
-		   (yp+1.0));
+	 xmax=1e10;
+	 c=ll;
+	 while (c)
+	 {
+	    /* each line has two events: beginning and end */
+	    if (c->xmin<xmax && c->xmin>xmin) xmax=c->xmin;
+	    if (c->xmax<xmax && c->xmax>xmin) xmax=c->xmax;
+	    c=c->next;
+	 }
+	 if (xmax==1e10) break; /* no more events */
+
+	 if (xmax>ixmax) xmax=ixmax;
+	 tog=polyfill_event(xmin,xmax,&ll,tog,yp,buf);
 	 
-	 v1=v1->next;
+	 /* shift to get next event */
+	 xmin=xmax;
+	 xmax=xmin-1.0;
       }
-#endif
-
-/* find out what to antialias, and what to fill, and if to resort stuff */
-
-      if (yp>=0 && yp<img->ysize)
+      
+      
+      /* remove any old vertices */
+      while (to_loose!=to_add && to_loose->y<yp+1.0-1e-10)
       {
-	 int xmin,xmax;
-
-	 polyfill_row(img, buf, &vertices,yp, &xmin,&xmax);
-
-#ifdef POLYDEBUG
-	 fprintf(stderr,"yp=%g dest=&%lx (&%lx..&%lx) xmin=%d xmax=%d;   ",
-		 yp,(int)dest,(int)img->img,
-		 (int)img->img+img->xsize*img->ysize,
-		 xmin,xmax);
-	 fprintf(stderr,"\n");
-#endif
-
-	 for (;xmin<xmax;xmin++)
-	    dest[xmin].r=(unsigned char)(dest[xmin].r*(1.0-buf[xmin])+rgb.r*buf[xmin]),
-	    dest[xmin].g=(unsigned char)(dest[xmin].g*(1.0-buf[xmin])+rgb.g*buf[xmin]),
-	    dest[xmin].b=(unsigned char)(dest[xmin].b*(1.0-buf[xmin])+rgb.b*buf[xmin]);
-	 dest+=img->xsize;
+	 struct vertex *vx=to_loose;
+	 to_loose=to_loose->next;
+	 sub_vertices(&ll,vx,yp);
       }
 
-/* remove done vertices if any */
-
-      while (nextb && nextb->y<yp+1.0-1e-10)
+      /* write this row */
+      d=img->img+img->xsize*y;
+      for (i=0; i<img->xsize; i++)
       {
-	 sub_vertices(&vertices,nextb,yp);
-	 nextb=nextb->next;
+#ifdef POLYDEBUG
+	 fprintf(stderr,"%3.2f ",buf[i]);
+#endif
+	 d->r=(COLORTYPE)((d->r*(1.0-buf[i]))+(img->rgb.r*buf[i]));
+	 d->g=(COLORTYPE)((d->g*(1.0-buf[i]))+(img->rgb.g*buf[i]));
+	 d->b=(COLORTYPE)((d->b*(1.0-buf[i]))+(img->rgb.b*buf[i]));
+	 d++;
       }
+#ifdef POLYDEBUG
+      fprintf(stderr,"\n");
+#endif
 
-      yp+=1.0;
+      y++;
+   }
+   while (ll)
+   {
+      struct line_list *c;
+      ll=(c=ll)->next;
+      free(c);
    }
 }
 
 static INLINE void polyfill_free(struct vertex *top)
 {
-   struct vertex_list *v,*vn;
+   struct line_list *v,*vn;
    struct vertex *tn;
 
    while (top)
@@ -800,19 +619,26 @@ static INLINE struct vertex *polyfill_add(struct vertex *top,
 	 return NULL;
       }
 
-   if (a->size<6) {
+   if (a->size<6) 
+   {
+      return top; 
+#if 0
       polyfill_free(top);
       error("Illegal argument %d to %s, too few vertices (min 3)\n", arg, what);
       return NULL; /* no polygon with less then tree corners */
+#endif
    }
 
 #define POINT(A,N) (((A)->item[N].type==T_FLOAT)?((A)->item[N].u.float_number):((float)((A)->item[N].u.integer)))
 
    last=first=vertex_new(POINT(a,0),POINT(a,1),&top);
 
+   if (!last) return NULL;
+
    for (n=2; n+1<a->size; n+=2)
    {
       cur=vertex_new(POINT(a,n),POINT(a,n+1),&top);
+      if (!cur) return NULL;
       if (cur->y<last->y)
 	 vertex_connect(cur,last);
       else if (cur->y>last->y)
@@ -840,9 +666,14 @@ static INLINE struct vertex *polyfill_add(struct vertex *top,
 void image_polyfill(INT32 args)
 {
    struct vertex *v;
+   float *buf;
 
    if (!THIS->img)
-      error("No image when calling Image.image->polyfill()\n");
+      error("Image.image->polyfill: no image\n");
+
+   buf=malloc(sizeof(float)*(THIS->xsize+1));
+   if (!buf)
+      error("Image.image->polyfill: out of memory\n");
 
    v=polyfill_begin();
 
@@ -853,25 +684,33 @@ void image_polyfill(INT32 args)
       if (sp[-1].type!=T_ARRAY)
       {
 	 polyfill_free(v);
-	 error("Illegal argument %d to Image.image->polyfill(), expected array\n",
+	 error("Image.image->polyfill: Illegal argument %d, expected array\n",
 	       args);
       }
       if ((v_tmp=polyfill_add(v, sp[-1].u.array, args, "Image.image->polyfill()"))) {
 	 v = v_tmp;
       } else {
 	 polyfill_free(v);
-	 error("Bad argument %d to Image.image->polyfill(), bad vertice\n", args);
+	 error("Image.image->polyfill: Bad argument %d, bad vertex\n", args);
       }
       args--;
       pop_stack();
    }
 
+fprintf(stderr,"foo\n");
+
    if (!v) return; /* no vertices */
 
-   polyfill_some(THIS,v);
+fprintf(stderr,"bar\n");
+
+   polyfill_some(THIS,v,buf);
+
+fprintf(stderr,"gazonk\n");
    
    polyfill_free(v);
    
+   free(buf);
+
    THISOBJ->refs++;
    push_object(THISOBJ);
 }