URI: 
       tplsvg.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tplsvg.c (7991B)
       ---
            1 #include <stdio.h>
            2 #include <math.h>
            3 #include <string.h>
            4 #include "pic.h"
            5 extern int dbg;
            6 
            7 #define        abs(n)        (n >= 0 ? n : -(n))
            8 #define        max(x,y)        ((x)>(y) ? (x) : (y))
            9 
           10 char        *textshift = "\\v'.2m'";        /* move text this far down */
           11 
           12 /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */
           13 /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
           14 /* default output is 6x6 inches */
           15 
           16 
           17 double        xscale;
           18 double        yscale;
           19 
           20 double        hpos        = 0;        /* current horizontal position in output coordinate system */
           21 double        vpos        = 0;        /* current vertical position; 0 is top of page */
           22 
           23 double        htrue        = 0;        /* where we really are */
           24 double        vtrue        = 0;
           25 
           26 double        X0, Y0;                /* left bottom of input */
           27 double        X1, Y1;                /* right top of input */
           28 
           29 double        hmax;                /* right end of output */
           30 double        vmax;                /* top of output (down is positive) */
           31 
           32 extern        double        deltx;
           33 extern        double        delty;
           34 extern        double        xmin, ymin, xmax, ymax;
           35 
           36 double        xconv(double), yconv(double), xsc(double), ysc(double);
           37 void        space(double, double, double, double);
           38 void        hgoto(double), vgoto(double), hmot(double), vmot(double);
           39 void        move(double, double), movehv(double, double);
           40 
           41 char        svgfill[40] = "transparent";
           42 char        svgstroke[40] = "black";
           43 
           44 void openpl(char *s)        /* initialize device; s is residue of .PS invocation line */
           45 {
           46         double maxw, maxh, ratio = 1;
           47         double odeltx = deltx, odelty = delty;
           48 
           49         hpos = vpos = 0;
           50         maxw = getfval("maxpswid");
           51         maxh = getfval("maxpsht");
           52         if (deltx > maxw) {        /* shrink horizontal */
           53                 ratio = maxw / deltx;
           54                 deltx *= ratio;
           55                 delty *= ratio;
           56         }
           57         if (delty > maxh) {        /* shrink vertical */
           58                 ratio = maxh / delty;
           59                 deltx *= ratio;
           60                 delty *= ratio;
           61         }
           62         if (ratio != 1) {
           63                 fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty);
           64                 fprintf(stderr, " %g X %g\n", deltx, delty);
           65         }
           66         space(xmin, ymin, xmax, ymax);
           67 
           68         printf("<svg height=\"%.3f\" width=\"%.3f\"\n", yconv(ymin)+10, xconv(xmax)+10);
           69         printf("     xmlns=\"http://www.w3.org/2000/svg\">\n");
           70         printf("<g transform=\"translate(5 5)\">\n");
           71 
           72         /*
           73         printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax);
           74         printf("... %.3fi %.3fi %.3fi %.3fi\n",
           75                 xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
           76         printf(".nr 00 \\n(.u\n");
           77         printf(".nf\n");
           78         printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
           79         */
           80 }
           81 
           82 void space(double x0, double y0, double x1, double y1)        /* set limits of page */
           83 {
           84         X0 = x0;
           85         Y0 = y0;
           86         X1 = x1;
           87         Y1 = y1;
           88         xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0);
           89         yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0);
           90 
           91         xscale *= 144;
           92         yscale *= 144;
           93 }
           94 
           95 double xconv(double x)        /* convert x from external to internal form */
           96 {
           97         return (x-X0) * xscale;
           98 }
           99 
          100 double xsc(double x)        /* convert x from external to internal form, scaling only */
          101 {
          102 
          103         return (x) * xscale;
          104 }
          105 
          106 double yconv(double y)        /* convert y from external to internal form */
          107 {
          108         return (Y1-y) * yscale;
          109 }
          110 
          111 double ysc(double y)        /* convert y from external to internal form, scaling only */
          112 {
          113         return (y) * yscale;
          114 }
          115 
          116 void closepl(char *PEline)        /* clean up after finished */
          117 {
          118         printf("</g>\n");
          119         printf("</svg>\n");
          120 }
          121 
          122 void move(double x, double y)        /* go to position x, y in external coords */
          123 {
          124         hgoto(xconv(x));
          125         vgoto(yconv(y));
          126 }
          127 
          128 void movehv(double h, double v)        /* go to internal position h, v */
          129 {
          130         hgoto(h);
          131         vgoto(v);
          132 }
          133 
          134 void hmot(double n)        /* generate n units of horizontal motion */
          135 {
          136         hpos += n;
          137 }
          138 
          139 void vmot(double n)        /* generate n units of vertical motion */
          140 {
          141         vpos += n;
          142 }
          143 
          144 void hgoto(double n)
          145 {
          146         hpos = n;
          147 }
          148 
          149 void vgoto(double n)
          150 {
          151         vpos = n;
          152 }
          153 
          154 void hvflush(void)        /* get to proper point for output */
          155 {
          156 /*
          157         if (fabs(hpos-htrue) >= 0.0005) {
          158                 printf("\\h'%.3fi'", hpos - htrue);
          159                 htrue = hpos;
          160         }
          161         if (fabs(vpos-vtrue) >= 0.0005) {
          162                 printf("\\v'%.3fi'", vpos - vtrue);
          163                 vtrue = vpos;
          164         }
          165 */
          166 }
          167 
          168 void printlf(int n, char *f)
          169 {
          170 }
          171 
          172 void troff(char *s)        /* output troff right here */
          173 {
          174         printf("%s\n", s);
          175 }
          176 
          177 void label(char *s, int t, int nh)        /* text s of type t nh half-lines up */
          178 {
          179         char *anchor;
          180 
          181         if (!s)
          182                 return;
          183 
          184         if (t & ABOVE)
          185                 nh++;
          186         else if (t & BELOW)
          187                 nh--;
          188         t &= ~(ABOVE|BELOW);
          189         anchor = 0;
          190         if (t & LJUST) {
          191                 // default
          192         } else if (t & RJUST) {
          193                 anchor = "end";
          194         } else {        /* CENTER */
          195                 anchor = "middle";
          196         }
          197         printf("<text x=\"%.3f\" y=\"%.3f\"", hpos, vpos-(double)(nh-0.4)*(12.0/72)/2*144);
          198         if(anchor)
          199                 printf(" text-anchor=\"%s\"", anchor);
          200         printf(">%s</text>\n", s);
          201 }
          202 
          203 void line(double x0, double y0, double x1, double y1, int attr, double ddval)        /* draw line from x0,y0 to x1,y1 */
          204 {
          205         printf("<path d=\"M %.3f %.3f L %.3f %.3f\" fill=\"transparent\" stroke=\"black\"", xconv(x0), yconv(y0), xconv(x1), yconv(y1));
          206         if(attr & DASHBIT)
          207                 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
          208         else if(attr & DOTBIT)
          209                 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
          210         printf("/>\n");
          211 }
          212 
          213 void arrow(double x0, double y0, double x1, double y1, double w, double h,
          214          double ang, int nhead)         /* draw arrow (without shaft) */
          215 {
          216         double alpha, rot, drot, hyp;
          217         double dx, dy;
          218         int i;
          219 
          220         rot = atan2(w / 2, h);
          221         hyp = sqrt(w/2 * w/2 + h * h);
          222         alpha = atan2(y1-y0, x1-x0) + ang;
          223         if (nhead < 2)
          224                 nhead = 2;
          225         dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha);
          226         printf("<path d=\"");
          227         for (i = 1; i >= 0; i--) {
          228                 drot = 2 * rot / (double) (2-1) * (double) i;
          229                 dx = hyp * cos(alpha + PI - rot + drot);
          230                 dy = hyp * sin(alpha + PI - rot + drot);
          231                 dprintf("dx,dy = %g,%g\n", dx, dy);
          232                 if(i == 1)
          233                         printf("M %.3f %.3f L %.3f %.3f", xconv(x1+dx), yconv(y1+dy), xconv(x1), yconv(y1));
          234                 else
          235                         printf(" L %.3f %.3f", xconv(x1+dx), yconv(y1+dy));
          236         }
          237         if (nhead > 2)
          238                 printf(" Z");
          239         printf("\"");
          240         if(nhead > 3)
          241                 printf(" fill=\"black\" stroke=\"black\"");
          242         else if(nhead == 3)
          243                 printf(" fill=\"white\" stroke=\"black\"");
          244         else
          245                 printf(" fill=\"transparent\" stroke=\"black\"");
          246         printf("/>\n");
          247 }
          248 
          249 double lastgray = 0;
          250 
          251 void fillstart(double v, int vis, int fill)
          252 {
          253         int x;
          254 
          255         if(fill) {
          256                 x = (int)(v*255.0);
          257                 sprintf(svgfill, "#%02x%02x%02x", x, x, x);
          258         } else
          259                 strcpy(svgfill, "transparent");
          260         if(vis)
          261                 strcpy(svgstroke, "black");
          262         else
          263                 strcpy(svgstroke, "transparent");
          264 }
          265 
          266 void fillend(void)
          267 {
          268         strcpy(svgfill, "transparent");
          269         strcpy(svgstroke, "black");
          270 }
          271 
          272 void box(double x0, double y0, double x1, double y1, int attr, double ddval)
          273 {
          274         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));
          275         if(attr & DASHBIT)
          276                 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
          277         else if(attr & DOTBIT)
          278                 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
          279         printf("/>\n");
          280 
          281 }
          282 
          283 void circle(double x, double y, double r)
          284 {
          285         printf("<circle cx=\"%.3f\" cy=\"%.3f\" r=\"%.3f\" fill=\"%s\" stroke=\"%s\"/>\n", xconv(x), yconv(y), xsc(r), svgfill, svgstroke);
          286 }
          287 
          288 void spline(double x, double y, double n, ofloat *p, int attr, double ddval)
          289 {
          290         int i;
          291         double x1, y1;
          292 
          293         printf("<path d=\"M %.3f %.3f", xconv(x), yconv(y));
          294         x1 = 0;
          295         y1 = 0;
          296         for (i = 0; i < 2 * n; i += 2) {
          297                 x1 = x;
          298                 y1 = y;
          299                 x += p[i];
          300                 y += p[i+1];
          301                 if(i == 0)
          302                         printf(" L %.3f %.3f", xconv((x+x1)/2), yconv((y+y1)/2));
          303                 else
          304                         printf(" Q %.3f %.3f %.3f %.3f", xconv(x1), yconv(y1), xconv((x+x1)/2), yconv((y+y1)/2));
          305         }
          306         printf(" L %.3f %.3f", xconv(x), yconv(y));
          307         printf("\" fill=\"%s\" stroke=\"%s\"", svgfill, svgstroke);
          308         if(attr & DASHBIT)
          309                 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
          310         else if(attr & DOTBIT)
          311                 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
          312         printf("/>\n");
          313 }
          314 
          315 void ellipse(double x, double y, double r1, double r2)
          316 {
          317         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);
          318 }
          319 
          320 void arc(double x, double y, double x0, double y0, double x1, double y1, double r)        /* draw arc with center x,y */
          321 {
          322         printf("<path d=\"M %.3f %.3f A %.3f %.3f %d %d %d %.3f %.3f\" fill=\"%s\" stroke=\"%s\"/>\n",
          323                 xconv(x0), yconv(y0),
          324                 xsc(r), ysc(r), 0, 0, 0, xconv(x1), yconv(y1),
          325                 svgfill, svgstroke);
          326 }