xref: /plan9/sys/src/cmd/pic/circgen.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include	<stdio.h>
23e12c5d1SDavid du Colombier #include	"pic.h"
33e12c5d1SDavid du Colombier #include	"y.tab.h"
43e12c5d1SDavid du Colombier 
circgen(int type)53e12c5d1SDavid du Colombier obj *circgen(int type)
63e12c5d1SDavid du Colombier {
73e12c5d1SDavid du Colombier 	static double rad[2] = { HT2, WID2 };
83e12c5d1SDavid du Colombier 	static double rad2[2] = { HT2, HT2 };
93e12c5d1SDavid du Colombier 	int i, at, t, with, battr;
103e12c5d1SDavid du Colombier 	double xwith, ywith;
113e12c5d1SDavid du Colombier 	double r, r2, ddval, fillval;
123e12c5d1SDavid du Colombier 	obj *p, *ppos;
133e12c5d1SDavid du Colombier 	Attr *ap;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier 	battr = at = 0;
163e12c5d1SDavid du Colombier 	with = xwith = ywith = fillval = ddval = 0;
173e12c5d1SDavid du Colombier 	t = (type == CIRCLE) ? 0 : 1;
183e12c5d1SDavid du Colombier 	if (type == CIRCLE)
193e12c5d1SDavid du Colombier 		r = r2 = getfval("circlerad");
203e12c5d1SDavid du Colombier 	else if (type == ELLIPSE) {
213e12c5d1SDavid du Colombier 		r = getfval("ellipsewid") / 2;
223e12c5d1SDavid du Colombier 		r2 = getfval("ellipseht") / 2;
233e12c5d1SDavid du Colombier 	}
243e12c5d1SDavid du Colombier 	for (i = 0; i < nattr; i++) {
253e12c5d1SDavid du Colombier 		ap = &attr[i];
263e12c5d1SDavid du Colombier 		switch (ap->a_type) {
273e12c5d1SDavid du Colombier 		case TEXTATTR:
283e12c5d1SDavid du Colombier 			savetext(ap->a_sub, ap->a_val.p);
293e12c5d1SDavid du Colombier 			break;
303e12c5d1SDavid du Colombier 		case RADIUS:
313e12c5d1SDavid du Colombier 			r = ap->a_val.f;
323e12c5d1SDavid du Colombier 			break;
333e12c5d1SDavid du Colombier 		case DIAMETER:
343e12c5d1SDavid du Colombier 		case WIDTH:
353e12c5d1SDavid du Colombier 			r = ap->a_val.f / 2;
363e12c5d1SDavid du Colombier 			break;
373e12c5d1SDavid du Colombier 		case HEIGHT:
383e12c5d1SDavid du Colombier 			r2 = ap->a_val.f / 2;
393e12c5d1SDavid du Colombier 			break;
403e12c5d1SDavid du Colombier 		case SAME:
413e12c5d1SDavid du Colombier 			r = rad[t];
423e12c5d1SDavid du Colombier 			r2 = rad2[t];
433e12c5d1SDavid du Colombier 			break;
443e12c5d1SDavid du Colombier 		case WITH:
453e12c5d1SDavid du Colombier 			with = ap->a_val.i;
463e12c5d1SDavid du Colombier 			break;
473e12c5d1SDavid du Colombier 		case AT:
483e12c5d1SDavid du Colombier 			ppos = ap->a_val.o;
493e12c5d1SDavid du Colombier 			curx = ppos->o_x;
503e12c5d1SDavid du Colombier 			cury = ppos->o_y;
513e12c5d1SDavid du Colombier 			at++;
523e12c5d1SDavid du Colombier 			break;
533e12c5d1SDavid du Colombier 		case INVIS:
543e12c5d1SDavid du Colombier 			battr |= INVIS;
553e12c5d1SDavid du Colombier 			break;
56*7dd7cddfSDavid du Colombier 		case NOEDGE:
57*7dd7cddfSDavid du Colombier 			battr |= NOEDGEBIT;
58*7dd7cddfSDavid du Colombier 			break;
593e12c5d1SDavid du Colombier 		case DOT:
603e12c5d1SDavid du Colombier 		case DASH:
613e12c5d1SDavid du Colombier 			battr |= ap->a_type==DOT ? DOTBIT : DASHBIT;
623e12c5d1SDavid du Colombier 			if (ap->a_sub == DEFAULT)
633e12c5d1SDavid du Colombier 				ddval = getfval("dashwid");
643e12c5d1SDavid du Colombier 			else
653e12c5d1SDavid du Colombier 				ddval = ap->a_val.f;
663e12c5d1SDavid du Colombier 			break;
673e12c5d1SDavid du Colombier 		case FILL:
683e12c5d1SDavid du Colombier 			battr |= FILLBIT;
693e12c5d1SDavid du Colombier 			if (ap->a_sub == DEFAULT)
703e12c5d1SDavid du Colombier 				fillval = getfval("fillval");
713e12c5d1SDavid du Colombier 			else
723e12c5d1SDavid du Colombier 				fillval = ap->a_val.f;
733e12c5d1SDavid du Colombier 			break;
743e12c5d1SDavid du Colombier 		}
753e12c5d1SDavid du Colombier 	}
763e12c5d1SDavid du Colombier 	if (type == CIRCLE)
773e12c5d1SDavid du Colombier 		r2 = r;	/* probably superfluous */
783e12c5d1SDavid du Colombier 	if (with) {
793e12c5d1SDavid du Colombier 		switch (with) {
803e12c5d1SDavid du Colombier 		case NORTH:	ywith = -r2; break;
813e12c5d1SDavid du Colombier 		case SOUTH:	ywith = r2; break;
823e12c5d1SDavid du Colombier 		case EAST:	xwith = -r; break;
833e12c5d1SDavid du Colombier 		case WEST:	xwith = r; break;
843e12c5d1SDavid du Colombier 		case NE:	xwith = -r * 0.707; ywith = -r2 * 0.707; break;
853e12c5d1SDavid du Colombier 		case SE:	xwith = -r * 0.707; ywith = r2 * 0.707; break;
863e12c5d1SDavid du Colombier 		case NW:	xwith = r * 0.707; ywith = -r2 * 0.707; break;
873e12c5d1SDavid du Colombier 		case SW:	xwith = r * 0.707; ywith = r2 * 0.707; break;
883e12c5d1SDavid du Colombier 		}
893e12c5d1SDavid du Colombier 		curx += xwith;
903e12c5d1SDavid du Colombier 		cury += ywith;
913e12c5d1SDavid du Colombier 	}
923e12c5d1SDavid du Colombier 	if (!at) {
933e12c5d1SDavid du Colombier 		if (isright(hvmode))
943e12c5d1SDavid du Colombier 			curx += r;
953e12c5d1SDavid du Colombier 		else if (isleft(hvmode))
963e12c5d1SDavid du Colombier 			curx -= r;
973e12c5d1SDavid du Colombier 		else if (isup(hvmode))
983e12c5d1SDavid du Colombier 			cury += r2;
993e12c5d1SDavid du Colombier 		else
1003e12c5d1SDavid du Colombier 			cury -= r2;
1013e12c5d1SDavid du Colombier 	}
1023e12c5d1SDavid du Colombier 	p = makenode(type, 2);
1033e12c5d1SDavid du Colombier 	p->o_val[0] = rad[t] = r;
1043e12c5d1SDavid du Colombier 	p->o_val[1] = rad2[t] = r2;
1053e12c5d1SDavid du Colombier 	if (r <= 0 || r2 <= 0) {
1063e12c5d1SDavid du Colombier 		ERROR "%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2 WARNING;
1073e12c5d1SDavid du Colombier 	}
1083e12c5d1SDavid du Colombier 	p->o_attr = battr;
1093e12c5d1SDavid du Colombier 	p->o_ddval = ddval;
1103e12c5d1SDavid du Colombier 	p->o_fillval = fillval;
1113e12c5d1SDavid du Colombier 	extreme(curx+r, cury+r2);
1123e12c5d1SDavid du Colombier 	extreme(curx-r, cury-r2);
1133e12c5d1SDavid du Colombier 	if (type == CIRCLE)
1143e12c5d1SDavid du Colombier 		dprintf("C %g %g %g\n", curx, cury, r);
1153e12c5d1SDavid du Colombier 	if (type == ELLIPSE)
1163e12c5d1SDavid du Colombier 		dprintf("E %g %g %g %g\n", curx, cury, r, r2);
1173e12c5d1SDavid du Colombier 	if (isright(hvmode))
1183e12c5d1SDavid du Colombier 		curx += r;
1193e12c5d1SDavid du Colombier 	else if (isleft(hvmode))
1203e12c5d1SDavid du Colombier 		curx -= r;
1213e12c5d1SDavid du Colombier 	else if (isup(hvmode))
1223e12c5d1SDavid du Colombier 		cury += r2;
1233e12c5d1SDavid du Colombier 	else
1243e12c5d1SDavid du Colombier 		cury -= r2;
1253e12c5d1SDavid du Colombier 	return(p);
1263e12c5d1SDavid du Colombier }
127