|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 9521 (0x2531)
Types: TextFile
Names: »gf.c«
└─⟦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«
#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';
}