|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 35849 (0x8c09)
Types: TextFile
Names: »df.c.backup«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
└─⟦this⟧ »./DVIware/laser-setters/quicspool/src/df.c.backup«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z«
└─⟦ca79c7339⟧
└─⟦this⟧ »DVIware/laser-setters/quicspool/src/df.c.backup«
/* 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"