Ilya Zakharevich on Wed, 19 Jan 2000 17:10:18 -0500


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[PATCH 2.0.18] Postpone rounding of graphic until the output


There are some flaws in the current model of plotting in PARI: the
moment you output graphic primitives to a rectangle, the coordinates
are snapped to the integer grid in the rectangle.  This makes it
harder to implement rescaling of graphs.  Suppose what you are
interested in is GIF output, you output some graphic to rectangles,
preview it in X, do modifications until things fit.

However, to emit the picture to GIF you need to calculate all the
elements again, since GIF may be of different resolution.  Adding a
modifications of plotdraw() and plotcopy() with rescaling should be
trivial, but with the current model it is not viable, because rounding
will accumulate (especially if you rescale to a finer grid).

The following patch makes no changes to the interface of PARI, but
postpones rounding until the graphic reaches the device driver (PS, X,
or gnuplot).  Rescaling versions of plotdraw() and plotcopy() may
follow soon.

The patch has a negative side effect of increasing memory footprint of
plotting (if long is 32bit), but I estimate that the difference will
not be noticable.

Enjoy,
Ilya

--- ./src/graph/plotport.c~	Fri Dec  3 13:10:44 1999
+++ ./src/graph/plotport.c	Wed Jan 19 16:35:10 2000
@@ -304,8 +304,6 @@ rectscale(long ne, GEN x1, GEN x2, GEN y
  * }
  */
 
-#define DTOL(t) ((long)(t + 0.5))
-
 static void
 rectmove0(long ne, double x, double y, long relative)
 {
@@ -317,8 +315,8 @@ rectmove0(long ne, double x, double y, l
   else
    { RXcursor(e) = x; RYcursor(e) = y; }
   RoNext(z) = 0; RoType(z) = ROt_MV;
-  RoMVx(z) = DTOL(RXcursor(e) * RXscale(e) + RXshift(e));
-  RoMVy(z) = DTOL(RYcursor(e) * RYscale(e) + RYshift(e));
+  RoMVx(z) = RXcursor(e) * RXscale(e) + RXshift(e);
+  RoMVy(z) = RYcursor(e) * RYscale(e) + RYshift(e);
   if (!RHead(e)) RHead(e)=RTail(e)=z;
   else { RoNext(RTail(e))=z; RTail(e)=z; }
 }
@@ -346,10 +344,11 @@ rectpoint0(long ne, double x, double y,l
   else
    { RXcursor(e) = x; RYcursor(e) = y; }
   RoNext(z)=0;
-  RoPTx(z) = DTOL(RXcursor(e)*RXscale(e) + RXshift(e));
-  RoPTy(z) = DTOL(RYcursor(e)*RYscale(e) + RYshift(e));
-  RoType(z) = ((RoPTx(z)<0)||(RoPTy(z)<0)||(RoPTx(z)>RXsize(e))
-	       ||(RoPTy(z)>RYsize(e))) ? ROt_MV : ROt_PT;
+  RoPTx(z) = RXcursor(e)*RXscale(e) + RXshift(e);
+  RoPTy(z) = RYcursor(e)*RYscale(e) + RYshift(e);
+  RoType(z) = ( DTOL(RoPTx(z)) < 0
+		|| DTOL(RoPTy(z)) < 0 || DTOL(RoPTx(z)) > RXsize(e)
+		|| DTOL(RoPTy(z)) > RYsize(e) ) ? ROt_MV : ROt_PT;
   if (!RHead(e)) RHead(e)=RTail(e)=z;
   else { RoNext(RTail(e))=z; RTail(e)=z; }
   RoCol(z)=current_color[ne];
@@ -378,18 +377,18 @@ rectcolor(long ne, long color)
 void
 rectline0(long ne, double gx2, double gy2, long relative) /* code = ROt_MV/ROt_LN */
 {
-  long dx,dy,dxy,xmin,xmax,ymin,ymax,x1,y1,x2,y2;
+  double dx,dy,dxy,xmin,xmax,ymin,ymax,x1,y1,x2,y2;
   PariRect *e = check_rect_init(ne);
   RectObj *z = (RectObj*) gpmalloc(sizeof(RectObj2P));
 
-  x1 = DTOL(RXcursor(e)*RXscale(e) + RXshift(e));
-  y1 = DTOL(RYcursor(e)*RYscale(e) + RYshift(e));
+  x1 = RXcursor(e)*RXscale(e) + RXshift(e);
+  y1 = RYcursor(e)*RYscale(e) + RYshift(e);
   if (relative)
     { RXcursor(e)+=gx2; RYcursor(e)+=gy2; }
   else
     { RXcursor(e)=gx2; RYcursor(e)=gy2; }
-  x2 = DTOL(RXcursor(e)*RXscale(e) + RXshift(e));
-  y2 = DTOL(RYcursor(e)*RYscale(e) + RYshift(e));
+  x2 = RXcursor(e)*RXscale(e) + RXshift(e);
+  y2 = RYcursor(e)*RYscale(e) + RYshift(e);
   xmin = max(min(x1,x2),0); xmax = min(max(x1,x2),RXsize(e));
   ymin = max(min(y1,y2),0); ymax = min(max(y1,y2),RYsize(e));
   dxy = x1*y2 - y1*x2; dx = x2-x1; dy = y2-y1;
@@ -432,19 +431,19 @@ rectrline(long ne, GEN gx2, GEN gy2)
 void
 rectbox0(long ne, double gx2, double gy2, long relative)
 {
-  long x1,y1,x2,y2,xmin,ymin,xmax,ymax;
+  double x1,y1,x2,y2,xmin,ymin,xmax,ymax;
   double xx,yy;
   PariRect *e = check_rect_init(ne);
   RectObj *z = (RectObj*) gpmalloc(sizeof(RectObj2P));
 
-  x1 = DTOL(RXcursor(e)*RXscale(e) + RXshift(e));
-  y1 = DTOL(RYcursor(e)*RYscale(e) + RYshift(e));
+  x1 = RXcursor(e)*RXscale(e) + RXshift(e);
+  y1 = RYcursor(e)*RYscale(e) + RYshift(e);
   if (relative)
   { xx = RXcursor(e)+gx2; yy = RYcursor(e)+gy2; }
   else
   {  xx = gx2; yy = gy2; }
-  x2=DTOL(xx*RXscale(e) + RXshift(e));
-  y2=DTOL(yy*RYscale(e) + RYshift(e));
+  x2 = xx*RXscale(e) + RXshift(e);
+  y2 = yy*RYscale(e) + RYshift(e);
   xmin = max(min(x1,x2),0); xmax = min(max(x1,x2),RXsize(e));
   ymin = max(min(y1,y2),0); ymax = min(max(y1,y2),RYsize(e));
 
@@ -495,16 +494,17 @@ killrect(long ne)
 void
 rectpoints0(long ne, double *listx, double *listy, long lx) /* code = ROt_MP */
 {
-  long *ptx,*pty,x,y,i,cp=0;
+  double *ptx, *pty, x, y;
+  long i, cp=0;
   PariRect *e = check_rect_init(ne);
   RectObj *z = (RectObj*) gpmalloc(sizeof(RectObjMP));
 
-  ptx=(long*) gpmalloc(lx*sizeof(long));
-  pty=(long*) gpmalloc(lx*sizeof(long));
+  ptx=(double*) gpmalloc(lx*sizeof(double));
+  pty=(double*) gpmalloc(lx*sizeof(double));
   for (i=0; i<lx; i++)
   {
-    x=DTOL(RXscale(e)*listx[i] + RXshift(e));
-    y=DTOL(RYscale(e)*listy[i] + RYshift(e));
+    x = RXscale(e)*listx[i] + RXshift(e);
+    y = RYscale(e)*listy[i] + RYshift(e);
     if ((x>=0)&&(y>=0)&&(x<=RXsize(e))&&(y<=RYsize(e)))
     {
       ptx[cp]=x; pty[cp]=y; cp++;
@@ -544,22 +544,23 @@ rectpoints(long ne, GEN listx, GEN listy
 void
 rectlines0(long ne, double *x, double *y, long lx, long flag) /* code = ROt_ML */
 {
-  long i,I,*ptx,*pty;
+  long i,I;
+  double *ptx,*pty;
   PariRect *e = check_rect_init(ne);
   RectObj *z = (RectObj*) gpmalloc(sizeof(RectObj2P));
 
   I = flag ? lx+1 : lx;
-  ptx = (long*) gpmalloc(I*sizeof(long));
-  pty = (long*) gpmalloc(I*sizeof(long));
+  ptx = (double*) gpmalloc(I*sizeof(double));
+  pty = (double*) gpmalloc(I*sizeof(double));
   for (i=0; i<lx; i++)
   {
-    ptx[i]=DTOL(RXscale(e)*x[i] + RXshift(e));
-    pty[i]=DTOL(RYscale(e)*y[i] + RYshift(e));
+    ptx[i] = RXscale(e)*x[i] + RXshift(e);
+    pty[i] = RYscale(e)*y[i] + RYshift(e);
   }
   if (flag)
   {
-    ptx[i]=DTOL(RXscale(e)*x[0] + RXshift(e));
-    pty[i]=DTOL(RYscale(e)*y[0] + RYshift(e));
+    ptx[i] = RXscale(e)*x[0] + RXshift(e);
+    pty[i] = RYscale(e)*y[0] + RYshift(e);
   }
   RoNext(z)=0; RoType(z)=ROt_ML;
   RoMLcnt(z)=lx; RoMLxs(z)=ptx; RoMLys(z)=pty;
@@ -616,8 +617,8 @@ rectstring3(long ne, char *str, long dir
   strcpy(s,str);
   RoNext(z)=0; RoType(z) = ROt_ST;
   RoSTl(z) = l; RoSTs(z) = s;
-  RoSTx(z) = DTOL(RXscale(e)*RXcursor(e)+RXshift(e));
-  RoSTy(z) = DTOL(RYscale(e)*RYcursor(e)+RYshift(e));
+  RoSTx(z) = RXscale(e)*RXcursor(e)+RXshift(e);
+  RoSTy(z) = RYscale(e)*RYcursor(e)+RYshift(e);
   RoSTdir(z) = dir;
   if (!RHead(e)) RHead(e)=RTail(e)=z;
   else { RoNext(RTail(e))=z; RTail(e)=z; }
@@ -735,10 +736,10 @@ rectcopy(long source, long dest, long xo
       case ROt_MP: case ROt_ML:
 	next = (RectObj*) gpmalloc(sizeof(RectObjMP));
 	memcpy(next,p1,sizeof(RectObjMP));
-	RoMPxs(next) = (long*) gpmalloc(sizeof(long)*RoMPcnt(next));
-	RoMPys(next) = (long*) gpmalloc(sizeof(long)*RoMPcnt(next));
-	memcpy(RoMPxs(next),RoMPxs(p1),sizeof(long)*RoMPcnt(next));
-	memcpy(RoMPys(next),RoMPys(p1),sizeof(long)*RoMPcnt(next));
+	RoMPxs(next) = (double*) gpmalloc(sizeof(double)*RoMPcnt(next));
+	RoMPys(next) = (double*) gpmalloc(sizeof(double)*RoMPcnt(next));
+	memcpy(RoMPxs(next),RoMPxs(p1),sizeof(double)*RoMPcnt(next));
+	memcpy(RoMPys(next),RoMPys(p1),sizeof(double)*RoMPcnt(next));
 	for (i=0; i<RoMPcnt(next); i++)
 	{
 	  RoMPxs(next)[i] += xoff; RoMPys(next)[i] += yoff;
@@ -770,7 +771,7 @@ rectcopy(long source, long dest, long xo
 
 /* A simpler way is to clip by 4 half-planes */
 static int
-clipline(long xmin, long xmax, long ymin, long ymax, long *x1p, long *y1p, long *x2p, long *y2p)
+clipline(long xmin, long xmax, long ymin, long ymax, double *x1p, double *y1p, double *x2p, double *y2p)
 {
     int xy_exch = 0, rc = CLIPLINE_NONEMPTY;
     double t;
@@ -875,8 +876,8 @@ rectclip(long rect)
       next = RoNext(p1);
       switch(RoType(p1)) {
       case ROt_PT:
-	  if ( RoPTx(p1) < xmin || RoPTx(p1) > xmax
-	       || RoPTy(p1) < ymin || RoPTy(p1) > ymax) {
+	  if ( DTOL(RoPTx(p1)) < xmin || DTOL(RoPTx(p1)) > xmax
+	       || DTOL(RoPTy(p1)) < ymin || DTOL(RoPTy(p1)) > ymax) {
 		 remove:
 	      *prevp = next;
 	      free(p1);
@@ -916,8 +917,9 @@ rectclip(long rect)
 	  int f = 0, t = 0;
 
 	  while (f < c) {
-	      if ( RoMPxs(p1)[f] >= xmin && RoMPxs(p1)[f] <= xmax
-		   && RoMPys(p1)[f] >= ymin && RoMPys(p1)[f] <= ymax) {
+	      if ( DTOL(RoMPxs(p1)[f]) >= xmin && DTOL(RoMPxs(p1)[f]) <= xmax
+		   && DTOL(RoMPys(p1)[f]) >= ymin
+		   && DTOL(RoMPys(p1)[f]) <= ymax) {
 		  if (t != f) {
 		      RoMPxs(p1)[t] = RoMPxs(p1)[f];
 		      RoMPys(p1)[t] = RoMPys(p1)[f];
@@ -937,7 +939,7 @@ rectclip(long rect)
 	     several pieces if some part is clipped. */
 	  int c = RoMPcnt(p1) - 1;
 	  int f = 0, t = 0, had_lines = 0, had_hole = 0, rc;
-	  long ox = RoMLxs(p1)[0], oy = RoMLys(p1)[0], oxn, oyn;
+	  double ox = RoMLxs(p1)[0], oy = RoMLys(p1)[0], oxn, oyn;
 
 	  while (f < c) {
 	      /* Endpoint of this segment is the startpoint of the
@@ -994,10 +996,10 @@ rectclip(long rect)
 		  RoType(n) = ROt_ML;
 		  RoCol(n) = RoCol(p1);
 		  RoMLcnt(n) = c - f;
-		  RoMLxs(n) = (long*) gpmalloc(sizeof(long)*(c - f));
-		  RoMLys(n) = (long*) gpmalloc(sizeof(long)*(c - f));
-		  memcpy(RoMPxs(n),RoMPxs(p1) + f, sizeof(long)*(c - f));
-		  memcpy(RoMPys(n),RoMPys(p1) + f, sizeof(long)*(c - f));
+		  RoMLxs(n) = (double*) gpmalloc(sizeof(double)*(c - f));
+		  RoMLys(n) = (double*) gpmalloc(sizeof(double)*(c - f));
+		  memcpy(RoMPxs(n),RoMPxs(p1) + f, sizeof(double)*(c - f));
+		  memcpy(RoMPys(n),RoMPys(p1) + f, sizeof(double)*(c - f));
 		  RoMPxs(n)[0] = oxn; RoMPys(n)[0] = oyn; 
 		  RoNext(n) = next;
 		  RoNext(p1) = n;
@@ -1820,7 +1822,8 @@ postdraw0(long *w, long *x, long *y, lon
 void
 postdraw00(long *w, long *x, long *y, long lw, long scale)
 {
-  long *ptx,*pty,*numpoints,*numtexts,*xtexts,*ytexts,*dirtexts;
+  double *ptx,*pty;
+  long *numpoints,*numtexts,*xtexts,*ytexts,*dirtexts;
   RectObj *p1;
   PariRect *e;
   long i,j,x0,y0;
@@ -1882,27 +1885,27 @@ postdraw00(long *w, long *x, long *y, lo
       switch(RoType(p1))
       {
 	case ROt_PT:
-	  points[nd[ROt_PT]].x=RoPTx(p1)+x0;
-	  points[nd[ROt_PT]].y=RoPTy(p1)+y0;
+	  points[nd[ROt_PT]].x = DTOL(RoPTx(p1)+x0);
+	  points[nd[ROt_PT]].y = DTOL(RoPTy(p1)+y0);
 	  nd[ROt_PT]++; break;
 	case ROt_LN:
-	  seg[nd[ROt_LN]].x1=RoLNx1(p1)+x0;
-	  seg[nd[ROt_LN]].y1=RoLNy1(p1)+y0;
-	  seg[nd[ROt_LN]].x2=RoLNx2(p1)+x0;
-	  seg[nd[ROt_LN]].y2=RoLNy2(p1)+y0;
+	  seg[nd[ROt_LN]].x1 = DTOL(RoLNx1(p1)+x0);
+	  seg[nd[ROt_LN]].y1 = DTOL(RoLNy1(p1)+y0);
+	  seg[nd[ROt_LN]].x2 = DTOL(RoLNx2(p1)+x0);
+	  seg[nd[ROt_LN]].y2 = DTOL(RoLNy2(p1)+y0);
 	  nd[ROt_LN]++; break;
 	case ROt_BX:
-	  a=rect[nd[ROt_BX]].x=RoBXx1(p1)+x0;
-	  b=rect[nd[ROt_BX]].y=RoBXy1(p1)+y0;
-	  rect[nd[ROt_BX]].width =RoBXx2(p1)+x0-a;
-	  rect[nd[ROt_BX]].height=RoBXy2(p1)+y0-b;
+	  a=rect[nd[ROt_BX]].x = DTOL(RoBXx1(p1)+x0);
+	  b=rect[nd[ROt_BX]].y = DTOL(RoBXy1(p1)+y0);
+	  rect[nd[ROt_BX]].width = DTOL(RoBXx2(p1)+x0-a);
+	  rect[nd[ROt_BX]].height = DTOL(RoBXy2(p1)+y0-b);
 	  nd[ROt_BX]++; break;
 	case ROt_MP:
-	  ptx=RoMPxs(p1); pty=RoMPys(p1);
+	  ptx = RoMPxs(p1); pty = RoMPys(p1);
 	  for (j=0; j<RoMPcnt(p1); j++)
 	  {
-	    points[nd[ROt_PT]+j].x=ptx[j]+x0;
-	    points[nd[ROt_PT]+j].y=pty[j]+y0;
+	    points[nd[ROt_PT]+j].x = DTOL(ptx[j]+x0);
+	    points[nd[ROt_PT]+j].y = DTOL(pty[j]+y0);
 	  }
 	  nd[ROt_PT]+=RoMPcnt(p1); break;
 	case ROt_ML:
@@ -1911,16 +1914,16 @@ postdraw00(long *w, long *x, long *y, lo
 	  lines[nd[ROt_ML]]=(SPoint*)gpmalloc(RoMLcnt(p1)*sizeof(SPoint));
 	  for (j=0; j<RoMLcnt(p1); j++)
 	  {
-	    lines[nd[ROt_ML]][j].x=ptx[j]+x0;
-	    lines[nd[ROt_ML]][j].y=pty[j]+y0;
+	    lines[nd[ROt_ML]][j].x = DTOL(ptx[j]+x0);
+	    lines[nd[ROt_ML]][j].y = DTOL(pty[j]+y0);
 	  }
 	  nd[ROt_ML]++; break;
 	case ROt_ST:
-	  texts[nd[ROt_ST]]=RoSTs(p1);
-	  numtexts[nd[ROt_ST]]=RoSTl(p1);
-	  xtexts[nd[ROt_ST]]=RoSTx(p1)+x0;
-	  ytexts[nd[ROt_ST]]=RoSTy(p1)+y0;
-	  dirtexts[nd[ROt_ST]]=RoSTdir(p1);
+	  texts[nd[ROt_ST]] = RoSTs(p1);
+	  numtexts[nd[ROt_ST]] = RoSTl(p1);
+	  xtexts[nd[ROt_ST]] = DTOL(RoSTx(p1)+x0);
+	  ytexts[nd[ROt_ST]] = DTOL(RoSTy(p1)+y0);
+	  dirtexts[nd[ROt_ST]] = RoSTdir(p1);
 	  nd[ROt_ST]++; break;
 	default: break;
       }
--- ./src/graph/plotX.c~	Wed Dec  1 12:41:04 1999
+++ ./src/graph/plotX.c	Wed Jan 19 16:52:51 2000
@@ -116,7 +116,8 @@ zmalloc(size_t x)
 void
 rectdraw0(long *w, long *x, long *y, long lw, long do_free)
 {
-  long *ptx,*pty,*c, shift;
+  double *ptx,*pty;
+  long *c, shift;
   long *numpoints[MAX_COLORS],*numtexts[MAX_COLORS];
   long *xtexts[MAX_COLORS],*ytexts[MAX_COLORS];
   long rcolcnt[MAX_COLORS][ROt_MAX];
@@ -269,7 +270,7 @@ rectdraw0(long *w, long *x, long *y, lon
         oldheight = height; force = 1;
 
         /* recompute scale */
-	xs=((double)width)/w_width; ys=((double)height)/w_height;
+	xs = ((double)width)/w_width; ys=((double)height)/w_height;
       }
       case Expose: if (!force) break;
         force = 0;
@@ -282,27 +283,27 @@ rectdraw0(long *w, long *x, long *y, lon
 	    switch(RoType(p1))
 	    {
 	      case ROt_PT:
-		points[col][c[ROt_PT]].x=(long)((RoPTx(p1)+x0)*xs);
-		points[col][c[ROt_PT]].y=(long)((RoPTy(p1)+y0)*ys);
+		points[col][c[ROt_PT]].x = DTOL((RoPTx(p1)+x0)*xs);
+		points[col][c[ROt_PT]].y = DTOL((RoPTy(p1)+y0)*ys);
 		c[ROt_PT]++;break;
 	      case ROt_LN:
-		seg[col][c[ROt_LN]].x1= (long)((RoLNx1(p1)+x0)*xs);
-		seg[col][c[ROt_LN]].y1= (long)((RoLNy1(p1)+y0)*ys);
-		seg[col][c[ROt_LN]].x2= (long)((RoLNx2(p1)+x0)*xs);
-		seg[col][c[ROt_LN]].y2= (long)((RoLNy2(p1)+y0)*ys);
+		seg[col][c[ROt_LN]].x1 = DTOL((RoLNx1(p1)+x0)*xs);
+		seg[col][c[ROt_LN]].y1 = DTOL((RoLNy1(p1)+y0)*ys);
+		seg[col][c[ROt_LN]].x2 = DTOL((RoLNx2(p1)+x0)*xs);
+		seg[col][c[ROt_LN]].y2 = DTOL((RoLNy2(p1)+y0)*ys);
 		c[ROt_LN]++;break;
 	      case ROt_BX:
-		a=rec[col][c[ROt_BX]].x = (long)((RoBXx1(p1)+x0)*xs);
-		b=rec[col][c[ROt_BX]].y = (long)((RoBXy1(p1)+y0)*ys);
-		rec[col][c[ROt_BX]].width = (long)((RoBXx2(p1)+x0-a)*xs);
-		rec[col][c[ROt_BX]].height = (long)((RoBXy2(p1)+y0-b)*ys);
+		a=rec[col][c[ROt_BX]].x = DTOL((RoBXx1(p1)+x0)*xs);
+		b=rec[col][c[ROt_BX]].y = DTOL((RoBXy1(p1)+y0)*ys);
+		rec[col][c[ROt_BX]].width = DTOL((RoBXx2(p1)+x0-a)*xs);
+		rec[col][c[ROt_BX]].height = DTOL((RoBXy2(p1)+y0-b)*ys);
 		c[ROt_BX]++;break;
 	      case ROt_MP:
-		ptx=RoMPxs(p1); pty=RoMPys(p1);
+		ptx = RoMPxs(p1); pty = RoMPys(p1);
 		for(j=0;j<RoMPcnt(p1);j++)
 		{
-		  points[col][c[ROt_PT]+j].x= (long)((ptx[j]+x0)*xs);
-		  points[col][c[ROt_PT]+j].y= (long)((pty[j]+y0)*ys);
+		  points[col][c[ROt_PT]+j].x = DTOL((ptx[j]+x0)*xs);
+		  points[col][c[ROt_PT]+j].y = DTOL((pty[j]+y0)*ys);
 		}
 		c[ROt_PT]+=RoMPcnt(p1);break;
 	      case ROt_ML:
@@ -312,8 +313,8 @@ rectdraw0(long *w, long *x, long *y, lon
 		  (XPoint*)zmalloc(RoMLcnt(p1)*sizeof(XPoint));
 		for(j=0;j<RoMLcnt(p1);j++)
 		{
-		  lines[col][c[ROt_ML]][j].x= (long)((ptx[j]+x0)*xs);
-		  lines[col][c[ROt_ML]][j].y= (long)((pty[j]+y0)*ys);
+		  lines[col][c[ROt_ML]][j].x = DTOL((ptx[j]+x0)*xs);
+		  lines[col][c[ROt_ML]][j].y = DTOL((pty[j]+y0)*ys);
 		}
 		c[ROt_ML]++;break;
 	      case ROt_ST:
@@ -332,10 +333,10 @@ rectdraw0(long *w, long *x, long *y, lon
 		shift = (hjust == RoSTdirLEFT ? 0 :
 			 (hjust == RoSTdirRIGHT ? 2 : 1));
 		xtexts[col][c[ROt_ST]] 
-		    = (long)(( RoSTx(p1) + x0 + hgap
+		    = DTOL(( RoSTx(p1) + x0 + hgap
 			       - (strlen(RoSTs(p1)) * pari_plot.fwidth
 				  * shift)/2)*xs);
-		ytexts[col][c[ROt_ST]]= (long)((RoSTy(p1)+y0-vgap/2)*ys);
+		ytexts[col][c[ROt_ST]] = DTOL((RoSTy(p1)+y0-vgap/2)*ys);
 		c[ROt_ST]++;break;
 	      default: break;
 	    }
--- ./src/graph/rect.h~	Wed Dec  1 12:41:05 1999
+++ ./src/graph/rect.h	Wed Jan 19 16:32:51 2000
@@ -3,6 +3,8 @@
 #define PLOT_NAME_LEN 20
 #define NUMRECT 18
 
+#define DTOL(t) ((long)(t + 0.5))
+
 typedef struct PARI_plot {
   long width;
   long height;
@@ -53,21 +55,21 @@ typedef struct PariRect {
 typedef struct RectObj1P {
   struct RectObj *next;
   long code,color;
-  long x,y;
+  double x,y;
 } RectObj1P;
 
 typedef struct RectObj2P {
   struct RectObj *next;
   long code,color;
-  long x1,y1;
-  long x2,y2;
+  double x1,y1;
+  double x2,y2;
 } RectObj2P;
 
 typedef struct RectObjMP {
   struct RectObj *next;
   long code,color;
   long count;
-  long *xs,*ys;
+  double *xs,*ys;
 } RectObjMP;
 
 typedef struct RectObjST {
@@ -75,7 +77,8 @@ typedef struct RectObjST {
   long code,color;
   long length;
   char *s;
-  long x,y,dir;
+  double x,y;
+  long dir;
 } RectObjST;
 
 typedef struct RectObjPN {
--- ./src/graph/plotgnuplot.c~	Wed Dec  1 12:41:04 1999
+++ ./src/graph/plotgnuplot.c	Wed Jan 19 16:09:03 2000
@@ -24,7 +24,7 @@
 void
 rectdraw0(long *w, long *x, long *y, long lw, long do_free)
 {
-  long *ptx,*pty;
+  double *ptx,*pty;
   long i,j,x0,y0, hjust, vjust, hgap, vgap, hgapsize, vgapsize;
   long good, seen_graph = 0;
   int point_type = -1, line_type = 0;
@@ -85,52 +85,54 @@ rectdraw0(long *w, long *x, long *y, lon
       switch(RoType(p1))
       {
 	case ROt_PT:
-	  point(RoPTx(p1)+x0, w_height - 1 - RoPTy(p1) - y0, point_type);
+	  point(DTOL(RoPTx(p1)+x0), w_height - 1 - DTOL(RoPTy(p1) + y0),
+		point_type);
 	  break;
 	case ROt_LN:
-	  move(RoLNx1(p1)+x0, w_height - 1 - RoLNy1(p1) - y0);
-	  vector(RoLNx2(p1)+x0, w_height - 1 - RoLNy2(p1) - y0);
+	  move(DTOL(RoLNx1(p1)+x0), w_height - 1 - DTOL(RoLNy1(p1) + y0));
+	  vector(DTOL(RoLNx2(p1)+x0), w_height - 1 - DTOL(RoLNy2(p1) + y0));
 	  break;
 	case ROt_BX:
-	  move(RoBXx1(p1)+x0, w_height - 1 - RoBXy1(p1) - y0);
-	  vector(RoBXx2(p1)+x0, w_height - 1 - RoBXy1(p1) - y0);
-	  vector(RoBXx2(p1)+x0, w_height - 1 - RoBXy2(p1) - y0);
-	  vector(RoBXx1(p1)+x0, w_height - 1 - RoBXy2(p1) - y0);
-	  vector(RoBXx1(p1)+x0, w_height - 1 - RoBXy1(p1) - y0);
+	  move(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
+	  vector(DTOL(RoBXx2(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
+	  vector(DTOL(RoBXx2(p1)+x0), w_height - 1 - DTOL(RoBXy2(p1) + y0));
+	  vector(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy2(p1) + y0));
+	  vector(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
 	  break;
 	case ROt_MP:
 	  ptx=RoMPxs(p1);
 	  pty=RoMPys(p1);
 	  for(j=0;j<RoMPcnt(p1);j++)
 	  {
-	    point(ptx[j]+x0,  w_height - 1 - pty[j] - y0, point_type);
+	    point(DTOL(ptx[j] + x0),  w_height - 1 - DTOL(pty[j] + y0),
+		  point_type);
 	  }
 	  break;
 	case ROt_ML:
 	  ptx=RoMLxs(p1);
 	  pty=RoMLys(p1);
 	  j = 0;
-	  if (ptx[j]+x0 < 0 || ptx[j]+x0 >= w_width
-	      || pty[j] + y0 < 0 || pty[j] + y0 >= w_height) {
+	  if (DTOL(ptx[j]+x0) < 0 || DTOL(ptx[j]+x0) >= w_width
+	      || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
 	    good = 0;
 	  } else {
-	    move(ptx[j]+x0, w_height - 1 - pty[j] - y0);
+	    move(DTOL(ptx[j]+x0), w_height - 1 - DTOL(pty[j] + y0));
 	    good = 1;
 	  }
 	  for(j=1;j<RoMLcnt(p1);j++)
 	  {
 	    if (good) {
-	      if (ptx[j]+x0 < 0 || ptx[j]+x0 >= w_width
-		  || pty[j] + y0 < 0 || pty[j] + y0 >= w_height) {
+	      if (DTOL(ptx[j] + x0) < 0 || DTOL(ptx[j]+x0) >= w_width
+		  || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
 		good = 0;
 	      } else {
-		vector(ptx[j]+x0, w_height - 1 - pty[j] - y0);
+		vector(DTOL(ptx[j] + x0), w_height - 1 - DTOL(pty[j] + y0));
 	      }
 	    } else {
-	      if (ptx[j]+x0 < 0 || ptx[j]+x0 >= w_width
-		  || pty[j] + y0 < 0 || pty[j] + y0 >= w_height) {
+	      if (DTOL(ptx[j] + x0) < 0 || DTOL(ptx[j] + x0) >= w_width
+		  || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
 	      } else {
-		move(ptx[j]+x0, w_height - 1 - pty[j] - y0);
+		move(DTOL(ptx[j]+x0), w_height - 1 - DTOL(pty[j] + y0));
 		good = 1;
 	      }
 	    }
@@ -153,15 +155,16 @@ rectdraw0(long *w, long *x, long *y, lon
 	      can_justify = justify_text(shift); /* 1 for LEFT */
 	      strdir = RoSTdir(p1);
 	  }
-	  xstart = RoSTx(p1) + x0 + hgap
+	  xstart = DTOL(RoSTx(p1) + x0) + hgap
 	      - (can_justify ? 0 
 		 : ((RoSTl(p1) * pari_plot.fwidth - 1) * shift / 2));
 	  xend = xstart + (can_justify ? 0 : RoSTl(p1) * pari_plot.fwidth - 1);
 	  if (xstart < 0 || xend >= w_width
-	      || RoSTy(p1) + y0 < 0 || RoSTy(p1) + y0 >= w_height) {
+	      || DTOL(RoSTy(p1) + y0) < 0 
+	      || DTOL(RoSTy(p1) + y0) >= w_height) {
 	  } else {
 	      put_text(xstart,
-		       w_height - 1 - RoSTy(p1) - y0 + vgap,
+		       w_height - 1 - DTOL(RoSTy(p1) + y0) + vgap,
 		       RoSTs(p1));
 	  }
 	  break;