| #include <stdio.h> |
| #include <math.h> |
| #include <string.h> |
| #include "pic.h" |
| extern int dbg; |
| |
| #define abs(n) (n >= 0 ? n : -(n)) |
| #define max(x,y) ((x)>(y) ? (x) : (y)) |
| |
| char *textshift = "\\v'.2m'"; /* move text this far down */ |
| |
| /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */ |
| /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */ |
| /* default output is 6x6 inches */ |
| |
| |
| double xscale; |
| double yscale; |
| |
| double hpos = 0; /* current horizontal position in output coordinate system */ |
| double vpos = 0; /* current vertical position; 0 is top of page */ |
| |
| double htrue = 0; /* where we really are */ |
| double vtrue = 0; |
| |
| double X0, Y0; /* left bottom of input */ |
| double X1, Y1; /* right top of input */ |
| |
| double hmax; /* right end of output */ |
| double vmax; /* top of output (down is positive) */ |
| |
| extern double deltx; |
| extern double delty; |
| extern double xmin, ymin, xmax, ymax; |
| |
| double xconv(double), yconv(double), xsc(double), ysc(double); |
| void space(double, double, double, double); |
| void hgoto(double), vgoto(double), hmot(double), vmot(double); |
| void move(double, double), movehv(double, double); |
| |
| char svgfill[40] = "transparent"; |
| char svgstroke[40] = "black"; |
| |
| void openpl(char *s) /* initialize device; s is residue of .PS invocation line */ |
| { |
| double maxw, maxh, ratio = 1; |
| double odeltx = deltx, odelty = delty; |
| |
| hpos = vpos = 0; |
| maxw = getfval("maxpswid"); |
| maxh = getfval("maxpsht"); |
| if (deltx > maxw) { /* shrink horizontal */ |
| ratio = maxw / deltx; |
| deltx *= ratio; |
| delty *= ratio; |
| } |
| if (delty > maxh) { /* shrink vertical */ |
| ratio = maxh / delty; |
| deltx *= ratio; |
| delty *= ratio; |
| } |
| if (ratio != 1) { |
| fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty); |
| fprintf(stderr, " %g X %g\n", deltx, delty); |
| } |
| space(xmin, ymin, xmax, ymax); |
| |
| printf("<svg height=\"%.3f\" width=\"%.3f\"\n", yconv(ymin)+10, xconv(xmax)+10); |
| printf(" xmlns=\"http://www.w3.org/2000/svg\">\n"); |
| printf("<g transform=\"translate(5 5)\">\n"); |
| |
| /* |
| printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax); |
| printf("... %.3fi %.3fi %.3fi %.3fi\n", |
| xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax)); |
| printf(".nr 00 \\n(.u\n"); |
| printf(".nf\n"); |
| printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s); |
| */ |
| } |
| |
| void space(double x0, double y0, double x1, double y1) /* set limits of page */ |
| { |
| X0 = x0; |
| Y0 = y0; |
| X1 = x1; |
| Y1 = y1; |
| xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0); |
| yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0); |
| |
| xscale *= 144; |
| yscale *= 144; |
| } |
| |
| double xconv(double x) /* convert x from external to internal form */ |
| { |
| return (x-X0) * xscale; |
| } |
| |
| double xsc(double x) /* convert x from external to internal form, scaling only */ |
| { |
| |
| return (x) * xscale; |
| } |
| |
| double yconv(double y) /* convert y from external to internal form */ |
| { |
| return (Y1-y) * yscale; |
| } |
| |
| double ysc(double y) /* convert y from external to internal form, scaling only */ |
| { |
| return (y) * yscale; |
| } |
| |
| void closepl(char *PEline) /* clean up after finished */ |
| { |
| printf("</g>\n"); |
| printf("</svg>\n"); |
| } |
| |
| void move(double x, double y) /* go to position x, y in external coords */ |
| { |
| hgoto(xconv(x)); |
| vgoto(yconv(y)); |
| } |
| |
| void movehv(double h, double v) /* go to internal position h, v */ |
| { |
| hgoto(h); |
| vgoto(v); |
| } |
| |
| void hmot(double n) /* generate n units of horizontal motion */ |
| { |
| hpos += n; |
| } |
| |
| void vmot(double n) /* generate n units of vertical motion */ |
| { |
| vpos += n; |
| } |
| |
| void hgoto(double n) |
| { |
| hpos = n; |
| } |
| |
| void vgoto(double n) |
| { |
| vpos = n; |
| } |
| |
| void hvflush(void) /* get to proper point for output */ |
| { |
| /* |
| if (fabs(hpos-htrue) >= 0.0005) { |
| printf("\\h'%.3fi'", hpos - htrue); |
| htrue = hpos; |
| } |
| if (fabs(vpos-vtrue) >= 0.0005) { |
| printf("\\v'%.3fi'", vpos - vtrue); |
| vtrue = vpos; |
| } |
| */ |
| } |
| |
| void printlf(int n, char *f) |
| { |
| } |
| |
| void troff(char *s) /* output troff right here */ |
| { |
| printf("%s\n", s); |
| } |
| |
| void label(char *s, int t, int nh) /* text s of type t nh half-lines up */ |
| { |
| char *anchor; |
| |
| if (!s) |
| return; |
| |
| if (t & ABOVE) |
| nh++; |
| else if (t & BELOW) |
| nh--; |
| t &= ~(ABOVE|BELOW); |
| anchor = 0; |
| if (t & LJUST) { |
| // default |
| } else if (t & RJUST) { |
| anchor = "end"; |
| } else { /* CENTER */ |
| anchor = "middle"; |
| } |
| printf("<text x=\"%.3f\" y=\"%.3f\"", hpos, vpos-(double)(nh-0.4)*(12.0/72)/2*144); |
| if(anchor) |
| printf(" text-anchor=\"%s\"", anchor); |
| printf(">%s</text>\n", s); |
| } |
| |
| void line(double x0, double y0, double x1, double y1, int attr, double ddval) /* draw line from x0,y0 to x1,y1 */ |
| { |
| printf("<path d=\"M %.3f %.3f L %.3f %.3f\" fill=\"transparent\" stroke=\"black\"", xconv(x0), yconv(y0), xconv(x1), yconv(y1)); |
| if(attr & DASHBIT) |
| printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval)); |
| else if(attr & DOTBIT) |
| printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval)); |
| printf("/>\n"); |
| } |
| |
| void arrow(double x0, double y0, double x1, double y1, double w, double h, |
| double ang, int nhead) /* draw arrow (without shaft) */ |
| { |
| double alpha, rot, drot, hyp; |
| double dx, dy; |
| int i; |
| |
| rot = atan2(w / 2, h); |
| hyp = sqrt(w/2 * w/2 + h * h); |
| alpha = atan2(y1-y0, x1-x0) + ang; |
| if (nhead < 2) |
| nhead = 2; |
| dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha); |
| printf("<path d=\""); |
| for (i = 1; i >= 0; i--) { |
| drot = 2 * rot / (double) (2-1) * (double) i; |
| dx = hyp * cos(alpha + PI - rot + drot); |
| dy = hyp * sin(alpha + PI - rot + drot); |
| dprintf("dx,dy = %g,%g\n", dx, dy); |
| if(i == 1) |
| printf("M %.3f %.3f L %.3f %.3f", xconv(x1+dx), yconv(y1+dy), xconv(x1), yconv(y1)); |
| else |
| printf(" L %.3f %.3f", xconv(x1+dx), yconv(y1+dy)); |
| } |
| if (nhead > 2) |
| printf(" Z"); |
| printf("\""); |
| if(nhead > 3) |
| printf(" fill=\"black\" stroke=\"black\""); |
| else if(nhead == 3) |
| printf(" fill=\"white\" stroke=\"black\""); |
| else |
| printf(" fill=\"transparent\" stroke=\"black\""); |
| printf("/>\n"); |
| } |
| |
| double lastgray = 0; |
| |
| void fillstart(double v, int vis, int fill) |
| { |
| int x; |
| |
| if(fill) { |
| x = (int)(v*255.0); |
| sprintf(svgfill, "#%02x%02x%02x", x, x, x); |
| } else |
| strcpy(svgfill, "transparent"); |
| if(vis) |
| strcpy(svgstroke, "black"); |
| else |
| strcpy(svgstroke, "transparent"); |
| } |
| |
| void fillend(void) |
| { |
| strcpy(svgfill, "transparent"); |
| strcpy(svgstroke, "black"); |
| } |
| |
| void box(double x0, double y0, double x1, double y1, int attr, double ddval) |
| { |
| printf("<path d=\"M %.3f %.3f V %.3f H %.3f V %.3f Z\" fill=\"transparent\" stroke=\"black\"", xconv(x0), yconv(y0), yconv(y1), xconv(x1), yconv(y0)); |
| if(attr & DASHBIT) |
| printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval)); |
| else if(attr & DOTBIT) |
| printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval)); |
| printf("/>\n"); |
| |
| } |
| |
| void circle(double x, double y, double r) |
| { |
| printf("<circle cx=\"%.3f\" cy=\"%.3f\" r=\"%.3f\" fill=\"%s\" stroke=\"%s\"/>\n", xconv(x), yconv(y), xsc(r), svgfill, svgstroke); |
| } |
| |
| void spline(double x, double y, double n, ofloat *p, int attr, double ddval) |
| { |
| int i; |
| double x1, y1, x2, y2; |
| |
| printf("<path d=\"M %.3f %.3f", xconv(x), yconv(y)); |
| x1 = 0; |
| y1 = 0; |
| for (i = 0; i < 2 * n; i += 2) { |
| x2 = x1; |
| y2 = y1; |
| x1 = x; |
| y1 = y; |
| x += p[i]; |
| y += p[i+1]; |
| if(i == 0) |
| printf(" L %.3f %.3f", xconv((x+x1)/2), yconv((y+y1)/2)); |
| else |
| printf(" Q %.3f %.3f %.3f %.3f", xconv(x1), yconv(y1), xconv((x+x1)/2), yconv((y+y1)/2)); |
| } |
| printf(" L %.3f %.3f", xconv(x), yconv(y)); |
| printf("\" fill=\"%s\" stroke=\"%s\"", svgfill, svgstroke); |
| if(attr & DASHBIT) |
| printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval)); |
| else if(attr & DOTBIT) |
| printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval)); |
| printf("/>\n"); |
| } |
| |
| void ellipse(double x, double y, double r1, double r2) |
| { |
| printf("<ellipse cx=\"%.3f\" cy=\"%.3f\" rx=\"%.3f\" ry=\"%.3f\" fill=\"%s\" stroke=\"%s\"/>\n", xconv(x), yconv(y), xsc(r1), ysc(r2), svgfill, svgstroke); |
| } |
| |
| void arc(double x, double y, double x0, double y0, double x1, double y1, double r) /* draw arc with center x,y */ |
| { |
| printf("<path d=\"M %.3f %.3f A %.3f %.3f %d %d %d %.3f %.3f\" fill=\"%s\" stroke=\"%s\"/>\n", |
| xconv(x0), yconv(y0), |
| xsc(r), ysc(r), 0, 0, 0, xconv(x1), yconv(y1), |
| svgfill, svgstroke); |
| } |