diff options
Diffstat (limited to 'dviware/quicspool/src/gf.c')
-rw-r--r-- | dviware/quicspool/src/gf.c | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/dviware/quicspool/src/gf.c b/dviware/quicspool/src/gf.c new file mode 100644 index 0000000000..33ccb06eaf --- /dev/null +++ b/dviware/quicspool/src/gf.c @@ -0,0 +1,419 @@ +#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'; +} |