|
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 U
Length: 161680 (0x27790) Types: TextFile Notes: Uncompressed file
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦037544301⟧ »./DVIware/obsolete/ln01.sh.Z« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦037544301⟧ »DVIware/obsolete/ln01.sh.Z« └─⟦this⟧
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # ln01 # This archive created: Fri Mar 11 15:55:17 1988 export PATH; PATH=/bin:$PATH if test ! -d 'ln01' then echo shar: creating directory "'ln01'" mkdir 'ln01' fi echo shar: entering directory "'ln01'" cd 'ln01' if test ! -d 'ln01' then echo shar: creating directory "'ln01'" mkdir 'ln01' fi echo shar: entering directory "'ln01'" cd 'ln01' echo shar: extracting "'Makefile'" '(1642 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' # # ln01 driver routines # DEBUGFLAGS = -DDEBUG LN01sFLAG = -DLN01s CFLAGS = -O -c $(DEBUGFLAGS) PFLAGS = -Pln LDFLAGS = all: pxltoln01 lndvif makelnentry fonttest SOURCES = pxltoln01.h pxltoln01.c \ lndvif.h lndvif.c \ lncmd.h lncode.h lncode.c lnfile.h lnfile.c \ makelnentry.c fonttest.c cnvt-plain PTOLNOBJS = pxltoln01.o lnfile.o lncode.o \ ../utilities.o ../pxlfile.o ../dimen.o ../fontcap.o PTOLNHEADERS = pxltoln01.h lnfile.h lncode.h \ ../utilities.h ../pxlfile.h ../dimen.h ../fontcap.h pxltoln01: $(PTOLNHEADERS) $(PTOLNOBJS) cc -o pxltoln01 $(PTOLNOBJS) $(LDFLAGS) pxltoln01.o: $(PTOLNHEADERS) pxltoln01.c cc $(CFLAGS) pxltoln01.c LNDVIFHEADERS = ../paths.h lndvif.h ../utilities.h ../dvifile.h ../pxlfile.h \ ../dimen.h ../fontcap.h lncode.h lncmd.h LNDVIFOBJS = lndvif.o lncode.o \ ../utilities.o ../dimen.o ../dvifile.o ../pxlfile.o ../fontcap.o lndvif: $(LNDVIFHEADERS) $(LNDVIFOBJS) cc -o lndvif $(LNDVIFOBJS) $(LDFLAGS) lndvif.o: $(LNDVIFHEADERS) lndvif.c cc $(CFLAGS) $(LN01sFLAG) lndvif.c lnfile.o: lncode.h lnfile.h lnfile.c cc $(CFLAGS) lnfile.c lncode.o: lncode.h lncode.c cc $(CFLAGS) lncode.c MLOBJS = makelnentry.o ../utilities.o MLHEADERS = ../utilities.h makelnentry.o: $(MLHEADERS) makelnentry.c cc $(CFLAGS) makelnentry.c makelnentry: $(MLOBJS) cc $(MLOBJS) -o makelnentry $(LDFLAGS) fonttest: ../paths.h fonttest.o lncode.o cc -o fonttest fonttest.o lncode.o $(LDFLAGS) fonttest.o: lncmd.h lncode.h fonttest.c cc $(CFLAGS) fonttest.c list: lpr -p $(PFLAGS) $(SOURCES) Makefile clean: rm -f *.o SHAR_EOF fi # end of overwriting check echo shar: extracting "'cnvt-plain'" '(725 characters)' if test -f 'cnvt-plain' then echo shar: will not over-write existing file "'cnvt-plain'" else cat << \SHAR_EOF > 'cnvt-plain' # cnvt-plain Samuel W. Bent 8/15/84 # Convert all the plain TeX fonts to LN01 format. Argument is magnification. if ($#argv > 0) then set magv = ( $argv ) else set magv = 1500 endif set pxl = pxl set ln = ln set pxldir = /usr/public/pxlfonts set lndir = /usr/public/pxlfonts echo Reading PXL files from $pxldir --- writing LN files in $lndir foreach mag ( $magv ) foreach font ( amr10 amr7 amr5 ammi10 ammi7 ammi5 ambx10 ambx7 ambx5 \ amti10 amex10 amsl10 amtt10 \ amsy10 amsy7 amsy5 ) if (-e $pxldir/$font.$mag$pxl) then echo $font.$mag$pxl " --> " $font.$mag$ln pxltoln01 $pxldir/$font.$mag$pxl | conv - > $lndir/$font.$mag$ln else echo "Can't find " $font.$mag$pxl endif end end SHAR_EOF fi # end of overwriting check echo shar: extracting "'fonttest.c'" '(1828 characters)' if test -f 'fonttest.c' then echo shar: will not over-write existing file "'fonttest.c'" else cat << \SHAR_EOF > 'fonttest.c' /* This ought to print the characters in a TeX ln01 font */ #include <stdio.h> #include "../paths.h" #include "lncmd.h" #include "lncode.h" #define LMARG 300 #define TMARG 300 #define BASELINE 300 main(argc,argv) int argc; char **argv; { int ch; int count; int i; FILE *in, *out; char buf[1024]; char fontfile[200]; char answer[200]; static char ln01[] = LN01DEVICE; char *output; int append, summary; if (argc>1) output = argv[1]; else output = ln01; out = fopen(output,"w"); if (out==NULL) exit(1); for (i=1;;++i) { fprintf(stderr,"Font file %d? ",i); scanf("%s", fontfile); if ((in = fopen(fontfile,"r")) == NULL) { fprintf(stderr,"Can't load font %s \n", fontfile); continue; }; fprintf(out,LN_RESET); fprintf(stderr," Append? "); scanf("%s", answer); append = (*answer=='y' || *answer=='Y'); fprintf(stderr," Summary? "); scanf("%s", answer); summary = (*answer=='y' || *answer=='Y'); if (append && summary) fprintf(out,LN_APPENDFONT_SUMMARY); else if (append && !summary) fprintf(out,LN_APPENDFONT); else if (!append && summary) fprintf(out,LN_LOADFONT_SUMMARY); else if (!append && !summary) fprintf(out,LN_LOADFONT); while((count = fread(buf,1,1024,in)) > 0) { fwrite(buf,1,count,out); }; fclose(in); fprintf(out,LN_ENDLOAD, "Font test"); fprintf(out,LN_RESET); fprintf(out,"\033[11m"); /* seclect portrait font */ fprintf(out,"\033[3300t\33[0;3300r\33[0;2550s"); /* set margins */ fprintf(out,"\033P1;19}%-20s\33\134", fontfile); /* select test font*/ fprintf(out,"\033[19m"); fprintf(out,"\033[%d`\33[%dd", LMARG, TMARG); for (ch=0;ch<128;++ch) { /* print a table of the font */ if (ch%020==0) fprintf(out,"\033[%d`\33[%de", LMARG, BASELINE); fprintf(out,"%c", lncode[ch]); }; fprintf(out,"\f\033c"); fflush(out); } } SHAR_EOF fi # end of overwriting check echo shar: extracting "'lncmd.h'" '(1545 characters)' if test -f 'lncmd.h' then echo shar: will not over-write existing file "'lncmd.h'" else cat << \SHAR_EOF > 'lncmd.h' /* lncmd.h Samuel W. Bent 8/6/84 */ /* commands for the LN01 * The commands are control strings for use with printf. The expected arguments * are indicated in the comments. For example, to move to x-coord 1500, * say printf(LN_XABS,1500) */ #define LN_LOADFONT "\033P1;1y" /* followed by font record */ #define LN_LOADFONT_SUMMARY "\033P1;0y" /* ... and print summary page */ #define LN_APPENDFONT "\033P2;1y" /* append next font record */ #define LN_APPENDFONT_SUMMARY "\033P2;0y" /* ... and print summary page */ #define LN_ENDLOAD ";%s\033\\" /* (comment) */ #define LN_NAMEFONT "\033P1;1%d}%-20.20s\033\\" /* (number,name) */ #define LN_SELECTFONT "\033[1%dm" /* (number) */ #define LN_TOPOFFORM "\033[%dt" /* (dist to bottom in PXLs) */ #define LN_VMARGINS "\033[%d;%dr" /* (top,bottom) from top */ #define LN_HMARGINS "\033[%d;%ds" /* (left,right) from left */ #define LN_XABS "\033[%d`" /* (x) */ #define LN_XINCR "\033[%da" /* (dx) */ #define LN_YABS "\033[%dd" /* (y) */ #define LN_YINCR "\033[%de" /* (dy) */ #define LN_RULE "\033[1;%d;%d;%d;%d!|" /* (upleftx,uplefty,ht,wd) */ #define LN_NEWPAGE "\014" /* eject page */ #define LN_TOGGLEOFFSET "\033[1!}" /* shift paper stacker */ #define LN_PXLUNIT "\033[7 I" /* distance unit is pixel */ #define LN_RESET "\033c" /* reset to default state */ #define LN_ASSIGNEDFONTS 10 /* number of font assignment slots */ #ifdef LN01s #define LN_MAXFONTMEM 400000 /* size of font ram */ #else #define LN_MAXFONTMEM 193608 /* size of font ram */ #endif SHAR_EOF fi # end of overwriting check echo shar: extracting "'lncode.h'" '(209 characters)' if test -f 'lncode.h' then echo shar: will not over-write existing file "'lncode.h'" else cat << \SHAR_EOF > 'lncode.h' /* lncode.h Samuel W. Bent 8/6/84 */ /* Definitions for the TeX interface with the LN01 */ #define LN_XOFFSET 4 /* Assume ref point lies this many pxls right of envelope edge */ extern int lncode[]; SHAR_EOF fi # end of overwriting check echo shar: extracting "'lncode.c'" '(894 characters)' if test -f 'lncode.c' then echo shar: will not over-write existing file "'lncode.c'" else cat << \SHAR_EOF > 'lncode.c' /* lncode.c Samuel W. Bent 8/1/84 */ /* translate 7-bit codes to 8-bit graphic chars */ int lncode[] = { 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247, 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257, 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047, 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057, 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077, 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117, 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127, 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137, 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147, 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157, 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167, 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0300}; SHAR_EOF fi # end of overwriting check echo shar: extracting "'lndvif.c'" '(39597 characters)' if test -f 'lndvif.c' then echo shar: will not over-write existing file "'lndvif.c'" else cat << \SHAR_EOF > 'lndvif.c' /* lndvif.c Samuel W. Bent 7/30/84 */ /* This program reads a DVI file (in type 2 format), and prints the * document on the LN01. It is based on Knuth's dvitype.web, version 2.2. * The input file is stdin, the output is stdout; someone (usually the * spooler) should arrange for the desired input file and the LN01 to be * associated with these file pointers. * * The general method is to interpret the DVI commands, maintaining the * current position in two ways: (h,v) - in DVI units, and (hh,vv) - * in pixels. After reading a page, sort the characters and rules by * their (vv,hh) values, then send commands to the LN01. * * Because an LN01 font has no provision for a horizontal offset from the * left edge of a character envelope to the reference point, all characters * assume a standard offset, LN_XOFFSET. Any character whose offset exceeds * this must be repositioned slightly to the left. * * The LN01 has only enough memory to hold 10 fonts, so any document * that uses more causes font loads in the midst of printing. In * addition, this program writes a log file indicating which fonts are * loaded. If the next document to be printed is also a DVI file, perhaps * no font load will be needed; but if it's a troff file, a font load will * certainly be necessary. * * The LN01s has much more memory, and can load fonts incrementally. There's * a different algorithm for selecting and loading fonts that tries to avoid * reloading from scratch unless absolutely necessary. */ /* #define DEBUG /* Also defined in Makefile */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #include <strings.h> #include "../paths.h" #include "lndvif.h" #include "../utilities.h" #include "../dimen.h" #include "../dvifile.h" #include "../pxlfile.h" #include "../fontcap.h" #include "lncmd.h" #include "lncode.h" char PGM_NAME[] = "lndvif"; \f /* Data structures */ char *namearg = NULL; /* user who asked for printing */ char *hostarg = NULL; /* where he came from */ char *acctfile = NULL; /* where to write accounting line */ int PAGE_WIDTH; /* width of physical page in pixels */ int PAGE_HEIGHT; /* height of physical page in pixels */ int dviindex, ln01index; /* indices for dvi file and ln01 */ int pxlcapindex; /* index for PXL file database */ int lncapindex; /* index for LN file database */ int curpage; /* sequence number of current page */ PREAMBLE preamble; /* preamble of current dvi file */ POSTAMBLE postamble; /* postamble */ POSTPOSTAMBLE postpostamble; /* postpostamble */ bool inpostamble; /* true when reading postamble */ long f, h,v, w,x, y,z; /* DVI registers: font, position, horiz space amounts, vert space amounts */ long hh,vv; /* position in pixels */ STACKITEM stack[MAXSTACKDEPTH]; /* stack for registers */ int top=0; /* index of first free position in stack */ FONT *fontp; /* pointer to current font structure */ FONT *fcache[CACHEFONTS]; /* buckets for first few fonts */ FONT *fontptrarray[TABLEFONTS]; /* unordered table for remaining fonts */ int fpalen; /* first free slot in fontptrarray */ FONT *allfonts[MAX_FONTS]; /* list of all fonts */ int fonts; /* number of fonts */ FONT *font_to_load[MAX_FONTS]; /* fonts selected for next font load */ FONT *loadedfont[MAX_FONTS]; /* fonts currently loaded in LN01 */ int loadedfonts; /* number of loaded fonts */ FONT *fontassignment[LN_ASSIGNEDFONTS]; /* assigning fonts in LN01 */ int nrassigned; /* number of fonts assigned so far */ long time=0; /* for stamping fonts for LRU reassignment */ long boptime; /* time of last BOP */ FONT *lnfontp; /* current LN01 font */ char rulebuffer[RULEBUFFERSIZE]; /* buffer for rule commands */ OUTCHAR outchardata[MAXCHARS]; /* characters to be printed */ OUTCHAR *outchar[MAXCHARS]; /* pointers to characters to be printed */ int ocindex; /* number of characters printed this page */ int xx,yy; /* current LN01 position */ int obchars, obrules; /* number of out of bounds chars and rules */ OUTCHAR *retry[MAXRETRIES]; /* chars to retry (due to negative kerns) */ int retries; /* number of chars in current line to retry */ int bigcmds; /* number of commands causing new record */ int flindex; /* index of font log file */ char fontlog[MAX_FONTS][MAXLINELENGTH]; /* names of currently loaded fonts */ int fontsize[MAX_FONTS]; /* sizes of currently loaded fonts */ int flsize; /* number of currently loaded fonts */ int last_flsize; /* number the last time we updated log */ long fontmem; /* total size of currently loaded fonts */ bool fonts_reloaded=false; /* true if we reload LN01 fonts */ bool fonts_changed=false; /* true if we reload or append fonts */ char summary_line[MAXSUMMARYLINES][OUTLINELENGTH+1]; /* summary messages */ int summary_index; int Vflg; /* Print progress reports? */ FILE *Vfp = NULL; /* where to print progress reports */ char *Vfilename = NULL; /* where to print progress reports */ #ifdef DEBUG int dflg; /* debug level */ int Dflg; /* printing phase debug level */ bool debugmode; /* true if debugging, so don't load fonts or change system-wide environment (font log, etc.) */ char line[OUTLINELENGTH+1]; /* current line, for debugging */ int lineindex; /* index into line */ #endif char *fontlogfile; /* name of font log file */ int needed; /* number of fonts needed on current page */ long neededmem; /* total size of fonts needed on current page */ long needed_newmem; /* size of fonts that are needed but not loaded */ FONT *font_to_load[MAX_FONTS]; /* pointers to fonts to be loaded next */ int fonts_to_load; /* number of fonts to be loaded */ bool append_new_fonts; /* true if fonts should be appended */ \f main(argc,argv) int argc; char **argv; { while (--argc) { if (**++argv == '-') set_option(&argc,&argv); else acctfile = *argv; }; #ifdef DEBUG debugmode = (dflg!=0 || Dflg!=0); #endif Initialize(); read_font_log(); print_dvi_file(); finish(); } \f set_option(argcp,argvp) int *argcp; char ***argvp; { switch ((*argvp)[0][1]) { case 'x': PAGE_WIDTH = atoi(&(*argvp)[0][2]); break; case 'y': PAGE_HEIGHT = atoi(&(*argvp)[0][2]); break; case 'n': if ((*argvp)[0][2]=='\0') { if (*argcp > 1) { --*argcp; namearg = *++(*argvp); }; } else { namearg = &((*argvp)[0][2]); }; break; case 'h': if ((*argvp)[0][2]=='\0') { if ((*argcp) > 1) { (*argcp)--; hostarg = *++(*argvp); }; } else { hostarg = &((*argvp)[0][2]); }; break; case 'V': /* verbose -- tell file what's happening */ ++Vflg; Vfilename = &((*argvp)[0][2]); break; #ifdef DEBUG case 'd': /* debug */ ++Vflg; /* implies V */ if ((*argvp)[0][2]=='\0') dflg = EVERYPAGE; else sscanf( &((*argvp)[0][2]), "%d", &dflg); break; case 'D': /* debug */ ++Vflg; /* implies V */ if ((*argvp)[0][2]=='\0') Dflg = EVERYFONTASSIGN; else sscanf( &((*argvp)[0][2]), "%d", &Dflg); break; #endif default: break; } } account(who, from, acctfile) char *who, *from, *acctfile; { register FILE *a; if (who == NULL || acctfile == NULL) return; if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL) return; /* * LN01 accounting is done by the page; */ fprintf(a, "d%6.2f\t", (float) curpage); if (from != NULL) fprintf(a, "%s:", from); fprintf(a, "%s\n", who); fclose(a); } \f Initialize() { int i; umask(000); /* allow anyone to write files we create. The only file affected is the font log. */ InitializeFiles(&dviindex,&ln01index); /* prime the file pump */ if ( (lncapindex=OpenFile(LNCAP,"r")) <0) Error(2,"Can't open %s",LNCAP); set_device_resolution(DEVICE_RES); /* set resolution */ for (i=0;i<MAXCHARS;++i) { /* initialize pointers */ outchar[i] = &(outchardata[i]); }; if (Vflg) { /* set up for progress reports */ if (Vfilename==NULL || Vfilename[0]=='\0') { Vfp = stderr; } else { Vfp = fopen(Vfilename,"w"); if (Vfp==NULL) Error(2,"Can't open %s",Vfilename); }; }; if (PAGE_HEIGHT==0) PAGE_HEIGHT = DEF_PAGE_HEIGHT; /* set page dimensions */ if (PAGE_WIDTH==0) PAGE_WIDTH = DEF_PAGE_WIDTH; set_pagesize(true); fontlogfile = FONTLOG; #ifdef DEBUG if (debugmode) fontlogfile = DEBUG_FONTLOG; line[0]='['; /* initialize debug output */ lineindex = 1; #endif } set_pagesize(reset) bool reset; { if (reset) printf(LN_RESET); printf(LN_SELECTFONT,1); /* select ROM portrait font to start */ printf(LN_TOPOFFORM,PAGE_HEIGHT); /* set page size and margins */ printf(LN_VMARGINS,0,PAGE_HEIGHT); printf(LN_HMARGINS,0,PAGE_WIDTH); } print_summary() { int i; #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) { fprintf(Vfp, "Font usage:\n"); for (i=0;i<fonts;++i) { fprintf(Vfp," %-20s %5d chars\n", allfonts[i]->truename, allfonts[i]->chars_in_doc); }; }; #endif if (summary_index==0) return; printf(LN_RESET); printf(LN_SELECTFONT,1); /* Print summary in portrait ROM */ printf("Errors encountered in TeX job for %s at %s:\n\n\n", namearg==NULL? "?": namearg, hostarg==NULL? "?" : hostarg); for (i=0;i<summary_index;++i) { if (Vflg) fprintf(Vfp, "%s\n", summary_line[i]); printf("%s\n", summary_line[i]); }; printf(LN_NEWPAGE); summary_index = 0; } read_font_log() { int len, size; char line[MAXLINELENGTH]; bool sizeOK = true; fontmem = 0; flindex = OpenFile(fontlogfile,"r"); if (flindex<0) { /* no font log, assume memory full */ fontmem = LN_MAXFONTMEM+1; return; }; ReadFromFile(flindex); #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp, "Font log:\n"); #endif for (;;) { /* read line from font log file */ len = getline(line, MAXLINELENGTH); if (len<=0) break; size = 0; sscanf(line, "%s %d", fontlog[flsize], &size); if (size>0) { /* should always be true */ fontsize[flsize] = size; fontmem += fontsize[flsize]; } else { /* just in case someone forgot to write size */ sizeOK = false; }; #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp," %-20s %6d\n", fontlog[flsize], fontsize[flsize]); #endif ++flsize; }; if (!sizeOK) fontmem = LN_MAXFONTMEM+1; /* missing font will cause reload */ #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp," %-20s %6d\n", "Available", LN_MAXFONTMEM-fontmem); #endif last_flsize = flsize; CloseFile(flindex); umask(000); /* make sure daemon can read this file */ flindex = OpenFile(fontlogfile,"a"); /* prepare for updates */ } open_font_log() { if (fonts_reloaded) { if (flindex>=0) CloseFile(flindex); flindex = OpenFile(fontlogfile,"w"); }; } write_font_log() { int i; if (!fonts_changed) return; /* Don't bother if we didn't change fonts */ if (flindex<0) return; /* if no fontlog file, forget it */ WriteToFile(flindex); for (i=(fonts_reloaded? 0 : last_flsize); i<flsize; ++i) { putline("%s\t%6d\n", fontlog[i], fontsize[i]); }; last_flsize = flsize; Flush(); fonts_changed = fonts_reloaded = false; } #ifdef DEBUG dump_font_log() { int i; for (i=0;i<flsize;++i) { fprintf(Vfp," %s\t%6d\n", fontlog[i], fontsize[i]); }; } #endif \f print_dvi_file() { int cmd; long firstpage; ReadFromFile(dviindex); GotoByte(0); do cmd=GetByte(); while (cmd==NOP); if (cmd==PRE) { /* check for preamble and read it */ inpostamble = false; get_preamble(&preamble); set_DVI_dimens(preamble.numerator, preamble.denominator, preamble.magnification); #ifdef DEBUG if (dflg>=EVERYAMBLE) dump_preamble(Vfp,&preamble); #endif firstpage = WhereIsRead(); preload_fonts(); /* read font definitions */ GotoByte(firstpage); } else { message("Input is apparently not a DVI file --- no preamble."); return; }; do { /* then read the rest of the file */ cmd = GetByte(); #ifdef DEBUG if (dflg>=EVERYCMD) fprintf(Vfp,"cmd(%d)=%d ", WhereIsRead()-1,cmd); #endif switch (cmd) { case BOP: ++curpage; boptime = time++; read_page(); sort_page(); print_page(); break; case NOP: break; case FNTDEF1: define_font(1,false); break; case FNTDEF2: define_font(2,false); break; case FNTDEF3: define_font(3,false); break; case FNTDEF4: define_font(4,false); break; case POST: inpostamble = true; get_postamble(&postamble); #ifdef DEBUG if (dflg>=EVERYAMBLE) dump_postamble(Vfp,&postamble); #endif break; case POSTPOST: get_postpostamble(&postpostamble); #ifdef DEBUG if (dflg>=EVERYAMBLE) dump_postpostamble(Vfp,&postpostamble); #endif break; default: Error(2,"Bad command (%o) at byte %d", cmd, WhereIsRead()-1); break; }; } while (cmd!=POSTPOST); } read_page() { int cmd; long prevpageptr; #ifdef DEBUG if (debugmode) fprintf(Vfp,"Page %d...\n",curpage); #endif Skip(40); /* Skip count registers */ prevpageptr = Get4Byte(); /* remember address of previous page */ h=v= hh=vv= w=x=y=z = 0; top = 0; ocindex = 0; rulebuffer[0] = '\0'; obchars = obrules = 0; do { /* Command interpreter */ cmd = GetByte(); #ifdef DEBUG if (dflg>=EVERYCMD) fprintf(Vfp, "cmd(%d)=%d ",WhereIsRead()-1,cmd); #endif if (SETCHAR<=cmd && cmd<SET1) { setchar(cmd,true); continue; }; if (FNTNUM<=cmd && cmd<FNT1) { changefont(cmd-FNTNUM); continue; }; switch (cmd) { case SET1: setchar(GetByte(), true); break; case SET2: setchar(Get2Byte(), true); break; case SET3: setchar(Get3Byte(), true); break; case SET4: setchar(Get4Byte(), true); break; case SETRULE: setrule(true); break; case PUT1: setchar(GetByte(), false); break; case PUT2: setchar(Get2Byte(), false); break; case PUT3: setchar(Get3Byte(), false); break; case PUT4: setchar(Get4Byte(), false); break; case PUTRULE: setrule(false); break; case NOP: break; case BOP: message("BOP in middle of page at byte %d", WhereIsRead()-1); break; case EOP: #ifdef DEBUG if (dflg>=EVERYLINE) dump_line(); #endif break; case PUSH: push(); break; case POP: pop(); break; case RIGHT1: hmove(GetByte()); break; case RIGHT2: hmove(Get2Byte()); break; case RIGHT3: hmove(Get3Byte()); break; case RIGHT4: hmove(Get4Byte()); break; case W0: hmove(w); break; case W1: w = GetByte(); hmove(w); break; case W2: w = Get2Byte(); hmove(w); break; case W3: w = Get3Byte(); hmove(w); break; case W4: w = Get4Byte(); hmove(w); break; case X0: hmove(x); break; case X1: x = GetByte(); hmove(x); break; case X2: x = Get2Byte(); hmove(x); break; case X3: x = Get3Byte(); hmove(x); break; case X4: x = Get4Byte(); hmove(x); break; case DOWN1: vmove(GetByte()); break; case DOWN2: vmove(Get2Byte()); break; case DOWN3: vmove(Get3Byte()); break; case DOWN4: vmove(Get4Byte()); break; case Y0: vmove(y); break; case Y1: y = GetByte(); vmove(y); break; case Y2: y = Get2Byte(); vmove(y); break; case Y3: y = Get3Byte(); vmove(y); break; case Y4: y = Get4Byte(); vmove(y); break; case Z0: vmove(z); break; case Z1: z = GetByte(); vmove(z); break; case Z2: z = Get2Byte(); vmove(z); break; case Z3: z = Get3Byte(); vmove(z); break; case Z4: z = Get4Byte(); vmove(z); break; case FNT1: changefont(GetByte()); break; case FNT2: changefont(Get2Byte()); break; case FNT3: changefont(Get3Byte()); break; case FNT4: changefont(Get4Byte()); break; case XXX1: special(GetByte()); break; case XXX2: special(Get2Byte()); break; case XXX3: special(Get3Byte()); break; case XXX4: special(Get4Byte()); break; case FNTDEF1: define_font(1,false); break; case FNTDEF2: define_font(2,false); break; case FNTDEF3: define_font(3,false); break; case FNTDEF4: define_font(4,false); break; case PRE: message("PRE in middle of page at byte %d", WhereIsRead()-1); break; case POST: message("POST in middle of page at byte %d", WhereIsRead()-1); break; case POSTPOST: message("POSTPOST in middle of page at byte %d", WhereIsRead()-1); break; default: message("Unknown opcode %d at byte %d", cmd,WhereIsRead()-1); break; }; } while (cmd != EOP); if (obchars>0 || obrules>0) { message("Ignored %d characters and %d rules outside page boundaries on page %d", obchars, obrules, curpage); }; return(prevpageptr); } vmove(dy) long dy; { v += dy; if (abs(dy)<fontp->vspace) { /* "small" motion */ vv += DVItoPXL(dy); } else { /* "large" motion */ vv = DVItoPXL(v); #ifdef DEBUG if (dflg>=EVERYLINE) { dump_line(); }; #endif }; } hmove(dx) long dx; { int i; h += dx; if (abs(dx)<fontp->space) { /* "small" motion */ hh += DVItoPXL(dx); } else { /* "large" motion */ hh = DVItoPXL(h); #ifdef DEBUG if (dflg>=EVERYLINE) { append_to_line(' '); for (i=1;i<dx/fontp->size;++i) append_to_line(' '); }; #endif }; } charmove(dh,dhh) long dh, dhh; { h += dh; hh += dhh; } setchar(c,moverefpt) int c; bool moverefpt; { CHAR *cp; OUTCHAR *ocp; long xx,yy; cp = &(fontp->charinfo[c]); #ifdef DEBUG if (dflg>=EVERYCHAR) { fprintf(Vfp, "f=%d c=0%o-%c: vh=(%d,%d) vvhh=(%d,%d) wxyz=(%d,%d,%d,%d)\n", f,c, 040<=c&&c<=0176 ? (char) c : '?', v,h, vv,hh, w,x,y,z); }; if (dflg>=EVERYLINE && 041<=c && c<=0176) append_to_line( (char) c); #endif xx = hh+ZERO_X + cp->xcorr-LN_XOFFSET; yy = vv+ZERO_Y; if (xx>=PAGE_WIDTH || yy>=PAGE_HEIGHT || xx<0 || yy<0) { obchars++; return; }; ocp = outchar[ocindex++]; ocp->ch = c; ocp->font = f; ++(fontp->chars_on_page); ocp->yx = Pack(yy,xx); if (moverefpt) { charmove(cp->dviwidth,cp->pxlwidth); }; } setrule(moverefpt) bool moverefpt; { long height, width; char buf[100]; int xxul,yyul, xxlr,yylr; height = Get4Byte(); width = Get4Byte(); xxul = hh+ZERO_X; yyul = vv-DVItoRulePXL(height)+ZERO_Y; xxlr = xxul + DVItoRulePXL(width); yylr = vv+ZERO_Y; #ifdef DEBUG if (dflg>=EVERYCHAR) { fprintf(Vfp, "Rule: hw=(%d,%d) vh=(%d,%d) vvhh=(%d,%d) wxyz=(%d,%d,%d,%d)\n", height,width, v,h, vv,hh, w,x,y,z); }; if (Dflg>=EVERYRULE) fprintf(Vfp,"Rule: yx=(%d,%d) hw=(%d,%d)\n", vv,hh, DVItoRulePXL(height),DVItoRulePXL(width) ); #endif if (xxlr>=PAGE_WIDTH || yylr>=PAGE_HEIGHT || xxul<0 || yyul<0) { obrules++; return; }; #ifdef DEBUG if (dflg>=EVERYPAGE) ++bigcmds; #endif sprintf(buf, LN_RULE, xxul, yyul, yylr-yyul, xxlr-xxul ); strcat(rulebuffer, buf); if (moverefpt) hmove(width); } push() { STACKITEM * sp; if (top>=MAXSTACKDEPTH) Error(2,"Stack overflow at level %d, byte%d", top,WhereIsRead()-1); sp = &stack[top]; sp->h = h; sp->v = v; sp->w = w; sp->x = x; sp->y = y; sp->z = z; sp->hh = hh; sp->vv = vv; ++top; } pop() { STACKITEM * sp; if (--top<0) Error(2,"Stack underflow at byte %d", WhereIsRead()-1); sp = &stack[top]; h = sp->h; v = sp->v; w = sp->w; x = sp->x; y = sp->y; z = sp->z; hh = sp->hh; vv = sp->vv; } FONT *find_fontp(fontno) int fontno; { int i; FONT *fontp; if (fontno<CACHEFONTS) fontp = fcache[fontno]; else { for (i=0;i<fpalen;++i) { if (fontptrarray[i]->number == fontno) { fontp = fontptrarray[i]; break; }; }; if (i>=fpalen) { message("Can't find font %d",fontno); }; }; return (fontp); } changefont(fontno) int fontno; { f = fontno; fontp = find_fontp(fontno); fontp->timestamp = time++; } define_font(fnlen,really_define) int fnlen; bool really_define; { FONTDEF fd; int pxlsize; char pxlname[MAXNAMESIZE]; char full_pxlname[MAXNAMESIZE]; int pxlindex; FONT *fp; char lnname[LNNAME_SIZE]; char full_lnname[MAXNAMESIZE]; int status; struct stat sbuf; double pxlmag; int c; PXLCHAR *pcp, pxldir[0200]; PXLHEADER pxlhead; CHAR *cp; bool using_default; get_fontdef(&fd, fnlen); #ifdef DEBUG if (dflg>=EVERYFONTDEF || (inpostamble && dflg>=EVERYAMBLE) || (really_define && Dflg>=EVERYFONTLOAD)) dump_fontdef(Vfp,&fd); #endif if (!really_define) return; /* select ln file */ pxlsize = ROUND( (double)preamble.magnification * fd.scalesize/fd.designsize * DEVICE_RES/pxlfilePXLperIN ); ReadFromFile(lncapindex); match_lnfile(fd.name,pxlsize, lnname); make_pxlname(lnname, pxlname); sprintf(full_lnname, "%s/%s", LNPATH, lnname); sprintf(full_pxlname, "%s/%s", PXLPATH, pxlname); if ( (fp= (FONT *)malloc(sizeof(FONT)))==NULL ) Error(2,"Cannot allocate memory for %s",pxlname); strcpy(fp->truename, lnname); fp->missing = false; status = stat(full_lnname,&sbuf); using_default = false; if (status!=0 || (pxlindex=OpenFile(full_pxlname,"r"))<0) { using_default = true; message("Substituted %s for missing font %s", DEFAULT_FONT, lnname); fp->missing = true; strcpy(lnname, DEFAULT_FONT); make_pxlname(lnname, pxlname); sprintf(full_lnname, "%s/%s", LNPATH, lnname); sprintf(full_pxlname, "%s/%s", PXLPATH, pxlname); status = stat(full_lnname,&sbuf); if (status!=0 || (pxlindex=OpenFile(full_pxlname,"r"))<0) { message("Can't open %s",pxlname); finish(); }; }; ReadFromFile(pxlindex); get_pxlheader(&pxlhead); if (!using_default && (double) abs(pxlhead.magnification-pxlsize)/pxlsize > SIZE_TOLERANCE) { message("Substituted %s for %s.%dpxl -- spacing may be off.", pxlname, fd.name, pxlsize); fp->missing = true; }; /* read its directory */ pxlmag = GetRealMag(pxlhead.magnification) * pxlfilePXLperIN / DEVICE_RES; GotoByte(pxlhead.directoryptr); get_pxldirectory(pxldir); /* insert in table */ if (fd.number<CACHEFONTS) fcache[fd.number] = fp; else fontptrarray[fpalen++] = fp; /* fill in font info */ if (fonts>=MAX_FONTS) { message("Too many fonts."); finish(); }; allfonts[fonts++] = fp; fp->number = fd.number; strcpy(fp->name,lnname); fp->size = fd.scalesize; fp->loaded = false; fp->timestamp = -fd.number; /* guess that low number fonts are used first */ fp->lnno = -1; fp->chars_on_page = 0; fp->chars_in_doc = 0; fp->bytes = 3*(sbuf.st_size)/4; /* adjust for SIXEL encoding */ fp->space = fd.scalesize / 6; fp->vspace = (5*fd.scalesize) / 6; /* fill in character info */ for (c=0;c<0200;++c) { cp = &fp->charinfo[c]; pcp = &pxldir[c]; cp->xcorr = MIN( -(pcp->xoffset-LN_XOFFSET), 0); cp->dviwidth = DUtoDVI(pcp->tfmwidth, fd.scalesize); cp->pxlwidth = ROUND( pxlmag * FIXtoPXL(DUtoFIX(pcp->tfmwidth, pxlhead.designsize))); }; CloseFile(pxlindex); /* done with pxl file */ ReadFromFile(dviindex); /* return to reading DVI file */ } special(length) int length; { Skip(length); } preload_fonts() { int cmd; int i,j; FONT *fp; ReadFromFile(dviindex); GotoFontdefs(); do { cmd = GetByte(); switch (cmd) { case FNTDEF1: define_font(1,true); break; case FNTDEF2: define_font(2,true); break; case FNTDEF3: define_font(3,true); break; case FNTDEF4: define_font(4,true); break; case NOP: break; case POSTPOST: break; default: message("Bad command (0%o) at byte %d in postamble", cmd, WhereIsRead()-1); break; }; } while (cmd!=POSTPOST); loadedfonts = 0; /* Mark fonts that are already loaded */ for (i=0; i<fonts; ++i) { fp = allfonts[i]; for (j=0; j<flsize; ++j) { if (strcmp(fp->name,fontlog[j])==0) { loadedfont[loadedfonts++] = fp; fp->loaded = true; break; }; }; }; } sort_page() { OUTCHAR *ocp; int i,j, t; long key; int swaps; swaps = 0; for (t=ocindex; t>1; ) { /* Shellsort */ if (t<5) t = 1; else t = (5*t-1)/11; for (j=t; j<ocindex; ++j) { ocp = outchar[j]; key = ocp->yx; for (i=j-t; i>=0 && outchar[i]->yx>key; i-=t) { outchar[i+t] = outchar[i]; ++swaps; }; outchar[i+t] = ocp; }; }; #ifdef DEBUG if (dflg>=EVERYPAGE) fprintf(Vfp, "%d chars, shellsort made %d swaps\n", ocindex, swaps); #endif } print_page() { int index, tmp; OUTCHAR *ocp; #ifdef DEBUG if (dflg>=EVERYPAGE) bigcmds = 0; #endif load_fonts(); /* ensure the fonts are present */ printf("%s",rulebuffer); f = MAXINT; xx=yy=MAXINT; for (index=0; index<ocindex; ++index) { ocp = outchar[index]; print_char(ocp); }; flush_retries(); printf(LN_NEWPAGE); ++bigcmds; #ifdef DEBUG if (debugmode) { fprintf(Vfp, "...page %d (%d big commands)\n", curpage, bigcmds); }; #endif } load_fonts() { int i, missing_chars; char mcfonts[800]; FONT *fp; neededmem = needed_newmem = 0; /* find out how much font memory is needed */ needed = 0; for (i=0;i<fonts;++i) { if (allfonts[i]->chars_on_page > 0) { neededmem += allfonts[i]->bytes; if (!allfonts[i]->loaded) { needed_newmem += allfonts[i]->bytes; }; fp = allfonts[needed]; /* move needed fonts to front */ allfonts[needed] = allfonts[i]; allfonts[i] = fp; ++needed; }; }; choose_fonts_to_load(); download_fonts(); missing_chars = 0; strcpy(mcfonts, ""); for (i=0; i<needed; ++i) { fp = allfonts[i]; if (fp->missing) { /* check for missing fonts */ missing_chars += fp->chars_on_page; strcat(mcfonts, fp->truename); strcat(mcfonts, " "); }; fp->chars_in_doc += fp->chars_on_page; /* accumulate reference counts */ fp->chars_on_page = 0; }; if (missing_chars>0) { message("Page %d: substituted for %d characters from fonts %s", curpage, missing_chars, mcfonts); }; } download_fonts() { int i; FONT *fp; char comment[150]; if (fonts_to_load==0) return; /* don't do unnecessary work */ if (append_new_fonts) { /* if appending */ for (i=0;i<loadedfonts;++i) { /* deassign font IDs */ fp = loadedfont[i]; fp->lnno = -1; }; fonts_changed = true; } else { /* if reloading */ for (i=0;i<loadedfonts;++i) { /* unload current fonts */ fp = loadedfont[i]; fp->loaded = false; fp->lnno = -1; }; loadedfonts = 0; flsize = 0; /* also in fontlog */ fontmem = 0; fonts_reloaded = true; fonts_changed = true; }; open_font_log(); /* deletes font log, if reloading */ nrassigned = 0; /* deassign all font IDs */ #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp,"%s %d fonts: ", append_new_fonts? "Appending" : "Loading", fonts_to_load); #endif if (append_new_fonts) /* load new ones */ printf(LN_APPENDFONT); else printf(LN_LOADFONT); for (i=0; i<fonts_to_load; ++i) { /* for each font to load */ fp = font_to_load[i]; loadedfont[loadedfonts++] = fp; /* remember it's loaded */ fp->loaded = true; strcpy(fontlog[flsize],fp->name); /* and add to font log */ fontsize[flsize++] = fp->bytes; fontmem += fp->bytes; #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp,"%s ",fp->name); if (!debugmode) { /* don't load if only debugging */ send_font_record(fp); }; #else send_font_record(fp); /* ship the font record */ #endif }; #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) fprintf(Vfp,"\n"); #endif sprintf(comment, "TeX fonts for %s at %s", namearg, hostarg); printf(LN_ENDLOAD, comment); write_font_log(); set_pagesize(false); lnfontp = NULL; /* LN01 has no current assigned font */ } /* This procedure selects fonts to be loaded, and decides if they * can be appended to the current fonts or if the whole font memory * must be reloaded. * The procedure makes the following assumptions: * allfonts[..] - contains pointers to all the fonts, with the ones * needed on the current page appearing first. * needed - counts how may fonts are needed on current page. * fontmem - total size in bytes of currently loaded fonts. * neededmem - size of fonts needed on current page. * needed_newmem - size of fonts needed but not currently loaded. * It returns its answer as follows: * font_to_load[..] - pointers to fonts that should be loaded * fonts_to_load - how many fonts should be loaded * append_new_fonts - true if fonts can be appended (LN01s only) */ choose_fonts_to_load() { FONT *fp; int cutoff, cumul_size, newmem; int i, j, cmd; long save_position; int key; char *reason; static char too_many[] = "Too many fonts"; static char too_big[] = "Font memory exceeded"; int nlchars; char nlfonts[800]; bool newfonts; #ifdef DEBUG if (Dflg>=EVERYFONTLOAD) { fprintf(Vfp,"Need %d fonts (%d bytes, %d new). Available font memory = %d\n", needed, neededmem, needed_newmem, LN_MAXFONTMEM-fontmem); }; #endif fonts_to_load = 0; append_new_fonts = false; if (needed_newmem==0) return; /* no new fonts needed */ #ifdef LN01s if (fontmem+needed_newmem <= LN_MAXFONTMEM) { /* if new fonts fit */ for (i=0;i<needed;++i) { /* select new ones */ if (!allfonts[i]->loaded) font_to_load[fonts_to_load++] = allfonts[i]; }; append_new_fonts = true; /* and append them */ } else if (neededmem<=LN_MAXFONTMEM) { /* if needed fonts fit */ for (i=0;i<needed;++i) { /* select them */ font_to_load[fonts_to_load++] = allfonts[i]; }; append_new_fonts = false; /* and reload them */ } else { /* needed fonts don't fit, so select most frequent */ for (i=1; i<needed; ++i) { /* insertion sort */ fp = allfonts[i]; key = fp->chars_on_page + LBONUS*(fp->loaded?1:0); for (j=i-1; j>=0; --j) { if (allfonts[j]->chars_on_page+LBONUS*(fp->loaded?1:0) > key) allfonts[j+1] = allfonts[j]; else break; }; allfonts[j+1] = fp; }; cumul_size = newmem = 0; cutoff = 0; for (i=0;i<needed;++i) { /* select while there's room */ fp = allfonts[i]; cumul_size += fp->bytes; if (cumul_size<=LN_MAXFONTMEM) { font_to_load[fonts_to_load++] = fp; if (!fp->loaded) newmem += fp->bytes; ++cutoff; } else break; }; if (fontmem + newmem <= LN_MAXFONTMEM) { /* if new fonts will fit */ j = fonts_to_load; fonts_to_load = 0; for (i=0;i<j;++i) { /* select only them */ fp = font_to_load[i]; if (!fp->loaded) font_to_load[fonts_to_load++] = fp; }; append_new_fonts = true; } else append_new_fonts = false; /* otherwise, reload */ reason = too_big; if (cutoff<needed) { /* Can't load all the fonts needed */ nlchars = 0; strcpy(nlfonts, "\0"); for (i=cutoff; i<needed; ++i) { nlchars += allfonts[i]->chars_on_page; strcat(nlfonts, allfonts[i]->truename); strcat(nlfonts, " "); }; message("%s on page %d; ignored %d characters from fonts %s", reason, curpage, nlchars, nlfonts); }; }; #else if (needed<=LN_MAXLOADEDFONTS && neededmem<=LN_MAXFONTMEM) { cumul_size = 0; /* needed fonts fit, so load them */ for (i=0;i<needed;++i) { fp = allfonts[i]; fp->toload = true; cumul_size += fp->bytes; font_to_load[i] = fp; }; cutoff = needed; ReadFromFile(dviindex); /* now try to load next used fonts too*/ save_position = WhereIsRead(); /* remember where we are */ do { /* look ahead */ cmd = GetByte(); if (SETCHAR<=cmd && cmd<SET1) { /* ignore characters */ continue; }; if (FNTNUM<=cmd && cmd<FNT1) { /* wake up for font switches */ fp = find_fontp(cmd-FNTNUM); goto fontswitch; }; switch (cmd) { /* wake up for font switches */ case FNT1: fp = find_fontp(GetByte()); goto fontswitch; case FNT2: fp = find_fontp(Get2Byte()); goto fontswitch; case FNT3: fp = find_fontp(Get3Byte()); goto fontswitch; case FNT4: fp = find_fontp(Get4Byte()); goto fontswitch; case EOP: /* a whole page fits, so update cutoff */ fonts_to_load = cutoff; if (fonts_to_load==LN_MAXLOADEDFONTS) cmd = POST; /* stop looking if we've filled all the slots */ break; /* ignore everything else */ case BOP: Skip(44); break; case NOP: case PRE: case POST: case POSTPOST: case PUSH: case POP: case W0: case X0: case Y0: case Z0: break; case SET1: case PUT1: case RIGHT1: case DOWN1: case W1: case X1: case Y1: case Z1: Skip(1); break; case SET2: case PUT2: case RIGHT2: case DOWN2: case W2: case X2: case Y2: case Z2: Skip(2); break; case SET3: case PUT3: case RIGHT3: case DOWN3: case W3: case X3: case Y3: case Z3: Skip(3); break; case SET4: case PUT4: case RIGHT4: case DOWN4: case W4: case X4: case Y4: case Z4: Skip(4); break; case SETRULE: case PUTRULE: Skip(8); break; case XXX1: Skip(GetByte()); break; case XXX2: Skip(Get2Byte()); break; case XXX3: Skip(Get3Byte()); break; case XXX4: Skip(Get4Byte()); break; case FNTDEF1: Skip(13); Skip(GetByte()+GetByte()); break; case FNTDEF2: Skip(14); Skip(GetByte()+GetByte()); break; case FNTDEF3: Skip(15); Skip(GetByte()+GetByte()); break; case FNTDEF4: Skip(16); Skip(GetByte()+GetByte()); break; default: Error(2, "Bad command %d near byte %d", cmd, WhereIsRead()); break; }; continue; /* most commands just keep looping */ fontswitch: /* except font switches */ if (fp->toload) continue; /* already seen this font */ font_to_load[cutoff++] = fp; /* append new one */ fp->toload = true; cumul_size += fp->bytes; /* accumulate total font memory */ if (cutoff>LN_MAXLOADEDFONTS || cumul_size>LN_MAXFONTMEM) { break; /* stop looking on overflow, and use cutoff from previous page */ }; if (cutoff==fonts) { /* all the fonts fit! */ fonts_to_load = cutoff; break; }; } while (cmd!=POST); GotoByte(save_position); /* go back to where we were */ fonts_to_load = cutoff; for (i=0; i<cutoff; ++i) { /* unmark all fonts */ font_to_load[i]->toload = false; }; } else { /* needed fonts don't fit - load most frequent ones */ for (i=1; i<needed; ++i) { /* insertion sort */ fp = allfonts[i]; key = fp->chars_on_page + LBONUS*(fp->loaded?1:0); for (j=i-1; j>=0; --j) { if (allfonts[j]->chars_on_page+LBONUS*(fp->loaded?1:0) > key) allfonts[j+1] = allfonts[j]; else break; }; allfonts[j+1] = fp; }; cutoff = needed; cumul_size = 0; /* add up sizes */ for (i=0;i<needed;++i) { cumul_size += allfonts[i]->bytes; if (cumul_size>LN_MAXFONTMEM) { cutoff = i; reason = too_big; break; }; }; if (cutoff>LN_MAXLOADEDFONTS) { /* but don't load too many fonts */ cutoff = LN_MAXLOADEDFONTS; reason = too_many; }; newfonts = false; for (i=0; i<cutoff; ++i) { /* mark fonts to load */ font_to_load[i] = allfonts[i]; if (!font_to_load[i]->loaded) newfonts = true; }; if (newfonts) fonts_to_load = cutoff; /* maybe no new fonts to load */ else fonts_to_load = 0; if (cutoff<needed) { /* Can't load all the fonts needed */ nlchars = 0; strcpy(nlfonts, "\0"); for (i=cutoff; i<needed; ++i) { nlchars += allfonts[i]->chars_on_page; strcat(nlfonts, allfonts[i]->truename); strcat(nlfonts, " "); }; message("%s on page %d; ignored %d characters from fonts %s", reason, curpage, nlchars, nlfonts); }; }; #endif } send_font_record(fp) FONT *fp; { int count; FILE *in, *out; char buf[1024]; sprintf(buf, "%s/%s", LNPATH, fp->name); if ((in = fopen(buf,"r")) == NULL) { message("Can't load font %s \n", buf); return; }; out = stdout; while((count = fread(buf,1,1024,in)) > 0) { fwrite(buf,1,count,out); }; fclose(in); } print_char(ocp) OUTCHAR *ocp; { int tmp; bool newline; if (ocp->font!=f) changefont(ocp->font); if (!fontp->loaded) return; /* ignore chars whose fonts aren't loaded */ newline = false; if (Left(ocp->yx)!=yy) { flush_retries(); newline = true; tmp = Left(ocp->yx); if (tmp>yy) printf(LN_YINCR, tmp-yy); else printf(LN_YABS, tmp); yy = tmp; #ifdef DEBUG if (dflg>=EVERYPAGE) ++bigcmds; #endif }; if (Right(ocp->yx)!=xx) { tmp = Right(ocp->yx); if (tmp>xx) printf(LN_XINCR, tmp-xx); else { if (newline) { printf(LN_XABS, tmp); #ifdef DEBUG if (dflg>=EVERYPAGE) ++bigcmds; #endif } else { /* negative kern */ retry[retries++] = ocp; return; }; }; xx = tmp; }; if (ocp->font!=f) changefont(ocp->font); /* retries may have changed font */ if (lnfontp != fontp) select_lnfont(); printf("%c",lncode[ocp->ch]); #ifdef DEBUG if (Dflg>=EVERYPOS) fprintf(Vfp,"(%d,%d)", yy,xx); if (Dflg>=EVERYOUTFONT) fprintf(Vfp,"[%d]",ocp->font); if (Dflg>=EVERYOUTCHAR) fprintf(Vfp,"%c",lncode[ocp->ch]); #endif xx += fontp->charinfo[ocp->ch].pxlwidth; } flush_retries() { int oldretries, rindex; int saveDflg; if (retries==0) return; #ifdef DEBUG if (Dflg>=EVERYRETRY) { fprintf(Vfp,"Retry: {"); saveDflg = Dflg; Dflg = MAX(Dflg,EVERYOUTCHAR); }; #endif while (retries>0) { oldretries = retries; retries = 0; xx = Right(retry[0]->yx); printf(LN_XABS, xx); #ifdef DEBUG if (Dflg>=EVERYRETRY) fprintf(Vfp," [%d,%d] ", yy,xx); if (dflg>=EVERYPAGE) ++bigcmds; #endif for (rindex=0; rindex<oldretries; ++rindex) { print_char(retry[rindex]); }; }; #ifdef DEBUG if (Dflg>=EVERYRETRY) { fprintf(Vfp,"}\n"); Dflg = saveDflg; }; #endif } select_lnfont() { int index; int i; long lru; index = fontp->lnno; if (index<0) { /* if not assigned ... */ if (nrassigned<LN_ASSIGNEDFONTS) { /* use a free slot */ index = nrassigned++; fontp->lnno = index; } else { /* or replace least recently used */ lru = MAXINT; for (i=0;i<LN_ASSIGNEDFONTS;++i) { if (fontassignment[i]->timestamp < lru) { index = i; lru = fontassignment[i]->timestamp; }; }; fontp->lnno = index; fontassignment[index]->lnno = -1; /* mark unassigned */ }; fontassignment[index] = fontp; printf(LN_NAMEFONT, fontp->lnno, fontp->name); #ifdef DEBUG if (Dflg>=EVERYFONTASSIGN) fprintf(Vfp,"Assigned %d to %s\n", fontp->lnno, fontp->truename); #endif }; /* Assert: index = fontp->lnno */ printf(LN_SELECTFONT,index); lnfontp = fontp; } message(format, a1,a2,a3,a4,a5,a6,a7,a8) char *format; { char str[10*OUTLINELENGTH]; int i; sprintf(str, format, a1,a2,a3,a4,a5,a6,a7,a8); for (i=0;i<strlen(str);i+=OUTLINELENGTH) { strncpy(summary_line[summary_index],&str[i],OUTLINELENGTH); summary_line[summary_index++][OUTLINELENGTH] = '\0'; }; if (Vflg) fprintf(Vfp,"%s\n", str); } #ifdef DEBUG append_to_line(c) char c; { line[lineindex++] = c; if (lineindex==OUTLINELENGTH) { line[lineindex] = '\0'; fprintf(Vfp,"%s\n",line); strcpy(line," ... "); lineindex = 9; }; } dump_line() { if (lineindex>1) { append_to_line(']'); line[lineindex] = '\0'; fprintf(Vfp,"%s\n",line); line[0]='['; lineindex = 1; }; } dump_outchar(fp,ocp) FILE *fp; OUTCHAR *ocp; { fprintf(fp,"(0%o,%d,%d,%d)",ocp->ch,ocp->font,Left(ocp->yx),Right(ocp->yx)); } #endif finish() { print_summary(); printf(LN_TOGGLEOFFSET); /* spooler really should do this */ fflush(stdout); account(namearg, hostarg, acctfile); open_font_log(); write_font_log(); exit(0); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'lndvif.h'" '(2982 characters)' if test -f 'lndvif.h' then echo shar: will not over-write existing file "'lndvif.h'" else cat << \SHAR_EOF > 'lndvif.h' /* lndvif.h Samuel W. Bent 8/2/84 */ /* Constants for lndvif.c */ typedef int bool; #define true 1 #define false 0 #define MAXINT 2147483647 #define MIN(A, B) ((A) < (B) ? (A):(B) ) #define MAX(A, B) ((A) > (B) ? (A):(B) ) #define DEFAULT_FONT "amr10.1500ln" #define MAX_FONTS 64 /* maximum number of fonts in one document */ #define LN_MAXLOADEDFONTS 10 /* number of TeX fonts LN01 can load at once */ #define MAXSTACKDEPTH 51 /* stack size */ #define MAXNAMESIZE 80 /* length of file names */ #define LNNAME_SIZE 21 /* length of LN01 internal font name */ #define MAXSUMMARYLINES 50 /* number of summary lines */ #define OUTLINELENGTH 79 /* length of output lines */ #define CACHEFONTS 64 /* store first few fonts in buckets */ #define TABLEFONTS MAX_FONTS /* remaining fonts in unordered table */ #define MAXCHARS 15000 /* number of characters per page */ #define MAXRETRIES 100 /* number of negative kerns per line */ #define RULEBUFFERSIZE 5000 /* length of buffer for rule commands */ #define SIZE_TOLERANCE 0.05 /* relative error for mag selection */ #define LBONUS 15 /* a loaded font is worth this many chars */ #define DEVICE_RES 300 /* LN01 prints 300 pixels/inch */ #define ZERO_X 300 /* x coord of (0,0) point (1" from edge) */ #define ZERO_Y 300 /* y coord of (0,0) point (1" from edge) */ #define DEF_PAGE_WIDTH 2550 /* maximum x pixel */ #define DEF_PAGE_HEIGHT 3300 /* maximum y pixel */ typedef struct {long h,v,w,x,y,z,hh,vv} STACKITEM; typedef struct { /* A character in a font */ long dviwidth; /* width in DVIs */ long pxlwidth; /* width in PXLs */ int xcorr; /* PXLs to move left to align ref pt */ } CHAR; typedef struct { /* A font */ int number; /* Number, from DVI file */ char name[LNNAME_SIZE]; /* Name within LN01 */ char truename[LNNAME_SIZE]; /* Name user thinks it's called */ long size; /* (Scaled) size in DVIs */ bool loaded; /* True when downloaded to LN01 */ bool toload; /* Tre when selected for next font load */ int lnno; /* Assigned number within LN01, or <0 */ int timestamp; /* Time when last invoked */ int chars_on_page; /* Number of chars on current page */ int chars_in_doc; /* Number of chars in document */ bool missing; /* True if can't find font or right mag */ long bytes; /* Size of font record in bytes */ long space; /* Threshold for "large" space, in DVIs */ long vspace; /* Same for vertical space */ CHAR charinfo[0200]; /* The characters themselves */ } FONT; typedef struct { /* A character ready to be printed */ long yx; /* (y,x) position: y<<16 | x */ int font; /* DVI font number */ short ch; /* Positon in font */ } OUTCHAR; #define EVERYAMBLE 1 /* debugging levels */ #define EVERYPAGE 2 #define EVERYLINE 3 #define EVERYFONTDEF 4 #define EVERYCHAR 5 #define EVERYCMD 6 #define EVERYFONTLOAD 1 #define EVERYFONTASSIGN 2 #define EVERYRETRY 3 #define EVERYOUTCHAR 4 #define EVERYRULE 5 #define EVERYOUTFONT 6 #define EVERYPOS 7 SHAR_EOF fi # end of overwriting check echo shar: extracting "'lnfile.h'" '(1748 characters)' if test -f 'lnfile.h' then echo shar: will not over-write existing file "'lnfile.h'" else cat << \SHAR_EOF > 'lnfile.h' /* lnfile.h Samuel W. Bent 7/17/84 */ /* Declarations common to programs that use LN01 font files */ #include "lncode.h" /* Constants */ #define LN_HEADERBYTE 0xAA #define LN_HEADERLENGTH 48 #define LN_TRAILERBYTE 0x55 #define LN_TRAILERLENGTH 8 #define LN_FC 040 #define LN_LC lncode[0177] #define LN_SP_ADDR (LN_HEADERLENGTH+(LN_LC+1)*8) #define LN_PORTRAIT 0 #define LN_LANDSCAPE 1 #define LN_FIXEDWIDTH 0 #define LN_VARWIDTH 2 /* Types */ typedef short byte; typedef struct { /* info global to an LN01 font file */ byte rlev; /* revision level */ byte aspect; /* portrait/landscape + fixed/variable width */ short fsize; /* length of file-header (bytes) */ char name[20]; /* name */ byte udist; /* underline distance */ byte uthick; /* underline thickness */ byte sdist; /* stroke-through distance */ byte sthick; /* stroke-through thickness */ byte supdist; /* superscript distance */ byte subdist; /* subscript distance */ short depth; /* max depth */ short height; /* max height */ short baseline; /* baseline distance */ byte firstc; /* first character code */ byte lastc; /* last character code */ char partno[5]; /* part number */ char null[3]; /* null */ } LNHEADER; typedef struct { /* LN01 character */ short count; /* number of bytes in bitmap */ int bitp; /* address of bitmap (bytes) */ byte seg; /* segment (always '377) */ byte height; /* height of bitmap (bytes) */ byte offset; /* y dist from ref pt to LL corner (2 bits) */ byte width; /* char width (pxls) */ byte off_adj; /* 1 if offset is odd, 0 if even */ } LNCHAR; SHAR_EOF fi # end of overwriting check echo shar: extracting "'lnfile.c'" '(1056 characters)' if test -f 'lnfile.c' then echo shar: will not over-write existing file "'lnfile.c'" else cat << \SHAR_EOF > 'lnfile.c' /* lnfile.c Samuel W. Bent 7/30/84 */ #include <stdio.h> #include "lncode.h" #include "lnfile.h" /* Printing routines (for debugging) */ dump_lnheader(hp) LNHEADER *hp; { int i; fprintf(stderr,"rlev=%d aspect=0%o size=%d name='%.20s'\n", hp->rlev,hp->aspect,hp->fsize,hp->name); fprintf(stderr," udist=%d uthick=%d sdist=%d sthick=%d supdist=%d subdist=%d\n", hp->udist,hp->uthick,hp->sdist,hp->sthick,hp->supdist,hp->subdist); fprintf(stderr," depth=%d height=%d bl=%d fc=0%o lc=0%o partno=(", hp->depth,hp->height,hp->baseline,hp->firstc,hp->lastc); for (i=0;i<4;++i) fprintf(stderr,"%d,",hp->partno[i]); fprintf(stderr,"%d)\n",hp->partno[4]); } dump_lnchar(lnchp) LNCHAR *lnchp; { fprintf(stderr,"count=%d bitp=%d ht=%d off=%d+%d wd=%d\n", lnchp->count,lnchp->bitp,lnchp->height, lnchp->offset,lnchp->off_adj,lnchp->width); } dump_lndir(dir) LNCHAR dir[]; { int ch; for (ch=LN_FC;ch<=LN_LC;++ch) { fprintf(stderr,"0%o-%c: ",ch, (040<ch && ch<0177)? ch : '?'); dump_lnchar(&dir[ch]); }; } SHAR_EOF fi # end of overwriting check echo shar: extracting "'makelnentry.c'" '(3852 characters)' if test -f 'makelnentry.c' then echo shar: will not over-write existing file "'makelnentry.c'" else cat << \SHAR_EOF > 'makelnentry.c' /* makelnentry - create lnfont database entries Sam Bent 5/25/84 */ /* This program examines each argument (assuming each to be the name of a * font raster file in LN01 format), and forms an entry suitable for * the lnfont database, 'lncap'. * It sends the results to stdout. The intended use is * makelnentry *.ln > /usr/lib/tex/fonts/lncap * * A typical entry in the database, illustrating its format is * amr10|Ten point text roman:\ * :1500:1643:1800: * meaning a font named 'amr10' (with a comment describing it) exists * at magnifications 1, 1.095 and 1.2. * * Options: * -i (interactive) Ask user for a comment for each font. * -v (verbose) Print progress reports on stderr. */ /* #define DEBUG */ #include <stdio.h> #include "../utilities.h" char PGM_NAME[] = "makelnentry"; #define MAXNAMELENGTH 100 /* length of file names */ #define MAXENTRIES 10 /* number of database entries per line */ #define NEWLINE "\\\n\t:" /* what to print to start a new line */ #define DEF_COMMENT "A font" /* default comment for data base */ \f /* Data structures */ char fontname[MAXNAMELENGTH]; /* name of current font */ char *filename; /* name of current file */ int magnification, /* current font's magnification */ iflg, /* interactive? */ vflg; /* verbose? */ int p; /* LN file's index */ int inIndex, outIndex; /* Indices for stdin and stdout */ \f /* Main loop. Open each file, read its directory, and form an entry. */ main (argc, argv) int argc; char **argv; { char * option; InitializeFiles(&inIndex,&outIndex); while (--argc>0) { filename = *++argv; if (filename[0]=='-') { /* Really an option! */ option = filename; while (*++option != '\0') { switch (*option) { case 'i': ++iflg; break; case 'v': ++vflg; break; default: Error(0,"Unknown switch: %s",filename); break; }; }; continue; /* so don't open any files */ }; if ((p=open_LN_file(filename))<0) continue; if (set_fontname_and_mag(filename) != 0) continue; print_entry(); close_LN_file(p); }; printf("\n"); } /* Try to open a LN file. * If it looks OK, return its index. * If we can't open it, or it looks wrong, return something <0. */ open_LN_file(filename) char *filename; { int p; long dirptr, end; if ((p=OpenFile(filename,"r"))<0) { /* try to open file */ Error(0,"Can't open %s",filename); return(p); }; return(p); } /* Close a LN file */ close_LN_file(p) int p; { CloseFile(p); } /* Set fontname and magnification from the name of the font we're looking at */ set_fontname_and_mag(filename) char *filename; { char *s, *t; s=filename; t=fontname; /* copy filename up to the */ while (*s!='\0' && *s!='.') { /* extension `.' into fontname */ *t++ = *s++; }; *t = '\0'; if (*s=='.') ++s; magnification = atoi(s); /* copy extension up to 'ln' */ if (magnification==0) { /* into magnification */ Error(0,"%s is missing magnification in extension",filename); return(-1); }; if (vflg) fprintf(stderr,"Font %s at magnification %d: ",fontname,magnification); return(0); } /* Form an entry for the current LN file and print it. */ print_entry() { static int entries; static char oldfontname[MAXNAMELENGTH]; char comment[MAXLINELENGTH]; if (strcmp(fontname,oldfontname)!=0) { /* A new font name */ strcpy(comment,DEF_COMMENT); /* default comment */ if (iflg) { /* get a comment from user */ fprintf(stderr,"Comment for font %s: ",fontname); ReadFromFile(inIndex); getline(comment,MAXLINELENGTH); }; strcpy(oldfontname,fontname); printf("\n%s|%s:%s",fontname, comment, NEWLINE); /* start a new line */ entries = 0; }; if (++entries>MAXENTRIES) { /* if line is full, start a new one */ printf("%s",NEWLINE); entries=1; }; printf("%d:",magnification); /* print entry */ } SHAR_EOF fi # end of overwriting check echo shar: extracting "'pxltoln01.c'" '(10760 characters)' if test -f 'pxltoln01.c' then echo shar: will not over-write existing file "'pxltoln01.c'" else cat << \SHAR_EOF > 'pxltoln01.c' /* pxltoln01 Samuel W. Bent 7/19/84 * * Usage: pxltoln01 file1 [file2 file3 ... ] * * Convert the named PXL files to LN01 format. The output is a "font record", * suitable for downloading to the LN01 after being encoded in SIXBIT form. * Typically, you would filter the output through 'conv' to get a file for * future loading. It may be useful (for debugging, say) to save the output * before converting to SIXBIT. * * Conversion proceeds in several phases: * 1) Adjust boundaries and offsets * 2) Rotate bit maps */ /* #define DEBUG /* also defined in Makefile */ #include <stdio.h> #include "pxltoln01.h" #include "lnfile.h" #include "../dimen.h" #include "../pxlfile.h" #include "../utilities.h" #include "../fontcap.h" #include "lncode.h" char PGM_NAME[] = "pxltoln01"; \f /* Data structures */ PXLHEADER pxlhead; /* header for current pxl file */ double pxlmag; /* conversion factor to pixels */ PXLCHAR pxldir[128]; /* directory of current pxl file */ char pxlname[FNAMELEN]; /* name of current pxl file */ char lnname[FNAMELEN]; /* name of LN01 font */ LNHEADER lnhead; /* header for current LN01 file */ LNCHAR lndir[256]; /* directory of current LN01 file */ int stdinIndex, stdoutIndex; /* index into file arrays */ #ifdef DEBUG int dflg; /* debug flag */ #endif \f main(argc,argv) int argc; char **argv; { int size; int pxlindex; InitializeFiles(&stdinIndex,&stdoutIndex); set_device_resolution(DEVICE_RES); while (--argc>0) { if (**++argv=='-') { option(&argc, &argv); continue; }; strncpy(pxlname,*argv,FNAMELEN); if ((pxlindex=open_pxl_file(pxlname))<0) continue; ReadFromFile(pxlindex); get_pxlheader(&pxlhead); pxlmag = GetRealMag(pxlhead.magnification) * pxlfilePXLperIN / DEVICE_RES; #ifdef DEBUG if (dflg>=EVERYPXLHEADER) dump_pxlheader(&pxlhead); #endif GotoByte(pxlhead.directoryptr); get_pxldirectory(pxldir); #ifdef DEBUG if (dflg>=EVERYPXLDIR) dump_pxldir(pxldir); #endif size = compute_ln_directory(lndir,pxldir,&pxlhead); #ifdef DEBUG if (dflg>=EVERYLNDIR) dump_lndir(lndir); #endif make_lnname(pxlname, lnname); compute_ln_header(&lnhead,&pxlhead,size,lnname); #ifdef DEBUG if (dflg>=EVERYLNHEADER) dump_lnheader(&lnhead); #endif write_ln_header_and_directory(&lnhead,lndir); rotate_characters(pxldir,lndir); write_ln_trailer(3-lnhead.fsize%3); } } option(argcp, argvp) int *argcp; char ***argvp; { char *arg; arg = **argvp; switch (*++arg) { #ifdef DEBUG case 'd': if ((*argvp)[0][2]=='\0') dflg = EVERYCHAR; else sscanf( &((*argvp)[0][2]), "%d", &dflg); ++dflg; break; #endif default: Error(1,"Unknown option '%s'",arg); break; }; } open_pxl_file(name) char *name; { int index; if ((index=OpenFile(name,"r"))<0) { Error(0,"Can't open %s\n",name); }; return(index); } compute_ln_directory(lndir,pxldir,pxlhp) LNCHAR lndir[]; PXLCHAR pxldir[]; PXLHEADER *pxlhp; { int ch, h, w; long lnpos; int dsize; float realmag; PXLCHAR *pchp; LNCHAR *lnchp; int even_offset; dsize = pxlhp->designsize; /* remember facts relevant to font */ realmag = GetRealMag(pxlhp->magnification); lnpos = LN_SP_ADDR + 2; /* start bitmaps after space */ for (ch=0;ch<128;++ch) { pchp = &pxldir[ch]; lnchp = &lndir[lncode[ch]]; if (pchp->bitp == 0) { /* all-white char */ lnchp->count = 2; lnchp->bitp = LN_SP_ADDR; lnchp->seg = 0377; lnchp->height = 2; lnchp->offset = 0; lnchp->off_adj= 0; lnchp->width = ROUND( pxlmag * FIXtoPXL(DUtoFIX(pchp->tfmwidth, pxlhp->designsize))); continue; }; h = pchp->height; /* get envelope height and width */ w = pchp->width; /* adjust y_offset for LL corner, and for evenness */ lnchp->offset = pchp->yoffset + 1 - h; lnchp->off_adj = lnchp->offset%2 == 0 ? 0 : 1; /* adjust width using max_xoffset and x_offset */ if (LN_XOFFSET>pchp->xoffset) w = w + LN_XOFFSET - pchp->xoffset; h = (h+lnchp->off_adj+7) / 8; /* adjust height for bytes */ h = MAX(h,2); /* minimum height is 2 bytes */ lnchp->height = h; /* find char width from tfm width */ lnchp->width = ROUND( pxlmag * FIXtoPXL(DUtoFIX(pchp->tfmwidth, pxlhp->designsize))); if (lnpos%2!=0) ++lnpos; /* align to even byte */ lnchp->count = h*w; lnchp->bitp = lnpos; lnpos += lnchp->count; lnchp->seg = 0377; }; return (lnpos); /* return file length */ } compute_ln_header(lnhp,pxlhp,size,name) LNHEADER *lnhp; PXLHEADER *pxlhp; int size; char *name; { double pht; lnhp->rlev = 1; lnhp->aspect = LN_PORTRAIT + LN_VARWIDTH; /* adjust for trailer */ lnhp->fsize = size + LN_TRAILERLENGTH; sprintf(lnhp->name,"%-20.20s",name); lnhp->firstc = LN_FC; lnhp->lastc = LN_LC; pht = pxlmag * FIXtoPXL(pxlhp->designsize); lnhp->udist = ROUND(pht*SUBPCT); lnhp->uthick = 3; lnhp->supdist = ROUND(pht*SUPPCT); lnhp->subdist = ROUND(pht*SUBPCT); lnhp->depth = ROUND(pht*DEPTHPCT); lnhp->height = ROUND(pht*HEIGHTPCT); lnhp->baseline = lnhp->height+lnhp->depth; } rotate_characters(pxldir,lndir) PXLCHAR pxldir[]; LNCHAR lndir[]; { PXLCHAR *pchp; LNCHAR *lnchp; int lastrow, row, col, ch, start, bits; int xoffset_adj, width, byte_adj, word_adj, offset_adj; int i, j, pad; unsigned raster[ 500*500/32 ]; unsigned A[64]; for (ch=0;ch<128;++ch) { /* for each character */ pchp = &pxldir[ch]; lnchp = &lndir[lncode[ch]]; offset_adj = lnchp->off_adj; xoffset_adj = lnchp->count/lnchp->height - pchp->width; byte_adj = 8*lnchp->height - pchp->height - offset_adj; word_adj = 31 - (pchp->height+byte_adj+offset_adj-1)%32; width = ((pchp->width+31)/32); lastrow = 0; /* fill in blank rows for byte alignment */ for (i=0;i<byte_adj;++i) { for (col=0;col<width;++col) raster[lastrow+col] = 0x0; lastrow += width; }; GotoByte(pchp->bitp); /* read in bitmap */ for (i=0;i<pchp->height;++i) { for (col=0;col<width;++col) raster[lastrow+col] = Get4Byte(); lastrow += width; }; /* fill in blank rows for offset and word alignments */ for (i=0;i<offset_adj+word_adj;++i) { for (col=0;col<width;++col) raster[lastrow+col] = 0x0; lastrow += width; }; for (row=0;row<lastrow;row+=32*width) { /* for each 32x32 block */ for (col=0;col<width;++col) { start = row+col; for (i=0;i<32;++i) { /* read block into array */ A[i] = raster[start]; start += width; }; rotate_array(A); /* rotate array */ start = row+col; for (i=0;i<32;++i) { /* replace block */ raster[start] = A[i]; start += width; }; }; /* for col */ }; /* for row */ WriteToFile(stdoutIndex); /* output result */ pad = lnchp->bitp - WhereIsWrite(); /* pad to even byte */ for (i=0;i<pad;++i) PutByte(0); #ifdef DEBUG if (dflg>=EVERYCHAR) { dump_label(ch); dump_pxlchar(pchp); dump_lnchar(lnchp); fprintf(stderr,"%d blank columns\n",xoffset_adj); } #endif for (j=0;j<xoffset_adj;++j) { for (i=0;i<lnchp->height;++i) { PutByte(0); }; }; #ifdef DEBUG if (dflg>=EVERYCHAR) { fprintf(stderr,"nr=%d wid=%d\n",lastrow,width); }; #endif start = lastrow-32*width + 0; for (j=1;j<=pchp->width;++j) { bits = (32-word_adj)/8; #ifdef DEBUG if (dflg>=EVERYROTATION) { fprintf(stderr,"%3d %1d ",j,bits); }; #endif for (row=start; row>=0; row-=32*width) { #ifdef DEBUG if (dflg>=EVERYROTATION) { dump_word(raster[row]); }; #endif switch (bits) { case 1: PutByte(raster[row]); break; case 2: Put2Byte(raster[row]); break; case 3: Put3Byte(raster[row]); break; case 4: Put4Byte(raster[row]); break; }; bits = 32/8; }; start += width; if (j%32 == 0) start += 1-32*width; #ifdef DEBUG if (dflg>=EVERYROTATION) { fprintf(stderr,"\n"); }; #endif }; }; } rotate_array(A) unsigned A[]; { static int Mask[]={0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000}; int i,j, p, m1,m2, dist; #ifdef DEBUG if (dflg>=EVERYBLOCK) dump_array(A); #endif for (i=0,j=31; i<31; ++i,--j) { /* rotate row i right by 31-i*/ m1 = ~(0xFFFFFFFE<<i); m2 = ~m1; A[i] = ((A[i]>>j) & m1) | ((A[i]<<(i+1)) & m2); }; for (p=0;p<5;++p) { /* rotate column i up by 31-i */ m1 = Mask[p]; m2 = ~m1; dist = 1<<p; for (i=0;i<dist;++i) A[i+32] = A[i]; for (i=0;i<32;++i) { A[i] = (A[i+dist]&m1) | (A[i]&m2); }; }; for (i=1,j=31; i<32; ++i,--j) { /* rotate row i left by i */ m1 = ~(0xFFFFFFFF<<i); m2 = ~m1; A[i] = ((A[i]>>j) & m1) | ((A[i]<<i) & m2); }; #ifdef DEBUG if (dflg>=EVERYBLOCK) dump_array(A); #endif } dump_raster(raster,width,frow,lrow) unsigned raster[]; int width, frow, lrow; { int row, i, j, k, c; row = frow*width; for (i=frow;i<=lrow;++i) { fprintf(stderr,"%3d ",i); for (j=0;j<width;++j) { dump_word(raster[row+j]); }; fprintf(stderr,"\n"); row += width; }; } dump_word(w) int w; { int i; for (i=31;i>=0;--i) { fprintf(stderr,"%c", (w&(1<<i))==0 ? '.' : 'X'); }; } #ifdef DEBUG dump_array(A) unsigned A[]; { int i,j,k; for (i=0;i<32;++i) { fprintf(stderr," %2d ",i); dump_word(A[i]); fprintf(stderr,"\n"); }; } dump_label(ch) int ch; { fprintf(stderr,"0%o-%c: ", ch, 040<ch && ch<0177 ? ch : '?'); } #endif write_ln_header_and_directory(hp,dir) LNHEADER *hp; LNCHAR dir[]; { int i, ch; LNCHAR *chp; WriteToFile(stdoutIndex); PutByte(LN_HEADERBYTE); PutByte(LN_HEADERBYTE); PutByte(hp->rlev); PutByte(hp->aspect); PutByte(hp->fsize); PutByte(hp->fsize >> 8); for (i=0;i<20;++i) PutByte(hp->name[i]); PutByte(hp->udist); PutByte(hp->uthick); PutByte(hp->sdist); PutByte(hp->sthick); PutByte(hp->supdist); PutByte(hp->subdist); PutByte(hp->depth); PutByte(hp->depth >> 8); PutByte(hp->height); PutByte(hp->height >> 8); PutByte(hp->baseline); PutByte(hp->baseline >> 8); PutByte(hp->firstc); PutByte(hp->lastc); for (i=0;i<5;++i) PutByte(hp->partno[i]); for (i=0;i<3;++i) PutByte(0); /* now write the directory */ for (ch=0; ch<hp->firstc; ++ch) { Put4Byte(0); Put4Byte(0); }; for (ch=hp->firstc; ch<=hp->lastc; ++ch) { chp = &dir[ch]; PutByte(chp->count); PutByte(chp->count >> 8); PutByte(chp->bitp); PutByte(chp->bitp >> 8); PutByte(chp->seg); PutByte((~chp->height)&077); PutByte((chp->offset - chp->off_adj)/2); PutByte(chp->width); }; /* finally, write two blank bytes for all-white characters */ PutByte(0); PutByte(0); } write_ln_trailer(pad) int pad; { int i; for (i=0;i<LN_TRAILERLENGTH;++i) PutByte(LN_TRAILERBYTE); for (i=0;i<pad;++i) PutByte(0); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'pxltoln01.h'" '(702 characters)' if test -f 'pxltoln01.h' then echo shar: will not over-write existing file "'pxltoln01.h'" else cat << \SHAR_EOF > 'pxltoln01.h' /* pxltoln01.h Samuel W. Bent 7/17/84 */ /* Constants */ #define DEVICE_RES 300 /* resolution of LN01 */ #define FNAMELEN 50 /* maximum length of file name */ #define SUPPCT 0.5 /* how high to raise superscripts */ #define SUBPCT 0.25 /* how much to lower subscripts */ #define HEIGHTPCT 0.9 /* ratio of design size for height */ #define DEPTHPCT 0.3 /* ratio of design size for depth */ #define BLPCT 1.2 /* ratio of design size for baselines */ #define MAX(X,Y) ( (X)>(Y) ? (X) : (Y) ) /* debug levels */ #define EVERYLNHEADER 1 #define EVERYPXLHEADER 2 #define EVERYCHAR 3 #define EVERYROTATION 4 #define EVERYPREROTATION 5 #define EVERYBLOCK 6 #define EVERYLNDIR 7 #define EVERYPXLDIR 8 SHAR_EOF fi # end of overwriting check echo shar: extracting "'conv.c'" '(1133 characters)' if test -f 'conv.c' then echo shar: will not over-write existing file "'conv.c'" else cat << \SHAR_EOF > 'conv.c' /* * conv - convert font file from/to Xerox 2700 format * * Fred Wilhelmsen * Dept. of Computer Science * University of Utah * * Usage: conv [-] < infile > outfile * - indicates encode mode * * Xerox font files must be encoded before downloading. */ #include <stdio.h> static char RCSid[] = "$Header: RCS/conv.c,v 1.1 83/03/14 13:54:21 fmw Exp $"; main(argc,argv) int argc; char **argv; { register long accum; register char c; register int i; if( argc == 1 ) { for(;;) { accum = (long)0; for( i = 0; i < 4; i++ ) { if( (c = getchar()) == EOF ) exit(0) ; accum = (accum<<6) + (long)((c+1) & 077) ; } putchar( (char)((accum >> 16) & (long)0377)) ; putchar( (char)((accum >> 8) & (long)0377)) ; putchar( (char)(accum & (long)0377)) ; } } if( argc == 2 ) { for(;;) { accum = (long)0 ; for( i = 0; i < 3; i++) { if( (c = getchar()) == EOF) exit(0) ; accum = (accum<<8) + (long)(c & 0377); } for( i = 3; i >= 0; i-- ) { c = (char)(( accum >> ( i*6)) & 077); putchar(( c | 0100 ) -1 ); } } } printf("Usage: conv [-] < infile > outfile\n"); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'ln-fload.c'" '(1944 characters)' if test -f 'ln-fload.c' then echo shar: will not over-write existing file "'ln-fload.c'" else cat << \SHAR_EOF > 'ln-fload.c' #include <stdio.h> /* * ln-fload * * load standard fonts (R, I, B & S in 8, 10 & 12 point sizes) onto the ln01. * * output is sent to stdout. it can be redirected as required. */ #define LOGFILE "/usr/spool/ln01/currfonts" FILE *tf, *logf; int out; FILE *con; char bitdir[] = BITDIR; char *outf = "/dev/ln0"; /* default output device */ /* if no arg, output is to stdout */ char buf[1024]; main(argc, argv) int argc; char *argv[]; { umask(000); if(argc > 1) { outf = argv[1]; if((tf=fopen(outf, "w")) == NULL) { con=fopen("/dev/console", "w"); fprintf(con, "ln-fload: cannot download to %s\n", outf); fclose(con); exit(2); } } else tf=stdout; if((logf = fopen(LOGFILE, "w")) == NULL) { con=fopen("/dev/console", "w"); fprintf(con, "ln-fload: cannot open font logfile\n"); fclose(con); exit(2); } out = fileno(tf); fprintf(tf, "\33c"); /* init ln01 */ if (argc>1) fprintf(tf, "\33P1;0y"); else fprintf(tf, "\33P1;1y"); fflush(tf); sendfont("R", 8); /* R font */ sendfont("R", 12); sendfont("R", 10); sendfont("I", 8); /* I font */ sendfont("I", 12); sendfont("I", 10); sendfont("B", 12); /* B font */ sendfont("B", 10); sendfont("B", 8); sendfont("S", 8); /* S font */ sendfont("S", 10); sendfont("S", 12); if (argc>1) fprintf(tf, ";Standard fonts loaded\33\134\33c\f\n"); else fprintf(tf, ";Standard fonts loaded\33\134\33c"); fclose(logf); /* fclose(tf); */ /* don't close if called by daemon */ } sendfont(s, size) char *s; int size; { register in, count, length; sprintf(buf, "%s/%s-%d", bitdir, s, size); if((in = open(buf, 0)) <0) { con = fopen("/dev/console", "w"); fprintf(con, "ln-fload: Font %s open error\n", buf); fclose(con); exit(2); } length=0; while((count = read(in, buf, 1024)) > 0) { write(out, buf, count); length += count; }; length = 3*length/4; fprintf(logf, "%s-%d\t%d\n", s, size, length); close(in); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'makefile'" '(1642 characters)' if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' # # ln01 driver routines # DEBUGFLAGS = -DDEBUG LN01sFLAG = -DLN01s CFLAGS = -O -c $(DEBUGFLAGS) PFLAGS = -Pln LDFLAGS = all: pxltoln01 lndvif makelnentry fonttest SOURCES = pxltoln01.h pxltoln01.c \ lndvif.h lndvif.c \ lncmd.h lncode.h lncode.c lnfile.h lnfile.c \ makelnentry.c fonttest.c cnvt-plain PTOLNOBJS = pxltoln01.o lnfile.o lncode.o \ ../utilities.o ../pxlfile.o ../dimen.o ../fontcap.o PTOLNHEADERS = pxltoln01.h lnfile.h lncode.h \ ../utilities.h ../pxlfile.h ../dimen.h ../fontcap.h pxltoln01: $(PTOLNHEADERS) $(PTOLNOBJS) cc -o pxltoln01 $(PTOLNOBJS) $(LDFLAGS) pxltoln01.o: $(PTOLNHEADERS) pxltoln01.c cc $(CFLAGS) pxltoln01.c LNDVIFHEADERS = ../paths.h lndvif.h ../utilities.h ../dvifile.h ../pxlfile.h \ ../dimen.h ../fontcap.h lncode.h lncmd.h LNDVIFOBJS = lndvif.o lncode.o \ ../utilities.o ../dimen.o ../dvifile.o ../pxlfile.o ../fontcap.o lndvif: $(LNDVIFHEADERS) $(LNDVIFOBJS) cc -o lndvif $(LNDVIFOBJS) $(LDFLAGS) lndvif.o: $(LNDVIFHEADERS) lndvif.c cc $(CFLAGS) $(LN01sFLAG) lndvif.c lnfile.o: lncode.h lnfile.h lnfile.c cc $(CFLAGS) lnfile.c lncode.o: lncode.h lncode.c cc $(CFLAGS) lncode.c MLOBJS = makelnentry.o ../utilities.o MLHEADERS = ../utilities.h makelnentry.o: $(MLHEADERS) makelnentry.c cc $(CFLAGS) makelnentry.c makelnentry: $(MLOBJS) cc $(MLOBJS) -o makelnentry $(LDFLAGS) fonttest: ../paths.h fonttest.o lncode.o cc -o fonttest fonttest.o lncode.o $(LDFLAGS) fonttest.o: lncmd.h lncode.h fonttest.c cc $(CFLAGS) fonttest.c list: lpr -p $(PFLAGS) $(SOURCES) Makefile clean: rm -f *.o SHAR_EOF fi # end of overwriting check echo shar: done with directory "'ln01'" cd .. if test ! -d 'doc' then echo shar: creating directory "'doc'" mkdir 'doc' fi echo shar: entering directory "'doc'" cd 'doc' echo shar: extracting "'prtex.l'" '(3524 characters)' if test -f 'prtex.l' then echo shar: will not over-write existing file "'prtex.l'" else cat << \SHAR_EOF > 'prtex.l' .TH PRTEX LOCAL 12/9/84 .SH NAME prtex \- cause TeX output to be printed .SH SYNOPSIS .B "prtex [-s] [-q] [-m N] [-r] [-c] [-Pdest] [-i] [-I] [-p pages] file1 [ [options] file2 ... ] [lpr options]" .SH DESCRIPTION Preprocess the named DVI files and spool the outputs to be printed on the named printer (default is the LN01). The extension ``.dvi'' is appended to each filename by default; an explicit extension overrides this. A filename of ``-'' denotes the standard input. .PP Preprocessing for the varian consists of selecting the right magnification of each font, converting DVI coordinates to pixel coordinates, and sorting in the vertical direction. The preprocessor, .I dvi2rmver, also detects errors due to malformed DVI files, missing fonts, and characters or rules off the edge of the page. .PP Options allow selecting pages, changing the global magnification, concatenating files into one DVI file, and rotating the page image. Options that appear after all file names are passed through to .I lpr (1); the most useful one is probably -m, to get mail when the file has been printed. .SH OPTIONS .TP 1in -m N Magnify the output by a factor of N/1000, overriding any magnification specified in the DVI file. .TP -q Run .I dvi2rmver, but do not spool the output for printing. This is useful to check for errors. (Implies -s.) .TP -s Save (do not remove) the DVI file after printing. By default, .I prtex removes DVI files. .TP -r Rotate page image (Varian only). .TP -Pdest Select a printer as the destination for the document. Currently recognized values for dest are "ln" (the LN01 laser printer and the default), and "va" (the varian). .TP -c Concatenate succeding DVI files into one before printing. .TP -p pages Print only the specified pages of the next DVI file. A page specifier is a list of "count specifiers", separated by dots (as in TeX's diagnostic output). A count specifier can be a single number like 3, a range like 1-10, or combinations of these separated by commas. The special character 'x' can be used in ranges to give open ended ranges. The page specifier selects the set of pages whose \\counts each match at least one of their corresponding ranges or values. Several page specifiers can be given for one file, each preceded by -p; the union of the specified pages will be included in the output. .TP -i Interactively decide whether to include each page of the next file. .TP -I Like -i, but applies to all remaining files. .SH "EXAMPLES" .TP 1in prtex -m1000 foo.dvi Change the global magnification of foo.dvi to 1000, and print it. .TP prtex -s -p 1-4,10 foo.dvi bar.dvi Print all pages in foo.dvi where \\count0 is between 1 and 4 or equal to 10, and every page of bar.dvi. Don't delete the DVI files. .TP prtex -p 1-x -p x--1..1 foo.dvi Print pages where \\count0 is at least 1, or where \\count0 is negative and \\count2 is 1. .TP prtex -p1.1.1 -i foo.dvi -m Ask whether to include every page; set default to include pages where \\counts 0, 1, and 2 all equal 1, and to exclude all others. Ask lpr to send mail upon completion of printing. .SH "SEE ALSO" .I tex (LOCAL), .I dviedit (LOCAL) .SH AUTHORS The Varian DVI preprocessor was originally written by Janet Incerpi at Brown, and later modified by Richard Furuta at Washington. This version, incorporating a remote database of font magnification information and interaction with the spooler, is by Samuel Bent at Wisconsin. The LN01 version, as well as the page selection and concatenation features, are also by Samuel Bent. SHAR_EOF fi # end of overwriting check echo shar: extracting "'tex.l'" '(7042 characters)' if test -f 'tex.l' then echo shar: will not over-write existing file "'tex.l'" else cat << \SHAR_EOF > 'tex.l' .TH TEX LOCAL 7/5/84 .SH NAME tex, initex, virtex \- text formatting and typesetting .SH SYNOPSIS .B tex [ first line ] .PP .B initex [ first line ] .PP .B virtex [ first line ] .SH DESCRIPTION TeX is a document formatting language designed by Donald Knuth at Stanford. A complete description of the language can be found in official user's guide, .I The TeXbook, by Donald E. Knuth. This book is available from the publisher (Addison-Wesley), from the TeX User's Group (c/o American Mathematical Society, P.O. Box 6248, Providence RI 02940, $15 prepaid), or from your local bookstore. .PP Arguments given on the command line are passed to the TeX programs as the first input line. As described in .I The TeXbook, that line should begin with a file name or a \\controlsequence. The normal usage is to say .RB `` tex .IR paper '' to start processing .I paper.tex. The default extension (`.tex') can be overridden by specifying an extension explicitly. The name ``paper'' will be the ``jobname'', and is used in forming output file names. If TeX doesn't get a file name in the first line, the jobname is ``texput''. .PP If there is no paper.tex in the current directory, TeX will look look through a search path of directories to try to find it. The standard library on the default search path has the basic format package, plain.tex, described in the TeXbook, as well as several others. It is hardly ever necessary to \\input plain, since the .I tex program has preloaded it. This means that all of the control sequences discussed in .I The TeXbook are known to .I tex. .PP A convenient file in the library is null.tex, containing nothing. When tex can't find a file it thinks you want to input, it keeps asking you for another file name; responding `null' gets you out of the loop if you don't want to input anything. .PP TeX formats the text and commands interspersed in its input, and outputs a typesetter independent file (called .I DVI, for .IR D e V ice .IR I ndependent ). TeX writes the output DVI file on .I jobname.dvi, and a transcript of the session, including error messages, on .I jobname.log. To print the output, run .I prtex (LOCAL) on the DVI file; for example, .RB `` prtex .IR jobname ''. .PP Environment variables can be used to set up directory paths to search when TeX opens a file for input, or to specify the editor to use when TeX switches from an error. For example, the .I csh command .br .in +2 setenv TEXINPUTS .:/usr/me/mylib:/usr/lib/tex/macros .in -2 or the .I sh command sequence .br .in +2 TEXINPUTS=.:/usr/me/mylib:/usr/lib/tex/macros .br export TEXINPUTS .in -2 .br cause all invocations of tex and its derivatives to look for \\input files first in the current directory, then in a hypothetical user's ``mylib'', and finally in the system library. Normally, the user will place the command sequence which sets up the TEXINPUTS environment variable in the .I .cshrc or .I .profile file. The Environment section below lists the relevant environment variables and their defaults. .PP The .I e response to TeX's error prompt causes the .I vi editor to start up at the current line of the current file. The environment variable TEXEDIT can be used to change the editor used. It should contain a string with "%s" indicating where the filename goes and "%d" indicating where the decimal linenumber (if any) goes. For example, a TEXEDIT string for a local version of .I vi can be set by: .br .ti +2 setenv TEXEDIT "/usr/local/vi +%d %s" .br (replacing the path name for vi as appropriate on your system). .PP .PP Two other TeX programs, .I initex and .IR virtex , can be used to create fast-loading customized versions of TeX. The .I initex program is used to create a .I format (.fmt) file that permits fast loading of fonts and macro packages. After processing the fonts and definitions desired, a \\dump command will create the format file. The format file is used by .I virtex. It needs to be given a format file name as the first thing it reads. A format file name is preceded by an &, which needs to be escaped with \\ if given on the command line. So, for instance, one could create a file myfmt.fmt using initex, and then set up a cshell alias with .br .ti +2 alias mytex "virtex \\&myfmt" .br to allow the use of ``mytex paper''. .SH ENVIRONMENT .PP .IP TEXINPUTS Search path for \\input and \\openin files. It should be colon-separated, and start with ``.''. The entire path must be no longer than 700 characters long. Default: .:/usr/lib/tex .IP TEXFONTS Search path for font metric files. The entire path must be no longer than 100 characters long. The default doesn't include the current area (".") to avoid confusing the programs that convert the output for printing on the various output devices (most of which don't know about the path stuff yet). Default: /usr/lib/tex/fonts .IP TEXFORMATS Search path for format files. Default: .:/usr/lib/tex/macros .IP TEXPOOL Search path for TeX strings. Default: .:/usr/lib/tex .IP TEXEDIT Command template for switching to editor. Default: "/usr/ucb/vi +%d %s" .SH "CAVEAT" There is an older version of TeX, called TeX78, described in the book .I TeX and METAFONT, by Donald E. Knuth (Digital Press, 1979). The present version (often referred to internally as TeX82) incorporates literally hundreds of changes from the older version. There have been incompatible changes in the DVI format between TeX78 and TeX82, so programs used to print TeX78 output will not work for TeX82. .SH FILES .TP 2.5i *.tex Input to TeX .TP *.dvi Device independent output files, to be interpreted by programs that know how to print on a particular device. .TP *.log Transcripts of TeX sessions, containing error messages and warnings. .TP /usr/lib/tex TeX's library area .TP /usr/lib/tex/macros TeX system macros and .fmt files .TP /usr/lib/tex/macros/plain.* The ``default'' macro package .TP /usr/lib/tex/fonts TeX's font information .TP /usr/lib/tex/fonts/*.tfm Width information used by TeX (TeX Font Metric files) .TP spool:/usr/public/pxlfonts/*.*pxl Bit maps for low resolution devices .TP /usr/lib/tex/tex.pool Encoded text of TeX's messages .br .SH "SEE ALSO" .I prtex (LOCAL) .br Donald E. Knuth, .I The TeXbook .br Leslie Lamport, .I The LaTeX Document Preparation System .br Michael Spivak, .I The Joy of TEX .br .I TUGBOAT (the publication of the TeX Users Group) .br .I Differences between TeX82 and SAIL TeX .SH "TRIVIA" TeX, pronounced properly, rhymes with ``blecchhh.'' The proper spelling in typewriter-like output is ``TeX'' and not ``TEX'' or ``tex.'' .SH "BUGS" Maybe there should be character other than & to specify format files, since if you forget the \\ on the command line, it doesn't do what you want! Also, there is no way to read a TeX input file with no filename extension. .SH "AUTHORS" TeX was designed by Donald E. Knuth, who implemented it using his WEB system for Pascal programs. It was ported to Unix at Stanford by Howard Trickey, and at Cornell by Pavel Curtis. This version is a combination of their efforts. SHAR_EOF fi # end of overwriting check echo shar: extracting "'dviedit.l'" '(3292 characters)' if test -f 'dviedit.l' then echo shar: will not over-write existing file "'dviedit.l'" else cat << \SHAR_EOF > 'dviedit.l' .TH DVIEDIT LOCAL 12/7/84 .SH NAME dviedit \- make simple changes to DVI files .SH SYNOPSIS .B "dviedit [-mN] [-ofilename] [-Vfilename] [-pP] [-i] file1 [ [-pP] [-i] file2 ...] " .SH DESCRIPTION Selected pages from the named files are concatenated into one DVI file. The DVI files must be compatible, in the sense that they have the same numerator and denominator parameters (from the preamble), and that they do not use the same font number for different fonts. (DVI files generated by plain TeX with no additonally defined fonts will be compatible.) The magnification for the resulting file is taken from the first input file. .PP Command line options can be given to select pages from the input files, change the overall magnification, and reroute the output to a named file. .SH OPTIONS .TP 1in -m N Set the overall magnification factor to N/1000, overriding any magnification specified in the DVI files. (By default, the magnification from the first input file overrides magnifications from the remaining files.) This magnifies the entire page image, so printing an unmagnified file with manification 1200 gives an effective \\hsize of 7.8 inches (6.5*1.2), meaning that lines will fall .8 inches off the right of an 8.5X11 page with 1 inch margins. .TP -o filename Send the output to filename. (By default, output is sent to stdout.) .TP -Vfilename Verbose. Print progress reports on filename (or on stderr, if filename is omitted). .I "No space should appear before the filename." Progress reports mostly amount to the page number of every page that is included in the output. .TP -i Interactive. For every page, you will be asked whether to include it in the output. Legal responses are "yes", "no", and "scroll"; other responses will give a default action (defined by the -p option, if any). "Scroll" means to take the default action without querying from now on. (Responses can be abbreviated to one letter.) .TP -p <page specifier> Select pages. A page specifier is a list of "count specifiers", separated by dots (as in TeX's diagnostic output). A count specifier can be a single number like 3, a range like 1-10, or combinations of these separated by commas. The special character 'x' can be used in ranges to give open ended ranges. The page specifier selects the set of pages whose \\counts each match at least one of their corresponding ranges or values. A page specifier applies only to the next input file. Several page specifiers can be given for one file, each preceded by -p; the union of the specified pages will be included in the output. .SH "EXAMPLES" .TP 1in dviedit -m1000 foo.dvi Change the global magnification of foo.dvi to 1000, and copy all pages to stdout. .TP dviedit -V -p 1-4,10 foo.dvi bar.dvi Include all pages in foo.dvi where \\count0 is between 1 and 4 or equal to 10, and every page of bar.dvi. Also print progress reports on stderr. .TP dviedit -o bar.dvi -p 1-x -p x--1..1 foo.dvi Include pages where \\count0 is at least 1, or where \\count0 is negative and \\count2 is 1. Place output in bar.dvi. .TP dviedit -p1.1.1 -i foo.dvi Ask whether to include every page; set default to include pages where \\counts 0, 1, and 2 all equal 1, and to exclude all others. .SH "SEE ALSO" .I tex (LOCAL), and .I prtex (LOCAL). .SH AUTHOR Samuel Bent. SHAR_EOF fi # end of overwriting check echo shar: done with directory "'doc'" cd .. echo shar: extracting "'NOTICE'" '(215 characters)' if test -f 'NOTICE' then echo shar: will not over-write existing file "'NOTICE'" else cat << \SHAR_EOF > 'NOTICE' The ln01 driver is obsolete and not maintained. Source code can be found in the ln01.sh file in ../ If you need it uncompress ln01.sh and run it through sh. These empty directories are here for your convenience. SHAR_EOF fi # end of overwriting check echo shar: extracting "'README'" '(11951 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' Instructions on installing LN01 and Varian back ends for TeX and a guide to the files Samuel W. Bent University of Wisconsin--Madison The files in this directory and its subdirectories implement TeX back ends (DVI filters) for the DEC LN01, DEC LN01s, and Varian printers. The filters work with either the 4.2BSD spooler or Waterloo's modified spooler; printing from remote machines is possible. Some distributions may not have the Varian files, since other Varian filters are available. INSTALLATION - GENERAL INSTRUCTIONS There are 7 steps to installing the filters and related files. 1) Change "paths.h" to relect your system's organization. 2) Install the PXL fonts and database (see below). 3) (LN01 only) Create and install the LN fonts and database (see below). 4) If you choose, redefine DEBUGFLAGS to null in the Makefile of each directory. This speeds up the programs a little at the expense of debugging potential. 5) (LN01 only) If you have an LN01, redfine LN01sFLAG to null in the Makefile of the /ln01 subdirectory. If you have an LN01s, redefine it to -DLN01s. 6) Compile all the programs by saying 'make all' first in this directory, then in all subdirectories. 7) Install the executables and on-line documentation (see below). PATHS Before installing the programs, you may want to change some of the paths embedded in the code. Here are the paths, their current values (the ones used at Wisconsin), and what they mean. They are all defined in the file paths.h. LN01DEVICE (/dev/lp1): device name for the LN01 TFMPATH (/usr/lib/tex/fonts): where the .tfm files live PXLPATH (/usr/public/pxlfonts): where the PXL font raster files live LNPATH (/usr/public/pxlfonts): where the LN01 format rasters live PXLCAP (/usr/lib/tex/fonts/pxlcap): the database describing PXL files LNCAP (/usr/lib/tex/fonts/lncap): the database describing LN files FONTLOG (/usr/spool/ln01/currfonts): says which fonts were last downloaded to the LN01 DEBUG_FONTLOG (/tmp/currfonts): used instead of FONTLOG when debugging TEMPFILE (/usr/tmp/dvipXXXXXX): temporary file for dviedit Should you wish to change any of these, you'll have to remake some of the software. After making your changes, say make all first in this directory, then in each subdirectory. The installation instructions tell you to "put foo somewhere (/usr/local)". This means to move the file named foo to a reasonable place, usually somewhere in the execution search path for all users, such as /usr/local (where we put it at Wisconsin). HOW TeX AND DITROFF SHARE THE LN01 TeX and ditroff use the FONTLOG file (/usr/spool/ln01/currfonts) to tell each other which fonts currently reside in the LN01's font memory. Both filters should check this file before sending data to the LN01 to make sure the proper fonts are present, and both should update the file to reflect any changes they make to the font memory. The LN01 back end for ditroff uses a set of 12 standard fonts (at least that's the way it works at Wisconsin). TeX, on the other hand, uses whatever fonts are called for in the document. TeX also reloads in the middle of a document if it suddenly needs new fonts. (For the LN01, there is a limit of 10 fonts per page due to the size of some hardware tables, but a document can use as many fonts as it likes. The LN01s is limited only by the size of its font memory.) There are two consequences of all this. 1) Be sure the FONTLOG file (/usr/spool/ln01/currfonts) is sufficiently unprotected so that the printing daemon can read, write, and create it. Ideally, it should be owned by "daemon" with protection -rw-rw-rw-. 2) Be sure your ditroff filter checks the FONTLOG file for the fonts it needs, since TeX may unload them if it runs out of room. BRIEF DESCRIPTION OF ALL FILES In this directory: README This file. HISTORY Log of changes to the filter prtex Shell script to send DVI files to printer paths.h Definitions of paths dvifile.h dvifile.c Utilities for dealing with DVI files pxlfile.h pxlfile.c Utilities for dealing with PXL files dimen.h dimen.c Dimension conversion routines fontcap.h fontcap.c Utilities for reading the font database files utilities.h utilities.c Miscellaneous routines, mostly file reading and writing makepxlentry.c Create entries for the PXLCAP database dviedit.h dviedit.c Utility to concatenate and select pages from DVI files In ./ln01 lndvif.h lndvif.c The DVI filter for the LN01 lncmd.h Definitions for LN01 commands lncode.h lncode.c Conversion from TeX character codes to LN01 codes pxltoln01.h pxltoln01.c Convert PXL files to raw LN01 format conv.c Convert raw LN01 format to SIXEL or vice-versa cnvt-plain Shell script to convert all plain TeX fonts makelnentry.c Create entries for the LNCAP database fonttest.c Send a font to the LN01 (to see if conversion worked right) ln-fload.c Reload ditroff fonts In ./varian: dvi2rmver.h dvi2rmver.c First pass of DVI-to-Varian process; sorts page. vardvif.h vardvif.c Second pass; DVI filter for Varian In ./=doc: tex.l Man page for tex prtex.l Man page for prtex dviedit.l Man page for dviedit To be created: /usr/lib/tex/fonts/pxlcap PXLCAP font database /usr/lib/tex/fonts/lncap LNCAP font database /usr/spool/ln01/currfonts FONTLOG INSTALLING PXL FONTS 1) Make a directory corresponding to PXLPATH, and put all your *.nnnnpxl files there. 2) Install makepxlentry somewhere (/usr/local). 3) Connect to the PXLPATH directory and say makepxlentry -i *.*pxl > foo The -i is optional; if you include it you get to invent a short comment describing each font. 4) Move foo to the file named by PXLCAP. 5) Should you later add new fonts, do step 3 for the new fonts, then merge the results into PXLCAP using an editor. INSTALLING LN01 FONTS 1) Make a directory corresponding to PXLPATH, and put all your *.nnnnpxl file there. 2) Install pxltoln01, conv, and cnvt-plain somewhere (/usr/local). 3) Connect to the PXLPATH directory. For each font you want available for the LN01, say pxltoln01 amr10.1500pxl | conv - > amr10.1500ln (Replace "amr10.1500" with the appropriate name for each font.) To speed things up, cnvt-plain repeats this command for the 16 fonts of plain TeX, at a magnification you supply (default is 1500, namely \magstep0 for a 300 pxl/in printer). For example, cnvt-plain 1500 1643 1800 does the conversion for all plain TeX fonts at \magstep0, \magstephalf, and \magstep1. *NOTE* cnvt-plain defines two shell variables, pxlpath and lnpath. If necessary, change cnvt-plain so that these agree with the paths in paths.h. 4) Move the *ln files to the directory corresponding to LNPATH. 5) Install makelnentry somewhere (/usr/local). 6) Connect to the LNPATH directory and say makelnentry -i *.*ln > foo The -i is optional; if you include it you get to invent a short comment describing each font. 7) Move foo to the file name by LNCAP. 8) Should you later add new fonts, do step 6 for the new fonts, then merge the results into LNCAP using the editor. INSTALLING THE LN01 FILTER 1) Put lndvif somewhere (/usr/local). 2) Add a field to the LN01's entry in /etc/printcap that reads df=/usr/local/lndvif 3) If you use the Waterloo spooler, be sure the LN01's entry in /etc/printcap has a "d" in its "fx" field. Wisconsin's entry reads fx=ftpdn 4) Put prtex somewhere (/usr/local) on each remote machine from which requests to print DVI files may originate. 5) Put dviedit somewhere (/usr/local) on each remote machine. 6) Put tex.l, prtex.l, and dviedit.l somewhere (/usr/man/manl) on each remote machine. 7) Announce to your users that the LN01 is ready for TeX. INSTALLING THE VARIAN FILTER 1) Put vardvif somewhere (/usr/local). 2) Add a field to the Varian's entry in /etc/printcap that reads df=/usr/local/vardvif 3) If you use the Waterloo spooler, be sure the Varian's entry in /etc/printcap has a "d" in its "fx" field. Wisconsin's entry reads fx=flptdngvc 4) Put prtex somewhere (/usr/local) on each remote machine from which requests to print DVI files may originate. 5) Put dviedit somewhere (/usr/local) on each remote machine. 6) Put tex.l, prtex.l, and dviedit.l somewhere (/usr/man/manl) on each remote machine. 7) Put dvi2rmver somewhere (/usr/local) on each remote machine. 8) Announce to your users that the Varian is ready for TeX. SOME COMMENTS The LN01 assumes that the reference point of each character is at the left edge of the envelope surrounding the black pixels; there is no provision for the envelope to be offset left or right. Since many TeX characters have envelopes offset forward from their reference points, the LN01 versions of TeX fonts need to include several blank columns. Furthermore, any character whose envelope is offset more than LN_XOFFSET pixels backward must be repositioned before printing. Making LN_XOFFSET larger reduces the frequency of repositioning, but increases the number of blank columns for "forward" characters. Currently, LN_XOFFSET=4. The following paragraphs apply only to the LN01 (as opposed to LN01s). The LN01 stores character raster images in its own memory; it has about 193K for rasters and about 1740 positions in its character table. Since TeX fonts use all 128 positions, and since the LN01 doesn't let you use positions '0-'37 or '200-'237 but charges you for them anyway, there's only room in the character table for 10 TeX fonts. Naturally if some of those fonts need lots of raster storage, you may run out of raster space before character space. Font loading works pretty well at magnifications \magstep0 and \magstephalf, as long as you don't ask for subsubscripts and bold on the same page (or another combination of sophisticated text and sophisticated math). At \magstep1, the size of the amex10.1800ln begins to run you out of raster space. Loading the entire font memory takes two to three minutes. There is no way to replace a single font; whenever you need a new font you have to reload everything. The filter uses lookahead to load fonts so as to maximize the time to the next font load ("Belady optimal lookahead"). Overall, the situation is far from ideal. When you get frustrated at the limitations, I suggest kicking the printer. I'd kick its designer if I had him around. For LN01s owners, here's the good news. The LN01s has about 400K of font raster memory and no restriction on the number of fonts per page (other than total font memory). Furthermore, it can load fonts without erasing its font memory. Before printing each page, the filter first tries to load fonts used on the page that are not already present. If this fails to load all the fonts on the page, it will try to erase the font memory and reload, hoping that removing fonts from previous pages frees up some room. If this fails too, it simply loads the most frequent fonts on the page. The Varian filter is only slightly changed from the version due to Janet Incerpi and Rick Furuta that I received in April, 1984. To make it work with remote spooling, I had to remove the dependence of the first pass (sorting the page by vertical component) on the PXL files. This I did by using a "worst case" vertical offset for each character in the first pass, then correcting to the real offset in the second pass, which is done on the machine with the printer and the PXL files. The worst case offsets are stored in the PXLCAP file, which needs to live on the remote machines. I also fixed a few bugs in the Varian filter; it was printing rules slightly wrong and doing other minor things I don't remember at the moment. SHAR_EOF fi # end of overwriting check echo shar: extracting "'Makefile'" '(1314 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' # # Routines of general interest # DEBUGFLAGS = -DDEBUG CFLAGS = -O -c $(DEBUGFLAGS) PFLAGS = -Pln SOURCES = paths.h \ utilities.h utilities.c \ dimen.h dimen.c \ pxlfile.h pxlfile.c \ dvifile.h dvifile.o \ fontcap.h fontcap.c \ makepxlentry.c \ dviedit.h dviedit.c \ prtex support: utilities.o dimen.o pxlfile.o dvifile.o fontcap.o all: makepxlentry support dviedit MPOBJS = makepxlentry.o utilities.o pxlfile.o MPHEADERS = utilities.h pxlfile.h makepxlentry.o: $(MPHEADERS) makepxlentry.c cc $(CFLAGS) makepxlentry.c makepxlentry: $(MPOBJS) cc $(MPOBJS) -o makepxlentry $(LDFLAGS) utilities.o: utilities.h utilities.c cc $(CFLAGS) utilities.c dimen.o: dimen.h dimen.c cc $(CFLAGS) dimen.c pxlfile.o: pxlfile.h pxlfile.c dimen.h cc $(CFLAGS) pxlfile.c dvifile.o: dvifile.h dvifile.c cc $(CFLAGS) dvifile.c fontcap.o: paths.h fontcap.h pxlfile.c utilities.h cc $(CFLAGS) fontcap.c DVIEDITOBJS = dviedit.o utilities.o dvifile.o dimen.o DVIEDITHEADERS = paths.h dviedit.h utilities.h dvifile.h dimen.h divedit.o: $(DVIEDITHEADERS) dviedit.c cc $(CFLAGS) makepxlentry.c dviedit: $(DVIEDITOBJS) cc $(DVIEDITOBJS) -o dviedit $(LDFLAGS) list: lpr -p $(PFLAGS) $(SOURCES) Makefile clean: rm -f *.o SHAR_EOF fi # end of overwriting check echo shar: extracting "'dimen.c'" '(2003 characters)' if test -f 'dimen.c' then echo shar: will not over-write existing file "'dimen.c'" else cat << \SHAR_EOF > 'dimen.c' /* dimen.c Samuel W. Bent 7/30/84 */ /* utilities for dimensions */ #include <stdio.h> #include "dimen.h" int PXLperIN; double PXLperFIX; double PXLperDVI; double PXLperDVIunmag; static long magnification; static double realmag; static long numerator; static long denominator; set_device_resolution(p) int p; { PXLperIN = p; PXLperFIX = (double) PXLperIN / FIXperIN; } set_DVI_dimens(n,d,m) long n,d,m; { magnification = m; realmag = GetRealMag(magnification); numerator = n; denominator = d; PXLperDVIunmag = (double) n/d * INperRSU * PXLperIN; PXLperDVI = PXLperDVIunmag * realmag; } #include <stdio.h> long DUtoDVI(du,z) long du; /* tfm width in DUs (=2^-20 DSs) */ long z; /* DVIs per DS */ { int a,b,c,d,e; long alpha; long w; a = (du>>24) & 0377; b = (du>>16) & 0377; c = (du>>8) & 0377; d = du & 0377; alpha = z<<4; e = 0; while (z>=040000000) { z >>= 1; ++e; }; w = ( ( (((d*z)>>8) + c*z) >>8) + b*z) >> (4-e); if (a!=0 && a!=0377) Error(0,"Bad tfm width %d",du); if (a==0377) w -= alpha; return(w); } pxlwidth(du,fix_per_ds,realmag,pxl_per_in) long du, fix_per_ds; float realmag; int pxl_per_in; { return ( FIXtoPXL((int) (DUtoDS(du) * fix_per_ds * realmag) )); } /* this routine takes a integer representation of a mag factor (value of the magnification times 1000) and returns the float representation (no 1000 factor). The routine does a certain amount of faking to make sure that the magnification returned is correct. */ double GetRealMag(intmag) int intmag; { double realmag; if (intmag == 1095) realmag = 1.095445; /* stephalf */ else if (intmag == 1315) realmag = 1.314534; /* stepihalf */ else if (intmag == 2074) realmag = 2.0736; /* stepiv */ else if (intmag == 2488) realmag = 2.48832; /* stepv */ else if (intmag == 2986) realmag = 2.985984; /* stepiv */ else realmag = (double) intmag / 1000; /* remaining mags have been ok */ return (realmag); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'dimen.h'" '(1148 characters)' if test -f 'dimen.h' then echo shar: will not over-write existing file "'dimen.h'" else cat << \SHAR_EOF > 'dimen.h' /* dimen.h Samuel W. Bent 7/30/84 */ /* Common definitions for dimensions in DVI, PXL, and device programs */ /* Interface */ #define ROUND(f) ( (int) (f+0.5) ) #define CEIL(f) ( (int) (f+0.99) ) #define FIXtoPXL(fix) ( ROUND( (double)fix * PXLperFIX )) #define FIXtoPT(fix) ( (double)fix / FIXperPT ) #define DUtoDS(du) ( (double) du / DUperDS ) #define DVItoPXL(dvi) ( ROUND( (double)dvi * PXLperDVI )) #define DVItoRulePXL(dvi) ( CEIL( (double)dvi * PXLperDVI )) #define DVItoPXLunmag(dvi) ( ROUND( (double)dvi * PXLperDVIunmag )) long DUtoDVI(); /* args=(du,DVIperDS) */ #define DUtoFIX DUtoDVI /* long DUtoFIX(); /* args=(du,FIXperDS) */ double GetRealMag(); /* args=(intmag), return intmag/1000 with fudging */ /* Constants */ #define pxlfilePXLperIN 200 #define PTperIN 72.27 #define CMperIN 2.54 #define RSUperCM 100000 #define RSUperIN (RSUperCM * CMperIN) #define INperRSU (1.0/RSUperIN) #define FIXperPT 1048576 #define FIXperIN (FIXperPT * PTperIN) #define DUperDS 1048576 #define SPperPT 65536 #define SPperIN ((double) SPperPT * PTperIN) extern double PXLperFIX; extern double PXLperDVI; extern double PXLperDVIunmag; SHAR_EOF fi # end of overwriting check echo shar: extracting "'dvifile.c'" '(4066 characters)' if test -f 'dvifile.c' then echo shar: will not over-write existing file "'dvifile.c'" else cat << \SHAR_EOF > 'dvifile.c' /* dvifile.c Samuel W. Bent 8/3/84 */ /* Routines for reading DVI files */ #include <stdio.h> #include "dvifile.h" get_preamble(pap) PREAMBLE *pap; { int i,k; char *s; pap->version = GetByte(); pap->numerator = Get4Byte(); pap->denominator = Get4Byte(); pap->magnification = Get4Byte(); k = GetByte(); s = pap->comment; for (i=0;i<k;++i) *s++ = GetByte(); *s = '\0'; } write_preamble(pap) PREAMBLE *pap; { int i,k; char *s; PutByte(PRE); PutByte(pap->version); Put4Byte(pap->numerator); Put4Byte(pap->denominator); Put4Byte(pap->magnification); k = strlen(pap->comment); PutByte(k); s = pap->comment; for (i=0;i<k;++i) PutByte(*s++); } dump_preamble(fp,pap) FILE *fp; PREAMBLE *pap; { fprintf(fp,"Preamble: %s\n", pap->comment); fprintf(fp," ver=%d num=%d denom=%d mag=%d\n", pap->version, pap->numerator, pap->denominator, pap->magnification); } get_postamble(pap) POSTAMBLE *pap; { pap->lastpage = Get4Byte(); pap->numerator = Get4Byte(); pap->denominator = Get4Byte(); pap->magnification = Get4Byte(); pap->maxheight = Get4Byte(); pap->maxwidth = Get4Byte(); pap->maxstack = Get2Byte(); pap->pagecount = Get2Byte(); } write_postamble(pap) POSTAMBLE *pap; { PutByte(POST); Put4Byte(pap->lastpage); Put4Byte(pap->numerator); Put4Byte(pap->denominator); Put4Byte(pap->magnification); Put4Byte(pap->maxheight); Put4Byte(pap->maxwidth); Put2Byte(pap->maxstack); Put2Byte(pap->pagecount); } dump_postamble(fp,pap) FILE *fp; POSTAMBLE *pap; { fprintf(fp,"Postamble: pageptr=%d num=%d denom=%d mag=%d\n", pap->lastpage, pap->numerator, pap->denominator, pap->magnification); fprintf(fp," maxht=%d maxwd=%d stack=%d pages=%d\n", pap->maxheight, pap->maxwidth, pap->maxstack, pap->pagecount); } get_postpostamble(ppp) POSTPOSTAMBLE *ppp; { ppp->postptr = Get4Byte(); ppp->version = GetByte(); } write_postpostamble(ppp) POSTPOSTAMBLE *ppp; { PutByte(POSTPOST); Put4Byte(ppp->postptr); PutByte(ppp->version); } dump_postpostamble(fp,ppp) FILE *fp; POSTPOSTAMBLE *ppp; { fprintf(fp,"Postpostamble: postptr=%d version=%d\n", ppp->postptr, ppp->version); } get_counts(cr) COUNTREGS cr; { int i; for (i=0;i<10;++i) { cr[i] = Get4Byte(); }; } write_counts(cr) COUNTREGS cr; { int i; for (i=0;i<10;++i) { Put4Byte(cr[i]); }; } get_fontdef(fdp, fnlen) FONTDEF *fdp; int fnlen; { int i,k; char *s; switch (fnlen) { case 1: fdp->number = GetByte(); break; case 2: fdp->number = Get2Byte(); break; case 3: fdp->number = Get3Byte(); break; case 4: fdp->number = Get4Byte(); break; }; fdp->checksum = Get4Byte(); fdp->scalesize = Get4Byte(); fdp->designsize = Get4Byte(); fdp->arealen = GetByte(); fdp->namelen = GetByte(); k = fdp->arealen + fdp->namelen; s = fdp->name; for (i=0;i<k;++i) { *s++ = GetByte(); }; *s = '\0'; } write_fontdef(fdp) FONTDEF *fdp; { int i,k; char *s; if (fdp->number < 01<<8) { PutByte(FNTDEF1); PutByte(fdp->number); } else if (fdp->number < 01<<16) { PutByte(FNTDEF2); Put2Byte(fdp->number); } else if (fdp->number < 01<<24) { PutByte(FNTDEF3); Put3Byte(fdp->number); } else { PutByte(FNTDEF4); Put4Byte(fdp->number); }; Put4Byte(fdp->checksum); Put4Byte(fdp->scalesize); Put4Byte(fdp->designsize); PutByte(fdp->arealen); PutByte(fdp->namelen); k = fdp->arealen + fdp->namelen; s = fdp->name; for (i=0;i<k;++i) { PutByte(*s++); }; } dump_fontdef(fp,fdp) FILE *fp; FONTDEF *fdp; { fprintf(fp,"Font %d (%s): ds=%d ss=%d cksum=%d\n", fdp->number, fdp->name, fdp->designsize, fdp->scalesize, fdp->checksum); } GotoPostamble() { GotoEnd(); Skip(-4); while (GetByte()==DVIPAD) Skip(-2); /* One step forward, two back */ Skip(-5); GotoByte(Get4Byte()); } GotoFontdefs() { GotoPostamble(); Skip(1 + 4 + 4+4+4 + 4+4 + 2+2); /* Skip postamble proper */ } SHAR_EOF fi # end of overwriting check echo shar: extracting "'dvifile.h'" '(1892 characters)' if test -f 'dvifile.h' then echo shar: will not over-write existing file "'dvifile.h'" else cat << \SHAR_EOF > 'dvifile.h' /* dvifile.h Samuel W. Bent 8/2/84 */ /* Common definitions for programs that read and write DVI files */ #define VERSION 2 /* works for DVI format version 2 */ typedef struct { short version; long numerator; long denominator; long magnification; char comment[256]; } PREAMBLE; typedef struct { long lastpage; long numerator; long denominator; long magnification; long maxheight; long maxwidth; short maxstack; short pagecount; } POSTAMBLE; typedef struct { long postptr; short version; } POSTPOSTAMBLE; typedef int COUNTREGS[10]; typedef struct { long number; long checksum; long scalesize; long designsize; short arealen; short namelen; char name[512]; } FONTDEF; /* Opcodes */ #define SETCHAR 0 /* set_char commands from 0 .. 127 */ #define SET1 128 #define SET2 129 #define SET3 130 #define SET4 131 #define SETRULE 132 #define PUT1 133 #define PUT2 134 #define PUT3 135 #define PUT4 136 #define PUTRULE 137 #define NOP 138 #define BOP 139 #define EOP 140 #define PUSH 141 #define POP 142 #define RIGHT1 143 #define RIGHT2 144 #define RIGHT3 145 #define RIGHT4 146 #define W0 147 #define W1 148 #define W2 149 #define W3 150 #define W4 151 #define X0 152 #define X1 153 #define X2 154 #define X3 155 #define X4 156 #define DOWN1 157 #define DOWN2 158 #define DOWN3 159 #define DOWN4 160 #define Y0 161 #define Y1 162 #define Y2 163 #define Y3 164 #define Y4 165 #define Z0 166 #define Z1 167 #define Z2 168 #define Z3 169 #define Z4 170 #define FNTNUM 171 /* fnt_num_0 .. fnt_num_63 is 171 to 234 */ #define FNT1 235 #define FNT2 236 #define FNT3 237 #define FNT4 238 #define XXX1 239 #define XXX2 240 #define XXX3 241 #define XXX4 242 #define FNTDEF1 243 #define FNTDEF2 244 #define FNTDEF3 245 #define FNTDEF4 246 #define PRE 247 #define POST 248 #define POSTPOST 249 #define UNDEF 250 /* 250 .. 255 are undefined opcodes */ #define DVIPAD 223 SHAR_EOF fi # end of overwriting check echo shar: extracting "'fontcap.c'" '(2813 characters)' if test -f 'fontcap.c' then echo shar: will not over-write existing file "'fontcap.c'" else cat << \SHAR_EOF > 'fontcap.c' /* fontcap.c Samuel W. Bent 8/4/84 */ /* Utilities for the font database file, pxlcap and lncap */ #include <stdio.h> #include <strings.h> #include "paths.h" #include "fontcap.h" #include "dimen.h" #include "utilities.h" match_pxlfile(name,size, pxlname) char *name; int size; char *pxlname; { int len, trymag, bestmatch, bestmag; char *s; char line[MAXLINELENGTH+1]; sprintf(pxlname, "%s.%dpxl", name,size); /* Set default name */ len = strlen(name); /* But try to find the real font */ GotoByte(0); /* Should be reading "pxlcap" */ for (;;) { if (getline(line,MAXLINELENGTH)<=0) return; /* give up if EOF */ if (strncmp(name,line,len)==0) break; /* found the right name */ }; s = line; /* now look for mag closest to size */ bestmatch = MAXINT; bestmag = size; for (;;) { s = index(s,':'); if (s==NULL || *s++=='\\') { /* end of the line, get another */ if (getline(line,MAXLINELENGTH)<=0) break; s = line; if (*s!='\t' && *s!=' ') break; /* end of entry for this name */ continue; }; trymag = atoi(s); /* compare mag with best match */ if (trymag==0) continue; if (abs(size-trymag)<bestmatch) { bestmatch = abs(size-trymag); bestmag = trymag; }; }; sprintf(pxlname, "%s.%dpxl", name,bestmag); } match_lnfile(name,size, lnname) char *name; int size; char *lnname; { int len, trymag, bestmatch, bestmag; char *s; char line[MAXLINELENGTH+1]; sprintf(lnname, "%s.%dln", name,size); /* Set default name */ len = strlen(name); /* But try to find the real font */ GotoByte(0); /* Should be reading "lncap" */ for (;;) { if (getline(line,MAXLINELENGTH)<=0) return; /* give up if EOF */ if (strncmp(name,line,len)==0) break; /* found the right name */ }; s = line; /* now look for mag closest to size */ bestmatch = MAXINT; bestmag = size; for (;;) { s = index(s,':'); if (s==NULL || *s++=='\\') { /* end of the line, get another */ if (getline(line,MAXLINELENGTH)<=0) break; s = line; if (*s!='\t' && *s!=' ') break; /* end of entry for this name */ continue; }; trymag = atoi(s); /* compare mag with best match */ if (trymag==0) continue; if (abs(size-trymag)<bestmatch) { bestmatch = abs(size-trymag); bestmag = trymag; }; }; sprintf(lnname, "%s.%dln", name,bestmag); } make_lnname(pxlname, lnname) char *pxlname, *lnname; { char *s; strcpy(lnname,pxlname); s = rindex(lnname,'p'); if (s!=NULL && strcmp(s,"pxl")==0) { lnname[strlen(lnname)-3]='\0'; }; strcat(lnname,"ln"); } make_pxlname(lnname, pxlname) char *lnname, *pxlname; { char *s; strcpy(pxlname,lnname); s = rindex(pxlname,'l'); if (s!=NULL && strcmp(s,"ln")==0) { pxlname[strlen(pxlname)-2]='\0'; ;} strcat(pxlname,"pxl"); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'fontcap.h'" '(144 characters)' if test -f 'fontcap.h' then echo shar: will not over-write existing file "'fontcap.h'" else cat << \SHAR_EOF > 'fontcap.h' /* fontcap.h Samuel W. Bent 8/5/84 */ /* Definitions for programs that use the font databases, pxlcap and lncap */ #define MAXINT 2147483647 SHAR_EOF fi # end of overwriting check echo shar: extracting "'prtex'" '(1446 characters)' if test -f 'prtex' then echo shar: will not over-write existing file "'prtex'" else cat << \SHAR_EOF > 'prtex' #! /bin/csh -f # print dvi, version 2 files--Richard Furuta, 4/6/83 # modified to work with spooler -- Samuel Bent 5/11/84 umask 0 set flags=() noglob set destdir=(/usr/local) unset q unset s unset t unset v set hbuf=(-h) # rotate the output by default set dest = ln # send to ln01 by default top: if ($#argv > 0) then switch ($argv[1]) case -m: shift argv set flags = ($flags -m $argv[1]) shift argv goto top case -h: set hbuf = (-h) shift argv goto top case -q: set q set s shift argv goto top case -s: set s shift argv goto top case -v: set hbuf = () shift argv goto top case -Pln: case -Pln01: set dest = ln shift argv goto top case -Pva: case -Pvarian: case -Pvar: case -Pv: set dest = va shift argv goto top case -*: set flags = ($flags $argv[1]) shift argv goto top endsw endif if ($#argv == 0) then set argv = ( - ) endif foreach fname ($argv) if ($fname == - ) then set jobname = stdin else set jobname = $fname if (-e $fname.dvi) then set fname = $fname.dvi endif endif if ($dest == ln) then lpr -d -Pln -J$jobname $fname else if ($?q) then ${destdir}/dvi2rmver $hbuf $flags < $fname > /dev/null else ${destdir}/dvi2rmver $hbuf $flags < $fname | lpr -d -Pva -J$jobname endif endif if ($status == 0 && $?s == 0 && $fname != - ) then rm $fname endif end SHAR_EOF fi # end of overwriting check echo shar: extracting "'makepxlentry.c'" '(5637 characters)' if test -f 'makepxlentry.c' then echo shar: will not over-write existing file "'makepxlentry.c'" else cat << \SHAR_EOF > 'makepxlentry.c' /* makepxlentry - create pxlfont database entries Sam Bent 5/25/84 */ /* This program opens each argument (assuming each to be a PXL-format * raster file), reads the PXL directory information to find the x- and * y-offsets, and forms an entry suitable for the pxlfont database, 'pxlcap'. * It sends the results to stdout. The intended use is * makepxlentry *.pxl > /usr/lib/tex/fonts/pxlcap * * A typical entry in the database, illustrating its format is * amr10|Ten point text roman:\ * :1000x1y21:1200x3y25: * meaning a font named 'amr10' (with a comment describing it) exists * at magnification 1 with maximum x-offset 1 and y-offset 21, and at * magnification 1.2 with maximum x-offset 3 and y-offset 25. * * Options: * -i (interactive) Ask user for a comment for each font. * -v (verbose) Print progress reports on stderr. */ /* #define DEBUG */ #include <stdio.h> #include "utilities.h" #include "pxlfile.h" char PGM_NAME[] = "makepxlentry"; #define MAXNAMELENGTH 100 /* length of file names */ #define MAXENTRIES 5 /* number of database entries per line */ #define NEWLINE "\\\n\t:" /* what to print to start a new line */ #define DEF_COMMENT "A font" /* default comment for data base */ #ifndef MAXLINELENGTH #define MAXLINELENGTH 100 /* length of input line */ #endif \f /* Data structures */ char fontname[MAXNAMELENGTH]; /* name of current font */ char *filename; /* name of current file */ int max_xoffset, /* largest x-offset of font (in pixels) */ max_yoffset, /* largest y-offset of font (in pixels) */ magnification, /* current font's magnification */ iflg, /* interactive? */ vflg; /* verbose? */ int p; /* PXL file's index */ int inIndex, outIndex; /* Indices for stdin and stdout */ \f /* Main loop. Open each file, read its directory, and form an entry. */ main (argc, argv) int argc; char **argv; { char * option; InitializeFiles(&inIndex,&outIndex); while (--argc>0) { filename = *++argv; if (filename[0]=='-') { /* Really an option! */ option = filename; while (*++option != '\0') { switch (*option) { case 'i': ++iflg; break; case 'v': ++vflg; break; default: Error(0,"Unknown switch: %s",filename); break; }; }; continue; /* so don't open any files */ }; if ((p=open_PXL_file(filename))<0) continue; if (set_fontname_and_mag(filename) != 0) continue; find_max_offsets(p); print_entry(); close_PXL_file(p); }; printf("\n"); } /* Try to open a PXL file. * If it looks OK, return its index. * If we can't open it, or it looks wrong, return something <0. */ open_PXL_file(filename) char *filename; { int p; long dirptr, end; if ((p=OpenFile(filename,"r"))<0) { /* try to open file */ Error(0,"Can't open %s",filename); return(p); }; ReadFromFile(p); GotoByte(0); if (Get4Byte()!=PXLMAGIC) { /* check that 1st word is 1001 */ Error(0,"%s is not a PXL file",filename); return(-1); }; GotoEnd(); /* prepare to read last two words */ end = WhereIsRead(); Skip(-8); dirptr = Get4Byte()*4; if (dirptr!=end-517*4) { /* directory pointer should point to Error(0,"%s has bad directory pointer",filename); /* end-517 words */ return(-1); }; if (Get4Byte()!=PXLMAGIC) { /* check that last word is 1001 */ Error(0,"%s is not a PXL file",filename); return(-1); }; GotoByte(dirptr+4); /* position at offset field of first entry */ return(p); /* return index */ } /* Close a PXL file */ close_PXL_file(p) int p; { CloseFile(p); } /* Set fontname and magnification from the name of the font we're looking at */ set_fontname_and_mag(filename) char *filename; { char *s, *t; s=filename; t=fontname; /* copy filename up to the */ while (*s!='\0' && *s!='.') { /* extension `.' into fontname */ *t++ = *s++; }; *t = '\0'; if (*s=='.') ++s; magnification = atoi(s); /* copy extension up to 'pxl' */ if (magnification==0) { /* into magnification */ Error(0,"%s is missing magnification in extension",filename); return(-1); }; if (vflg) fprintf(stderr,"Font %s at magnification %d: ",fontname,magnification); return(0); } /* Search the directory for the maximum x and y offsets. * Assume the file p is positioned at the offset field of the * first entry in the directory. * Set the global variables max_xoffset and max_yoffset. */ find_max_offsets(p) { int i, xoffset, yoffset; ReadFromFile(p); max_xoffset = max_yoffset = 0; for (i=0;i<128;++i) { xoffset = Get2Byte(); /* compare x-offset */ max_xoffset = (xoffset>max_xoffset ? xoffset : max_xoffset); yoffset = Get2Byte(); /* compare y-offset */ max_yoffset = (yoffset>max_yoffset ? yoffset : max_yoffset); Skip(12); /* skip to next entry */ }; if (vflg) fprintf(stderr,"max_xoffset=%d, max_yoffset=%d\n", max_xoffset, max_yoffset); } /* Form an entry for the current PXL file and print it. */ print_entry() { static int entries; static char oldfontname[MAXNAMELENGTH]; char comment[MAXLINELENGTH]; if (strcmp(fontname,oldfontname)!=0) { /* A new font name */ strcpy(comment,DEF_COMMENT); /* default comment */ if (iflg) { /* get a comment from user */ fprintf(stderr,"Comment for font %s: ",fontname); ReadFromFile(inIndex); getline(comment,MAXLINELENGTH); }; strcpy(oldfontname,fontname); printf("\n%s|%s:%s",fontname, comment, NEWLINE); /* start a new line */ entries = 0; }; if (++entries>MAXENTRIES) { /* if line is full, start a new one */ printf("%s",NEWLINE); entries=1; }; printf("%dx%dy%d:",magnification,max_xoffset,max_yoffset); /* print entry */ } SHAR_EOF fi # end of overwriting check echo shar: extracting "'pxlfile.h'" '(939 characters)' if test -f 'pxlfile.h' then echo shar: will not over-write existing file "'pxlfile.h'" else cat << \SHAR_EOF > 'pxlfile.h' /* pxlfile.h Samuel W. Bent 7/17/84 */ /* Common definitions for programs that use PXL files * PXL files store integers in BigEndian order, most significant byte first. */ /* Constants */ #define PXLMAGIC 1001 /* Types */ typedef struct { /* directory entry in pxl file */ short height; /* height of envelope (pixels) */ short width; /* width of envelope (pixels) */ short xoffset; /* x distance from corner to ref point (pxls) */ short yoffset; /* y distance from corner to ref point (pxls) */ long bitp; /* ptr to bitmap (bytes) */ long tfmwidth; /* width (FIXes) */ } PXLCHAR; typedef struct { /* info global to a pxl file */ long checksum; /* checksum (0 means no checksum) */ long magnification; /* magnification factor * 1000 */ long designsize; /* design size (FIXes) */ long directoryptr; /* ptr to directory (bytes) */ } PXLHEADER; SHAR_EOF fi # end of overwriting check echo shar: extracting "'pxlfile.c'" '(1304 characters)' if test -f 'pxlfile.c' then echo shar: will not over-write existing file "'pxlfile.c'" else cat << \SHAR_EOF > 'pxlfile.c' /* pxlfile.c Samuel W. Bent 7/30/84 */ #include <stdio.h> #include "pxlfile.h" #include "dimen.h" get_pxlheader(hp) PXLHEADER *hp; { GotoEnd(); Skip(-20); hp->checksum = Get4Byte(); hp->magnification = Get4Byte(); hp->designsize = Get4Byte(); hp->directoryptr = Get4Byte()*4; /* convert words to bytes */ } get_pxlchar(pchp) PXLCHAR *pchp; { pchp->width = Get2Byte(); pchp->height = Get2Byte(); pchp->xoffset = Get2Byte(); pchp->yoffset = Get2Byte(); pchp->bitp = Get4Byte()*4; /* change words to bytes */ pchp->tfmwidth = Get4Byte(); } get_pxldirectory(dir) PXLCHAR dir[]; { int ch; for (ch=0;ch<0200;++ch) { get_pxlchar(&dir[ch]); }; } /* Printing routines (for debugging) */ dump_pxlheader(hp) PXLHEADER *hp; { fprintf(stderr,"cksum=%d mag=%d dsize=%-4.3f dirp=%u\n", hp->checksum,hp->magnification, FIXtoPT(hp->designsize), hp->directoryptr); } dump_pxlchar(pchp) PXLCHAR *pchp; { fprintf(stderr,"h=%d w=%d xoff=%d yoff=%d addr=%u tfw=%-4.3f\n", pchp->height,pchp->width,pchp->xoffset,pchp->yoffset, pchp->bitp, DUtoDS(pchp->tfmwidth) ); } dump_pxldir(dir) PXLCHAR dir[]; { int ch; for (ch=0;ch<128;++ch) { fprintf(stderr,"0%o-%c: ",ch, (040<ch && ch<0177)? ch : '?'); dump_pxlchar(&dir[ch]); }; } SHAR_EOF fi # end of overwriting check echo shar: extracting "'utilities.c'" '(5407 characters)' if test -f 'utilities.c' then echo shar: will not over-write existing file "'utilities.c'" else cat << \SHAR_EOF > 'utilities.c' /* Utilities for DVI and PXL programs */ /* Calling programs must define: * PGM_NAME */ #include <stdio.h> #include "utilities.h" #define MAXFILES 20 /* hope that's enough */ static FILE * fp[MAXFILES]; /* convert from index to file ptr */ static int nrfiles; /* how many files in the table */ static char FNAME[MAXFILES][50];/* name of each file */ static FILE * READfp; /* current file to read */ static int READindex= -1; /* its index in the table */ static FILE * WRITEfp; /* current file to write */ static int WRITEindex= -1; /* its index in the table */ static long bytepos[MAXFILES]; /* byte positions of all files */ static long READpos; /* byte position of current read file */ static long WRITEpos; /* byte position of current write file */ /* Initialize the file interface with stdin and stdout */ InitializeFiles(inIndex,outIndex) int *inIndex, *outIndex; { int index; index=Insert(stdin); bytepos[index]=0; strcpy(FNAME[index],"stdin"); *inIndex = index; index = Insert(stdout); bytepos[index]=0; strcpy(FNAME[index],"stdout"); *outIndex = index; } /* Open a new file and return its index. * Return something <0 if anything goes wrong. */ OpenFile(filename,mode) char * filename; char * mode; { FILE * newfp; int index; if ((newfp=fopen(filename,mode))==NULL) { /* try to open the file */ return(-1); }; if ((index=Insert(newfp)) < 0) return (-1); /* insert it in table */ bytepos[index] = 0; strncpy(FNAME[index],filename,50); return(index); } /* Close a file */ CloseFile(index) int index; { fclose(fp[index]); Delete(index); } /* Switch current read file */ ReadFromFile(index) int index; { if (READindex==index) return; /* if already reading it, do nothing */ bytepos[READindex]=READpos; /* save position of old file */ READindex = index; READfp = fp[READindex]; READpos = bytepos[READindex]; } /* Switch current write file */ WriteToFile(index) int index; { if (WRITEindex==index) return; bytepos[WRITEindex]=WRITEpos; WRITEindex = index; WRITEfp = fp[WRITEindex]; WRITEpos = bytepos[WRITEindex]; } /* Return position of read file */ long WhereIsRead() { return(READpos); } /* Return position of write file */ long WhereIsWrite() { return(WRITEpos); } GetByte() { int i; READpos++; i = getc (READfp); if (i == EOF) Error (2,"EOF encountered unexpectedly in %s", FNAME[READindex]); return (i); } /* Move to given position in read file */ GotoByte (n) long n; { fseek (READfp, n, 0); READpos = n; } /* Skip n bytes in read file */ Skip (n) int n; { GotoByte(READpos+n); } /* Go to the end of the current read file */ GotoEnd() { fseek(READfp,0L,2); /* read to end of file */ READpos = ftell(READfp); } /* take next two bytes and return as integer */ Get2Byte () { int n; n = 0; n |= GetByte (); n <<= 8; n |= GetByte (); n <<= 16; n >>= 16; /* sign extend */ return (n); } /* take next three bytes and return as integer */ Get3Byte () { int n; n = 0; n |= GetByte (); n <<= 8; n |= GetByte (); n <<= 8; n |= GetByte (); n <<= 8; n >>= 8; /* sign extend */ return (n); } /* take next four bytes and return as integer */ Get4Byte () { int n; n = 0; n |= GetByte (); n <<= 8; n |= GetByte (); n <<= 8; n |= GetByte (); n <<= 8; n |= GetByte (); return (n); } PutByte(b) int b; { putc(b&0377,WRITEfp); WRITEpos++; } Put2Byte(x) int x; { PutByte( x>>8 ); PutByte( x ); } Put3Byte(x) int x; { PutByte( x>>16 ); PutByte( x>>8 ); PutByte( x ); } Put4Byte(x) int x; { PutByte( x>>24 ); PutByte( x>>16 ); PutByte( x>>8 ); PutByte( x ); } /* Insert a file pointer into table, if not already there */ static Insert(newfp) FILE * newfp; { int i, index; index = nrfiles; for (i=0;i<nrfiles;++i) { if (fp[i]==newfp) { index=i; break; }; if (fp[i]==NULL) { index = i; }; }; if (index==nrfiles) { if ((index=nrfiles++)>=MAXFILES) { Error(2,"Too many open files"); }; }; fp[index] = newfp; return(index); } /* Remove an entry from file table */ static Delete(index) int index; { fp[index]=NULL; } Left (word) int word; { int temp; temp = word >> 16; if (temp & 0100000) temp = temp | ~0177777; /* sign extend if negative */ return (temp); } Right (word) int word; { int temp; temp = word & 0177777; if (temp & 0100000) temp = temp | ~0177777; /* sign extend if negative */ return (temp); } Pack(l,r) int l,r; { return( ((l<<16) & ~0177777) | (r & 0177777) ); } Error (code, format, a1, a2, a3, a4, a5, a6, a7, a8) int code; char *format; /* Print error message. Exit if code<>0. */ { fprintf(stderr,"%s: ",PGM_NAME); fprintf(stderr,format, a1,a2,a3,a4,a5,a6,a7,a8); fprintf(stderr,"\n"); if (code!=0) exit (code); } /* Read a line from current file */ getline(s, lim) char *s; int lim; { int c; int len; while (--lim>0 && (c=getc(READfp))!=EOF && c!='\n') { *s++ = c; ++len; }; if (lim==0) { --s; --len; }; *s = '\0'; if (c==EOF) return(-1); else return(len); } putline(format, a1,a2,a3,a4,a5,a6,a7,a8) char *format; { fprintf(WRITEfp, format, a1,a2,a3,a4,a5,a6,a7,a8); } Flush() { fflush(WRITEfp); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'utilities.h'" '(1993 characters)' if test -f 'utilities.h' then echo shar: will not over-write existing file "'utilities.h'" else cat << \SHAR_EOF > 'utilities.h' /* utilities.h Samuel W. Bent 7/30/84 */ /* Utilities for reading, writing, and manipulating files in the TeX * family (DVI, PXL, etc.). All integers are stored in BigEndian order, * that is with the most significant byte first. */ extern char PGM_NAME[]; #define MAXLINELENGTH 200 /* length of input lines */ InitializeFiles(); /* args=(&inIndex,&outIndex). Initialize file system, set indices for stdin and stdout */ OpenFile(); /* args=(filename,mode), return index for new file, or <0 if error */ CloseFile(); /* args=(index) */ ReadFromFile(); /* args=(index), set current read file */ WriteToFile(); /* args=(index), set current write file */ long WhereIsRead(); /* return byte pos of read file */ long WhereIsWrite(); /* return byte pos of write file */ GetByte(); /* return next byte of read file */ Get2Byte(); /* return integer in next 2 bytes of read file */ Get3Byte(); /* return integer in next 3 bytes of read file */ Get4Byte(); /* return integer in next 4 bytes of read file */ GotoByte(); /* args=(pos). Set read file to position pos */ GotoEnd(); /* Move to end of read file */ Skip(); /* args=(n), skip n bytes (pos or neg) in read file */ PutByte(); /* args=(b). Append byte b to write file */ Put2Byte(); /* args=(w). Append integer w to write file, using 2 bytes */ Put3Byte(); /* args=(w). Append integer w to write file, using 3 bytes */ Put4Byte(); /* args=(w). Append integer w to write file, using 4 bytes */ Error(); /* args=(code,format,a1,...), print formatted error message with components a1,a2,... Exit with completion code, if code is not 0 */ getline(); /* args=(s,lim), read line from stdin into s, but no more than lim chars */ Left(); /* args=(w), return signed integer in upper 16 bits of w */ Right(); /* args=(w), return signed integer in lower 16 bits of w */ Pack(); /* args=(l,r), pack signed integers into a word */ #define LEFT(w) ( (w>>16)&0xFFFF ) /* unsigned */ #define RIGHT(w) ( w&0xFFFF ) /* unsigned */ SHAR_EOF fi # end of overwriting check echo shar: extracting "'paths.h'" '(347 characters)' if test -f 'paths.h' then echo shar: will not over-write existing file "'paths.h'" else cat << \SHAR_EOF > 'paths.h' #define LN01DEVICE "/dev/lp1" #define TFMPATH "/usr/lib/tex" #define PXLPATH "/usr/public/pxlfonts" #define LNPATH "/usr/public/pxlfonts" #define PXLCAP "/usr/lib/tex/fonts/pxlcap" #define LNCAP "/usr/lib/tex/fonts/lncap" #define FONTLOG "/usr/spool/ln01/currfonts" #define DEBUG_FONTLOG "/tmp/currfonts" #define TEMPFILE "/usr/tmp/dvipXXXXXX" SHAR_EOF fi # end of overwriting check echo shar: extracting "'HISTORY'" '(1807 characters)' if test -f 'HISTORY' then echo shar: will not over-write existing file "'HISTORY'" else cat << \SHAR_EOF > 'HISTORY' August, 1984: Implemented DVI filter for LN01, revised DVI filter for varian. 10/9/84 Released first version to Furuta. 10/20/84 Reworked font loading code to use lookahead (to find Belady optimal working set). 11/2/84 Bug: When a font is missing from LNCAP, I was supposed to substitute a default font. I wrote make_pxlname(pxlname,lnname) instead of make_pxlname(lnname,pxlname); result was error --- "Can't open amr8.1643pxl". Also changed fontlog code to avoid rewriting the log when debugging. 12/4/84 Changed lndvif to check for preamble before beginning. Now it will print a summary page if you spool a non-DVI file, telling you that you blew it. (Before it just logged an error in the error file.) 1/22/85 Changed the code for loading fonts to completely factor out the decision of which fonts to load. Then, added a different algorithm for selecting fonts that's appropriate for the LN01s. It uses all the font memory and loads only the new fonts needed on each page. Also, changed font loads so they didn't issue a RESET; this makes the number in the led display on the LN01s correspond to the page number. 1/23/85 Changed ditroff filter (ln01f and dln01) to check the font log and load troff fonts if necessary. Then, removed call to /etc/ln-fload from lndvif. The DVI filter no longer reloads ditroff's fonts. 1/29/85 Fixed bug whereby fontlog wasn't getting updated after reloading, if no appends followed. This caused subsequent troff jobs to mistakenly believe their fonts were present, and ended up spitting blank paper all over the floor. 1/31/85 Fixed bugs: define_font wasn't closing the PXL file, eventually leading to too many open files; open_font_log tried to close fontlog, even if it wasn't open. Added information to error messages dealing with loading fonts. SHAR_EOF fi # end of overwriting check echo shar: extracting "'dviedit.c'" '(20791 characters)' if test -f 'dviedit.c' then echo shar: will not over-write existing file "'dviedit.c'" else cat << \SHAR_EOF > 'dviedit.c' /* dviedit.c 11/24/84 Samuel W. Bent */ /* This program does some simple editing of DVI files. It is intended to * be used as a filter before spooling the DVI file with lpr. * Usage is: dviedit [flags] file1 file2 ... * * Flags and their meanings: * * -p <page specifier> Extract specified pages. A <page specifier> is * a sequence of up to 10 <count specifiers> separated * by periods; it selects pages whose 10 \counts match * the respective specifiers. A <count specifier> is * either a single number like 4, a range like 1-10, * a sequence of these two types separated by commas, * or empty. An empty specifier matches any value; * a non-empty one matches a value in any of the given * ranges or equal to any of the given numbers. The * symbol X (or x) can be used to give "half-ranges", * as in 1-x or x-10. * -m <magnification> Change the overall magnification of the * DVI file to <magnification>/1000. * -g Merge Tektronix graphic files given by \special's. * -o <filename> Send output to named file. * -i Interactively ask user what to do. * * The selected pages from all the named files are concatenated into one * DVI file. The output is sent to stdout unless a "-o" argument appears. * The input files must all be compatible with the first one, in the sense that * their numerator and denominator paramaters (from the preamble) must agree, * and they may not use the same font number for different fonts. */ /* #define DEBUG /* Also defined in Makefile */ #include <stdio.h> extern char *mktemp(); #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #include <strings.h> #include "paths.h" #include "dviedit.h" #include "utilities.h" #include "dimen.h" #include "dvifile.h" char PGM_NAME[] = "dviedit"; \f /* Data structures */ int dviindex; /* index for dvi file */ int pxlcapindex; /* index for PXL file database */ int curpage; /* sequence number of current page */ PREAMBLE preamble; /* preamble of current dvi file */ POSTAMBLE postamble; /* postamble */ POSTPOSTAMBLE postpostamble; /* postpostamble */ bool inpostamble; /* true when reading postamble */ long f, h,v, w,x, y,z; /* DVI registers: font, position, horiz space amounts, vert space amounts */ STACKITEM stack[MAXSTACKDEPTH]; /* stack for registers */ int top=0; /* index of first free position in stack */ FONT *fontp; /* pointer to current font structure */ FONT *fcache[CACHEFONTS]; /* buckets for first few fonts */ FONT *fontptrarray[TABLEFONTS]; /* unordered table for remaining fonts */ int fpalen; /* first free slot in fontptrarray */ FONT *allfonts[MAX_FONTS]; /* list of all fonts */ int fonts; /* number of fonts */ int Vflg; /* Print progress reports? */ FILE *Vfp = NULL; /* where to print progress reports */ char *Vfilename = NULL; /* where to print progress reports */ #ifdef DEBUG int dflg; /* debug level */ #endif PAGERECORD pagerec[MAXPAGERECS]; /* page specifiers */ int pagerecs=0; /* number of page specifiers */ int gflg; /* merge graphics files? */ int iflg; /* interactive? */ int cflg; /* concatenate dvi files? */ int magarg; /* new global magnification */ char *outputarg; /* file for output */ char *filename; /* name of currrent input file */ int stdinindex; /* index of stdin */ int stdoutindex; /* index of stdout */ int outindex; /* index of output file */ int postindex; /* index of postamble file */ char *postfile; /* name of postamble file */ int nullindex; /* index of /dev/null */ bool firstfile=true; /* true while reading the first file to catenate */ PREAMBLE master_pre; /* preamble for output */ POSTAMBLE master_post; /* postamble for output */ POSTPOSTAMBLE master_postpost; /* postpostamble for output */ long lastpageptr= -1; /* address of last page in output file */ char answer[MAXLINELEN]; /* user's answer to interactive question */ \f main(argc,argv) int argc; char **argv; { int i; InitializeFiles(&stdinindex, &stdoutindex); postfile = mktemp(TEMPFILE); postindex = OpenFile(postfile,"w"); if (postindex<0) Error(2,"Can't open temp file %s", postfile); nullindex = OpenFile("/dev/null","w"); if (nullindex<0) Error(2,"Can't open /dev/null"); Initialize_options(); while (--argc) { if (**++argv == '-') set_option(&argc,&argv); else edit_dvifile(*argv); }; cleanup(); exit(0); } \f Initialize_options() { magarg = 0; outputarg = NULL; Vfp = stderr; Vfilename = NULL; } set_option(argcp,argvp) int *argcp; char ***argvp; { char *pagearg; int count, sign, value; PAGERECORD *prp; char *s; switch ((*argvp)[0][1]) { case 'V': /* verbose -- tell file what's happening */ ++Vflg; if ((*argvp)[0][2]=='\0') Vfp = stderr; else { Vfilename = &((*argvp)[0][2]); Vfp = fopen(Vfilename,"w"); if (Vfp==NULL) Error(2,"Can't open %s", Vfilename); }; break; #ifdef DEBUG case 'd': /* debug */ ++Vflg; /* implies V */ if ((*argvp)[0][2]=='\0') dflg = EVERYAMBLE; else sscanf( &((*argvp)[0][2]), "%d", &dflg); break; #endif case 'i': /* interactive */ ++iflg; break; case 'g': /* merge graphics files */ ++gflg; break; case 'c': /* concatenate files */ ++cflg; break; case 'm': /* change global magnification */ if ((*argvp)[0][2]=='\0') { if (*argcp>1) { --*argcp; sscanf( *++(*argvp), "%d", &magarg); }; } else { sscanf( &((*argvp)[0][2]), "%d", &magarg); }; break; case 'o': /* send output to file */ if ((*argvp)[0][2]=='\0') { if (*argcp > 1) { --*argcp; s = *++(*argvp); }; } else { s = &((*argvp)[0][2]); }; if (firstfile) outputarg = s; else fprintf(stderr,"The -o option must precede the file names.\n"); break; case 'p': if ((*argvp)[0][2]=='\0') { if (*argcp > 1) { --*argcp; pagearg = *++(*argvp); }; } else { pagearg = &((*argvp)[0][2]); }; count = 0; prp = &pagerec[pagerecs]; while (true) { if (*pagearg=='.') { /* empty count specifier */ ++count; ++pagearg; continue; }; prp->count = count; /* non-empty --- fill in count */ if (*pagearg=='x' || *pagearg=='X') { /* minimum low value */ prp->low = MININT; ++pagearg; } else { /* explicit low value */ sign = 1; if (*pagearg=='-') { sign = -1; ++pagearg; }; value = 0; while (isdigit(*pagearg)) value = 10*value + (*pagearg++)-'0'; prp->low = sign*value; }; if (*pagearg!='-') prp->high = prp->low; /* no high value */ else if (*++pagearg=='x' || *pagearg=='X') { /* max high value */ prp->high = MAXINT; ++pagearg; } else { /* explicit high value */ sign = 1; if (*pagearg=='-') { sign = -1; ++pagearg; }; value = 0; while (isdigit(*pagearg)) value = 10*value + (*pagearg++)-'0'; prp->high = sign*value; }; prp = &pagerec[++pagerecs]; /* move to new record */ if (*pagearg=='.') ++count; if (*pagearg=='\0') break; if (*pagearg!='.' && *pagearg!=',') Error(2, "Bad page specifier: %s", **argvp); ++pagearg; }; prp->count = -1; /* end with dummy record */ prp->low = prp->high = 0; ++pagerecs; break; default: Error(0, "Unknown option: %s", **argvp); break; } } \f dump_options() { int i; fprintf(stderr,"dflg=%d gflg=%d iflg=%d cflg=%d mag=%d output=%s\n", dflg, gflg, iflg, cflg, magarg, outputarg); if (pagerecs>0) { fprintf(stderr,"Pages: %3d %3d %3d\n", pagerec[0].count, pagerec[0].low, pagerec[0].high); for (i=1;i<pagerecs-1;i++) { fprintf(stderr," %3d %3d %3d\n", pagerec[i].count, pagerec[i].low, pagerec[i].high); }; }; } \f edit_dvifile(filearg) char *filearg; { int cmd; long firstpage; filename = filearg; if (pagerecs>0) --pagerecs; /* mark end of page specs */ pagerec[pagerecs].count = -1; pagerec[pagerecs++].low = -1; dviindex = OpenFile(filename,"r"); /* open file */ if (dviindex<0) { Error(2,"Can't open %s", filename); }; ReadFromFile(dviindex); GotoByte(0); /* read preamble */ do cmd = GetByte(); while (cmd==NOP); if (cmd!=PRE) Error(2,"%s doesn't start with preamble", filename); get_preamble(&preamble); copy_preamble(&preamble); /* initialize output */ firstpage = WhereIsRead(); preload_fonts(); /* get fonts from postamble */ GotoByte(firstpage); do { /* then read the rest of the file */ cmd = GetByte(); #ifdef DEBUG if (dflg>=EVERYCMD) fprintf(Vfp,"cmd(%d)=%d ", WhereIsRead()-1,cmd); #endif switch (cmd) { case BOP: ++curpage; read_page(); break; case NOP: break; case FNTDEF1: define_font(1,false); break; case FNTDEF2: define_font(2,false); break; case FNTDEF3: define_font(3,false); break; case FNTDEF4: define_font(4,false); break; case POST: break; default: Error(2,"Bad command (%o) at byte %d", cmd, WhereIsRead()-1); break; }; } while (cmd!=POST); inpostamble = true; /* read postamble */ get_postamble(&postamble); copy_postamble(&postamble); #ifdef DEBUG if (dflg>=EVERYAMBLE) dump_postamble(Vfp,&postamble); #endif do { /* read until postpostamble */ cmd=GetByte(); switch (cmd) { case NOP: break; case FNTDEF1: define_font(1,false); break; case FNTDEF2: define_font(2,false); break; case FNTDEF3: define_font(3,false); break; case FNTDEF4: define_font(4,false); break; case POSTPOST: get_postpostamble(&postpostamble); #ifdef DEBUG if (dflg>=EVERYAMBLE) dump_postpostamble(Vfp,&postpostamble); #endif break; default: Error(2,"Bad command (%o) at byte %d", cmd, WhereIsRead()-1); break; }; } while (cmd!=POSTPOST); pagerecs = 0; /* reset page specs */ firstfile = false; /* finished with first file */ } \f read_page() { int cmd; long prevpageptr; int curcount, curval; bool allcountsOK, curcountOK; int i; PAGERECORD *prp; long tmp; COUNTREGS cr; /* count registers */ #ifdef DEBUG if (dflg>=EVERYPAGE) fprintf(Vfp,"Page %d...\n",curpage); #endif get_counts(cr); /* read count registers */ prevpageptr = Get4Byte(); /* remember address of previous page */ allcountsOK = curcountOK = true; /* see if this page was selected */ curcount = -2; /* first count is a new count */ for (i=0;;++i) { /* for each page spec ... */ prp = &pagerec[i]; if (prp->count != curcount) { /* if new count, see if last matched */ curcount = prp->count; allcountsOK = allcountsOK && curcountOK; curcountOK = false; }; if (prp->count != -1) { /* see if present count matches */ curval = cr[curcount]; if (prp->low<=curval && curval<=prp->high) { curcountOK = true; }; } else { /* end of clause; see if all match */ if (allcountsOK || prp->low==-1) break; allcountsOK = curcountOK = true; /* prepare for next clause */ curcount = -2; }; }; if (iflg>0) { /* ask user whether to copy page */ ReadFromFile(stdinindex); fprintf(stderr,"\nPage "); display_counts(cr,stderr); fprintf(stderr," (%c) ? ", allcountsOK? 'y' : 'n'); getline(answer,MAXLINELEN); if (*answer=='y' || *answer=='Y') allcountsOK=true; if (*answer=='n' || *answer=='N') allcountsOK=false; if (*answer=='s' || *answer=='S') iflg=0; ReadFromFile(dviindex); }; if (allcountsOK) { /* prepare to copy page */ WriteToFile(outindex); tmp = lastpageptr; lastpageptr = WhereIsWrite(); PutByte(BOP); /* write page header */ write_counts(cr); Put4Byte(tmp); master_post.pagecount++; /* increment number of pages */ if (Vflg) { fprintf(Vfp," ["); display_counts(cr,Vfp); }; } else { /* or copy it to /dev/null */ WriteToFile(nullindex); }; copy_page(); if (allcountsOK) { if (Vflg) fprintf(Vfp,"]"); }; return(prevpageptr); } display_counts(cr,fp) COUNTREGS cr; FILE *fp; { int i,k; k=0; for (i=0;i<10;++i) { if (cr[i]!=0) { for (++k;k<i;++k) fprintf(fp,"."); fprintf(fp,"%d",cr[i]); k=i; }; }; } copy_page() { int cmd; do { /* Command interpreter */ cmd = GetByte(); #ifdef DEBUG if (dflg>=EVERYCMD) fprintf(Vfp, "cmd(%d)=%o ",WhereIsRead()-1,cmd); #endif if (cmd<FNTDEF1 || FNTDEF4<cmd) PutByte(cmd); /* copy the command */ if (SETCHAR<=cmd && cmd<SET1) { continue; }; if (FNTNUM<=cmd && cmd<FNT1) { changefont(cmd-FNTNUM,false); continue; }; switch (cmd) { case SET1: PutByte(GetByte()); break; case SET2: Put2Byte(Get2Byte()); break; case SET3: Put3Byte(Get3Byte()); break; case SET4: Put4Byte(Get4Byte()); break; case SETRULE: Put4Byte(Get4Byte()); Put4Byte(Get4Byte()); break; case PUT1: PutByte(GetByte()); break; case PUT2: Put2Byte(Get2Byte()); break; case PUT3: Put3Byte(Get3Byte()); break; case PUT4: Put4Byte(Get4Byte()); break; case PUTRULE: Put4Byte(Get4Byte()); Put4Byte(Get4Byte()); break; case NOP: break; case BOP: Error(2,"BOP in middle of page at byte %d", WhereIsRead()-1); break; case EOP: break; case PUSH: break; case POP: break; case RIGHT1: PutByte(GetByte()); break; case RIGHT2: Put2Byte(Get2Byte()); break; case RIGHT3: Put3Byte(Get3Byte()); break; case RIGHT4: Put4Byte(Get4Byte()); break; case W0: break; case W1: PutByte(GetByte()); break; case W2: Put2Byte(Get2Byte()); break; case W3: Put3Byte(Get3Byte()); break; case W4: Put4Byte(Get4Byte()); break; case X0: break; case X1: PutByte(GetByte()); break; case X2: Put2Byte(Get2Byte()); break; case X3: Put3Byte(Get3Byte()); break; case X4: Put4Byte(Get4Byte()); break; case DOWN1: PutByte(GetByte()); break; case DOWN2: Put2Byte(Get2Byte()); break; case DOWN3: Put3Byte(Get3Byte()); break; case DOWN4: Put4Byte(Get4Byte()); break; case Y0: break; case Y1: PutByte(GetByte()); break; case Y2: Put2Byte(Get2Byte()); break; case Y3: Put3Byte(Get3Byte()); break; case Y4: Put4Byte(Get4Byte()); break; case Z0: break; case Z1: PutByte(GetByte()); break; case Z2: Put2Byte(Get2Byte()); break; case Z3: Put3Byte(Get3Byte()); break; case Z4: Put4Byte(Get4Byte()); break; case FNT1: changefont(GetByte(),true); break; case FNT2: changefont(Get2Byte(),true); break; case FNT3: changefont(Get3Byte(),true); break; case FNT4: changefont(Get4Byte(),true); break; case XXX1: special(GetByte()); break; case XXX2: special(Get2Byte()); break; case XXX3: special(Get3Byte()); break; case XXX4: special(Get4Byte()); break; case FNTDEF1: define_font(1,false); break; case FNTDEF2: define_font(2,false); break; case FNTDEF3: define_font(3,false); break; case FNTDEF4: define_font(4,false); break; case PRE: Error(2,"PRE in middle of page at byte %d", WhereIsRead()-1); break; case POST: Error(2,"POST in middle of page at byte %d", WhereIsRead()-1); break; case POSTPOST: Error(2,"POSTPOST in middle of page at byte %d", WhereIsRead()-1); break; default: Error(2,"Unknown opcode %o at byte %d", cmd,WhereIsRead()-1); break; }; } while (cmd != EOP); } \f special(length) int length; { int i; for (i=0;i<length;++i) { PutByte(GetByte()); }; } \f preload_fonts() { int cmd; int i,j; FONT *fp; ReadFromFile(dviindex); GotoFontdefs(); do { cmd = GetByte(); switch (cmd) { case FNTDEF1: define_font(1,true); break; case FNTDEF2: define_font(2,true); break; case FNTDEF3: define_font(3,true); break; case FNTDEF4: define_font(4,true); break; case NOP: break; case POSTPOST: break; default: Error(2,"Bad command (%o) at byte %d, in postamble", cmd, WhereIsRead()-1); break; }; } while (cmd!=POSTPOST); } FONT *find_fontp(fontno) int fontno; { int i; FONT *fontp; if (fontno<CACHEFONTS) fontp = fcache[fontno]; else { for (i=0;i<fpalen;++i) { if (fontptrarray[i]->number == fontno) { fontp = fontptrarray[i]; break; }; }; if (i>=fpalen) { fontp = NULL; }; }; return (fontp); } define_font(fnlen,really_define) int fnlen; bool really_define; { FONTDEF fd; FONT *fp; get_fontdef(&fd, fnlen); #ifdef DEBUG if (dflg>=EVERYFONTDEF) dump_fontdef(Vfp,&fd); #endif if (!really_define) return; if ((fp=find_fontp(fd.number)) != NULL) { /* if this is an old font */ if (strcmp(fp->name,fd.name)!=0 || fp->size!=fd.scalesize) { /* check for consistency */ Error(2,"Duplicate font number %d -- %s and %s", fd.number, fp->name, fd.name); }; return; } WriteToFile(postindex); /* write new fonts to postamble file */ write_fontdef(&fd); WriteToFile(outindex); /* and to output */ write_fontdef(&fd); if ( (fp= (FONT *)malloc(sizeof(FONT)))==NULL ) Error(2,"Cannot allocate memory for %s",fd.name); if (fd.number<CACHEFONTS) fcache[fd.number] = fp; else fontptrarray[fpalen++] = fp; /* fill in font info */ allfonts[fonts++] = fp; fp->number = fd.number; strcpy(fp->name, fd.name); fp->size = fd.scalesize; } changefont(fontno, fntcmd) int fontno; bool fntcmd; { f = fontno; fontp = find_fontp(fontno); if (fntcmd) { if (fontno < 1<<8) PutByte(fontno); else if (fontno < 1<<15) Put2Byte(fontno); else if (fontno < 1<<23) Put3Byte(fontno); else Put4Byte(fontno); }; } \f copy_preamble(pap) PREAMBLE *pap; { if (firstfile) { /* if this is first file in the list */ master_pre.version = pap->version; /* save preamble */ master_pre.numerator = pap->numerator; master_pre.denominator = pap->denominator; master_pre.magnification = (magarg==0? pap->magnification : magarg); sprintf(master_pre.comment, "dviedit:%.247s", pap->comment); master_post.pagecount = 0; /* initialize number of pages */ if (outputarg==NULL) { /* open the output file */ outindex = stdoutindex; } else { outindex = OpenFile(outputarg,"w"); if (outindex<0) { Error(2,"Can't open %s", outputarg); }; }; WriteToFile(outindex); write_preamble(&master_pre); /* write the preamble */ } else { /* check for consistency */ if (pap->version!=master_pre.version) Error(2,"Inconsistent preamble version in %s", filename); if (pap->numerator!=master_pre.numerator) Error(2,"Inconsistent preamble numerator in %s", filename); if (pap->denominator!=master_pre.denominator) Error(2,"Inconsistent preamble denominator in %s", filename); }; } copy_postamble(pap) POSTAMBLE *pap; { if (firstfile) { /* copy postamble */ master_post.lastpage = -1; master_post.numerator = pap->numerator; master_post.denominator = pap->denominator; master_post.magnification = master_pre.magnification; master_post.maxheight = pap->maxheight; master_post.maxwidth = pap->maxwidth; master_post.maxstack = pap->maxstack; } else { /* increase maxima */ if (pap->maxheight>master_post.maxheight) master_post.maxheight = pap->maxheight; if (pap->maxwidth>master_post.maxwidth) master_post.maxwidth = pap->maxwidth; if (pap->maxstack>master_post.maxstack) master_post.maxstack = pap->maxstack; }; } cleanup() { int cmd; FONTDEF fd; WriteToFile(postindex); /* mark end of postamble file */ PutByte(POSTPOST); CloseFile(postindex); WriteToFile(outindex); /* write postamble in output file */ master_post.lastpage = lastpageptr; master_postpost.postptr = WhereIsWrite(); master_postpost.version = master_pre.version; write_postamble(&master_post); postindex = OpenFile(postfile,"r"); /* write font definitions */ if (postindex<0) Error(2,"Can't reopen temp file %s", postfile); ReadFromFile(postindex); GotoByte(0); do { cmd = GetByte(); switch(cmd) { case FNTDEF1: get_fontdef(&fd,1); write_fontdef(&fd); break; case FNTDEF2: get_fontdef(&fd,2); write_fontdef(&fd); break; case FNTDEF3: get_fontdef(&fd,3); write_fontdef(&fd); break; case FNTDEF4: get_fontdef(&fd,4); write_fontdef(&fd); break; case POSTPOST: break; default: Error(2,"Bad command (%0) in postamble file:", cmd); }; } while (cmd!=POSTPOST); write_postpostamble(&master_postpost); /* write postpostamble */ PutByte(DVIPAD); /* write padding */ PutByte(DVIPAD); PutByte(DVIPAD); PutByte(DVIPAD); CloseFile(postindex); unlink(postfile); if (Vflg) fprintf(Vfp,"\nDone!\n"); } SHAR_EOF fi # end of overwriting check echo shar: extracting "'dviedit.h'" '(1257 characters)' if test -f 'dviedit.h' then echo shar: will not over-write existing file "'dviedit.h'" else cat << \SHAR_EOF > 'dviedit.h' typedef int bool; #define true 1 #define false 0 #define MAXINT 2147483647 #define MININT -2147483648 #define MIN(A, B) ((A) < (B) ? (A):(B) ) #define MAX(A, B) ((A) > (B) ? (A):(B) ) #define MAX_FONTS 64 /* maximum number of fonts in one document */ #define MAXLOADEDFONTS 10 /* number of TeX fonts LN01 can load at once */ #define MAXSTACKDEPTH 51 /* stack size */ #define MAXNAMESIZE 80 /* length of file names */ #define OUTLINELENGTH 79 /* length of output lines */ #define CACHEFONTS 64 /* store first few fonts in buckets */ #define TABLEFONTS MAX_FONTS /* remaining fonts in unordered table */ #define MAXLINELEN 200 /* length of input lines */ #define MAXPAGERECS 100 /* number of page specifiers allowed */ typedef struct { /* A font */ int number; /* Number, from DVI file */ char name[MAXNAMESIZE]; /* Name */ long size; /* (Scaled) size in DVIs */ bool loaded; /* True when downloaded to LN01 */ } FONT; typedef struct { /* A page specifier record */ int count; /* which counter to test */ int low; /* low end of range */ int high; /* high end of range */ } PAGERECORD; typedef struct {long h,v,w,x,y,z,hh,vv} STACKITEM; #define EVERYPAGE 1 #define EVERYAMBLE 2 #define EVERYFONTDEF 3 #define EVERYCMD 4 SHAR_EOF fi # end of overwriting check echo shar: done with directory "'ln01'" cd .. # End of shell archive exit 0