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

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

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

#! /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 4 (of 6)."
# Contents:  transfig/fig2dev/dev/genlatex.c
#   transfig/fig2dev/dev/genps.c
# Wrapped by beck@rocky on Thu May 17 15:56:13 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'transfig/fig2dev/dev/genlatex.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genlatex.c'\"
else
echo shar: Extracting \"'transfig/fig2dev/dev/genlatex.c'\" \(20332 characters\)
sed "s/^X//" >'transfig/fig2dev/dev/genlatex.c' <<'END_OF_FILE'
X/* 
X *	genlatex.c : LaTeX driver for fig2dev
X *
X *	Author: Frank Schmuck, Cornell University 6/88
X * 	Converted from fig2latex 5/89 by Micah Beck
X *
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 "object.h"
X#include "fig2dev.h"
X#include "texfonts.h"
X
Xextern char *strchr();
Xextern void printf(), fprintf();
Xextern double rad2deg, sin(), cos(), acos(), fabs(), atan();
X
X#ifdef hpux
X#define rint(a) floor((a)+0.5)     /* close enough? */
X#endif
X
X#ifdef gould
X#define rint(a) floor((a)+0.5)     /* close enough? */
X#endif
X
X/* 
X *  Installation dependent constants:
X *
X *  THINDOT	latex command for generating a dot if line width = \thinlines
X *  THICKDOT	latex command for generating a dot if line width = \thicklines
X *  MIN_LEN	shortest slanted line that latex can produce; shorter lines will
X *		we translated into a sequence of dots generated by \multiput.
X *  THICK_LDOT	latex command for generating the dot for making short slanted
X *		lines if line width = \thinlines
X *  THIN_LDOT	...  if line width = \thicklines
X */
X#define THICKDOT	"\\tenrm ."
X#define THINDOT		"\\sevrm ."
Xdouble	THIN_XOFF =	(0.1/72.0);
Xdouble	THIN_YOFF =	(0.7/72.0);
Xdouble	THICK_XOFF =	(0.4/72.0);
Xdouble	THICK_YOFF =	(0.6/72.0);
X#define THICK_LDOT	"\\sevrm ."
X#define THIN_LDOT	"\\fivrm ."
Xdouble	THIN_LXOFF =	(0.1/72.0);
Xdouble	THIN_LYOFF =	(0.7/72.0);
Xdouble	THICK_LXOFF =	(0.4/72.0);
Xdouble	THICK_LYOFF =	(0.6/72.0);
X#define MIN_LEN		(13.0/72.0)	/* 13  points */
X
X/*
X *  other constants and macros
X */
X#define TOP		840
X#define THINLINES	1
X#define THICKLINES	2
X
X/*
X * Cornell DVI-to-IP has trouble with circles of radius greater than 8pt.
X */
X#ifdef CORNELL
X#define MAXCIRCLEDIA	16
X#else
X#define MAXCIRCLEDIA	80
X#endif
X#define MAXCIRCLERAD	((MAXCIRCLEDIA-0.5)/(2*72.27))
X
X#define	SWAP(x,y)	{tmp=x; x=y; y=tmp;}
X#define TRANS(x,y)		(*translate_coordinates)(&x,&y)
X#define TRANS2(x1,y1,x2,y2)	(*translate_coordinates)(&x1,&y1); \
X				(*translate_coordinates)(&x2,&y2)
X#define TRANSD(x,y)		(*translate_coordinates_d)(&x,&y)
X#define	MIN(x,y)	(((x) <= (y))? (x): (y))
X#define	MAX(x,y)	(((x) >= (y))? (x): (y))
X#define	ABS(x)		(((x) >= 0)? (x): -(x))
X#define round(x)	((int) ((x) + ((x >= 0)? 0.5: -0.5)))
X#define round4(x)	((round(10000.0*(x))/10000.0))
X
Xchar		thindot [] = THINDOT;
Xchar		thickdot[] = THICKDOT;
Xchar		thin_ldot [] = THIN_LDOT;
Xchar		thick_ldot[] = THICK_LDOT;
X
Xint		coord_system;
Xint		verbose = 0;
Xdouble		dash_mag = 1.0;
Xint		thick_width = 1;
Xdouble		tolerance = 2.0;
Xdouble		arc_tolerance = 1.0;
Xint		(*translate_coordinates)() = NULL;
Xint		(*translate_coordinates_d)() = NULL;
Xdouble		unitlength;
Xint		cur_thickness = -1;
Xdouble		ldot_diameter = 1.0/72.0;
Xchar		*dot_cmd = thindot;
Xchar		*ldot_cmd = thin_ldot;
Xdouble		dot_xoffset;
Xdouble		dot_yoffset;
Xdouble		ldot_xoffset;
Xdouble		ldot_yoffset;
X
Xstatic translate1(xp, yp)
Xint	*xp, *yp;
X{
X	*xp = *xp + 1;
X	*yp = *yp + 1;
X	}
X
Xstatic translate2(xp, yp)
Xint	*xp, *yp;
X{
X	*xp = *xp + 1;
X	*yp = TOP - *yp -1;
X	}
X
Xstatic translate1_d(xp, yp)
Xdouble	*xp, *yp;
X{
X	*xp = *xp + 1.0;
X	*yp = *yp + 1.0;
X	}
X
Xstatic translate2_d(xp, yp)
Xdouble	*xp, *yp;
X{
X	*xp = *xp + 1.0;
X	*yp = (double)TOP - *yp -1.0;
X	}
X
Xvoid genlatex_option(opt, optarg)
Xchar opt, *optarg;
X{
X    switch (opt) {
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 thin/thick line threshold */
X	    thick_width = atoi(optarg);
X	    break;
X
X	case 'd':
X	    dash_mag = atof(optarg);	/* set dash magnification */
X	    break;
X
X	case 'v':
X	    verbose = 1;		/* verbose mode */
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, "latex");
X	    exit(1);
X	    break;
X	}
X}
X
Xvoid genlatex_start(objects)
XF_compound	*objects;
X{
X	int tmp;
X
X	fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);
X
X	coord_system = objects->nwcorner.y;
X 	unitlength = mag/objects->nwcorner.x;
X
X	switch (coord_system) {
X	    case 1:
X		translate_coordinates = translate1;
X		translate_coordinates_d = translate1_d;
X		break;
X	    case 2:
X		translate_coordinates = translate2;
X		translate_coordinates_d = translate2_d;
X		break;
X	    default:
X		fprintf(stderr, "Wrong coordinate system; cannot continue\n");
X		return;
X	    }
X
X	TRANS2(llx, lly, urx, ury);
X	if (llx > urx) SWAP(llx, urx)
X	if (lly > ury) SWAP(lly, ury)
X
X	/* LaTeX start */
X	fprintf(tfp, "\\setlength{\\unitlength}{%.4fin}%%\n",
X						round4(unitlength));
X	fprintf(tfp, "\\begin{picture}(%d,%d)(%d,%d)\n",
X	 				 urx-llx, ury-lly, llx, lly);
X}
X
Xvoid genlatex_end()
X{
X	/* LaTeX ending */
X	fprintf(tfp, "\\end{picture}\n");
X}
X
Xstatic set_linewidth(w)
Xint	w;
X{
X	int		latex_w;
X
X	if (w == 0) return;
X	/* latex only knows thin lines or thick lines */
X	latex_w = (w >= thick_width)? THICKLINES: THINLINES;
X	if (latex_w != cur_thickness) {
X	    cur_thickness = latex_w;
X	    if (cur_thickness == THICKLINES) {
X		fprintf(tfp, "\\thicklines\n");
X		dot_cmd = thickdot;
X		dot_xoffset = round4(THICK_XOFF/unitlength);
X		dot_yoffset = round4(THICK_YOFF/unitlength);
X		ldot_cmd = thick_ldot;
X		ldot_xoffset = round4(THICK_LXOFF/unitlength);
X		ldot_yoffset = round4(THICK_LYOFF/unitlength);
X		}
X	    else {
X		fprintf(tfp, "\\thinlines\n");
X		dot_cmd = thin_ldot;
X		dot_xoffset = round4(THIN_XOFF/unitlength);
X		dot_yoffset = round4(THIN_YOFF/unitlength);
X		ldot_cmd = thin_ldot;
X		ldot_xoffset = round4(THIN_LXOFF/unitlength);
X		ldot_yoffset = round4(THIN_LYOFF/unitlength);
X		}
X	    }
X	}
X
Xvoid genlatex_line(l)
XF_line	*l;
X{
X	F_point		*p, *q;
X	int		x, y, llx, lly, urx, ury, arrow;
X
X	if (verbose) fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");
X
X	set_linewidth(l->thickness);
X
X	p = l->points;
X	q = p->next;
X
X	if (q == NULL) { /* A single point line */
X	    x = p->x; y = p->y;
X	    TRANS(x, y);
X	    fprintf(tfp, "\\put(%3d,%3d){\\makebox(%.4f,%.4f){%s}}\n",
X	      x, y, dot_xoffset, dot_yoffset, dot_cmd);
X	    return;
X	    }
X
X	if (l->type == T_BOX) { /* A box */
X	    x = p->x; y = p->y;
X	    TRANS(x, y);
X	    llx = urx = x;
X	    lly = ury = y;
X	    while (q != NULL) {
X		x = q->x; y = q->y;
X		TRANS(x, y);
X		if (x < llx) llx = x;
X		if (y < lly) lly = y;
X		if (x > urx) urx = x;
X		if (y > ury) ury = y;
X		q = q->next;
X		}
X	    put_box (llx, lly, urx, ury, l->style, l->style_val);
X	    return;
X	    }
X
X	while (q != NULL) {
X	    arrow = 0;
X	    if (l->for_arrow  &&  q->next == NULL)
X		arrow = 1;
X	    if (l->back_arrow  &&  p == l->points)
X		arrow = (arrow)? 2: -1;
X	    single_line(p->x, p->y, q->x, q->y, arrow, l->style, l->style_val);
X	    p = q;
X	    q = q->next;
X	    }
X
X	if (l->area_fill && (int)l->area_fill != DEFAULT)
X		fprintf(stderr, "Line area fill not implemented\n");
X	}
X
Xstatic single_line (x1, y1, x2, y2, arrow, style, val)
Xint	x1, y1, x2, y2, arrow, style;
Xdouble	val;
X{
X	int    dx, dy, sx, sy;
X	double l, m, deviation;
X
X	TRANS2(x1, y1, x2, y2);
X	dx = x2-x1;
X	dy = y2-y1;
X	/*** compute direction vector ***/
X	get_slope(dx, dy, &sx, &sy, arrow);
X	/*** compute line length in x-direction ***/
X	if (sx == 0) {
X	    l = (double)abs(dy);
X	} else {
X	    m = (double)abs(sy) / (double)abs(sx);
X	    l = ((double)abs(dx) + m*(double)abs(dy)) / (1.0 + m*m);
X	    deviation = fabs(l-abs(dx)) + fabs(m*l-abs(dy));
X	    if (deviation > tolerance)
X		fprintf(stderr,
X		  "Not a LaTeX slope (%d, %d), deviation %.1f pixels\n",
X		  dx, dy, deviation);
X	}
X	l = round4(l);
X	/*** output letex command ***/
X	switch (style) {
X	    case SOLID_LINE:
X		put_solidline(x1, y1, sx, sy, l, arrow);
X		break;
X	    case DASH_LINE:
X		put_dashline(x1, y1, sx, sy, l, arrow, val);
X		break;
X	    case DOTTED_LINE:
X		put_dotline(x1, y1, sx, sy, l, arrow, val);
X		break;
X	    }
X	}
X
X
X/*
X * draw box
X */
Xstatic put_box (llx, lly, urx, ury, style, val)
Xint	llx, lly, urx, ury, style;
Xdouble	val;
X{
X	int	dlen;
X
X	switch (style) {
X	    case SOLID_LINE:
X		fprintf(tfp, "\\put(%3d,%3d){\\framebox(%d,%d){}}\n",
X		  llx, lly, urx-llx, ury-lly);
X		break;
X	    case DASH_LINE:
X		dlen = round(val*dash_mag);
X		fprintf(tfp, "\\put(%3d,%3d){\\dashbox{%d}(%d,%d){}}\n",
X		  llx, lly, dlen, urx-llx, ury-lly);
X		break;
X	    case DOTTED_LINE:
X		put_dotline (llx, lly, 1, 0, (double)(urx-llx), 0, val);
X		put_dotline (llx, ury, 1, 0, (double)(urx-llx), 0, val);
X		put_dotline (llx, lly, 0, 1, (double)(ury-lly), 0, val);
X		put_dotline (urx, lly, 0, 1, (double)(ury-lly), 0, val);
X		break;
X	    }
X	return;
X	}
X
X/*
X * draw a solid line given latex slope
X */
Xstatic put_solidline (x, y, sx, sy, l, arrow)
Xint	x, y, sx, sy, arrow;
Xdouble	l;
X{
X	double	cosine;		/* cosine of line angle */
X	double	dx, dy;
X	int	x2, y2, n;
X
X	if (sx) {
X	    cosine = (double)abs(sx) / hypot((double)sx, (double)sy);
X	    x2 = (sx >= 0)? x + round(l): x - round(l);
X	    y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx);
X	    }
X	else {
X	    cosine = 1.0;
X	    x2 = x;
X	    y2 = (sy >= 0)? y + round(l): y - round(l);
X	    }
X	if (sx == 0  ||  sy == 0  ||  (l/cosine)*unitlength >= MIN_LEN) {
X	    switch (arrow) {
X	    case 0:  /* simple line */
X		fprintf(tfp, "\\put(%3d,%3d){\\line(%2d,%2d)", x, y, sx,sy);
X		break;
X	    case 1:  /* forward arrow */
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x, y, sx,sy);
X		break;
X	    case -1: /* backward arrow */
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x2, y2, -sx,-sy);
X		break;
X	    case 2:  /* double arrow */
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){  0}}\n", x,y,-sx,-sy);
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x, y, sx, sy);
X		break;
X		}
X	    if (l == floor(l))
X		fprintf(tfp, "{%3.0f}}\n", l);
X	    else
X		fprintf(tfp, "{%7.3f}}\n", l);
X	    }
X	else {
X	    n = 2 * (l/cosine) / (ldot_diameter/unitlength);
X	    fprintf(stderr, "Line too short; will do %d dots\n", n);
X	    dx = l / (double)n;
X	    if (sx < 0) dx = -dx;
X	    dy = dx * (double)sy / (double)sx;
X	    fprintf(tfp, 
X	      "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\makebox(%.4f,%.4f){%s}}\n",
X	      x, y, dx, dy, n+1, ldot_xoffset, ldot_yoffset, ldot_cmd);
X	    if (arrow == 1  ||  arrow == 2)  /* forward arrow */
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2,y2, sx,sy);
X	    if (arrow == -1  ||  arrow == 2) /* backward arrow */
X		fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x,y, -sx,-sy);
X	    }
X	}
X
X/*
X * draw a dashed line given latex slope
X */
Xstatic put_dashline (x, y, sx, sy, l, arrow, val)
Xint	x, y, sx, sy, arrow;
Xdouble	l;
Xdouble	val;
X{
X	double	cosine;		/* cosine of line angle */
X	double	nd;		/* number of dashes and gaps fitting on line */
X	int	n;		/* nd rounded to the nearest odd integer */
X	double	dl;		/* actual x-length of each dash */
X	double	dg;		/* actual x-length of each gap */
X	double	dx, dy;		/* step between dashes */
X	int	x2, y2;
X
X
X	if (sx) {
X	    cosine = (double)abs(sx) / hypot((double)sx, (double)sy);
X	    x2 = (sx >= 0)? x + round(l): x - round(l);
X	    y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx );
X	    }
X	else {
X	    cosine = 1.0;
X	    x2 = x;
X	    y2 = (sy >= 0)? y + round(l): y - round(l);
X	    }
X	/*** compute number of dashes, length of dashes and gaps ***/
X	nd = l / (val*dash_mag*cosine);
X	n = (int) (rint((nd + 1.0)/2.0)*2 - 1);
X	dl = l / (double)n;
X	if (sx  &&  sy  &&  (dl/cosine)*unitlength < MIN_LEN) {
X	    fprintf(stderr, "Dash too small; using larger dash\n");
X	    dl = MIN_LEN/unitlength * cosine;
X	    nd = l / dl;
X	    n = (int) (rint((nd + 1.0)/2.0)*2 - 1);
X	    }
X	if (2*dl >= l  ||  (sx  &&  sy  &&  (l/cosine)*unitlength < MIN_LEN)) {
X	    fprintf(stderr, "Dashed line too short; drawing solid line\n");
X	    put_solidline (x, y, sx, sy, l, arrow);
X	    return;
X	    }
X	dg = (l - (n/2+1)*dl) / (double)(n/2);
X	if (sx) {
X	    dx = dl+dg;
X	    if (sx < 0) dx = -dx;
X	    dy = dx * (double)sy / (double)sx;
X	    }
X	else {
X	    dx = 0.0;
X	    dy = dl+dg;
X	    if (sy < 0) dy = -dy;
X	    }
X	/*** draw dashed line ***/
X	fprintf(tfp, "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\line(%2d,%2d){%7.3f}}\n",
X	    x, y, dx, dy, n/2+1, sx, sy, dl);
X	/*** draw arrow heads ***/
X	if (arrow == 1  ||  arrow == 2)
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2, y2, sx, sy);
X	if (arrow == -1  ||  arrow == 2)
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x, y, -sx, -sy);
X	}
X
X/*
X * draw a dotted line given latex slope
X */
Xstatic put_dotline (x, y, sx, sy, l, arrow, val)
Xint	x, y, sx, sy, arrow;
Xdouble	l;
Xdouble	val;
X{
X	double	cosine;		/* cosine of line angle */
X	double	nd;		/* number of dots fitting on line */
X	int	n;		/* nd rounded to the nearest integer */
X	double	dx, dy;		/* step between dashes */
X	int	x2, y2;
X
X
X	cosine = (sx)? (double)abs(sx) / hypot((double)sx, (double)sy): 1.0;
X	/*** compute step width ***/
X	nd = l / (3*val*cosine);
X	n = rint(nd);
X	dx = l / (double)n;
X	if (sx) {
X	    dx = l / (double)n;
X	    if (sx < 0) dx = -dx;
X	    dy = dx * (double)sy / (double)sx;
X	    }
X	else {
X	    dx = 0.0;
X	    dy = l / (double)n;
X	    if (sy < 0) dy = -dy;
X	    }
X	/*** draw arrow heads ***/
X	if (arrow == 1  ||  arrow == 2) {
X	    /* forward arrow */
X	    if (sx) {
X		x2 = (sx >= 0)? x + round(l): x - round(l);
X		y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx );
X		}
X	    else {
X		x2 = x;
X		y2 = (sy >= 0)? y + round(l): y - round(l);
X		}
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2, y2, sx, sy);
X	    n--;
X	    }
X	if (arrow == -1  ||  arrow == 2) {
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x, y, -sx, -sy);
X	    x = round(x + dx);
X	    y = round(y + dy);
X	    n--;
X	    }
X	/*** draw dotted line ***/
X	fprintf(tfp, "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\makebox(%.4f,%.4f){%s}}\n",
X	    x, y, dx, dy, n+1, dot_xoffset, dot_yoffset, dot_cmd);
X	}
X
Xvoid genlatex_spline(s)
XF_spline	*s;
X{
X	fprintf(stderr, "Can't generate spline; omitting object\n");
X	}
X
Xvoid genlatex_ellipse(e)
XF_ellipse	*e;
X{
X	int  x, y, d, dx, dy;
X
X	if (verbose) fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");
X
X	set_linewidth(e->thickness);
X	switch (e->style) {
X	    case SOLID_LINE:
X		break;
X	    case DASH_LINE:
X		fprintf(stderr, "Dashed circles and elipses not supported\n");
X		break;
X	    case DOTTED_LINE:
X		fprintf(stderr, "Dotted circles and elipses not supported\n");
X		break;
X	    }
X
X	x = e->center.x;
X	y = e->center.y;
X	TRANS(x, y);
X	if ((e->type == T_CIRCLE_BY_RAD || e->type == T_CIRCLE_BY_DIA)
X			&& e->radiuses.x*unitlength <= MAXCIRCLERAD) {
X
X	    d = 2 * e->radiuses.x;
X	    if (e->area_fill == BLACK_FILL)
X	    	fprintf(tfp, "\\put(%3d,%3d){\\circle*{%d}}\n", x, y, d);
X	    else {
X	      	fprintf(tfp, "\\put(%3d,%3d){\\circle{%d}}\n", x, y, d);
X		if (e->area_fill && (int)e->area_fill != DEFAULT)
X			fprintf(stderr, "Circle area fill not implemented\n");
X	    }
X
X	} else {	    
X	    dx = 2 * e->radiuses.x;
X	    dy = 2 * e->radiuses.y;
X	    fprintf(tfp, "\\put(%3d,%3d){\\oval(%d,%d)}\n", x, y, dx, dy);
X	    if (e->area_fill && (int)e->area_fill != DEFAULT)
X		fprintf(stderr, "Ellipse area fill not implemented\n");
X	}
X      }
X
Xvoid genlatex_text(t)
XF_text	*t;
X{
X	int   	x, y;
X	char	*tpos, *cp;
X
X	if (verbose) fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");
X
X	x = t->base_x;
X	y = t->base_y;
X	TRANS(x, y);
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	    }
X
X	/* raisebox is used to position text at baseline */
X	fprintf(tfp, 
X	  "\\put(%3d,%3d){\\makebox(0,0)%s{\\raisebox{0pt}[0pt][0pt]",
X	  x, y, tpos);
X	fprintf(tfp, "{\\%s%s ", 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, "}}}\n");
X	}
X
Xvoid genlatex_arc(a)
XF_arc	*a;
X/*
X *  Approximates an arc by a sequence of quarter ovals.
X *
X *  Example:
X *
X *	Arc with center at (0,0) and radius 10 from +45 degree to +225 degree
X *	(arc from p1 = (7.07, 7.07) to p2 = (-7.07, -7.07) counterclockwise).
X *	This arc is approximated by three quarter ovals, one for each quadrant
X *	through which the arc goes:
X *
X *	 1. quarter oval from p1 to the intersection of arc and y-axis,
X *	    i.e., from (7.07, 7.07) to (0, 10) in quadrant 0
X *
X *		\put(0, 7.07){\oval(14.14, 5.86)[tr]}
X *
X *	 2. quarter oval from intersection arc/y-axis to intersection arc/x-axis
X *	    i.e., from (0, 10) to (-10, 0) in quadrant 1
X *
X *		\put(0, 0){\oval(20,20)[tl]}
X *
X *	 3. quarter oval from p1 to the intersection of arc and y-axis,
X *	    i.e., from (-10, 0) to (-7.07, -7.07) in quadrant 2
X *
X *		\put(-7.07, 0){\oval(5.86, 14.14)[bl]}
X */
X{
X	F_pos		p1, p2, pq[4];
X	double		cx, cy;
X	double		v1x, v1y, v2x, v2y;
X	double		r, angle1, angle2;
X	int		q1, q2;
X	int		p1_arrow, p2_arrow;
X	static char	*ad1[4] = { " 0,-1", " 1, 0", " 0, 1", "-1, 0" };
X	static char	*ad2[4] = { "-1, 0", " 0,-1", " 1, 0", " 0, 1" };
X
X	set_linewidth(a->thickness);
X	switch (a->style) {
X	    case SOLID_LINE:
X		break;
X	    case DASH_LINE:
X		fprintf(stderr, "Dashed arcs not supported\n");
X		break;
X	    case DOTTED_LINE:
X		fprintf(stderr, "Dotted arcs not supported\n");
X		break;
X	    }
X	if (a->direction == 1) {
X	    p1 = a->point[0];
X	    p2 = a->point[2];
X	    p1_arrow = (a->back_arrow != NULL);
X	    p2_arrow = (a->for_arrow != NULL);
X	    }
X	else {
X	    p1 = a->point[2];
X	    p2 = a->point[0];
X	    p1_arrow = (a->for_arrow != NULL);
X	    p2_arrow = (a->back_arrow != NULL);
X	    }
X	cx = a->center.x;
X	cy = a->center.y;
X	TRANS2(p1.x, p1.y, p2.x, p2.y);
X	TRANSD(cx, cy);
X	/*** compute vectors and angles from arc center to p1, p2 ***/
X	v1x = (double)p1.x - cx;
X	v1y = (double)p1.y - cy;
X	v2x = (double)p2.x - cx;
X	v2y = (double)p2.y - cy;
X	angle1 = atan2(v1y, v1x) * rad2deg;
X	angle2 = atan2(v2y, v2x) * rad2deg;
X	if (angle1 < 0.0)
X	    angle1 += 360.0; 
X	if (angle2 < 0.0)
X	    angle2 += 360.0; 
X	/* compute arc radius */
X	r = hypot(v1x, v1y);
X	/*** compute intersection of arc with x and y axis (origin at cx, cy) */
X	pq[0].x = round(cx);
X	pq[0].y = round(cy + r);
X	pq[1].x = round(cx - r);
X	pq[1].y = round(cy);
X	pq[2].x = round(cx);
X	pq[2].y = round(cy - r);
X	pq[3].x = round(cx + r);
X	pq[3].y = round(cy);
X	/*** compute in which quadrants p1 and p2 are located ***/
X	q1 = (int)(angle1/90.0);
X	q2 = (int)(angle2/90.0);
X	if (fabs(angle1 - 90.0*q1) > arc_tolerance 
X	 || fabs(angle2 - 90.0*q2) > arc_tolerance)
X	    fprintf(stderr, "Approximating arc by ovals\n");
X	/*** Draw arc ***/
X	if (p1_arrow)
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%s){0}}\n", p1.x, p1.y, ad1[q1]);
X	while (q1 != q2) {
X	    put_quarter(p1, pq[q1], q1);
X	    p1 = pq[q1];
X	    q1 = (q1 + 1) % 4;
X	    }
X	put_quarter(p1, p2, q1);
X	if (p2_arrow)
X	    fprintf(tfp, "\\put(%3d,%3d){\\vector(%s){0}}\n", p2.x, p2.y, ad2[q2]);
X
X	if (a->area_fill && (int)a->area_fill != DEFAULT)
X		fprintf(stderr, "Arc area fill not implemented\n");
X	}
X
Xstatic put_quarter(p1, p2, q)
XF_pos	p1, p2;
Xint	q;
X/*
X *  Draw quarter oval from p1 to p2 in quadrant q
X */
X{
X	char	*opt;
X	int	px, py, dx, dy;
X
X	dx = 2*ABS(p1.x - p2.x);
X	dy = 2*ABS(p1.y - p2.y);
X	if (dx == 0  &&  dy == 0)
X	    return;
X	switch (q) {
X	    case 0:
X		px = MIN(p1.x, p2.x);
X		py = MIN(p1.y, p2.y);
X		opt = "tr";
X		break;
X	    case 1:
X		px = MAX(p1.x, p2.x);
X		py = MIN(p1.y, p2.y);
X		opt = "tl";
X		break;
X	    case 2:
X		px = MAX(p1.x, p2.x);
X		py = MAX(p1.y, p2.y);
X		opt = "bl";
X		break;
X	    case 3:
X		px = MIN(p1.x, p2.x);
X		py = MAX(p1.y, p2.y);
X		opt = "br";
X		break;
X	    }
X	fprintf(tfp, "\\put(%3d,%3d){\\oval(%3d,%3d)[%s]}\n", px, py, dx, dy, opt);
X	}
X
Xstruct driver dev_latex = {
X     	genlatex_option,
X	genlatex_start,
X	genlatex_arc,
X	genlatex_ellipse,
X	genlatex_line,
X	genlatex_spline,
X	genlatex_text,
X	genlatex_end,
X	EXCLUDE_TEXT
X};
END_OF_FILE
if test 20332 -ne `wc -c <'transfig/fig2dev/dev/genlatex.c'`; then
    echo shar: \"'transfig/fig2dev/dev/genlatex.c'\" unpacked with wrong size!
fi
# end of 'transfig/fig2dev/dev/genlatex.c'
fi
if test -f 'transfig/fig2dev/dev/genps.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genps.c'\"
else
echo shar: Extracting \"'transfig/fig2dev/dev/genps.c'\" \(17407 characters\)
sed "s/^X//" >'transfig/fig2dev/dev/genps.c' <<'END_OF_FILE'
X/* 
X *	genps.c: PostScript driver for fig2dev
X *
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 <pwd.h>
X#include "object.h"
X#include "fig2dev.h"
X
Xextern			x_flag;
X
X#define		PAGE_WIDTH		612	/* points; 8.5" */
X#define		PAGE_HEIGHT		792	/* points; 11" */
X#define		TRUE			1
X#define		FALSE			0
X#define		POINT_PER_INCH		72
X#define		ULIMIT_FONT_SIZE	300
X
Xint		coord_system;
Xint		show_page = 0;
Xint		cur_thickness;
Xint		center = 0;
Xint		landscape = 0;
X
Xstatic char		*fontnames_x[] = {
X			"Times-Roman", "Times-Roman",	/* default */
X			"Times-Italic",			/* italic */
X			"Times-Bold",			/* bold */
X			"Times-BoldItalic",
X			"AvantGarde",
X			"AvantGarde-BookOblique",
X			"AvantGarde-Demi",
X			"AvantGarde-DemiOblique",
X			"Bookman-Light",
X			"Bookman-LightItalic",
X			"Bookman-Demi",
X			"Bookman-DemiItalic",
X			"Courier",	
X			"Courier-Oblique",
X			"Courier-Bold",
X			"Courier-BoldItalic",
X			"Helvetica",
X			"Helvetica-Oblique",
X			"Helvetica-Bold",
X			"Helvetica-BoldOblique",
X			"Helvetica-Narrow",
X			"Helvetica-Narrow-Oblique",
X			"Helvetica-Narrow-Bold",
X			"Helvetica-Narrow-BoldOblique",
X			"NewCenturySchlbk-Roman",
X			"NewCenturySchlbk-Italic",
X			"NewCenturySchlbk-Bold",
X			"NewCenturySchlbk-BoldItalic",
X			"Palatino-Roman",
X			"Palatino-Italic",
X			"Palatino-Bold",
X			"Palatino-BoldItalic",
X			"Symbol",
X			"ZapfChancery-MediumItalic",
X			"ZapfDingbats"
X		};
X
Xstatic char		*fontnames_sv[] = {
X			"Times-Roman", "Times-Roman",	/* default */
X			"Times-Roman",			/* roman */
X			"Times-Bold",			/* bold */
X			"Times-Italic",			/* italic */
X			"Helvetica",			/* sans serif */
X			"Courier"			/* typewriter */
X		};
X#define MAXFONT (x_flag ? 35 : 5)
X
X#define PS_FONTNAMES	(x_flag ? fontnames_x : fontnames_sv)
X
X#define PSFONT(F) \
X	 ((F) <= MAXFONT ? PS_FONTNAMES[(F)+1] : PS_FONTNAMES[0])
X
X#define PSFONTSIZE(S)	(((S) > 0 ? \
X				((S) <= ULIMIT_FONT_SIZE ? \
X			 		(S) : \
X					ULIMIT_FONT_SIZE) : \
X				font_size)/mag)
X
X#define GRAYVAL(F)	(x_flag ? ((int)(F) <= 21 ? \
X				(21 - (int)(F))/20.0 : 0.0) : \
X				((int)(F) <= 5 ? ((int)(F) - 1)/4.0 : 0.0))
X
X#define		BEGIN_PROLOG	"\
X/$F2psDict 32 dict def \
X$F2psDict begin\
X	$F2psDict /mtrx matrix put\
X"
X#define		ELLIPSE_PS	" \
X/DrawEllipse {\
X	/endangle exch def\
X	/startangle exch def\
X	/yrad exch def\
X	/xrad exch def\
X	/y exch def\
X	/x exch def\
X	/savematrix mtrx currentmatrix def\
X	x y translate xrad yrad scale 0 0 1 startangle endangle arc\
X	savematrix setmatrix\
X	} def\
X"
X/* The original PostScript definition for adding a spline section to the
X * current path uses recursive bisection.  The following definition using the
X * curveto operator is more efficient since it executes at compiled rather
X * than interpreted code speed.  The Bezier control points are 2/3 of the way
X * from z1 (and z3) to z2.
X *
X * ---Rene Llames, 21 July 1988.
X */
X#define		SPLINE_PS	" \
X/DrawSplineSection {\
X	/y3 exch def\
X	/x3 exch def\
X	/y2 exch def\
X	/x2 exch def\
X	/y1 exch def\
X	/x1 exch def\
X	/xa x1 x2 x1 sub 0.666667 mul add def\
X	/ya y1 y2 y1 sub 0.666667 mul add def\
X	/xb x3 x2 x3 sub 0.666667 mul add def\
X	/yb y3 y2 y3 sub 0.666667 mul add def\
X	x1 y1 lineto\
X	xa ya xb yb x3 y3 curveto\
X	} def\
X"
X#define		END_PROLOG	"\
X	end\
X	/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def\
X	/$F2psEnd {$F2psEnteredState restore end} def\
X	%%EndProlog\
X"
X
Xvoid genps_option(opt, optarg)
Xchar opt;
Xchar *optarg;
X{
X	int i;
X
X	switch (opt) {
X
X	case 'f':
X		for ( i = 1; i <= MAXFONT + 1; i++ )
X			if ( !strcmp(optarg, PS_FONTNAMES[i]) ) break;
X
X		if ( i > MAXFONT + 1 )
X			fprintf(stderr,
X				"warning: non-standard font name %s\n", optarg);
X
X	    	fontnames_sv[0] = fontnames_sv[1] = optarg;
X	    	fontnames_x[0] = fontnames_x[1] = optarg;
X	    	break;
X
X	case 'c':
X	    	center = 1;
X		break;
X
X	case 's':
X		if (font_size <= 0 || font_size > ULIMIT_FONT_SIZE) {
X			fprintf(stderr,
X				"warning: font size %d out of bounds\n", font_size);
X		}
X		break;
X
X	case 'P':
X		show_page = 1;
X		break;
X
X      	case 'm':
X      	case 'L':
X		break;
X
X      	case 'l':
X		landscape = 1;
X		break;
X
X	default:
X		put_msg(Err_badarg, opt, "ps");
X		exit(1);
X		break;
X	}
X}
X
Xvoid genps_start(objects)
XF_compound	*objects;
X{
X	char		host[256];
X	struct passwd	*who;
X	long		when;
X	extern char	*ctime(), *strcpy();
X	extern long	time();
X	double		tx, scalex, scaley;
X	double		dx, dy, origx, origy;
X	int		itmp;
X
X	coord_system = objects->nwcorner.y;
X	scalex = scaley = mag * POINT_PER_INCH / (double)objects->nwcorner.x;
X	/* convert to point unit */
X	llx = (int)ceil(llx * scalex); lly = (int)ceil(lly * scaley);
X	urx = (int)ceil(urx * scalex); ury = (int)ceil(ury * scaley);
X	if (landscape)          /* swap x,y */
X		{
X		itmp = llx; llx = lly; lly = itmp;
X		itmp = urx; urx = ury; ury = itmp;
X		}
X	if (center) {
X	    dx = urx - llx;
X	    dy = ury - lly;
X	    tx = (PAGE_WIDTH - dx) / 2.0;
X	    if (landscape)
X		origx=0;
X	    else
X		origx = tx - llx;
X	    urx = (llx=tx) + dx;
X	    ury = (PAGE_HEIGHT + dy) / 2.0;
X	    if (coord_system == 2)
X		origy = ury + lly;
X	    else
X		origy = ury - dy - lly;
X	    lly = ury - dy;
X	    }
X	else {
X	    origx = 0.0;
X	    origy = PAGE_HEIGHT;
X	    }
X
X	if (coord_system == 2) scaley = -scaley;
X
X	fprintf(tfp, "%%!\n");	/* PostScript magic strings */
X	who = getpwuid(getuid());
X	if (-1 == gethostname(host, sizeof(host)))
X	    (void)strcpy(host, "unknown-host!?!?");
X	(void) time(&when);
X	fprintf(tfp, "%%%%Title: %s\n", ((from) ? from : "stdin"));
X	fprintf(tfp, "%%%%Creator: %s\n", prog);
X	fprintf(tfp, "%%%%CreationDate: %s", ctime(&when));
X	fprintf(tfp, "%%%%For: %s@%s (%s)\n",
X			who->pw_name, host, who->pw_gecos);
X	fprintf(tfp, "%%%%Pages: %d\n", show_page);
X
X	if (show_page)
X	  fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury);
X	else
X	  fprintf(tfp, "%%%%BoundingBox: 0 0 %d %d\n", urx-llx, ury-lly);
X
X	fprintf(tfp, "%%%%EndComments\n");
X	fprintf(tfp, "%s\n", BEGIN_PROLOG);
X	if (ellipse_exist(objects)) fprintf(tfp, "%s\n", ELLIPSE_PS);
X	if (normal_spline_exist(objects)) fprintf(tfp, "%s\n", SPLINE_PS);
X	fprintf(tfp, "%s\n", END_PROLOG);
X	fprintf(tfp, "$F2psBegin\n");
X	fprintf(tfp, "1 setlinecap 1 setlinejoin\n");
X
X	if (!show_page) fprintf(tfp, "%d %d translate\n", -llx, lly);
X	fprintf(tfp, "%f %f translate %.3f %.3f scale\n",
X		origx, (show_page ? origy : ury-lly), scalex, scaley);
X
X	/* **** Land scape mode ****/
X	if (landscape)
X	    fprintf(tfp, "%d 0 translate 90 rotate\n", PAGE_WIDTH);
X
X	/*    if ((t = PAGE_HEIGHT / SCALE / WIDTH) < 1.0)
X	*	fprintf(tfp, "%f %f scale\n", t, t);
X	*   }
X	*else if ((t = PAGE_HEIGHT / SCALE / HEIGHT) < 1.0)
X	*    fprintf(tfp, "%f %f scale\n", t, t);
X	*/
X
X	}
X
Xvoid genps_end()
X{
X	if (show_page) fprintf(tfp, "showpage\n");
X	fprintf(tfp, "$F2psEnd\n");
X	}
X
Xstatic set_style(s, v)
Xint	s;
Xdouble	v;
X{
X	if (s == DASH_LINE) {
X	    if (v > 0.0) fprintf(tfp, "\t[%f] 0 setdash\n", v);
X	    }
X	else if (s == DOTTED_LINE) {
X	    if (v > 0.0) fprintf(tfp, "\t[1 %f] 0 setdash\n", v);
X	    }
X	}
X
Xstatic reset_style(s, v)
Xint	s;
Xdouble	v;
X{
X	if (s == DASH_LINE) {
X	    if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n");
X	    }
X	else if (s == DOTTED_LINE) {
X	    if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n");
X	    }
X	}
X
Xstatic set_linewidth(w)
Xint	w;
X{
X	extern int	cur_thickness;
X
X	if (w != cur_thickness) {
X	    cur_thickness = w;
X	    fprintf(tfp, "%.3f setlinewidth\n", 1.0 * cur_thickness);
X	    }
X	}
X
Xvoid genps_line(l)
XF_line	*l;
X{
X	F_point		*p, *q;
X	/* JNT */
X	int		radius;
X	
X	set_linewidth(l->thickness);
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	    fprintf(tfp, "newpath %d %d moveto %d %d lineto stroke\n",
X			p->x, p->y, p->x, p->y);
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	fprintf(tfp, "%% Polyline\n");
X	/* JNT */
X	        if (l->type == T_ARC_BOX)
X                {
X                register int xmin,xmax,ymin,ymax;
X
X                xmin = xmax = p->x;
X                ymin = ymax = p->y;
X                while (p->next != NULL) /* find lower left and upper right corne
Xrs */
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                fprintf(tfp, "newpath %d %d moveto",xmin+radius, ymin);
X                fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat",
X                                xmin, ymin, xmin, ymax-radius, radius);
X                fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
Xugh bl to br */
X                                xmin, ymax, xmax-radius, ymax, radius);
X                fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
Xugh br to tr */
X                                xmax, ymax, xmax, ymin+radius, radius);
X                fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
Xugh tr to tl */
X                                xmax, ymin, xmin+radius, ymin, radius);
X		}
X        else
X                {
X	fprintf(tfp, "newpath %d %d moveto", p->x, p->y);
X	while (q->next != NULL) {
X	    p = q;
X	    q = q->next;
X	    fprintf(tfp, " %d %d lineto", p->x, p->y);
X	    }
X		}
X	if (l->type == T_POLYLINE)
X	    fprintf(tfp, " %d %d lineto stroke\n", q->x, q->y);
X	else
X	    fprintf(tfp, " closepath ");
X	if (l->area_fill && (int)l->area_fill != DEFAULT)
X		fprintf(tfp, "gsave %6.3f setgray fill grestore ",
X			GRAYVAL(l->area_fill));
X	fprintf(tfp, "stroke\n");
X	reset_style(l->style, l->style_val);
X	if (l->for_arrow)
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
Xvoid genps_spline(s)
XF_spline	*s;
X{
X	if (int_spline(s))
X	    genps_itp_spline(s);
X	else
X	    genps_ctl_spline(s);
X	}
X
Xgenps_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	p = s->points;
X	if (s->back_arrow)
X	    draw_arrow_head(a->rx, a->ry, (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	    b = b->next;
X	    }
X	if (closed_spline(s)) fprintf(tfp, " closepath ");
X	if (s->area_fill && (int)s->area_fill != DEFAULT)
X		fprintf(tfp, "gsave %6.3f setgray fill grestore ",
X			GRAYVAL(s->area_fill));
X	fprintf(tfp, " stroke\n");
X	reset_style(s->style, s->style_val);
X
X	if (s->for_arrow)
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
Xgenps_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	/*
X	if (first) {
X	    first = FALSE;
X	    fprintf(tfp, "%s\n", SPLINE_PS);
X	    }
X	*/
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) {
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; p = q, 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	    }
X	else {
X	    fprintf(tfp, "\t%.3f %.3f lineto ", c, d);
X	    }
X	if (s->area_fill && (int)s->area_fill != DEFAULT)
X		fprintf(tfp, "gsave %6.3f setgray fill grestore ",
X			GRAYVAL(s->area_fill));
X	fprintf(tfp, "stroke\n");
X	reset_style(s->style, s->style_val);
X	if (s->for_arrow) {
X	    draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
X				s->for_arrow->wid);
X	    }
X	}
X
Xvoid genps_ellipse(e)
XF_ellipse	*e;
X{
X	set_linewidth(e->thickness);
X	set_style(e->style, e->style_val);
X	if (e->angle == 0)
X	{
X	    fprintf(tfp, "%% Ellipse\n");
X	    fprintf(tfp, "newpath %d %d %d %d 0 360 DrawEllipse ",
X	          e->center.x, e->center.y, e->radiuses.x, e->radiuses.y);
X	}
X	else
X	{
X	    fprintf(tfp, "%% Rotated Ellipse\n");
X	    fprintf(tfp, "gsave\n");
X	    fprintf(tfp, "%d %d translate\n",e->center.x, e->center.y);
X	    fprintf(tfp, "%6.3f rotate\n",e->angle*180/M_PI);
X	    fprintf(tfp, "newpath 0 0 %d %d 0 360 DrawEllipse ",
X		 e->radiuses.x, e->radiuses.y);
X	}
X	if (e->area_fill && (int)e->area_fill != DEFAULT)
X		fprintf(tfp, "gsave %6.3f setgray fill grestore ",
X			GRAYVAL(e->area_fill));
X	fprintf(tfp, "stroke\n");
X	if (e->angle != 0)
X	    fprintf(tfp, "grestore\n");
X	reset_style(e->style, e->style_val);
X	}
X
X#define	TEXT_PS		"\
X/%s findfont %.3f scalefont setfont\n\
X"
Xvoid genps_text(t)
XF_text	*t;
X{
X	char		*cp;
X
X	fprintf(tfp, TEXT_PS, PSFONT(t->font), PSFONTSIZE(t->size));
X
X	fprintf(tfp, "%d %d moveto \n", t->base_x,  t->base_y);
X	if (coord_system == 2) fprintf(tfp, "1 -1 scale\n");
X
X	/* this loop escapes characters '(', ')', and '\' */
X	fputc('(', tfp);
X	for(cp = t->cstring; *cp; cp++) {
X	      if (strchr("()\\", *cp)) fputc('\\', tfp);
X	      fputc(*cp, tfp);
X	      }
X	fputc(')', tfp);
X
X	if ((t->type == T_CENTER_JUSTIFIED) || (t->type == T_RIGHT_JUSTIFIED)){
X
X	  	fprintf(tfp, "dup stringwidth pop ");
X		if (t->type == T_CENTER_JUSTIFIED) fprintf(tfp, "2 div ");
X		fprintf(tfp, "neg 0 rmoveto ");
X	      	}
X
X	else if ((t->type != T_LEFT_JUSTIFIED) && (t->type != DEFAULT))
X		fprintf(stderr, "Text incorrectly positioned\n");
X
X	fprintf(tfp, " gsave %6.3f rotate show grestore ", t->angle*180/M_PI);
X	if (coord_system == 2) fprintf(tfp, "1 -1 scale\n");
X
X	}
X
Xvoid genps_arc(a)
XF_arc	*a;
X{
X	double		angle1, angle2, dx, dy, radius, x, y;
X	double		cx, cy, sx, sy, ex, ey;
X	int		direction;
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	if (a->for_arrow) {
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) {
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 = hypot(dx, dy);
X	angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
X	angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
X	/* direction = 1 -> Counterclockwise */
X	set_style(a->style, a->style_val);
X	fprintf(tfp, "newpath %.3f %.3f %.3f %.3f %.3f %s\n",
X		cx, cy, radius, angle1, angle2,
X		((direction == 1) ? "arc" : "arcn"));
X	if (a->area_fill && (int)a->area_fill != DEFAULT)
X		fprintf(tfp, "gsave %6.3f setgray fill grestore ",
X			GRAYVAL(a->area_fill));
X	fprintf(tfp, "stroke\n");
X	reset_style(a->style, a->style_val);
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
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	fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto %.3f %.3f lineto stroke\n",
X		xc, yc, x2, y2, xd, yd);
X	}
X
Xstatic ellipse_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
Xstatic normal_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
Xstruct driver dev_ps = {
X     	genps_option,
X	genps_start,
X	genps_arc,
X	genps_ellipse,
X	genps_line,
X	genps_spline,
X	genps_text,
X	genps_end,
X	INCLUDE_TEXT
X};
END_OF_FILE
if test 17407 -ne `wc -c <'transfig/fig2dev/dev/genps.c'`; then
    echo shar: \"'transfig/fig2dev/dev/genps.c'\" unpacked with wrong size!
fi
# end of 'transfig/fig2dev/dev/genps.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
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.