plsvg.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 }