66ee7c172964fe9665479973fa7c7536afe03fa2
kate
  Tue Apr 10 22:05:33 2018 -0700
Add Postscript for bezier curve.  Fix ellipse. refs #21109

diff --git src/hg/lib/hvGfx.c src/hg/lib/hvGfx.c
index 97a40a7..6ef915e 100644
--- src/hg/lib/hvGfx.c
+++ src/hg/lib/hvGfx.c
@@ -221,62 +221,30 @@
     gfxPolyAddPoint(t1, x+w/2, y+h);
     gfxPolyAddPoint(t2, x+w/2, y+h/2);
     gfxPolyAddPoint(t2, x+w, y);
     gfxPolyAddPoint(t2, x+w, y+h);
     }
 /* The two filled triangles. */
 vgDrawPoly(hvg->vg, t1, hvgColor, TRUE);
 vgDrawPoly(hvg->vg, t2, hvgColor, TRUE);
 /* The two outline triangles. */
 vgDrawPoly(hvg->vg, t1, color, FALSE);
 vgDrawPoly(hvg->vg, t2, color, FALSE);
 gfxPolyFree(&t1);
 gfxPolyFree(&t2);
 }
 
-/* from memgfx.c and vPng.c*/
-
-struct memPng
-/* Something that handles a PNG. */
-    {
-    struct memGfx mg;	/* Memory form.  This needs to be first field. */
-    char *fileName;	/* PNG file name. */
-    boolean useTransparency;   /* Make background color transparent if TRUE. */
-    };
-
-#define _mgBpr(mg) ((mg)->width)
-#define _mgPixAdr(mg,x,y) ((mg)->pixels+_mgBpr(mg) * (y) + (x))
-
-INLINE void mixDot(struct hvGfx *hvg, int x, int y,  float frac, Color col)
-/* Puts a single dot on the image, mixing it with what is already there
- * based on the frac argument. */
-{
-struct memPng *png = (struct memPng *)hvg->vg->data;
-struct memGfx *img = (struct memGfx *)png;
-if ((x < img->clipMinX) || (x > img->clipMaxX) || (y < img->clipMinY) || (y > img->clipMaxY))
-    return;
-
-Color *pt = _mgPixAdr(img,x,y);
-float invFrac = 1 - frac;
-
-int r = COLOR_32_RED(*pt) * invFrac + COLOR_32_RED(col) * frac;
-int g = COLOR_32_GREEN(*pt) * invFrac + COLOR_32_GREEN(col) * frac;
-int b = COLOR_32_BLUE(*pt) * invFrac + COLOR_32_BLUE(col) * frac;
-hvGfxDot(hvg, x, y, MAKECOLOR_32(r,g,b));
-hvGfxDot(hvg, x, y, MAKECOLOR_32(r,g,b));
-}
-
 void hvGfxDottedLine(struct hvGfx *hvg, int x1, int y1, int x2, int y2, Color color, boolean isDash)
 /* Brezenham line algorithm, alternating dots, by 1 pixel or two (isDash true) */
 {   
 int duty_cycle;
 int incy;
 int delta_x, delta_y;
 int dots;
 int dotFreq = (isDash ? 3 : 2);
 delta_y = y2-y1;
 delta_x = x2-x1;
 if (delta_y < 0)  
     {   
     delta_y = -delta_y;
     incy = -1; 
     }   
@@ -313,129 +281,15 @@
     dots = delta_y+1;
     while (--dots >= 0)
         {   
         if (dots % dotFreq)
             hvGfxDot(hvg,x1,y1,color);
         duty_cycle += delta_x;
         y1+=incy;
         if (duty_cycle > 0)
             {   
             duty_cycle -= delta_y;        /* update duty cycle */
             x1 += 1;
             }   
         }   
     }   
 }   
-
-int hvGfxCurveSegAA(struct hvGfx *hvg, int x0, int y0, int x1, int y1, int x2, int y2, 
-                        Color color, boolean isDashed)
-/* Draw a segment of an anti-aliased curve within 3 points (quadratic Bezier)
- * Return max y value. Optionally alternate dots.
- * Adapted trivially from code posted on github and at http://members.chello.at/~easyfilter/bresenham.html */
- /* Thanks to author  * @author Zingl Alois
- * @date 22.08.2016 */
-{
-   int yMax = 0;
-   int sx = x2-x1, sy = y2-y1;
-   long xx = x0-x1, yy = y0-y1, xy;             /* relative values for checks */
-   double dx, dy, err, ed, cur = xx*sy-yy*sx;                    /* curvature */
-
-   assert(xx*sx <= 0 && yy*sy <= 0);      /* sign of gradient must not change */
-
-   if (sx*(long)sx+sy*(long)sy > xx*xx+yy*yy) {     /* begin with longer part */
-      x2 = x0; x0 = sx+x1; y2 = y0; y0 = sy+y1; cur = -cur;     /* swap P0 P2 */
-   }
-   if (cur != 0)
-   {                                                      /* no straight line */
-      xx += sx; xx *= sx = x0 < x2 ? 1 : -1;              /* x step direction */
-      yy += sy; yy *= sy = y0 < y2 ? 1 : -1;              /* y step direction */
-      xy = 2*xx*yy; xx *= xx; yy *= yy;             /* differences 2nd degree */
-      if (cur*sx*sy < 0) {                              /* negated curvature? */
-         xx = -xx; yy = -yy; xy = -xy; cur = -cur;
-      }
-      dx = 4.0*sy*(x1-x0)*cur+xx-xy;                /* differences 1st degree */
-      dy = 4.0*sx*(y0-y1)*cur+yy-xy;
-      xx += xx; yy += yy; err = dx+dy+xy;                   /* error 1st step */
-      int dots = 0;
-      do {
-         cur = fmin(dx+xy,-xy-dy);
-         ed = fmax(dx+xy,-xy-dy);               /* approximate error distance */
-         ed += 2*ed*cur*cur/(4*ed*ed+cur*cur);
-         if (!isDashed || (++dots % 3))
-            {
-            mixDot(hvg, x0,y0, 1-fabs(err-dx-dy-xy)/ed, color);          /* plot curve */
-            if (y0 > yMax)
-                yMax = y0;
-            }
-         if (x0 == x2 || y0 == y2) break;     /* last pixel -> curve finished */
-         x1 = x0; cur = dx-err; y1 = 2*err+dy < 0;
-         if (2*err+dx > 0) {                                        /* x step */
-            if (err-dy < ed) 
-                {
-                mixDot(hvg, x0,y0+sy, 1-fabs(err-dy)/ed, color);
-                if (y0 > yMax)
-                    yMax = y0;
-                }
-            x0 += sx; dx -= xy; err += dy += yy;
-         }
-         if (y1) {                                                  /* y step */
-            if (cur < ed) 
-                {
-                mixDot(hvg, x1+sx,y0, 1-fabs(cur)/ed, color);
-                if (y0 > yMax)
-                    yMax = y0;
-                }
-            y0 += sy; dy -= xy; err += dx += xx;
-         }
-      } while (dy < dx);                  /* gradient negates -> close curves */
-   }
-   hvGfxLine(hvg, x0,y0, x2,y2, color);                  /* plot remaining needle to end */
-   if (y0 > yMax)
-       yMax = y0;
-   return yMax;
-}
-
-int hvGfxCurve(struct hvGfx *hvg, int x0, int y0, int x1, int y1, int x2, int y2, 
-                        Color color, boolean isDashed)
-/* Draw a segment of an anti-aliased curve within 3 points (quadratic Bezier)
- * Return max y value. Optionally alternate dots.
- * Adapted trivially from code posted at http://members.chello.at/~easyfilter/bresenham.html
- */
-/* TODO: allow specifying a third point on the line
- *  P(t) = (1-t)^2 * p0 + 2 * (1-t) * t * p1 + t^2 * p2
- */
-{
-   int x = x0-x1, y = y0-y1;
-   double t = x0-2*x1+x2, r;
-   int yMax = 0, yMaxRet = 0;
-   if ((long)x*(x2-x1) > 0) {                        /* horizontal cut at P4? */
-      if ((long)y*(y2-y1) > 0)                     /* vertical cut at P6 too? */
-         if (fabs((y0-2*y1+y2)/t*x) > abs(y)) {               /* which first? */
-            x0 = x2; x2 = x+x1; y0 = y2; y2 = y+y1;            /* swap points */
-         }                            /* now horizontal cut at P4 comes first */
-      t = (x0-x1)/t;
-      r = (1-t)*((1-t)*y0+2.0*t*y1)+t*t*y2;                       /* By(t=P4) */
-      t = (x0*x2-x1*x1)*t/(x0-x1);                       /* gradient dP4/dx=0 */
-      x = floor(t+0.5); y = floor(r+0.5);
-      r = (y1-y0)*(t-x0)/(x1-x0)+y0;                  /* intersect P3 | P0 P1 */
-      yMax = hvGfxCurveSegAA(hvg,x0,y0, x,floor(r+0.5), x,y, color, isDashed);
-      r = (y1-y2)*(t-x2)/(x1-x2)+y2;                  /* intersect P4 | P1 P2 */
-      x0 = x1 = x; y0 = y; y1 = floor(r+0.5);             /* P0 = P4, P1 = P8 */
-   }
-   if ((long)(y0-y1)*(y2-y1) > 0) {                    /* vertical cut at P6? */
-      t = y0-2*y1+y2; t = (y0-y1)/t;
-      r = (1-t)*((1-t)*x0+2.0*t*x1)+t*t*x2;                       /* Bx(t=P6) */
-      t = (y0*y2-y1*y1)*t/(y0-y1);                       /* gradient dP6/dy=0 */
-      x = floor(r+0.5); y = floor(t+0.5);
-      r = (x1-x0)*(t-y0)/(y1-y0)+x0;                  /* intersect P6 | P0 P1 */
-      yMaxRet = hvGfxCurveSegAA(hvg,x0,y0, floor(r+0.5),y, x,y, color, isDashed);
-      if (yMaxRet > yMax)
-        yMax = yMaxRet;
-      r = (x1-x2)*(t-y2)/(y1-y2)+x2;                  /* intersect P7 | P1 P2 */
-      x0 = x; x1 = floor(r+0.5); y0 = y1 = y;             /* P0 = P6, P1 = P7 */
-   }
-   yMaxRet = hvGfxCurveSegAA(hvg,x0,y0, x1,y1, x2,y2, color, isDashed); /* remaining part */
-   if (yMaxRet > yMax)
-     yMax = yMaxRet;
-   return yMax;
-}
-