|
|
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.