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