plan9port

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

circgen.c (2651B)


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