|
|
1.1 root 1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4: #include <math.h>
5: #include "pic.h"
6: #include "y.tab.h"
7:
8: int whatpos(obj *p, int corner, double *px, double *py);
9: void makeattr(int type, int sub, YYSTYPE val);
10: YYSTYPE getblk(obj *, char *);
11:
12: setdir(int n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
13: {
14: switch (n) {
15: case UP: hvmode = U_DIR; break;
16: case DOWN: hvmode = D_DIR; break;
17: case LEFT: hvmode = L_DIR; break;
18: case RIGHT: hvmode = R_DIR; break;
19: }
20: return(hvmode);
21: }
22:
23: curdir(void) /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
24: {
25: switch (hvmode) {
26: case R_DIR: return RIGHT;
27: case L_DIR: return LEFT;
28: case U_DIR: return UP;
29: case D_DIR: return DOWN;
30: }
31: ERROR "can't happen curdir" FATAL;
32: return 0;
33: }
34:
35: double getcomp(obj *p, int t) /* return component of a position */
36: {
37: switch (t) {
38: case DOTX:
39: return p->o_x;
40: case DOTY:
41: return p->o_y;
42: case DOTWID:
43: switch (p->o_type) {
44: case BOX:
45: case BLOCK:
46: case TEXT:
47: return p->o_val[0];
48: case CIRCLE:
49: case ELLIPSE:
50: return 2 * p->o_val[0];
51: case LINE:
52: case ARROW:
53: return p->o_val[0] - p->o_x;
54: case PLACE:
55: return 0;
56: }
57: case DOTHT:
58: switch (p->o_type) {
59: case BOX:
60: case BLOCK:
61: case TEXT:
62: return p->o_val[1];
63: case CIRCLE:
64: case ELLIPSE:
65: return 2 * p->o_val[1];
66: case LINE:
67: case ARROW:
68: return p->o_val[1] - p->o_y;
69: case PLACE:
70: return 0;
71: }
72: case DOTRAD:
73: switch (p->o_type) {
74: case CIRCLE:
75: case ELLIPSE:
76: return p->o_val[0];
77: }
78: }
79: ERROR "you asked for a weird dimension or position" WARNING;
80: return 0;
81: }
82:
83: double exprlist[100];
84: int nexpr = 0;
85:
86: void exprsave(double f)
87: {
88: exprlist[nexpr++] = f;
89: }
90:
91: char *sprintgen(char *fmt)
92: {
93: char buf[1000];
94:
95: sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
96: nexpr = 0;
97: free(fmt);
98: return tostring(buf);
99: }
100:
101: void makefattr(int type, int sub, double f) /* double attr */
102: {
103: YYSTYPE val;
104: val.f = f;
105: makeattr(type, sub, val);
106: }
107:
108: void makeoattr(int type, obj *o) /* obj* attr */
109: {
110: YYSTYPE val;
111: val.o = o;
112: makeattr(type, 0, val);
113: }
114:
115: void makeiattr(int type, int i) /* int attr */
116: {
117: YYSTYPE val;
118: val.i = i;
119: makeattr(type, 0, val);
120: }
121:
122: void maketattr(int sub, char *p) /* text attribute: takes two */
123: {
124: YYSTYPE val;
125: val.p = p;
126: makeattr(TEXTATTR, sub, val);
127: }
128:
129: void addtattr(int sub) /* add text attrib to existing item */
130: {
131: attr[nattr-1].a_sub |= sub;
132: }
133:
134: void makevattr(char *p) /* varname attribute */
135: {
136: YYSTYPE val;
137: val.p = p;
138: makeattr(VARNAME, 0, val);
139: }
140:
141: void makeattr(int type, int sub, YYSTYPE val) /* add attribute type and val */
142: {
143: if (type == 0 && val.i == 0) { /* clear table for next stat */
144: nattr = 0;
145: return;
146: }
147: if (nattr >= nattrlist)
148: attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
149: dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i);
150: attr[nattr].a_type = type;
151: attr[nattr].a_sub = sub;
152: attr[nattr].a_val = val;
153: nattr++;
154: }
155:
156: void printexpr(double f) /* print expression for debugging */
157: {
158: printf("%g\n", f);
159: }
160:
161: void printpos(obj *p) /* print position for debugging */
162: {
163: printf("%g, %g\n", p->o_x, p->o_y);
164: }
165:
166: char *tostring(char *s)
167: {
168: register char *p;
169:
170: p = malloc(strlen(s)+1);
171: if (p == NULL)
172: ERROR "out of space in tostring on %s", s FATAL;
173: strcpy(p, s);
174: return(p);
175: }
176:
177: obj *makepos(double x, double y) /* make a position cell */
178: {
179: obj *p;
180:
181: p = makenode(PLACE, 0);
182: p->o_x = x;
183: p->o_y = y;
184: return(p);
185: }
186:
187: obj *makebetween(double f, obj *p1, obj *p2) /* make position between p1 and p2 */
188: {
189: obj *p;
190:
191: dprintf("fraction = %.2f\n", f);
192: p = makenode(PLACE, 0);
193: p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
194: p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
195: return(p);
196: }
197:
198: obj *getpos(obj *p, int corner) /* find position of point */
199: {
200: double x, y;
201:
202: whatpos(p, corner, &x, &y);
203: return makepos(x, y);
204: }
205:
206: int whatpos(obj *p, int corner, double *px, double *py) /* what is the position (no side effect) */
207: {
208: double x, y, x1, y1;
209:
210: dprintf("whatpos %o %d %d\n", p, p->o_type, corner);
211: x = p->o_x;
212: y = p->o_y;
213: if (p->o_type != PLACE && p->o_type != MOVE) {
214: x1 = p->o_val[0];
215: y1 = p->o_val[1];
216: }
217: switch (p->o_type) {
218: case PLACE:
219: break;
220: case BOX:
221: case BLOCK:
222: case TEXT:
223: switch (corner) {
224: case NORTH: y += y1 / 2; break;
225: case SOUTH: y -= y1 / 2; break;
226: case EAST: x += x1 / 2; break;
227: case WEST: x -= x1 / 2; break;
228: case NE: x += x1 / 2; y += y1 / 2; break;
229: case SW: x -= x1 / 2; y -= y1 / 2; break;
230: case SE: x += x1 / 2; y -= y1 / 2; break;
231: case NW: x -= x1 / 2; y += y1 / 2; break;
232: case START:
233: if (p->o_type == BLOCK)
234: return whatpos(objlist[(int)p->o_val[2]], START, px, py);
235: case END:
236: if (p->o_type == BLOCK)
237: return whatpos(objlist[(int)p->o_val[3]], END, px, py);
238: }
239: break;
240: case ARC:
241: switch (corner) {
242: case START:
243: if (p->o_attr & CW_ARC) {
244: x = p->o_val[2]; y = p->o_val[3];
245: } else {
246: x = x1; y = y1;
247: }
248: break;
249: case END:
250: if (p->o_attr & CW_ARC) {
251: x = x1; y = y1;
252: } else {
253: x = p->o_val[2]; y = p->o_val[3];
254: }
255: break;
256: }
257: if (corner == START || corner == END)
258: break;
259: x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
260: /* Fall Through! */
261: case CIRCLE:
262: case ELLIPSE:
263: switch (corner) {
264: case NORTH: y += y1; break;
265: case SOUTH: y -= y1; break;
266: case EAST: x += x1; break;
267: case WEST: x -= x1; break;
268: case NE: x += 0.707 * x1; y += 0.707 * y1; break;
269: case SE: x += 0.707 * x1; y -= 0.707 * y1; break;
270: case NW: x -= 0.707 * x1; y += 0.707 * y1; break;
271: case SW: x -= 0.707 * x1; y -= 0.707 * y1; break;
272: }
273: break;
274: case LINE:
275: case SPLINE:
276: case ARROW:
277: switch (corner) {
278: case START: break; /* already in place */
279: case END: x = x1; y = y1; break;
280: default: /* change! */
281: case CENTER: x = (x+x1)/2; y = (y+y1)/2; break;
282: case NORTH: if (y1 > y) { x = x1; y = y1; } break;
283: case SOUTH: if (y1 < y) { x = x1; y = y1; } break;
284: case EAST: if (x1 > x) { x = x1; y = y1; } break;
285: case WEST: if (x1 < x) { x = x1; y = y1; } break;
286: }
287: break;
288: case MOVE:
289: /* really ought to be same as line... */
290: break;
291: }
292: dprintf("whatpos returns %g %g\n", x, y);
293: *px = x;
294: *py = y;
295: return 1;
296: }
297:
298: obj *gethere(void) /* make a place for curx,cury */
299: {
300: dprintf("gethere %g %g\n", curx, cury);
301: return(makepos(curx, cury));
302: }
303:
304: obj *getlast(int n, int t) /* find n-th previous occurrence of type t */
305: {
306: int i, k;
307: obj *p;
308:
309: k = n;
310: for (i = nobj-1; i >= 0; i--) {
311: p = objlist[i];
312: if (p->o_type == BLOCKEND) {
313: i = p->o_val[4];
314: continue;
315: }
316: if (p->o_type != t)
317: continue;
318: if (--k > 0)
319: continue; /* not there yet */
320: dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
321: return(p);
322: }
323: ERROR "there is no %dth last", n WARNING;
324: return(NULL);
325: }
326:
327: obj *getfirst(int n, int t) /* find n-th occurrence of type t */
328: {
329: int i, k;
330: obj *p;
331:
332: k = n;
333: for (i = 0; i < nobj; i++) {
334: p = objlist[i];
335: if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */
336: i = p->o_val[5] + 1;
337: continue;
338: }
339: if (p->o_type != t)
340: continue;
341: if (--k > 0)
342: continue; /* not there yet */
343: dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
344: return(p);
345: }
346: ERROR "there is no %dth ", n WARNING;
347: return(NULL);
348: }
349:
350: double getblkvar(obj *p, char *s) /* find variable s2 in block p */
351: {
352: YYSTYPE y;
353:
354: y = getblk(p, s);
355: return y.f;
356: }
357:
358: obj *getblock(obj *p, char *s) /* find variable s in block p */
359: {
360: YYSTYPE y;
361:
362: y = getblk(p, s);
363: return y.o;
364: }
365:
366: YYSTYPE getblk(obj *p, char *s) /* find union type for s in p */
367: {
368: static YYSTYPE bug;
369: struct symtab *stp;
370:
371: if (p->o_type != BLOCK) {
372: ERROR ".%s is not in that block", s WARNING;
373: return(bug);
374: }
375: for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
376: if (strcmp(s, stp->s_name) == 0) {
377: dprintf("getblk %s found x,y= %g,%g\n",
378: s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
379: return(stp->s_val);
380: }
381: ERROR "there is no .%s in that []", s WARNING;
382: return(bug);
383: }
384:
385: obj *fixpos(obj *p, double x, double y)
386: {
387: dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
388: return makepos(p->o_x + x, p->o_y + y);
389: }
390:
391: obj *addpos(obj *p, obj *q)
392: {
393: dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
394: return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
395: }
396:
397: obj *subpos(obj *p, obj *q)
398: {
399: dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
400: return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
401: }
402:
403: obj *makenode(int type, int n)
404: {
405: obj *p;
406:
407: p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat));
408: if (p == NULL)
409: ERROR "out of space in makenode" FATAL;
410: p->o_type = type;
411: p->o_count = n;
412: p->o_nobj = nobj;
413: p->o_mode = hvmode;
414: p->o_x = curx;
415: p->o_y = cury;
416: p->o_nt1 = ntext1;
417: p->o_nt2 = ntext;
418: ntext1 = ntext; /* ready for next caller */
419: if (nobj >= nobjlist)
420: objlist = (obj **) grow((char *) objlist, "objlist",
421: nobjlist *= 2, sizeof(obj *));
422: objlist[nobj++] = p;
423: return(p);
424: }
425:
426: void extreme(double x, double y) /* record max and min x and y values */
427: {
428: if (x > xmax)
429: xmax = x;
430: if (y > ymax)
431: ymax = y;
432: if (x < xmin)
433: xmin = x;
434: if (y < ymin)
435: ymin = y;
436: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.