diff options
Diffstat (limited to 'dviware/dvibit/dvibit.c')
-rw-r--r-- | dviware/dvibit/dvibit.c | 1293 |
1 files changed, 1293 insertions, 0 deletions
diff --git a/dviware/dvibit/dvibit.c b/dviware/dvibit/dvibit.c new file mode 100644 index 0000000000..7063aafcc7 --- /dev/null +++ b/dviware/dvibit/dvibit.c @@ -0,0 +1,1293 @@ +/* +** +** dvibit 1 December 1983 Mark Senn +** +** 21 January 1984 James L. Schaad +** +** This program is a PRELIMINARY VERSION. Improvements will be made +** before the production version is released. +** +** This program displays a DVI file on a version 3.10 BBN BitGraph +** terminal. To use the program say `dvibit dvifile'. This program +** can only process DVI format 2 files. +** +** After each page of the output is displayed the program will wait for +** the RETURN key to be typed before displaying the following page. +** +** This is a `bare bones' DVI-to-BitGraph program. Minimal error checking +** is done. For more complete error checking dvitype(1) should be run. +** +** Stephan Bechtolsheim, Bob Brown, Richard Furuta, and Robert Wells +** provided invaluable help and advice. +** +** +** In the new version of the program the following changes have been made +** (release date of new version 21 January 1984): +** +** 1. The program no longer writes out a log file unless it is necessary +** to record non-fatal errors. If it is necessary to make a log file +** and the directory will not allow the create of the log file then +** the program will continue as if no error had happened. Log file +** creation may be prevented entirely by including -l in the command +** line. +** +** 2. The program now defaults to going to the end of the file and reading +** in all of the font definitions before any text is displayed on the +** screen. This means that font definitions that are encountered in +** the file are now ignored. Note that one may return to reading in +** the font definitions as they are encountered, but this is not +** recommended since there are no traps to prevent multiple reading in +** of font definitions. The in line reading of font definitions may +** be obtained by including a -p in the command line. +** +** 3. The program under went a major restructuring of where routines lie, +** routines are now called as subroutines when ever practical rather +** than using goto's. This leads to a much cleaner mainline program +** and does not loose a significant amount of time to overhead since +** the program is usually I/O bound. +** +** 4. The ability to skip pages in the file was added. One may jump +** a number of pages forwards or backward in the file. This number +** of pages was relative, no need was seen for absolute jumping since +** there may be multiple pages in the file with the same page number +** and this would result in a confict as to which page was really meant. +** This feature may be obtained from the command line by including a +** +xxx before the file name, this will skip xxx pages into the file +** before displaying any printed material. +** +** 5. This also has a fairly simplistic clipping routine incorpated into +** the display of charactors. It does not always seem to work at the +** peak but I don't want to bother trying to improve it at this time. +*/ + + +/**********************************************************************/ +/*********************** external definitions ***********************/ +/**********************************************************************/ + +#include "commands.h" +#include <sgtty.h> +#include <signal.h> +#include <stdio.h> + +char *getenv(); +char *index(); +char *malloc(); +char *rindex(); +char *sprintf(); +char *strcpy(); + +/* #define Debug /* when testing */ + +/* We leave USEGLOBALMAG undefined because there are only a very limited number + font magnifications provided for this program and if it is defined, any + dvi file is as likely as not to fail */ +/* ---fixme--- put something into the log file if it's not mag 1000 */ +/* #define USEGLOBALMAG /* when defined, the dvi global magnification is applied */ + +#define BIGBGCHAR 32 /* number of 16 bit words in a big character */ +#define DVIFORMAT 2 +#define FALSE 0 +#define FIRSTBGCHAR 32 +#define FIRSTPXLCHAR 0 +#ifndef FONTAREA +#define FONTAREA "/usr/lib/tex/fonts/" +#endif +#define LASTBGCHAR 127 +#define LASTPXLCHAR 127 +#define NBGFONTS 3 /* number of PXL fonts that can be downloaded into the BitGraph */ +#define NPXLCHARS 128 +#define PXLID 1001 +#define RESOLUTION 118 /* is really 91.72192515 */ +#define STACKSIZE 100 +#define STRSIZE 257 +#define TRUE 1 +#define XDIFFMAX 20 +#define XDIFFORG (FIRSTBGCHAR+XDIFFMAX) +#define XSIZE 768 +#define YDIFFMAX 20 +#define YDIFFORG (FIRSTBGCHAR+XDIFFMAX+1+XDIFFMAX+YDIFFMAX) +#define YSIZE 1024 + +int G_errenc = FALSE; /* has an error been encountered? */ +char G_Logname[STRSIZE]; /* name of log file, if created */ +int G_interactive = TRUE; /* is the program running interactively */ + /* (i.e., standard output not redirected)? */ +int G_logging = 0; /* Is a log file being created? */ +struct sgttyb G_intty; /* information about stdin if interactive */ +FILE *G_logfp; /* log file pointer (for errors) */ +char G_progname[STRSIZE]; /* program name */ + +struct char_entry { /* character entry */ + unsigned short wp, hp; /* width and height in pixels */ + short xoffp, yoffp; /* x offset and y offset in pixels */ + int pfrp; /* pixel file raster pointer */ + int tfmw; /* TFM width */ + int pxlw; /* pixel width (the TFM width rounded to pixels) */ + unsigned istoobig : 1; /* is the character too big to fit in the BitGraph? */ + unsigned isloaded : 1; /* is the character loaded in the BitGraph? */ + /* We depend on the two preceding bit fields to */ + /* be zero initially; they are not explicitly set. */ + int bgfont, bgchar; /* BitGraph font and character */ +}; + + +struct font_entry { /* font entry */ + int k, c, s, d, a, l; char n[STRSIZE]; /* FNT_DEF command parameters */ + int font_space; /* computed from FNT_DEF s parameter */ + int font_mag; /* computed from FNT_DEF s and d parameters */ + char name[STRSIZE]; /* full name of PXL file */ + int magnification; /* magnification read from PXL file */ + int designsize; /* design size read from PXL file */ + struct char_entry ch[NPXLCHARS]; /* character information */ + struct font_entry *next; /* pointer to next font entry */ +}; + + + +/************************************************************************/ + + +struct char_entry *bgcp[NBGFONTS+(NBGFONTS+2)/3][NPXLCHARS]; + /* Pointer to corresponding char_entry for */ + /* this BitGraph font and character. These */ + /* pointers are used to set the char_entry's */ + /* status to not loaded when we have to reuse*/ + /* the BitGraph character. We depend on all */ + /* these being NULL initially; they are not */ + /* explicitly set. */ +float conv; /* converts DVI units to pixels */ +int den; /* denominator specified in preamble */ +FILE *dvifp; /* DVI file pointer */ +struct font_entry *fontptr; /* font_entry pointer */ +int fullfont = 0; /* full font to load in BitGraph */ +struct font_entry *hfontptr = NULL; /* head font_entry pointer */ +int h; /* current horizontal position */ +int hh; /* current horizontal position in pixels */ +int mag; /* magnification specified in preamble */ +int num; /* numerator specified in preamble */ +int partchar = FIRSTBGCHAR; /* partial font character to load in BitGraph*/ +int partfont = NBGFONTS; /* partial font to load in BitGraph */ +int pbghpos; /* previous BitGraph horizontal position */ +int pbgvpos; /* previous BitGraph vertical position */ +struct font_entry *pfontptr = NULL; /* previous font_entry pointer */ +int pbgf = -1; /* previous BItGraph font */ +long postambleptr; /* Pointer to the postamble */ +FILE *pxlfp; /* PXL file pointer */ +struct tchars tcb; /* information about special terminal chars */ +struct sgttyb tty; /* to see if program is running interactively*/ +int xdiff; /* x difference */ +int xscreen; /* x screen adjustment */ +int v; /* current vertical position */ +int vv; /* current vertical position in pixels */ +int ydiff; /* y difference */ +int yscreen; /* y screen adjustment */ + + + +/**********************************************************************/ +/******************************* main *******************************/ +/**********************************************************************/ + +main(argc, argv) + int argc; + char *argv[]; + +{ + void GotInterrupt(); + float ActualFactor(); + + + struct stack_entry { /* stack entry */ + int h, hh, v, vv, w, x, y, z; /* what's on stack */ + }; + + int argind; /* argument index for flags */ + int command; /* current command */ + long cpagep; /* current page pointer */ + char curarea[STRSIZE]; /* current file area */ + char curext[STRSIZE]; /* current file extension */ + char curname[STRSIZE]; /* current file name */ + char filename[STRSIZE]; /* file name */ + register int i; /* command parameter; loop index */ + int k; /* temperary parameter */ + char n[STRSIZE]; /* command parameter */ + int PagesLeft; /* Number of pages left to skip */ + int PreLoad = TRUE; /* preload the font descriptions? */ + long ppagep; /* previous page pointer */ + int SkipMode = FALSE; /* in skip mode flag */ + int sp; /* stack pointer */ + struct stack_entry stack[STACKSIZE]; /* stack */ + int t; /* temporary */ + char tc; /* temporary character */ + char *tcp, *tcp1; /* temporary character pointers */ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + int val, val2; /* hold temporary values for commands */ + int w; /* current horizontal spacing */ + int x; /* current horizontal spacing */ + int y; /* current vertical spacing */ + int z; /* current vertical spacing */ + + strcpy(G_progname, argv[0]); + + if (argc < 2) { + fprintf(stderr, "\nusage: %s -pl +pages dvifile\n\n", G_progname); + exit(1); + } + + if (ioctl(1,TIOCGETP,&tty) == -1) + G_interactive = FALSE; + + if (G_interactive) { + if ((tcp=getenv("TERM")) == NULL) { + fprintf (stderr, "\n%s: can't find environment variable \"TERM\"\n\n", G_progname); + exit (1); + } else { + if (strcmp(tcp,"bitgraph") && strncmp(tcp,"bg",2)) { + fprintf(stderr, "\n%s: can't run interactively on non-BitGraph terminal\n\n", G_progname); + exit(1); + } + } + } + + argind = 1; + while (*argv[argind] == '-') + { tcp = argv[argind]; + tcp++; + switch(*tcp){ + case 'l': /* l prohibits logging of errors */ + G_logging = -1; + break; + + case 'p': /* p prohibits pre-font loading */ + PreLoad = FALSE; + break; + + default: + printf("%c is not a legal flag\n", *tcp); + } + argind++; + } + + if (*argv[argind] == '+') + { sscanf(&argv[argind][1], "%d", &PagesLeft); + argind++; + SkipMode = TRUE; + PagesLeft++; + } + + tcp = rindex(argv[argind], '/'); + if (tcp == NULL) { + curarea[0] = '\0'; + tcp = argv[argind]; + } else { + strncpy(curarea, argv[argind], tcp-argv[argind]+1); + tcp += 1; + } + tcp1 = index(tcp, '.'); + if (tcp1 == NULL) { + strcpy(curname, tcp); + tcp1 = index(tcp, '\0'); + } else + strncpy(curname, tcp, tcp1-tcp); + strcpy(curext, tcp1); + + strcpy(filename, curarea); + strcat(filename, curname); + if (curext[0] == '\0') + strcat(filename, ".dvi"); + else + strcat(filename, curext); + if ((dvifp=fopen(filename,"r")) == NULL) { + fprintf(stderr, "\n%s: can't open DVI file \"%s\"\n\n", G_progname, filename); + exit(1); + } + + strcpy(G_Logname, curname); + strcat(G_Logname, ".loh"); + + if (NoSignExtend(dvifp,1) != PRE) { + fprintf(stderr, "\n%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n", G_progname); + exit(1); + } + + signal(SIGINT, SIG_IGN); /* ignore interrupts */ + InitTerm(); + signal(SIGINT, GotInterrupt); /* catch interrupts */ + + if (G_interactive) { + ioctl(0, TIOCGETC, &tcb); /* get special characters */ + ioctl(0, TIOCGETP, &G_intty); /* get modes */ + tty = G_intty; + tty.sg_flags |= CBREAK; + tty.sg_flags &= ~ECHO; + ioctl(0, TIOCSETP, &tty); /* set modes */ + } + + i = SignExtend(dvifp,1); + if (i != DVIFORMAT) { + fprintf(stderr, "\n%s: DVI format = %d, can only process DVI format %d files\n\n", G_progname, i, DVIFORMAT); + exit(1); + } + if (PreLoad) + { ReadPostAmble(); + fseek(dvifp, (long) 14, 0); + } else + { num = NoSignExtend(dvifp,4); + den = NoSignExtend(dvifp,4); +#ifdef USEGLOBALMAG + mag = NoSignExtend(dvifp,4); + conv = ((float)num/(float)den) * ((float)mag/1000.0) * ((float)RESOLUTION/254000.0); +#else + mag = NoSignExtend(dvifp,4); /* get it even though it'll be ignored */ + conv = ((float)num/(float)den) * ((float)RESOLUTION/254000.0); +#endif + } + + k = NoSignExtend(dvifp,1); + GetBytes(dvifp, n, k); + + while (TRUE) + + switch (command=NoSignExtend(dvifp,1)) { + + case SET1: case SET2: case SET3: case SET4: + val = NoSignExtend(dvifp, command-SET1+1); + if (!SkipMode) prochar(val, command); + break; + + case SET_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp,4); + if (!SkipMode) prorule(val, val2, 1); + break; + + case PUT1: case PUT2: case PUT3: case PUT4: + val = NoSignExtend(dvifp,command-PUT1+1); + if (!SkipMode) prochar(val, command); + break; + + case PUT_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp,4); + if (!SkipMode) prorule(val, val2, 0); + break; + + case NOP: + break; + + case BOP: + cpagep = ftell(dvifp) - 1; + for (i=0; i<=9; i++) + NoSignExtend(dvifp,4); + ppagep = NoSignExtend(dvifp,4); + + printf("\033[2J"); /* ED Erase in Display */ + pbghpos = pbgvpos = -99; + h = hh = v = vv = w = x = y = z = 0; + sp = 0; + fontptr = NULL; + if (PagesLeft) + { PagesLeft--; + if (!PagesLeft) SkipMode = FALSE; + }; + break; + + case EOP: + printf("\033:-99;-99m"); /* BBNMOV Move Graphically */ + if (G_interactive && !SkipMode) { + t = FALSE; + while (!t) { /* sorry about this flow of control kludge */ + t = TRUE; + tc = getchar(); + if (tc==tcb.t_eofc) AllDone(); + switch (tc) { + case '\n': + xscreen = yscreen = 0; + break; + + case 'd': + yscreen -= (YSIZE/3); + fseek(dvifp, cpagep, 0); + break; + + case 'l': + xscreen -= (XSIZE/3); + fseek(dvifp, cpagep, 0); + break; + + case 'p': + if (ppagep != -1) { + fseek(dvifp, ppagep, 0); + } else { + fseek(dvifp, cpagep, 0); + } + xscreen = yscreen = 0; + break; + + case 'r': + xscreen += (XSIZE/3); + fseek(dvifp, cpagep, 0); + break; + + case 'u': + yscreen += (YSIZE/3); + fseek(dvifp, cpagep, 0); + break; + + case '-': + /* read in val */ + val = ReadInt(); + while (val-- && ppagep != -1) + { fseek(dvifp, ppagep, 0); + NoSignExtend(dvifp, 1); + for(i=0; i<=9; i++) + NoSignExtend(dvifp, 4); + cpagep = ppagep; + ppagep = NoSignExtend(dvifp, 4); + } + fseek(dvifp, cpagep, 0); + xscreen = yscreen = 0; + break; + + case '+': + /* read in val */ + val = ReadInt(); + SkipMode = TRUE; + PagesLeft = val; + break; + + default: + t = FALSE; + } + } + } + break; + + case PUSH: + if (sp >= STACKSIZE) + Fatal("stack overflow"); + stack[sp].h = h; + stack[sp].hh = hh; + stack[sp].v = v; + stack[sp].vv = vv; + stack[sp].w = w; + stack[sp].x = x; + stack[sp].y = y; + stack[sp].z = z; + sp++; + break; + + case POP: + --sp; + if (sp < 0) + Fatal("stack underflow"); + h = stack[sp].h; + hh = stack[sp].hh; + v = stack[sp].v; + vv = stack[sp].vv; + w = stack[sp].w; + x = stack[sp].x; + y = stack[sp].y; + z = stack[sp].z; + break; + + case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4: + val = SignExtend(dvifp,command-RIGHT1+1); + if (!SkipMode) MoveOver(val); + break; + + case W0: + if (!SkipMode) MoveOver(w); + break; + + case W1: case W2: case W3: case W4: + w = SignExtend(dvifp,command-W1+1); + if (!SkipMode) MoveOver(w); + break; + + case X0: + if (!SkipMode) MoveOver(x); + break; + + case X1: case X2: case X3: case X4: + x = SignExtend(dvifp,command-X1+1); + if (!SkipMode) MoveOver(x); + break; + + case DOWN1: case DOWN2: case DOWN3: case DOWN4: + val = SignExtend(dvifp,command-DOWN1+1); + if (!SkipMode) MoveDown(val); + break; + + case Y0: + if (!SkipMode) MoveDown(y); + break; + + case Y1: case Y2: case Y3: case Y4: + y = SignExtend(dvifp,command-Y1+1); + if (!SkipMode) MoveDown(y); + break; + + case Z0: + if (!SkipMode) MoveDown(z); + break; + + case Z1: case Z2: case Z3: case Z4: + z = SignExtend(dvifp,command-Z1+1); + if (!SkipMode) MoveDown(z); + break; + + case FNT1: case FNT2: case FNT3: case FNT4: + if (!SkipMode) SetFntNum(NoSignExtend(dvifp,command-FNT1+1)); + break; + + case XXX1: case XXX2: case XXX3: case XXX4: + k = NoSignExtend(dvifp,command-XXX1+1); + while (k--) + NoSignExtend(dvifp,1); + break; + + case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: + if (PreLoad) + { SkipFontDef (NoSignExtend(dvifp, command-FNT_DEF1+1)); + } else + { ReadFontDef (NoSignExtend(dvifp, command-FNT_DEF1+1)); + } + break; + + case PRE: + Fatal("PRE occurs within file"); + break; + + case POST: + fseek(dvifp, cpagep, 0); + SkipMode = FALSE; + PagesLeft = 0; + break; + + case POST_POST: + Fatal("POST_POST with no preceding POST"); + break; + + default: + if (command >= FNT_NUM_00 && command <= FNT_NUM_63) + {if (!SkipMode) SetFntNum(command - FNT_NUM_00);} + else if (command >= SET_CHAR_000 && command <= SET_CHAR_127) + {if (!SkipMode) prochar(command - SET_CHAR_000, command);} + else + Fatal("%d is an undefined command", command); + break; + + } + +} + + + +/* */ + +static prochar(c, command) + int c, command; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + + tcharptr = &(fontptr->ch[c]); + if (tcharptr->istoobig) + { fflush(stdout); + if (fontptr != pfontptr) + { if (pfontptr != NULL) + fclose(pxlfp); + if ((pxlfp=fopen(fontptr->name,"r")) == NULL) + Fatal("PXL file \"%s\" disappeared (big character)! - %d", fontptr->name, fontptr); + pfontptr = fontptr; + } + printf( "\033:%d;%dm", + (pbghpos=(hh-tcharptr->xoffp))+xscreen , + (pbgvpos=(YSIZE-vv+tcharptr->yoffp))+yscreen ); /* BBNMOV Move Graphically */ + fseek(pxlfp, tcharptr->pfrp*4, 0); + printf("\033P:1;%d;%ds", tcharptr->wp, tcharptr->hp); /* BBNDPD Display Pixel Data */ + LoadRast(pxlfp, tcharptr->wp, tcharptr->hp); + printf("\033\\"); /* ST String Terminator */ + } else + { if (!tcharptr->isloaded) + { fflush(stdout); + if (fontptr != pfontptr) + { if (pfontptr != NULL) + fclose(pxlfp); + if ((pxlfp=fopen(fontptr->name,"r")) == NULL) + Fatal("PXL file \"%s\" disappeared (normal character)! - b", fontptr->name); + pfontptr = fontptr; + } + if (bgcp[tcharptr->bgfont][tcharptr->bgchar] != NULL) + if (bgcp[tcharptr->bgfont][tcharptr->bgchar]->isloaded) + { bgcp[tcharptr->bgfont][tcharptr->bgchar]->isloaded = FALSE; + printf("\033:2;%d;%cL", tcharptr->bgchar, '0'+tcharptr->bgfont); + /* BBNSFP Set Font Parameters to reset character */ + } + fseek(pxlfp, tcharptr->pfrp*4, 0); + printf("\033P:0;%d;%c;%d;%d;%d;%d;%dL", + tcharptr->bgchar , (char)('0'+tcharptr->bgfont) , + tcharptr->wp , tcharptr->hp , + tcharptr->xoffp , tcharptr->hp-tcharptr->yoffp-1 , + tcharptr->pxlw-tcharptr->xoffp ); /* BBNLFC Load Font Character */ + LoadRast(pxlfp, tcharptr->wp, tcharptr->hp); + printf("\033\\"); /* ST String Terminator */ + tcharptr->isloaded = TRUE; + bgcp[tcharptr->bgfont][tcharptr->bgchar] = tcharptr; + } + if ((hh - tcharptr->xoffp + tcharptr->pxlw <= XSIZE - xscreen) + && (hh /* - tcharptr->xoffp */ >= - xscreen) && (vv <= YSIZE + yscreen) + && (vv >= yscreen)) + { xdiff = hh-pbghpos; ydiff = YSIZE-vv-pbgvpos; + if ((xdiff) || (ydiff)) + if ((abs(xdiff) <= XDIFFMAX) && (abs(ydiff) <= YDIFFMAX)) + { putchar('\016'); /* SO Switches to the G1 character set */ + if (xdiff) + putchar(XDIFFORG+xdiff); + if (ydiff) + putchar(YDIFFORG+ydiff); + putchar('\017'); /* SI Switches to the G0 character set */ + } else + printf("\033:%d;%dm", hh+xscreen, YSIZE-vv+yscreen); /* BBNMOV Move Graphically */ + if (tcharptr->bgfont != pbgf) + { printf("\033(%c", (char)('0'+tcharptr->bgfont)); /* SCS Select G0 to be a loadable font */ + pbgf = tcharptr->bgfont; + } + putchar(tcharptr->bgchar); + pbghpos = hh+tcharptr->pxlw-tcharptr->xoffp; pbgvpos = YSIZE-vv; + } + } + if (command <= SET4) + { /* note dependency on command opcodes */ + h += tcharptr->tfmw; + hh += tcharptr->pxlw; + } +} + + +/**********************************************************************/ +/***************************** prorule ******************************/ +/**********************************************************************/ + +/* this routine will draw a rule on the screen */ + +static prorule(a, b, Set) /* this should be a, b not b, a but it does not + work if that is done so I swapped them jls */ +int a, b, Set; +{ + if ((a>0) && (b>0)) + printf("\033:15;%d;%d;%d;%d;%d;%dr", + hh+xscreen , YSIZE-vv+yscreen , + hh+xscreen , YSIZE-vv+yscreen , + RulePixels(b,conv) , RulePixels(a,conv)); /* BBNRAST Rastop */ + if (Set) + { h += b; + hh += RulePixels(b, conv); + } +} + + +/**********************************************************************/ +/**************************** SetFntNum *****************************/ +/**********************************************************************/ + +/* this routine is used to specify the font to be used in printing future + characters */ + +static SetFntNum(k) +int k; +{ + fontptr = hfontptr; + while ((fontptr!=NULL) && (fontptr->k!=k)) + fontptr = fontptr->next; + if (fontptr == NULL) + Fatal("font %d undefined", k); +} + + +/**********************************************************************/ +/**************************** MoveOver ******************************/ +/**********************************************************************/ + +static MoveOver(b) +int b; +{ + h += b; + if (abs(b) >= fontptr->font_space) + hh = PixRound(h, conv); + else + hh += PixRound(b, conv); +} + + +/**********************************************************************/ +/**************************** MoveDown ******************************/ +/**********************************************************************/ + +static MoveDown(a) +int a; +{ + v += a; + if (abs(a) >= 5*fontptr->font_space) + vv = PixRound(v, conv); + else + vv += PixRound(a, conv); +} + + +/**********************************************************************/ +/************************ FindPostAmblePtr **************************/ +/**********************************************************************/ + +/* this routine will move to the end of the file and find the start + of the postamble */ + +static FindPostAmblePtr (postambleptr) +long *postambleptr; +{ + int i; + + fseek (dvifp, (long) 0, 2); /* goto end of file */ + *postambleptr = ftell (dvifp) - 4; + fseek (dvifp, *postambleptr, 0); + + while (TRUE) { + fseek (dvifp, --(*postambleptr), 0); + if (((i = NoSignExtend (dvifp, 1)) != 223) && + (i != DVIFORMAT)) + Fatal ("Bad end of DVI file"); + if (i == DVIFORMAT) + break; + } + fseek (dvifp, (*postambleptr) - 4, 0); + (*postambleptr) = NoSignExtend (dvifp, 4); + fseek (dvifp, *postambleptr, 0); +} + + +/**********************************************************************/ +/************************** ReadPostAmble ***************************/ +/**********************************************************************/ + +/* this routine is used to read in the postable values. It initializes + the magnification and checks the stack height prior to starting + printing the document */ + +static ReadPostAmble() +{ + FindPostAmblePtr (&postambleptr); + if (NoSignExtend (dvifp, 1) != POST) + Fatal ("POST missing at head of postamble"); +#ifdef Debug + fprintf (stderr, "got POST command\n"); +#endif +/* lastpageptr = */ NoSignExtend (dvifp, 4); + num = NoSignExtend (dvifp, 4); + den = NoSignExtend (dvifp, 4); +#ifdef USEGLOBALMAG + mag = NoSignExtend(dvifp,4); + conv = ((float)num/(float)den) * ((float)mag/1000.0) * ((float)RESOLUTION/254000.0); +#else + mag = NoSignExtend(dvifp,4); /* get it even though it'll be ignored */ + conv = ((float)num/(float)den) * ((float)RESOLUTION/254000.0); +#endif + /* denominator/numerator here since will be dividing by the conversion + factor */ + NoSignExtend(dvifp,4); /* height-plus-depth of tallest page */ + NoSignExtend(dvifp,4); /* width of widest page */ + if (NoSignExtend (dvifp, 2) >= STACKSIZE) + Fatal ("Stack size is too small"); + NoSignExtend(dvifp, 2); /* this read the number of pages in the DVI + file */ +#ifdef Debug + fprintf (stderr, "now reading font defs"); +#endif + GetFontDef (); +} + + + +/**********************************************************************/ +/**************************** GetFontDef ****************************/ +/**********************************************************************/ +static GetFontDef() +/* to read the font definition as they are in the postamble of the DVI file. + note that the font directory is not yet loaded I order to adapt ourselves + to the existing "verser" the following font paramters are copied onto + output fontno ( 4 bytes), chksum, fontmag, fontnamelength ( 1 byte), + fontname. At the end a -1 is put onto the file */ +{ + char str[50], *calloc (); + unsigned char byte; + int i, fnamelen; + + while (((byte = NoSignExtend (dvifp, 1)) >= FNT_DEF1) && (byte <= FNT_DEF4)) + { ReadFontDef (NoSignExtend(dvifp, byte - FNT_DEF1 + 1)); + } + + if (byte != POST_POST) + Fatal ("POST_POST missing after fontdefs"); +} + + + +/**********************************************************************/ +/*************************** ReadFontDef ****************************/ +/**********************************************************************/ +static int ReadFontDef (k) + int k; +{ + int c, s, d, a, l, t, i; + char n[STRSIZE]; + struct font_entry *tfontptr; /* temporary font_entry pointer */ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + + c = NoSignExtend(dvifp,4); + s = NoSignExtend(dvifp,4); + d = NoSignExtend(dvifp,4); + a = NoSignExtend(dvifp,1); + l = NoSignExtend(dvifp,1); + GetBytes(dvifp, n, a+l); + n[a+l] = '\0'; + if ((tfontptr=(struct font_entry *)malloc(sizeof(struct font_entry))) == NULL) + Fatal("can't malloc space for font_entry"); + tfontptr->next = hfontptr; + + fontptr = hfontptr = tfontptr; + fontptr->k = k; + fontptr->c = c; + fontptr->s = s; + fontptr->d = d; + fontptr->a = a; + fontptr->l = l; + strcpy(fontptr->n, n); + fontptr->font_space = s/6; +#ifdef USEGLOBALMAG + fontptr->font_mag = (int)((ActualFactor((int)(((float)s/(float)d)*1000.0 + 0.5)) * + ActualFactor(mag) * + (float)RESOLUTION * 5.0) + 0.5); +#else + fontptr->font_mag = (int)((ActualFactor((int)(((float)s/(float)d)*1000.0 + 0.5)) * + (float)RESOLUTION * 5.0) + 0.5); +#endif + sprintf(fontptr->name, "%s%s.%dpxl", ((a==0)?FONTAREA:""), n, fontptr->font_mag); + if (fontptr != pfontptr) + { if (pfontptr != NULL) + fclose(pxlfp); +#ifdef Debug + fprintf(stderr,"Opening PXL file \"%s\"\n", fontptr->name); +#endif + if ((pxlfp=fopen(fontptr->name,"r")) == NULL) + Fatal("can't open PXL file \"%s\"", fontptr->name); + pfontptr = fontptr; + } + if ((t=NoSignExtend(pxlfp,4)) != PXLID) + Fatal("PXL ID = %d, can only process PXL ID = %d files", t, PXLID); + fseek(pxlfp, 0, 2); + fseek(pxlfp, -20, 1); + t = NoSignExtend(pxlfp,4); + if ((fontptr->c!=0) && (t!=0) && (fontptr->c!=t)) + Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d", + fontptr->name, fontptr->c, t); + fontptr->magnification = NoSignExtend(pxlfp,4); + fontptr->designsize = NoSignExtend(pxlfp,4); + fseek(pxlfp, NoSignExtend(pxlfp,4)*4, 0); + for (i=FIRSTPXLCHAR; i<=LASTPXLCHAR; i++) + { tcharptr = &(fontptr->ch[i]); + tcharptr->wp = NoSignExtend(pxlfp,2); tcharptr->hp = NoSignExtend(pxlfp,2); + tcharptr->xoffp = SignExtend(pxlfp,2); tcharptr->yoffp = SignExtend(pxlfp,2); + tcharptr->pfrp = NoSignExtend(pxlfp,4); + tcharptr->tfmw = ((float)NoSignExtend(pxlfp,4)*(float)s) / (float)(1<<20); + tcharptr->pxlw = PixRound(tcharptr->tfmw, conv); + if ((tcharptr->hp*((tcharptr->wp+15)/16)) >= BIGBGCHAR) + tcharptr->istoobig = TRUE; + if (i < FIRSTBGCHAR) + { tcharptr->bgfont = partfont; + tcharptr->bgchar = partchar+i; + } else + { tcharptr->bgfont = fullfont; + tcharptr->bgchar = i; + } + } + fullfont = (fullfont+1) % NBGFONTS; + if (fullfont == 0) { + partfont = NBGFONTS; + partchar = FIRSTBGCHAR; + } else { + partchar += FIRSTBGCHAR; + if (partchar > LASTBGCHAR) { + partfont++; + partchar = FIRSTBGCHAR; + } + } +} + + +/**********************************************************************/ +/*************************** SkipFontDef ****************************/ +/**********************************************************************/ + +/* If font definition has already been read in then use this routine to + skip over the definition bytes in the dvi format file. */ + +static int SkipFontDef (k) + int k; +{ + int a, l; + char n[STRSIZE]; + + NoSignExtend(dvifp,4); + NoSignExtend(dvifp,4); + NoSignExtend(dvifp,4); + a = NoSignExtend(dvifp,1); + l = NoSignExtend(dvifp,1); + GetBytes(dvifp, n, a+l); +} + + +/**********************************************************************/ +/***************************** AllDone ******************************/ +/**********************************************************************/ + +/* this routine is used to exit the program. It will reset the terminal + and if a log file exists then a message to that effect will be + printed as well. */ + +AllDone() +{ + char t; + + ResetTerm(); + printf("\033:0;0m"); /* BBNMOV Move Graphically */ + if (G_errenc && G_logging == 1) { + fseek(G_logfp, 0, 0); + while ((t=getc(G_logfp)) != EOF) + putchar(t); + } + if (G_logging == 1) printf("Log file created\n"); + exit(G_errenc); +} + + + +/**********************************************************************/ +/**************************** ReadInt *******************************/ +/**********************************************************************/ + +/* this routine is used to read in an integer from the stdin stream. + This routine is necessary since the terminal is running in + CBREAK mode and therefore will not do editing of the input + stream for one. */ + +ReadInt() +{ + int value = 0; + int byte; + + while ((byte = getchar()) != /* tcb.t_brkc */ 10) + { if (byte >= 48 /* "0" */ && byte <= 57 /* "9" */) + value = value * 10 + byte - 48; + if (byte == tty.sg_erase) value = value / 10; + } + return(value); +} + + +/**********************************************************************/ +/****************************** Fatal *******************************/ +/**********************************************************************/ + +/* issue a fatal error message */ + +Fatal(fmt, args) + char *fmt; /* format */ +/* char *args; /* arguments */ + + { +#ifdef Debug + fprintf(stderr,"Fatal error---The format is %s\n",fmt); fflush(stderr); +#endif + if (G_logging == 1) + { fprintf(G_logfp, "%s: FATAL--", G_progname); + _doprnt(fmt, &args, G_logfp); + fprintf(G_logfp, "\n"); + } + + printf("\033:0;0m"); /* BBNMOV Move Graphically */ + ResetTerm(); + fprintf(stderr, "\n%s: FATAL--", G_progname); + _doprnt(fmt, &args, stderr); + fprintf(stderr, "\n\n"); + fflush(stderr); + if (G_logging == 1) printf("Log file created\n"); + exit(1); +} + + +/**********************************************************************/ +/***************************** GetBytes *****************************/ +/**********************************************************************/ + + /* get n bytes from file fp */ + +GetBytes(fp, cp, n) + register FILE *fp; /* file pointer */ + register char *cp; /* character pointer */ + register int n; /* number of bytes */ + +{ + while (n--) + *cp++ = getc(fp); +} + + +/**********************************************************************/ +/*************************** GotInterrupt ***************************/ +/**********************************************************************/ + + /* don't leave terminal in a weird state */ + +void GotInterrupt(sig) + int sig; + +{ + ResetTerm(); + if (G_logging == 1) printf("Log file created\n"); + exit(G_errenc); +} + + +/**********************************************************************/ +/***************************** InitTerm *****************************/ +/**********************************************************************/ + + /* initialize terminal */ + +InitTerm() + +{ + register int i; /* loop index */ + + printf("\033:["); /* BBNPSH Push Context */ + printf("\033[?7l"); /* RM DECAWM no right margin wrap wanted. */ + printf("\033:2L"); /* BBNSFP Set Font Parameters to reset all fonts */ + printf("\033:7o"); /* BBNSTO Set Text Operation */ + + for (i=(-XDIFFMAX); i<=XDIFFMAX; i++) /* load horizontal skips */ + printf("\033P:0;%d;%c;0;0;0;0;%dL", + XDIFFORG+i, (char)('0'+NBGFONTS+(NBGFONTS+2)/3), i); /* BBNLFC Load Font Character */ + for (i=(-YDIFFMAX); i<=YDIFFMAX; i++) /* load vertical skips */ + printf("\033P:0;%d;%c;0;0;0;0;0;%dL", + YDIFFORG+i, (char)('0'+NBGFONTS+(NBGFONTS+2)/3), i); /* BBNLFC Load Font Character */ + printf("\033)%c", (char)('0'+NBGFONTS+(NBGFONTS+2)/3)); /* SCS Select G1 to be a loadable font */ +} + + +/**********************************************************************/ +/***************************** LoadRast *****************************/ +/**********************************************************************/ + + /* load raster pattern into BitGraph */ + +LoadRast(pxlfp, w, h) + FILE *pxlfp; /* PXL file pointer */ + int w; /* width of raster in pixels */ + int h; /* height of raster in pixels */ + +{ + register int ew; /* extra word at end of row? */ + register int t; /* temporary */ + register int ww; /* width of raster in words */ + + ww = (w+15) / 16; + ew = ww & 1; + while (h--) { + t = ww; + while (t--) + PutOut(NoSignExtend(pxlfp,2)); + if (ew) + NoSignExtend(pxlfp,2); + } +} + + +/**********************************************************************/ +/*************************** NoSignExtend ***************************/ +/**********************************************************************/ + + /* return n byte quantity from file fd */ + +NoSignExtend(fp, n) + register FILE *fp; /* file pointer */ + register int n; /* number of bytes */ + +{ + register int x; /* number being constructed */ + + x = 0; + while (n--) { + x <<= 8; + x |= getc(fp); + } + return(x); +} + + +/**********************************************************************/ +/***************************** PixRound *****************************/ +/**********************************************************************/ + + /* return rounded number of pixels */ + +PixRound(x, conv) + register int x; /* in DVI units */ + register float conv; /* conversion factor */ + +{ + return((int)((float)x*conv+0.5)); +} + + +/**********************************************************************/ +/****************************** PutOut ******************************/ +/**********************************************************************/ + + /* put a 16-bit raster pattern to the BitGraph */ + +PutOut(x) + register int x; /* number to put out */ + +{ + int negative; /* was x negative? */ + register int part1, part2, part3; /* parts of number */ + + negative = FALSE; + if (x < 0) { + negative = TRUE; + x = -x; + } + part1 = (x & 0xfc00) >> 10; + part2 = (x & 0x03f0) >> 4; + part3 = (x & 0x000f); + if (part1) { + putchar(0100+part1); + putchar(0100+part2); + } else + if (part2) + putchar(0100+part2); + if (negative) + putchar(040+part3); + else + putchar(060 + part3); +} + + +/**********************************************************************/ +/**************************** ResetTerm *****************************/ +/**********************************************************************/ + + /* Reset Terminal */ + +ResetTerm() + +{ + printf("\033:2L"); /* BBNSFP Set Font Parameters to reset all fonts */ + printf("\033:]"); /* Pop Context (BBNPOP) */ + fflush(stdout); + if (G_interactive) + ioctl(0, TIOCSETP, &G_intty); /* restore modes */ +} + + +/**********************************************************************/ +/**************************** RulePixels ****************************/ +/**********************************************************************/ + + /* return number of pixels in a rule */ + +RulePixels(x, conv) + register int x; /* in DVI units */ + register float conv; /* conversion factor */ + +{ + register int n; + + n = x*conv; + if (n < x*conv) + return(n+1); + else + return(n); +} + + +/**********************************************************************/ +/**************************** SignExtend ****************************/ +/**********************************************************************/ + + /* return n byte quantity from file fd */ + +SignExtend(fp, n) + register FILE *fp; /* file pointer */ + register int n; /* number of bytes */ + +{ + int n1; /* number of bytes */ + register int x; /* number being constructed */ + + x = 0; + n1 = n; + while (n--) { + x <<= 8; + x |= getc(fp); + } + x<<=32-8*n1; x>>=32-8*n1; /* sign extend */ + return(x); +} + + +/**********************************************************************/ +/***************************** Warning ******************************/ +/**********************************************************************/ + + /* issue a warning */ + +Warning(fmt, args) + char *fmt; /* format */ + char *args; /* arguments */ +{ + if (G_logging = 0) + {G_logfp=fopen(G_Logname,"w+"); + G_logging = 1; + if (G_logfp == NULL) G_logging = -1; + } + + G_errenc = TRUE; + if (G_logging == 1) + { _doprnt(fmt, &args, G_logfp); + fprintf(G_logfp, "\n"); + } +} + +/**********************************************************************/ +/************************** ActualFactor ****************************/ +/**********************************************************************/ + + /* compute the actual size factor given the approximation */ + +float ActualFactor(unmodsize) + int unmodsize; /* actually factor * 1000 */ +{ + float realsize; /* the actual magnification factor */ + + realsize = (float)unmodsize / 1000.0; + /* a real hack to correct for rounding in some cases--rkf */ + if(unmodsize==1095) realsize = 1.095445; /*stephalf*/ + else if(unmodsize==1315) realsize=1.314534; /*stepihalf*/ + else if(unmodsize==2074) realsize=2.0736; /*stepiv*/ + else if(unmodsize==2488) realsize=2.48832; /*stepv*/ + else if(unmodsize==2986) realsize=2.985984; /*stepiv*/ + /* the remaining magnification steps are represented with sufficient + accuracy already */ + return(realsize); +} |