DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T f

⟦a6b7a5bae⟧ TextFile

    Length: 16638 (0x40fe)
    Types: TextFile
    Names: »fig2tex.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./tex82/TeXgraphics/transfig/fig2tex/fig2tex.c« 

TextFile

/* 
 *	Fig2tex : The fig-to-PicTeX translator
 *
 *	Modified from ftp, the fig-to-to-pic translator
 *
 *	University of Texas at Austin,
 *
*/
/*
 * Modified 1987 for PicTeX output by Micah Beck (beck@svax.cs.cornell.edu)
 *
 */
#include <stdio.h>
#include <math.h>
#include "object.h"
#include "choices.h"

#define	round(x)	((int) (x + .5))

#define max(a,b)	((a > b) ? a : b)
#define min(a,b)	((a < b) ? a : b)

#define MINMAX(X,Y) {	min_x = min(X, min_x);	\
			min_y = min(Y, min_y);	\
			max_x = max(X, max_x);	\
			max_y = max(Y, max_y);	\
			}

#define SWITCH(T,A,B) {	register T t;	\
			t = A;		\
			A = B;		\
			B = t;		\
			}
#define EPSILON 0.02
#define CLOSE(A,B) (fabs(A-B) < EPSILON)

extern int getopt();
extern char *optarg;
extern int optind;

extern double sin(), cos(), acos(), fabs();

FILE		*tfp;
float		PIX_PER_INCH, mag;
int		cur_style, cur_dashlength;

main(argc, argv)
int	 argc;
char	*argv[];
{
	char		*textfont, *linethick, *plotsymbol;
	char		*from, *to, text[80], c;
	FILE		*ffp;
	int		arb, size, type, style, thickness, direction;
	int		n, num_obj, font, object;
	int		f_arrow, b_arrow, arrow_wid, arrow_ht;
	float		CANVAS_WIDTH, CANVAS_HEIGHT, ORIGIN;
	float		dummy, width, height, length, dash_length;
	float		a, b;
	float		x, y, x1, y1, x2, y2, xsav, ysav;
	float		cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
	float		min_x, min_y, max_x, max_y;
	double		dx1, dx2, dy1, dy2, r1, th1, r2, th2, theta, t;

	mag = 1.0;
	textfont = "\\twltt";
	linethick = ".7pt";
	plotsymbol = "\\sevrm .";

	from = NULL;
	to = NULL;

	while ((c = getopt(argc, argv, "af:l:p:m:")) != EOF)

	    switch (c) {

		case 'a':			/* arbitrary text */
		    arb = 1;

		case 'f':			/* set text font */
		    textfont = optarg;
		    break;

		case 'l':			/* set line thickness */
		    linethick = optarg;
		    break;

		case 'p':			/* set plot symbol */
		    plotsymbol = optarg;
		    break;

		case 'm':
		    mag = atof(optarg);		/* set magnification */
		    break;

		case '?':
		    exit(1);
		    break;
	    }

	if (optind < argc) from = argv[optind++];  /*  from file  */
	if (optind < argc) to   = argv[optind];  /*  to file    */

	if (from == NULL) 
	    ffp = stdin;
	else if ((ffp = fopen(from, "r")) == NULL) {
	    fprintf(stderr, "Couldn't open %s\n", from);
	    exit(1);
	    }
	if (to == NULL) 
	    tfp = stdout;
	else if ((tfp = fopen(to, "w")) == NULL) {
	    fprintf(stderr, "Couldn't open %s\n", to);
	    exit(1);
	    }

	cur_style = SOLID_LINE;
	cur_dashlength = 0;

	fscanf(ffp,"%f %f %f %f\n", &PIX_PER_INCH, &ORIGIN, 
		&CANVAS_WIDTH, &CANVAS_HEIGHT);

	max_x = max_y = 0;
	min_x = CANVAS_WIDTH;
	min_y = CANVAS_HEIGHT;

	fprintf(tfp, "\\mbox{\\beginpicture\n");
	fprintf(tfp, "\\setcoordinatesystem units <%6.3fin,%6.3fin>\n",
			mag, mag);
	fprintf(tfp, "\\linethickness=%s\n", linethick);
	fprintf(tfp, "\\setplotsymbol ({%s})\n", plotsymbol);
	fprintf(tfp, "\\setlinear\n");

        fprintf(tfp, "\\if \\picturemode \\nopics \\else\n");
	fprintf(tfp, "\\if \\picturemode \\dottedpics \\setdots \\fi");

        fprintf(tfp, "\\if \\picturemode \\optpics\n");
	fprintf(tfp, "\\unitlength=%6.3fin\n", mag);
	fprintf(tfp, "\\thicklines\n");
	fprintf(tfp, "\\fi\n");

	num_obj = 0;
	while ((fscanf(ffp, "%d", &object)) != EOF) {
	    switch (object) {

		case ARC :
		    num_obj++;
		    fprintf(tfp, "%%\n%% Fig ARC object (#%d)\n%%\n", num_obj);

		    n = fscanf(ffp, " %d %d %d %f %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
				&type, &style, &thickness, 
				&dash_length, &direction, &f_arrow, &b_arrow,
				&arrow_ht, &arrow_wid, &x, &y,
				&x1, &y1, &dummy, &dummy, &x2, &y2);
		    if (n != 17) {
			fprintf(stderr, "Arc (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			}

		    if (direction == 1) {
			SWITCH(float, x1, x2);
			SWITCH(float, y1, y2);
			SWITCH(int, f_arrow, b_arrow);
		 	}

		    dx1 = x1 - x;
		    dy1 = y1 - y;
		    dx2 = x2 - x;
		    dy2 = y2 - y;
		    
		    rtop(dx1, dy1, &r1, &th1);
		    rtop(dx2, dy2, &r2, &th2);
		    theta = th1 - th2;
		    if (theta > 0) theta -= 360;

		    MINMAX(x1, y1);
		    MINMAX(x2, y2);
		    for (t = 0; t > theta * acos(0.0) / 90; t -= .1)
			MINMAX(x + r1 * cos(th1+t), y + r1 * sin(th1+t));

		    x = x / PIX_PER_INCH; /*  (x,y) is the center of the arc */
		    y = (CANVAS_HEIGHT - y) / PIX_PER_INCH;
		    x1 = x1 / PIX_PER_INCH;
		    y1 = (CANVAS_HEIGHT - y1) / PIX_PER_INCH;
		    x2 = x2 / PIX_PER_INCH;
		    y2 = (CANVAS_HEIGHT - y2) / PIX_PER_INCH;

		    if (b_arrow) setarrow(tfp,
				((float)arrow_wid)/PIX_PER_INCH,
				((float)arrow_ht)/PIX_PER_INCH,
				x1+(y1-y), y1-(x1-x), x1, y1);
		    if (f_arrow) setarrow(tfp,
				((float)arrow_wid)/PIX_PER_INCH,
				((float)arrow_ht)/PIX_PER_INCH,
				x2-(y2-y), y2+(x2-x), x2, y2);

		    setstyle(style, dash_length);

		    fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
			theta, x1, y1, x, y);
		    break;

		case POLYLINE :
		    num_obj++;
		    fprintf(tfp, "%%\n%% Fig POLYLINE object (#%d)\n%%\n",
			    num_obj);

		    n = fscanf(ffp, " %d %d %d %f %d %d %d %d", 
				&type, &style, &thickness, 
				&dash_length, &f_arrow, &b_arrow,
				&arrow_ht, &arrow_wid);
		    if (n != 8) {
			fprintf(stderr, "Line (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			}

		    if (fscanf(ffp, " %f %f %f %f", &x1, &y1, &x2, &y2) != 4) {
			fprintf(stderr, "Line (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			};

		    MINMAX(x1, y1);

		    x1 = x1 / PIX_PER_INCH;
		    y1 = (CANVAS_HEIGHT - y1) / PIX_PER_INCH;
		    if (x2 == 9999 && y2 == 9999) { /* A single point line */
			fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f/\n",
			    	x1, y1, x1, y1);
		        break;
			}

		    MINMAX(x2, y2);

		    x2 = x2 / PIX_PER_INCH;
		    y2 = (CANVAS_HEIGHT - y2) / PIX_PER_INCH;

		    if (b_arrow) setarrow(tfp,
				((float)arrow_wid)/PIX_PER_INCH,
				((float)arrow_ht)/PIX_PER_INCH,
				x2, y2, x1, y1);

		    setstyle(style, dash_length);

		    putline(x1, y1, x2, y2);

		    for (;;) {
			if (fscanf(ffp, " %f %f", &x, &y) != 2) {
			    fprintf(stderr, "Line (object #%d) is incomplete\n",
				num_obj);
			    fscanf(ffp, "%*[^\n]");  /* Flush the buffer */
			    break;
			    };
			if (x == 9999) break;

		        MINMAX(x, y);

			x = x / PIX_PER_INCH;
			y = (CANVAS_HEIGHT - y) / PIX_PER_INCH;

			putline(x2, y2, x, y);

			x1 = x2;
			y1 = y2;
			x2 = x;
			y2 = y;
			}

		    if (f_arrow) setarrow(tfp,
					((float)arrow_wid)/PIX_PER_INCH, 
					((float)arrow_ht) /PIX_PER_INCH,
					x1, y1, x2, y2);

		    break;

		case SPLINE :
		    num_obj++;
		    fprintf(tfp, "%%\n%% Fig SPLINE object (#%d)\n%%\n",
			    num_obj);

		    n = fscanf(ffp, " %d %d %d %f %d %d %d %d", &type, &style,
				&thickness, &dash_length, 
				&f_arrow, &b_arrow, &arrow_ht, &arrow_wid);
		    if (n != 8) {
			fprintf(stderr, "Spline (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			}

		    if (fscanf(ffp, " %f %f %f %f", &x1, &y1, &x2, &y2) != 4) {
			fprintf(stderr, "Spline (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			};

		    MINMAX(x1, y1);
		    MINMAX(x2, y2);

		    y1 = (CANVAS_HEIGHT - y1);
		    y2 = (CANVAS_HEIGHT - y2);

		    if (b_arrow) setarrow(tfp,
					((float)arrow_wid)/PIX_PER_INCH,
					((float)arrow_ht)/PIX_PER_INCH,
					x2/PIX_PER_INCH, y2/PIX_PER_INCH,
					x1/PIX_PER_INCH, y1/PIX_PER_INCH);

		    setstyle(style, dash_length);

		    cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
		    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;

		    if (type == DRAW_SPLINE)
			    fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f\n",
			    	x1/PIX_PER_INCH, y1/PIX_PER_INCH,
				cx1/PIX_PER_INCH, cy1/PIX_PER_INCH);
		    else
			    fprintf(tfp, "\\plot \n");

		    /* save closure point for close splines */
		    xsav = x2;
		    ysav = y2;

		    for (n=2;;n++) {
			if (fscanf(ffp, " %f %f", &x, &y) != 2) {
			    fprintf(stderr, "Spline (object #%d) is incomplete\n",
				num_obj);
			    fscanf(ffp, "%*[^\n]");  /* Flush the buffer */
			    break;
			    };
			if (x == 9999) break;

		        MINMAX(x, y);
			y = (CANVAS_HEIGHT - y);

	    		x1 = x2;  y1 = y2;
	    		x2 = x;  y2 = y;
	    		cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
	    		cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
	    		chaikin_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
	    		cx1 = cx4;  cy1 = cy4;
	    		cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
	    		}

		    if (type == DRAW_SPLINE)
			fprintf(tfp, "\t%6.3f %6.3f /\n",
			    (int)x2/PIX_PER_INCH, (int)y2/PIX_PER_INCH);
		    else {
			fprintf(tfp, "\t/\n\\plot\n");
			x1 = x2;  y1 = y2;
			x2 = xsav;  y2 = ysav;
			cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
			cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;

			chaikin_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
			fprintf(tfp, "\t/\n");
			}
		
	       	    if (f_arrow) setarrow(tfp,
					((float)arrow_wid)/PIX_PER_INCH, 
					((float)arrow_ht) /PIX_PER_INCH,
					x1/PIX_PER_INCH, y1/PIX_PER_INCH,
					x2/PIX_PER_INCH, y2/PIX_PER_INCH);
		    break;

		case ELLIPSE :
		    num_obj++;
		    fprintf(tfp, "%%\n%% Fig ELLIPSE object (#%d)\n%%\n",
			    num_obj);

		    n = fscanf(ffp, " %d %d %d %f %d %f %f %f %f %f %f %f %f\n", 
				&type, &style, &thickness, &dash_length,
				&direction, &x, &y, &a, &b, 
				&dummy, &dummy, &dummy, &dummy);
		    if (n != 13) {
			fprintf(stderr, "Ellipse (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			}

		    setstyle(style, dash_length);

		    MINMAX(x+a, y);
		    MINMAX(x-a, y);
		    MINMAX(x, y+b);
		    MINMAX(x, y-b);

		    x = x / PIX_PER_INCH;
		    y = (CANVAS_HEIGHT - y) / PIX_PER_INCH;
		    width = a / PIX_PER_INCH;
		    height = b / PIX_PER_INCH;
		    if (!latexcircle(width, height, x, y))
		 	fprintf(tfp, "\\iffalse ");
		    fprintf(tfp, "\\else\n");
		    fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n",
			    width, height);
		    fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n",
			    x+width, y, x, y);
		    fprintf(tfp, "\\fi\n");

		    break;

		case TEXT :
		    num_obj++;
		    fprintf(tfp, "%%\n%% Fig TEXT object (#%d)\n%%\n",
			    num_obj);

		    n = fscanf(ffp, "%d %d %d %f %f %f %f %[^\n]",
				&font, &size,
				&style, &height, &length, &x, &y, text);
		    if (n != 8) {
			fprintf(stderr, "Text (object #%d) is incomplete\n",
				num_obj);
			fscanf(ffp, " %[^\n]", text); /* skip to next line */
			break;
			}

		    MINMAX(x,y);
		    MINMAX(x+length, y-height)
		    x = x / PIX_PER_INCH;
		    y = (CANVAS_HEIGHT - y) / PIX_PER_INCH;
		    if (arb)
			/* arbitrary tex needs no hbox */
		    	fprintf(tfp, "\\put {%s %s} [lB] at %6.3f %6.3f\n",
			    textfont, text, x, y);
		    else
		    	fprintf(tfp, "\\put {\\hbox to %6.3fin{%s %s}} [lB] at %6.3f %6.3f\n",
			    length/PIX_PER_INCH, textfont, text, x, y);
		    break;

		case COMPOUND :
		    fscanf(ffp, " %[^\n]", text); /* ignore the rest */

		default :
		    break;
		}
	    }
	fprintf(tfp, "\\fi\n");
	fprintf(tfp, "\\linethickness=0pt\n");
        fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
			min_x/PIX_PER_INCH,(CANVAS_HEIGHT-max_y)/PIX_PER_INCH,
			max_x/PIX_PER_INCH,(CANVAS_HEIGHT-min_y)/PIX_PER_INCH);
	fprintf(tfp, "\\endpicture}\n");
	}

/*
 * putline - use rules if possible
 */
putline (start_x, start_y, end_x, end_y)
float	start_x, start_y, end_x, end_y;
{
    if (cur_style == SOLID_LINE &&
	    (CLOSE (start_x, end_x) || CLOSE (start_y, end_y)))
	fprintf(tfp, "\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
		start_x, start_y, end_x, end_y);

    else {
	if (!latexline(start_x, start_y, end_x, end_y))
	    fprintf(tfp, "\\iffalse\n");
	fprintf(tfp, "\\else\n");
	fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
					start_x, start_y, end_x, end_y);
	fprintf(tfp, "\\fi\n");
	}
}


/* 
 * setstyle - issue style commands as appropriate
 */
setstyle(style, dash_length)
int style;
float dash_length;
{
    switch (style) {
	 case SOLID_LINE:
	    if (cur_style == SOLID_LINE) break;
	    fprintf(tfp, "\\setsolid\n");
	    break;

	case DASH_LINE:
	    if (cur_style == DASH_LINE && cur_dashlength == dash_length)
		break;
	    fprintf(tfp, "\\setdashes <%7.4fin>\n",dash_length / PIX_PER_INCH);
	    break;

	case DOTTED_LINE:
	    if (cur_style == DOTTED_LINE)
		break;
	    fprintf(tfp, "\\setdots \n");
	    break;
	    }

	cur_style = style;
	cur_dashlength = dash_length;
    }

/*
 * setarrow - construct an arrow from a given direction
 */
setarrow(tfp, w, l, ex, ey, ax, ay)
FILE *tfp;
float w, l, ex, ey, ax, ay;
{
	float L, beta, gamma;

	L = hypot(ex - ax, ey - ay);
	ex = (ax + .01*(ex - ax)/L);
	ey = (ay + .01*(ey - ay)/L);

	gamma = w/l;
	beta = gamma/2;
	setstyle(SOLID_LINE, 0.0);
	fprintf(tfp, "\\arrow <%6.3fin> [%6.3f,%6.3f] from %6.3f %6.3f to %6.3f %6.3f\n",
		l*mag, beta, gamma, ex, ey, ax, ay);
}


/*
 * rtop - rectangular to polar conversion
 */
rtop(x, y, r, th)
double x, y, *r, *th;
{
	*r = hypot(x,y);
	*th = acos(x/(*r)) * 90 /acos(0.0);

	if (y < 0) *th = 360 - *th;
}


/****************************************************************************

	The following spline drawing routine is from 

	"An Algorithm for High-Speed Curve Generation" 
	by George Merrill Chaikin,
	Computer Graphics and Image Processing, 3, Academic Press, 
	1974, 346-349.

	and

	"On Chaikin's Algorithm" by R. F. Riesenfeld,
	Computer Graphics and Image Processing, 4, Academic Press, 
	1975, 304-310.

*****************************************************************************/

chaikin_spline(x1, y1, x2, y2, x3, y3, x4, y4)
float	x1, y1, x2, y2, x3, y3, x4, y4;
{
	float	xmid, ymid;

	xmid = (x2 + x3) / 2;  ymid = (y2 + y3) / 2;
	if (fabs(x1 - xmid) < 1 && fabs(y1 - ymid) < 1) 
	    draw_vector(x1, y1, xmid, ymid);

	else {
	    chaikin_spline(x1, y1, 
			((x1 + x2) / 2),  ((y1 + y2) / 2),
			((3*x2 + x3) / 4), ((3*y2 + y3) / 4), xmid, ymid);
	    }

	if (fabs(xmid - x4) < 1 && fabs(ymid - y4) < 1) {
	    draw_vector(xmid, ymid, x4, y4);
	    }
	else {
	    chaikin_spline(xmid, ymid, 
			((x2 + 3*x3) / 4),  ((y2 + 3*y3) / 4),
			((x3 + x4) / 2),  ((y3 + y4) / 2), x4, y4);

	    }
	}

draw_vector(x1, y1, x2, y2)
float x1, y1, x2, y2;
{
	fprintf(tfp, "\t%6.3f %6.3f\n",
		x2 / PIX_PER_INCH, y2 / PIX_PER_INCH);
}


/********************************************************************

	LaTeX Object Optimizer Routines

********************************************************************/

/*
 * Slopes implemented in LaTeX and the corresponding args to \line
 */
float slopes[][2]= {	{0.,1.},
			{1.,1.},{2.,1.},{3.,1.},{4.,1.},{5.,1.},{6.,1.},
			{1.,2.},	{3.,2.},	{5.,2.},
			{1.,3.},{2.,3.},	{4.,3.},{5.,3.},
			{1.,4.},	{3.,4.},	{5.,4.},
			{1.,5.},{2.,5.},{3.,5.},{4.,5.},{6.,5.},
			{1.,6.},			{5.,6.},
			{-1.,0.}};

float upslope[2]={1.,0.}, downslope[2]={-1.,0.};

/*
 * latexline - generate a LaTeX line if possible
 */
latexline(x1, y1, x2, y2)
float x1, y1, x2, y2;
{
	float *lineargs;
	float len, sl, t, delta;
	int  sign = 1;
	int i;

	if (cur_style != SOLID_LINE) return(0);

	if (CLOSE(x1, x2)) {

	    len = fabs(y2-y1);
	    if (y2 > y1)

	        lineargs = upslope;
	    else {
	    	lineargs = downslope;
		}
	     }
	else {

	    if (x2 < x1) {
		SWITCH(float, x1, x2);
		SWITCH(float, y1, y2);
		}

	    len = x2 - x1;
	    if (len*mag < 1/7.) return(0);

	    sl = (y2 - y1) / (x2 - x1);
	    if (sl < 0) {
		sl = -sl;
		sign = -1;
	    }

	
	    for (i=0, delta=1.0; slopes[i][0] >= 0; i++) 
		if ((t = fabs(atan(sl) - atan(slopes[i][0]/slopes[i][1]))) < delta) {
		    delta = t;
		    lineargs = slopes[i];
		}
	    }

	if (CLOSE(delta, 0.0)) {
	    fprintf(tfp, "\\if \\picturemode \\optpics\n");
	    fprintf(tfp,"\\put {\\line(%.0f,%.0f){%6.3f}} [Bl] at %6.3f %6.3f\n",
		    	lineargs[1], sign*lineargs[0], len, x1, y1);
	    return(1);
 	    }
	else
	    return(0);

    }

/*
 * latexcircle - generate a LaTeX circle if possible
 */
latexcircle(w, h, x, y)
float w, h, x, y;
{
	if (cur_style != SOLID_LINE) return(0);
	if (!CLOSE(w, h)) return(0);
	if (2*w > 15.5/72.27) return(0);

	fprintf(tfp, "\\if \\picturemode \\optpics\n");
	fprintf(tfp, "\\put {\\circle{%6.3f}} [lB] at %6.3f %6.3f\n",
		    2*w, x, y);
	return(1);
}