Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/pic/linegen.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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