plan9port

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

circgen.c (2713B)


      1 #include	<stdio.h>
      2 #include	"pic.h"
      3 #include	"y.tab.h"
      4 
      5 obj *circgen(int type)
      6 {
      7 	static double rad[2] = { HT2, WID2 };
      8 	static double rad2[2] = { HT2, HT2 };
      9 	int i, at, t, with, battr;
     10 	double xwith, ywith;
     11 	double r, r2, ddval, fillval;
     12 	obj *p, *ppos;
     13 	Attr *ap;
     14 
     15 	r = r2 = 0.0; /* Botch? (gcc) */
     16 
     17 	battr = at = 0;
     18 	with = xwith = ywith = fillval = ddval = 0;
     19 	t = (type == CIRCLE) ? 0 : 1;
     20 	if (type == CIRCLE)
     21 		r = r2 = getfval("circlerad");
     22 	else if (type == ELLIPSE) {
     23 		r = getfval("ellipsewid") / 2;
     24 		r2 = getfval("ellipseht") / 2;
     25 	}
     26 	for (i = 0; i < nattr; i++) {
     27 		ap = &attr[i];
     28 		switch (ap->a_type) {
     29 		case TEXTATTR:
     30 			savetext(ap->a_sub, ap->a_val.p);
     31 			break;
     32 		case RADIUS:
     33 			r = ap->a_val.f;
     34 			break;
     35 		case DIAMETER:
     36 		case WIDTH:
     37 			r = ap->a_val.f / 2;
     38 			break;
     39 		case HEIGHT:
     40 			r2 = ap->a_val.f / 2;
     41 			break;
     42 		case SAME:
     43 			r = rad[t];
     44 			r2 = rad2[t];
     45 			break;
     46 		case WITH:
     47 			with = ap->a_val.i;
     48 			break;
     49 		case AT:
     50 			ppos = ap->a_val.o;
     51 			curx = ppos->o_x;
     52 			cury = ppos->o_y;
     53 			at++;
     54 			break;
     55 		case INVIS:
     56 			battr |= INVIS;
     57 			break;
     58 		case NOEDGE:
     59 			battr |= NOEDGEBIT;
     60 			break;
     61 		case DOT:
     62 		case DASH:
     63 			battr |= ap->a_type==DOT ? DOTBIT : DASHBIT;
     64 			if (ap->a_sub == DEFAULT)
     65 				ddval = getfval("dashwid");
     66 			else
     67 				ddval = ap->a_val.f;
     68 			break;
     69 		case FILL:
     70 			battr |= FILLBIT;
     71 			if (ap->a_sub == DEFAULT)
     72 				fillval = getfval("fillval");
     73 			else
     74 				fillval = ap->a_val.f;
     75 			break;
     76 		}
     77 	}
     78 	if (type == CIRCLE)
     79 		r2 = r;	/* probably superfluous */
     80 	if (with) {
     81 		switch (with) {
     82 		case NORTH:	ywith = -r2; break;
     83 		case SOUTH:	ywith = r2; break;
     84 		case EAST:	xwith = -r; break;
     85 		case WEST:	xwith = r; break;
     86 		case NE:	xwith = -r * 0.707; ywith = -r2 * 0.707; break;
     87 		case SE:	xwith = -r * 0.707; ywith = r2 * 0.707; break;
     88 		case NW:	xwith = r * 0.707; ywith = -r2 * 0.707; break;
     89 		case SW:	xwith = r * 0.707; ywith = r2 * 0.707; break;
     90 		}
     91 		curx += xwith;
     92 		cury += ywith;
     93 	}
     94 	if (!at) {
     95 		if (isright(hvmode))
     96 			curx += r;
     97 		else if (isleft(hvmode))
     98 			curx -= r;
     99 		else if (isup(hvmode))
    100 			cury += r2;
    101 		else
    102 			cury -= r2;
    103 	}
    104 	p = makenode(type, 2);
    105 	p->o_val[0] = rad[t] = r;
    106 	p->o_val[1] = rad2[t] = r2;
    107 	if (r <= 0 || r2 <= 0) {
    108 		ERROR "%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2 WARNING;
    109 	}
    110 	p->o_attr = battr;
    111 	p->o_ddval = ddval;
    112 	p->o_fillval = fillval;
    113 	extreme(curx+r, cury+r2);
    114 	extreme(curx-r, cury-r2);
    115 	if (type == CIRCLE)
    116 		dprintf("C %g %g %g\n", curx, cury, r);
    117 	if (type == ELLIPSE)
    118 		dprintf("E %g %g %g %g\n", curx, cury, r, r2);
    119 	if (isright(hvmode))
    120 		curx += r;
    121 	else if (isleft(hvmode))
    122 		curx -= r;
    123 	else if (isup(hvmode))
    124 		cury += r2;
    125 	else
    126 		cury -= r2;
    127 	return(p);
    128 }