diff --git a/src/modules/Image/polyfill.c b/src/modules/Image/polyfill.c
index eca89537462d9a4b8a82c44999115eb202d6e72d..641af39306368f69be602b00558c8009f175bab8 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.11 1997/11/05 03:29:17 mirar Exp $");
+RCSID("$Id: polyfill.c,v 1.12 1997/11/05 03:30:02 mirar Exp $");
 
 /* Prototypes are needed for these */
 extern double floor(double);
@@ -29,7 +29,7 @@ extern double floor(double);
 /*
 **! module Image
 **! note
-**!	$Id: polyfill.c,v 1.11 1997/11/05 03:29:17 mirar Exp $
+**!	$Id: polyfill.c,v 1.12 1997/11/05 03:30:02 mirar Exp $
 **! class image
 */
 
@@ -121,16 +121,16 @@ static void vertex_connect(struct vertex *above,
 static INLINE float vertex_xmax(struct vertex_list *v,float yp,float *ydest)
 {
    if (v->dx>0.0)
-      if (v->below->y>yp+1.0)
+      if (v->below->y>yp+1.0+1e-10)
 	 return v->above->x+v->dx*((*ydest=(yp+1.0))-v->above->y);
       else
 	 return (*ydest=v->below->y),v->below->x;
    else if (v->dx<0.0)
-      if (v->above->y<yp)
+      if (v->above->y<yp-1e-10)
 	 return v->above->x+v->dx*((*ydest=yp)-v->above->y);
       else
 	 return (*ydest=v->above->y),v->above->x;
-   else if (v->below->y>yp+1.0) 
+   else if (v->below->y>yp+1.0+1e-10) 
       return (*ydest=yp+1.0),v->above->x;
    else
       return (*ydest=v->below->y),v->below->x;
@@ -139,16 +139,16 @@ static INLINE float vertex_xmax(struct vertex_list *v,float yp,float *ydest)
 static INLINE float vertex_xmin(struct vertex_list *v,float yp,float *ydest)
 {
    if (v->dx<0.0)
-      if (v->below->y>yp+1.0)
+      if (v->below->y>yp+1.0+1e-10)
 	 return v->above->x+v->dx*((*ydest=(yp+1.0))-v->above->y);
       else
 	 return (*ydest=v->below->y),v->below->x;
    else if (v->dx>0.0)
-      if (v->above->y<yp)
+      if (v->above->y<yp-1e-10)
 	 return v->above->x+v->dx*((*ydest=yp)-v->above->y);
       else
 	 return (*ydest=v->above->y),v->above->x;
-   else if (v->above->y<yp) 
+   else if (v->above->y<yp-1e-10) 
       return (*ydest=yp),v->above->x;
    else
       return (*ydest=v->above->y),v->above->x;
@@ -160,51 +160,72 @@ static void add_vertices(struct vertex_list **first,
 {
    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;
+   }
+
    while (what)
    {
-      float xi,yi;
-      float xw = what->above->x;
-      float yw = what->above->y;
+      what->xmin=vertex_xmin(what,yp,&what->yxmin);
+      what->xmax=vertex_xmax(what,yp,&what->yxmax);
 
       ins=first;
 
 #ifdef POLYDEBUG
-   fprintf(stderr,"insert %g,%g - %g,%g  %g  xw==%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->dx,xw);
+	  what->below->x,what->below->y,
+	  what->xmin,what->yxmin,
+	  what->xmax,what->yxmax);
 #endif
 
-
+      /* fast jump vectorgroups on the left */
       while (*ins)
       {
-	 if (fabs((*ins)->dy)<1e-10 || fabs(what->dy)<1e-10) xi=xw;
-	 else xi = (*ins)->above->x + (*ins)->dx*(yw-(*ins)->above->y);
-	 yi=yw;
-
-	 if (xw<xi && what->dx<0.0) break;
-	 if (xw>xi && what->dx>0.0) break;
-
-	 if (xw==xi && 
-/*	     ((*ins)->below->x>xw || (*ins)->above->x>xw) &&*/
-	     (*ins)->dx>what->dx) break;
+	 if ((*ins)->xmax>what->xmin) break;
+	 ins=&((*ins)->next);
+      }
 
-#ifdef POLYDEBUG
-	 fprintf(stderr," after %g,%g - %g,%g  %g  i=%g,%g w=%g,%g\n",
-		(*ins)->above->x,(*ins)->above->y,
-		(*ins)->below->x,(*ins)->below->y,(*ins)->dx,
-		xi,yi,xw,yw);
+      /* ok, place in correct y for x=what->xmin or x=(*ins)->xmin */
 
-#endif
+      while (*ins)
+      {
+	 /* case: -what-> <-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; }
+	 /* case:   <-what-    */
+	 /*       -ins-        */
+	 else 
+	    { if (VY((*ins),what->xmin)>what->yxmin) break; }
+
+	 /* case: -what->    */
+	 /*           -ins-  */
+	 if ((*ins)->xmax>what->xmax)
+	    { if (VY((*ins),what->xmax)>what->yxmax) break; }
+	 /* case:    -what-    */
+	 /*       -ins->       */
+	 else 
+	    { if ((*ins)->yxmax>VY(what,(*ins)->xmax)) break; }
 
 	 ins=&((*ins)->next);
       }
 
+
 #ifdef POLYDEBUG
       if (*ins)
-	 fprintf(stderr," before %g,%g - %g,%g  %g  i=%g,%g w=%g,%g\n",
-		(*ins)->above->x,(*ins)->above->y,
-		(*ins)->below->x,(*ins)->below->y,(*ins)->dy,
-		xi,yi,xw,yw);
+	 fprintf(stderr," before %g,%g - %g,%g  %g,%g - %g,%g\n",
+		 (*ins)->above->x,(*ins)->above->y,
+		 (*ins)->below->x,(*ins)->below->y,
+		 (*ins)->xmin,(*ins)->yxmin,
+		 (*ins)->xmax,(*ins)->yxmax);
 #endif
 
 
@@ -225,14 +246,29 @@ static void sub_vertices(struct vertex_list **first,
 
    ins=first;
 
+#ifdef POLYDEBUG
+   fprintf(stderr,"remove %lx %g,%g\n",below,below->x,below->y);
+#endif
+
    while (*ins)
+   {
       if ((*ins)->below==below) 
       {
 	 c=*ins;
 	 *ins=(*ins)->next;
 	 free(c);
       }
-      else ins=&((*ins)->next);
+      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 polygone_row_fill(float *buf,
@@ -273,18 +309,22 @@ static int polygone_row_vertices(float *buf,
 
    fill=fill?-1:1;
    
+#if 1
    v=v1;
    while (v)
    {
-      if (v->xmin==xmin && v->yxmin==yp)
+      if (v->xmin==xmin && v->yxmin==yp && v->above->y<yp 
+	  && v->xmin<xmax && v->xmax>xmin)
       {
 	 fill=-fill;
 #ifdef POLYDEBUG
-	 fprintf(stderr,"aa toggle fill: %d\n",fill);
+	 fprintf(stderr,"aa toggle fill: %d->%d on %g,%g-%g,%g\n",
+		 -fill,fill,v->xmin,v->yxmin,v->xmax,v->yxmax);
 #endif
       }
       v=v->next;
    }
+#endif
 
    if (fill<0) polygone_row_fill(buf,xmin,xmax);
 
@@ -292,12 +332,13 @@ static int polygone_row_vertices(float *buf,
    while (v!=v2)
    {
 #ifdef POLYDEBUG
-      fprintf(stderr,"aa << %g,%g-%g,%g %g,%g-%g,%g fill=%d xofill=%d\n",
-       v->above->x,v->above->y,
-       v->below->x,v->below->y,
-       v->xmin,v->yxmin,
-       v->xmax,v->yxmax,
-	     fill,xofill);
+      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) 
@@ -393,19 +434,20 @@ static int toggle_fill(struct vertex_list *v1,
 
 static void polygone_row(struct image *img,
 			 float *buf,
-			 struct vertex_list *vertices,
+			 struct vertex_list **vertices,
 			 float yp,
 			 int *pixmin,int *pixmax)
 {
    struct vertex_list *v,*v1;
-   float xmax,xmin,nxmax;
+   float xmax,xmin,nxmax,rxmax,yl,xl;
    int fill=0,i;
    int ixmin,ixmax;
 
    xmin=1e10;
    xmax=-1e10;
+   rxmax=0;
 
-   v=vertices;
+   v=*vertices;
    while (v)
    {
       v->xmin=vertex_xmin(v,yp,&v->yxmin);
@@ -418,10 +460,13 @@ static void polygone_row(struct image *img,
    *pixmin=ixmin=floor(xmin);
    *pixmax=ixmax=ceil(xmax);
 
+   rxmax=xmax;
+   if (rxmax>img->xsize) rxmax=img->xsize;
+
    if (ixmin<0)
    {
       *pixmin=ixmin=xmin=0;
-      v=vertices;
+      v=*vertices;
       while (v)
       {
 	 if (v->xmin<0 && v->yxmin==yp) fill=!fill;
@@ -435,11 +480,11 @@ static void polygone_row(struct image *img,
 
    for (i=ixmin; i<=ixmax; i++) buf[i]=0.0;
 
-   v=vertices;
+   v=*vertices;
    nxmax=xmax=v->xmax;
    v1=v;
    
-   v1=v=vertices;
+   v1=v=*vertices;
 
 #ifdef POLYDEBUG
    while (v)
@@ -449,7 +494,7 @@ static void polygone_row(struct image *img,
 	     v->xmin,v->yxmin,
 	     v->xmax,v->yxmax),v=v->next;
 
-   v=vertices;
+   v=*vertices;
 #endif
 
    for (;;)
@@ -459,16 +504,13 @@ static void polygone_row(struct image *img,
 		xmin,xmax,nxmax);
 #endif
 
-      /* skip uninteresting, ends < v->xmin */
-      while (v1 && v1->xmax<xmin) v1=v1->next;
-      if (!v1) break;
-	 
+      if (!v1) break; /* sanity check */
+
       /* get next start or end */
 
       v=v1;
       nxmax=0;
-      xmax=1e10;
-      /* known: v->xmin>=xmin */
+      xmax=v->xmax;
       while (v)
       {
 #ifdef POLYDEBUG
@@ -478,48 +520,125 @@ static void polygone_row(struct image *img,
 	     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->xmax>nxmax) nxmax=v->xmax;
-
+	 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);
+		 xmin,xmax,nxmax);
 #endif
 
 	 v=v->next;
       }
-      
-      if (xmax>nxmax) xmax=nxmax;
-      if (xmin>xmax) xmax=xmin;
+
+#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;
-      
-      if (xmin==nxmax) break;
 
-      fill=polygone_row_vertices(buf,v1,v,xmin,xmax,yp,fill);
+#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
       
-      if ((xmin=xmax)>=ixmax) break;
+      /* sort sanity check (needed, since sort is based on one line) */
 
-      while (v1 && v1->xmax<xmin) v1=v1->next;
-      if (!v1) break;
-      v=vertices;
-      while (v) 
+      v=v1;
+      yl=0;
+      xl=0;
+      while (v)
       {
-	 if (v->xmax==xmax && v->yxmax==yp) fill=!fill;
+	 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;
       }
+
+      if (xmin!=nxmax)
+	polygone_row_vertices(buf,v1,v,xmin,xmax,yp,fill);
       
-      if (v && xmax==nxmax && v->xmin>nxmax) /* jump */
+      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 */
       {
-	 xmin=v->xmin;
-	 if (nxmax>=ixmax) break;
+	 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) 
-	    if (v->xmin>ixmax)
-	       polygone_row_fill(buf,nxmax,ixmax);
-	    else
-	       polygone_row_fill(buf,nxmax,v->xmin);
+	    polygone_row_fill(buf,xmax,xminf);
+	 if (xminf==ixmax) break;
+
+	 xmin=xminf;
       }
+      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 polygone_some(struct image *img,
@@ -530,13 +649,24 @@ static void polygone_some(struct image *img,
    float yp;
    int i;
 
-
    rgb_group *dest=img->img,rgb=img->rgb;
    float *buf=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);
@@ -547,12 +677,13 @@ static void polygone_some(struct image *img,
    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)
+      while (next && next->y<=yp+1.0-1e-10)
       {
 	 add_vertices(&vertices,next->below,yp);
 	 next=next->next;
@@ -589,14 +720,13 @@ fprintf(stderr,"\n\nrow y=%g..%g\n",yp,yp+1);
       {
 	 int xmin,xmax;
 
-	 polygone_row(img, buf, vertices,yp, &xmin,&xmax);
+	 polygone_row(img, buf, &vertices,yp, &xmin,&xmax);
 
-#if POLYDEBUG
+#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);
-	 for (i=xmin; i<xmax; i++) fprintf(stderr,"%5.3f,",buf[i]);
 	 fprintf(stderr,"\n");
 #endif
 
@@ -609,13 +739,13 @@ fprintf(stderr,"\n\nrow y=%g..%g\n",yp,yp+1);
 
 /* remove done vertices if any */
 
-      yp+=1.0;
-
-      while (nextb && nextb->y<=yp)
+      while (nextb && nextb->y<yp+1.0-1e-10)
       {
 	 sub_vertices(&vertices,nextb,yp);
 	 nextb=nextb->next;
       }
+
+      yp+=1.0;
    }
 }