diff options
author | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
---|---|---|
committer | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
commit | 7d0663b7c023cd7dd2764cb232798f8bc1309c20 (patch) | |
tree | e5b8eca2f1b0e825f115fb1b73c3ccb0103b9f39 /src/cmd/svgpic/plsvg.c | |
parent | 5e176c5794de5124b67d3ac4ea7afe2f210b6d84 (diff) | |
parent | 711336c348ac9b98cd22464496e6b7e9a109c3a9 (diff) | |
download | plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.gz plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.bz2 plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.zip |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/cmd/svgpic/plsvg.c')
-rw-r--r-- | src/cmd/svgpic/plsvg.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/src/cmd/svgpic/plsvg.c b/src/cmd/svgpic/plsvg.c new file mode 100644 index 00000000..3f342e68 --- /dev/null +++ b/src/cmd/svgpic/plsvg.c @@ -0,0 +1,328 @@ +#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); +} |