summaryrefslogtreecommitdiff
path: root/dviware/quicspool/src/df.c_backup
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/quicspool/src/df.c_backup')
-rw-r--r--dviware/quicspool/src/df.c_backup1164
1 files changed, 1164 insertions, 0 deletions
diff --git a/dviware/quicspool/src/df.c_backup b/dviware/quicspool/src/df.c_backup
new file mode 100644
index 0000000000..1ef9a3ea8a
--- /dev/null
+++ b/dviware/quicspool/src/df.c_backup
@@ -0,0 +1,1164 @@
+/* TeX driver */
+/*
+$Log: df.c.backup,v $
+Revision 1.2 88/02/03 08:52:23 simpson
+added tpic support
+
+Revision 1.1 88/01/15 13:03:27 simpson
+initial release
+
+Revision 0.2 87/12/18 11:39:36 simpson
+added void for lint
+
+Revision 0.1 87/12/11 18:30:46 simpson
+beta test
+
+*/
+#ifndef lint
+static char *rcs = "$Header: df.c.backup,v 1.2 88/02/03 08:52:23 simpson Exp $";
+#endif
+#include <stdio.h>
+#include <signal.h>
+#include <assert.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/profile.h>
+#include <local/qms.h>
+#include "dvi.h"
+#include "constants.h"
+#include "fontinfo.h"
+#include "fontnode.h"
+
+/* Cast for accessing LocalInfo */
+#define LI(p) ((struct LocalInfo *)p->localinfo)
+
+struct Stack {
+ long h, v, w, x, y, z;
+};
+
+struct DviNode {
+ long dvinumber;
+ struct DviNode *next;
+};
+
+struct LocalInfo {
+ long widths[256]; /* RSUs. Font but ! file mag in account */
+ short mapsize[2][256];/* Width & height of each char bitmap */
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ struct DviNode *dvifontnumbers; /* List of #s DVI file uses */
+ char pathname[81]; /* Full pathname in file system */
+};
+
+double ConvInches; /* RSU->inches. File mag not taken into account */
+char *Whoami; /* argv[0] */
+char Orientation = 'P'; /* P=Portrait, L=Landscape */
+char *Model; /* Model of printer being used */
+char PKName[101]; /* Only used by pkeofsocleanup() */
+char *Xxxstring; /* String found in XXX? command */
+char *Pxxxstring; /* And a pointer used by lexical analyzer */
+char PKDir[101]; /* Location of PK font files */
+int Magnification; /* Magnification file was TeXed at (x1000) */
+int MaxBlocks; /* # of free blocks w/out ram or rom fonts, ovls */
+int CurRamBlocks; /* # of blocks used by ram fonts */
+int CurRomBlocks; /* # of blocks used by rom fonts */
+int DownLoadFNum; /* Number of font currently being downloaded */
+int UserFontCount = 30001; /* User fonts start getting #s from here */
+int Origin[2]; /* Origin of a postprocessor graph in pixels */
+long Numerator, Denominator; /* From .dvi preamble */
+FILE *ReadLine; /* Debugger port tty */
+struct sigvec SigStruct;
+struct FontNode *FontList; /* List containing all fnts & their attributes */
+extern char *Host, *User;
+extern FILE *Accting;
+extern Boolean Accounting;
+extern int NumPages;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ void qmsfntfree(), cleanup(), dvieofsoexit(), readpreamble(),
+ seteoffunction(), dvieofsocleanup(), process();
+ Boolean found, loadnametable(), setnewid();
+ int c;
+ int *intptr, *tempintptr;
+ int simplyexit(), callcleanup();
+ int romlist[41]; /* List of rom font #s */
+ char *strcpy();
+#ifdef DEBUG
+ char *malloc(), orien;
+ int i, fontno, size;
+ struct fontnode *fn;
+ FILE *f;
+#endif
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct qmsram *raminfo;
+ struct qmsfnt *fntinfo;
+ struct FontNode *createfontlist();
+ struct fontnode *p;
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF)
+ switch (c) {
+ case 'x':
+ if (atoi(optarg) > 2550)
+ Orientation = 'L';
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'y':
+ case 'w':
+ case 'l':
+ case 'i':
+ break;
+ default:
+ exit(2);
+ }
+ SigStruct.sv_handler = simplyexit;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: model binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ Model = v->value.s;
+ fputs(QUICON, stdout);
+ printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD);
+ fputs(QUICOFF, stdout);
+ (void)fflush(stdout);
+ if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: readline binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ if (!(ReadLine = fopen(v->value.s, "r"))) {
+ fprintf(stderr, "%s: could not open %s for reading\n", Whoami,
+ v->value.s);
+ exit(2);
+ }
+#ifdef DEBUG
+ raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram));
+ raminfo->TR = 401;
+ raminfo->AR = 387;
+ raminfo->FR = 13;
+ raminfo->OR = 0;
+#else
+ qmsopen(fileno(stdout), fileno(ReadLine));
+ if (!(raminfo = qmsram())) {
+ fprintf(stderr, "%s: could not get printer ram info\n", Whoami);
+ exit(2);
+ }
+#endif
+ MaxBlocks = raminfo->AR + raminfo->FR;
+ /* Save 5 blocks for filling with tpic */
+ MaxBlocks -= 5;
+#ifdef DEBUG
+ fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt));
+ fntinfo->ram = fntinfo->rom = NULL;
+ for (i = 0; i < 13; i++) {
+ switch (i) {
+ case 0:
+ fontno = 521;
+ orien = 'L';
+ break;
+ case 1:
+ fontno = 522;
+ orien = 'L';
+ break;
+ case 2:
+ fontno = 523;
+ orien = 'L';
+ break;
+ case 3:
+ fontno = 524;
+ orien = 'L';
+ break;
+ case 4:
+ fontno = 1100;
+ orien = 'P';
+ break;
+ case 5:
+ fontno = 1103;
+ orien = 'P';
+ break;
+ case 6:
+ fontno = 1200;
+ orien = 'P';
+ break;
+ case 7:
+ fontno = 1204;
+ orien = 'P';
+ break;
+ case 8:
+ fontno = 1217;
+ orien = 'L';
+ case 9:
+ fontno = 7009;
+ orien = 'P';
+ break;
+ case 10:
+ fontno = 7010;
+ orien = 'P';
+ break;
+ case 11:
+ fontno = 7036;
+ orien = 'P';
+ break;
+ case 12:
+ fontno = 7037;
+ orien = 'P';
+ break;
+ }
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->rom, fntinfo->rom = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = 1024; /* Rom fonts occupy one block */
+ fn->version = '0';
+ fn->class = '1';
+ }
+ /* For testing, ramfonts contains the already loaded fonts. It should
+ * consist of lines containing two numbers and a letter, the first being
+ * the font number, the second being the font size, and the third letter
+ * is an orientation. The orientation should be the character immediately
+ * after the size of the font.
+ */
+ if (f = fopen("ramfonts", "r")) { /* File is optional for testing */
+ while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3)
+ {
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->ram, fntinfo->ram = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = size;
+ fn->version = '0';
+ fn->class = '1';
+ raminfo->AR -= CEILING(size / 1024.0);
+ raminfo->FR += CEILING(size / 1024.0);
+ }
+ fclose(f);
+ }
+#else
+ if (!(fntinfo = qmsfnt())) {
+ fprintf(stderr, "%s: could not get printer font info\n", Whoami);
+ exit(2);
+ }
+#endif
+ for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next)
+ CurRomBlocks += CEILING(p->bytes / (double)1024);
+ CurRamBlocks = raminfo->FR - CurRomBlocks;
+ /* Make an array of rom font #s */
+ for (p = fntinfo->rom, intptr = romlist; p; p = p->next) {
+ for (tempintptr = romlist, found = FALSE; tempintptr < intptr;
+ tempintptr++)
+ if (*tempintptr == p->number)
+ found = TRUE;
+ if (!found)
+ *intptr++ = p->number;
+ }
+ *intptr = 0;
+ if (EQ(Model, "QMS800"))
+ (void)strcpy(PKDir, "--PKDIR1--");
+ else
+ (void)strcpy(PKDir, "--PKDIR2--");
+ if (!loadnametable(PKDir, romlist, 1)) {
+ fprintf(stderr, "%s: could not open font directory %s\n", Whoami,
+ PKDir);
+ exit(2);
+ }
+ FontList = createfontlist(fntinfo);
+ qmsfntfree(fntinfo);
+ if (!setnewid(Host, User)) {
+ fprintf(stderr, "%s: could not change user id to %s\n", Whoami,
+ User);
+ exit(2); /* This is fatal, bud. */
+ }
+ seteoffunction(dvieofsoexit);
+ readpreamble();
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 :
+ (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 *
+ 1000) : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ fputs(FREEOFF, stdout);
+ seteoffunction(dvieofsocleanup);
+ process();
+ cleanup(FontList, SUCCEED);
+}
+
+/* Reads the info in the DVI preamble */
+void readpreamble()
+{
+ int i, k;
+ long integer();
+ unsigned long uinteger();
+
+ if (cgetchar() != PRE) {
+ fprintf(stderr, "%s: input file is not a DVI file\n", Whoami);
+ exit(2);
+ }
+ if (cgetchar() != DVIID) {
+ fprintf(stderr, "%s: wrong version of DVI file \n", Whoami);
+ exit(2);
+ }
+ Numerator = uinteger(stdin, 4);
+ Denominator = uinteger(stdin, 4);
+ Magnification = integer(stdin, 4);
+ k = cgetchar(); /* Ignore comment */
+ for (i = 0; i < k; i++)
+ (void)cgetchar();
+ ConvInches = 1 / 100000.0 / 2.54;
+ /* RSU 1m 100cm 1inch n inches */
+ /* x --------- x ----- x ------ = */
+ /* 10^7 RSUs 1m 2.54cm */
+}
+
+/* Main routine that interprets the DVI file */
+void process()
+{
+ unsigned long uinteger(), ulk, uli;
+ struct FontNode *curfontnode = NULL, *getdvifontnode(), *tempcurfontnode;
+ struct Stack *tempstack;
+ Boolean download(), makeroom(), fontselected = FALSE;
+ int ch, ldirectory, lfontname, i;
+ long dvifontnum, dvichecksum, scalefactor, designsize, curfontnum,
+ integer(), a, b;
+ char directory[256], fontname[256], *push(), *pop(), *malloc();
+ void fonttolist(), adjust(), endoflist();
+ long h, v, w, x, y, z; /* In RSUs. Mag not taken in account */
+ long realhpxl, realvpxl; /* Real h & v in printer in pixels */
+ long virthpxl, virtvpxl; /* Virtual h & v current point in */
+ /* pixels. Mag is taken in account */
+
+ for (ch = cgetchar(); ch != BOP; ch = cgetchar())
+ switch (ch) {
+ case NOP:
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor, designsize,
+ directory, fontname);
+ break;
+ default:
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ while (ch == BOP) {
+ for (i = 0; i < 10; i++)
+ (void)integer(stdin, 4);
+ (void)uinteger(stdin, 4); /* Pointer to previous page */
+ virthpxl = virtvpxl = realhpxl = realvpxl = h = v = w = x = y = z = 0;
+ for (ch = cgetchar(); ch != EOP; ch = cgetchar()) {
+ virthpxl = ROUND(h*ConvInches*RESOLUTION*(Magnification/1000.0));
+ virtvpxl = ROUND(v*ConvInches*RESOLUTION*(Magnification/1000.0));
+ if (SETCHAR0 <= ch && ch < 128) {
+ /* The following statement will only be true if the first
+ * font in the dvi file was not found at any magnification.
+ * In this case, skip this character since we don't know
+ * how to increment the virtual or real pixel locations!
+ * The true coordinates will probably be reset when TeX
+ * pops the stack at the beginning of a line.
+ */
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curfontnode->blocksize, LI(curfontnode)->pathname);
+ goto trytocontinue1;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue1;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+ /* SliTeX fonts have width but no bitmap. Unfortunately the
+ * QMS will not print (or download) a character with width and
+ * no bitmap so we must not print characters that are not in
+ * the font. If you do, you will get the lowest character in
+ * the font.
+ */
+trytocontinue1: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ h += LI(curfontnode)->widths[ch];
+ } else if (FNTNUM0 <= ch && ch < FNT1) {
+ curfontnum = ch - FNTNUM0;
+ if (!(tempcurfontnode = getdvifontnode(FontList,
+ curfontnum, Orientation)))
+ continue; /* Font file was not found during FNTDEF */
+ curfontnode = tempcurfontnode;
+ endoflist(&FontList, curfontnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ } else switch (ch) {
+ case SET1:
+ case SET2:
+ case SET3:
+ case SET4:
+ ch = uinteger(stdin, ch - SET1 + 1);
+ assert(0 <= ch && ch <= 255);
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n",
+ Whoami, curfontnode->blocksize,
+ LI(curfontnode)->pathname);
+ goto trytocontinue2;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue2;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber,
+ ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue2: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ h += LI(curfontnode)->widths[ch];
+ break;
+ case SETRULE:
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ a = integer(stdin, 4);
+ b = integer(stdin, 4);
+ if (a > 0 && b > 0) {
+ printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ printf("%s%05d%05d", LINE,
+ ROUND(b/(double)SPOINT/PPI*(double)Magnification),
+ ROUND(a/(double)SPOINT/PPI*(double)Magnification));
+ printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ realhpxl += ROUND(b / (double)SPOINT / PPI *
+ RESOLUTION * (Magnification / 1000.0));
+ }
+ h += ROUND(b * (Numerator / (double)Denominator));
+ break;
+ case PUT1:
+ case PUT2:
+ case PUT3:
+ case PUT4:
+ ch = uinteger(stdin, ch - PUT1 + 1);
+ assert(0 <= ch && ch <= 255);
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n",
+ Whoami, curfontnode->blocksize,
+ LI(curfontnode)->pathname);
+ goto trytocontinue3;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue3;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber,
+ ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue3: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ break;
+ case PUTRULE:
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ a = integer(stdin, 4);
+ b = integer(stdin, 4);
+ if (a > 0 && b > 0) {
+ printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ printf("%s%05d%05d", LINE,
+ ROUND(b/(double)SPOINT/PPI*(double)Magnification),
+ ROUND(a/(double)SPOINT/PPI*(double)Magnification));
+ printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ realhpxl += ROUND(b / (double)SPOINT / PPI *
+ RESOLUTION * (Magnification / 1000.0));
+ }
+ break;
+ case NOP:
+ break;
+ case PUSH:
+ tempstack = (struct Stack *)malloc((unsigned)sizeof(
+ struct Stack));
+ tempstack->h = h, tempstack->v = v, tempstack->w = w,
+ tempstack->x = x, tempstack->y = y, tempstack->z = z;
+ (void)push((char *)tempstack);
+ break;
+ case POP:
+ tempstack = (struct Stack *)pop();
+ assert(tempstack);
+ h = tempstack->h, v = tempstack->v, w = tempstack->w,
+ x = tempstack->x, y = tempstack->y, z = tempstack->z;
+ free((char *)tempstack);
+ break;
+ case RIGHT1:
+ case RIGHT2:
+ case RIGHT3:
+ case RIGHT4:
+ h += integer(stdin, ch - RIGHT1 + 1) * (Numerator /
+ (double)Denominator);
+ break;
+ case W0:
+horw: h += w;
+ break;
+ case W1:
+ case W2:
+ case W3:
+ case W4:
+ w = integer(stdin, ch - W1 + 1) * (Numerator /
+ (double)Denominator);
+ goto horw;
+ case X0:
+horx: h += x;
+ break;
+ case X1:
+ case X2:
+ case X3:
+ case X4:
+ x = integer(stdin, ch - X1 + 1) * (Numerator /
+ (double)Denominator);
+ goto horx;
+ case DOWN1:
+ case DOWN2:
+ case DOWN3:
+ case DOWN4:
+ v += integer(stdin, ch - DOWN1 + 1) * (Numerator /
+ (double)Denominator);
+ break;
+ case Y0:
+very: v += y;
+ break;
+ case Y1:
+ case Y2:
+ case Y3:
+ case Y4:
+ y = integer(stdin, ch - Y1 + 1) * (Numerator /
+ (double)Denominator);
+ goto very;
+ case Z0:
+verz: v += z;
+ break;
+ case Z1:
+ case Z2:
+ case Z3:
+ case Z4:
+ z = integer(stdin, ch - Z1 + 1) * (Numerator /
+ (double)Denominator);
+ goto verz;
+ case FNT1:
+ case FNT2:
+ case FNT3:
+ case FNT4:
+ curfontnum = uinteger(stdin, ch - FNT1 + 1);
+ if (!(tempcurfontnode = getdvifontnode(FontList,
+ curfontnum, Orientation)))
+ continue;
+ curfontnode = tempcurfontnode;
+ endoflist(&FontList, curfontnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ ulk = uinteger(stdin, ch - XXX1 + 1);
+ Pxxxstring = Xxxstring = malloc((unsigned)(ulk + 1));
+ for (uli = 0; uli < ulk; uli++)
+ Xxxstring[uli] = cgetchar();
+ Xxxstring[uli] = '\0';
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ Origin[0] = virthpxl + RESOLUTION, Origin[1] = virtvpxl +
+ RESOLUTION;
+ (void)yyparse();
+ free(Xxxstring);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ?
+ 11 * 1000 : (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ?
+ (int)(8.5 * 1000) : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ realhpxl = realvpxl = 0;
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor,
+ designsize, directory, fontname);
+ break;
+ default: /* Bad DVI command */
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ }
+ NumPages++;
+ printf("%s", FORMFEED);
+ for (ch = cgetchar(); ch != BOP && ch != POST; ch = cgetchar())
+ switch (ch) {
+ case NOP:
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor,
+ designsize, directory, fontname);
+ break;
+ default:
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ }
+ while (getchar() != EOF)
+ ;
+}
+
+
+/* Returns the full pathname of the pk file found or NULL if not found.
+ * The algorithm is as follows:
+ * Create a new path, say TEXFONTS*, which is equal to $TEXFONTS:PKDir
+ * if there is a directory name in the DVI file {
+ * look in that directory for the font at any magnification
+ * if found {
+ * select this font
+ * return it
+ * }
+ * }
+ * look in TEXFONTS* directories consecutively for font with closest
+ * magnification
+ * if no font matches, return NULL
+ */
+char *findpkfont(directory, fontname, designsize, scalefactor)
+char *directory;
+char *fontname;
+long designsize, scalefactor;
+{
+ int closestnumber = MAX_INTEGER;
+ int desiredmagnification = ROUND(RESOLUTION *
+ ((double)scalefactor / designsize) * (Magnification /
+ 1000.0));
+ int dirdsize, dirmag;
+ Boolean extractinfo();
+ static char returnvalue[101];
+ char dirfname[81], dirsfname[81], hostname[81], component[81];
+ char fontpaths[201], *strcpy(), *nextcomponent();
+ char *p, *comp, *fgetenv(), *expandtilde(), *expandhome();
+ DIR *dirp;
+ struct direct *direntry;
+
+ returnvalue[0] = '\0';
+ (void)gethostname(hostname, 80);
+ if (!EQ(hostname, Host) || !(p = fgetenv("TEXFONTS", User)))
+ (void)strcpy(fontpaths, PKDir);
+ else
+ (void)sprintf(fontpaths, "%s:%s", p, PKDir);
+ if (directory && strlen(directory) > 0) {
+ if (dirp = opendir(directory)) {
+ for (direntry = readdir(dirp); direntry; direntry =
+ readdir(dirp)) {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s%s", directory,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ }
+ }
+ for (p = &fontpaths[0]; comp = nextcomponent(&p); ) {
+ (void)strcpy(component, comp);
+ (void)expandtilde(component);
+ (void)expandhome(component);
+ if (dirp = opendir(component)) {
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp))
+ {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s/%s", component,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+ }
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ return NULL;
+}
+
+/* Adjusts the real current position to the virtual current position */
+void adjust(realh, realv, virth, virtv, h, v)
+long *realh, *realv;
+long virth, virtv;
+long h, v;
+{
+ if (*realh != virth + RESOLUTION) {
+ printf("%s%05d%s", TAB, ROUND(h * ConvInches * Magnification) + 1000,
+ ENDCMD); /* Add 1000 since the origin is (1in,1in) */
+ *realh = virth + RESOLUTION;
+ }
+ if (*realv != virtv + RESOLUTION) {
+ printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v * ConvInches *
+ Magnification) + 1000, ENDCMD);
+ *realv = virtv + RESOLUTION;
+ }
+}
+
+/* Adds a new font to the font list. The width info, mapsize, qmsheight,
+ * qmsbaseline, pathname, blocksize and dvifontnumber in the FontNode
+ * structure and LocalInfo structure are filled in also. If the font is
+ * loaded on startup, the blocksize is left as is; otherwise, the blocksize
+ * is estimated.
+ */
+void fonttolist(fontnumber, dvichecksum, scalefactor, designsize, directory,
+fontname)
+long fontnumber;
+long dvichecksum;
+long scalefactor, designsize;
+char *directory, *fontname;
+{
+ struct DviNode *d;
+ struct FontInfo *fi, *getfontinfo();
+ struct FontNode *fn, *getfontnode();
+ char *fullfontpath, *findpkfont(), *tail();
+ void cleanup(), pkeofsocleanup(), seteoffunction(),
+ dvieofsocleanup();
+ int qmsfontnum, i;
+ Boolean found;
+
+ if (!(fullfontpath = findpkfont(directory, fontname, designsize,
+ scalefactor))) {
+ fprintf(stderr, "%s: could not find font %s anywhere\n", Whoami,
+ fontname);
+ return; /* Try to continue */
+ }
+ if (EQN(PKDir, fullfontpath, strlen(PKDir)) && fullfontpath[strlen(PKDir)]
+ == '/' && EQ(&fullfontpath[strlen(PKDir)+1], tail(fullfontpath)))
+ qmsfontnum = getnumfromtable(tail(fullfontpath));
+ else /*tail(fullfontpath) ! necessarily == fontname if exact size !found*/
+ qmsfontnum = UserFontCount++;
+ assert(qmsfontnum > 0);
+ if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) {
+ bzero((char *)(fn = (struct FontNode *)malloc((unsigned)sizeof(struct
+ FontNode))), sizeof(struct FontNode));
+ fn->next = FontList, FontList = fn;
+ }
+ if (!fn->localinfo)
+ bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)),
+ sizeof(struct LocalInfo));
+ fn->flags |= RAM;
+ if (Orientation == 'P')
+ fn->flags |= PORT;
+ fn->qmsnumber = qmsfontnum;
+ (void)strcpy(LI(fn)->pathname, fullfontpath);
+ for (d = LI(fn)->dvifontnumbers, found = FALSE; d && !found; d = d->next)
+ if (d->dvinumber == fontnumber)
+ found = TRUE;
+ if (!found) {
+ d = (struct DviNode *)malloc(sizeof(struct DviNode));
+ d->next = LI(fn)->dvifontnumbers, LI(fn)->dvifontnumbers = d;
+ d->dvinumber = fontnumber;
+ }
+ (void)strcpy(PKName, fullfontpath);
+ seteoffunction(pkeofsocleanup);
+ if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") ||
+ EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") &&
+ !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) {
+ fprintf(stderr, "%s: cannot open or invalid font file %s\n", Whoami,
+ fullfontpath);
+ fn->flags |= LOADED; /* Try to continue */
+ fn->blocksize = 0;
+ return;
+ }
+ seteoffunction(dvieofsocleanup);
+ LI(fn)->qmsheight = fi->qmsheight;
+ LI(fn)->qmsbaseline = fi->qmsbaseline;
+ if (!(fn->flags & PRELOADED))
+ fn->blocksize = fi->blocksize;
+ for (i = 0; i < 256; i++) {
+ LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds /
+ (double)FIX) / FIX) * (2.54 / PPI * 100000) * ((fi->hppp /
+ (double)SPOINT * PPI / RESOLUTION) / (Magnification / 1000.0)));
+ LI(fn)->mapsize[0][i] = fi->chararray[i].w;
+ LI(fn)->mapsize[1][i] = fi->chararray[i].h;
+ }
+/* fi->chararray[i].tfm is in units of FIXes/designsize. fi->hppp is in units
+ * of scaled points times pixels/point. Convert the width into RSUs with only
+ * font magnification taken into account by the following formulas:
+ *
+ * tfm designsize
+ * x ---------- = width in points
+ * FIX
+ *
+ * width 1inch 2.54cm 1m 10^7RSUs
+ * in x -------- x ------ x ----- x -------- = width in RSUs
+ * points 72.27pts 1inch 100cm 1m
+ *
+ * hppp PPI
+ * ------ x = Resolution designed for (the number before "pk" in the
+ * SPOINT file name)
+ *
+ * Multiplying the width in RSUs by the number before the "pk" in the file
+ * name yields the width in RSUs with font and file magnification taken into
+ * account. Dividing by the file magnification yields the width with only
+ * the font magnification taken into account.
+ */
+ if (dvichecksum != 0 && fi->cs != 0)
+ if (dvichecksum != fi->cs)
+ fprintf(stderr,
+ "%s: DVI checksum (O%lo) != PK checksum (O%lo) in %s\n",
+ Whoami, dvichecksum, fi->cs, LI(fn)->pathname);
+}
+
+/* Downloads a font */
+Boolean download(fn)
+struct FontNode *fn;
+{
+ struct CharInfo *ci;
+ char *tail(), *strcpy();
+ void resetpkfile(), seteoffunction(),
+ downloadpkeofsocleanup(), dvieofsocleanup();
+ int downloadinterrupt(), callcleanup();
+ int downloadtype, result, i, truebyteswide, bytestooutput,
+ row, bytes;
+
+ if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ?
+ 'P' : 'L') != Orientation)
+ return FALSE;
+ resetpkfile();
+ downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) &&
+ Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500"))
+ && Orientation == 'L' ? 'X' : 'Y');
+ DownLoadFNum = fn->qmsnumber;
+ (void)sigblock(SIGINT); /* Temporarily block interrupts */
+ SigStruct.sv_handler = downloadinterrupt;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ (void)strcpy(PKName, LI(fn)->pathname);
+ seteoffunction(downloadpkeofsocleanup);
+ /* #defining ASCIILOAD causes ASCII characters to be used for the download
+ * sequence. Twice as many characters must be sent but it is useful for
+ * looking at the output when debugging. Also, you can actually see the
+ * bitmaps in the output. ASCII loading must be used when you can't get
+ * hardware flow control to work. Far out.
+ */
+#ifdef ASCIILOAD
+ fputs(FREEFORM, stdout);
+#else
+ fputs(EIGHTBITON, stdout);
+#endif
+ printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation,
+ tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline);
+ (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */
+ while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) !=
+ 1)
+ switch (result) {
+ case 2:
+ fprintf(stderr, "%s: could not open %s\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 3:
+ fprintf(stderr, "%s: %s is not a PK file\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 4:
+ fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 0: /* Ok. Got a bitmap */
+ if (ci->h == 0 || ci->w == 0)
+ continue;
+ putchar(',');
+ printf("%02X%03d", ci->cc, ROUND(LI(fn)->widths[ci->cc] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION));
+ if (downloadtype == 'X') {
+ printf("%03d%03d", ci->h, ci->w);
+ printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+'
+ : '-', ABS(LI(fn)->qmsbaseline - ci->voff));
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff));
+ } else {
+ printf("%03d%03d", ci->w, ci->h);
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff));
+ printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) -
+ (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight
+ - LI(fn)->qmsbaseline) - (ci->h - ci->voff)));
+ i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */
+ }
+ truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */
+ bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */
+#ifdef ASCIILOAD
+ for (row = 0; row < ci->h; row++) {
+#else
+ for (row = 0; row < ci->h; row++)
+#endif
+ for (bytes = 0; bytes < bytestooutput; bytes++) {
+ if (bytes == truebyteswide - 1)
+ *(ci->bitmap + row * truebyteswide + bytes) &=
+ 0xFF<<7-(ci->w+7)%8;
+ if (bytes < truebyteswide) {
+ i = *(ci->bitmap + row * truebyteswide + bytes) &
+ 0xFF;
+#ifdef ASCIILOAD
+ printf("%c%c", "0123456789ABCDEF"[i >> 4],
+ "0123456789ABCDEF"[i & 0xF]);
+#else
+ if (i == '^')
+ printf("^^");
+ else
+ (void)putchar(i);
+#endif
+ } else
+#ifdef ASCIILOAD
+ printf("00");
+#else
+ (void)putchar(0);
+#endif
+ }
+#ifdef ASCIILOAD
+ putchar('\n');
+ }
+#endif
+ break;
+ } /* End switch */
+#ifdef ASCIILOAD
+ printf("%s%s", ENDCMD, FREEOFF);
+#else
+ printf("%s%s", ENDCMD, EIGHTBITOFF);
+#endif
+ putchar('\r'); /* Ends the pass */
+ (void)sigblock(SIGINT);
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ seteoffunction(dvieofsocleanup);
+ CurRamBlocks += fn->blocksize;
+ fn->flags |= LOADED;
+ (void)sigsetmask(sigblock(0) & ~SIGINT);
+ return TRUE;
+}
+
+/* Returns a pointer to a font on the font list using the DVI number; NULL
+ * if not found.
+ */
+struct FontNode *getdvifontnode(head, dvinumber, orientation)
+struct FontNode *head;
+long dvinumber;
+int orientation;
+{
+ struct FontNode *p;
+ struct DviNode *d;
+
+ for (p = head; p; p = p->next)
+ if (p->flags & RAM && (p->flags & PORT ? 'P' : 'L') == orientation
+ && p->localinfo && LI(p)->dvifontnumbers)
+ for (d = LI(p)->dvifontnumbers; d; d = d->next)
+ if (d->dvinumber == dvinumber)
+ return p;
+ return NULL;
+}
+
+/* The following are routines called when a SIGINT is received or EOF is
+ * unexpectedly encountered when reading a file.
+ */
+simplyexit()
+{
+ exit(SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */
+}
+
+void dvieofsoexit()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami);
+ exit(2);
+}
+
+void dvieofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void pkeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF in PK file %s\n", Whoami, PKName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void downloadpkeofsocleanup()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ pkeofsocleanup();
+}
+
+downloadinterrupt()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ callcleanup();
+}
+
+
+/* Lex and Yacc routines to parse \special command string */
+#include "xxx.c"