From d87898db347967fcf8ea6d74017331353adefd10 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Mon, 7 Mar 1983 22:50:50 -0800 Subject: [PATCH] date and time created 83/03/07 14:50:50 by ralph SCCS-vsn: old/vfilters/rvcat/rvcat.c 4.1 --- usr/src/old/vfilters/rvcat/rvcat.c | 915 +++++++++++++++++++++++++++++ 1 file changed, 915 insertions(+) create mode 100644 usr/src/old/vfilters/rvcat/rvcat.c diff --git a/usr/src/old/vfilters/rvcat/rvcat.c b/usr/src/old/vfilters/rvcat/rvcat.c new file mode 100644 index 0000000000..c06f6daa6f --- /dev/null +++ b/usr/src/old/vfilters/rvcat/rvcat.c @@ -0,0 +1,915 @@ +#include +#include +#include +#include +#include +#include +#include + +/* + * Cat Simulator for Versatec and Varian + * Modified for Varian with rotated fonts: wnj 5/30/80. + * + * Takes two extra special codes defined by rvsort: + * 0115 - break for new page, goto (0,0) + * 0116 - lead 64* following byte + */ + +static char *sccsid ="@(#)rvcat.c 4.1 (Berkeley) %G%"; + +int prtmode[] = {VPRINT, 0, 0}; +int pltmode[] = {VPLOT, 0, 0}; + +#define DISPATCHSIZE 256 /* must be a power of two */ +#define CHARMASK (DISPATCHSIZE-1) +#define NFONTS 25 +#define SPECIALFONT 3 +#define DSIZ ((sizeof *dispatch)*DISPATCHSIZE) +#define MAXF 4 + +#define LOCAL_RAILMAG ".railmag" +#define GLOBAL_RAILMAG "/usr/lib/vfont/railmag" + +/* + * Here we make up for the fact that we only have 2112 + * bits vertically when we need 2200 (11''*200/in), by + * a 4% vertical size squashing. + */ +#define CONVERT(n) ((n*(200./432.))*(2112./2200.)) +#define RECONVERT(n) ((n*(432./200.))*(2200./2112.)) + +#define VA_RASTER_LENGTH 2112 + +#define VA_BYTES_PER_LINE (VA_RASTER_LENGTH/8) + +#define NLINES 110 +#define VA_BUFFER_SIZE (NLINES*VA_BYTES_PER_LINE) + +#define FF_LINES 1600 /* Scan lines to output before formfeeding. */ +#define PAGE_LINES 1700 /* 8.5 inches * 200 lines/inch. */ + +#define min(a,b) (a', /*>*/ + '@', /*@*/ + '\\', /*\\*/ + '^', /*^*/ + '{', /*{*/ + '}', /*}*/ + '~' /*~*/ +}; + +char spectab[128] = { + '\0', /*blank*/ + 'w', /*psi*/ + 'h', /*theta*/ + 'm', /*nu*/ + 'l', /*mu*/ + 'k', /*lambda*/ + 'i', /*iota*/ + 'f', /*zeta*/ + 'r', /*sigma*/ + 'd', /*delta*/ + 'b', /*beta*/ + 'n', /*xi*/ + 'g', /*eta*/ + 'u', /*phi*/ + 't', /*upsilon*/ + 'j', /*kappa*/ + '\0', /*blank*/ + 'p', /*pi*/ + '@', /*at-sign*/ + '7', /*down arrow*/ + '\0', /*blank*/ + 'a', /*alpha*/ + '|', /*or*/ + 'v', /*chi*/ + '"', /*"*/ + 'e', /*epsilon*/ + '=', /*=*/ + 'o', /*omicron*/ + '4', /*left arrow*/ + 'q', /*rho*/ + '6', /*up arrow*/ + 's', /*tau*/ + '_', /*underrule*/ + '\\', /*\*/ + 'W', /*Psi*/ + '\07', /*bell system sign*/ + '\001', /*infinity*/ + 'c', /*gamma*/ + '\002', /*improper superset*/ + '\003', /*proportional to*/ + '\004', /*right hand*/ + 'x', /*omega*/ + '\0', /*blank*/ + '(', /*gradient*/ + '\0', /*blank*/ + 'U', /*Phi*/ + 'H', /*Theta*/ + 'X', /*Omega*/ + '\005', /*cup (union)*/ + '\006', /*root en*/ + '\014', /*terminal sigma*/ + 'K', /*Lambda*/ + '-', /*minus*/ + 'C', /*Gamma*/ + '\015', /*integral sign*/ + 'P', /*Pi*/ + '\032', /*subset of*/ + '\033', /*superset of*/ + '2', /*approximates*/ + 'y', /*partial derivative*/ + 'D', /*Delta*/ + '\013', /*square root*/ + 'R', /*Sigma*/ + '1', /*approx =*/ + '\0', /*blank*/ + '>', /*>*/ + 'N', /*Xi*/ + '<', /*<*/ + '\016', /*slash (longer)*/ + '\034', /*cap (intersection)*/ + 'T', /*Upsilon*/ + '\035', /*not*/ + '\023', /*right ceiling (rt of ")*/ + '\024', /*left top (of big curly)*/ + '\017', /*bold vertical*/ + '\030', /*left center of big curly bracket*/ + '\025', /*left bottom*/ + '\026', /*right top*/ + '\031', /*right center of big curly bracket*/ + '\027', /*right bot*/ + '\021', /*right floor (rb of ")*/ + '\020', /*left floor (left bot of big sq bract)*/ + '\022', /*left ceiling (lt of ")*/ + '*', /*multiply*/ + '/', /*divide*/ + '\010', /*plus-minus*/ + '\011', /*<=*/ + '\012', /*>=*/ + '0', /*identically equal*/ + '3', /*not equal*/ + '{', /*{*/ + '}', /*}*/ + '\'', /*' acute accent*/ + '\`', /*` grave accent*/ + '^', /*^*/ + '#', /*sharp*/ + '\036', /*left hand*/ + '\037', /*member of*/ + '~', /*~*/ + 'z', /*empty set*/ + '\0', /*blank*/ + 'Y', /*dbl dagger*/ + 'Z', /*box rule*/ + '9', /*asterisk*/ + '[', /*improper subset*/ + ']', /*circle*/ + '\0', /*blank*/ + '+', /*eqn plus*/ + '5', /*right arrow*/ + '8' /*section mark*/ +}; + + +onintr() +{ + signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGTERM, SIG_IGN); + exit(1); +} + +main(argc, argv) + int argc; + char *argv[]; +{ + char *namearg; + char *hostarg; + char *acctfile; + + if (signal(SIGINT, SIG_IGN) == SIG_DFL) { + signal(SIGPIPE, SIG_IGN); + signal(SIGINT, onintr); + signal(SIGHUP, onintr); + } else + signal(SIGHUP, SIG_IGN); + if (signal(SIGTERM, SIG_IGN) == SIG_DFL) + signal(SIGTERM, onintr); + + varian = 1; /* Default is the varian */ + namearg = NULL; + hostarg = NULL; + acctfile = NULL; + BYTES_PER_LINE = VA_BYTES_PER_LINE; + BUFFER_SIZE = VA_BUFFER_SIZE; + + if (argv[0][strlen(argv[0])-1] == 'W') { /* Wide: the versatec. */ +/* + varian = 0; + BYTES_PER_LINE = VP_BYTES_PER_LINE; + BUFFER_SIZE = VP_BUFFER_SIZE; +*/ + fprintf(stderr, "rvcat: W not implemented\n"); + } + + while (--argc) { + if (*(*++argv) == '-') + switch (argv[0][1]) { + + case 'n': + if (argc > 1) { + argc--; + namearg = *++argv; + } + break; + + case 'h': + if (argc > 1) { + argc--; + hostarg = *++argv; + } + break; + + default: + fprintf(stderr, "usage: rvcat[W] [-n name] [-h host] [accounting file]\n"); + exit(2); + } + else + acctfile = *argv; + } + ioctl(vc, VSETSTATE, pltmode); + readrm(); + ofile(); + ioctl(vc, VSETSTATE, prtmode); + if (varian) + write(vc, "\f", 2); + else + write(vc, "\n\n\n\n\n", 6); + account(namearg, hostarg, acctfile); + exit(0); +} + +readrm() +{ + register int i; + register char *cp; + register int rmfd; + char c; + + if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0) + if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) { + fprintf(stderr, "rvcat: No railmag file\n"); + exit(2); + } + cp = fnbuf; + for (i = 0; i < 4; i++) { + fontname[i] = cp; + while (read(rmfd, &c, 1) == 1 && c != '\n') + *cp++ = c; + *cp++ = '\0'; + } + close(rmfd); +} + +ofile() +{ + register int c; + register int i; + double scol; + static int initialized; + + lines = 0; + while ((c = getchar()) != EOF) { + if (!c) + continue; + if (c & 0200) { + esc += (~c) & 0177; + continue; + } + if (esc) { + if (back) + esc = -esc; + col += esc; + esc = 0; + i = CONVERT(col); + while (i >= NLINES) { + slop_lines(15); + i = CONVERT(col); + } + ypos = i; + } + if ((c & 0377) < 0100) /* Purely for efficiency */ + goto normal_char; + switch (c) { + + case 0100: + esc = 0; + lead = 0; + linecount = 0; + verd = 0; + back = 0; + mcase = 0; + railmag = 0; + if (loadfont(railmag, cpsize) < 0) + fprintf(stderr, "rvcat: Can't load initial font\n"); + if (initialized) + goto reset; + initialized = 1; + row = 0; + xpos = CONVERT(row); + for (c = 0; c < BUFFER_SIZE; c++) + buffer[c] = 0; + col = 0; + ypos = 0; + break; + + case 0101: /* lower rail */ + crail(railmag &= ~01); + break; + + case 0102: /* upper rail */ + crail(railmag |= 01); + break; + + case 0103: /* upper mag */ + crail(railmag |= 02); + break; + + case 0104: /* lower mag */ + crail(railmag &= ~02); + break; + + case 0105: /* lower case */ + mcase = 0; + break; + + case 0106: /* upper case */ + mcase = 0100; + break; + + case 0107: /* escape forward */ + back = 0; + break; + + case 0110: /* escape backwards */ + back = 1; + break; + + case 0111: /* stop */ + break; + + case 0112: /* lead forward */ + verd = 0; + break; + + case 0113: /* undefined */ + break; + + case 0114: /* lead backward */ + verd = 1; + break; + + case 0115: /* undefined */ +reset: + c = lines % PAGE_LINES; + while (c < FF_LINES) { + slop_lines(min(FF_LINES - c, NLINES)); + c = lines % PAGE_LINES; + } + new_page(PAGE_LINES - c); + break; + + case 0116: + lead = (getchar() & 0377) * 64; + goto leadin; + + case 0117: + break; + + default: + if ((c & 0340) == 0140) /* leading */ { + lead = (~c) & 037; +leadin: + if (verd) + lead = -lead; + row += lead*3; /* Lead is 3 units */ + xpos = CONVERT(row); + continue; + } + if ((c & 0360) == 0120) /* size change */ { + loadfont(railmag, findsize(c & 017)); + continue; + } + if (c & 0300) + continue; + +normal_char: + if (row < 0 || CONVERT(row) >= VA_RASTER_LENGTH) + continue; + c = (c & 077) | mcase; + outc(c); + } + } +out: + slop_lines(NLINES); +} + +findsize(code) + register int code; +{ + register struct point_sizes *psp; + + psp = point_sizes; + while (psp->real_code != 0) { + if ((psp->stupid_code & 017) == code) + break; + psp++; + } + code = 0; + if (!(last_ssize & 0200) && (psp->stupid_code & 0200)) + code = -55; + else if ((last_ssize & 0200) && !(psp->stupid_code & 0200)) + code = 55; + if (back) + code = -code; + esc += code; + last_ssize = psp->stupid_code; + return (psp->real_code); +} + +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; + /* + * Varian accounting is done by 11 inch pages; + * Versatec accounting is by the (12 inch) foot. + */ + fprintf(a, "t%6.2f\t", (lines / 200.0) / (varian ? 11.0 : 12.0)); + if (from != NULL) + fprintf(a, "%s:", from); + fprintf(a, "%s\n", who); + fclose(a); +} + +crail(nrail) + register int nrail; +{ + register int psize; + + psize = cpsize; + if (fontwanted && psize != npsize) + psize = npsize; + loadfont(nrail, psize); +} + + +loadfont(fnum, size) + register int fnum; + register int size; +{ + register int i; + char cbuf[80]; + + fontwanted = 0; + if (fnum == cfnum && size == cpsize) + return(0); + for (i = 0; i < NFONTS; i++) + if (fontdes[i].fnum == fnum && fontdes[i].psize == size) { + cfnum = fontdes[i].fnum; + cpsize = fontdes[i].psize; + dispatch = &fontdes[i].disp[0]; + bits = fontdes[i].bits; + cfont = i; + return (0); + } + if (fnum < 0 || fnum >= MAXF) { + fprintf(stderr, "rvcat: Internal error: illegal font\n"); + return(-1); + } + nfontnum = fnum; + npsize = size; + fontwanted++; + return (0); +} + + +getfont() +{ + register int fnum, size, font; + int d; + char cbuf[BUFSIZ]; + char *cp = cbuf; + char *dp; + + if (!fontwanted) + return(0); + fnum = nfontnum; + size = npsize; + sprintf(cbuf, "%s.%dr", fontname[fnum], size); + font = open(cbuf, 0); + if (font == -1) { + perror(cbuf); + fontwanted = 0; + return (-1); + } + if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436) + fprintf(stderr, "rvcat: %s: Bad font file", cbuf); + else { + cfont = relfont(); + if (((bits=nalloc(header.size+DSIZ+1,1))== NULL) + && ((bits=allpanic(header.size+DSIZ+1))== NULL)) { + fprintf(stderr, "rvcat: %s: ran out of memory\n", cbuf); + exit(2); + } else { + /* + * have allocated one chunk of mem for font, dispatch. + * get the dispatch addr, align to word boundary. + */ + d = (int) bits+header.size; + d += 1; + d &= ~1; + if (read(font, d, DSIZ)!=DSIZ + || read(font, bits, header.size)!=header.size) + fprintf(stderr, "rvcat: bad font header"); + else { + close(font); + cfnum = fontdes[cfont].fnum = fnum; + cpsize = fontdes[cfont].psize = size; + fontdes[cfont].bits = bits; + fontdes[cfont].disp = (struct dispatch *) d; + dispatch = &fontdes[cfont].disp[0]; + fontwanted = 0; + return (0); + } + } + } + close(font); + fontwanted = 0; + return(-1); +} + +int lastloaded = -1; + +relfont() +{ + register int newfont; + + newfont = lastloaded; + /* + * optimization for special font. since we think that usually + * there is only one character at a time from any special math + * font, make it the candidate for removal. + */ + if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0) + if (++newfont>=NFONTS) + newfont = 0; + lastloaded = newfont; + if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0) + nfree(fontdes[newfont].bits); + fontdes[newfont].bits = 0; + return (newfont); +} + +char * +allpanic(nbytes) + int nbytes; +{ + register int i; + + for (i = 0; i <= NFONTS; i++) + if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0) + nfree(fontdes[i].bits); + lastloaded = cfont; + for (i = 0; i <= NFONTS; i++) { + fontdes[i].fnum = fontdes[i].psize = -1; + fontdes[i].bits = 0; + cfnum = cpsize = -1; + } + return(nalloc(nbytes,1)); +} + +int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8, + 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 }; +int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707, + 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff }; +int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 }; + +outc(code) + int code; +{ + char c; /* character to print */ + register struct dispatch *d; /* ptr to character font record */ + register char *addr; /* addr of font data */ + int llen; /* length of each font line */ + int nlines; /* number of font lines */ + register char *scanp; /* ptr to output buffer */ + int scanp_inc; /* increment to start of next buffer */ + int offset; /* bit offset to start of font data */ + int i; /* loop counter */ + register int count; /* font data ptr */ + register unsigned fontdata; /* font data temporary */ + register int off8; /* offset + 8 */ + int b0poff; /* bit offset back towards buf0p */ + + if (fontwanted) + getfont(); + if (railmag == SPECIALFONT) { + if ((c = spectab[code]) < 0) + return(0); + } else if ((c = asctab[code]) < 0) + return(0); + d = dispatch+c; + if (d->nbytes) { + addr = bits+d->addr; + llen = (d->down+d->up+7)/8; + nlines = d->left+d->right; + if (ypos+d->right >= NLINES) + slop_lines(ypos+d->right-NLINES+6); + b0poff = BYTES_PER_LINE*8 - 1 - (xpos+d->down); + scanp = ((ypos-d->left-1)*BYTES_PER_LINE+b0poff/8)+buf0p; + if (scanp < &buffer[0]) + scanp += BUFFER_SIZE; + scanp_inc = BYTES_PER_LINE-llen; + offset = -(b0poff&07); + off8 = offset+8; + for (i = 0; i < nlines; i++) { + if (scanp >= &buffer[BUFFER_SIZE]) + scanp -= BUFFER_SIZE; + count = llen; + if (scanp + count <= &buffer[BUFFER_SIZE]) + do { + fontdata = *(unsigned *)addr; + addr += 4; + if (count < 4) + fontdata &= ~strim[count]; + *(unsigned *)scanp |= (fontdata << offset) &~ M[off8]; + scanp++; + *(unsigned *)scanp |= (fontdata << off8) &~ N[off8]; + scanp += 3; + count -= 4; + } while (count > 0); + scanp += scanp_inc+count; + addr += count; + } + return (1); + } + return (0); +} + +slop_lines(ncols) + int ncols; +{ + register int i, rcols; + + lines += ncols; + rcols = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE; + if (rcols < ncols) { + if (write(vc, buf0p, BYTES_PER_LINE * rcols) < 0) + exit(1); + clear(buf0p, rcols * BYTES_PER_LINE); + buf0p = buffer; + ncols -= rcols; + ypos -= rcols; + col -= RECONVERT(rcols); + } + if (write(vc, buf0p, BYTES_PER_LINE * ncols) < 0) + exit(1); + clear(buf0p, BYTES_PER_LINE * ncols); + buf0p += BYTES_PER_LINE * ncols; + if (buf0p >= &buffer[BUFFER_SIZE]) + buf0p -= BUFFER_SIZE; + ypos -= ncols; + col -= RECONVERT(ncols); +} + +/*ARGSUSED*/ +clear(lp, nbytes) + int *lp; + int nbytes; +{ + asm("movc5 $0,(sp),$0,8(ap),*4(ap)"); +} + +/* Start a new page by formfeeding, resetting buffer and column counters. */ +new_page(lines_left) + int lines_left; /* ... on page. */ +{ + lines += lines_left; + buf0p = buffer; /* Clear out buffer and reset pointers. */ + clear(buf0p, BYTES_PER_LINE * NLINES); + row = 0; + col = 0; + xpos = CONVERT(row); + ypos = 0; + ioctl(vc, VSETSTATE, prtmode); + write (vc, "\f", 2); + ioctl(vc, VSETSTATE, pltmode); +} + +char * +nalloc(i, j) + int i, j; +{ + register char *cp; + + cp = calloc(i, j); + return(cp); +} + +nfree(cp) + char *cp; +{ + free(cp); +} -- 2.20.1