plan9port

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

blockgen.c (5073B)


      1 #include	<stdio.h>
      2 #include	"pic.h"
      3 #include	"y.tab.h"
      4 
      5 #define	NBRACK	20	/* depth of [...] */
      6 #define	NBRACE	20	/* depth of {...} */
      7 
      8 struct pushstack stack[NBRACK];
      9 int	nstack	= 0;
     10 struct pushstack bracestack[NBRACE];
     11 int	nbstack	= 0;
     12 
     13 obj*
     14 leftthing(int c)	/* called for {... or [... */
     15 			/* really ought to be separate functions */
     16 {
     17 	obj *p;
     18 
     19 	if (c == '[') {
     20 		if (nstack >= NBRACK)
     21 			ERROR "[...] nested too deep" FATAL;
     22 		stack[nstack].p_x = curx;
     23 		stack[nstack].p_y = cury;
     24 		stack[nstack].p_hvmode = hvmode;
     25 		curx = cury = 0;
     26 		stack[nstack].p_xmin = xmin;
     27 		stack[nstack].p_xmax = xmax;
     28 		stack[nstack].p_ymin = ymin;
     29 		stack[nstack].p_ymax = ymax;
     30 		nstack++;
     31 		xmin = ymin = 30000;
     32 		xmax = ymax = -30000;
     33 		p = makenode(BLOCK, 7);
     34 		p->o_val[4] = nobj;	/* 1st item within [...] */
     35 		if (p->o_nobj != nobj-1)
     36 			fprintf(stderr, "nobjs wrong%d %d\n", p->o_nobj, nobj);
     37 	} else {
     38 		if (nbstack >= NBRACK)
     39 			ERROR "{...} nested too deep" FATAL;
     40 		bracestack[nbstack].p_x = curx;
     41 		bracestack[nbstack].p_y = cury;
     42 		bracestack[nbstack].p_hvmode = hvmode;
     43 		nbstack++;
     44 		p = NULL;
     45 	}
     46 	return(p);
     47 }
     48 
     49 obj*
     50 rightthing(obj *p, int c)	/* called for ... ] or ... } */
     51 {
     52 	obj *q;
     53 
     54 	if (c == '}') {
     55 		nbstack--;
     56 		curx = bracestack[nbstack].p_x;
     57 		cury = bracestack[nbstack].p_y;
     58 		hvmode = bracestack[nbstack].p_hvmode;
     59 		q = makenode(MOVE, 0);
     60 		dprintf("M %g %g\n", curx, cury);
     61 	} else {
     62 		nstack--;
     63 		curx = stack[nstack].p_x;
     64 		cury = stack[nstack].p_y;
     65 		hvmode = stack[nstack].p_hvmode;
     66 		q = makenode(BLOCKEND, 7);
     67 		q->o_val[4] = p->o_nobj + 1;	/* back pointer */
     68 		p->o_val[5] = q->o_nobj - 1;	/* forward pointer */
     69 		p->o_val[0] = xmin; p->o_val[1] = ymin;
     70 		p->o_val[2] = xmax; p->o_val[3] = ymax;
     71 		p->o_symtab = q->o_symtab = stack[nstack+1].p_symtab;
     72 		xmin = stack[nstack].p_xmin;
     73 		ymin = stack[nstack].p_ymin;
     74 		xmax = stack[nstack].p_xmax;
     75 		ymax = stack[nstack].p_ymax;
     76 	}
     77 	return(q);
     78 }
     79 
     80 obj*
     81 blockgen(obj *p, obj *q)	/* handles [...] */
     82 {
     83 	int i, invis, at, with;
     84 	double ddval, h, w, xwith, ywith;
     85 	double x0, y0, x1, y1, cx, cy;
     86 	obj *ppos;
     87 	Attr *ap;
     88 
     89 	invis = at = 0;
     90 	with = xwith = ywith = 0;
     91 	ddval = 0;
     92 	w = p->o_val[2] - p->o_val[0];
     93 	h = p->o_val[3] - p->o_val[1];
     94 	cx = (p->o_val[2] + p->o_val[0]) / 2;	/* geom ctr of [] wrt local orogin */
     95 	cy = (p->o_val[3] + p->o_val[1]) / 2;
     96 	dprintf("cx,cy=%g,%g\n", cx, cy);
     97 	for (i = 0; i < nattr; i++) {
     98 		ap = &attr[i];
     99 		switch (ap->a_type) {
    100 		case HEIGHT:
    101 			h = ap->a_val.f;
    102 			break;
    103 		case WIDTH:
    104 			w = ap->a_val.f;
    105 			break;
    106 		case WITH:
    107 			with = ap->a_val.i;	/* corner */
    108 			break;
    109 		case PLACE:	/* actually with position ... */
    110 			ppos = ap->a_val.o;
    111 			xwith = cx - ppos->o_x;
    112 			ywith = cy - ppos->o_y;
    113 			with = PLACE;
    114 			break;
    115 		case AT:
    116 		case FROM:
    117 			ppos = ap->a_val.o;
    118 			curx = ppos->o_x;
    119 			cury = ppos->o_y;
    120 			at++;
    121 			break;
    122 		case INVIS:
    123 			invis = INVIS;
    124 			break;
    125 		case TEXTATTR:
    126 			savetext(ap->a_sub, ap->a_val.p);
    127 			break;
    128 		}
    129 	}
    130 	if (with) {
    131 		switch (with) {
    132 		case NORTH:	ywith = -h / 2; break;
    133 		case SOUTH:	ywith = h / 2; break;
    134 		case EAST:	xwith = -w / 2; break;
    135 		case WEST:	xwith = w / 2; break;
    136 		case NE:	xwith = -w / 2; ywith = -h / 2; break;
    137 		case SE:	xwith = -w / 2; ywith = h / 2; break;
    138 		case NW:	xwith = w / 2; ywith = -h / 2; break;
    139 		case SW:	xwith = w / 2; ywith = h / 2; break;
    140 		}
    141 		curx += xwith;
    142 		cury += ywith;
    143 	}
    144 	if (!at) {
    145 		if (isright(hvmode))
    146 			curx += w / 2;
    147 		else if (isleft(hvmode))
    148 			curx -= w / 2;
    149 		else if (isup(hvmode))
    150 			cury += h / 2;
    151 		else
    152 			cury -= h / 2;
    153 	}
    154 	x0 = curx - w / 2;
    155 	y0 = cury - h / 2;
    156 	x1 = curx + w / 2;
    157 	y1 = cury + h / 2;
    158 	extreme(x0, y0);
    159 	extreme(x1, y1);
    160 	p->o_x = curx;
    161 	p->o_y = cury;
    162 	p->o_nt1 = ntext1;
    163 	p->o_nt2 = ntext;
    164 	ntext1 = ntext;
    165 	p->o_val[0] = w;
    166 	p->o_val[1] = h;
    167 	p->o_val[2] = cx;
    168 	p->o_val[3] = cy;
    169 	p->o_val[5] = q->o_nobj - 1;		/* last item in [...] */
    170 	p->o_ddval = ddval;
    171 	p->o_attr = invis;
    172 	dprintf("[] %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w);
    173 	if (isright(hvmode))
    174 		curx = x1;
    175 	else if (isleft(hvmode))
    176 		curx = x0;
    177 	else if (isup(hvmode))
    178 		cury = y1;
    179 	else
    180 		cury = y0;
    181 	for (i = 0; i <= 5; i++)
    182 		q->o_val[i] = p->o_val[i];
    183 	stack[nstack+1].p_symtab = NULL;	/* so won't be found again */
    184 	blockadj(p);	/* fix up coords for enclosed blocks */
    185 	return(p);
    186 }
    187 
    188 void
    189 blockadj(obj *p)	/* adjust coords in block starting at p */
    190 {
    191 	double dx, dy;
    192 	int n, lev;
    193 
    194 	dx = p->o_x - p->o_val[2];
    195 	dy = p->o_y - p->o_val[3];
    196 	n = p->o_nobj + 1;
    197 	dprintf("into blockadj: dx,dy=%g,%g\n", dx, dy);
    198 	for (lev = 1; lev > 0; n++) {
    199 		p = objlist[n];
    200 		if (p->o_type == BLOCK)
    201 			lev++;
    202 		else if (p->o_type == BLOCKEND)
    203 			lev--;
    204 		dprintf("blockadj: type=%d o_x,y=%g,%g;", p->o_type, p->o_x, p->o_y);
    205 		p->o_x += dx;
    206 		p->o_y += dy;
    207 		dprintf(" becomes %g,%g\n", p->o_x, p->o_y);
    208 		switch (p->o_type) {	/* other absolute coords */
    209 		case LINE:
    210 		case ARROW:
    211 		case SPLINE:
    212 			p->o_val[0] += dx;
    213 			p->o_val[1] += dy;
    214 			break;
    215 		case ARC:
    216 			p->o_val[0] += dx;
    217 			p->o_val[1] += dy;
    218 			p->o_val[2] += dx;
    219 			p->o_val[3] += dy;
    220 			break;
    221 		}
    222 	}
    223 }