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