v08i022: xfig -- X Drawing Tool, Part13/21

Brian V. Smith envbvs at epb2.lbl.gov
Wed Jul 4 04:01:34 AEST 1990


Submitted-by: envbvs at epb2.lbl.gov (Brian V. Smith)
Posting-number: Volume 8, Issue 22
Archive-name: xfig2.8/part13

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 13 (of 21)."
# Contents:  f2hp.c movept.c read.c
# Wrapped by envbvs at epb2.lbl.gov on Thu Jun 28 08:52:45 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'f2hp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'f2hp.c'\"
else
echo shar: Extracting \"'f2hp.c'\" \(18027 characters\)
sed "s/^X//" >'f2hp.c' <<'END_OF_FILE'
X/* 
X *	f2hp : Fig-to-HPGL translator
X *
X *      Original Copyright (c) 1986 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X *
X *	Created from f2ps by B.V. Smith 5/90
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "object.h"
X#include "resources.h"
X
X#define		PAGE_WIDTH		(10.250-0.250)	/* 10"  X plot area (7475A) */
X#define		PAGE_HEIGHT		(7.796-0.596)	/* 7.2" Y plot area */
X#define		POINT_PER_INCH		72		/* text ppi */
X#define		MAX_COLORS		6		/* number of pens */
X#define		DEFAULT_COLOR		0		/* black */
X#define		UP			0
X#define		DOWN			1
X
X#define TRANSF_X(x)	(x)*scalex
X#define TRANSF_Y(y)	(coord_system==2? (ury-(y))*scaley: (y)*scaley)
X
Xchar		Usage[] = "Usage: %s [-P][-L][-debug][-e scale] [input [output]]\n";
Xchar		*prog;
Xint		cur_thickness;
Xint		cur_color= -9;
Xint		cur_areafill=0;
Xint		debug = 0;
Xint		landscape = 1;
Xint		pen=UP;
Xextern int	num_object;
Xchar		*from = NULL, *to = NULL;
XFILE		*tfp = NULL;
Xchar		Err_incomp[] = "Incomplete %s object at line %d.";
Xchar		Err_mem[] = "Running out of memory.";
Xdouble		scale = 1.0;
Xdouble		scalex, scaley;
Xint		coord_system;
Xint		ppi;
Xint		llx, lly, urx, ury;
X
Xint		fill_type[NUMFILLPATS] = {4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
X					  4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 1};
Xint		fill_spacing[NUMFILLPATS] = {8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6,
X					     4, 4, 4, 4, 4, 4, 2, 2, 0};
Xint		fill_angle[NUMFILLPATS] = {0, 0, 45, 45, 90, 90, 0, 0, 45, 45, 
X					   90, 90, 0, 0, 45, 45, 90, 90, 0, 0, 0};
Xint		line_thickness; /* not needed for f2ps, arrow.c needs it for fig */
X
Xget_args(argc, argv)
Xint	 argc;
Xchar	*argv[];
X{
X	char	*a;
X	int	first = 1;
X
X	prog = *argv;
X	while (--argc) {
X	    a = *++argv;
X	    if (*a == '-') {
X		if (*++a == 'l' || *a == 'L') {	/* Landscape */
X		    landscape = 1;
X		    }
X		else if (*a == 'p' || *a == 'P') {	/* Portrait */
X		    landscape = 0;
X		    }
X		else if (*a == 'd')	/* debug printing */
X			debug = 1;
X		else if (*a == 'e') {	/* Enlarging factor followed */
X		    if (--argc)
X			scale = atof(*++argv);
X		    else
X			goto error_exit;
X		    }
X		else
X		    goto error_exit;
X		}
X	    else if (first) {
X		from = a;	/*  from file  */
X		first = 0;
X		}
X	    else if (first == 0) {
X		to = a;		/*  to file  */
X		first = -1;
X		}
X	    else
X		goto error_exit;
X	    }
X	return;
X
X    error_exit:
X	fprintf(stderr, Usage, prog);
X	exit(1);
X	}
X
Xmain(argc, argv)
Xint	 argc;
Xchar	*argv[];
X{
X	F_compound	objects;
X	int		status;
X
X	get_args(argc, argv);
X
X	if (to == NULL)
X	    tfp = stdout;
X	else if ((tfp = fopen(to, "w")) == NULL) {
X	    fprintf(stderr, "%s: Couldn't open %s", prog, to);
X	    fprintf(stderr, Usage, prog);
X	    exit(1);
X	    }
X
X	if (from)
X	    status = read_fig(from, &objects);
X	else 	/* read from stdin */
X	    status = readfp_fig(stdin, &objects);
X
X	if (status != 0) {
X	    if (from) read_fail_message(from, status);
X	    fprintf(stderr,"\n");
X	    exit(1);
X	    }
X	genhp_objects(&objects);
X	if (tfp != stdout) 
X		(void)fclose(tfp);
X	exit(0);
X	}
X
Xprolog(objects)
XF_compound	*objects;
X	{
X	plotter_on();
X	fprintf(tfp, "\033.I80;;17:");	/* set x-on/x-off */
X	fprintf(tfp, "\033.N;19:");
X	/* **** rotate for portrait mode **** */
X	if (!landscape) 	/* must reset clip window and plotter limits with rotaton */
X	    fprintf(tfp, "RO 90;IW;IP;\n");
X	fprintf(tfp, "SC %d %d %d %d;\n", llx, urx, lly, ury);
X	}
X
Xepilog()
X	{
X	penup();
X	fprintf(tfp,"PA %d %d; ",urx,ury);
X	fprintf(tfp, "SP;\n");
X	plotter_off();
X	}
X
Xplotter_on()
X	{
X	fprintf(tfp,"\033.(\n");
X	}
X
Xplotter_off()
X	{
X	fprintf(tfp,"\033.)\n");
X	}
X
Xgenhp_objects(objects)
XF_compound	*objects;
X{
X	F_arc		*a;
X	F_compound	*c;
X	F_ellipse	*e;
X	F_line		*l;
X	F_spline	*s;
X	F_text		*t;
X	int		itmp;
X	int		color;
X
X	/* Compute bounding box of objects */
X	compound_bound(objects, &llx, &lly, &urx, &ury);
X	if (llx > urx) {
X	    fprintf(stderr, "%s: No object",prog);
X	    return;
X	    }
X
X	ppi = objects->nwcorner.x;		/* ppi */
X	coord_system = objects->nwcorner.y;	/* 1=y normal, 2=y flipped */
X
X	scalex = scaley = scale;		/* user enlarging factor */
X
X	/*************************************************************************/
X	/* we will just set llx lly etc to plotter area 			 */
X	/*************************************************************************/
X
X	llx = lly = 0;			/* lower left */
X	urx = PAGE_WIDTH*ppi;
X	ury = PAGE_HEIGHT*ppi;
X
X	if (!landscape)			/* swap x,y */
X		{
X		itmp = llx; llx = lly; lly = itmp;
X		itmp = urx; urx = ury; ury = itmp;
X		}
X
X	prolog(objects);
X
X	/* plot color 0 first then 1, ... */
X	for (color=-1; color < MAX_COLORS; color++)
X		{
X		for (a = objects->arcs; a != NULL; a = a->next) 
X			genhp_arc(a,color);
X		for (c = objects->compounds; c != NULL; c = c->next) 
X			genhp_compound(c,color);
X		for (e = objects->ellipses; e != NULL; e = e->next) 
X			genhp_ellipse(e,color);
X		for (l = objects->lines; l != NULL; l = l->next) 
X			genhp_line(l,color);
X		for (s = objects->splines; s != NULL; s = s->next) 
X			genhp_spline(s,color);
X		for (t = objects->texts; t != NULL; t = t->next) 
X			genhp_text(t,color);
X		}
X	epilog();
X	}
X
Xset_style(s, v)
Xint	s;
Xdouble	v;
X{
X	if (s == DASH_LINE) {
X	    if (v > 0.0) fprintf(tfp, "LT 2;\n");
X	    }
X	else if (s == DOTTED_LINE) {
X	    if (v > 0.0) fprintf(tfp, "LT 1;\n");
X	    }
X	}
X
Xreset_style(s, v)
Xint	s;
Xdouble	v;
X{
X	if (s == DASH_LINE) {
X	    if (v > 0.0) fprintf(tfp, "LT;\n");
X	    }
X	else if (s == DOTTED_LINE) {
X	    if (v > 0.0) fprintf(tfp, "LT;\n");
X	    }
X	}
X
Xset_areafill(a)
Xint a;
X	{
X	if (cur_areafill == a)
X		return;
X	cur_areafill = a;
X	fprintf(tfp, "FT %d %d %d;\n",
X			fill_type[a-1],fill_spacing[a-1],fill_angle[a-1]);
X	}
X
Xset_linewidth(w)
Xint	w;
X	{
X	cur_thickness = w;
X	}
X
Xset_color(c)
Xint	c;
X	{
X	if (c < 0)
X		c = DEFAULT_COLOR;
X	if (cur_color == c)
X		return;
X	cur_color = c;
X	fprintf(tfp,"SP %d;\n",c+1);
X	}
X
Xmoveto(x,y)
Xint x,y;
X	{
X	penup();
X	fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
X	}
X
Xdrawto(x,y)
Xint x,y;
X	{
X	pendown();
X	fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
X	}
X
Xf_moveto(x,y)
Xdouble x,y;
X	{
X	penup();
X	fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
X	}
X
Xf_drawto(x,y)
Xdouble x,y;
X	{
X	pendown();
X	fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
X	}
X
Xpenup()
X	{
X	if (pen != UP)
X		fprintf(tfp,"PU; ");
X	pen = UP;
X	}
X
Xpendown()
X	{
X	if (pen != DOWN)
X		fprintf(tfp,"PD; ");
X	pen = DOWN;
X	}
X
Xgenhp_compound(com,color)
XF_compound	*com;
Xint color;
X{
X	F_arc		*a;
X	F_compound	*c;
X	F_ellipse	*e;
X	F_line		*l;
X	F_spline	*s;
X	F_text		*t;
X
X	for (a = com->arcs; a != NULL; a = a->next) 
X		genhp_arc(a,color);
X	for (c = com->compounds; c != NULL; c = c->next) 
X		genhp_compound(c,color);
X	for (e = com->ellipses; e != NULL; e = e->next) 
X		genhp_ellipse(e,color);
X	for (l = com->lines; l != NULL; l = l->next) 
X		genhp_line(l,color);
X	for (s = com->splines; s != NULL; s = s->next) 
X		genhp_spline(s,color);
X	for (t = com->texts; t != NULL; t = t->next) 
X		genhp_text(t,color);
X	}
X
X#define FILL_RECT(x,y)	fprintf(tfp,"RA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
X#define EDGE_RECT(x,y)	fprintf(tfp,"EA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
X#define FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2f %d %d; ", \
X				TRANSF_X(r),(angle),(sweep))
X#define ARC_TO(x,y,angle) fprintf(tfp,"AA %.2f %.2f %d; ", \
X				TRANSF_X((x)),TRANSF_Y((y)),(angle))
X#define F_FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2lf %d %d; ", \
X				TRANSF_X(r),(angle),(sweep))
X#define F_ARC_TO(x,y,angle) fprintf(tfp,"AA %.2lf %.2lf %d; ", \
X				TRANSF_X((x)),TRANSF_Y((y)),(angle))
X#define CIRCLE(r)	fprintf(tfp,"CI %.2f;",TRANSF_X(r))
X
Xgenhp_line(l,color)
XF_line	*l;
Xint color;
X	{
X	F_point	*p, *q;
X	int	radius,tmp;
X	int	xmin,xmax,ymin,ymax;
X
X	if (color != l->color)
X		return;
X
X	set_linewidth(l->thickness);
X	set_color(l->color);
X	radius = l->radius;		/* radius of rounded-corner boxes */
X	p = l->points;
X	q = p->next;
X	if (q == NULL) { /* A single point line */
X	    if (l->thickness > 0)
X		{
X		moveto(p->x,p->y);
X		pendown();
X		penup();
X		}
X	    return;
X	    }
X	if (l->back_arrow)
X	    draw_arrow_head((double)q->x, (double)q->y, (double)p->x,
X			(double)p->y, l->back_arrow->ht, l->back_arrow->wid);
X	set_style(l->style, l->style_val);
X	if (l->area_fill)
X		set_areafill(l->area_fill);
X	xmin = xmax = p->x;
X	ymin = ymax = p->y;
X
X	while ((l->type == T_BOX || l->type == T_ARC_BOX) &&
X		  p->next != NULL)	/* find lower left and upper right corners */
X		{
X		p=p->next;
X		if (xmin > p->x)
X			xmin = p->x;
X		else if (xmax < p->x)
X			xmax = p->x;
X		if (ymin > p->y)
X			ymin = p->y;
X		else if (ymax < p->y)
X			ymax = p->y;
X		}
X	if (l->type == T_ARC_BOX)	/* rounded-corner box */
X		{
X		if (l->area_fill)
X			{
X			moveto(xmin+radius,ymin);
X			FILL_RECT(xmax-radius,ymin+radius);
X			moveto(xmin,ymin+radius);
X			FILL_RECT(xmax,ymax-radius);
X			moveto(xmin+radius,ymax-radius);
X			FILL_RECT(xmax-radius,ymax);
X
X			/* now do the corner wedges */
X			moveto(xmin+radius,ymin+radius);
X			FILL_WEDGE(radius,90,90);
X			moveto(xmin+radius,ymax-radius);
X			FILL_WEDGE(radius,180,90);
X			moveto(xmax-radius,ymax-radius);
X			FILL_WEDGE(radius,270,90);
X			moveto(xmax-radius,ymin+radius);
X			FILL_WEDGE(radius,0,90);
X			}
X		/* draw the outline of the box */
X		moveto(xmin+radius,ymin);
X		pendown();
X		ARC_TO(xmin+radius,ymin+radius,90);
X		drawto(xmin,ymax-radius);
X		ARC_TO(xmin+radius,ymax-radius,90);
X		drawto(xmax-radius,ymax);
X		ARC_TO(xmax-radius,ymax-radius,90);
X		drawto(xmax,ymin+radius);
X		ARC_TO(xmax-radius,ymin+radius,90);
X		drawto(xmin+radius,ymin);
X		} /* T_ARC_BOX */
X	else if (l->type == T_BOX)
X		{
X		moveto(xmin,ymin);
X		if (l->area_fill)
X			FILL_RECT(xmax,ymax);
X		EDGE_RECT(xmax,ymax);
X		}
X	else /* POLYGON or POLYLINE */
X		{
X		moveto(p->x, p->y);
X		while (q->next != NULL)
X			{
X			p = q;
X			q = q->next;
X			drawto(p->x, p->y);
X			}
X		drawto(q->x, q->y);
X		}
X	penup();
X
X	reset_style(l->style, l->style_val);
X	if (l->for_arrow && l->thickness > 0)
X	    draw_arrow_head((double)p->x, (double)p->y, (double)q->x,
X			(double)q->y, l->for_arrow->ht, l->for_arrow->wid);
X	}
X
Xgenhp_spline(s,color)
XF_spline	*s;
Xint color;
X{
X	if (color != s->color)
X		return;
X
X	set_color(s->color);
X#ifndef notdef
X	fprintf(stderr,"No spline yet\n");
X#else
X	if (int_spline(s))
X	    genhp_itp_spline(s);
X	else
X	    genhp_ctl_spline(s);
X#endif
X	}
X
Xgenhp_itp_spline(s)
XF_spline	*s;
X{
X	F_point		*p, *q;
X	F_control	*a, *b;
X
X	set_linewidth(s->thickness);
X	a = s->controls;
X	b = a->next;
X	p = s->points;
X	if (s->back_arrow && s->thickness > 0)
X	    draw_arrow_head(b->lx, b->ly, (double)p->x,
X			(double)p->y, s->back_arrow->ht, s->back_arrow->wid);
X
X	set_style(s->style, s->style_val);
X	fprintf(tfp, "%% Interpolated spline\n");
X	fprintf(tfp, "newpath %d %d moveto\n", p->x, p->y);
X	for (q = p->next; q != NULL; p = q, q = q->next) {
X	    b = a->next;
X	    fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n",
X			a->rx, a->ry, b->lx, b->ly, q->x, q->y);
X	    a = b;
X	    }
X	if (closed_spline(s)) 
X		{
X		fprintf(tfp, " closepath ");
X		if (s->area_fill)
X			{
X			set_areafill(s->area_fill);
X			fprintf(tfp, " gsave fill grestore ");
X			set_areafill(NUMFILLPATS);	/* back to black for line */
X			}
X		}
X	if (s->thickness > 0)
X	    fprintf(tfp, " stroke\n");
X	reset_style(s->style, s->style_val);
X
X	if (s->for_arrow && s->thickness > 0)
X	    draw_arrow_head(a->lx, a->ly, (double)p->x,
X			(double)p->y, s->for_arrow->ht, s->for_arrow->wid);
X	}
X
Xgenhp_ctl_spline(s)
XF_spline	*s;
X{
X	double		a, b, c, d, x1, y1, x2, y2, x3, y3;
X	F_point		*p, *q;
X
X	p = s->points;
X	x1 = p->x; y1 = p->y;
X	p = p->next;
X	c = p->x; d = p->y;
X	set_linewidth(s->thickness);
X	x3 = a = (x1 + c) / 2;
X	y3 = b = (y1 + d) / 2;
X	if (s->back_arrow && s->thickness > 0) {
X	    draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid);
X	    }
X	set_style(s->style, s->style_val);
X	if (! closed_spline(s)) {
X	    fprintf(tfp, "%% Open spline\n");
X	    fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto\n",
X			x1, y1, x3, y3);
X	    }
X	else {
X	    fprintf(tfp, "%% Closed spline\n");
X	    fprintf(tfp, "newpath %.3f %.3f moveto\n", a, b);
X	    }
X	for (q = p->next; q != NULL; q = q->next) {
X	    x1 = x3; y1 = y3;
X	    x2 = c;  y2 = d;
X	    c = q->x; d = q->y;
X	    x3 = (x2 + c) / 2;
X	    y3 = (y2 + d) / 2;
X	    fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n",
X			x1, y1, x2, y2, x3, y3);
X	    }
X	/*
X	* At this point, (x2,y2) and (c,d) are the position of the 
X	* next-to-last and last point respectively, in the point list
X	*/
X	if (closed_spline(s)) {
X	    fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ",
X			x3, y3, c, d, a, b);
X	    if (s->area_fill)
X		{
X		set_areafill(s->area_fill);
X		fprintf(tfp, " gsave fill grestore\n");
X		set_areafill(NUMFILLPATS);	/* back to black for line */
X		}
X	    if (s->thickness > 0)
X		fprintf(tfp, " stroke\n");
X	    }
X	else {
X	    if (s->thickness > 0)
X		fprintf(tfp, "\t%.3f %.3f lineto stroke\n", c, d);
X	    else
X		fprintf(tfp, "\t%.3f %.3f lineto\n", c, d);
X	    }
X	reset_style(s->style, s->style_val);
X	if (s->for_arrow && s->thickness > 0) 
X	    {
X	    draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
X				s->for_arrow->wid);
X	    }
X	}
X
Xgenhp_ellipse(e,color)
XF_ellipse	*e;
Xint color;
X	{
X	int	rx,ry,cx,cy;
X	double	x,y;
X	int	npts;
X	double	theta,inc;
X
X	if (color != e->color)
X		return;
X
X	set_linewidth(e->thickness);
X	set_color(e->color);
X	set_style(e->style, e->style_val);
X	if (e->area_fill)
X		set_areafill(e->area_fill);
X	rx = e->radiuses.x;
X	ry = e->radiuses.y;
X	cx = e->center.x;
X	cy = e->center.y;
X	if (rx == ry)
X		{  /* CIRCLE */
X		moveto(cx, cy);
X		if (e->area_fill)
X			FILL_WEDGE(rx, 0, 360);
X		/* outline the circle */
X		CIRCLE(rx);
X		}
X	else /* ellipse */
X		{
X		npts = (rx+ry)*2;	/* pick some number of points proportional
X					   to the size of the ellipse to plot */
X		inc = 2.0*M_PI/npts;
X		moveto(cx+rx,cy);
X		for (theta = 0.0; theta <= 2*M_PI; theta += inc)
X			{
X			x = cx + rx*cos(theta);
X			y = cy + ry*sin(theta);
X			f_drawto(x,y);
X			}
X		drawto(cx+rx, cy);
X		}
X	penup();
X	reset_style(e->style, e->style_val);
X	}
X
X
X#define IS_ITALICS(f) ((f)&1)
X
Xgenhp_text(t,color)
XF_text	*t;
Xint color;
X	{
X	double	height;
X	int	len;
X
X	if (color != t->color)
X		return;
X
X	set_color(t->color);
X	height = (double) t->size/POINT_PER_INCH*2.54;	/* height in cm */
X
X	height = height*scale;
X	height = height/1.5;		/* kludge for now */
X	fprintf(tfp,"SI %.2lf %.2lf;",height/2.54,height);
X	len = strlen(t->cstring);
X	if (IS_ITALICS(t->font))	/* slant for Italics font */
X		fprintf(tfp,"SL %.2f;",tan((double)30.0*M_PI/180.0));	/* 30 degrees */
X	moveto(t->base_x,t->base_y);
X	if (t->type == T_RIGHT_JUSTIFIED)
X		fprintf(tfp,"CP %d 0; ",-len);
X	else if (t->type == T_CENTER_JUSTIFIED)
X		fprintf(tfp,"CP %.1f 0; ",-len/2.0);
X	fprintf(tfp,"LB%s\003;\n",t->cstring);
X	if (IS_ITALICS(t->font))
X		fprintf(tfp,"SL;");
X	}
X
Xgenhp_arc(a,color)
XF_arc	*a;
Xint color;
X{
X	double		angle1, angle2, dx, dy, radius, x, y;
X	double		cx, cy, sx, sy, ex, ey;
X	int		sweep;
X	int		direction;
X
X	if (color != a->color)
X		return;
X
X	cx = a->center.x; cy = a->center.y;
X	sx = a->point[0].x; sy = a->point[0].y;
X	ex = a->point[2].x; ey = a->point[2].y;
X
X	if (coord_system == 2)
X	    direction = !a->direction;
X	else
X	    direction = a->direction;
X	set_linewidth(a->thickness);
X	set_color(a->color);
X	if (a->for_arrow && a->thickness > 0) {
X	    arc_tangent(cx, cy, ex, ey, direction, &x, &y);
X	    draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid);
X	    }
X	if (a->back_arrow && a->thickness > 0) {
X	    arc_tangent(cx, cy, sx, sy, !direction, &x, &y);
X	    draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid);
X	    }
X	dx = cx - sx;
X	dy = cy - sy;
X	radius = sqrt(dx*dx + dy*dy);
X	angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
X	angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
X	/* make the angles go from 0 to 2PI */
X	if (angle1 < 0.0)
X		angle1 += 360.0;
X	if (angle2 < 0.0)
X		angle2 += 360.0;
X	/* direction 1 -> Counter-Clockwise */
X	if (direction == 1) /* ccw */
X		{
X		if (angle1 > angle2)
X			sweep = 360.0 - angle1 + angle2;
X		else
X			sweep = angle2 - angle1;
X		}
X	else /* cw */
X		{
X		if (angle1 > angle2)
X			sweep = - (angle1 - angle2);
X		else
X			sweep = - (360.0 - angle2 + angle1);
X		}
X	if (debug)
X	    fprintf(stderr,"#%d: dir=%s, a1 = %.1f, a2 = %.1f, sweep = %d\n",
X		a->thickness,direction==0?"cw ":"ccw",cx,cy,angle1,angle2,sweep);
X	set_style(a->style, a->style_val);
X	if (a->area_fill)
X		{
X		set_areafill(a->area_fill);
X		f_moveto(cx,cy);
X		F_FILL_WEDGE(radius,(int)angle1,sweep);
X		}
X	f_moveto(ex,ey);
X	pendown();
X	F_ARC_TO(cx,cy,sweep);
X	penup();
X
X	reset_style(a->style, a->style_val);
X	}
X
Xarc_tangent(x1, y1, x2, y2, direction, x, y)
Xdouble	x1, y1, x2, y2, *x, *y;
Xint	direction;
X{
X	if (direction) { /* counter clockwise  */
X	    *x = x2 + (y2 - y1);
X	    *y = y2 - (x2 - x1);
X	    }
X	else {
X	    *x = x2 - (y2 - y1);
X	    *y = y2 + (x2 - x1);
X	    }
X	}
X
X/*	draw arrow heading from (x1, y1) to (x2, y2)	*/
X
Xdraw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
Xdouble	x1, y1, x2, y2, arrowht, arrowwid;
X{
X	double	x, y, xb, yb, dx, dy, l, sina, cosa;
X	double	xc, yc, xd, yd;
X
X	dx = x2 - x1;  dy = y1 - y2;
X	l = sqrt((double)(dx*dx + dy*dy));	/* length of line */
X	sina = dy / l;  cosa = dx / l;
X	xb = x2*cosa - y2*sina;
X	yb = x2*sina + y2*cosa;
X	x = xb - arrowht;
X	y = yb - arrowwid / 2;
X	xc = x*cosa + y*sina;			/* one tail of arrow */
X	yc = -x*sina + y*cosa;
X	y = yb + arrowwid / 2;
X	xd = x*cosa + y*sina;			/* other tail of arrow */
X	yd = -x*sina + y*cosa;
X	f_moveto(xc,yc);
X	f_drawto(x2,y2);
X	f_drawto(xd,yd);
X	penup();
X	}
X
Xellipse_exist(ob)
XF_compound	*ob;
X{
X	F_compound	*c;
X
X	if (NULL != ob->ellipses) return(1);
X
X	for (c = ob->compounds; c != NULL; c = c->next) {
X	    if (ellipse_exist(c)) return(1);
X	    }
X
X	return(0);
X	}
X
Xnormal_spline_exist(ob)
XF_compound	*ob;
X{
X	F_spline	*s;
X	F_compound	*c;
X
X	for (s = ob->splines; s != NULL; s = s->next) {
X	    if (normal_spline(s)) return(1);
X	    }
X
X	for (c = ob->compounds; c != NULL; c = c->next) {
X	    if (normal_spline_exist(c)) return(1);
X	    }
X
X	return(0);
X	}
X
X/*VARARGS1*/
Xput_msg(format, arg1, arg2, arg3, arg4, arg5)
X	char    *format;
X	int     arg1, arg2, arg3, arg4, arg5;
X{
X	fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5);
X}
END_OF_FILE
if test 18027 -ne `wc -c <'f2hp.c'`; then
    echo shar: \"'f2hp.c'\" unpacked with wrong size!
fi
# end of 'f2hp.c'
fi
if test -f 'movept.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'movept.c'\"
else
echo shar: Extracting \"'movept.c'\" \(17045 characters\)
sed "s/^X//" >'movept.c' <<'END_OF_FILE'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "func.h"
X#include "object.h"
X#include "paintop.h"
X
X#define			TOLERANCE	3
Xextern int		latexline_mode, latexarrow_mode;
Xextern int		magnet_mode;
X
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
Xextern			null_proc();
Xextern			set_popupmenu();
XF_line			*line_point_search();
XF_spline		*spline_point_search();
XF_ellipse		*ellipse_point_search();
XF_arc			*arc_point_search();
X
Xextern F_compound	objects;
X
Xextern F_point		*moved_point, *left_point;
Xextern F_pos		last_position, new_position;
Xextern int		movedpoint_num;
Xextern int		last_object;
Xextern int		fix_x, fix_y, cur_x, cur_y;
Xextern int		pointmarker_shown;
Xextern int		foreground_color, background_color;
X
Xextern			elastic_box(), move_ebrbox(), move_ebdbox();
Xextern			move_cbrbox(), move_cbdbox();
X
Xextern int		init_move_point();
Xextern int		move_linepoint(), fix_movedlinepoint();
Xextern int		move_latexlinepoint(), fix_movedlatexlinepoint();
Xextern int		fix_box();
Xextern int		fix_movedsplinepoint();
Xextern int		move_arcpoint(), fix_movedarcpoint();
Xextern int		fix_movedellipsepoint();
X
Xstatic F_line		*line;
Xstatic F_spline		*spline;
Xstatic F_ellipse	*ellipse;
Xstatic F_arc		*arc;
X
Xstatic int		latex_fix_x, latex_fix_y;
XCURSOR			cur_latexcursor;
XBoolean			init_ellipsepointmoving();
X
Xmove_point_selected()
X{
X	canvas_kbd_proc = null_proc;
X	canvas_locmove_proc = null_proc;
X	canvas_leftbut_proc = init_move_point;
X	canvas_middlebut_proc = null_proc;
X	canvas_rightbut_proc = set_popupmenu;
X	set_cursor(&pick9_cursor);
X	reset_action_on();
X	}
X
Xinit_move_point(x, y)
Xint	x, y;
X{
X	Boolean Ok=True;
X
X	if ((line = line_point_search(x, y, TOLERANCE,
X		&left_point, &moved_point)) != NULL) {
X	    init_linepointmoving(line);
X	    }
X	else if ((spline = spline_point_search(x, y, 
X		TOLERANCE, &left_point, &moved_point)) != NULL){
X	    init_splinepointmoving(spline);
X	    }
X	else if ((ellipse = ellipse_point_search(x, y, TOLERANCE, 
X		&movedpoint_num)) != NULL) {
X	    if (!init_ellipsepointmoving(ellipse))	/* selected center, ignore */
X		Ok=False;
X	    }
X	else if ((arc = arc_point_search(x, y, TOLERANCE, 
X		&movedpoint_num)) != NULL) {
X	    init_arcpointmoving(arc);
X	    }
X	else {
X	    return;
X	    }
X	if (Ok)		/* movepoint went ok */
X		{
X		canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
X		erase_pointmarker();
X		}
X	}
X
Xwrapup_movepoint()
X{
X	show_pointmarker();
X	move_point_selected();
X	}
X
X/*************************  ellipse  *******************************/
X
XF_ellipse *
Xellipse_point_search(x, y, tol, point_num)
Xint	x, y, tol, *point_num;
X{
X	F_ellipse	*e;
X
X	for (e = objects.ellipses; e != NULL; e = e->next) {
X	    if (abs(e->start.x - x) <= tol && abs(e->start.y - y) <= tol) {
X		*point_num = 0;
X		return(e);
X		}
X	    if (abs(e->end.x - x) <= tol && abs(e->end.y - y) <= tol) {
X		*point_num = 1;
X		return(e);
X		}
X	    }
X	return(NULL);
X	}
X
Xstatic F_ellipse	*cur_e;
X
XBoolean
Xinit_ellipsepointmoving(ellipse)
XF_ellipse	*ellipse;
X{
X	if (movedpoint_num == 0) {  /*  center point is selected - disallow */
X	    if (ellipse->type == T_ELLIPSE_BY_RAD || 
X		ellipse->type == T_CIRCLE_BY_RAD) {
X		return False;	/* don't erase point_marker etc */
X		}
X	    last_position.x = cur_x = ellipse->start.x;
X	    last_position.y = cur_y = ellipse->start.y;
X	    fix_x = ellipse->end.x;  fix_y = ellipse->end.y;
X	    switch (ellipse->type) {
X		case T_ELLIPSE_BY_DIA :
X		    canvas_locmove_proc = move_ebdbox;
X		    ellipsebydia_box(INV_PAINT);
X		    break;
X		case T_CIRCLE_BY_DIA :
X		    canvas_locmove_proc = move_cbdbox;
X		    circlebydia_box(INV_PAINT);
X		    break;
X		}
X	    }
X	else {
X	    last_position.x = cur_x = ellipse->end.x;
X	    last_position.y = cur_y = ellipse->end.y;
X	    fix_x = ellipse->start.x;  fix_y = ellipse->start.y;
X	    switch (ellipse->type) {
X		case T_ELLIPSE_BY_RAD :
X		    canvas_locmove_proc = move_ebrbox;
X		    ellipsebyrad_box(INV_PAINT);
X		    break;
X		case T_CIRCLE_BY_RAD :
X		    canvas_locmove_proc = move_cbrbox;
X		    circlebyrad_box(INV_PAINT);
X		    break;
X		case T_ELLIPSE_BY_DIA :
X		    canvas_locmove_proc = move_ebdbox;
X		    ellipsebydia_box(INV_PAINT);
X		    break;
X		case T_CIRCLE_BY_DIA :
X		    canvas_locmove_proc = move_cbdbox;
X		    circlebydia_box(INV_PAINT);
X		    break;
X		}
X	    }
X	cur_e = ellipse;
X	set_temp_cursor(&crosshair_cursor);
X	win_setmouseposition(canvas_win, cur_x, cur_y);
X	canvas_middlebut_proc = fix_movedellipsepoint;
X	canvas_leftbut_proc = null_proc;
X	return True;	/* all is Ok */
X	}
X
Xfix_movedellipsepoint(x, y)
Xint	x, y;
X{
X	switch (cur_e->type) {
X	    case T_ELLIPSE_BY_RAD :
X		ellipsebyrad_box(INV_PAINT);
X		break;
X	    case T_CIRCLE_BY_RAD :
X		circlebyrad_box(INV_PAINT);
X		break;
X	    case T_ELLIPSE_BY_DIA :
X		ellipsebydia_box(INV_PAINT);
X		break;
X	    case T_CIRCLE_BY_DIA :
X		circlebydia_box(INV_PAINT);
X		break;
X	    }
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_ELLIPSE);
X	set_latestellipse(cur_e);
X	relocate_ellipsepoint(cur_e, x, y, movedpoint_num);
X	wrapup_movepoint();
X	}
X
Xrelocate_ellipsepoint(ellipse, x, y, point_num)
XF_ellipse	*ellipse;
Xint		x, y, point_num;
X{
X	int	dx, dy;
X
X	set_temp_cursor(&wait_cursor);
X	if (pointmarker_shown) toggle_ellipsepointmarker(ellipse);
X	draw_ellipse(ellipse, background_color);
X	if (point_num == 0) {  /*  starting point is selected  */
X	    fix_x = ellipse->end.x;  fix_y = ellipse->end.y;
X	    ellipse->start.x = x;  ellipse->start.y = y;
X	    }
X	else {
X	    fix_x = ellipse->start.x;  fix_y = ellipse->start.y;
X	    ellipse->end.x = x;  ellipse->end.y = y;
X	    }
X	switch (ellipse->type) {
X	    case T_ELLIPSE_BY_RAD :
X		ellipse->radiuses.x = abs(x - fix_x) + 1;
X		ellipse->radiuses.y = abs(y - fix_y) + 1;
X		break;
X	    case T_CIRCLE_BY_RAD :
X		dx = fix_x - x;  dy = fix_y - y;
X		ellipse->radiuses.x = sqrt((double)(dx*dx + dy*dy)) + .5;
X		ellipse->radiuses.y = ellipse->radiuses.x;
X		break;
X	    case T_ELLIPSE_BY_DIA :
X		ellipse->center.x = (fix_x + x) / 2;
X		ellipse->center.y = (fix_y + y) / 2;
X		ellipse->radiuses.x = abs(ellipse->center.x - fix_x);
X		ellipse->radiuses.y = abs(ellipse->center.y - fix_y);
X		break;
X	    case T_CIRCLE_BY_DIA :
X		dx = ellipse->center.x = (fix_x + x) / 2 +.5;
X		dy = ellipse->center.y = (fix_y + y) / 2 +.5;
X		dx -= x;  dy -= y; 
X		ellipse->radiuses.x = sqrt((double)(dx*dx + dy*dy)) + .5;
X		ellipse->radiuses.y = ellipse->radiuses.x;
X		break;
X	    }
X	draw_ellipse(ellipse, foreground_color);
X	if (pointmarker_shown) toggle_ellipsepointmarker(ellipse);
X	reset_cursor();
X	set_modifiedflag();
X	}
X
X/***************************  arc  *********************************/
X
Xstatic F_arc		*cur_a;
X
XF_arc *
Xarc_point_search(x, y, tol, point_num)
Xint	x, y, tol, *point_num;
X{
X	F_arc	*a;
X	int	i;
X
X	for(a = objects.arcs; a != NULL; a = a->next) {
X	    for (i = 0; i < 3; i++) {
X		if (abs(a->point[i].x - x) <= tol && 
X			abs(a->point[i].y - y) <= tol) {
X		    *point_num = i;
X		    return(a);
X		    }
X		}
X	    }
X	return(NULL);
X	}
X
Xinit_arcpointmoving(arc)
XF_arc	*arc;
X{
X	cur_a = arc;
X	last_position.x = cur_x = arc->point[movedpoint_num].x;
X	last_position.y = cur_y = arc->point[movedpoint_num].y;
X	set_temp_cursor(&crosshair_cursor);
X	win_setmouseposition(canvas_win, cur_x, cur_y);
X	draw_arclink(INV_PAINT);
X	canvas_locmove_proc = move_arcpoint;
X	canvas_middlebut_proc = fix_movedarcpoint;
X	canvas_leftbut_proc = null_proc;
X	}
X
Xmove_arcpoint(x, y)
Xint	x, y;
X{
X	draw_arclink(INV_PAINT);
X	cur_x = x;  cur_y = y;
X	draw_arclink(INV_PAINT);
X	}
X
Xdraw_arclink(op)
Xint	op;
X{
X	switch (movedpoint_num) {
X	    case 0 :
X		pw_vector(canvas_win, cur_x, cur_y, 
X			arc->point[1].x, arc->point[1].y, op, 1, SOLID_LINE, 0.0);
X		break;
X	    case 1 :
X		pw_vector(canvas_win, arc->point[0].x, arc->point[0].y,
X			cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X		pw_vector(canvas_win, arc->point[2].x, arc->point[2].y,
X			cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X		break;
X	    default :
X		pw_vector(canvas_win, arc->point[2].x, arc->point[2].y,
X			cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X	    }
X	}
X
Xfix_movedarcpoint(x, y)
Xint	x, y;
X{
X	draw_arclink(INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_ARC);
X	set_latestarc(cur_a);
X	relocate_arcpoint(cur_a, x, y, movedpoint_num);
X	wrapup_movepoint();
X	}
X
Xrelocate_arcpoint(arc, x, y, movedpoint_num)
XF_arc	*arc;
Xint			 x, y, movedpoint_num;
X{
X	float	xx, yy;
X	F_pos	p[3];
X
X	p[0] = arc->point[0];
X	p[1] = arc->point[1];
X	p[2] = arc->point[2];
X	p[movedpoint_num].x = x;
X	p[movedpoint_num].y = y;
X	if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) {
X	    set_temp_cursor(&wait_cursor);
X	    if (pointmarker_shown) toggle_arcpointmarker(arc);
X	    draw_arc(arc, background_color);	/* erase old arc */
X	    arc->point[movedpoint_num].x = x;
X	    arc->point[movedpoint_num].y = y;
X	    arc->center.x = xx;
X	    arc->center.y = yy;
X	    arc->direction = compute_direction(p[0], p[1], p[2]);
X	    draw_arc(arc, foreground_color);	/* draw new arc */
X	    if (pointmarker_shown) toggle_arcpointmarker(arc);
X	    reset_cursor();
X	    set_modifiedflag();
X	    }
X	}
X
X/**************************  spline  *******************************/
X
Xstatic F_spline		*cur_s;
X
Xinit_splinepointmoving(s)
XF_spline	*s;
X{
X	F_point	*p;
X
X	cur_s = s;
X	last_position.x = cur_x = moved_point->x;
X	last_position.y = cur_y = moved_point->y;
X	set_temp_cursor(&crosshair_cursor);
X	win_setmouseposition(canvas_win, cur_x, cur_y);
X	if (closed_spline(s) && left_point == NULL) {
X	    for (left_point = moved_point->next, 
X		p = left_point->next; 
X		p->next != NULL; 
X		left_point = p, p = p->next);
X	    }
X	draw_pointlink(INV_PAINT);
X	canvas_locmove_proc = move_linepoint;
X	canvas_middlebut_proc = fix_movedsplinepoint;
X	canvas_leftbut_proc = null_proc;
X	}
X
XF_spline *
Xspline_point_search(x, y, tol, p, q)
Xint	x, y, tol;
XF_point	**p, **q;
X{
X	F_spline	*s;
X
X	for (s = objects.splines; s != NULL; s= s->next) {
X	    *p = NULL;
X	    for (*q = s->points; *q != NULL; *p = *q, *q = (*q)->next) {
X		if (abs((*q)->x - x) <= tol && abs((*q)->y - y) <= tol)
X		    return(s);
X		}
X	    }
X	return(NULL);
X	}
X
Xfix_movedsplinepoint(x, y)
Xint	x, y;
X{
X	draw_pointlink(INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_SPLINE);
X	set_latestspline(cur_s);
X	relocate_splinepoint(cur_s, x, y, moved_point);
X	wrapup_movepoint();
X	}
X
Xrelocate_splinepoint(s, x, y, moved_point)
XF_spline	*s;
Xint		x, y;
XF_point		*moved_point;
X{
X	set_temp_cursor(&wait_cursor);
X	if (pointmarker_shown) toggle_splinepointmarker(s);  
X	draw_spline(s, ERASE); /* erase old spline */
X	moved_point->x = x;
X	moved_point->y = y;
X	if (closed_spline(s)) {
X	    left_point->next->x = x;
X	    left_point->next->y = y;
X	    }
X	if (int_spline(s)) remake_control_points(s);
X	draw_spline(s, PAINT); /* draw spline with moved point */
X	if (pointmarker_shown) toggle_splinepointmarker(s);  
X	reset_cursor();
X	set_modifiedflag();
X	}
X
X/***************************  line  ********************************/
X
Xstatic F_line		*cur_l;
X
Xinit_linepointmoving(line)
XF_line	*line;
X{
X	int	box_case;
X	int	latex_case;
X	F_point	*p;
X
X	cur_l = line;
X	box_case = 0;
X	latex_case = 0;
X	last_position.x = cur_x = moved_point->x;
X	last_position.y = cur_y = moved_point->y;
X	set_temp_cursor(&crosshair_cursor);
X	win_setmouseposition(canvas_win, cur_x, cur_y);
X	switch (line->type) {
X	    case T_POLYGON :
X		if (left_point == NULL)
X		    for (left_point = moved_point->next, 
X			p = left_point->next; 
X			p->next != NULL; 
X			left_point = p, p = p->next);
X		break;
X	    case T_BOX :
X	    case T_ARC_BOX :
X		if (moved_point->next->next == NULL) { /* point 4 */
X		    fix_x = line->points->next->x;
X		    fix_y = line->points->next->y;
X		    }
X		else {
X		    fix_x = moved_point->next->next->x;
X		    fix_y = moved_point->next->next->y;
X		    }
X		if (line->type == T_ARC_BOX)
X			draw_arc_box(line, ERASE);
X		else
X			draw_line(line, ERASE);
X		box_case = 1;
X		break;
X	    case T_POLYLINE :
X		if (left_point != NULL) {
X		    if (left_point == line->points) {
X			if (line->back_arrow) /*  backward arrow  */
X			    draw_arrow(cur_x, cur_y,
X				left_point->x, left_point->y,
X				line->back_arrow, ERASE);
X			}
X		    }
X		else if (line->back_arrow) /*  backward arrow  */
X		    draw_arrow(moved_point->next->x, moved_point->next->y,
X			cur_x, cur_y, line->back_arrow, ERASE);
X		p = moved_point->next;
X		if (p != NULL) {
X		    if (line->for_arrow && p->next == NULL) 
X			draw_arrow(cur_x, cur_y, p->x, p->y, 
X			    line->for_arrow, ERASE);
X			}
X		else if (line->for_arrow)/* f arrow */
X		    draw_arrow(left_point->x, left_point->y, 
X			cur_x, cur_y, line->for_arrow, ERASE);
X		if (latexline_mode || latexarrow_mode) {
X		    if (left_point != NULL) {
X			latex_fix_x = left_point->x;
X			latex_fix_y = left_point->y;
X			latex_case = 1;
X			}
X		    else if (p != NULL) {
X			latex_fix_x = p->x;
X			latex_fix_y = p->y;
X			latex_case = 1;
X			}
X		    }
X	    }
X	if (box_case) {
X	    draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
X	    canvas_locmove_proc = elastic_box;
X	    canvas_middlebut_proc = fix_box;
X	    }
X	else if (latex_case) {
X	    draw_pointlink(INV_PAINT);
X	    canvas_locmove_proc = move_latexlinepoint;
X	    canvas_middlebut_proc = fix_movedlatexlinepoint;
X	    cur_latexcursor = &crosshair_cursor;
X	    }
X	else {
X	    draw_pointlink(INV_PAINT);
X	    canvas_locmove_proc = move_linepoint;
X	    canvas_middlebut_proc = fix_movedlinepoint;
X	    }
X	canvas_leftbut_proc = null_proc;
X	}
X
Xmove_linepoint(x, y)
Xint	x, y;
X{
X	draw_pointlink(INV_PAINT);
X	cur_x = x;
X	cur_y = y;
X	draw_pointlink(INV_PAINT);
X	}
X
Xmove_latexlinepoint(x, y)
Xint	x, y;
X{
X	CURSOR	 c;
X
X	draw_pointlink(INV_PAINT);
X	latex_endpoint(latex_fix_x, latex_fix_y, x, y, &cur_x, &cur_y,
X	    latexarrow_mode, (magnet_mode)? 5: 1);
X	draw_pointlink(INV_PAINT);
X	c = (x == cur_x  &&  y == cur_y)? &null_cursor: &crosshair_cursor;
X	if (c != cur_latexcursor) {
X	    set_temp_cursor(c);
X	    cur_latexcursor = c;
X	    }
X	}
X
Xfix_box(x, y)
Xint	x, y;
X{
X	draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_POLYLINE);
X	set_latestline(line);
X	relocate_linepoint(line, x, y, fix_x, fix_y, moved_point, 
X		left_point);
X	wrapup_movepoint();
X	}
X
Xassign_newboxpoint(b, x1, y1, x2, y2)
XF_line	*b;
Xint	x1, y1, x2, y2;
X{
X	F_point	*p;
X	register int tmp;
X
X	p = b->points;
X	if (x1 > x2)		/* sort them so that lower left is first */
X		{
X		tmp = x1; x1 = x2; x2 = tmp;
X		}
X	if (y1 > y2)
X		{
X		tmp = y1; y1 = y2; y2 = tmp;
X		}
X	p->x = x1;	p->y = y1;	p = p->next;
X	p->x = x1;	p->y = y2;	p = p->next;
X	p->x = x2;	p->y = y2;	p = p->next;
X	p->x = x2;	p->y = y1;	p = p->next;
X	p->x = x1;	p->y = y1;	p = p->next;
X	}
X
Xfix_movedlinepoint(x, y)
Xint	x, y;
X{
X	draw_pointlink(INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_POLYLINE);
X	set_latestline(cur_l);
X	relocate_linepoint(cur_l, x, y, fix_x, fix_y, moved_point, left_point);
X	wrapup_movepoint();
X	}
X
Xfix_movedlatexlinepoint(x, y)
Xint	x, y;
X{
X	draw_pointlink(INV_PAINT);
X	latex_endpoint(latex_fix_x, latex_fix_y, x, y, &x, &y,
X	    latexarrow_mode, (magnet_mode)? 5: 1);
X	if (cur_latexcursor != &crosshair_cursor)
X	    set_temp_cursor(&crosshair_cursor);
X	win_setmouseposition(canvas_win, x, y);
X	new_position.x = x;
X	new_position.y = y;
X	clean_up();
X	set_action_object(F_MOVE_POINT, O_POLYLINE);
X	set_latestline(cur_l);
X	relocate_linepoint(cur_l, x, y, fix_x, fix_y, moved_point, left_point);
X	wrapup_movepoint();
X	}
X
Xrelocate_linepoint(line, x, y, fix_x, fix_y, moved_point, left_point)
XF_line	*line;
Xint	x, y;
XF_point	*moved_point, *left_point;
X{
X	if (pointmarker_shown) toggle_linepointmarker(line);
X	draw_line(line, ERASE);
X	switch (line->type) {
X	    case T_BOX :
X	    case T_ARC_BOX:
X		assign_newboxpoint(line, fix_x, fix_y, x, y);
X		break;
X	    case T_POLYGON :
X		if (line->points == moved_point) {
X		    left_point->next->x = x;
X		    left_point->next->y = y;
X		    }
X	    default :
X		moved_point->x = x;
X		moved_point->y = y;
X	    }
X	draw_line(line, PAINT);
X	if (pointmarker_shown) toggle_linepointmarker(line);  
X	set_modifiedflag();
X	}
X
Xdraw_pointlink(op)
Xint	op;
X{
X	F_point	*p;
X
X	if (left_point != NULL) {
X	    pw_vector(canvas_win, left_point->x, left_point->y,
X			cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X	    }
X	if ((p = moved_point->next) != NULL) {
X	    pw_vector(canvas_win, p->x, p->y, cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X	    }
X	}
X
XF_line *
Xline_point_search(x, y, tol, p, q)
Xint	x, y, tol;
XF_point	**p, **q;
X{
X	F_line	*l;
X	F_point	*a, *b;
X
X	for (l = objects.lines; l != NULL; l= l->next) {
X	    for (a = NULL, b = l->points; b != NULL; a = b, b = b->next) {
X		if (abs(b->x - x) <= tol && abs(b->y - y) <= tol) {
X		    *p = a;
X		    *q = b;
X		    return(l);
X		    }
X		}
X	    }
X	return(NULL);
X	}
END_OF_FILE
if test 17045 -ne `wc -c <'movept.c'`; then
    echo shar: \"'movept.c'\" unpacked with wrong size!
fi
# end of 'movept.c'
fi
if test -f 'read.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'read.c'\"
else
echo shar: Extracting \"'read.c'\" \(16741 characters\)
sed "s/^X//" >'read.c' <<'END_OF_FILE'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : August 1985.
X *	2nd revision : March 1988.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "alloc.h"
X#include "object.h"
X#include "psfonts.h"
X
Xextern F_arrow		*make_arrow();
Xextern char		*calloc();
Xextern int		errno;
X
Xstatic F_ellipse	*read_ellipseobject();
Xstatic F_line		*read_lineobject();
Xstatic F_text		*read_textobject();
Xstatic F_spline		*read_splineobject();
Xstatic F_arc		*read_arcobject();
Xstatic F_compound	*read_compoundobject();
X
X#define			BUF_SIZE		1024
X
Xchar		buf[BUF_SIZE];
Xint		line_no;
Xint		num_object;
Xint		proto;		/* file protocol*10 */
X
Xread_fail_message(file, err)
Xchar	*file;
Xint	err;
X{
X	extern char	*sys_errlist[];
X
X	if (err == 0)		/* Successful read */
X	    return;
X#ifdef ENAMETOOLONG
X	else if (err == ENAMETOOLONG)
X	    put_msg("File name \"%s\" is too long", file);
X#endif
X	else if (err == ENOENT)
X	    put_msg("File \"%s\" does not exist", file);
X	else if (err == ENOTDIR)
X	    put_msg("A name in the path \"%s\" is not a directory", file);
X	else if (err == EACCES)
X	    put_msg("Read access to file \"%s\" is blocked", file);
X	else if (err == EISDIR)
X	    put_msg("File \"%s\" is a directory", file);
X	else if (err == -2) {
X	    put_msg("File \"%s\" is empty", file);
X	    }
X	else if (err == -1) {
X	    /* Format error; relevant error message is already delivered */
X	    }
X	else
X	    put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
X	}
X
X/**********************************************************
XRead_fig returns :
X
X     0 : successful read.
X    -1 : File is in incorrect format
X    -2 : File is empty
Xerr_no : if file can not be read for various reasons
X
XThe resolution (ppi) and the coordinate system (coord_sys) are
Xstored in obj->nwcorner.x and obj->nwcorner.y respectively.
XThe coordinate system is 1 for lower left at 0,0 and 
X2 for upper left at 0,0
X>>> xfig only uses 2 for the coordinate system. <<<
X**********************************************************/
X
Xread_fig(file_name, obj)
Xchar		*file_name;
XF_compound	*obj;
X{
X	FILE	*fp;
X
X	line_no = 0;
X	if ((fp = fopen(file_name, "r")) == NULL)
X	    return(errno);
X	else
X	    return(readfp_fig(fp, obj));
X	}
X
Xreadfp_fig(fp, obj)
XFILE  *fp;
XF_compound    *obj;
X{
X	int	status;
X	float	fproto;
X  
X	num_object = 0;
X	bzero((char*)obj, COMOBJ_SIZE);
X	if (fgets(buf,BUF_SIZE,fp)==0)	/* version */
X		return -2;
X	if (strncmp(buf,"#FIG",4)==0)	/* versions 1.4/later have #FIG in first line */
X		{
X		if ((sscanf(index(buf,' ')+1,"%f",&fproto))==0)	/* assume 1.4 */
X			proto=14;
X		else
X			proto = (fproto+.01)*10;	/* protocol version*10 */
X		status = read_objects(fp, obj);
X		}
X	else
X		{
X		proto = 13;
X		status = read_1_3_objects(fp, obj);
X		}
X
X	fclose(fp);
X	return(status);
X        }
X	
Xint
Xread_objects(fp, obj)
XFILE		*fp;
XF_compound	*obj;
X{
X	F_ellipse	*e, *le = NULL;
X	F_line		*l, *ll = NULL;
X	F_text		*t, *lt = NULL;
X	F_spline	*s, *ls = NULL;
X	F_arc		*a, *la = NULL;
X	F_compound	*c, *lc = NULL;
X	int		object, ppi, coord_sys;
X
X	line_no++;
X	if (get_line(fp) < 0) {
X	    put_msg("File is truncated");
X	    return(-1);
X	    }
X	if (2 != sscanf(buf,"%d%d\n", &ppi, &coord_sys)) {
X	    put_msg("Incomplete data at line %d", line_no);
X	    return(-1);
X	    }
X
X	obj->nwcorner.x = ppi;
X	obj->nwcorner.y = coord_sys;
X	while (get_line(fp) > 0) {
X	    if (1 != sscanf(buf, "%d", &object)) {
X		put_msg("Incorrect format at line %d", line_no);
X		return(-1);
X		}
X	    switch (object) {
X		case O_POLYLINE :
X		    if ((l = read_lineobject(fp)) == NULL) return(-1);
X		    if (ll)
X			ll = (ll->next = l);
X		    else 
X			ll = obj->lines = l;
X		    num_object++;
X		    break;
X		case O_SPLINE :
X		    if ((s = read_splineobject(fp)) == NULL) return(-1);
X		    if (ls)
X			ls = (ls->next = s);
X		    else 
X			ls = obj->splines = s;
X		    num_object++;
X		    break;
X		case O_ELLIPSE :
X		    if ((e = read_ellipseobject()) == NULL) return(-1);
X		    if (le)
X			le = (le->next = e);
X		    else 
X			le = obj->ellipses = e;
X		    num_object++;
X		    break;
X		case O_ARC :
X		    if ((a = read_arcobject(fp)) == NULL) return(-1);
X		    if (la)
X			la = (la->next = a);
X		    else 
X			la = obj->arcs = a;
X		    num_object++;
X		    break;
X		case O_TEXT :
X		    if ((t = read_textobject(fp)) == NULL) return(-1);
X		    if (lt)
X			lt = (lt->next = t);
X		    else 
X			lt = obj->texts = t;
X		    num_object++;
X		    break;
X		case O_COMPOUND :
X		    if ((c = read_compoundobject(fp)) == NULL) return(-1);
X		    if (lc)
X			lc = (lc->next = c);
X		    else 
X			lc = obj->compounds = c;
X		    num_object++;
X		    break;
X		default :
X		    put_msg("Incorrect object code at line %d", line_no);
X		    return(-1);
X		} /*  switch */
X	    } /*  while */
X	if (feof(fp))
X	    return(0);
X	else
X	    return(errno);
X	} /*  read_objects */
X
Xstatic F_arc *
Xread_arcobject(fp)
XFILE	*fp;
X{
X	F_arc	*a;
X	int	n, fa, ba;
X	int	type, style;
X	float	thickness, wid, ht;
X
X	if (NULL == (Arc_malloc(a))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	a->next = NULL;
X	a->for_arrow = a->back_arrow = NULL;	/* added 8/23/89 B.V.Smith */
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%f%f%d%d%d%d%d%d\n",
X		&a->type, &a->style, &a->thickness, 
X		&a->color, &a->depth, 
X		&a->pen, &a->area_fill,
X		&a->style_val, &a->direction, &fa, &ba,
X		&a->center.x, &a->center.y, 
X		&a->point[0].x, &a->point[0].y, 
X		&a->point[1].x, &a->point[1].y, 
X		&a->point[2].x, &a->point[2].y);
X	if (n != 19) {
X	    put_msg(Err_incomp, "arc", line_no);
X	    free((char*)a);
X	    return(NULL);
X	    }
X
X	skip_comment(fp);
X	if (fa) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "arc", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    a->for_arrow = make_arrow(type, style, thickness, wid, ht);
X	    skip_comment(fp);
X	    }
X	skip_comment(fp);
X	if (ba) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "arc", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    a->back_arrow = make_arrow(type, style, thickness, wid, ht);
X	    }
X	return(a);
X	}
X
Xstatic F_compound *
Xread_compoundobject(fp)
XFILE	*fp;
X{
X	F_arc		*a, *la = NULL;
X	F_ellipse	*e, *le = NULL;
X	F_line		*l, *ll = NULL;
X	F_spline	*s, *ls = NULL;
X	F_text		*t, *lt = NULL;
X	F_compound	*com, *c, *lc = NULL;
X	int		n, object;
X
X	if (NULL == (Compound_malloc(com))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	com->arcs = NULL;
X	com->ellipses = NULL;
X	com->lines = NULL;
X	com->splines = NULL;
X	com->texts = NULL;
X	com->compounds = NULL;
X	com->next = NULL;
X	n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
X		&com->secorner.x, &com->secorner.y);
X	if (4 != n) {
X	    put_msg(Err_incomp, "compound", line_no);
X	    free((char*)com);
X	    return(NULL);
X	    }
X	while (get_line(fp) > 0) {
X	    if (1 != sscanf(buf, "%d", &object)) {
X		put_msg(Err_incomp, "compound", line_no);
X		free_compound(&com);
X		return(NULL);
X		}
X	    switch (object) {
X		case O_POLYLINE :
X		    if ((l = read_lineobject(fp)) == NULL) { 
X			free_line(&l);
X			return(NULL);
X			}
X		    if (ll)
X			ll = (ll->next = l);
X		    else 
X			ll = com->lines = l;
X		    break;
X		case O_SPLINE :
X		    if ((s = read_splineobject(fp)) == NULL) { 
X			free_spline(&s);
X			return(NULL);
X			}
X		    if (ls)
X			ls = (ls->next = s);
X		    else 
X			ls = com->splines = s;
X		    break;
X		case O_ELLIPSE :
X		    if ((e = read_ellipseobject()) == NULL) { 
X			free_ellipse(&e);
X			return(NULL);
X			}
X		    if (le)
X			le = (le->next = e);
X		    else 
X			le = com->ellipses = e;
X		    break;
X		case O_ARC :
X		    if ((a = read_arcobject(fp)) == NULL) { 
X			free_arc(&a);
X			return(NULL);
X			}
X		    if (la)
X			la = (la->next = a);
X		    else 
X			la = com->arcs = a;
X		    break;
X		case O_TEXT :
X		    if ((t = read_textobject(fp)) == NULL) { 
X			free_text(&t);
X			return(NULL);
X			}
X		    if (lt)
X			lt = (lt->next = t);
X		    else 
X			lt = com->texts = t;
X		    break;
X		case O_COMPOUND :
X		    if ((c = read_compoundobject(fp)) == NULL) { 
X			free_compound(&c);
X			return(NULL);
X			}
X		    if (lc)
X			lc = (lc->next = c);
X		    else 
X			lc = com->compounds = c;
X		    break;
X		case O_END_COMPOUND :
X		    return(com);
X		default :
X		    put_msg("Wrong object code at line %d", line_no);
X		    return(NULL);
X		} /*  switch */
X	    }
X	if (feof(fp))
X	    return(com);
X	else
X	    return(NULL);
X	}
X
Xstatic F_ellipse *
Xread_ellipseobject()
X{
X	F_ellipse	*e;
X	int		n;
X
X	if (NULL == (Ellipse_malloc(e))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	e->next = NULL;
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n",
X		&e->type, &e->style, &e->thickness,
X		&e->color, &e->depth, &e->pen, &e->area_fill,
X		&e->style_val, &e->direction, &e->angle,
X		&e->center.x, &e->center.y, 
X		&e->radiuses.x, &e->radiuses.y, 
X		&e->start.x, &e->start.y, 
X		&e->end.x, &e->end.y);
X	if (n != 18) {
X	    put_msg(Err_incomp, "ellipse", line_no);
X	    free((char*)e);
X	    return(NULL);
X	    }
X	return(e);
X	}
X
Xstatic F_line *
Xread_lineobject(fp)
XFILE	*fp;
X{
X	F_line	*l;
X	F_point	*p, *q;
X	int	n, x, y, fa, ba;
X	int	type, style;
X	float	thickness, wid, ht;
X
X	if (NULL == (Line_malloc(l))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	l->points = NULL;
X	l->for_arrow = l->back_arrow = NULL;
X	l->next = NULL;
X
X	sscanf(buf,"%*d%d",&l->type);
X#ifndef TFX
X	/* 2.0 or later; has separate radius parm for arc-box corners */
X	if (l->type == T_ARC_BOX && proto >= 20)
X		{
X		n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d",
X			&l->type, &l->style, &l->thickness, &l->color,
X			&l->depth, &l->pen, &l->area_fill, &l->style_val, &l->radius,
X			&fa, &ba);
X		}
X	/* old format uses pen for radius of arc-box corners */
X	else
X#endif TFX
X		{
X		n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d",
X			&l->type, &l->style, &l->thickness, &l->color,
X			&l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
X#ifndef TFX
X		if (l->type == T_ARC_BOX)
X			{
X			l->radius = l->pen;
X			l->pen = 0;
X			}
X		else
X#endif TFX
X			l->radius = 0;
X		}
X
X#ifdef TFX
X	if (n != 10)
X#else
X	if ((proto==14 && n != 10) || 
X	    (proto==20 && (l->type == T_ARC_BOX && n != 11) || 
X			  (l->type != T_ARC_BOX && n != 10))) {
X#endif TFX
X	    put_msg(Err_incomp, "line", line_no);
X	    free((char*)l);
X	    return(NULL);
X	    }
X	skip_comment(fp);
X	if (fa) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "line", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    l->for_arrow = make_arrow(type, style, thickness, wid, ht);
X	    skip_comment(fp);
X	    }
X	if (ba) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "line", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    l->back_arrow = make_arrow(type, style, thickness, wid, ht);
X	    skip_comment(fp);
X	    }
X
X	if (NULL == (l->points = Point_malloc(p))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	p->next = NULL;
X
X	/* points start on new line */
X	line_no++;
X
X	/* read first point */
X	if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
X	    put_msg(Err_incomp, "line", line_no);
X	    free_linestorage(l);
X	    return(NULL);
X	    }
X	/* read subsequent points */
X	for (;;) {
X	    if (fscanf(fp, "%d%d", &x, &y) != 2) {
X		put_msg(Err_incomp, "line", line_no);
X		free_linestorage(l);
X		return(NULL);
X		}
X	    if (x == 9999) break;
X	    if (NULL == (Point_malloc(q))) {
X		put_msg(Err_mem);
X		free_linestorage(l);
X		return(NULL);
X		}
X	    q->x = x;
X	    q->y = y;
X	    q->next = NULL;
X	    p->next = q;
X	    p = q;
X	    }
X	skip_line(fp);
X	return(l);
X	}
X
Xstatic F_spline *
Xread_splineobject(fp)
XFILE	*fp;
X{
X	F_spline	*s;
X	F_point		*p, *q;
X	F_control	*cp, *cq;
X	int		c, n, x, y, fa, ba;
X	int		type, style;
X	float		thickness, wid, ht;
X	float		lx, ly, rx, ry;
X
X	if (NULL == (Spline_malloc(s))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	s->points = NULL;
X	s->controls = NULL;
X	s->for_arrow = s->back_arrow = NULL;
X	s->next = NULL;
X
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d%d%d", 
X	    	&s->type, &s->style, &s->thickness, &s->color,
X		&s->depth, &s->pen, &s->area_fill, &s->style_val, &fa, &ba);
X	if (n != 10) {
X	    put_msg(Err_incomp, "spline", line_no);
X	    free((char*)s);
X	    return(NULL);
X	    }
X	skip_comment(fp);
X	if (fa) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "spline", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    s->for_arrow = make_arrow(type, style, thickness, wid, ht);
X	    skip_comment(fp);
X	    }
X	if (ba) {
X	    line_no++;
X	    if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X		fprintf(stderr, Err_incomp, "spline", line_no);
X		return(NULL);
X		}
X	    skip_line(fp);
X	    s->back_arrow = make_arrow(type, style, thickness, wid, ht);
X	    skip_comment(fp);
X	    }
X
X	line_no++;
X
X	/* Read points */
X	if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
X	    put_msg(Err_incomp, "spline", line_no);
X	    free_splinestorage(s);
X	    return(NULL);
X	    };
X	if (NULL == (s->points = Point_malloc(p))) {
X	    put_msg(Err_mem);
X	    free_splinestorage(s);
X	    return(NULL);
X	    }
X	p->x = x; p->y = y;
X	for (c = 1;;) {
X	    if (fscanf(fp, "%d%d", &x, &y) != 2) {
X		put_msg(Err_incomp, "spline", line_no);
X		p->next = NULL;
X		free_splinestorage(s);
X		return(NULL);
X		};
X	    if (x == 9999) break;
X	    if (NULL == (Point_malloc(q))) {
X		put_msg(Err_mem);
X		free_splinestorage(s);
X		return(NULL);
X		}
X	    q->x = x;
X	    q->y = y;
X	    p->next = q;
X	    p = q;
X	    c++;
X	    }
X	p->next = NULL;
X	skip_line(fp);
X
X	if (normal_spline(s)) return(s);
X
X	line_no++;
X	skip_comment(fp);
X	/* Read controls */
X	if ((n = fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry)) != 4) {
X	    put_msg(Err_incomp, "spline", line_no);
X	    free_splinestorage(s);
X	    return(NULL);
X	    };
X	if (NULL == (s->controls = Control_malloc(cp))) {
X	    put_msg(Err_mem);
X	    free_splinestorage(s);
X	    return(NULL);
X	    }
X	cp->lx = lx; cp->ly = ly;
X	cp->rx = rx; cp->ry = ry;
X	while (--c) {
X	    if (fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry) != 4) {
X		put_msg(Err_incomp, "spline", line_no);
X		cp->next = NULL;
X		free_splinestorage(s);
X		return(NULL);
X		};
X	    if (NULL == (Control_malloc(cq))) {
X		put_msg(Err_mem);
X		cp->next = NULL;
X		free_splinestorage(s);
X		return(NULL);
X		}
X	    cq->lx = lx; cq->ly = ly;
X	    cq->rx = rx; cq->ry = ry;
X	    cp->next = cq;
X	    cp = cq;
X	    }
X	cp->next = NULL;
X
X	skip_line(fp);
X	return(s);
X	}
X
Xstatic F_text *
Xread_textobject(fp)
XFILE	*fp;
X{
X	F_text	*t;
X	int	n;
X	int	ignore = 0;
X	char	s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
X
X	if (NULL == (Text_malloc(t))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	t->next = NULL;
X	/* The text object is terminated by a CONTROL-A, so we read
X           everything up to the CONTROL-A and then read that character.
X           If we do not find the CONTROL-A on this line then this must
X           be a multi-line text object and we will have to read more. */
X	n = sscanf(buf,"%*d%d%d%d%d%d%d%f%d%d%d%d%d %[^\1]%[\1]",
X		&t->type, &t->font, &t->size, &t->pen,
X		&t->color, &t->depth, &t->angle,
X		&t->style, &t->height, &t->length, 
X		&t->base_x, &t->base_y, s, junk);
X	if (n != 13 && n != 14) {
X	    put_msg(Err_incomp, "text", line_no);
X	    free((char*)t);
X	    /* return(NULL); */
X	    }
X	if (n == 13) {
X	  /* Read in the remainder of the text object. */
X	  do {
X	    fgets(buf, BUF_SIZE, fp);
X	    line_no++;  		/* As is done in get_line */
X	    n = sscanf(buf,"%[^\1]%[\1]", s_temp, junk);
X	    /* Safety check */
X	    if (strlen(s)+1 + strlen(s_temp)+1 > BUF_SIZE) {
X	      /* Too many characters.  Ignore the rest. */
X	      ignore = 1;
X	    }
X	    if (!ignore)
X	      strcat(s, s_temp);
X	  } while (n == 1);
X	}
X	if (t->type > T_RIGHT_JUSTIFIED)
X		{
X		put_msg("Invalid text justification at line %d.",line_no);
X		return(NULL);
X		}
X	if (t->font >= NUMFONTS)
X		{
X		put_msg("Invalid text font (%d) at line %d.",t->font,line_no);
X		return(NULL);
X		}
X	if (strlen(s) == 0)
X		(void) strcpy(s," ");
X	t->cstring = (char*)calloc((unsigned)(strlen(s)+1), sizeof(char));
X	if (NULL == t->cstring) {
X	    put_msg(Err_mem);
X	    free((char*)t);
X	    return(NULL);
X	    }
X	(void) strcpy(t->cstring, s);
X	return(t);
X	}
X
Xget_line(fp)
XFILE	*fp;
X{
X	while (1) {
X	    if (NULL == fgets(buf, BUF_SIZE, fp)) {
X		return(-1);
X		}
X	    line_no++;
X	    if (*buf != '\n' && *buf != '#')	/* Skip empty and comment lines */
X		return(1);
X	    }
X	}
X
Xskip_comment(fp)
XFILE	*fp;
X{
X	char c;
X
X	while ((c = fgetc(fp)) == '#') skip_line(fp);
X	if (c != '#') ungetc(c, fp);
X	}
X
Xskip_line(fp)
XFILE	*fp;
X{
X	while (fgetc(fp) != '\n') {
X	    if (feof(fp)) return;
X	    }
X	}
END_OF_FILE
if test 16741 -ne `wc -c <'read.c'`; then
    echo shar: \"'read.c'\" unpacked with wrong size!
fi
# end of 'read.c'
fi
echo shar: End of archive 13 \(of 21\).
cp /dev/null ark13isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 21 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list