home *** CD-ROM | disk | FTP | other *** search
-
- #include "dvi2tty.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #if defined(VMS)
- #include types.h
- #include stat
- #endif
- #if defined(MSDOS)
- #include <math.h>
- #endif
- #include "commands.h"
-
- #if defined(VMS)
- #define mseek vmsseek
- #define ROUND(a) (a>=0.0 ? (int) (a + 0.5) : (int) (a - 0.5) )
- #else
- #define mseek fseek
- #endif
-
- #define VERSIONID 2 /* dvi version number that pgm handles */
- #define VERTICALEPSILON 450000L /* crlf when increasing v more than this */
-
- #define rightmargin 152 /* nr of columns allowed to the right of h=0*/
- #define leftmargin -50 /* give some room for negative h-coordinate */
- #define LINELEN 203 /* rightmargin - leftmargin + 1 */
-
- #define MOVE TRUE /* if advancing h when outputing a rule */
- #define STAY FALSE /* if not advancing h when outputing a rule */
-
- #define absolute 0 /* for seeking in files */
- #define relative 1
-
- #define FORM 12 /* formfeed */
- #define SPACE 32 /* space */
- #define DEL 127 /* delete */
-
- #define LASTCHAR 127 /* max dvi character, above are commands */
-
- #define IMIN(a, b) (a<b ? a : b)
- #define IMAX(a, b) (a>b ? a : b)
-
- #define get1() num(1)
- #define get2() num(2)
- #define get3() num(3)
- #define get4() num(4)
- #define sget1() snum(1)
- #define sget2() snum(2)
- #define sget3() snum(3)
- #define sget4() snum(4)
-
- char *dvistuff = "@(#) dvistuff.c 4.0 04/02/90 M.J.E. Mol (c) 1989, 1990";
-
- /*---------------------------------------------------------------------------*/
-
- typedef struct {
- long hh;
- long vv;
- long ww;
- long xx;
- long yy;
- long zz;
- } stackitem;
-
- typedef struct lineptr { /* the lines of text to be output to outfile */
- long vv; /* vertical position of the line */
- int charactercount; /* pos of last char on line */
- struct lineptr *prev; /* preceding line */
- struct lineptr *next; /* succeeding line */
- char text[LINELEN+1]; /* leftmargin...rightmargin */
- } linetype;
-
- typedef struct _font {
- long num;
- struct _font * next;
- char * name;
- } font;
-
-
- /*---------------------------------------------------------------------------*/
-
- bool pageswitchon; /* true if user-set pages to print */
- bool sequenceon; /* false if pagesw-nrs refers to TeX-nrs */
- bool scascii; /* if true make Scand. nat. chars right */
- bool noffd; /* if true output ^L instead of formfeed */
-
- int opcode; /* dvi-opcodes */
-
- long h, v; /* coordinates, horizontal and vertical */
- long w, x, y, z; /* horizontal and vertical amounts */
-
- long pagecounter; /* sequence page number counter */
- long backpointer; /* pointer for offset to previous page */
- long pagenr; /* TeX page number */
- int stackmax; /* stacksize required */
-
- long maxpagewidth; /* width of widest page in file */
- long charwidth; /* aprox width of character */
-
- linetype * currentline; /* pointer to current line on current page */
- linetype * firstline; /* pointer to first line on current page */
- linetype * lastline; /* pointer to last line on current page */
- int firstcolumn; /* 1st column with something to print */
-
- stackitem * stack; /* stack for dvi-pushes */
- int sptr; /* stack pointer */
-
- font * fonts = NULL; /* List of fontnames defined */
- int symbolfont = FALSE; /* true if font is a symbol font */
-
- /*---------------------------------------------------------------------------*/
-
- #if defined(MSDOS)
- void postamble (void);
- void preamble (void);
- void walkpages (void);
- void initpage (void);
- void dopage (void);
- void skippage (void);
- void printpage (void);
- bool inlist (long);
- void rule (bool, long, long);
- void ruleaux (long, long, char);
- long horizontalmove (long);
- int skipnops (void);
- linetype * getline (void);
- linetype * findline (void);
- unsigned long num (int);
- long snum (int);
- void dochar (char);
- void symchar (char);
- void normchar (char);
- void outchar (char);
- void putcharacter (long);
- void setchar (long);
- void fontdef (int);
- void setfont (long);
- #else
- void postamble ();
- void preamble ();
- void walkpages ();
- void initpage ();
- void dopage ();
- void skippage ();
- void printpage ();
- bool inlist ();
- void rule ();
- void ruleaux ();
- long horizontalmove ();
- int skipnops ();
- linetype * getline ();
- linetype * findline ();
- unsigned long num ();
- long snum ();
- void dochar ();
- void symchar ();
- void normchar ();
- void outchar ();
- void putcharacter ();
- void setchar ();
- void fontdef ();
- void setfont ();
- #if defined(VMS)
- long vmsseek ();
- long vms_ftell ();
- long vms_ungetc ();
- #endif
- #endif
-
-
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
-
- /*
- * The main function for processing the dvi file.
- * Here we assume there are to file pointers: DVIfile and output.
- * Also we have a list of pages pointed to by 'currentpage',
- * which is only used (in 'inlist()') when a page list is given.
- */
-
- void dvimain()
- {
-
- postamble(); /* seek and process the postamble */
- /* note that walkpages *must* immediately follow preamble */
- preamble(); /* process preamble */
- walkpages(); /* time to do the actual work! */
-
- } /* dvimain */
-
- /*---------------------------------------------------------------------------*/
-
- void postamble() /* find and process postamble, use random access */
- {
- register long size;
- register int count;
- struct stat st;
-
- fstat (fileno(DVIfile), &st);
- size = (long) st.st_size; /* get size of file */
- count = -1;
- do { /* back file up past signature bytes (223), to id-byte */
- if (size == 0)
- errorexit(nopst);
- size--;
- mseek(DVIfile, size, absolute);
- opcode = (int) get1();
- count++;
- } while (opcode == TRAILER);
- if (count < 4) { /* must have 4 trailer bytes */
- foo = count;
- errorexit(fwsgn);
- }
- if (opcode != VERSIONID)
- errorexit(badid);
- mseek(DVIfile, size-4, absolute); /* back up to back-pointer */
- mseek(DVIfile, sget4(), absolute); /* and to start of postamble */
- if (get1() != POST)
- errorexit(nopst);
- mseek(DVIfile, 20L, relative); /* lastpageoffset, numerator, denominator */
- /* magnification, maxpageheight */
- maxpagewidth = sget4();
- charwidth = maxpagewidth / (ttywidth + espace);
- stackmax = (int) get2();
- if ((stack = (stackitem *) malloc(stackmax * sizeof(stackitem))) == NULL)
- errorexit(stkrq);
-
- /* get2() -- totalpages */
- /* fontdefs do fontdefs in flight ... */
-
- } /* postamble */
-
- /*---------------------------------------------------------------------------*/
-
- void preamble() /* process preamble, use random access */
- {
-
- mseek(DVIfile, 0L, absolute); /* read the dvifile from the start */
- if ((opcode = skipnops()) != PRE)
- errorexit(nopre);
- opcode = (int) get1(); /* check id in preamble, ignore rest of it */
- if (opcode != VERSIONID)
- errorexit(badid);
- mseek(DVIfile, 12L, relative); /* numerator, denominator, magnification */
- mseek(DVIfile, get1(), relative); /* skip job identification */
-
- } /* preamble */
-
- /*----------------------------------------------------------------------------*/
-
- void walkpages() /* process the pages in the DVI-file */
- {
- register bool wantpage;
-
- pagecounter = 0L;
- while ((opcode = skipnops()) != POST) {
- if (opcode != BOP) /* should be at start of page now */
- errorexit(nobop);
- else {
- pagecounter++;
- pagenr = sget4(); /* get TeX page number */
- mseek(DVIfile, 36L, relative); /* skip page header */
- backpointer = sget4(); /* get previous page offset */
- if (pageswitchon)
- if (sequenceon)
- wantpage = inlist(pagecounter);
- else
- wantpage = inlist(pagenr);
- else
- wantpage = TRUE;
-
- if (wantpage) {
- initpage();
- dopage();
- printpage();
- }
- else {
- skippage();
- }
- }
- }
-
- } /* walkpages */
-
- /*---------------------------------------------------------------------------*/
-
- void initpage()
- {
-
- h = 0L; v = 0L; /* initialize coordinates */
- x = 0L; w = 0L; y = 0L; z = 0L; /* initialize amounts */
- sptr = 0; /* initialize stack */
- currentline = getline(); /* initialize list of lines */
- currentline->vv = 0L;
- firstline = currentline;
- lastline = currentline;
- firstcolumn = rightmargin;
- if (pageswitchon) {
- if ((sequenceon && (pagecounter != firstpage->pag)) ||
- (!sequenceon && (pagenr != firstpage->pag)))
- if (noffd)
- fprintf(output, "^L\n");
- else
- putc(FORM, output);
- }
- else
- if (backpointer != -1) /* not FORM at first page */
- if (noffd)
- fprintf(output, "^L\n");
- else
- putc(FORM, output);
-
- } /* initpage */
-
- /*----------------------------------------------------------------------------*/
-
- void dopage()
- {
-
- while ((opcode = (int) get1()) != EOP) { /* process page until eop */
- if (opcode <= LASTCHAR)
- dochar((char) opcode);
- else if ((opcode >= FONT_00) && (opcode <= FONT_63))
- setfont(opcode - FONT_00);
- else if (opcode > POST_POST)
- errorexit(illop);
- else
- switch (opcode) {
- case SET1 : setchar(get1()); break;
- case SET2 : setchar(get2()); break;
- case SET3 : setchar(get3()); break;
- case SET4 : setchar(get4()); break;
- case SET_RULE : { long height = sget4();
- rule(MOVE, sget4(), height); break;
- }
- case PUT1 : putcharacter(get1()); break;
- case PUT2 : putcharacter(get2()); break;
- case PUT3 : putcharacter(get3()); break;
- case PUT4 : putcharacter(get4()); break;
- case PUT_RULE : { long height = sget4();
- rule(STAY, sget4(), height); break;
- }
- case NOP : break; /* no-op */
- case BOP : errorexit(bdbop); break;
- /* case EOP : break; strange place to have EOP */
- case PUSH : if (sptr >= stackmax) /* push */
- errorexit(stkof);
- stack[sptr].hh = h;
- stack[sptr].vv = v;
- stack[sptr].ww = w;
- stack[sptr].xx = x;
- stack[sptr].yy = y;
- stack[sptr].zz = z;
- sptr++;
- break;
- case POP : if (sptr == 0) /* pop */
- errorexit(stkuf);
- sptr--;
- h = stack[sptr].hh;
- v = stack[sptr].vv;
- w = stack[sptr].ww;
- x = stack[sptr].xx;
- y = stack[sptr].yy;
- z = stack[sptr].zz;
- break;
- case RIGHT1 : (void) horizontalmove(sget1()); break;
- case RIGHT2 : (void) horizontalmove(sget2()); break;
- case RIGHT3 : (void) horizontalmove(sget3()); break;
- case RIGHT4 : (void) horizontalmove(sget4()); break;
- case W0 : h += w; break;
- case W1 : w = horizontalmove(sget1()); break;
- case W2 : w = horizontalmove(sget2()); break;
- case W3 : w = horizontalmove(sget3()); break;
- case W4 : w = horizontalmove(sget4()); break;
- case X0 : h += x; break;
- case X1 : x = horizontalmove(sget1()); break;
- case X2 : x = horizontalmove(sget2()); break;
- case X3 : x = horizontalmove(sget3()); break;
- case X4 : x = horizontalmove(sget4()); break;
- case DOWN1 : v += sget1(); break;
- case DOWN2 : v += sget2(); break;
- case DOWN3 : v += sget3(); break;
- case DOWN4 : v += sget4(); break;
- case Y0 : v += y; break;
- case Y1 : y = sget1(); v += y; break;
- case Y2 : y = sget2(); v += y; break;
- case Y3 : y = sget3(); v += y; break;
- case Y4 : y = sget4(); v += y; break;
- case Z0 : v += z; break;
- case Z1 : z = sget1(); v += z; break;
- case Z2 : z = sget2(); v += z; break;
- case Z3 : z = sget3(); v += z; break;
- case Z4 : z = sget4(); v += z; break;
- case FNT1 :
- case FNT2 :
- case FNT3 :
- case FNT4 : setfont(num(opcode - FNT1 + 1));
- break;
- case XXX1 : mseek(DVIfile, get1(), relative); break;
- case XXX2 : mseek(DVIfile, get2(), relative); break;
- case XXX3 : mseek(DVIfile, get3(), relative); break;
- case XXX4 : mseek(DVIfile, get4(), relative); break;
- case FNT_DEF1 :
- case FNT_DEF2 :
- case FNT_DEF3 :
- case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1);
- break;
- case PRE : errorexit(bdpre); break;
- case POST : errorexit(bdpst); break;
- case POST_POST: errorexit(bdpp); break;
- }
- }
-
- } /* dopage */
-
- /*----------------------------------------------------------------------------*/
-
- void skippage() /* skip past one page */
- {
- register int opcode;
-
- while ((opcode = (int) get1()) != EOP) {
- if (opcode > POST_POST)
- errorexit(illop);
- else
- switch (opcode) {
- case SET1 :
- case PUT1 :
- case RIGHT1 :
- case W1 :
- case X1 :
- case DOWN1 :
- case Y1 :
- case Z1 : /* assume FNT change can also be skipped */
- case FNT1 : mseek(DVIfile, 1L, relative); break;
- case SET2 :
- case PUT2 :
- case RIGHT2 :
- case W2 :
- case X2 :
- case DOWN2 :
- case Y2 :
- case Z2 :
- case FNT2 : mseek(DVIfile, 2L, relative); break;
- case SET3 :
- case PUT3 :
- case RIGHT3 :
- case W3 :
- case X3 :
- case DOWN3 :
- case Y3 :
- case Z3 :
- case FNT3 : mseek(DVIfile, 3L, relative); break;
- case SET4 :
- case PUT4 :
- case RIGHT4 :
- case W4 :
- case X4 :
- case DOWN4 :
- case Y4 :
- case Z4 :
- case FNT4 : mseek(DVIfile, 4L, relative); break;
- case SET_RULE :
- case PUT_RULE : mseek(DVIfile, 8L, relative); break;
- case BOP : errorexit(bdbop); break;
- case XXX1 : mseek(DVIfile, get1(), relative); break;
- case XXX2 : mseek(DVIfile, get2(), relative); break;
- case XXX3 : mseek(DVIfile, get3(), relative); break;
- case XXX4 : mseek(DVIfile, get4(), relative); break;
- case FNT_DEF1 :
- case FNT_DEF2 :
- case FNT_DEF3 :
- case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1); break;
- case PRE : errorexit(bdpre); break;
- case POST : errorexit(bdpst); break;
- case POST_POST: errorexit(bdpp); break;
- }
- }
-
- } /* skippage */
-
- /*---------------------------------------------------------------------------*/
-
- void printpage() /* 'end of page', writes lines of page to output file */
- {
- register int i, j;
- register char ch;
-
- if (sptr != 0)
- fprintf(stderr, "dvi2tty: warning - stack not empty at eop.\n");
- for (currentline = firstline; currentline != nil;
- currentline = currentline->next) {
- if (currentline != firstline) {
- foo = ((currentline->vv - currentline->prev->vv)/VERTICALEPSILON)-1;
- if (foo > 3)
- foo = 3; /* linespacings not too large */
- for (i = 1; i <= (int) foo; i++)
- putc('\n', output);
- }
- if (currentline->charactercount >= leftmargin) {
- foo = ttywidth - 2;
- for (i = firstcolumn, j = 1; i <= currentline->charactercount;
- i++, j++) {
- ch = currentline->text[i - leftmargin];
- if (ch >= SPACE)
- putc(ch, output);
- if ((j > (int) foo) && (currentline->charactercount > i+1)) {
- fprintf(output, "*\n"); /* if line to large */
- fprintf(output, " *"); /* mark output */
- j = 2;
- }
- }
- }
- putc('\n', output);
- }
-
- currentline = firstline;
- while (currentline->next != nil) {
- currentline = currentline->next;
- free(currentline->prev);
- }
- free(currentline); /* free last line */
- currentline = nil;
-
- } /* printpage */
-
- /*----------------------------------------------------------------------------*/
-
- bool inlist(pagenr) /* ret true if in list of pages */
- register long pagenr;
- {
-
- while ((currentpage->pag < 0) && (currentpage->pag != pagenr) &&
- !currentpage->all && (currentpage->nxt != nil))
- currentpage = currentpage->nxt;
- if ((currentpage->all && (pagenr < currentpage->pag)) ||
- (currentpage->pag == pagenr))
- return TRUE;
- else if (pagenr > 0) {
- while ((currentpage->pag < pagenr) && (currentpage->nxt != nil))
- currentpage = currentpage->nxt;
- if (currentpage->pag == pagenr)
- return TRUE;
- }
- return FALSE;
-
- } /* inlist */
-
- /*----------------------------------------------------------------------------*/
-
- void rule(moving, rulewt, ruleht)
- register bool moving;
- register long rulewt, ruleht;
- { /* output a rule (vertical or horizontal), increment h if moving is true */
-
- register char ch; /* character to set rule with */
- register long saveh, savev;
- /* rule -- starts up the recursive routine */
- if (!moving)
- saveh = h;
- if ((ruleht <= 0) || (rulewt <= 0))
- h += rulewt;
- else {
- savev = v;
- if ((ruleht / rulewt) > 0) /* value < 1 truncates to 0 */
- ch = '|';
- else if (ruleht > (VERTICALEPSILON / 2))
- ch = '=';
- else
- ch = '_';
- ruleaux(rulewt, ruleht, ch);
- v = savev;
- }
- if (!moving)
- h = saveh;
-
- } /* rule */
-
-
-
- void ruleaux(rulewt, ruleht, ch) /* recursive that does the job */
- register long rulewt, ruleht;
- register char ch;
- {
- register long wt, lmh, rmh;
-
- wt = rulewt;
- lmh = h; /* save left margin */
- if (h < 0) { /* let rules that start at negative h */
- wt -= h; /* start at coordinate 0, but let it */
- h = 0; /* have the right length */
- }
- while (wt > 0) { /* output the part of the rule that */
- rmh = h; /* goes on this line */
- outchar(ch);
- wt -= (h-rmh); /* decrease the width left on line */
- }
- ruleht -= VERTICALEPSILON; /* decrease the height */
- if (ruleht > VERTICALEPSILON) { /* still more vertical? */
- rmh = h; /* save current h (right margin) */
- h = lmh; /* restore left margin */
- v -= (VERTICALEPSILON + VERTICALEPSILON / 10);
- ruleaux(rulewt, ruleht, ch);
- h = rmh; /* restore right margin */
- }
-
- } /* ruleaux */
-
- /*----------------------------------------------------------------------------*/
-
- long horizontalmove(amount)
- register long amount;
- {
-
- #if defined(MSDOS)
- if (labs(amount) > charwidth / 4L) {
- #else
- if (abs(amount) > charwidth / 4L) {
- #endif
- foo = 3*charwidth / 4;
- if (amount > 0)
- amount = ((amount+foo) / charwidth) * charwidth;
- else
- #if defined(VMS)
- amount = (ROUND( (float) (amount-foo) / charwidth) + 1)* charwidth;
- #else
- amount = ((amount-foo) / charwidth) * charwidth;
- #endif
- h += amount;
- return amount;
- }
- else
- return 0;
-
- } /* horizontalmove */
-
- /*----------------------------------------------------------------------------*/
-
- int skipnops() /* skips by no-op commands */
- {
- register int opcode;
-
- while ((opcode = (int) num(1)) == NOP);
- return opcode;
-
- } /* skipnops */
-
- /*----------------------------------------------------------------------------*/
-
- linetype *getline() /* returns an initialized line-object */
- {
- register int i;
- register linetype *temp;
-
- if ((temp = (linetype *) malloc(sizeof(linetype))) == NULL)
- errorexit(lnerq);
- temp->charactercount = leftmargin - 1;
- temp->prev = nil;
- temp->next = nil;
- for (i = 0; i < LINELEN; i++)
- temp->text[i] = ' ';
- temp->text[i] = '\0';
- return temp;
-
- } /* getline */
-
- /*----------------------------------------------------------------------------*/
-
- linetype *findline() /* find best fit line were text should go */
- { /* and generate new line if needed */
- register linetype *temp;
- register long topd, botd;
-
- if (v <= firstline->vv) { /* above first line */
- if (firstline->vv - v > VERTICALEPSILON) {
- temp = getline();
- temp->next = firstline;
- firstline->prev = temp;
- temp->vv = v;
- firstline = temp;
- }
- return firstline;
- }
-
- if (v >= lastline->vv) { /* below last line */
- if (v - lastline->vv > VERTICALEPSILON) {
- temp = getline();
- temp->prev = lastline;
- lastline->next = temp;
- temp->vv = v;
- lastline = temp;
- }
- return lastline;
- }
-
- temp = lastline; /* in between two lines */
- while ((temp->vv > v) && (temp != firstline))
- temp = temp->prev;
-
- /* temp->vv < v < temp->next->vv --- temp is above, temp->next is below */
- topd = v - temp->vv;
- botd = temp->next->vv - v;
- if ((topd < VERTICALEPSILON) || (botd < VERTICALEPSILON))
- if (topd < botd) /* take best fit */
- return temp;
- else
- return temp->next;
-
- /* no line fits suitable, generate a new one */
- currentline = getline();
- currentline->next = temp->next;
- currentline->prev = temp;
- temp->next->prev = currentline;
- temp->next = currentline;
- currentline->vv = v;
- return currentline;
-
- } /* findline */
-
- /*----------------------------------------------------------------------------*/
-
- unsigned long num(size)
- register int size;
- {
- register int i;
- register long x = 0;
-
- for (i = 0; i < size; i++)
- x = (x << 8) + (unsigned) getc(DVIfile);
- return x;
-
- } /* num */
-
-
- long snum(size)
- register int size;
- {
- register int i;
- register long x = 0;
-
- x = getc(DVIfile);
- if (x & 0x80)
- x -= 0x100;
- for (i = 1; i < size; i++)
- x = (x << 8) + (unsigned) getc(DVIfile);
- return x;
-
- } /* snum */
-
- /*----------------------------------------------------------------------------*/
-
- void dochar(ch)
- register char ch;
- {
-
- if (symbolfont == TRUE)
- symchar(ch);
- else
- normchar(ch);
-
- return;
-
- } /* dochar */
-
-
-
- void symchar(ch) /* output ch to appropriate line */
- register char ch;
- {
-
- switch (ch) { /* can do a lot more on MSDOS machines ... */
- case 0: ch = '-'; break;
- case 1: ch = '.'; break;
- case 2: ch = 'x'; break;
- case 3: ch = '*'; break;
- case 13: ch = 'O'; break;
- case 14: ch = 'O'; break;
- case 15: ch = 'o'; break;
- case 24: ch = '~'; break;
- case 102: ch = '{'; break;
- case 103: ch = '}'; break;
- case 104: ch = '<'; break;
- case 105: ch = '>'; break;
- case 106: ch = '|'; break;
- case 110: ch = '\\'; break;
- }
- outchar(ch);
-
- return;
-
- } /* symchar */
-
-
-
- void normchar(ch)
- register char ch;
- {
-
- switch (ch) {
- case 11 : outchar('f'); ch = 'f'; break; /* ligature */
- case 12 : outchar('f'); ch = 'i'; break; /* ligature */
- case 13 : outchar('f'); ch = 'l'; break; /* ligature */
- case 14 : outchar('f'); outchar('f');
- ch = 'i'; break; /* ligature */
- case 15 : outchar('f'); outchar('f');
- ch = 'l'; break; /* ligature */
- case 16 : ch = 'i'; break;
- case 17 : ch = 'j'; break;
- case 25 : outchar('s'); ch = 's'; break; /* German double s */
- case 26 : outchar('a'); ch = 'e'; break; /* Dane/Norw ae */
- case 27 : outchar('o'); ch = 'e'; break; /* Dane/Norw oe */
- case 28 : if (scascii)
- ch = '|'; /* Dane/Norw /o */
- else
- ch = 'o';
- break;
- case 29 : outchar('A'); ch = 'E'; break; /* Dane/Norw AE */
- case 30 : outchar('O'); ch = 'E'; break; /* Dane/Norw OE */
- case 31 : if (scascii)
- ch = '\\'; /* Dane/Norw /O */
- else
- ch = 'O';
- break;
- case 92 : ch = '"'; break; /* \ from `` */
- case 123 : ch = '-'; break; /* { from -- */
- case 124 : ch = '_'; break; /* | from --- */
- case 125 : ch = '"'; break; /* } from \H */
- case 126 : ch = '"'; break; /* ~ from \~ */
- case 127 : ch = '"'; break; /* DEL from \" */
- #if 0
- case 18 : ch = '`'; break /* from \` */
- case 19 : ch = ''''; break /* from \' */
- case 20 : ch = '~'; break /* from \v */
- case 21 : ch = '~'; break /* from \u */
- case 22 : ch = '~'; break /* from \= */
- case 24 : ch = ','; break /* from \c */
- case 94 : ch = '^'; break /* ^ from \^ */
- case 95 : ch = '`'; break /* _ from \. */
- #endif
- }
- outchar(ch);
-
- return;
-
- } /*normchar */
-
-
-
- void outchar(ch) /* output ch to appropriate line */
- register char ch;
- {
- register int i, j;
-
- /* fprintf(stderr, "hor: %ld, ver: %ld\n", h, v); */
- #if defined(MSDOS)
- if (labs(v - currentline->vv) > VERTICALEPSILON / 2L)
- #else
- if (abs(v - currentline->vv) > VERTICALEPSILON / 2L)
- #endif
- currentline = findline();
-
- #if 0
- j = (int) (((double) h / (double) maxpagewidth) * (ttywidth-1)) + 1;
- #else
- j = (int) (h / charwidth);
- #endif
- if (j > rightmargin) /* leftmargin <= j <= rightmargin */
- j = rightmargin;
- else if (j < leftmargin)
- j = leftmargin;
- foo = leftmargin - 1;
- /*
- /* This code does not really belong here ...
- /*
- /*-------------------------------------------------------------*/
- /* The following is very specialized code, it handles national */
- /* Swe/Fin characters. They are respectively: a and o with two */
- /* dots ("a & "o) and a with a circle (Oa). In Swe/Fin "ASCII" */
- /* these characters replace }{|][ and \. TeX outputs these by */
- /* first issuing the dots or circle and then backspace and set */
- /* the a or o. When dvitty finds an a or o it searches in the */
- /* near vicinity for the character codes that represent circle */
- /* or dots and if one is found the corresponding national char */
- /* replaces the special character codes. */
- /*-------------------------------------------------------------*/
- if (scascii) {
- if ((ch == 'a') || (ch == 'A') || (ch == 'o') || (ch == 'O')) {
- for (i = IMAX(leftmargin, j-2);
- i <= IMIN(rightmargin, j+2);
- i++)
- if ((currentline->text[i - leftmargin] == 127) ||
- (currentline->text[i - leftmargin] == 34) ||
- (currentline->text[i - leftmargin] == 23))
- foo = i;
- if (foo >= leftmargin) {
- j = (int) foo;
- switch (currentline->text[j - leftmargin]) {
- case 127 : case 34:
- if (ch == 'a')
- ch = '{';
- else if (ch == 'A') /* dots ... */
- ch = '[';
- else if (ch == 'o')
- ch = '|';
- else if (ch == 'O')
- ch = '\\';
- break;
- case 23 : if (ch == 'a')
- ch = '}';
- else if (ch == 'A') /* circle */
- ch = ']';
- break;
- }
- }
- }
- }
- /*----------------- end of 'Scandinavian code' ----------------*/
- if (foo == leftmargin-1)
- while ((currentline->text[j - leftmargin] != SPACE)
- && (j < rightmargin)) {
- j++;
- h += charwidth;
- }
- if ( ((ch >= SPACE) && (ch != DEL)) ||
- (scascii && (ch == 23)) ) {
- /* (scascii && (ch == DEL)) ) { if VMS ??? */
- if (j < rightmargin)
- currentline->text[j - leftmargin] = ch;
- else
- currentline->text[rightmargin - leftmargin] = '@';
- if (j > currentline->charactercount)
- currentline->charactercount = j;
- if (j < firstcolumn)
- firstcolumn = j;
- h += charwidth;
- }
-
- } /* outchar */
-
- /*----------------------------------------------------------------------------*/
-
- void putcharacter(charnr) /* output character, don't change h */
- register long charnr;
- {
- register long saveh;
-
- saveh = h;
- if ((charnr >= 0) && (charnr <= LASTCHAR))
- outchar((char) charnr);
- else
- setchar(charnr);
- h = saveh;
-
- } /* putcharacter */
-
- /*----------------------------------------------------------------------------*/
-
- void setchar(charnr)
- long charnr;
- { /* should print characters with character code>127 from current font */
- /* note that the parameter is a dummy, since ascii-chars are<=127 */
-
- outchar('#');
-
- } /* setchar */
-
-
- /*----------------------------------------------------------------------------*/
-
-
- void fontdef(x)
- register int x;
- {
- register int i;
- char * name;
- font * fnt;
- int namelen;
- long fntnum;
- int new = 0;
-
- fntnum = num(x);
- (void) get4(); /* checksum */
- (void) get4(); /* scale */
- (void) get4(); /* design */
- namelen = (int) get1() + (int) get1();
- fnt = fonts;
- while (fnt != NULL && fnt->num != fntnum) /* does fontnum exist */
- fnt = fnt->next;
- if (fnt == NULL) {
- if ((fnt = (font *) malloc(sizeof(font))) == NULL) {
- perror("fontdef");
- exit(1);
- }
- fnt->num = fntnum;
- new = 1;
- }
- else
- free(fnt->name); /* free old name */
- if ((name = (char *) malloc(namelen * sizeof(char))) == NULL) {
- perror("fontdef");
- exit(1);
- }
-
- for (i = 0; i < namelen; i++)
- name[i] = get1();
- fnt->name = name;
- if (new) {
- fnt->next = fonts;
- fonts = fnt;
- }
-
- return;
-
- } /* fontdef */
-
-
-
- void setfont(fntnum)
- long fntnum;
- {
- font * fnt;
- char * s;
-
- fnt = fonts;
- while (fnt != NULL && fnt->num != fntnum)
- fnt = fnt->next;
- if (fnt == NULL) {
- /* error : font not found */
- symbolfont = FALSE;
- return;
- }
-
- s = fnt->name;
- while ((s = strchr(s, 's')) != NULL) {
- if (strncmp("sy", s, 2) == 0) {
- symbolfont = TRUE;
- return;
- }
- }
-
- symbolfont = FALSE;
- return;
-
- } /* setfont */
-
-
- /*----------------------------------------------------------------------------*/
-
-
- #if defined(VMS)
- long vmsseek(fp,n,dir)
- FILE *fp;
- long n;
- long dir;
- {
- long k,m,pos,val,oldpos;
- struct stat buffer;
-
- for (;;) { /*loops only once or twice*/
- switch (dir) {
- case 0: /*from BOF*/
- oldpos = vms_ftell(fp);
- k = n & 511;
- m = n >> 9;
- if (((*fp)->_cnt) && ((oldpos >> 9) == m)) {
- val = 0; /* still in */
- (*fp)->_ptr = ((*fp)->_base) + k;
- (*fp)->_cnt = 512 - k;
- }
- else {
- val = fseek(fp, m << 9, 0);
- if (val == 0) {
- (*fp)->_cnt = 0;
- (void) fgetc(fp);
- (*fp)->_ptr = ((*fp)->_base) + k;
- (*fp)->_cnt = 512 - k;
- }
- }
- return(val);
-
- case 1: pos = vms_ftell(fp);
- if (pos == EOF)
- return (EOF);
- n += pos;
- dir = 0;
- break;
-
- case 2: val = fstat(fileno(fp), &buffer);
- if (val == EOF)
- return (EOF);
- n += buffer.st_size - 1;
-
- dir = 0;
- break;
-
- default : return (EOF);
- }
- }
-
- } /* vmsseek */
-
-
-
- long vms_ftell(fp)
- FILE *fp;
- {
- char c;
- long pos;
- long val;
- if ((*fp)->_cnt == 0) {
- c = fgetc(fp);
- val = vms_ungetc(c, fp);
- if (val != c)
- return (EOF);
- }
- pos = ftell(fp);
- if (pos >= 0)
- pos += ((*fp)->_ptr) - ((*fp)->_base);
- return (pos);
-
- } /* vms_ftell */
-
-
-
- long vms_ungetc(c,fp)
- char c;
- FILE *fp;
- {
- if ((c == EOF) && feof(fp))
- return (EOF);
- else if ((*fp)->_cnt >= 512)
- return (EOF);
- else {
- (*fp)->_cnt++;
- (*fp)->_ptr--;
- *((*fp)->_ptr) = c;
- return (c);
- }
-
- } /*vms_ungetc */
- #endif
-