[comp.sources.unix] v23i016: Tools for creating TeX documents with portable graphics, Part03/06

rsalz@bbn.com (Rich Salz) (08/31/90)

Submitted-by: Micah Beck <beck@cs.cornell.edu>
Posting-number: Volume 23, Issue 16
Archive-name: transfig/part03

#! /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 3 (of 6)."
# Contents:  transfig/fig2dev/dev/genpic.c
#   transfig/fig2dev/dev/genpictex.c transfig/fig2dev/read.c
# Wrapped by beck@rocky on Thu May 17 15:56:12 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'transfig/fig2dev/dev/genpic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genpic.c'\"
else
echo shar: Extracting \"'transfig/fig2dev/dev/genpic.c'\" \(11817 characters\)
sed "s/^X//" >'transfig/fig2dev/dev/genpic.c' <<'END_OF_FILE'
X/* 
X *	genpic : PIC driver for fig2dev
X *
X *	Author: Conrad Kwok, UC Davis, 12/88
X *      Modified: Richard Auletta, George Mason Univ., 6/21/89
X *	Added code comments are marked with "rja".
X *      Added: Support for native pic arrowheads.
X *      Added: Support for arrowheads at both ends of lines, arc, splines.
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "object.h"
X#include "fig2dev.h"
X#include "picfonts.h"
X
Xvoid genpic_ctl_spline(), genpic_itp_spline();
Xvoid genpic_open_spline(), genpic_closed_spline();
X
X#define			TOP	10.5	/* top of page is 10.5 inch */
Xstatic double		ppi;
Xstatic int		CONV = 0;
X
Xvoid genpic_option(opt, optarg)
Xchar opt, *optarg;
X{
X	switch (opt) {
X
X	case 'f':		/* set default text font */
X	        {   int i;
X
X		    for ( i = 1; i <= MAXFONT + 1; i++ )
X			if ( !strcmp(optarg, fontnames[i]) ) break;
X
X		    if ( i > MAXFONT + 1 )
X			fprintf(stderr,
X				"warning: non-standard font name %s\n", optarg);
X		}
X		
X		fontnames[0] = fontnames[1] = optarg;
X		break;
X
X	case 's':
X		if (font_size <= 0 || font_size > MAXFONTSIZE) {
X			fprintf(stderr,
X				"warning: font size %d out of bounds\n", font_size);
X		}
X		break;
X
X	case 'm':
X	case 'L':
X		break;
X
X 	default:
X		put_msg(Err_badarg, opt, "pic");
X		exit(1);
X	}
X}
X
Xstatic double convy(a)
Xdouble	a;
X{
X	return((double)(CONV ? TOP-a : a));
X}
X
Xvoid genpic_start(objects)
XF_compound	*objects;
X{
X	int		coord_system;
X
X	ppi = objects->nwcorner.x/mag;
X	coord_system = objects->nwcorner.y;
X	if (coord_system == 2) CONV = 1;
X
X	fprintf(tfp, ".PS\n.ps %d\n", font_size);	/* PIC preamble */
X}
X
Xvoid genpic_end()
X{
X	fprintf(tfp, ".PE\n", font_size);	/* PIC ending */
X}
X
X/*
XThe line thickness is, unfortunately, multiple of pixel.
XOne pixel thickness is a little too thick on the hard copy
Xso I scale it with 0.7; i.e., it's a kludge.  The best way is
Xto allow thickness in fraction of pixel.
X
XNote that the current version of psdit (a ditroff to postcript filter)
Xwon't take the legitimate line thickness command.
X*/
Xstatic set_linewidth(w)
Xint	w;
X{
X	static int	cur_thickness = -1;
X
X	/*
X	if (w == 0) return;
X	if (w != cur_thickness) {
X	    cur_thickness = w;
X	    fprintf(tfp, "\"\\D't %.5fi'\"\n", 0.7 * cur_thickness / ppi);
X	    }
X	*/
X	}
X
Xstatic set_style(s, v)
Xint	s;
Xfloat	v;
X{
X	static float	style_val = -1;
X
X	if (s == DASH_LINE || s == DOTTED_LINE) {
X	    if (v == style_val) return;
X	    if (v == 0.0) return;
X	    style_val = v;
X	    fprintf(tfp, "dashwid = %.3fi\n", style_val/ppi);
X	    }
X	}
X
Xvoid genpic_line(l)
XF_line	*l;
X{
X	F_point		*p, *q;
X
X	set_linewidth(l->thickness);
X	set_style(l->style, l->style_val);
X	p = l->points;
X	q = p->next;
X	if (q == NULL) { /* A single point line */
X	    fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f\n",
X			p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
X	    return;
X	    }
X
X
X	if (l->style == DASH_LINE && l->style_val > 0.0)
X	    fprintf(tfp, "line dashed");
X	else if (l->style == DOTTED_LINE && l->style_val > 0.0)
X	    fprintf(tfp, "line dotted");
X	else
X	    fprintf(tfp, "line");
X
X	/*rja: Place arrowheads or lack there of on the line*/
X	if ((l->for_arrow) && (l->back_arrow))
X	    fprintf(tfp, " <-> from");
X	else if (l->back_arrow)
X	    fprintf(tfp, " <- from");
X	else if (l->for_arrow)
X	    fprintf(tfp, " -> from");
X        else
X	    fprintf(tfp, " from ");
X
X	fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
X	while (q->next != NULL) {
X	    p = q;
X	    q = q->next;
X	    fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
X	    }
X	fprintf(tfp, " %.3f,%.3f\n", q->x/ppi, convy(q->y/ppi));
X	}
X
Xvoid genpic_spline(s)
XF_spline	*s;
X{
X	if (int_spline(s))
X	    genpic_itp_spline(s);
X	else
X	    genpic_ctl_spline(s);
X	}
X
Xvoid genpic_ctl_spline(s)
XF_spline	*s;
X{
X	if (closed_spline(s))
X	    genpic_closed_spline(s);
X	else
X	    genpic_open_spline(s);
X	}
X
Xvoid genpic_open_spline(s)
XF_spline	*s;
X{
X	double		x1, y1, x2, y2;
X	F_point		*p, *q;
X
X	p = s->points;
X	x1 = p->x/ppi; y1 = convy(p->y/ppi);
X	p = p->next;
X	x2 = p->x/ppi; y2 = convy(p->y/ppi);
X
X
X	/* Pic's spline supports only solid line style */
X	/* set_linewidth(s->thickness); */
X
X	if (p->next == NULL) {
X	    fprintf(tfp, "line");
X
X           /*rja: Attach arrowhead as required */
X	    if ((s->for_arrow) && (s->back_arrow))
X	       fprintf(tfp, " <->");
X	    else if (s->back_arrow)
X	       fprintf(tfp, " <-");
X	    else if (s->for_arrow)
X	       fprintf(tfp, " ->");
X
X	    fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f\n", x1, y1, x2, y2);
X	    return;
X	    }
X
X	fprintf(tfp, "spline"); 
X
X           /*rja: Attach arrowhead as required */
X	    if ((s->for_arrow) && (s->back_arrow))
X	       fprintf(tfp, " <->");
X	    else if (s->back_arrow)
X	       fprintf(tfp, " <-");
X	    else if (s->for_arrow)
X	       fprintf(tfp, " ->");
X
X	fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);
X
X	for (q = p->next; q->next != NULL; p = q, q = q->next)
X	    fprintf(tfp, " to %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
X	fprintf(tfp, " to %.3f,%.3f\n", (x2=q->x/ppi), (y2=convy(q->y/ppi)));
X
X	}
X
Xvoid genpic_ellipse(e)
XF_ellipse	*e;
X{
X	set_linewidth(e->thickness);
X	fprintf(tfp, "ellipse at %.3f,%.3f wid %.3f ht %.3f\n",
X		e->center.x/ppi, convy(e->center.y/ppi),
X		2 * e->radiuses.x/ppi, 2 * e->radiuses.y/ppi);
X	}
X
X/*
XText is display on the screen with the base line starting at
X(base_x, base_y); some characters extend below this line.
XPic displays the center of the height of text at the given
Xcoordinate. HT_OFFSET is use to compensate all the above factors
Xso text position in fig 1.4 should be at the same position on
Xthe screen as on the hard copy.
X*/
X#define			HT_OFFSET	(0.2 / 72.0)
X
Xvoid genpic_text(t)
XF_text	*t;
X{
X	float	y;
X        char *tpos;
X	int all_default = 0;
X
X	/* all_default = all_default && t->font <= 0 && t->size <= 0 ; */
X
X	if (all_default)
X	  fprintf(tfp, "\"");
X	else
X	  fprintf(tfp, "\"\\s%d\\f%s", PICFONTSIZE(t->size), PICFONT(t->font) );
X
X        switch (t->type) {
X        case T_LEFT_JUSTIFIED:
X        case DEFAULT:
X            tpos = "ljust";
X            break;
X        case T_CENTER_JUSTIFIED:
X            tpos = "";
X            break;
X        case T_RIGHT_JUSTIFIED:
X            tpos = "rjust";
X            break;
X        default:
X            fprintf(stderr, "unknown text position type\n");
X            exit(1);
X        }    
X	y = convy(t->base_y/ppi) + PICFONTSIZE(t->size) * HT_OFFSET;
X
X	if (all_default)	
X		fprintf(tfp, "%s\" at %.3f,%.3f %s\n",
X			t->cstring, t->base_x/ppi, y, tpos);
X	else
X		fprintf(tfp, "%s\\fP\" at %.3f,%.3f %s\n",
X			t->cstring, t->base_x/ppi, y, tpos);
X	}
X
Xvoid genpic_arc(a)
XF_arc	*a;
X{
X	double		x, y;
X	double		cx, cy, sx, sy, ex, ey;
X
X	cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
X	sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
X	ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
X
X	set_linewidth(a->thickness);
X
X	    fprintf(tfp, "arc ");
X
X           /*rja: Attach arrowhead as required */
X	    if ((a->for_arrow) && (a->back_arrow))
X	       fprintf(tfp, " <->");
X	    else if (a->back_arrow)
X	       fprintf(tfp, " <-");
X	    else if (a->for_arrow)
X	       fprintf(tfp, " ->");
X
X
X	if (a->direction)
X	    fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f\n",
X			cx, cy, sx, sy, ex, ey);
X	else
X	    fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f cw\n",
X			cx, cy, sx, sy, ex, ey);
X
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((dx*dx + dy*dy));
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;
X	yc = -x*sina + y*cosa;
X	y = yb + arrowwid / 2;
X	xd = x*cosa + y*sina;
X	yd = -x*sina + y*cosa;
X	fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f to %.3f,%.3f\n",
X		xc, yc, x2, y2, xd, yd);
X	}
X
X#define		THRESHOLD	.05	/* inch */
X
Xquadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
Xdouble	a1, b1, a2, b2, a3, b3, a4, b4;
X{
X	double	x1, y1, x4, y4;
X	double	xmid, ymid;
X
X	x1 = a1; y1 = b1;
X	x4 = a4; y4 = b4;
X
X	xmid = (a2 + a3) / 2;
X	ymid = (b2 + b3) / 2;
X	if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD) {
X	    fprintf(tfp, "\tto %.3f,%.3f\\\n", xmid, ymid);
X	    }
X	else {
X	    quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
X			((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
X	    }
X
X	if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
X	    fprintf(tfp, "\tto %.3f,%.3f\\\n", x4, y4);
X	    }
X	else {
X	    quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
X			((a3+x4)/2), ((b3+y4)/2), x4, y4);
X	    }
X	}
X
Xvoid genpic_closed_spline(s)
XF_spline	*s;
X{
X	F_point	*p;
X	double	cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
X	double	x1, y1, x2, y2;
X
X	p = s->points;
X	x1 = p->x/ppi;  y1 = convy(p->y/ppi);
X	p = p->next;
X	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
X	cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
X
X	for (p = p->next; p != NULL; p = p->next) {
X	    fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
X	    x1 = x2;  y1 = y2;
X	    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
X	    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
X	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
X	    fprintf(tfp, "\n");
X	    cx1 = cx4;  cy1 = cy4;
X	    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
X	    }
X	x1 = x2;  y1 = y2;
X	p = s->points->next;
X	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
X	cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
X	fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
X	quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
X	fprintf(tfp, "\n");
X	}
X
Xvoid genpic_itp_spline(s)
XF_spline	*s;
X{
X	F_point		*p1, *p2, *pfirst;
X	F_control	*cp1, *cp2;
X	double		x1, x2, y1, y2;
X
X	p1 = s->points;
X	cp1 = s->controls;
X	cp2 = cp1->next;
X	x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
X
X         pfirst = p1->next;/*save first to test in loop*/
X	for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
X		p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
X
X	    fprintf(tfp, "line ");
X
X           /*rja: Attach arrowhead as required */
X
X	    if ((s->back_arrow) && (p2 == pfirst))
X	       fprintf(tfp, " <- ");
X	    else if ((s->for_arrow) && (p2->next == NULL))
X	       fprintf(tfp, " -> ");
X
X	    fprintf(tfp, " from %.3f,%.3f ", x2, y2);
X
X	    x1 = x2; y1 = y2;
X	    x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
X	    bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
X		(double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
X	    fprintf(tfp, "\n");
X	    }
X
X	}
X
Xbezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
Xdouble	a0, b0, a1, b1, a2, b2, a3, b3;
X{
X	double	x0, y0, x3, y3;
X	double	sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
X
X	x0 = a0; y0 = b0;
X	x3 = a3; y3 = b3;
X	if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD) {
X	    fprintf(tfp, "\tto %.3f,%.3f\\\n", x3, y3);
X	    }
X	else {
X	    tx = (a1 + a2) / 2;		ty = (b1 + b2) / 2;
X	    sx1 = (x0 + a1) / 2;	sy1 = (y0 + b1) / 2;
X	    sx2 = (sx1 + tx) / 2;	sy2 = (sy1 + ty) / 2;
X	    tx2 = (a2 + x3) / 2;	ty2 = (b2 + y3) / 2;
X	    tx1 = (tx2 + tx) / 2;	ty1 = (ty2 + ty) / 2;
X	    xmid = (sx2 + tx1) / 2;	ymid = (sy2 + ty1) / 2;
X
X	    bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
X	    bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
X	    }
X	}
X
Xstruct driver dev_pic = {
X     	genpic_option,
X	genpic_start,
X	genpic_arc,
X	genpic_ellipse,
X	genpic_line,
X	genpic_spline,
X	genpic_text,
X	genpic_end,
X	INCLUDE_TEXT
X};
END_OF_FILE
if test 11817 -ne `wc -c <'transfig/fig2dev/dev/genpic.c'`; then
    echo shar: \"'transfig/fig2dev/dev/genpic.c'\" unpacked with wrong size!
fi
# end of 'transfig/fig2dev/dev/genpic.c'
fi
if test -f 'transfig/fig2dev/dev/genpictex.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genpictex.c'\"
else
echo shar: Extracting \"'transfig/fig2dev/dev/genpictex.c'\" \(13702 characters\)
sed "s/^X//" >'transfig/fig2dev/dev/genpictex.c' <<'END_OF_FILE'
X/* 
X *	genpictex.C : PiCTeX driver for fig2dev
X *
X * 	Author Micah Beck, Cornell University, 4/88
X *	(beck@svax.cs.cornell.edu)
X*/
X#ifdef hpux
X#include <sys/types.h>
X#endif
X#include <sys/file.h>
X#include <stdio.h>
X#include <math.h>
X#include "pi.h"
X#include "object.h"
X#include "fig2dev.h"
X#include "texfonts.h"
X
Xextern char *strchr();
Xextern void fprintf();
Xextern double sin(), cos(), acos(), fabs();
X
Xvoid genpictex_ctl_spline(), genpictex_itp_spline();
X
Xstatic int		coord_system;
Xstatic double		dash_length = -1;
Xstatic int		line_style = SOLID_LINE;
Xstatic char 		*linethick = "0.7pt";
Xstatic char		*plotsymbol = "\\sevrm .";
X
Xstatic void genpictex_option(opt, optarg)
Xchar opt, *optarg;
X{
X	switch (opt) {
X
X		case 'f':			/* set default text font */
X	        {   int i;
X
X		    for ( i = 1; i <= MAXFONT + 1; i++ )
X			if ( !strcmp(optarg, fontnames[i]) ) break;
X
X		    if ( i > MAXFONT + 1 )
X			fprintf(stderr,
X				"warning: non-standard font name %s\n", optarg);
X		}
X		
X		    fontnames[0] = fontnames[1] = optarg;
X		    break;
X
X		case 'l':			/* set line thickness */
X		    linethick = optarg;
X		    break;
X
X		case 'p':			/* set plot symbol */
X		    plotsymbol = optarg;
X		    break;
X
X		case 's':
X		    if (font_size <= 0 || font_size > MAXFONTSIZE) {
X			fprintf(stderr,
X				"warning: font size %d out of bounds\n", font_size);
X		    }
X		    break;
X
X		case 'm':
X		case 'L':
X		    break;
X
X	default:
X		put_msg(Err_badarg, opt, "pictex");
X		exit(1);
X		break;
X	}
X}
X
X#define			TOP	10.5	/* top of page is 10.5 inch */
Xstatic double		ppi;
Xstatic int		CONV = 0;
X
Xstatic double convy(a)
Xdouble	a;
X{
X	return((double)(CONV ? TOP-a : a));
X}
X
Xvoid genpictex_start(objects)
XF_compound	*objects;
X{
X	fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);
X
X	coord_system = objects->nwcorner.y;
X	ppi = objects->nwcorner.x;
X	if (coord_system == 2) CONV = 1;
X
X	/* PiCTeX start */
X	fprintf(tfp, "\\mbox{\\beginpicture\n");
X	fprintf(tfp, "\\setcoordinatesystem units <%6.3fin,%6.3fin>\n",
X			mag, mag);
X	fprintf(tfp, "\\unitlength=%6.3fin\n", mag);
X	fprintf(tfp, "\\linethickness=%s\n", linethick);
X	fprintf(tfp, "\\setplotsymbol ({%s})\n", plotsymbol);
X	fprintf(tfp, "\\setlinear\n");
X}
X
Xvoid genpictex_end()
X{
X	/* PiCTeX ending */
X	fprintf(tfp, "\\linethickness=0pt\n");
X        fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
X		llx/ppi, convy(lly/ppi), urx/ppi, convy(ury/ppi));
X	fprintf(tfp, "\\endpicture}\n");
X}
X
Xstatic set_linewidth(w)
Xint	w;
X{
X	static int	cur_thickness = -1;
X
X	if (w == 0) return;
X	if (w != cur_thickness) {
X	    cur_thickness = w;
X/*	fprintf(tfp, "\\linethickness=%6.3fin\n",0.7 * cur_thickness);*/
X/* PIC  fprintf(tfp, "\"D't %.3fi'\"\n", 0.7 * cur_thickness);*/
X	    }
X	}
X
Xvoid genpictex_line(l)
XF_line	*l;
X{
X	F_point		*p, *q;
X
X	fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");
X
X	set_linewidth(l->thickness);
X	set_style(l->style, l->style_val);
X
X	p = l->points;
X	q = p->next;
X
X	if (q == NULL) { /* A single point line */
X	    fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
X			p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
X	    return;
X	    }
X	if (l->back_arrow)
X	    draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi,
X		convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi);
X	set_style(l->style, l->style_val);
X
X	while (q->next != NULL) {
X
X	    putline(p->x, p->y, q->x, q->y);
X	    p = q;
X	    q = q->next;
X	    }
X
X	putline(p->x, p->y, q->x, q->y);
X	if (l->for_arrow)
X	    draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi,
X		convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi);
X
X	if (l->area_fill && (int)l->area_fill != DEFAULT)
X		fprintf(stderr, "Line area fill not implemented\n");
X	}
X
X/* 
X * set_style - issue style commands as appropriate
X */
Xstatic set_style(style, dash_len)
Xint style;
Xdouble dash_len;
X{
X    switch (style) {
X	 case SOLID_LINE:
X	    if (line_style == SOLID_LINE) break;
X	    fprintf(tfp, "\\setsolid\n");
X	    break;
X
X	case DASH_LINE:
X	    if (line_style == DASH_LINE && dash_length == dash_len)
X		break;
X	    fprintf(tfp, "\\setdashes <%7.4fin>\n", dash_len/ppi);
X	    break;
X
X	case DOTTED_LINE:
X	    if (line_style == DOTTED_LINE)
X		break;
X	    fprintf(tfp, "\\setdots \n");
X	    break;
X	    }
X
X	line_style = style;
X	dash_length = dash_len;
X    }
X
X/*
X * putline - use rules if possible
X */
Xstatic putline (start_x, start_y, end_x, end_y)
Xint	start_x, start_y, end_x, end_y;
X{
X    if (line_style == SOLID_LINE &&
X	    ((start_x == end_x) || (start_y == end_y)))
X	fprintf(tfp, "\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
X		start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi));
X
X    else {
X	fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
X		start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi));
X	}
X}
X
X
Xvoid genpictex_spline(s)
XF_spline	*s;
X{
X	set_linewidth(s->thickness);
X	set_style(s->style, s->style_val);
X
X	if (int_spline(s))
X	    genpictex_itp_spline(s);
X	else
X	    genpictex_ctl_spline(s);
X
X	if (s->area_fill && (int)s->area_fill != DEFAULT)
X		fprintf(stderr, "Spline area fill not implemented\n");
X}
X
Xvoid genpictex_ellipse(e)
XF_ellipse	*e;
X{
X	fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");
X
X	set_linewidth(e->thickness);
X	set_style(e->style, e->style_val);
X
X	if ((e->area_fill == BLACK_FILL) && (e->radiuses.x == e->radiuses.y))
X 		fprintf(tfp, "\\put{\\circle*{%6.3f}} at %6.3f %6.3f\n",
X		    2*e->radiuses.x/ppi,
X		    (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi));
X
X	else {
X
X		fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n",
X		    e->radiuses.x/ppi, e->radiuses.y/ppi);
X		fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n",
X		    (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi),
X		    e->center.x/ppi, convy(e->center.y/ppi));
X		if (e->area_fill && (int)e->area_fill != DEFAULT)
X			fprintf(stderr, "Ellipse area fill not implemented\n");
X		}
X	}
X
X#define			HT_OFFSET	(0.2 / 72.0)
X
Xvoid genpictex_text(t)
XF_text	*t;
X{
X	double	x, y;
X	char *tpos, *cp;
X
X        fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");
X
X	x = t->base_x/ppi;
X	y = convy(t->base_y/ppi);
X
X	switch (t->type) {
X
X	    case T_LEFT_JUSTIFIED:
X	    case DEFAULT:
X	    	tpos = "[lB]";
X		break;
X
X	    case T_CENTER_JUSTIFIED:
X	    	tpos = "[B]";
X		break;
X
X	    case T_RIGHT_JUSTIFIED:
X	    	tpos = "[rB]";
X		break;
X
X	    default:
X		fprintf(stderr, "Text incorrectly positioned\n");
X		return;
X	    }
X
X	fprintf(tfp, "\\put {\\%s%s ",
X		TEXFONTSIZE(t->size), TEXFONT(t->font));
X
X	if (t->font && t->font !=DEFAULT)
X
X		/* this loop escapes characters "$&%#_{}" */
X		/* and deleted characters "~^\" */
X		for(cp = t->cstring; *cp; cp++) {
X	      	    if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp);
X	      	    if (strchr("~^\\", *cp))
X			fprintf(stderr,
X				"Bad character in text object '%c'\n" ,*cp);
X		    else
X			(void)fputc(*cp, tfp);
X	      	}
X	else 
X		fprintf(tfp, "%s", t->cstring);
X
X 	fprintf(tfp, "} %s at %6.3f %6.3f\n",
X	    tpos, x, y);
X	}
X
Xvoid genpictex_arc(a)
XF_arc	*a;
X{
X	double		x, y;
X	double		cx, cy, sx, sy, ex, ey;
X	double		dx1, dy1, dx2, dy2, r1, r2, th1, th2, theta;
X
X	set_linewidth(a->thickness);
X	set_style(a->style, a->style_val);
X
X	cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
X	sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
X	ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
X
X	if (a->for_arrow) {
X	    arc_tangent(cx, cy, ex, ey, a->direction, &x, &y);
X	    draw_arrow_head(x, y, ex, ey,
X			a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
X	    }
X	if (a->back_arrow) {
X	    arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y);
X	    draw_arrow_head(x, y, sx, sy,
X			a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
X	    }
X
X	dx1 = sx - cx;
X	dy1 = sy - cy;
X	dx2 = ex - cx;
X	dy2 = ey - cy;
X	    
X	rtop(dx1, dy1, &r1, &th1);
X	rtop(dx2, dy2, &r2, &th2);
X	theta = th2 - th1;
X	if (theta > 0) theta -= 2*M_PI;
X
X	set_linewidth(a->thickness);
X
X	if (a->direction)
X		fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
X			360+(180/M_PI * theta), sx, sy, cx, cy);
X	else
X		fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
X			-180/M_PI * theta, ex, ey, cx, cy);
X
X	if (a->area_fill && (int)a->area_fill != DEFAULT)
X		fprintf(stderr, "Arc area fill not implemented\n");
X	}
X
X
X
X/*
X * rtop - rectangular to polar conversion
X */
Xstatic rtop(x, y, r, th)
Xdouble x, y, *r, *th;
X{
X	*r = hypot(x,y);
X	*th = acos(x/(*r));
X
X	if (y < 0) *th = 2*M_PI - *th;
X}
X
Xstatic arc_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
Xstatic draw_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	int style;
X	double dash;
X
X        fprintf(tfp, "%%\n%% arrow head\n%%\n");
X
X	dx = x2 - x1;  dy = y1 - y2;
X	l = hypot(dx, dy);
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;
X	yc = -x*sina + y*cosa;
X	y = yb + arrowwid / 2;
X	xd = x*cosa + y*sina;
X	yd = -x*sina + y*cosa;
X
X	/* save line style and set to solid */
X	style = line_style;
X	dash = dash_length;
X	set_style(SOLID_LINE, 0.0);
X
X	fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f /\n%%\n",
X		xc, yc, x2, y2, xd, yd);
X
X	/* restore line style */
X	set_style(style, dash);
X	}
X
X#define		THRESHOLD	.05	/* inch */
X
Xstatic quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
Xdouble	a1, b1, a2, b2, a3, b3, a4, b4;
X{
X	double	x1, y1, x4, y4;
X	double	xmid, ymid;
X
X	x1 = a1; y1 = b1;
X	x4 = a4; y4 = b4;
X	xmid = (a2 + a3) / 2;
X	ymid = (b2 + b3) / 2;
X	if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
X	    fprintf(tfp, "\t%6.3f %6.3f\n", xmid, ymid);
X
X	else {
X	    quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
X			((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
X	    }
X
X	if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
X	    fprintf(tfp, "\t%6.3f %6.3f\n", x4, y4);
X
X	else {
X	    quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
X			((a3+x4)/2), ((b3+y4)/2), x4, y4);
X	    }
X	}
X
Xstatic void genpictex_ctl_spline(s)
XF_spline	*s;
X{
X	F_point	*p;
X	double	cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
X	double	x1, y1, x2, y2;
X
X    	fprintf(tfp, "%%\n%% Fig CONTROL PT SPLINE\n%%\n");
X
X	p = s->points;
X	x1 = p->x/ppi;  y1 = convy(p->y/ppi);
X	p = p->next;
X	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
X	cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
X
X	if (closed_spline(s)) {
X	    fprintf(tfp, "%% closed spline\n%%\n");
X	    fprintf(tfp, "\\plot\t%6.3f %6.3f \n ", cx1, cy1);
X	    }
X	else {
X	    fprintf(tfp, "%% open spline\n%%\n");
X	    if (s->back_arrow)
X	        draw_arrow_head(cx1, cy1, x1, y1,
X			s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
X	    fprintf(tfp, "\\plot\t%6.3f %6.3f %6.3f %6.3f\n ",
X		x1, y1, cx1, cy1);
X	    }
X
X	for (p = p->next; p != NULL; p = p->next) {
X	    x1 = x2;  y1 = y2;
X	    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
X	    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
X	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
X	    cx1 = cx4;  cy1 = cy4;
X	    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
X	    }
X	x1 = x2;  y1 = y2;
X	p = s->points->next;
X	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
X	cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
X	cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
X	if (closed_spline(s)) {
X	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
X	    fprintf(tfp, "\t/\n");
X	    }
X	else {
X	    fprintf(tfp, "\t /\n\\plot %6.3f %6.3f %6.3f %6.3f /\n",
X		cx1, cy1, x1, y1);
X	    if (s->for_arrow)
X	    	draw_arrow_head(cx1, cy1, x1, y1,
X			s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
X	    }
X
X	}
X
Xstatic void genpictex_itp_spline(s)
XF_spline	*s;
X{
X	F_point		*p1, *p2;
X	F_control	*cp1, *cp2;
X	double		x1, x2, y1, y2;
X
X	p1 = s->points;
X	cp1 = s->controls;
X	x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
X
X	if (s->back_arrow)
X	    draw_arrow_head(cp1->rx/ppi, convy(cp1->ry/ppi), x2, y2,
X		s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
X
X	fprintf(tfp, "\\plot %6.3f %6.3f ", x2, y2);
X	for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
X		p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
X	    x1 = x2; y1 = y2;
X	    x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
X	    bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
X		(double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
X	    }
X	fprintf(tfp, "\t/\n");
X
X	if (s->for_arrow)
X	    draw_arrow_head(cp1->lx/ppi, convy(cp1->ly/ppi), x2, y2,
X		s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
X	}
X
Xstatic bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
Xdouble	a0, b0, a1, b1, a2, b2, a3, b3;
X{
X	double	x0, y0, x3, y3;
X	double	sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
X
X	x0 = a0; y0 = b0;
X	x3 = a3; y3 = b3;
X	if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
X	    fprintf(tfp, "\t%6.3f %6.3f\n", x3, y3);
X
X	else {
X	    tx = (a1 + a2) / 2;		ty = (b1 + b2) / 2;
X	    sx1 = (x0 + a1) / 2;	sy1 = (y0 + b1) / 2;
X	    sx2 = (sx1 + tx) / 2;	sy2 = (sy1 + ty) / 2;
X	    tx2 = (a2 + x3) / 2;	ty2 = (b2 + y3) / 2;
X	    tx1 = (tx2 + tx) / 2;	ty1 = (ty2 + ty) / 2;
X	    xmid = (sx2 + tx1) / 2;	ymid = (sy2 + ty1) / 2;
X
X	    bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
X	    bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
X	    }
X	}
X
Xstruct driver dev_pictex = {
X     	genpictex_option,
X	genpictex_start,
X	genpictex_arc,
X	genpictex_ellipse,
X	genpictex_line,
X	genpictex_spline,
X	genpictex_text,
X	genpictex_end,
X	EXCLUDE_TEXT
X};
X
END_OF_FILE
if test 13702 -ne `wc -c <'transfig/fig2dev/dev/genpictex.c'`; then
    echo shar: \"'transfig/fig2dev/dev/genpictex.c'\" unpacked with wrong size!
fi
# end of 'transfig/fig2dev/dev/genpictex.c'
fi
if test -f 'transfig/fig2dev/read.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'transfig/fig2dev/read.c'\"
else
echo shar: Extracting \"'transfig/fig2dev/read.c'\" \(16332 characters\)
sed "s/^X//" >'transfig/fig2dev/read.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X#include <errno.h>
X#include "alloc.h"
X#include "object.h"
X
X#ifdef hpux
X#define bzero(s,n) memset((s),'\0',(n))
X#endif
X
X#ifdef gould
Xextern int            errno;
X#endif
X
Xextern void		fprintf(), ungetc();
Xextern F_arrow		*make_arrow();
Xextern char		*calloc();
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 = 0;
Xint			num_object;
Xint			tfx_flag;	/* TFX compatible */
Xint			x_flag;		/* xfig1.4X or 2.0 compatible */
Xint			v2_flag;	/* xfig2.0  compatible */
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	else if (err == ENAMETOOLONG)
X	    put_msg("File name \"%s\" is too long", file);
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 cooridnate system (coord_sys) are
Xstored in obj->nwcorner.x and obj->nwcorner.x respectively.
X**********************************************************/
X
Xread_fig(file_name, obj)
Xchar		*file_name;
XF_compound	*obj;
X{
X	FILE		*fp;
X
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	char		c;
X	int		status;
X
X	num_object = 0;
X	c = fgetc(fp);
X	if (feof(fp)) return(-2);
X	ungetc(c, fp);
X	bzero((char*)obj, COMOBJ_SIZE);
X	if (c == '#')
X	    status = read_objects(fp, obj);
X	else
X	    status = read_1_3_objects(fp, obj);
X	(void)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	bzero((char*)obj, COMOBJ_SIZE);
X	(void)fgets(buf, BUF_SIZE, fp);	/* get the version line */
X	tfx_flag = (!strncmp(&buf[strlen(buf)-3], "TFX", 3)); /* check for TFX */
X	v2_flag = (!strncmp(buf, "#FIG 2", 6));	/* v2.0 and later have extra
X						   field for arc_box radius */
X	x_flag = v2_flag || (!strncmp(buf, "#FIG 1.4X", 9));	/* non-TFX */
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	double	thickness, wid, ht;
X
X	if (NULL == (Arc_malloc(a))) {
X	    put_msg(Err_mem);
X	    return(NULL);
X	    }
X	a->pen = NULL;
X	a->area_fill = NULL;
X	a->for_arrow = NULL;
X	a->back_arrow = NULL;
X	a->next = NULL;
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d\n",
X		&a->type, &a->style, &a->thickness, 
X		&a->color, &a->depth, &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%lf%lf%lf", &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%lf%lf%lf", &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	Compound_malloc(com);
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	Ellipse_malloc(e);
X	e->area_fill = NULL;
X	e->pen = NULL;
X	e->next = NULL;
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%lf%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	double	thickness, wid, ht;
X
X	Line_malloc(l);
X	l->points = NULL;
X	l->pen = NULL;
X	l->area_fill = NULL;
X	l->for_arrow = NULL;
X	l->back_arrow = NULL;
X	l->next = NULL;
X
X	sscanf(buf,"%*d%d",&l->type);	/* get the line type */
X	/* 2.0 or later has separate radius parm for arc-box corners */
X	if (l->type == T_ARC_BOX && v2_flag)
X	    {
X	    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%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, &fa, &ba);
X	    }
X	/* old format uses pen for radius of arc-box corners */
X	else
X	    {
X	    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%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	    if (l->type == T_ARC_BOX)
X		{
X		l->radius = (int) l->pen;
X		l->pen = 0;
X		}
X	    else
X		l->radius = 0;
X	    }
X	if ((!v2_flag && n!=10) || 
X	     (v2_flag && (l->type == T_ARC_BOX && n!=11) ||
X			 (l->type != T_ARC_BOX && n!=10))) {
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%lf%lf%lf", &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%lf%lf%lf", &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	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	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	double		thickness, wid, ht;
X	double		lx, ly, rx, ry;
X
X	Spline_malloc(s);
X	s->points = NULL;
X	s->controls = NULL;
X	s->pen = NULL;
X	s->area_fill = NULL;
X	s->for_arrow = NULL;
X	s->back_arrow = NULL;
X	s->next = NULL;
X
X	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%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%lf%lf%lf", &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%lf%lf%lf", &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	/* 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	skip_comment(fp);
X	/* Read controls */
X	if ((n = fscanf(fp, "%lf%lf%lf%lf", &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, "%lf%lf%lf%lf", &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, ignore = 0;
X	char	s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
X
X	Text_malloc(t);
X	t->font = NULL;
X	t->size = NULL;
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%lf%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 != 14) && (n != 13)) {
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 (strlen(s) == 0) (void)strcpy(s, " ");
X	t->cstring = (char*)calloc((unsigned)(strlen(s)), 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+1);
X 	if (!tfx_flag && !x_flag) 
X 		t->size = 0;	/* 1.4(not X) and earlier had garbage in size*/
X	if (t->style > 1) {
X		put_msg(
X		    "Text styles not supported; default font substituted\n");
X		t->style = t->font = DEFAULT;
X	}
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 != '#') return(1);
X			/* Skip empty and comment lines */
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 16332 -ne `wc -c <'transfig/fig2dev/read.c'`; then
    echo shar: \"'transfig/fig2dev/read.c'\" unpacked with wrong size!
fi
# end of 'transfig/fig2dev/read.c'
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.