📄 dvistuff.c
字号:
/* * Include files */#include "dvi2tty.h"#if defined(VMS)# include types.h# include stat#else# if defined(THINK_C)# include <unix.h># else# include <sys/types.h># include <sys/stat.h># endif#endif#if defined(MSDOS) || defined(THINK_C)# include <math.h>#endif#include "commands.h"/* * Constant definitions */#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 MAXTERMWIDTH+20 /* nr of columns allowed to the right of h=0*/#define leftmargin -50 /* give some room for negative h-coordinate */#define LINELEN 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)/* * Structure and variable definitions */char *dvistuff = "@(#) dvistuff.c 5.12 27may1996 M.J.E. Mol (c) 1989-1996";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 accent; /* if true output accents etc: \'{e} etc. */bool ttfont = FALSE; /* if true we assumed ttfonts, not cmr */bool symbolfont = FALSE; /* true if font is a symbol font */bool japan = FALSE; /* switch to japanese fonts ... */bool mifont = FALSE;int jfontnum = 0;bool noffd; /* if true output ^L instead of formfeed */char * delim; /* -bdelim for font switch printing */bool printfont; /* true if user wants font switches printed */bool allchar; /* true if user sets all characters */ /* overrides sscasci, accent */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 */long lineheight = VERTICALEPSILON; /* aprox height of a line */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 *//* * Function definitions */#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);void jischar (long);int compute_jis (int, int, int *, int *);int getjsubfont (char *);#elsevoid postamble (void);void preamble (void);void walkpages (void);void initpage (void);void dopage (void);void skippage (void);void printpage (void);bool inlist (long pagenr);void rule (bool moving, long rulewt, long ruleht);void ruleaux (long rulewt, long ruleht, char ch);long horizontalmove (long amount);int skipnops (void);linetype * getline (void);linetype * findline (void);unsigned long num (int size);long snum (int size);void dochar (char ch);void symchar (char ch);void normchar (char ch);void outchar (char ch);void putcharacter (long charnr);void setchar (long charnr);void fontdef (int x);void setfont (long fntnum);void jischar (long charnr);void compute_jis (int f, int c, int * ku, int * ten);int getjsubfont (char * s);#if defined(VMS)long vmsseek ();long vms_ftell ();long vms_ungetc ();#endif#endif/* * DVIMAIN -- 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(void){ postamble(); /* seek and process the postamble */ preamble(); /* process preamble */ /* note that walkpages *must* immediately follow preamble */ walkpages(); /* time to do the actual work! */ return;} /* dvimain */ /* * POSTAMBLE -- Find and process postamble, use random access */void postamble(void){ register long size; register int count;#if !defined (THINK_C) struct stat st;#endif#if defined (THINK_C) size = DVIfile->len;#else fstat (fileno(DVIfile), &st); size = (long) st.st_size; /* get size of file */#endif count = -1; do { /* back file up past signature bytes (223), to id-byte */ if (size-- == 0) errorexit(nopst); 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 ... */ return;} /* postamble *//* * PREAMBLE --process preamble, use random access */void preamble(void){ 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 */ return;} /* preamble *//* * WALKPAGES -- process the pages in the DVI-file */void walkpages(void){ register bool wantpage; pagecounter = 0L; while ((opcode = skipnops()) != POST) { if (opcode != BOP) /* should be at start of page now */ errorexit(nobop); pagecounter++; pagenr = sget4(); /* get TeX page number */ mseek(DVIfile, 36L, relative); /* skip page header */ backpointer = sget4(); /* get previous page offset */ if (pageswitchon) wantpage = inlist(sequenceon ? pagecounter : pagenr); else wantpage = TRUE; if (wantpage) { initpage(); dopage(); printpage(); } else skippage(); } return;} /* walkpages *//* * INITPAGE -- Setup a new, empty page. */void initpage(void){ 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 : 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); } return;} /* initpage *//* * DOPAGE -- Process the dvi file until an end-off-page. * Build up a page image. */void dopage(void){ while ((opcode = (int) get1()) != EOP) { /* process page until eop */ if (opcode <= LASTCHAR) dochar((char) opcode); else if ((opcode >= FONT_00) && (opcode <= FONT_63)) setfont((long) opcode - FONT_00); else if (opcode > POST_POST) errorexit(illop); else switch (opcode) { case SET1 : japan ? jischar(get1()) : 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); 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; } } return;} /* dopage *//* * SKIPPAGE -- Scan the dvi file until an end-off-page. * Skip this page. */void skippage(void){ register int opcode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -