summaryrefslogtreecommitdiff
path: root/dviware/quicspool/src/nf.c_backup
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/quicspool/src/nf.c_backup')
-rw-r--r--dviware/quicspool/src/nf.c_backup1329
1 files changed, 1329 insertions, 0 deletions
diff --git a/dviware/quicspool/src/nf.c_backup b/dviware/quicspool/src/nf.c_backup
new file mode 100644
index 0000000000..544b2cf126
--- /dev/null
+++ b/dviware/quicspool/src/nf.c_backup
@@ -0,0 +1,1329 @@
+/* Ditroff driver */
+#ifndef lint
+static char *rcs = "$Header: nf.c.backup,v 1.2 88/02/03 08:52:15 simpson Exp $";
+#endif
+/*
+$Log: nf.c.backup,v $
+Revision 1.2 88/02/03 08:52:15 simpson
+added tpic support
+
+Revision 1.1 88/01/15 13:04:37 simpson
+initial release
+
+Revision 0.3 88/01/06 08:46:06 simpson
+corrected determination of charexists
+
+Revision 0.2 87/12/18 11:37:32 simpson
+added spline and ellipse support
+
+Revision 0.1 87/12/11 18:31:04 simpson
+beta test
+
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <math.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/standard.h>
+#include <local/qms.h>
+#include <local/profile.h>
+#include "fontnode.h"
+#include "fontinfo.h"
+#include "constants.h"
+#include "dev.h"
+
+#define FONTDIR "--FONTDIR--"
+#define DEVNAME "qms" /* Name given to -T option*/
+/* Cast for accessing LocalInfo */
+#define LI(p) ((struct LocalInfo *)p->localinfo)
+#define UNITWIDTH 10 /* Same as in DESC file */
+
+typedef struct {
+ double x, y;
+} COORDINATE;
+
+struct FontState {
+ int pointsize;
+ int font;
+};
+
+struct Stack {
+ struct FontState fontstate;
+ int h, v;
+};
+
+struct LocalInfo {
+ char name[21]; /* Name of font */
+ int pointsize;
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ char pathname[81]; /* Full pathname in file system */
+ Boolean charexists[256];/* True if there is such a character */
+ short bitmapsize[2][256]; /* Width & height of each char bitmap */
+ short widths[256]; /* True width of each char in pixels */
+ long maptable[160]; /* Encoding of troff special sequences */
+ short maptablesize; /* # of entries in map table */
+};
+
+char EOFName[101]; /* Used by pkeofsocleanup & desceofsocleanup */
+char *Whoami; /* argv[0] */
+char *Model; /* Model of printer being used */
+char Orientation = 'P';
+char MountTable[51][21]; /* Max of 50 different fonts in table */
+char *Xxxstring; /* String found in extension commands */
+char *Pxxxstring; /* Pointer used by the lexical analyzer */
+char PKDir[101]; /* Directory PK fonts are in */
+int MaxBlocks; /* # of free blocks w/out ram or rom fonts */
+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 Origin[2]; /* Origin of a postprocessor graph in pixels */
+FILE *ReadLine; /* Debugger port tty */
+struct sigvec SigStruct;
+struct FontNode *FontList; /* Contains all fonts & their attributes */
+extern char *Host, *User;
+extern FILE *Accting;
+extern Boolean Accounting;
+extern int NumPages;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ Boolean found, loadnametable(), setnewid();
+ extern int optind;
+ extern char *optarg;
+ int *intptr, *tempintptr;
+ int c;
+ int romlist[41]; /* List of rom font #s */
+ int simplyexit(), callcleanup();
+ void qmsfntfree(), cleanup(), seteoffunction(), process(),
+ troffeofsocleanup(), adjust();
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct qmsram *raminfo;
+ struct qmsfnt *fntinfo;
+ struct fontnode *p;
+ struct FontNode *createfontlist();
+#ifdef DEBUG
+ char *malloc(), orien;
+ int i, fontno, size;
+ FILE *f;
+ struct fontnode *fn;
+#endif
+
+ 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 block 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);
+ }
+ (void)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)sprintf(PKDir, "%s/wbfonts", FONTDIR);
+ else
+ (void)sprintf(PKDir, "%s/wwfonts", FONTDIR);
+ if (!loadnametable(PKDir, romlist, 10001)) {
+ 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 */
+ }
+ 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(troffeofsocleanup);
+ process();
+ cleanup(FontList, SUCCEED);
+}
+
+/* Main routine that interprets the troff file */
+void process()
+{
+ int specialfont = 4; /* Loc of S font in mount table */
+ int c, d, n;
+ int realhpxl = 0, realvpxl = 0,
+ virthpxl = 0, virtvpxl = 0; /*Virt & real cursor locs - pxls*/
+ Boolean switchedtospecial = FALSE;/* T if we switch to Special font */
+ Boolean firstpage = TRUE, fontselected = FALSE, download(), makeroom();
+ char *malloc(), *getstring(), *push(), *pop(), *strcpy(), *s,
+ *findpkfont(), extension[1000], *cgets(), *extractinteger();
+ void endoflist(), spline();
+ double radius, anglestart, angleend, decimalanglestart, a, b,
+ decimalangleend, controlpoints[37][3], curvepoints[500][3];
+ COORDINATE start, end, center, cur, new;
+ struct Stack *tempstack;
+ struct FontNode *fonttolist();
+ struct FontNode *curnode = NULL; /* Current font ditroff has selected */
+ struct FontNode *oldnode; /* 4 saving when trying special font */
+ /* Current font ditroff has selected */
+ struct FontState current;
+ /* For saving font when trying the special font */
+ struct FontState oldcurrent;
+
+ current.font = current.pointsize = 0;
+ bzero((char *)MountTable, sizeof(MountTable));
+ while (TRUE) { /* A non-returning function is called to exit */
+ switch (c = getnonblank(stdin)) {
+ case 's':
+ current.pointsize = getinteger(stdin);
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'f':
+ current.font = getinteger(stdin);
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'c': /* Character at current location */
+ c = cgetchar();
+ /* If we couldn't find the font, don't print anything since we
+ * don't know how to increment the real & virtual pixel locations.
+ */
+ if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c])
+ {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo &&
+ LI(curnode)->charexists[c]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks,
+ curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue1;
+ }
+ if (!download(curnode))
+ goto trytocontinue1;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+ /* For fonts with width but no bitmap, check the size of the
+ * raster. 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(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case 'C':
+ s = getstring(stdin);
+ if (!curnode || !curnode->localinfo || (c =
+ lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s)) == -1
+ || !LI(curnode)->charexists[c = LI(curnode)->maptable[c] >> 24 &
+ 0xFF]) {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo && (c =
+ lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s))
+ != -1 && LI(curnode)->charexists[c = LI(curnode)->maptable[c]
+ >> 24 & 0xFF]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks,
+ curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue2;
+ }
+ if (!download(curnode))
+ goto trytocontinue2;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue2:
+ if (LI(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ virthpxl += (c - '0') * 10 + (cgetchar() - '0');
+ c = cgetchar();
+ if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c])
+ {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo &&
+ LI(curnode)->charexists[c]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue3;
+ }
+ if (!download(curnode))
+ goto trytocontinue3;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue3:
+ if (LI(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case 'p': /* Begin a new page */
+ (void)getinteger(stdin); /* Ignore page number */
+ realhpxl = realvpxl = virthpxl = virtvpxl = 0;
+ printf("%s%05d%s", TAB, 0, ENDCMD);
+ printf("%s%05d%s", JUSTIFYMARGIN, 0, ENDCMD);
+ if (!firstpage)
+ fputs(FORMFEED, stdout), NumPages++;
+ else
+ firstpage = FALSE;
+ break;
+ case 'w': /* Appears between words - ignore */
+ break;
+ case 'H': /* Absolute horizontal */
+ virthpxl = getinteger(stdin);
+ break;
+ case 'h': /* Relative horizontal */
+ virthpxl += getinteger(stdin);
+ break;
+ case 'V': /* Absolute vertical */
+ virtvpxl = getinteger(stdin);
+ break;
+ case 'v': /* Relative vertical */
+ virtvpxl += getinteger(stdin);
+ break;
+ case 'n': /* At end of line */
+ (void)getinteger(stdin); /* Amount of space before line */
+ (void)getinteger(stdin); /* Amount of space after line */
+ break;
+ case '{': /* Push stack */
+ tempstack = (struct Stack *)malloc(sizeof(struct Stack));
+ tempstack->fontstate.pointsize = current.pointsize;
+ tempstack->fontstate.font = current.font;
+ tempstack->h = virthpxl, tempstack->v = virtvpxl;
+ (void)push((char *)&tempstack);
+ break;
+ case '}': /* Pop stack */
+ tempstack = (struct Stack *)pop();
+ current.pointsize = tempstack->fontstate.pointsize;
+ current.font = tempstack->fontstate.font;
+ virthpxl = tempstack->h, virtvpxl = tempstack->v;
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ free((char *)tempstack);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case '#': /* Comment */
+ while (cgetchar() != '\n')
+ ;
+ break;
+ case 'D': /* Graphics drawing commands */
+ switch (c = cgetchar()) {
+ case 'l': /* Line */
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ start.x = virthpxl, start.y = virtvpxl;
+ end.x = start.x + getinteger(stdin), end.y = start.y +
+ getinteger(stdin);
+ /* I don't know what this next character is. It is not
+ * documented.
+ */
+ while ((c = cgetchar()) != '\n');
+ ;
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND(virthpxl/(double)RESOLUTION*1000),
+ ROUND(virtvpxl/(double)RESOLUTION*1000));
+ printf("%s03", PENWIDTH);
+ printf("%s%05d:%05d", PENDOWN, ROUND(end.x / RESOLUTION *
+ 1000), ROUND(end.y / RESOLUTION * 1000));
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'c': /* Circle */
+ d = getinteger(stdin);
+ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", ARC,
+ virthpxl+.5*d>=0.0?'+':'-', ROUND((virthpxl+.5*d)/RESOLUTION
+ *1000.0),
+ virtvpxl>=0?'+':'-', ROUND(virtvpxl/(double)RESOLUTION*1000.0),
+ ROUND(.5*d/RESOLUTION*1000.0),
+ 0,0,3,ENDCMD);
+ printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ virthpxl += d;
+ break;
+ case 'e': /* Ellipse */
+ /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1
+ * where 'a' is the length of the semimajor axis and 'b' is
+ * the length of the semiminor axis. We divide each quadrant
+ * into 200 line segments and connect the line segments.
+ */
+ a = getinteger(stdin) / 2.0 / RESOLUTION, /* In inches */
+ b = getinteger(stdin) / 2.0 / RESOLUTION;
+ center.x = virthpxl / (double)RESOLUTION + a,
+ center.y = virtvpxl / (double)RESOLUTION;
+ cur.x = a, cur.y = 0.0; /* cur and new are */
+ fputs(VECTORON, stdout); /* relative to the origin */
+ printf("%s03", PENWIDTH);
+ for (n = 1; n <= 200; n++, cur = new) {
+ new.x = a*cos((n/200.0)*(PI/2.0)),
+ new.y = b*sin((n/200.0)*(PI/2.0));
+ /* First quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x+cur.x)*1000.0),
+ ROUND((center.y+cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x+new.x)*1000.0),
+ ROUND((center.y+new.y)*1000.0));
+ /* Second quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x-cur.x)*1000.0),
+ ROUND((center.y+cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x-new.x)*1000.0),
+ ROUND((center.y+new.y)*1000.0));
+ /* Third quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x-cur.x)*1000.0),
+ ROUND((center.y-cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x-new.x)*1000.0),
+ ROUND((center.y-new.y)*1000.0));
+ /* Fourth quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x+cur.x)*1000.0),
+ ROUND((center.y-cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x+new.x)*1000.0),
+ ROUND((center.y-new.y)*1000.0));
+ }
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl += ROUND(2.0 * a * RESOLUTION);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'a': /* Arc */
+ start.x = virthpxl, start.y = virtvpxl;
+ center.x = virthpxl + getinteger(stdin), center.y = virtvpxl
+ + getinteger(stdin);
+ end.x = center.x + getinteger(stdin), end.y = center.y +
+ getinteger(stdin);
+ radius = sqrt(pow(start.x - center.x, 2.0) + pow(start.y -
+ center.y, 2.0));
+ /* Ditroff uses reverse cartesian coordinate system */
+ anglestart = atan2(start.x - center.x, center.y - start.y);
+ angleend = atan2(end.x - center.x, center.y - end.y);
+ anglestart -= PI / 2.0;
+ angleend -= PI / 2.0;
+ if (anglestart < 0)
+ anglestart += 2 * PI;
+ if (angleend < 0)
+ angleend += 2 * PI;
+ decimalanglestart = angleend / PI * 500.0;
+ decimalangleend = anglestart / PI * 500.0;
+ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC,
+ center.x>0?'+':'-', ROUND(center.x/RESOLUTION*1000.0),
+ center.y>0?'+':'-', ROUND(center.y/RESOLUTION*1000.0),
+ ROUND(radius / RESOLUTION * 1000.0),
+ ROUND(decimalanglestart)>=1000?0:ROUND(decimalanglestart),
+ ROUND(decimalangleend)>=1000?0:ROUND(decimalangleend),
+ 3, ENDCMD);
+ printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y);
+ break;
+ case '~': /* Squiggly line */
+ (void)cgets(extension);
+ s = extension;
+ n = 0;
+ controlpoints[n][0] = virthpxl;
+ controlpoints[n][1] = virtvpxl;
+ controlpoints[n][2] = 0.0;
+ while (s = extractinteger(s, &c)) {
+ if (!(s = extractinteger(s, &d))) {
+ fprintf(stderr,
+ "%s: odd number of spline points given\n", Whoami);
+ break;
+ }
+ n++;
+ controlpoints[n][0] = controlpoints[n-1][0] + c;
+ controlpoints[n][1] = controlpoints[n-1][1] + d;
+ controlpoints[n][2] = 0.0; /* Ignore z axis */
+ }
+ spline(controlpoints, n, curvepoints, 499, 3); /* 2nd degree */
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND(curvepoints[0][0]/RESOLUTION*1000.0),
+ ROUND(curvepoints[0][1]/RESOLUTION*1000.0));
+ printf("%s03", PENWIDTH);
+ for (c = 1; c <= 499; c++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND(curvepoints[c][0]/RESOLUTION*1000.0),
+ ROUND(curvepoints[c][1]/RESOLUTION*1000.0));
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl = ROUND(curvepoints[n][0]), virtvpxl =
+ ROUND(curvepoints[n][1]);
+ realhpxl = realvpxl = 0;
+ break;
+ default:
+ fprintf(stderr, "%s: invalid ditroff draw command %c\n",
+ Whoami, c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ break;
+ case 'x': /* Device dependent commands */
+ switch (c = getnonblank(stdin)) {
+ case 'i': /* Init - do nothing */
+ while (!isspace(cgetchar())) /* Find next blank */
+ ;
+ break;
+ case 'T': /* Name of typesetter. -T option */
+ if (!EQ(DEVNAME, s = getstring(stdin))) {
+ fprintf(stderr,"%s: %s input given to ditroff filter\n",
+ Whoami, s);
+ cleanup(FontList, 2);
+ }
+ break;
+ case 'r': /* Resolution */
+ while (!isspace(getchar()))
+ ;
+ if (getinteger(stdin) != RESOLUTION) {
+ fprintf(stderr, "%s: ditroff input resolution != %d\n",
+ Whoami, RESOLUTION);
+ cleanup(FontList, 2);
+ }
+ /* Order of evaluation is immaterial */
+ if (getinteger(stdin) != 1 || getinteger(stdin) != 1) {
+ fprintf(stderr,
+ "%s: incorrect ditroff input increments\n", Whoami);
+ cleanup(FontList, 2);
+ }
+ break;
+ case 'p': /* Pause */
+ while (!isspace(cgetchar()))
+ ;
+ break;
+ case 's': /* Stop */
+ while ((c = getchar()) != EOF) /* Standard I/O getchar */
+ ;
+ callcleanup();
+ break;
+ case 't': /* Trailer */
+ while (!isspace(cgetchar()))
+ ;
+ break;
+ case 'f': /* Load font into mount table */
+ while (!isspace(cgetchar()))
+ ;
+ c = getinteger(stdin);
+ s = getstring(stdin);
+ (void)strcpy(MountTable[c], s);
+ /* The special font must be named S */
+ if (EQ(s, "S"))
+ specialfont = c;
+ if (!findpkfont(s, 10)) /* Just check for font, any size. */
+ fprintf(stderr,
+ "%s: could not find font %s at any magnification\n",
+ Whoami, s);
+ break;
+ case 'H': /* Height - QMS can't do */
+ while (!isspace(cgetchar()))
+ ;
+ (void)getinteger(stdin);
+ break;
+ case 'S': /* Slant - QMS can't do */
+ while (!isspace(cgetchar()))
+ ;
+ (void)getinteger(stdin);
+ break;
+ case 'X': /* Extensions */
+ (void)cgets(extension);
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ Pxxxstring = Xxxstring = extension;
+ Origin[0] = virthpxl, Origin[1] = virtvpxl;
+ (void)yyparse();
+ 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;
+ default:
+ fprintf(stderr, "%s: invalid ditroff x command %c\n", Whoami,
+ c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ break;
+ default:
+ fprintf(stderr, "%s: invalid ditroff command %c\n", Whoami, c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ }
+}
+
+/* Returns a pointer to a node on the FontList with the matching name,
+ * pointsize and orientation or NULL if not found.
+ */
+struct FontNode *getnodebyname(head, name, ptsize, or)
+struct FontNode *head;
+char *name;
+int ptsize;
+int or;
+{
+ struct FontNode *p;
+
+ for (p = head; p; p = p->next)
+ if (p->localinfo && LI(p)->pointsize == ptsize && (p->flags & PORT
+ ? 'P' : 'L') == or && EQ(LI(p)->name, name))
+ return p;
+ return NULL;
+}
+
+/* Adds a new font to the font list. All the fields in the LocalInfo
+ * structure are filled in. If the font is loaded on startup, the blocksize
+ * is left as is; otherwise, the blocksize is estimated.
+ */
+struct FontNode *fonttolist(font, pointsize)
+char *font;
+int pointsize;
+{
+ long fontstructoffset; /* Offset at beginning of font structure */
+ long funnycharoffset;/* Offset before funny_char_index_table */
+ long ftell();
+ int qmsfontnum, mag, ds, i, c, fontindex, encodecompare();
+ short size, index;
+ char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(),
+ descfilename[81], *findpkfont();
+ Boolean extractinfo();
+ void seteoffunction(), pkeofsocleanup(), desceofsocleanup(),
+ troffeofsocleanup();
+ FILE *f;
+ struct dev devheader;
+ struct font fontheader;
+ struct FontNode *fn, *getfontnode();
+ struct FontInfo *fi, *getfontinfo();
+
+ if (strlen(font) == 0 || pointsize == 0) /* One of the two has not */
+ return NULL; /* been filled in yet. */
+ /* If this works, we don't need to search the font directory */
+ if (fn = getnodebyname(FontList, font, pointsize, Orientation))
+ return fn;
+ if (!(fullfontpath = findpkfont(font, pointsize)))
+ return NULL; /* Try to continue */
+ qmsfontnum = getnumfromtable(tail(fullfontpath));
+ 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) /* This font is already on the list */
+ return fn;
+ else
+ 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)->name, font);
+ (void)strcpy(LI(fn)->pathname, fullfontpath);
+ (void)extractinfo(tail(LI(fn)->pathname), fontname, sfontname, &ds, &mag);
+ LI(fn)->pointsize = ROUND(mag / (double)RESOLUTION * UNITWIDTH);
+ (void)strcpy(EOFName, 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'))) {
+ FontList = FontList->next; /* Bad PK file or not readable */
+ fprintf(stderr, "%s: could not open or bad PK file %s\n", Whoami,
+ fullfontpath);
+ free(fn->localinfo), free((char *)fn);
+ return NULL;
+ }
+ if (!(fn->flags & PRELOADED))
+ fn->blocksize = fi->blocksize;
+ seteoffunction(troffeofsocleanup);
+ LI(fn)->qmsheight = fi->qmsheight;
+ LI(fn)->qmsbaseline = fi->qmsbaseline;
+ for (i = 0; i < 256; i++) {
+ if (fi->chararray[i].tfm > 0 || (fi->chararray[i].w > 0 &&
+ fi->chararray[i].h > 0))
+ LI(fn)->charexists[i] = TRUE;
+ else
+ LI(fn)->charexists[i] = FALSE;
+ LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds /
+ (double)FIX) / FIX) / PPI * RESOLUTION * ((double)LI(fn)->pointsize
+ / UNITWIDTH));
+ LI(fn)->bitmapsize[0][i] = fi->chararray[i].w;
+ LI(fn)->bitmapsize[1][i] = fi->chararray[i].h;
+ }
+ (void)sprintf(descfilename, "%s/%s", FONTDIR, "DESC.out");
+ LI(fn)->maptablesize = 0;
+ if (!(f = fopen(descfilename, "r"))) { /* Couldn't access DESC.out! */
+ static Boolean printed = FALSE;
+
+ if (!printed) { /* Only print error message once */
+ fprintf(stderr, "%s: could not open %s file \n", Whoami,
+ descfilename);
+ printed = TRUE;
+ }
+ return fn;
+ }
+ (void)strcpy(EOFName, descfilename);
+ seteoffunction(desceofsocleanup);
+ (void)cfread((char *)&devheader, sizeof(struct dev), 1, f);
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ while (size)
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ funnycharoffset = ftell(f);
+ assert(devheader.nchtab <= 160);
+ (void)fseek(f, (long)devheader.nchtab * sizeof(short) + devheader.lchname,
+ 1);
+ for (fontstructoffset = ftell(f); (i = fread((char *)&fontheader,
+ sizeof(struct font), 1, f)) == 1 && !EQ(LI(fn)->name, fontheader.namefont);
+ (void)fseek(f, 3L * fontheader.nwfont + 96 + devheader.nchtab, 1),
+ fontstructoffset = ftell(f))
+ ;
+ if (i != 1) { /* font not found */
+ (void)fclose(f);
+ seteoffunction(troffeofsocleanup);
+ return fn;
+ }
+ for (i = 0; i < devheader.nchtab; i++) {
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 *
+ fontheader.nwfont + 96 + i, 0);
+ if ((fontindex = cgetc(f)) == 0)
+ continue;
+ (void)fseek(f, funnycharoffset + i * sizeof(short), 0);
+ (void)cfread((char *)&index, sizeof(short), 1, f);
+ (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) +
+ index, 0);
+ /* The special strings are encoded, put in the maptable and
+ * sorted for fast lookup using a binary search. The encoding must
+ * preserve the uniqueness of the strings. Assuming special
+ * sequences are 3 bytes or less, we can put the bytes of the strings
+ * in the 3 low order bytes of the maptable[] word and use
+ * the high order byte to store the position in the font.
+ */
+ LI(fn)->maptable[LI(fn)->maptablesize] = 0;
+ while ((c = cgetc(f)) != '\0')
+ LI(fn)->maptable[LI(fn)->maptablesize] =
+ LI(fn)->maptable[LI(fn)->maptablesize] << 8 | c;
+ LI(fn)->maptable[LI(fn)->maptablesize] &= 0xFFFFFF;/*Keep low 3 bytes*/
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 2 *
+ fontheader.nwfont + fontindex, 0);
+ LI(fn)->maptable[LI(fn)->maptablesize] |= cgetc(f) << 24; /* Put font*/
+ LI(fn)->maptablesize++; /* pos in top byte */
+ }
+ (void)fclose(f);
+ seteoffunction(troffeofsocleanup);
+ qsort((char *)(LI(fn)->maptable), LI(fn)->maptablesize, sizeof(long),
+ encodecompare);
+ return fn;
+}
+
+/* Returns the full pathname of the font whose size most closely matches that
+ * passed as a parameter. Returns NULL if it can't open the directory or it
+ * cannot find the font at any magnification. The return value is static and
+ * overwritten with each call.
+ */
+char *findpkfont(fontname, pointsize)
+char *fontname;
+int pointsize;
+{
+ int closestnumber = MAX_INTEGER;
+ int desiredmagnification = ROUND(RESOLUTION * pointsize /
+ (double)UNITWIDTH);
+ static char returnvalue[101];
+ DIR *dirp;
+ struct direct *direntry;
+ char dirfname[81], dirsfname[81];
+ Boolean extractinfo();
+ int dirdsize, dirmag;
+
+ returnvalue[0] = '\0';
+ if (dirp = opendir(PKDir)) {
+ 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", PKDir,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ return NULL;
+}
+
+/* Adjusts printer coordinates so they correspond to ditroff's coordinates. It
+ * adjusts the real coordinates if necessary.
+ */
+void adjust(realh, realv, virth, virtv)
+int *realh, *realv, virth, virtv;
+{
+ if (*realh != virth) {
+ printf("%s%05d%s", TAB, ROUND(virth / (double)RESOLUTION * 1000.0),
+ ENDCMD);
+ *realh = virth;
+ }
+ if (*realv != virtv) {
+ printf("%s%05d%s", JUSTIFYMARGIN, ROUND(virtv / (double)RESOLUTION *
+ 1000.0), ENDCMD);
+ *realv = virtv;
+ }
+}
+
+/* Compares two encodings of troff special sequences */
+int encodecompare(one, two)
+long *one, *two;
+{
+ return (*one & 0xFFFFFF) == (*two & 0xFFFFFF) ? 0 : (*one & 0xFFFFFF)
+ < (*two & 0xFFFFFF) ? -1 : 1;
+}
+
+/* Looks up a special sequence in the maptable and returns the position
+ * found. It returns -1 if not found. This routine uses a binary search.
+ */
+int lookup(table, numvalues, key)
+long table[];
+int numvalues;
+char *key;
+{
+ int start = 0, end = numvalues - 1, midpoint;
+ long keyencoded; /* An encoded version of the key */
+ char *p;
+
+ for (p = key, keyencoded = 0; p && *p; p++)
+ keyencoded = (keyencoded << 8) | *p;
+ while (start <= end) {
+ midpoint = (start + end) / 2;
+ if ((keyencoded & 0xFFFFFF) == (table[midpoint] & 0xFFFFFF))
+ return midpoint;
+ if ((keyencoded & 0xFFFFFF) > (table[midpoint] & 0xFFFFFF))
+ start = midpoint + 1;
+ else
+ end = midpoint - 1;
+ }
+ return -1;
+}
+
+/* Downloads a font */
+Boolean download(fn)
+struct FontNode *fn;
+{
+ struct CharInfo *ci;
+ char *tail(), *strcpy();
+ void resetpkfile(), seteoffunction(),
+ downloadpkeofsocleanup(), troffeofsocleanup();
+ 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(EOFName, 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, LI(fn)->widths[ci->cc]);
+ 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(troffeofsocleanup);
+ CurRamBlocks += fn->blocksize;
+ fn->flags |= LOADED;
+ (void)sigsetmask(sigblock(0) & ~SIGINT);
+ return TRUE;
+}
+
+/* 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 troffeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading ditroff file\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void pkeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading PK file %s\n", Whoami,
+ EOFName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void desceofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DESC.out file %s\n",
+ Whoami, EOFName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+downloadinterrupt()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ callcleanup();
+}
+
+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();
+}
+
+#include "xxx.c"