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

⟦f756c9849⟧ TextFile

    Length: 11817 (0x2e29)
    Types: TextFile
    Names: »genpic.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/genpic.c« 

TextFile

/* 
 *	genpic : PIC driver for fig2dev
 *
 *	Author: Conrad Kwok, UC Davis, 12/88
 *      Modified: Richard Auletta, George Mason Univ., 6/21/89
 *	Added code comments are marked with "rja".
 *      Added: Support for native pic arrowheads.
 *      Added: Support for arrowheads at both ends of lines, arc, splines.
 */

#include <stdio.h>
#include <math.h>
#include "object.h"
#include "fig2dev.h"
#include "picfonts.h"

void genpic_ctl_spline(), genpic_itp_spline();
void genpic_open_spline(), genpic_closed_spline();

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

void genpic_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 '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, "pic");
		exit(1);
	}
}

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

void genpic_start(objects)
F_compound	*objects;
{
	int		coord_system;

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

	fprintf(tfp, ".PS\n.ps %d\n", font_size);	/* PIC preamble */
}

void genpic_end()
{
	fprintf(tfp, ".PE\n", font_size);	/* PIC ending */
}

/*
The line thickness is, unfortunately, multiple of pixel.
One pixel thickness is a little too thick on the hard copy
so I scale it with 0.7; i.e., it's a kludge.  The best way is
to allow thickness in fraction of pixel.

Note that the current version of psdit (a ditroff to postcript filter)
won't take the legitimate line thickness command.
*/
static set_linewidth(w)
int	w;
{
	static int	cur_thickness = -1;

	/*
	if (w == 0) return;
	if (w != cur_thickness) {
	    cur_thickness = w;
	    fprintf(tfp, "\"\\D't %.5fi'\"\n", 0.7 * cur_thickness / ppi);
	    }
	*/
	}

static set_style(s, v)
int	s;
float	v;
{
	static float	style_val = -1;

	if (s == DASH_LINE || s == DOTTED_LINE) {
	    if (v == style_val) return;
	    if (v == 0.0) return;
	    style_val = v;
	    fprintf(tfp, "dashwid = %.3fi\n", style_val/ppi);
	    }
	}

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

	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, "line from %.3f,%.3f to %.3f,%.3f\n",
			p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
	    return;
	    }


	if (l->style == DASH_LINE && l->style_val > 0.0)
	    fprintf(tfp, "line dashed");
	else if (l->style == DOTTED_LINE && l->style_val > 0.0)
	    fprintf(tfp, "line dotted");
	else
	    fprintf(tfp, "line");

	/*rja: Place arrowheads or lack there of on the line*/
	if ((l->for_arrow) && (l->back_arrow))
	    fprintf(tfp, " <-> from");
	else if (l->back_arrow)
	    fprintf(tfp, " <- from");
	else if (l->for_arrow)
	    fprintf(tfp, " -> from");
        else
	    fprintf(tfp, " from ");

	fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
	while (q->next != NULL) {
	    p = q;
	    q = q->next;
	    fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
	    }
	fprintf(tfp, " %.3f,%.3f\n", q->x/ppi, convy(q->y/ppi));
	}

void genpic_spline(s)
F_spline	*s;
{
	if (int_spline(s))
	    genpic_itp_spline(s);
	else
	    genpic_ctl_spline(s);
	}

void genpic_ctl_spline(s)
F_spline	*s;
{
	if (closed_spline(s))
	    genpic_closed_spline(s);
	else
	    genpic_open_spline(s);
	}

void genpic_open_spline(s)
F_spline	*s;
{
	double		x1, y1, x2, y2;
	F_point		*p, *q;

	p = s->points;
	x1 = p->x/ppi; y1 = convy(p->y/ppi);
	p = p->next;
	x2 = p->x/ppi; y2 = convy(p->y/ppi);


	/* Pic's spline supports only solid line style */
	/* set_linewidth(s->thickness); */

	if (p->next == NULL) {
	    fprintf(tfp, "line");

           /*rja: Attach arrowhead as required */
	    if ((s->for_arrow) && (s->back_arrow))
	       fprintf(tfp, " <->");
	    else if (s->back_arrow)
	       fprintf(tfp, " <-");
	    else if (s->for_arrow)
	       fprintf(tfp, " ->");

	    fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f\n", x1, y1, x2, y2);
	    return;
	    }

	fprintf(tfp, "spline"); 

           /*rja: Attach arrowhead as required */
	    if ((s->for_arrow) && (s->back_arrow))
	       fprintf(tfp, " <->");
	    else if (s->back_arrow)
	       fprintf(tfp, " <-");
	    else if (s->for_arrow)
	       fprintf(tfp, " ->");

	fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);

	for (q = p->next; q->next != NULL; p = q, q = q->next)
	    fprintf(tfp, " to %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
	fprintf(tfp, " to %.3f,%.3f\n", (x2=q->x/ppi), (y2=convy(q->y/ppi)));

	}

void genpic_ellipse(e)
F_ellipse	*e;
{
	set_linewidth(e->thickness);
	fprintf(tfp, "ellipse at %.3f,%.3f wid %.3f ht %.3f\n",
		e->center.x/ppi, convy(e->center.y/ppi),
		2 * e->radiuses.x/ppi, 2 * e->radiuses.y/ppi);
	}

/*
Text is display on the screen with the base line starting at
(base_x, base_y); some characters extend below this line.
Pic displays the center of the height of text at the given
coordinate. HT_OFFSET is use to compensate all the above factors
so text position in fig 1.4 should be at the same position on
the screen as on the hard copy.
*/
#define			HT_OFFSET	(0.2 / 72.0)

void genpic_text(t)
F_text	*t;
{
	float	y;
        char *tpos;
	int all_default = 0;

	/* all_default = all_default && t->font <= 0 && t->size <= 0 ; */

	if (all_default)
	  fprintf(tfp, "\"");
	else
	  fprintf(tfp, "\"\\s%d\\f%s", PICFONTSIZE(t->size), PICFONT(t->font) );

        switch (t->type) {
        case T_LEFT_JUSTIFIED:
        case DEFAULT:
            tpos = "ljust";
            break;
        case T_CENTER_JUSTIFIED:
            tpos = "";
            break;
        case T_RIGHT_JUSTIFIED:
            tpos = "rjust";
            break;
        default:
            fprintf(stderr, "unknown text position type\n");
            exit(1);
        }    
	y = convy(t->base_y/ppi) + PICFONTSIZE(t->size) * HT_OFFSET;

	if (all_default)	
		fprintf(tfp, "%s\" at %.3f,%.3f %s\n",
			t->cstring, t->base_x/ppi, y, tpos);
	else
		fprintf(tfp, "%s\\fP\" at %.3f,%.3f %s\n",
			t->cstring, t->base_x/ppi, y, tpos);
	}

void genpic_arc(a)
F_arc	*a;
{
	double		x, y;
	double		cx, cy, sx, sy, ex, ey;

	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);

	set_linewidth(a->thickness);

	    fprintf(tfp, "arc ");

           /*rja: Attach arrowhead as required */
	    if ((a->for_arrow) && (a->back_arrow))
	       fprintf(tfp, " <->");
	    else if (a->back_arrow)
	       fprintf(tfp, " <-");
	    else if (a->for_arrow)
	       fprintf(tfp, " ->");


	if (a->direction)
	    fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f\n",
			cx, cy, sx, sy, ex, ey);
	else
	    fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f cw\n",
			cx, cy, sx, sy, ex, ey);

	}

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)	*/

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;

	dx = x2 - x1;  dy = y1 - y2;
	l = sqrt((dx*dx + dy*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;
	fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f to %.3f,%.3f\n",
		xc, yc, x2, y2, xd, yd);
	}

#define		THRESHOLD	.05	/* inch */

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, "\tto %.3f,%.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, "\tto %.3f,%.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);
	    }
	}

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

	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;

	for (p = p->next; p != NULL; p = p->next) {
	    fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
	    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);
	    fprintf(tfp, "\n");
	    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;
	fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
	quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
	fprintf(tfp, "\n");
	}

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

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

         pfirst = p1->next;/*save first to test in loop*/
	for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
		p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {

	    fprintf(tfp, "line ");

           /*rja: Attach arrowhead as required */

	    if ((s->back_arrow) && (p2 == pfirst))
	       fprintf(tfp, " <- ");
	    else if ((s->for_arrow) && (p2->next == NULL))
	       fprintf(tfp, " -> ");

	    fprintf(tfp, " from %.3f,%.3f ", x2, y2);

	    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, "\n");
	    }

	}

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, "\tto %.3f,%.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_pic = {
     	genpic_option,
	genpic_start,
	genpic_arc,
	genpic_ellipse,
	genpic_line,
	genpic_spline,
	genpic_text,
	genpic_end,
	INCLUDE_TEXT
};