diff options
Diffstat (limited to 'dviware/quicspool/src/df.c_backup')
-rw-r--r-- | dviware/quicspool/src/df.c_backup | 1164 |
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" |