File: plfig.c

package info (click to toggle)
pic2fig 1.4-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, sarge
  • size: 296 kB
  • ctags: 719
  • sloc: ansic: 3,544; lex: 224; yacc: 199; makefile: 108
file content (402 lines) | stat: -rw-r--r-- 8,107 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#include <stdio.h>
#include <ctype.h>
#include <math.h>
extern int dbg;
char   *rindex ();

#define	abs(n)	(n >= 0 ? n : -(n))
#define	max(x,y)	((x)>(y) ? (x) : (y))
#define	PI	3.141592654
#define	PI2	(PI / 2)

#define	MAXDELT	((float) 10.5)

extern	int	res;		/* Typesetter resolution */
static	float	quarter_baseline = 3.0;	/* In points */

/* scaling stuff, specific to typesetter */
/* defined by s command as X0,CY0 to X1,CY1 */
/* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
/* default output is 6x6 inches */


float	xscale;
float	yscale;

int	hpos	= 0;	/* current horizontal position in output coordinate sys
tem */
int	vpos	= 0;	/* current vertical position; 0 is top of page */

int	htrue	= 0;	/* where we really are */
int	vtrue	= 0;

float	X0, CY0;	/* left bottom of input */
float	X1, CY1;	/* right top of input */

int	hmax;		/* right end of output */
int	vmax;		/* top of output (down is positive) */

extern	float	deltx;
extern	float	delty;
extern	float	xmin, ymin, xmax, ymax, sxmin, symin, sxmax, symax;
extern	int	crop;

extern	double	sqrt(), atan2();

openpl()	/* initialize device */
{
	float maxdelt;

	fig_begin_drawing();

	hpos = vpos = 0;
	hmax = vmax = 6 * res;	/* default = 6 x 6 */
	maxdelt = max(deltx, delty);
	if (maxdelt > MAXDELT) {
		fprintf(stderr, "pic2fig: %g X %g picture shrunk to", deltx, delty
);
		deltx *= MAXDELT/maxdelt;
		delty *= MAXDELT/maxdelt;
		fprintf(stderr, " %g X %g\n", deltx, delty);
	}
	if (deltx > 0 && delty > 0) {	/* have to change default size */
		hmax = res * deltx;
		vmax = res * delty;
	}
	if (crop) {
		if (xmax == xmin)
		    space(xmin, ymin, xmin + ymax-ymin, ymax);
		else
		    space(xmin, ymin, xmax, ymin + xmax-xmin);	/* assumes 1:1 
aspect ratio */
	}
	else
	    space(sxmin, symin, sxmax, symax);

	if (xconv(xmax) >= 32768 || yconv(ymax) >= 32768) {	/* internal tro
ff limit: 13 bits for motion */
		fprintf(stderr, "picture too high or wide\n");
		exit(1);
	}
}

closepl()	/* clean up after finished */
{
	movehv(0, 0);	/* get back to where we started */
	fig_end_drawing();
}

move(x, y)	/* go to position x, y in external coords */
	float x, y;
{
	hgoto(xconv(x));
	vgoto(yconv(y));
}

movehv(h, v)	/* go to internal position h, v */
	int h, v;
{
	hgoto(h);
	vgoto(v);
}

hgoto(n)
{
	hpos = n;
}

vgoto(n)
{
	vpos = n;
}

hvflush()	/* get to proper point for output */
{
	fig_hvflush((float) hpos, (float) vpos);
}

flyback()	/* return to upper left corner (entry point) */
{
/*	printf(".sp -1\n"); */
	htrue = vtrue = 0;
}

troff(s)	/* handle ".ps n" to set the pen size to "n" pixels */
	char *s;
{
    if (strncmp (s, ".ps", 3) == 0) {
	int     size;

	if (sscanf (s + 3, " %d ", &size) == 1)
	    pensize (size);
	else
	    fprintf (stderr, "Malformed .ps command: %s\n", s);
	return;
    }

    if (strncmp(s, ".baseline", 9) == 0) {
	float baseline;

	if (sscanf (s +9 , " %f ", &baseline) != 1)
	    fprintf (stderr, "Malformed .baseline command: %s\n", s);
	else
	    quarter_baseline = baseline / 4.0;
	return;
    }

    if (strncmp (s, ".tx", 3) == 0) {
	register int     index;
	int	pcount,
		bitpattern[32];
	register char   *t;

	t = s + 3;
	while (isspace (*t))
	    t++;
	if (sscanf (t, "%d", &pcount) != 1 || pcount <= 0) {
	    fprintf (stderr, "Malformed .tx command: %s\n", s);
	    return;
	}
	if (pcount > sizeof bitpattern/sizeof bitpattern[0]) {
	    fprintf (stderr, "Command too large: %s\n", s);
	    return;
	}
	for (index = 0; index < pcount; index++) {
	    while (*t && !isspace (*t))
		t++;
	    while (isspace(*t))
		t++;
	    if (sscanf (t, "%x", &bitpattern[index]) != 1) {
		fprintf (stderr, "Malformed .tx command: %s\n", s);
		return;
	    }
	}

	texture (pcount, bitpattern);
	return;
    }

    fprintf(stderr, "Unparseable text in PIC file \"%s\"\n", s);
}

label(s, t, nh)	/* text s of type t nh half-lines up */
/* t is either 'L' (left), 'C' (centered), 'R' (right), 'A', or 'B',
   or otherwise, treat as L */
	char *s;
	int t, nh;
{
	float aty, atx;

	if (t == 'A')
		nh++;
	else if (t == 'B')
		nh--;
	nh = nh*2 - 1;	/* One half line to make text come out at right place *
/
/* quarter_lines * res in points * quarter_baseline */
	aty = vpos - nh * (res/72.27) * quarter_baseline;
	atx = hpos;

	switch (t) {
	    case 'L':
	    default:
		fig_text_at(s, atx, aty, 0);
		break;
	    case 'C':
	    case 'A':
	    case 'B':
		fig_text_at(s, atx, aty, 1);
		break;
	    case 'R':
		fig_text_at(s, atx, aty, 2);
		break;
	}
}

line(x0, y0, x1, y1)	/* draw line from x0,y0 to x1,y1 */
	float x0, y0, x1, y1;
{
	move(x0, y0);
	cont(x1, y1);
}

dashed_line(x0, y0, x1, y1, inchesperdash, dotted)
float x0, y0, x1, y1, inchesperdash;
int dotted;			/* boolean */
{
    int h1, v1;
    move(x0, y0);
    h1 = xconv(x1);
    v1 = yconv(y1);
    hvflush();			/* Get to (hpos,vpos) */
    flyback();
    fig_drawto((float) h1, (float) v1);
    send_dashed_path(inchesperdash, dotted);
    clearpath();
    hpos = h1;
    vpos = v1;
}


arrow(x0, y0, x1, y1, w, h)	/* draw arrow (without line), head wid w & len 
h */
	float x0, y0, x1, y1, w, h;
{
	double alpha, rot, hyp;
	float dx, dy;

	rot = atan2( w / 2, h );
	hyp = sqrt(w/2 * w/2 + h * h);
	alpha = atan2(y1-y0, x1-x0);
	if (dbg)
		printf("rot=%f, hyp=%f, alpha=%f\n", rot, hyp, alpha);
	dx = hyp * cos(alpha + PI + rot);
	dy = hyp * sin(alpha + PI + rot);
	if (dbg) printf("dx,dy = %g,%g\n", dx, dy);
	line(x1+dx, y1+dy, x1, y1);
	dx = hyp * cos(alpha + PI - rot);
	dy = hyp * sin(alpha + PI - rot);
	if (dbg) printf("dx,dy = %g,%g\n", dx, dy);
	line(x1+dx, y1+dy, x1, y1);
}

box(x0, y0, x1, y1)
	float x0, y0, x1, y1;
{
	move(x0, y0);
	cont(x0, y1);
	cont(x1, y1);
	cont(x1, y0);
	cont(x0, y0);
}

cont(x, y)	/* continue line from here to x,y */
	float x, y;
{
	int h1, v1;

	h1 = xconv(x);
	v1 = yconv(y);
	hvflush();		/* causes drawto(hpos,vpos) */
	flyback();	/* expensive */
	fig_drawto((float) h1, (float) v1);
	hpos = h1;
	vpos = v1;
}

circle(x, y, r)
	float x, y, r;
{
	fig_flush();
	fig_circle((float) xconv(x), (float) yconv(y), (float) xsc(r));
	flyback();
}

tpspline(x, y, n, p)
	float x, y, *p;
	float n;
{
	int i, xx[50], yy[50], num;

	move(x, y);
	hvflush();		/* Invokes drawto(x,y) */
	num = 2;
	for (i = 0; i < 2 * n; i += 2) {
		xx[num] = xsc(p[i]);
		yy[num] = ysc(p[i+1]);
		num++;
	}
	xx[1] = hpos;
	yy[1] = vpos;
	for (i = 1; i < num; i++) {
		xx[i+1] += xx[i];
		yy[i+1] += yy[i];
	}
	draw_fig_spline(xx, yy, num);
	flyback();
}

ellipse(x, y, r1, r2)
	float x, y, r1, r2;
{
	fig_flush();
	fig_ellipse((float) xconv(x), (float) yconv(y), (float) xsc(r1),
		(float) abs(ysc(r2)));
	flyback();
}

/* draw CCW arc with center x,y starting at x0,y0 going to x1,y1, with rad=r *
/
/* start and stop are calculated in reverse because the positive y direction *
/
/* on the Imagen is downwards, which reverses "counterclockwise" */
arc(x, y, x0, y0, x1, y1, r)
	float x, y, x0, y0, x1, y1, r;
{
	float start, stop;

	fig_flush();
	r = xsc(r);
	start = atan2((float) ysc(y1-y), (float) xsc(x1-x));
	while (start < 0.0) start += 2*PI;
	while (start >= 2*PI) start -= 2*PI;
	stop = atan2((float) ysc(y0-y), (float) xsc(x0-x));
	while (stop > 2*PI) stop -= 2*PI;
	while (stop < start) stop += 2*PI;
	fig_arc((float) xconv(x), (float) yconv(y), r, r, start, stop);
	flyback();
}


space(x0, y0, x1, y1)	/* set limits of page */
	float x0, y0, x1, y1;
{
	if (x0 == x1)
		x1 = x0 + 1;
	if (y0 == y1)
		y1 = y0 - 1;	/* kludge */
	X0 = x0;
	CY0 = y0;
	X1 = x1;
	CY1 = y1;
	xscale = hmax / (X1-X0);
	yscale = vmax / (CY0-CY1);
	fig_window(x0, y0, x1, y1, x0/res, y1/res, x1/res, y0/res);
}

xconv(x)	/* convert x from external to internal form */
	float x;
{
	int v;

	v = (x-X0) * xscale + 0.5;
	return v;
}

xsc(x)	/* convert x from external to internal form, scaling only */
	float x;
{
	int v;

	v = (x) * xscale + 0.5;
	return v;
}

yconv(y)	/* convert y from external to internal form */
	float y;
{
	int v;

	y += CY1 - ymax;
	v = (y-CY1) * yscale + 0.5;
	return v;
}

ysc(y)	/* convert y from external to internal form, scaling only */
	float y;
{
	int v;

	v = (y) * yscale + 0.5;
	return v;
}