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 g

⟦732ad8d2e⟧ TextFile

    Length: 13702 (0x3586)
    Types: TextFile
    Names: »genpictex.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« 
        └─⟦036c765ac⟧ 
            └─⟦this⟧ »TeX3.0/TeXgraphics/transfig/fig2dev/dev/genpictex.c« 

TextFile

/* 
 *	genpictex.C : PiCTeX driver for fig2dev
 *
 * 	Author Micah Beck, Cornell University, 4/88
 *	(beck@svax.cs.cornell.edu)
*/
#ifdef hpux
#include <sys/types.h>
#endif
#include <sys/file.h>
#include <stdio.h>
#include <math.h>
#include "pi.h"
#include "object.h"
#include "fig2dev.h"
#include "texfonts.h"

extern char *strchr();
extern void fprintf();
extern double sin(), cos(), acos(), fabs();

void genpictex_ctl_spline(), genpictex_itp_spline();

static int		coord_system;
static double		dash_length = -1;
static int		line_style = SOLID_LINE;
static char 		*linethick = "0.7pt";
static char		*plotsymbol = "\\sevrm .";

static void genpictex_option(opt, optarg)
char opt, *optarg;
{
	switch (opt) {

		case 'f':			/* set default text font */
	        {   int i;

		    for ( i = 1; i <= MAXFONT + 1; i++ )
			if ( !strcmp(optarg, fontnames[i]) ) break;

		    if ( i > MAXFONT + 1 )
			fprintf(stderr,
				"warning: non-standard font name %s\n", optarg);
		}
		
		    fontnames[0] = fontnames[1] = optarg;
		    break;

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

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

		case 's':
		    if (font_size <= 0 || font_size > MAXFONTSIZE) {
			fprintf(stderr,
				"warning: font size %d out of bounds\n", font_size);
		    }
		    break;

		case 'm':
		case 'L':
		    break;

	default:
		put_msg(Err_badarg, opt, "pictex");
		exit(1);
		break;
	}
}

#define			TOP	10.5	/* top of page is 10.5 inch */
static double		ppi;
static int		CONV = 0;

static double convy(a)
double	a;
{
	return((double)(CONV ? TOP-a : a));
}

void genpictex_start(objects)
F_compound	*objects;
{
	fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);

	coord_system = objects->nwcorner.y;
	ppi = objects->nwcorner.x;
	if (coord_system == 2) CONV = 1;

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

void genpictex_end()
{
	/* PiCTeX ending */
	fprintf(tfp, "\\linethickness=0pt\n");
        fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
		llx/ppi, convy(lly/ppi), urx/ppi, convy(ury/ppi));
	fprintf(tfp, "\\endpicture}\n");
}

static set_linewidth(w)
int	w;
{
	static int	cur_thickness = -1;

	if (w == 0) return;
	if (w != cur_thickness) {
	    cur_thickness = w;
/*	fprintf(tfp, "\\linethickness=%6.3fin\n",0.7 * cur_thickness);*/
/* PIC  fprintf(tfp, "\"D't %.3fi'\"\n", 0.7 * cur_thickness);*/
	    }
	}

void genpictex_line(l)
F_line	*l;
{
	F_point		*p, *q;

	fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");

	set_linewidth(l->thickness);
	set_style(l->style, l->style_val);

	p = l->points;
	q = p->next;

	if (q == NULL) { /* A single point line */
	    fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
			p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
	    return;
	    }
	if (l->back_arrow)
	    draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi,
		convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi);
	set_style(l->style, l->style_val);

	while (q->next != NULL) {

	    putline(p->x, p->y, q->x, q->y);
	    p = q;
	    q = q->next;
	    }

	putline(p->x, p->y, q->x, q->y);
	if (l->for_arrow)
	    draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi,
		convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi);

	if (l->area_fill && (int)l->area_fill != DEFAULT)
		fprintf(stderr, "Line area fill not implemented\n");
	}

/* 
 * set_style - issue style commands as appropriate
 */
static set_style(style, dash_len)
int style;
double dash_len;
{
    switch (style) {
	 case SOLID_LINE:
	    if (line_style == SOLID_LINE) break;
	    fprintf(tfp, "\\setsolid\n");
	    break;

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

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

	line_style = style;
	dash_length = dash_len;
    }

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

    else {
	fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
		start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi));
	}
}


void genpictex_spline(s)
F_spline	*s;
{
	set_linewidth(s->thickness);
	set_style(s->style, s->style_val);

	if (int_spline(s))
	    genpictex_itp_spline(s);
	else
	    genpictex_ctl_spline(s);

	if (s->area_fill && (int)s->area_fill != DEFAULT)
		fprintf(stderr, "Spline area fill not implemented\n");
}

void genpictex_ellipse(e)
F_ellipse	*e;
{
	fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");

	set_linewidth(e->thickness);
	set_style(e->style, e->style_val);

	if ((e->area_fill == BLACK_FILL) && (e->radiuses.x == e->radiuses.y))
 		fprintf(tfp, "\\put{\\circle*{%6.3f}} at %6.3f %6.3f\n",
		    2*e->radiuses.x/ppi,
		    (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi));

	else {

		fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n",
		    e->radiuses.x/ppi, e->radiuses.y/ppi);
		fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n",
		    (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi),
		    e->center.x/ppi, convy(e->center.y/ppi));
		if (e->area_fill && (int)e->area_fill != DEFAULT)
			fprintf(stderr, "Ellipse area fill not implemented\n");
		}
	}

#define			HT_OFFSET	(0.2 / 72.0)

void genpictex_text(t)
F_text	*t;
{
	double	x, y;
	char *tpos, *cp;

        fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");

	x = t->base_x/ppi;
	y = convy(t->base_y/ppi);

	switch (t->type) {

	    case T_LEFT_JUSTIFIED:
	    case DEFAULT:
	    	tpos = "[lB]";
		break;

	    case T_CENTER_JUSTIFIED:
	    	tpos = "[B]";
		break;

	    case T_RIGHT_JUSTIFIED:
	    	tpos = "[rB]";
		break;

	    default:
		fprintf(stderr, "Text incorrectly positioned\n");
		return;
	    }

	fprintf(tfp, "\\put {\\%s%s ",
		TEXFONTSIZE(t->size), TEXFONT(t->font));

	if (t->font && t->font !=DEFAULT)

		/* this loop escapes characters "$&%#_{}" */
		/* and deleted characters "~^\" */
		for(cp = t->cstring; *cp; cp++) {
	      	    if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp);
	      	    if (strchr("~^\\", *cp))
			fprintf(stderr,
				"Bad character in text object '%c'\n" ,*cp);
		    else
			(void)fputc(*cp, tfp);
	      	}
	else 
		fprintf(tfp, "%s", t->cstring);

 	fprintf(tfp, "} %s at %6.3f %6.3f\n",
	    tpos, x, y);
	}

void genpictex_arc(a)
F_arc	*a;
{
	double		x, y;
	double		cx, cy, sx, sy, ex, ey;
	double		dx1, dy1, dx2, dy2, r1, r2, th1, th2, theta;

	set_linewidth(a->thickness);
	set_style(a->style, a->style_val);

	cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
	sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
	ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);

	if (a->for_arrow) {
	    arc_tangent(cx, cy, ex, ey, a->direction, &x, &y);
	    draw_arrow_head(x, y, ex, ey,
			a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
	    }
	if (a->back_arrow) {
	    arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y);
	    draw_arrow_head(x, y, sx, sy,
			a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
	    }

	dx1 = sx - cx;
	dy1 = sy - cy;
	dx2 = ex - cx;
	dy2 = ey - cy;
	    
	rtop(dx1, dy1, &r1, &th1);
	rtop(dx2, dy2, &r2, &th2);
	theta = th2 - th1;
	if (theta > 0) theta -= 2*M_PI;

	set_linewidth(a->thickness);

	if (a->direction)
		fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
			360+(180/M_PI * theta), sx, sy, cx, cy);
	else
		fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
			-180/M_PI * theta, ex, ey, cx, cy);

	if (a->area_fill && (int)a->area_fill != DEFAULT)
		fprintf(stderr, "Arc area fill not implemented\n");
	}



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

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

static arc_tangent(x1, y1, x2, y2, direction, x, y)
double	x1, y1, x2, y2, *x, *y;
int	direction;
{
	if (direction) { /* counter clockwise  */
	    *x = x2 + (y2 - y1);
	    *y = y2 - (x2 - x1);
	    }
	else {
	    *x = x2 - (y2 - y1);
	    *y = y2 + (x2 - x1);
	    }
	}

/*	draw arrow heading from (x1, y1) to (x2, y2)	*/

static draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
double	x1, y1, x2, y2, arrowht, arrowwid;
{
	double	x, y, xb, yb, dx, dy, l, sina, cosa;
	double	xc, yc, xd, yd;
	int style;
	double dash;

        fprintf(tfp, "%%\n%% arrow head\n%%\n");

	dx = x2 - x1;  dy = y1 - y2;
	l = hypot(dx, dy);
	sina = dy / l;  cosa = dx / l;
	xb = x2*cosa - y2*sina;
	yb = x2*sina + y2*cosa;
	x = xb - arrowht;
	y = yb - arrowwid / 2;
	xc = x*cosa + y*sina;
	yc = -x*sina + y*cosa;
	y = yb + arrowwid / 2;
	xd = x*cosa + y*sina;
	yd = -x*sina + y*cosa;

	/* save line style and set to solid */
	style = line_style;
	dash = dash_length;
	set_style(SOLID_LINE, 0.0);

	fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f /\n%%\n",
		xc, yc, x2, y2, xd, yd);

	/* restore line style */
	set_style(style, dash);
	}

#define		THRESHOLD	.05	/* inch */

static quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
double	a1, b1, a2, b2, a3, b3, a4, b4;
{
	double	x1, y1, x4, y4;
	double	xmid, ymid;

	x1 = a1; y1 = b1;
	x4 = a4; y4 = b4;
	xmid = (a2 + a3) / 2;
	ymid = (b2 + b3) / 2;
	if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
	    fprintf(tfp, "\t%6.3f %6.3f\n", xmid, ymid);

	else {
	    quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
			((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
	    }

	if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
	    fprintf(tfp, "\t%6.3f %6.3f\n", x4, y4);

	else {
	    quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
			((a3+x4)/2), ((b3+y4)/2), x4, y4);
	    }
	}

static void genpictex_ctl_spline(s)
F_spline	*s;
{
	F_point	*p;
	double	cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
	double	x1, y1, x2, y2;

    	fprintf(tfp, "%%\n%% Fig CONTROL PT SPLINE\n%%\n");

	p = s->points;
	x1 = p->x/ppi;  y1 = convy(p->y/ppi);
	p = p->next;
	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
	cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
	cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;

	if (closed_spline(s)) {
	    fprintf(tfp, "%% closed spline\n%%\n");
	    fprintf(tfp, "\\plot\t%6.3f %6.3f \n ", cx1, cy1);
	    }
	else {
	    fprintf(tfp, "%% open spline\n%%\n");
	    if (s->back_arrow)
	        draw_arrow_head(cx1, cy1, x1, y1,
			s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
	    fprintf(tfp, "\\plot\t%6.3f %6.3f %6.3f %6.3f\n ",
		x1, y1, cx1, cy1);
	    }

	for (p = p->next; p != NULL; p = p->next) {
	    x1 = x2;  y1 = y2;
	    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
	    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
	    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
	    cx1 = cx4;  cy1 = cy4;
	    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
	    }
	x1 = x2;  y1 = y2;
	p = s->points->next;
	x2 = p->x/ppi;  y2 = convy(p->y/ppi);
	cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
	cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
	if (closed_spline(s)) {
	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
	    fprintf(tfp, "\t/\n");
	    }
	else {
	    fprintf(tfp, "\t /\n\\plot %6.3f %6.3f %6.3f %6.3f /\n",
		cx1, cy1, x1, y1);
	    if (s->for_arrow)
	    	draw_arrow_head(cx1, cy1, x1, y1,
			s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
	    }

	}

static void genpictex_itp_spline(s)
F_spline	*s;
{
	F_point		*p1, *p2;
	F_control	*cp1, *cp2;
	double		x1, x2, y1, y2;

	p1 = s->points;
	cp1 = s->controls;
	x2 = p1->x/ppi; y2 = convy(p1->y/ppi);

	if (s->back_arrow)
	    draw_arrow_head(cp1->rx/ppi, convy(cp1->ry/ppi), x2, y2,
		s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);

	fprintf(tfp, "\\plot %6.3f %6.3f ", x2, y2);
	for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
		p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
	    x1 = x2; y1 = y2;
	    x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
	    bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
		(double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
	    }
	fprintf(tfp, "\t/\n");

	if (s->for_arrow)
	    draw_arrow_head(cp1->lx/ppi, convy(cp1->ly/ppi), x2, y2,
		s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
	}

static bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
double	a0, b0, a1, b1, a2, b2, a3, b3;
{
	double	x0, y0, x3, y3;
	double	sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;

	x0 = a0; y0 = b0;
	x3 = a3; y3 = b3;
	if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
	    fprintf(tfp, "\t%6.3f %6.3f\n", x3, y3);

	else {
	    tx = (a1 + a2) / 2;		ty = (b1 + b2) / 2;
	    sx1 = (x0 + a1) / 2;	sy1 = (y0 + b1) / 2;
	    sx2 = (sx1 + tx) / 2;	sy2 = (sy1 + ty) / 2;
	    tx2 = (a2 + x3) / 2;	ty2 = (b2 + y3) / 2;
	    tx1 = (tx2 + tx) / 2;	ty1 = (ty2 + ty) / 2;
	    xmid = (sx2 + tx1) / 2;	ymid = (sy2 + ty1) / 2;

	    bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
	    bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
	    }
	}

struct driver dev_pictex = {
     	genpictex_option,
	genpictex_start,
	genpictex_arc,
	genpictex_ellipse,
	genpictex_line,
	genpictex_spline,
	genpictex_text,
	genpictex_end,
	EXCLUDE_TEXT
};