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

⟦7f8dd5eac⟧ TextFile

    Length: 9521 (0x2531)
    Types: TextFile
    Names: »gf.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./DVIware/laser-setters/quicspool/src/gf.c« 
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/laser-setters/quicspool/src/gf.c« 

TextFile

#ifndef lint
static char *rcs = "$Header: gf.c,v 1.1 88/01/15 13:04:05 simpson Rel $";
#endif
/*
$Log:	gf.c,v $
 * Revision 1.1  88/01/15  13:04:05  simpson
 * initial release
 * 
 * Revision 0.1  87/12/11  18:30:56  simpson
 * beta test
 * 
*/
#include <stdio.h>
#include <signal.h>
#include <math.h>
#include <local/standard.h>
#include <local/qms.h>
#include <local/profile.h>
#include "constants.h"
#include "fontnode.h"

enum linetypes { dotted, solid, longdashed, shortdashed, dotdashed };
char	*Whoami;	/* argv[0] */
int	X, Y;
int	PortraitFont = 1204;
int	LandscapeFont = 1217;
int	curx, cury, lowx, lowy, highx, highy;
double  scalefactor;
enum linetypes linetype = solid;
extern char	*User;
extern char	*Host;
extern Boolean	Accounting;
extern int	NumPages;
extern FILE	*Accting;

main(argc, argv)
int	argc;
char	*argv[];
{
    extern int	    optind;
    extern char	    *optarg;
    PROFILE_VALUE   *v, *getbindingvalue();
    struct sigvec   SigStruct;
    int		    c, callcleanup();
    int		    xi, yi, x0, y0, x1, y1, r;
    char	    s[256];
    void	    sanestate(), openpl(), move(), line(), label(), erase(),
		    point(), cont(), space(), arc(), circle(), linemod(),
		    closepl(), getstring();
    void	    cleanup();

    Whoami = argv[0];
    while ((c = getopt(argc, argv, "x:y:n:h:w:l:")) != EOF)
	switch (c) {
	case 'x':
	    X = atoi(optarg);
	    break;
	case 'y':
	    Y = atoi(optarg);
	    break;
	case 'l':
	case 'w':
	    break;
	case 'n':
	    User = optarg;
	    break;
	case 'h':
	    Host = optarg;
	    break;
	case '?':
	    exit(2);
	}
    if (optind < argc) {
	Accounting = TRUE;
	if (!(Accting = fopen(argv[optind], "a"))) {
	    fprintf(stderr,"%s: cannot open accounting file %s\r\n", Whoami,
	    argv[optind]);
	    Accounting = FALSE;
	}
    }
    if (X > 2550) {
	if ((v = getbindingvalue("landscapefont")) && v->class ==
	PROFILE_INTEGER)
	    LandscapeFont = v->value.i;
    } else if ((v = getbindingvalue("portraitfont")) && v->class ==
    PROFILE_INTEGER)
	PortraitFont = v->value.i;
    SigStruct.sv_handler = callcleanup;
    SigStruct.sv_mask = 0;
    SigStruct.sv_onstack = 0;
    (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
    openpl();
    while ((c = getchar()) != EOF)
	switch (c) {
	case 'm':
	    xi = getsi(stdin);
	    yi = getsi(stdin);
	    move(xi,yi);
	    break;
	case 'l':
	    x0 = getsi(stdin);
	    y0 = getsi(stdin);
	    x1 = getsi(stdin);
	    y1 = getsi(stdin);
	    line(x0,y0,x1,y1);
	    break;
	case 't':
	    getstring(s,stdin);
	    label(s);
	    break;
	case 'e':
	    erase();
	    break;
	case 'p':
	    xi = getsi(stdin);
	    yi = getsi(stdin);
	    point(xi,yi);
	    break;
	case 'n':
	    xi = getsi(stdin);
	    yi = getsi(stdin);
	    cont(xi,yi);
	    break;
	case 's':
	    x0 = getsi(stdin);
	    y0 = getsi(stdin);
	    x1 = getsi(stdin);
	    y1 = getsi(stdin);
	    space(x0,y0,x1,y1);
	    break;
	case 'a':
	    xi = getsi(stdin);
	    yi = getsi(stdin);
	    x0 = getsi(stdin);
	    y0 = getsi(stdin);
	    x1 = getsi(stdin);
	    y1 = getsi(stdin);
	    arc(xi,yi,x0,y0,x1,y1);
	    break;
	case 'c':
	    xi = getsi(stdin);
	    yi = getsi(stdin);
	    r = getsi(stdin);
	    circle(xi,yi,r);
	    break;
	case 'f':
	    getstring(s,stdin);
	    linemod(s);
	    break;
	}
    (void)sigblock(SIGINT);
    closepl();
    fputs(QUICON, stdout);
    cleanup((struct FontNode *)NULL, SUCCEED);
}

callcleanup()
{
    void	cleanup();

    closepl();
    fputs(QUICON, stdout);
    cleanup((struct FontNode *)NULL, SUCCEED);
}

void openpl()
{
    fputs(QUICON, stdout);
    if (X > 2550)
	fputs(LANDSCAPE, stdout);
    else
	fputs(PORTRAIT, stdout);
    printf("%s00000", SYNTAX);
    printf("%s00000%05d", INITMARGVERT, X > 2550 ? (int)(8.5 * 1000) : 11 *
    1000);
    printf("%s00000%05d", INITMARGHORZ, X > 2550 ? 11 * 1000 : (int)(8.5 *
    1000));
    printf("%s%d%s", DEFFONT, X > 2550 ? LandscapeFont : PortraitFont,
    ENDCMD);
    fputs(FREEOFF, stdout);
    fputs(VECTORON, stdout);
}

void move(x, y)
int	x, y;
{
    curx = x;
    cury = y;
}

void line(x1, y1, x2, y2)
int	x1, y1, x2, y2;
{
    fputs(VECTORON, stdout);
    fputs("^V", stdout);
    switch (linetype) {
    case dotted:
	printf("2");
	break;
    case shortdashed:
	printf("4");
	break;
    case longdashed:
	printf("6");
	break;
    case dotdashed:
	printf("7");
	break;
    default:
	printf("0");
	break;
    } /* end switch */
    printf("^U%05d:%05d", (int)((x1 - lowx) * scalefactor / 300.0 * 1000.0), 
    (int)(((X > 2550 ? 8.5 : 11) - ((y1 - lowy) * scalefactor / 
    300.0)) * 1000.0));
    printf("^D%05d:%05d", (int)((x2 - lowx) * scalefactor / 300.0 * 1000.0),
    (int)(((X > 2550 ? 8.5 : 11) - ((y2 - lowy) * scalefactor / 
    300.0)) * 1000.0));
    fputs(VECTOROFF, stdout);
    curx = x2, cury = y2;
}

void label(s)
char	*s;
{
    double	scale;
    char	*ptr;

    /* Each character is assumed to be 54 units wide without scaling.
       Since the QMS fonts are proportional make sure that they are typeset
       in the right place. The minimum width can be 45 dots (a 'W' in
       font 1204) so adjust "scale" in case scalefactor would make
       the width smaller than this.
           54*x = 45      x = 45/54 = 0.833333
    */
    scale = scalefactor;
    if (scale < 0.833333)
	scale = 0.833333;
    for (ptr = s; *ptr != '\0' && *ptr != '\n'; ptr++) {
	printf("\r^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - (cury - 
	lowy) * scalefactor / 300.0) * 1000.0));
	printf("%s-00170", JUSTIFYRELATIVE);
	printf("^IH%05d", (int)((curx - lowx) * scalefactor / 300.0 *
	1000.0));
	if (ptr - s > 0)
	    printf("%s+%05d", TABRELATIVE, (int)(54 * (ptr - s) * scale / 
	    300.0 * 1000.0));
	(void)putchar(*ptr);
    }
}

void erase()
{
    NumPages++;
    putchar('\r');
    fputs(FORMFEED, stdout);
}

void point(x, y)
{
    printf("^IH%05d", (int)((((curx - lowx) * scalefactor - 5.0) / 300.0)
	* 1000.0));
    printf("^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy) 
    * scalefactor - 5.0) / 300.0) * 1000.0));
    printf("%s0003300033", LINE);
    curx = x;
    cury = y;
}

void cont(x, y)
int x, y;
{
    fputs(VECTORON, stdout);
    fputs("^V", stdout);
    switch (linetype) {
    case dotted:
	printf("2");
	break;
    case shortdashed:
	printf("4");
	break;
    case longdashed:
	printf("6");
	break;
    case dotdashed:
	printf("7");
	break;
    default:
	printf("0");
	break;
    } /* end switch */
    printf("^U%05d:%05d", (int)((curx - lowx) * scalefactor / 300.0 *
    1000.0), (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy) * 
    scalefactor / 300.0)) * 1000.0));
    printf("^D%05d:%05d", (int)((x - lowx) * scalefactor / 300.0 * 
    1000.0), (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) * 
    scalefactor / 300.0)) * 1000.0));
    fputs(VECTOROFF, stdout);
    curx = x, cury = y;
}

void space(x0, y0, x1, y1)
int	x0, y0, x1, y1;
{
    double	xscale, yscale;

    lowx = x0;
    highx = x1;
    lowy = y0;
    highy = y1;
    /* Pick smallest scale factor (x or y) and use it. Don't scale different
     * x and y directions or the image will become distorted.
     */
    xscale = (double)X / (highx - lowx);
    yscale = (double)Y / (highy - lowy);
    if (xscale > yscale)
	scalefactor = yscale > 1.0 ? 1.0 : yscale;
    else
	scalefactor = xscale > 1.0 ? 1.0 : xscale;
}

void arc(x, y, x0, y0, x1, y1)
{
    double	dx, dy, startangle, endangle;

    fputs(DECIMALARC, stdout);
    printf("+%05d+%05d", (int)((x - lowx) * scalefactor / 300.0 * 1000.0),
    (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) * scalefactor / 300.0)) * 
    1000.0));
    printf("%05d", (int)(sqrt(pow((double)x0 - x, 2.0) + 	/* radius */
    pow((double)y0 - y, 2.0)) * scalefactor / 300.0 * 1000.0));
    dx = x0 - x;
    dy = y0 - y;
    if (dx == 0.0)
	startangle = dy > 0.0 ? 90.0 : -90.0;
    else
	startangle = atan2(dy, dx) / PI * 180.0;
    if (startangle < 0.0)
	startangle += 360.0;
    startangle = 1000.0 - (startangle / 360.0 * 1000.0);
    if (startangle == 1000.0) 	/* QMS only takes 3 digits */
	startangle = 999.0;
    dx = x1 - x;
    dy = y1 - y;
    if (dx == 0.0)
	endangle = dy > 0.0 ? 90.0 : -90.0;
    else
	endangle = atan2(dy, dx) / PI * 180.0;
    if (endangle < 0.0)
	endangle += 360.0;
    endangle = 1000.0 - (endangle / 360.0 * 1000.0);
    if (endangle == 1000.0)
	endangle = 999.0;
    /* Since the QMS draws clockwise, reverse points */
    printf("%03d%03d", (int)endangle, (int)startangle);
    fputs("04", stdout);
    fputs(ENDCMD, stdout);
}

void circle(x, y, r)
int	x, y, r;
{
    arc(x, y, x + r, y, x - r, y);
    arc(x, y, x - r, y, x + r, y);
}

void linemod(s)
char	*s;
{
    int		stringlen;
    char	*index();

    if (index(s, '\n'))
	stringlen = s - index(s, '\n');
    else
	stringlen = 100;
    if (EQN(s, "dotted", stringlen))
	linetype = dotted;
    else if (EQN(s, "dotdashed", stringlen))
	linetype = dotdashed;
    else if (EQN(s, "longdashed", stringlen))
	linetype = longdashed;
    else if (EQN(s, "shortdashed", stringlen))
	linetype = shortdashed;
    else
	linetype = solid;
}

void closepl()
{
    NumPages++;
    (void)putchar('\r');
    fputs(FORMFEED, stdout);
    fputs(QUICOFF, stdout);
}

/* Get an integer stored in 2 ascii bytes */
int getsi(fin)
FILE *fin;
{
    short	a, b;

    if ((b = getc(fin)) == EOF)
	return(EOF);
    if ((a = getc(fin)) == EOF)
	return(EOF);
    a <<= 8;
    return a | b;
}

void getstring(s, fin)
char	*s;
FILE	*fin;
{
    for (; *s = getc(fin); s++)
	if (*s == '\n')
	    break;
    *s = '\0';
}