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