#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include "dev.h" #include "pp.h" /* * ALL geometry in device units */ #define B_MASK 0377 /* because we can't always say unsigned char */ #define DEFSIZE 10 /* point size of normal text (only used for vert. motion) */ #define PAGELENGTH (11*dev.res) #define PAGEWIDTH (8*dev.res) struct dev dev; struct Font font; char fontdir[]="/usr/lib/font"; char *devname="202"; char *fontname=0; unsigned char width[B_MASK+1]; char ligs[B_MASK+1]; char codes[B_MASK+1]; char fitab[B_MASK+1]; unsigned char special[96]; int miwidth; int havespecial=0; int pageno, hpos, vpos; int margin, vspace; char curfunc[128]; char idchars[]="_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char *curfile; char filetime[32]; int functionmarked; typedef struct{ int variant; /* ROMAN, ITALIC, BOLD or BLACK */ short size; /* point size */ unsigned char width[96]; /* width tables */ }Ftab; #define ROMAN 0 #define ITALIC 1 #define BOLD 2 #define BLACK 3 Ftab ftab[]={ #define R9 0 {ROMAN, 9}, #define R10 1 {ROMAN, 10}, #define R14 2 {ROMAN, 14}, #define I9 3 {ITALIC, 9}, #define I10 4 {ITALIC, 10}, #define I14 5 {ITALIC, 14}, #define B9 6 {BOLD, 9}, #define B10 7 {BOLD, 10}, #define B14 8 {BOLD, 14}, {0, 0} /* 0 size marks end */ }; Ftab *curfont=ftab; main(argc, argv) char *argv[]; { struct stat statbuf; long timebuf; char *ctime(); char *title=0; --argc; argv++; while(argc>0 && argv[0][0]=='-'){ switch(argv[0][1]){ default: error("usage: pp [-t\"Title\"] [-T202] [-fE] [-k] [files]", (char *)0); case 'k': ckeywords(&argv[0][2]); break; case 'f': fontname= &argv[0][2]; break; case 'b': blacken(); break; case 't': title= &argv[0][2]; break; case 'T': devname= &argv[0][2]; break; } --argc; argv++; } if(fontname==0){ fontname="Memphis"; blacken(); } load(); if(title){ time(&timebuf); coverpage(title, ctime(&timebuf)); } if(argc<=0){ curfile="<stdin>"; time(&timebuf); strcpy(filetime, ctime(&timebuf)+4); process(0); }else while(argc-->0){ stat(*argv, &statbuf); strcpy(filetime, ctime(&statbuf.st_mtime)+4); process(Open(curfile= *argv++)); } printf("x trailer\nV0\nx stop\n"); return 0; } blacken(){ register i; for(i=B9; i<=B14; i++) ftab[i].variant=BLACK; } char *fontexcep[][4]={ /* roman italic bold black indices match #defines above */ "R", "I", "B", "B", /* Times Roman */ "PA", "PI", "PB", "PB", /* Palatino */ "H", "HI", "HB", "HK", /* Helvetica */ "CW", "CS", "CS", "CS", /* constant width Courier */ "PO", "PI", "PB", "PX", /* constant width */ 0 }; char *suffix[]={ "", "I", "B", "BK" }; char * fonttag(variant){ static char buf[512]; register i; for(i=0;fontexcep[i][0];i++) if(strcmp(fontexcep[i][0], fontname)==0) return fontexcep[i][variant]; sprintf(buf, "%s%s", fontname, suffix[variant]); return buf; } load(){ register fd, i, j, mi; register Ftab *f; register char *s; char file[64]; char buf[600]; /* should be enough (gulp) */ long lseek(); sprintf(file, "%s/dev%s/DESC.out", fontdir, devname); fd=Open(file); Read(file, fd, &dev, sizeof dev); /* Find \(mi to remember its width */ if(lseek(fd, (dev.nsizes+1+dev.nchtab)*sizeof(short), 1)==-1L) error("device file incomplete", file); j=read(fd, buf, sizeof buf); for(s=buf,mi=0; j>0 && strcmp(s, "mi")!=0; mi++){ s+=strlen(s)+1; j-=strlen(s)+1; } if(j<=0) error("can't find minus in special font on", devname); close(fd); printf("x T %s\n", devname); printf("x res %d %d %d\n", dev.res, dev.hor, dev.vert); printf("x init\n"); sprintf(file, "%s/dev%s/S.out", fontdir, devname); readfont(file); printf("x font %d S\n", dev.nfonts); /* Guess? */ setwidths(special, dev.unitwidth); havespecial=1; miwidth=width[fitab[mi+128-32]]; margin=dev.res/2; /* 1/2 inch */ vspace=DEFSIZE*dev.res/72; /* units per line */ for(f=ftab; f->size; ){ sprintf(file, "%s/dev%s/%s.out", fontdir, devname, fonttag(f->variant)); readfont(file); printf("x font %d %s\n", (f-ftab)/3+1, fonttag(f->variant)); for(j=0; j<3; j++, f++) setwidths(f->width, f->size); } } setwidths(wt, size) register char *wt; { register i, n; for(i=0; i<96; i++, wt++){ if(n=fitab[i]) n=width[n]; else if(havespecial) n=special[i]; *wt=size*n/dev.unitwidth; } } readfont(file) char *file; { register fd; fd=Open(file); Read(file, fd, &font, sizeof font); Read(file, fd, width, font.nwfont&B_MASK); Read(file, fd, ligs, font.nwfont&B_MASK); Read(file, fd, codes, font.nwfont&B_MASK); /*Read(file, fd, fitab, dev.nchtab+128-32);*/ read(fd, fitab, dev.nchtab+128-32); close(fd); } coverpage(s, t) char *s, *t; { printf("p0\nV%d\n", dev.res*4); /* 3 inches down */ center(&ftab[B14], s); printf("v%d\n", dev.res); /* another inch */ center(&ftab[I9], t); } Open(s) char *s; { register f=open(s, 0); if(f<0) error("can't open", s); return f; } Read(s, f, a, n) char *s, *a; { if(read(f, a, n)!=n) error("read error on file", s); } error(s, t) char *s, *t; { fprintf(stderr, "pp: %s %s\n", s, t); exit(1); } char * extractfn(s) register char *s; { extern char *strrchr(), *strchr(); register char *t=strrchr(s, '('), *u; if(t==0) error("extract can't find function in", s); while(strchr(idchars, *t)==0) if(t<=s) return ""; else --t; for(u=t; u>=s && strchr(idchars, *u); --u) ; strncpy(curfunc, u+1, t-u); curfunc[t-u]=0; return curfunc; } /* * function name should not be in italics */ process(fd) register fd; { register char *s; register unsigned char *w; register type; register Ftab *f=0, *of; register c; char buf[32]; fileno(stdin)=fd; /* cough */ pageno=0; topofpage(); curfont= &ftab[R10]; curfunc[0]=0; while(type=yylex()){ of=f; /* * Appropriate font switches, etc. */ switch(type){ case FUNCTION: rjust(&ftab[I14], extractfn(yytext)); functionmarked=1; case OTHER: f= &ftab[R10]; break; case COMMENT:{ Ftab *oldfont; /* gotta do this in place, sigh */ oldfont = curfont; curfont = f= &ftab[I10]; w=f->width; drawstr(f, yytext); printf("f2 s10\n"); for(;;){ outchar(f, c=yyinput()); if(c==0) break; if(c=='*'){ GotStar: outchar(f, c=yyinput()); if(c=='/') break; if(c=='*') goto GotStar; } if(c=='\n'){ GotNewline: newline(); while((c=yyinput())=='\t') hpos=tabstop(w); if(c==' ') printf("H%d\n", hpos+=w['/'-32]); else if(c=='\n') goto GotNewline; else{ printf("H%d\n", hpos); outchar(f, c); if(c=='*') goto GotStar; } } } curfont=f=oldfont; printf("f%d s%d\n", (f-ftab)/3+1, f->size); continue; } case KEYWORD: f= &ftab[B10]; break; } if(functionmarked==0){ if(curfunc[0]){ sprintf(buf, "...%s", curfunc); rjust(&ftab[I9], buf); } functionmarked=1; } if(of!=f){ /* font switch */ printf("f%d s%d\n", (f-ftab)/3+1, f->size); curfont=f; } w=f->width; /* * Draw them. */ for(s=yytext; *s; s++){ switch(*s){ case '\n': newline(); break; case '\f': vpos = PAGELENGTH; newline(); break; case ' ': printf("h%d\n", w['n'-32]); hpos+=w['n'-32]; break; case '\t': hpos=tabstop(w); printf("H%d\n", hpos); break; case '-': printf("Cmi h%d\n", miwidth*f->size/dev.unitwidth); hpos+=miwidth*f->size/dev.unitwidth; break; default: printf("c%c h%d\n", *s, w[*s-32]); hpos+=w[*s-32]; break; } } } bottomofpage(); close(fd); } newline(){ if((vpos+=vspace)>PAGELENGTH-margin-3*vspace){ /* new page */ bottomofpage(); topofpage(); }else{ printf("n\n"); printf("v%d\n", vspace); } printf("H%d\n", hpos=margin); } topofpage(){ printf("p%d\n", pageno++); hpos=margin; vpos=margin; printf("V%d\n", vpos); printf("H%d\n", hpos); drawstr(&ftab[B14], curfile); rjust(&ftab[B14], curfile); printf("v%d\n", 3*vspace); vpos+=3*vspace; functionmarked=0; } bottomofpage(){ char buf[256]; printf("H%d\n", margin); printf("V%d\n", PAGELENGTH-margin); drawstr(&ftab[I9], filetime); sprintf(buf, "Page %d of %s", pageno, curfile); rjust(&ftab[I9], buf); } strwidth(f, s) Ftab *f; register char *s; { register unsigned char *w=f->width; register n=0; while(*s){ if(*s==' ') n+=w['n'-32]; else if(*s>' ') n+=w[*s-32]; s++; } return n; } rjust(f, s) register Ftab *f; register char *s; { printf("H%d\n", PAGEWIDTH-margin-strwidth(f, s)); drawstr(f, s); printf("H%d\n", hpos); } center(f, s) register Ftab *f; register char *s; { printf("H%d\n", (PAGEWIDTH-margin-strwidth(f, s))/2); drawstr(f, s); printf("H%d\n", hpos); } drawstr(f, s) register Ftab *f; register char *s; { register c; printf("f%d s%d\n", (f-ftab)/3+1, f->size); while(c= *s++) /* assignment = */ if(c==' ') printf("h%d\n", f->width['n'-32]); else printf("c%c h%d\n", c, f->width[c-32]); printf("f%d s%d\n", (curfont-ftab)/3+1, curfont->size); } outchar(f, c) register Ftab *f; register c; { register w; if(c==' ') printf("h%d\n", w=f->width['n'-32]); else printf("c%c h%d\n", c, w=f->width[c-32]); hpos+=w; } tabstop(w) register unsigned char *w; { register c, block; block = w['i'-32] == w['m'-32]? (8*w['n'-32]):(dev.res/2); c = margin + block*((hpos-margin+block-1)/block); if(hpos == c) c += block; return(c); }