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;
16 double defx, defy, xwith, ywith;
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];
23 Attr *ap, *chop_ap[4];
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++) {
38 savetext(ap->a_sub, ap->a_val.p);
51 ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
52 if (ap->a_sub == DEFAULT)
53 ddval = getfval("dashwid");
63 dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
68 dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
73 dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
78 dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
82 case HEIGHT: /* length of arrowhead */
85 case WIDTH: /* width of arrowhead */
93 dx[ndxy] = dy[ndxy] = some = 0;
95 ppos = attr[i].a_val.o;
96 dx[ndxy] = ppos->o_x - nx;
97 dy[ndxy] = ppos->o_y - ny;
105 dx[ndxy] = dy[ndxy] = some = 0;
108 dx[ndxy] = ppos->o_x;
109 dy[ndxy] = ppos->o_y;
112 case THEN: /* turn off any previous accumulation */
117 dx[ndxy] = dy[ndxy] = some = 0;
123 nx = curx = ppos->o_x;
124 ny = cury = ppos->o_y;
130 if (ap->a_sub != PLACENAME) {
132 chop1 = chop2 = ap->a_val.f;
136 chop_ap[chop++] = ap;
140 if (ap->a_sub == DEFAULT)
141 fillval = getfval("fillval");
143 fillval = ap->a_val.f;
147 if (with) { /* this doesn't work at all */
150 xwith = (dx[1] - dx[0]) / 2; ywith = (dy[1] - dy[0]) / 2; break;
152 for (i = 0; i < ndxy; i++) {
166 defx *= xtab[hvmode];
167 defy *= ytab[hvmode];
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);
187 theta = atan2(dy[ndxy-1], dx[ndxy-1]);
188 x1 = chop2 * cos(theta);
189 y1 = chop2 * sin(theta);
194 dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n",
195 x0, y0, x1, y1, curx, cury, nx, ny);
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");
205 head = HEAD2; /* default arrow head */
207 p->o_attr = head | invis | ddtype | battr;
208 p->o_fillval = fillval;
212 for (i = 0, j = 5; i < ndxy; i++, j += 2) {
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);
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]);
237 extreme(p->o_x, p->o_y);