diff options
Diffstat (limited to 'dviware/quicspool/src/tf.c_backup')
-rw-r--r-- | dviware/quicspool/src/tf.c_backup | 953 |
1 files changed, 953 insertions, 0 deletions
diff --git a/dviware/quicspool/src/tf.c_backup b/dviware/quicspool/src/tf.c_backup new file mode 100644 index 0000000000..c3b7897199 --- /dev/null +++ b/dviware/quicspool/src/tf.c_backup @@ -0,0 +1,953 @@ +/* Old troff driver */ +#ifndef lint +static char *rcs = "$Header: tf.c.backup,v 1.2 88/02/03 08:52:30 simpson Exp $"; +#endif +/* +$Log: tf.c.backup,v $ +Revision 1.2 88/02/03 08:52:30 simpson +added tpic support + +Revision 1.1 88/01/15 13:05:39 simpson +initial release + +Revision 0.2 87/12/18 11:38:39 simpson +added void for lint + +Revision 0.1 87/12/11 18:31:22 simpson +beta test + +*/ +#include <stdio.h> +#include <signal.h> +#include <assert.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" + +#define FONTDIR "--FONTDIR--" +/* Cast for accessing LocalInfo */ +#define LI(p) ((struct LocalInfo *)p->localinfo) + +#define TILT 1 /* 1 == down */ +#define RAIL 2 /* 1 == upper */ +#define MAGAZINE 4 /* 1 == upper */ +#define UPPERHALF 8 /* 1 == upper font half */ +#define ESCFORWARD 16 +#define LEADFORWARD 32 + +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 */ + short bitmapsize[2][256]; /* Width & height of each char bitmap */ + int widths[256]; /* Width in HORCATRESes */ +}; + +/* Old dumb troff only uses 4 fonts */ +char *Fonts[4] = {"R", "I", "B", "S"}; +char flags; /* ESCFORWARD,LEADFORWARD,UPPER,RAIL,MAGAZINE,TILT */ +char EOFName[101]; /* Used by pkeofsocleanup() */ +char *Whoami; /* argv[0] */ +char *Model; /* Model of printer being used */ +char Orientation = 'P'; +char PKDir[101]; /* Directory location of PK files */ +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 */ +FILE *ReadLine; /* Debugger port tty */ +struct sigvec SigStruct; +struct FontNode *FontList; /* Contains all fonts and 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(); + 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 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); + } + (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); + 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() +{ + struct FontNode *curnode= NULL; /* Current font troff has selected */ + struct FontNode *fonttolist(); + int curfont = 0; /* Current font selected in Fonts */ + int curptsize = 10; /* Current pt size selected */ + int c, d; + int realhpxl, realvpxl; /* Real pixel locations */ + int virthpxl, virtvpxl; /* Virtual pixel locations */ + int h; /* In HORCATRES */ + int v; /* In VERCATRES */ + Boolean single = TRUE; /* Doubler lens */ + Boolean fontselected = FALSE, download(), makeroom(); + /* The first escape and lead are skipped since this sets up the machine */ + Boolean skipesc = TRUE, skiplead = TRUE; + /* Keep track of whether we have printed on the page because the C/A/T */ + /* does a lot of leads at the end of a job. */ + Boolean printedonpage = FALSE; + int blankpagecount = 0; + extern char RegularToAscii[], SpecialToAscii[]; + void endoflist(); + + h = v = realhpxl = realvpxl = virthpxl = virtvpxl = 0; + while (TRUE) { /* A non-returning function is called to exit. */ + c = cgetchar(); + if (c == 0) /* Ignore nulls */ + continue; + if (c == 0xFF) { /* Alls 1s is an error */ + fprintf(stderr, "%s: invalid troff command 0xFF\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + virthpxl = ROUND(h / (double)HORCATRES * RESOLUTION); + virtvpxl = ROUND(v / (double)VERCATRES * RESOLUTION); + if (c & 0x80) { /* Escape code */ + if (skipesc) + skipesc = FALSE; + else { + d = (c ^ 0x7F) & 0x7F; + if (flags & ESCFORWARD) + h += d; + else + h -= d; + } + continue; + } + if (c & 0x40) { /* Control code */ + if (c & 0x20) { /* Lead code */ + if (skiplead) + skiplead = FALSE; + else { + d = (c ^ 0x1F) & 0x1F; + if (flags & LEADFORWARD) + v += d; + else + v -= d; + /* The C/A/T formfeeds by running off the page! Well, the + * the C/A/T uses (used?) continuous roll paper so this is + * not as crazy as it sounds. + */ + if (v > ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES)) + { + v -= ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES + ); + if (printedonpage) { + realhpxl = realvpxl = 0; + fputs(FORMFEED, stdout), NumPages++; + printedonpage = FALSE; + } else + blankpagecount++; /* Ignore at end of job but */ + } /* not in between */ + } + continue; + } + if (c & 0x10) { /* Size change */ + switch (c & 0xF) { + case 0: + if (!single) + h += 55; + single = TRUE; + curptsize = 7; + break; + case 1: + if (!single) + h += 55; + single = TRUE; + curptsize = 8; + break; + case 2: + if (!single) + h += 55; + single = TRUE; + curptsize = 10; + break; + case 3: + if (!single) + h += 55; + single = TRUE; + curptsize = 11; + break; + case 4: + if (!single) + h += 55; + single = TRUE; + curptsize = 12; + break; + case 5: + if (!single) + h += 55; + single = TRUE; + curptsize = 14; + break; + case 6: + if (!single) + h += 55; + single = TRUE; + curptsize = 18; + break; + case 7: + if (!single) + h += 55; + single = TRUE; + curptsize = 9; + break; + case 8: + if (!single) + h += 55; + single = TRUE; + curptsize = 6; + break; + case 9: + if (single) + h -= 55; + single = FALSE; + curptsize = 16; + break; + case 10: + if (single) + h -= 55; + single = FALSE; + curptsize = 20; + break; + case 11: + if (single) + h -= 55; + single = FALSE; + curptsize = 22; + break; + case 12: + if (single) + h -= 55; + single = FALSE; + curptsize = 24; + break; + case 13: + if (single) + h -= 55; + single = FALSE; + curptsize = 28; + break; + case 14: + if (single) + h -= 55; + single = FALSE; + curptsize = 36; + break; + case 15: + fprintf(stderr, "%s: invalid otroff size change 0x5F\n", + Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + curnode = fonttolist(Fonts[curfont], curptsize); + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + continue; + } + switch (c & 0xF) { /* Control code command */ + case 0x0: /* Initialize */ + flags |= ESCFORWARD | LEADFORWARD | TILT; + flags &= ~(MAGAZINE | RAIL | UPPERHALF); + break; + case 0x9: /* Stop */ + while (getchar() != EOF) + ; /* Consume rest of input */ + if (printedonpage) + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, SUCCEED); + case 0x2: /* Upper rail */ + flags |= RAIL; + goto reloadfont; + case 0x1: /* Lower rail */ + flags &= ~RAIL; + goto reloadfont; + case 0x3: /* Upper magazine */ + flags |= MAGAZINE; + goto reloadfont; + case 0x4: /* Lower magazine */ + flags &= ~MAGAZINE; +reloadfont: curfont = flags >> 1 & 0x3; /* Ignore tilt */ + curnode = fonttolist(Fonts[curfont], curptsize); + 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 0xE: /* Tilt up */ + break; /* No op */ + case 0xF: /* Tilt down */ + break; /* No op */ + case 0x6: /* Upper font half */ + flags |= UPPERHALF; + break; + case 0x5: /* Lower font half */ + flags &= ~UPPERHALF; + break; + case 0x7: + flags |= ESCFORWARD; /* Escape forward */ + break; + case 0x8: + flags &= ~ESCFORWARD; /* Escape backward */ + break; + case 0xA: /* Lead forward */ + flags |= LEADFORWARD; + break; + case 0xC: /* Lead backward */ + flags &= ~LEADFORWARD; + break; + case 0xB: /* Extension */ + switch (c = cgetchar()) { + case 1: /* Big lead */ + if (flags & LEADFORWARD) + v += 64 * cgetchar(); + else + v -= 64 * cgetchar(); + break; + case 2: /* Big escape */ + if (flags & ESCFORWARD) + h += 128 * cgetchar(); + else + h -= 128 * cgetchar(); + break; + case 3: /* Formfeed */ + fputs(FORMFEED, stdout), NumPages++; + realhpxl = realvpxl = 0; + printedonpage = FALSE; + break; + } + break; + case 0xD: /* Error! */ + fprintf(stderr, "%s: illegal otroff command 0x4D\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + continue; + } + d = c & 0x3F; /* Flash code */ + printedonpage = TRUE; + if (blankpagecount > 0) { + for (c = 0; c < blankpagecount; c++) + fputs(FORMFEED, stdout), NumPages++; + blankpagecount = 0; + } + if (d > 45 && flags & UPPERHALF) { + fprintf(stderr, "%s: illegal otroff flash code %d\n", Whoami, + d); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + if (flags & UPPERHALF) + d += 64; + d = (curfont == 3 ? SpecialToAscii[d] : RegularToAscii[d]); + if (d == 0) /* Character not used */ + continue; + /* If we couldn't find the font, don't anything since we don't know + * how to increment the real pixel locations. + */ + if (!curnode || !curnode->localinfo) + continue; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + 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 trytocontinue; + } + if (!download(curnode)) + goto trytocontinue; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + } + 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 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. + */ +trytocontinue: + if (LI(curnode)->bitmapsize[0][d] != 0 && LI(curnode)->bitmapsize[1][d] + != 0) { + if (d == '^' || d <= 32 || d >= 127) + printf("%s%02X", SPECIAL, d); + else + (void)putchar(d); + realhpxl += ROUND(LI(curnode)->widths[d] / (double)HORCATRES * + RESOLUTION); + } + } +} + +/* Adjusts printer coordinates so they correspond to otroff's coordinates. It + * adjusts the real coordinates if necessary. + */ +void adjust(realh, realv, virth, virtv, h, v) +int *realh, *realv, virth, virtv, h, v; +{ + if (*realh != virth) { + printf("%s%05d%s", TAB, ROUND(h / (double)HORCATRES * 1000.0), + ENDCMD); + *realh = virth; + } + if (*realv != virtv) { + printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v / (double)VERCATRES * + 1000.0), ENDCMD); + *realv = virtv; + } +} + +/* 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; +} + +/* 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/10.0); + 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; +} + +/* 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; +{ + int qmsfontnum, mag, ds, i; + char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(), + *findpkfont(), *strcpy(); + Boolean extractinfo(); + void seteoffunction(), pkeofsocleanup(), desceofsocleanup(), + troffeofsocleanup(); + 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 * 10); + (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++) { + LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds / + (double)FIX) / FIX) / PPI * HORCATRES * (LI(fn)->pointsize + / 10.0)); + LI(fn)->bitmapsize[0][i] = fi->chararray[i].w; + LI(fn)->bitmapsize[1][i] = fi->chararray[i].h; + } + return fn; +} + +/* 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, ROUND(LI(fn)->widths[ci->cc] / + (double)HORCATRES * 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(troffeofsocleanup); + CurRamBlocks += fn->blocksize; + fn->flags |= LOADED; + (void)sigsetmask(sigblock(0) & ~SIGINT); + return TRUE; +} + +/* The following routines are 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 otroff 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); +} + +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(); +} |