plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }