summaryrefslogtreecommitdiff
path: root/dviware/quicspool/src/gf.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/quicspool/src/gf.c')
-rw-r--r--dviware/quicspool/src/gf.c419
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';
+}