|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <math.h> ! 3: #include "pic.h" ! 4: #include "y.tab.h" ! 5: ! 6: obj *linegen(int type) ! 7: { ! 8: static double prevdx = HT; ! 9: static double prevdy = 0; ! 10: static double prevw = HT10; ! 11: static double prevh = HT5; ! 12: int i, j, some, head, ddtype, invis, chop, battr, with; ! 13: double ddval, chop1, chop2, x0, y0, x1, y1; ! 14: double fillval = 0; ! 15: double theta; ! 16: double defx, defy, xwith, ywith; ! 17: obj *p, *ppos; ! 18: static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ ! 19: static int ytab[] = { 0, 1, 0, -1 }; ! 20: double dx[500], dy[500]; ! 21: int ndxy; ! 22: double nx, ny; ! 23: Attr *ap, *chop_ap[4]; ! 24: ! 25: nx = curx; ! 26: ny = cury; ! 27: defx = getfval("linewid"); ! 28: defy = getfval("lineht"); ! 29: prevh = getfval("arrowht"); ! 30: prevw = getfval("arrowwid"); ! 31: dx[0] = dy[0] = ndxy = some = head = invis = battr = with = 0; ! 32: chop = chop1 = chop2 = 0; ! 33: ddtype = ddval = xwith = ywith = 0; ! 34: for (i = 0; i < nattr; i++) { ! 35: ap = &attr[i]; ! 36: switch (ap->a_type) { ! 37: case TEXTATTR: ! 38: savetext(ap->a_sub, ap->a_val.p); ! 39: break; ! 40: case HEAD: ! 41: head += ap->a_val.i; ! 42: break; ! 43: case INVIS: ! 44: invis = INVIS; ! 45: break; ! 46: case NOEDGE: ! 47: battr |= NOEDGEBIT; ! 48: break; ! 49: case DOT: ! 50: case DASH: ! 51: ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT; ! 52: if (ap->a_sub == DEFAULT) ! 53: ddval = getfval("dashwid"); ! 54: else ! 55: ddval = ap->a_val.f; ! 56: break; ! 57: case SAME: ! 58: dx[ndxy] = prevdx; ! 59: dy[ndxy] = prevdy; ! 60: some++; ! 61: break; ! 62: case LEFT: ! 63: dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; ! 64: some++; ! 65: hvmode = L_DIR; ! 66: break; ! 67: case RIGHT: ! 68: dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; ! 69: some++; ! 70: hvmode = R_DIR; ! 71: break; ! 72: case UP: ! 73: dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; ! 74: some++; ! 75: hvmode = U_DIR; ! 76: break; ! 77: case DOWN: ! 78: dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; ! 79: some++; ! 80: hvmode = D_DIR; ! 81: break; ! 82: case HEIGHT: /* length of arrowhead */ ! 83: prevh = ap->a_val.f; ! 84: break; ! 85: case WIDTH: /* width of arrowhead */ ! 86: prevw = ap->a_val.f; ! 87: break; ! 88: case TO: ! 89: if (some) { ! 90: nx += dx[ndxy]; ! 91: ny += dy[ndxy]; ! 92: ndxy++; ! 93: dx[ndxy] = dy[ndxy] = some = 0; ! 94: } ! 95: ppos = attr[i].a_val.o; ! 96: dx[ndxy] = ppos->o_x - nx; ! 97: dy[ndxy] = ppos->o_y - ny; ! 98: some++; ! 99: break; ! 100: case BY: ! 101: if (some) { ! 102: nx += dx[ndxy]; ! 103: ny += dy[ndxy]; ! 104: ndxy++; ! 105: dx[ndxy] = dy[ndxy] = some = 0; ! 106: } ! 107: ppos = ap->a_val.o; ! 108: dx[ndxy] = ppos->o_x; ! 109: dy[ndxy] = ppos->o_y; ! 110: some++; ! 111: break; ! 112: case THEN: /* turn off any previous accumulation */ ! 113: if (some) { ! 114: nx += dx[ndxy]; ! 115: ny += dy[ndxy]; ! 116: ndxy++; ! 117: dx[ndxy] = dy[ndxy] = some = 0; ! 118: } ! 119: break; ! 120: case FROM: ! 121: case AT: ! 122: ppos = ap->a_val.o; ! 123: nx = curx = ppos->o_x; ! 124: ny = cury = ppos->o_y; ! 125: break; ! 126: case WITH: ! 127: with = ap->a_val.i; ! 128: break; ! 129: case CHOP: ! 130: if (ap->a_sub != PLACENAME) { ! 131: if( chop == 0) ! 132: chop1 = chop2 = ap->a_val.f; ! 133: else ! 134: chop2 = ap->a_val.f; ! 135: } ! 136: chop_ap[chop++] = ap; ! 137: break; ! 138: case FILL: ! 139: battr |= FILLBIT; ! 140: if (ap->a_sub == DEFAULT) ! 141: fillval = getfval("fillval"); ! 142: else ! 143: fillval = ap->a_val.f; ! 144: break; ! 145: } ! 146: } ! 147: if (with) { /* this doesn't work at all */ ! 148: switch (with) { ! 149: case CENTER: ! 150: xwith = (dx[1] - dx[0]) / 2; ywith = (dy[1] - dy[0]) / 2; break; ! 151: } ! 152: for (i = 0; i < ndxy; i++) { ! 153: dx[i] -= xwith; ! 154: dy[i] -= ywith; ! 155: } ! 156: curx += xwith; ! 157: cury += ywith; ! 158: } ! 159: if (some) { ! 160: nx += dx[ndxy]; ! 161: ny += dy[ndxy]; ! 162: ndxy++; ! 163: defx = dx[ndxy-1]; ! 164: defy = dy[ndxy-1]; ! 165: } else { ! 166: defx *= xtab[hvmode]; ! 167: defy *= ytab[hvmode]; ! 168: dx[ndxy] = defx; ! 169: dy[ndxy] = defy; ! 170: ndxy++; ! 171: nx += defx; ! 172: ny += defy; ! 173: } ! 174: prevdx = defx; ! 175: prevdy = defy; ! 176: if (chop) { ! 177: if (chop == 1 && chop1 == 0) /* just said "chop", so use default */ ! 178: chop1 = chop2 = getfval("circlerad"); ! 179: theta = atan2(dy[0], dx[0]); ! 180: x0 = chop1 * cos(theta); ! 181: y0 = chop1 * sin(theta); ! 182: curx += x0; ! 183: cury += y0; ! 184: dx[0] -= x0; ! 185: dy[0] -= y0; ! 186: ! 187: theta = atan2(dy[ndxy-1], dx[ndxy-1]); ! 188: x1 = chop2 * cos(theta); ! 189: y1 = chop2 * sin(theta); ! 190: nx -= x1; ! 191: ny -= y1; ! 192: dx[ndxy-1] -= x1; ! 193: dy[ndxy-1] -= y1; ! 194: dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n", ! 195: x0, y0, x1, y1, curx, cury, nx, ny); ! 196: } ! 197: p = makenode(type, 5 + 2 * ndxy); ! 198: curx = p->o_val[0] = nx; ! 199: cury = p->o_val[1] = ny; ! 200: if (head || type == ARROW) { ! 201: p->o_nhead = getfval("arrowhead"); ! 202: p->o_val[2] = prevw; ! 203: p->o_val[3] = prevh; ! 204: if (head == 0) ! 205: head = HEAD2; /* default arrow head */ ! 206: } ! 207: p->o_attr = head | invis | ddtype | battr; ! 208: p->o_fillval = fillval; ! 209: p->o_val[4] = ndxy; ! 210: nx = p->o_x; ! 211: ny = p->o_y; ! 212: for (i = 0, j = 5; i < ndxy; i++, j += 2) { ! 213: p->o_val[j] = dx[i]; ! 214: p->o_val[j+1] = dy[i]; ! 215: if (type == LINE || type == ARROW) ! 216: extreme(nx += dx[i], ny += dy[i]); ! 217: else if (type == SPLINE && i < ndxy-1) { ! 218: /* to compute approx extreme of spline at p, ! 219: /* compute midway between p-1 and p+1, ! 220: /* then go 3/4 from there to p */ ! 221: double ex, ey, xi, yi, xi1, yi1; ! 222: xi = nx + dx[i]; yi = ny + dy[i]; /* p */ ! 223: xi1 = xi + dx[i+1]; yi1 = yi + dy[i+1]; /* p+1 */ ! 224: ex = (nx+xi1)/2; ey = (ny+yi1)/2; /* midway */ ! 225: ex += 0.75*(xi-ex); ey += 0.75*(yi-ey); ! 226: extreme(ex, ey); ! 227: nx = xi; ny = yi; ! 228: } ! 229: ! 230: } ! 231: p->o_ddval = ddval; ! 232: if (dbg) { ! 233: printf("S or L from %g %g to %g %g with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy); ! 234: for (i = 0, j = 5; i < ndxy; i++, j += 2) ! 235: printf("%g %g\n", p->o_val[j], p->o_val[j+1]); ! 236: } ! 237: extreme(p->o_x, p->o_y); ! 238: extreme(curx, cury); ! 239: return(p); ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.