Blame


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