|
|
1.1 ! root 1: /* Copyright (c) 1988 AT&T */ ! 2: /* All Rights Reserved */ ! 3: ! 4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 5: /* The copyright notice above does not evidence any */ ! 6: /* actual or intended publication of such source code. */ ! 7: ! 8: /* @(#)picasso:linegen.c 1.0 */ ! 9: #include "picasso.h" ! 10: #include "y.tab.h" ! 11: ! 12: static float *dx = NULL; ! 13: static float *dy = NULL; ! 14: static int nxy = 0; ! 15: static int nxyvec = 0; ! 16: ! 17: growxy() ! 18: { ! 19: if (nxy++ >= nxyvec - 1) { ! 20: dx = (float *)grow((char *)dx,"dx",nxyvec += 256,sizeof(float)); ! 21: dy = (float *)grow((char *)dy,"dy",nxyvec,sizeof(float)); ! 22: } ! 23: } ! 24: ! 25: obj *linegen(type) ! 26: { ! 27: static double prevdx = HT; ! 28: static double prevdy = 0; ! 29: static double prevw = HT10; /* arrow dimensions */ ! 30: static double prevh = HT5; ! 31: static double prevrad = 0; ! 32: static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ ! 33: static int ytab[] = { 0, 1, 0, -1 }; ! 34: ! 35: struct objattr obat; ! 36: double theta, defx, defy, nx, ny, x0, y0, x1, y1, chop1, chop2; ! 37: float bbox[4]; ! 38: int i, j, some, head, chop; ! 39: obj *p, *ppos; ! 40: Attr *ap; ! 41: struct symtab *xlist, *ylist; ! 42: ! 43: nx = curx; ! 44: ny = cury; ! 45: defy = getfval("lineht"); ! 46: defx = getfval("linewid"); ! 47: obat.a_ht = getfval("arrowht"); ! 48: obat.a_wid = getfval("arrowwid"); ! 49: obat.a_rad = getfval("linerad"); ! 50: obat.a_layer = (int)getfval("curlayer"); ! 51: obat.a_flags = EDGED; ! 52: obat.a_weight = obat.a_lcolor = obat.a_pcolor = obat.a_tcolor = -1; ! 53: obat.a_dashpat.a = (float *)0; ! 54: set_text(); ! 55: if (nxyvec == 0) ! 56: growxy(); ! 57: dx[0] = dy[0] = chop1 = chop2 = 0; ! 58: nxy = some = head = chop = 0; ! 59: for (i = 0; i < nattr; i++) { ! 60: ap = &attr[i]; ! 61: switch (ap->a_type) { ! 62: default: ! 63: miscattrs(ap, &obat); ! 64: break; ! 65: case HEAD: ! 66: head += ap->a_val.i; ! 67: break; ! 68: case CHOP: ! 69: if (chop++ == 0) ! 70: chop1 = chop2 = ap->a_val.f; ! 71: else ! 72: chop2 = ap->a_val.f; ! 73: break; ! 74: case SAME: ! 75: dx[nxy] = prevdx; ! 76: dy[nxy] = prevdy; ! 77: obat.a_rad = prevrad; ! 78: obat.a_ht = prevh; ! 79: obat.a_wid = prevw; ! 80: some++; ! 81: break; ! 82: case LEFT: ! 83: dx[nxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; ! 84: some++; ! 85: hvmode = L_DIR; ! 86: break; ! 87: case RIGHT: ! 88: dx[nxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; ! 89: some++; ! 90: hvmode = R_DIR; ! 91: break; ! 92: case UP: ! 93: dy[nxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; ! 94: some++; ! 95: hvmode = U_DIR; ! 96: break; ! 97: case DOWN: ! 98: dy[nxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; ! 99: some++; ! 100: hvmode = D_DIR; ! 101: break; ! 102: case XLIST: ! 103: xlist = findvar(ap->a_val.p, VARNAME); ! 104: break; ! 105: case YLIST: ! 106: ylist = findvar(ap->a_val.p, VARNAME); ! 107: if (some) { ! 108: nx += dx[nxy]; ! 109: ny += dy[nxy]; ! 110: growxy(); ! 111: } ! 112: first_xy(xlist, ylist, &x0, &y0); ! 113: dx[nxy] = x0 - nx; ! 114: dy[nxy] = y0 - ny; ! 115: while (next_xy(xlist, ylist, &x0, &y0)) { ! 116: nx += dx[nxy]; ! 117: ny += dy[nxy]; ! 118: growxy(); ! 119: dx[nxy] = x0 - nx; ! 120: dy[nxy] = y0 - ny; ! 121: } ! 122: some++; ! 123: break; ! 124: case TO: ! 125: if (some) { ! 126: nx += dx[nxy]; ! 127: ny += dy[nxy]; ! 128: growxy(); ! 129: } ! 130: ppos = ap->a_val.o; ! 131: dx[nxy] = Xformx(ppos, 1, ppos->o_x, ppos->o_y) - nx; ! 132: dy[nxy] = Xformy(ppos, 0, ppos->o_x, ppos->o_y) - ny; ! 133: some++; ! 134: break; ! 135: case BY: ! 136: if (some) { ! 137: nx += dx[nxy]; ! 138: ny += dy[nxy]; ! 139: growxy(); ! 140: } ! 141: ppos = ap->a_val.o; ! 142: dx[nxy] = Xformx(ppos, 1, ppos->o_x, ppos->o_y); ! 143: dy[nxy] = Xformy(ppos, 0, ppos->o_x, ppos->o_y); ! 144: some++; ! 145: break; ! 146: case THEN: /* turn off any previous accumulation */ ! 147: if (some) { ! 148: nx += dx[nxy]; ! 149: ny += dy[nxy]; ! 150: growxy(); ! 151: dx[nxy] = dy[nxy] = some = 0; ! 152: } ! 153: break; ! 154: case FROM: ! 155: case AT: ! 156: ppos = ap->a_val.o; ! 157: nx = curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y); ! 158: ny = cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y); ! 159: break; ! 160: } ! 161: } ! 162: if (some) { ! 163: nx += dx[nxy]; ! 164: ny += dy[nxy]; ! 165: growxy(); ! 166: defx = dx[nxy-1]; ! 167: defy = dy[nxy-1]; ! 168: } else { ! 169: defx *= xtab[hvmode]; ! 170: defy *= ytab[hvmode]; ! 171: dx[nxy] = defx; ! 172: dy[nxy] = defy; ! 173: growxy(); ! 174: nx += defx; ! 175: ny += defy; ! 176: } ! 177: prevdx = defx; ! 178: prevdy = defy; ! 179: prevh = obat.a_ht; ! 180: prevw = obat.a_wid; ! 181: prevrad = obat.a_rad; ! 182: if (chop) { ! 183: if (chop1 == -1.0) /* just said "chop", so use default */ ! 184: chop1 = getfval("circlerad"); ! 185: if (chop2 == -1.0) ! 186: chop2 = getfval("circlerad"); ! 187: x0 = dx[0] * dx[0] + dy[0] *dy[0]; ! 188: if (chop1 > sqrt(x0)) { ! 189: yyerror("can't chop that much"); ! 190: chop1 = x0; ! 191: } ! 192: theta = atan2(dy[0], dx[0]); ! 193: x0 = chop1 * cos(theta); ! 194: y0 = chop1 * sin(theta); ! 195: curx += x0; ! 196: cury += y0; ! 197: dx[0] -= x0; ! 198: dy[0] -= y0; ! 199: ! 200: x1 = dx[nxy-1] * dx[nxy-1] + dy[nxy-1] *dy[nxy-1]; ! 201: if (chop2 > sqrt(x1)) { ! 202: yyerror("can't chop that much"); ! 203: chop2 = x1; ! 204: } ! 205: theta = atan2(dy[nxy-1], dx[nxy-1]); ! 206: x1 = chop2 * cos(theta); ! 207: y1 = chop2 * sin(theta); ! 208: nx -= x1; ! 209: ny -= y1; ! 210: dx[nxy-1] -= x1; ! 211: dy[nxy-1] -= y1; ! 212: } ! 213: /* input file could specify ...to 3,2 to 3,2 ... ! 214: so eliminate repeated pts */ ! 215: for (i = j = 0; i < nxy; i++) { ! 216: if (dx[i] == 0. && dy[i] == 0.) ! 217: continue; ! 218: else if (j != i) { ! 219: dx[j] = dx[i]; ! 220: dy[j] = dy[i]; ! 221: } ! 222: j++; ! 223: } ! 224: nxy = j; ! 225: p = makenode(type, N_VAL + 6 + 2 * nxy, obat.a_layer); ! 226: primattrs(p, &obat); ! 227: text_bounds(p); ! 228: prevrad = p->o_val[N_VAL].f = obat.a_rad; ! 229: p->o_val[N_VAL+3].f = nxy; /* note: segments, not points */ ! 230: p->o_val[N_VAL+4].f = bbox[0] = bbox[2] = curx; ! 231: p->o_val[N_VAL+5].f = bbox[1] = bbox[3] = cury; ! 232: ! 233: for (i = 0, j = N_VAL+6; i < nxy; i++, j += 2) { ! 234: /* restoring absolute coordinates */ ! 235: p->o_val[j].f = curx += dx[i]; ! 236: p->o_val[j+1].f = cury += dy[i]; ! 237: extreme(curx, cury, bbox); /* OVERestimate, for splines */ ! 238: #if 0 ! 239: if (type == LINE || type == ARROW) ! 240: extreme(curx, cury, bbox); ! 241: else if (type == SPLINE) { ! 242: if (i < nxy-1) { ! 243: /* to compute approx extreme of spline at p, */ ! 244: /* compute midway between p-1 and p+1, */ ! 245: /* then go 3/4 from there to p */ ! 246: double ex, ey, xi, yi, xi1, yi1; ! 247: ! 248: xi = curx-dx[i]; ! 249: yi = cury-dy[i]; /* p-1 */ ! 250: xi1 = curx+dx[i+1]; ! 251: yi1 = cury+dy[i+1]; /* p+1 */ ! 252: ex = (curx+xi1)/2; ! 253: ey = (cury+yi1)/2; /* midpt */ ! 254: ex += 0.75*(curx-ex); ey += 0.75*(cury-ey); ! 255: extreme(ex, ey, bbox); ! 256: } ! 257: else extreme(curx, cury, bbox); ! 258: } ! 259: #endif ! 260: } ! 261: if (head || type == ARROW) { ! 262: if (head == 0) ! 263: head = HEAD2; /* default arrow head */ ! 264: p->o_attr |= head | arrowfill(); ! 265: p->o_val[N_VAL+1].f = obat.a_wid; ! 266: p->o_val[N_VAL+2].f = obat.a_ht; ! 267: if (head & HEAD1) ! 268: track_head (p->o_val[N_VAL+6].f, p->o_val[N_VAL+7].f, ! 269: p->o_val[N_VAL+4].f, p->o_val[N_VAL+5].f, ! 270: prevw, prevh, bbox); ! 271: if (head & HEAD2) { ! 272: j = N_VAL + 2 + 2 * nxy; ! 273: track_head (p->o_val[j+0].f, p->o_val[j+1].f, ! 274: p->o_val[j+2].f, p->o_val[j+3].f, ! 275: prevw, prevh, bbox); ! 276: } ! 277: } ! 278: track_bounds(bbox[0]-p->o_weight/2, bbox[1]-p->o_weight/2, ! 279: bbox[2]+p->o_weight/2, bbox[3]+p->o_weight/2); ! 280: p->o_x = 0.5 * (bbox[0] + bbox[2]); ! 281: p->o_y = 0.5 * (bbox[1] + bbox[3]); ! 282: p->o_wid = bbox[2] - bbox[0]; ! 283: p->o_ht = bbox[3] - bbox[1]; ! 284: return(p); ! 285: } ! 286: ! 287: arrowfill () /* a bit of a kludge for an obsolescent feature; arroprevw */ ! 288: { /* now is taken simply as odd (fill) or even (nofill) and */ ! 289: /* has no implication of "number of lines drawn" as in pic */ ! 290: ! 291: return (((int)getfval("arrowfill")) % 2) * HEADFILL; ! 292: } ! 293: ! 294: /* NOTE: DBK added bbox parameter to track_head 9/30/89. Only calls to ! 295: track_head are in linegen() above. The purpose is to get o_wid and o_ht ! 296: computed large enough so get_bounds won't lie about arrows. Note that ! 297: o_x and o_y may also be affected. */ ! 298: static ! 299: track_head (x0, y0, x1, y1, w, h, bbox) ! 300: double x0, y0, x1, y1, w, h; ! 301: float bbox[]; ! 302: { ! 303: double rot, hyp, phi; ! 304: ! 305: rot = atan2(w/2, h); ! 306: hyp = hypot(w/2, h); ! 307: phi = atan2(y1-y0, x1-x0) + M_PI - rot; ! 308: x0 = x1 + hyp * cos(phi); y0 = y1 + hyp * sin(phi); ! 309: extreme (x0, y0, Gbox); ! 310: extreme (x0, y0, bbox); ! 311: phi += 2 * rot; ! 312: x0 = x1 + hyp * cos(phi); y0 = y1 + hyp * sin(phi); ! 313: extreme (x0, y0, Gbox); ! 314: extreme (x0, y0, bbox); ! 315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.