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