xref: /csrg-svn/old/vfilters/rvcat/rvcat.c (revision 46421)
120200Sdist /*
220200Sdist  * Copyright (c) 1983 Regents of the University of California.
333682Sbostic  * All rights reserved.
433682Sbostic  *
542805Sbostic  * %sccs.include.redist.c%
620200Sdist  */
720200Sdist 
813945Ssam #ifndef lint
933682Sbostic char copyright[] =
1033682Sbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1133682Sbostic  All rights reserved.\n";
1233682Sbostic #endif /* not lint */
1313945Ssam 
1433682Sbostic #ifndef lint
15*46421Sbostic static char sccsid[] = "@(#)rvcat.c	5.6 (Berkeley) 02/15/91";
1633682Sbostic #endif /* not lint */
1733682Sbostic 
1811431Sralph /*
1911431Sralph  * Cat Simulator for Versatec and Varian
2011431Sralph  * Modified for Varian with rotated fonts: wnj 5/30/80.
2111431Sralph  *
2211431Sralph  * Takes two extra special codes defined by rvsort:
2311431Sralph  *	0115 - break for new page, goto (0,0)
2411431Sralph  *	0116 - lead 64* following byte
2511431Sralph  */
2611431Sralph 
2711580Sralph #include <stdio.h>
2811580Sralph #include <sys/vcmd.h>
2911580Sralph #include <vfont.h>
3011431Sralph 
3112125Sralph int	prtmode[] = {VPRINT};
3212125Sralph int	pltmode[] = {VPLOT};
3311431Sralph 
3411431Sralph #define DISPATCHSIZE		256	/* must be a power of two */
3511431Sralph #define CHARMASK		(DISPATCHSIZE-1)
3611431Sralph #define NFONTS			25
3711431Sralph #define SPECIALFONT		3
3811431Sralph #define DSIZ			((sizeof *dispatch)*DISPATCHSIZE)
3911431Sralph #define MAXF			4
4011431Sralph 
4111431Sralph #define LOCAL_RAILMAG		".railmag"
4211431Sralph #define GLOBAL_RAILMAG		"/usr/lib/vfont/railmag"
4311431Sralph 
4411431Sralph /*
4511431Sralph  * Here we make up for the fact that we only have 2112
4611431Sralph  * bits vertically when we need 2200 (11''*200/in), by
4711431Sralph  * a 4% vertical size squashing.
4811431Sralph  */
4911431Sralph #define CONVERT(n)		((n*(200./432.))*(2112./2200.))
5011431Sralph #define RECONVERT(n)		((n*(432./200.))*(2200./2112.))
5111431Sralph 
5211431Sralph #define NLINES			110
5311431Sralph 
5411431Sralph #define	FF_LINES		1600	/* Scan lines to output before formfeeding. */
5511431Sralph 
5611431Sralph #define	min(a,b)		(a<b ? a : b)
5711431Sralph 
5812468Sralph char	buffer[NLINES * 264];	/* Big enough for varain */
5912468Sralph char	*buf0p = &buffer[0];	/* Zero origin in circular buffer */
6011431Sralph 
6111431Sralph char	*calloc();
6211431Sralph char	*nalloc();
6311431Sralph char	*allpanic();
6411431Sralph 
6511431Sralph struct	header	header;
6611431Sralph struct dispatch *dispatch;
6711431Sralph 
6811431Sralph struct	fontdes {
6911431Sralph 	int	fnum;
7011431Sralph 	int	psize;
7111431Sralph 	struct	dispatch *disp;
7211431Sralph 	char	*bits;
7311431Sralph } fontdes[NFONTS] = {
7411431Sralph 	-1,
7511431Sralph 	-1
7611431Sralph };
7711431Sralph 
7811431Sralph struct point_sizes {
7911431Sralph 	int	stupid_code;
8011431Sralph 	int	real_code;
8111431Sralph } point_sizes[] = {
8211431Sralph 	010, 6,
8311431Sralph 	0, 7,
8411431Sralph 	01, 8,
8511431Sralph 	07, 9,
8611431Sralph 	02, 10,
8711431Sralph 	03, 11,
8811431Sralph 	04, 12,
8911431Sralph 	05, 14,
9011431Sralph 	0211, 16,
9111431Sralph 	06, 18,
9211431Sralph 	0212, 20,
9311431Sralph 	0213, 22,
9411431Sralph 	0214, 24,
9511431Sralph 	0215, 28,
9611431Sralph 	0216, 36,
9711431Sralph 	0, 0
9811431Sralph };
9911431Sralph 
10011431Sralph int	lines;
10111431Sralph 
10215693Sralph int	vc = 1;			/* varian/versatec output file descriptor */
10315693Sralph int	varian = 1;		/* 0 for versatec, 1 for varian. */
10415693Sralph int	BYTES_PER_LINE = 264;	/* number of bytes per raster line. */
10515693Sralph int	PAGE_LINES = 1700;	/* number of raster lines per page. */
10615693Sralph int	BUFFER_SIZE = NLINES * 264;	/* buffer size. */
10711431Sralph int	cfnum = -1;
10811431Sralph int	cpsize = 10;
10911431Sralph int	cfont = 1;
11011431Sralph char	*bits;
11111431Sralph int	nfontnum = -1;
11211431Sralph int	fontwanted = 1;
11311431Sralph int	npsize = 10;
11411431Sralph int	last_ssize = 02;
11511431Sralph int	xpos, ypos;
11611431Sralph int	esc, lead, back, verd, mcase, railmag;
11711431Sralph double	row, col;
11811431Sralph char	*fontname[MAXF];
11911431Sralph char	fnbuf[120];
12011431Sralph char	*scanline;
12111431Sralph int	linecount;
12211431Sralph 
12311431Sralph char	asctab[128] = {
12411431Sralph 	'\0',	/*blank*/
12511431Sralph 	'h',	/*h*/
12611431Sralph 	't',	/*t*/
12711431Sralph 	'n',	/*n*/
12811431Sralph 	'm',	/*m*/
12911431Sralph 	'l',	/*l*/
13011431Sralph 	'i',	/*i*/
13111431Sralph 	'z',	/*z*/
13211431Sralph 	's',	/*s*/
13311431Sralph 	'd',	/*d*/
13411431Sralph 	'b',	/*b*/
13511431Sralph 	'x',	/*x*/
13611431Sralph 	'f',	/*f*/
13711431Sralph 	'j',	/*j*/
13811431Sralph 	'u',	/*u*/
13911431Sralph 	'k',	/*k*/
14011431Sralph 	'\0',	/*blank*/
14111431Sralph 	'p',	/*p*/
14211431Sralph 	'\06',	/*_ 3/4 em dash*/
14311431Sralph 	';',	/*;*/
14411431Sralph 	'\0',	/*blank*/
14511431Sralph 	'a',	/*a*/
14611431Sralph 	'\05',	/*rule*/
14711431Sralph 	'c',	/*c*/
14811431Sralph 	'`',	/*` open*/
14911431Sralph 	'e',	/*e*/
15011431Sralph 	'\'',	/*' close*/
15111431Sralph 	'o',	/*o*/
15211431Sralph 	'\021',	/*1/4*/
15311431Sralph 	'r',	/*r*/
15411431Sralph 	'\022',	/*1/2*/
15511431Sralph 	'v',	/*v*/
15611431Sralph 	'-',	/*- hyphen*/
15711431Sralph 	'w',	/*w*/
15811431Sralph 	'q',	/*q*/
15911431Sralph 	'/',	/*/*/
16011431Sralph 	'.',	/*.*/
16111431Sralph 	'g',	/*g*/
16211431Sralph 	'\023',	/*3/4*/
16311431Sralph 	',',	/*,*/
16411431Sralph 	'&',	/*&*/
16511431Sralph 	'y',	/*y*/
16611431Sralph 	'\0',	/*blank*/
16711431Sralph 	'%',	/*%*/
16811431Sralph 	'\0',	/*blank*/
16911431Sralph 	'Q',	/*Q*/
17011431Sralph 	'T',	/*T*/
17111431Sralph 	'O',	/*O*/
17211431Sralph 	'H',	/*H*/
17311431Sralph 	'N',	/*N*/
17411431Sralph 	'M',	/*M*/
17511431Sralph 	'L',	/*L*/
17611431Sralph 	'R',	/*R*/
17711431Sralph 	'G',	/*G*/
17811431Sralph 	'I',	/*I*/
17911431Sralph 	'P',	/*P*/
18011431Sralph 	'C',	/*C*/
18111431Sralph 	'V',	/*V*/
18211431Sralph 	'E',	/*E*/
18311431Sralph 	'Z',	/*Z*/
18411431Sralph 	'D',	/*D*/
18511431Sralph 	'B',	/*B*/
18611431Sralph 	'S',	/*S*/
18711431Sralph 	'Y',	/*Y*/
18811431Sralph 	'\0',	/*blank*/
18911431Sralph 	'F',	/*F*/
19011431Sralph 	'X',	/*X*/
19111431Sralph 	'A',	/*A*/
19211431Sralph 	'W',	/*W*/
19311431Sralph 	'J',	/*J*/
19411431Sralph 	'U',	/*U*/
19511431Sralph 	'K',	/*K*/
19611431Sralph 	'0',	/*0*/
19711431Sralph 	'1',	/*1*/
19811431Sralph 	'2',	/*2*/
19911431Sralph 	'3',	/*3*/
20011431Sralph 	'4',	/*4*/
20111431Sralph 	'5',	/*5*/
20211431Sralph 	'6',	/*6*/
20311431Sralph 	'7',	/*7*/
20411431Sralph 	'8',	/*8*/
20511431Sralph 	'9',	/*9*/
20611431Sralph 	'*',	/***/
20711431Sralph 	'\04',	/*minus*/
20811431Sralph 	'\01',	/*fi*/
20911431Sralph 	'\02',	/*fl*/
21011431Sralph 	'\03',	/*ff*/
21111431Sralph 	'\020',	/* cent sign */
21211431Sralph 	'\012',	/*ffl*/
21311431Sralph 	'\011',	/*ffi*/
21411431Sralph 	'(',	/*(*/
21511431Sralph 	')',	/*)*/
21611431Sralph 	'[',	/*[*/
21711431Sralph 	']',	/*]*/
21811431Sralph 	'\013',	/* degree */
21911431Sralph 	'\014',	/* dagger */
22011431Sralph 	'=',	/*=*/
22111431Sralph 	'\017',	/* registered */
22211431Sralph 	':',	/*:*/
22311431Sralph 	'+',	/*+*/
22411431Sralph 	'\0',	/*blank*/
22511431Sralph 	'!',	/*!*/
22611431Sralph 	'\07',	/* bullet */
22711431Sralph 	'?',	/*?*/
22811431Sralph 	'\015',	/*foot mark*/
22911431Sralph 	'|',	/*|*/
23011431Sralph 	'\0',	/*blank*/
23111431Sralph 	'\016',	/* copyright */
23211431Sralph 	'\010',	/* square */
23311431Sralph 	'$',	/*$*/
23411431Sralph 	'\0',
23511431Sralph 	'\0',
23611431Sralph 	'"',	/*"*/
23711431Sralph 	'#',	/*#*/
23811431Sralph 	'<',	/*<*/
23911431Sralph 	'>',	/*>*/
24011431Sralph 	'@',	/*@*/
24111431Sralph 	'\\',	/*\\*/
24211431Sralph 	'^',	/*^*/
24311431Sralph 	'{',	/*{*/
24411431Sralph 	'}',	/*}*/
24511431Sralph 	'~'	/*~*/
24611431Sralph };
24711431Sralph 
24811431Sralph char spectab[128] = {
24911431Sralph 	'\0',	/*blank*/
25011431Sralph 	'w',	/*psi*/
25111431Sralph 	'h',	/*theta*/
25211431Sralph 	'm',	/*nu*/
25311431Sralph 	'l',	/*mu*/
25411431Sralph 	'k',	/*lambda*/
25511431Sralph 	'i',	/*iota*/
25611431Sralph 	'f',	/*zeta*/
25711431Sralph 	'r',	/*sigma*/
25811431Sralph 	'd',	/*delta*/
25911431Sralph 	'b',	/*beta*/
26011431Sralph 	'n',	/*xi*/
26111431Sralph 	'g',	/*eta*/
26211431Sralph 	'u',	/*phi*/
26311431Sralph 	't',	/*upsilon*/
26411431Sralph 	'j',	/*kappa*/
26511431Sralph 	'\0',	/*blank*/
26611431Sralph 	'p',	/*pi*/
26711431Sralph 	'@',	/*at-sign*/
26811431Sralph 	'7',	/*down arrow*/
26911431Sralph 	'\0',	/*blank*/
27011431Sralph 	'a',	/*alpha*/
27111431Sralph 	'|',	/*or*/
27211431Sralph 	'v',	/*chi*/
27311431Sralph 	'"',	/*"*/
27411431Sralph 	'e',	/*epsilon*/
27511431Sralph 	'=',	/*=*/
27611431Sralph 	'o',	/*omicron*/
27711431Sralph 	'4',	/*left arrow*/
27811431Sralph 	'q',	/*rho*/
27911431Sralph 	'6',	/*up arrow*/
28011431Sralph 	's',	/*tau*/
28111431Sralph 	'_',	/*underrule*/
28211431Sralph 	'\\',	/*\*/
28311431Sralph 	'W',	/*Psi*/
28411431Sralph 	'\07',	/*bell system sign*/
28511431Sralph 	'\001',	/*infinity*/
28611431Sralph 	'c',	/*gamma*/
28711431Sralph 	'\002',	/*improper superset*/
28811431Sralph 	'\003',	/*proportional to*/
28911431Sralph 	'\004',	/*right hand*/
29011431Sralph 	'x',	/*omega*/
29111431Sralph 	'\0',	/*blank*/
29211431Sralph 	'(',	/*gradient*/
29311431Sralph 	'\0',	/*blank*/
29411431Sralph 	'U',	/*Phi*/
29511431Sralph 	'H',	/*Theta*/
29611431Sralph 	'X',	/*Omega*/
29711431Sralph 	'\005',	/*cup (union)*/
29811431Sralph 	'\006',	/*root en*/
29911431Sralph 	'\014',	/*terminal sigma*/
30011431Sralph 	'K',	/*Lambda*/
30111431Sralph 	'-',	/*minus*/
30211431Sralph 	'C',	/*Gamma*/
30311431Sralph 	'\015',	/*integral sign*/
30411431Sralph 	'P',	/*Pi*/
30511431Sralph 	'\032',	/*subset of*/
30611431Sralph 	'\033',	/*superset of*/
30711431Sralph 	'2',	/*approximates*/
30811431Sralph 	'y',	/*partial derivative*/
30911431Sralph 	'D',	/*Delta*/
31011431Sralph 	'\013',	/*square root*/
31111431Sralph 	'R',	/*Sigma*/
31211431Sralph 	'1',	/*approx =*/
31311431Sralph 	'\0',	/*blank*/
31411431Sralph 	'>',	/*>*/
31511431Sralph 	'N',	/*Xi*/
31611431Sralph 	'<',	/*<*/
31711431Sralph 	'\016',	/*slash (longer)*/
31811431Sralph 	'\034',	/*cap (intersection)*/
31911431Sralph 	'T',	/*Upsilon*/
32011431Sralph 	'\035',	/*not*/
32111431Sralph 	'\023',	/*right ceiling (rt of ")*/
32211431Sralph 	'\024',	/*left top (of big curly)*/
32311431Sralph 	'\017',	/*bold vertical*/
32411431Sralph 	'\030',	/*left center of big curly bracket*/
32511431Sralph 	'\025',	/*left bottom*/
32611431Sralph 	'\026',	/*right top*/
32711431Sralph 	'\031',	/*right center of big curly bracket*/
32811431Sralph 	'\027',	/*right bot*/
32911431Sralph 	'\021',	/*right floor (rb of ")*/
33011431Sralph 	'\020',	/*left floor (left bot of big sq bract)*/
33111431Sralph 	'\022',	/*left ceiling (lt of ")*/
33211431Sralph 	'*',	/*multiply*/
33311431Sralph 	'/',	/*divide*/
33411431Sralph 	'\010',	/*plus-minus*/
33511431Sralph 	'\011',	/*<=*/
33611431Sralph 	'\012',	/*>=*/
33711431Sralph 	'0',	/*identically equal*/
33811431Sralph 	'3',	/*not equal*/
33911431Sralph 	'{',	/*{*/
34011431Sralph 	'}',	/*}*/
34111431Sralph 	'\'',	/*' acute accent*/
342*46421Sbostic 	'`',	/*` grave accent*/
34311431Sralph 	'^',	/*^*/
34411431Sralph 	'#',	/*sharp*/
34511431Sralph 	'\036',	/*left hand*/
34611431Sralph 	'\037',	/*member of*/
34711431Sralph 	'~',	/*~*/
34811431Sralph 	'z',	/*empty set*/
34911431Sralph 	'\0',	/*blank*/
35011431Sralph 	'Y',	/*dbl dagger*/
35111431Sralph 	'Z',	/*box rule*/
35211431Sralph 	'9',	/*asterisk*/
35311431Sralph 	'[',	/*improper subset*/
35411431Sralph 	']',	/*circle*/
35511431Sralph 	'\0',	/*blank*/
35611431Sralph 	'+',	/*eqn plus*/
35711431Sralph 	'5',	/*right arrow*/
35811431Sralph 	'8'	/*section mark*/
35911431Sralph };
36011431Sralph 
main(argc,argv)36111431Sralph main(argc, argv)
36211431Sralph 	int argc;
36311431Sralph 	char *argv[];
36411431Sralph {
36511580Sralph 	char *namearg = NULL;
36611580Sralph 	char *hostarg = NULL;
36711580Sralph 	char *acctfile = NULL;
36811431Sralph 
36911431Sralph 	while (--argc) {
37011431Sralph 		if (*(*++argv) == '-')
37111431Sralph 			switch (argv[0][1]) {
37212468Sralph 			case 'x':
37312468Sralph 				BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
37412468Sralph 				BUFFER_SIZE = NLINES * BYTES_PER_LINE;
37512468Sralph 				break;
37611431Sralph 
37712468Sralph 			case 'y':
37812468Sralph 				PAGE_LINES = atoi(&argv[0][2]);
37912468Sralph 				break;
38012468Sralph 
38111431Sralph 			case 'n':
38211431Sralph 				if (argc > 1) {
38311431Sralph 					argc--;
38411431Sralph 					namearg = *++argv;
38511431Sralph 				}
38611431Sralph 				break;
38711431Sralph 
38811431Sralph 			case 'h':
38911431Sralph 				if (argc > 1) {
39011431Sralph 					argc--;
39111431Sralph 					hostarg = *++argv;
39211431Sralph 				}
39311431Sralph 				break;
39411431Sralph 			}
39511431Sralph 		else
39611431Sralph 			acctfile = *argv;
39711431Sralph 	}
39811431Sralph 	ioctl(vc, VSETSTATE, pltmode);
39911431Sralph 	readrm();
40011431Sralph 	ofile();
40111431Sralph 	ioctl(vc, VSETSTATE, prtmode);
40211431Sralph 	if (varian)
40311431Sralph 		write(vc, "\f", 2);
40411431Sralph 	else
40511431Sralph 		write(vc, "\n\n\n\n\n", 6);
40611431Sralph 	account(namearg, hostarg, acctfile);
40711431Sralph 	exit(0);
40811431Sralph }
40911431Sralph 
readrm()41011431Sralph readrm()
41111431Sralph {
41211431Sralph 	register int i;
41311431Sralph 	register char *cp;
41411431Sralph 	register int rmfd;
41511431Sralph 	char c;
41611431Sralph 
41711431Sralph 	if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
41811431Sralph 		if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
41911431Sralph 			fprintf(stderr, "rvcat: No railmag file\n");
42011431Sralph 			exit(2);
42111431Sralph 		}
42211431Sralph 	cp = fnbuf;
42311580Sralph 	for (i = 0; i < MAXF; i++) {
42411431Sralph 		fontname[i] = cp;
42511431Sralph 		while (read(rmfd, &c, 1) == 1 && c != '\n')
42611431Sralph 			*cp++ = c;
42711431Sralph 		*cp++ = '\0';
42811431Sralph 	}
42911431Sralph 	close(rmfd);
43011431Sralph }
43111431Sralph 
ofile()43211431Sralph ofile()
43311431Sralph {
43411431Sralph 	register int c;
43511431Sralph 	register int i;
43611431Sralph 	double scol;
43711431Sralph 	static int initialized;
43811431Sralph 
43911431Sralph 	lines = 0;
44011431Sralph 	while ((c = getchar()) != EOF) {
44111431Sralph 		if (!c)
44211431Sralph 			continue;
44311431Sralph 		if (c & 0200) {
44411431Sralph 			esc += (~c) & 0177;
44511431Sralph 			continue;
44611431Sralph 		}
44711431Sralph 		if (esc) {
44811431Sralph 			if (back)
44911431Sralph 				esc = -esc;
45011431Sralph 			col += esc;
45111431Sralph 			esc = 0;
45211431Sralph 			i = CONVERT(col);
45311431Sralph 			while (i >= NLINES) {
45411431Sralph 				slop_lines(15);
45511431Sralph 				i = CONVERT(col);
45611431Sralph 			}
45711431Sralph 			ypos = i;
45811431Sralph 		}
45911431Sralph 		if ((c & 0377) < 0100)	/*  Purely for efficiency  */
46011431Sralph 			goto normal_char;
46111431Sralph 		switch (c) {
46211431Sralph 
46311431Sralph 		case 0100:
46411431Sralph 			esc = 0;
46511431Sralph 			lead = 0;
46611431Sralph 			linecount = 0;
46711431Sralph 			verd = 0;
46811431Sralph 			back = 0;
46911431Sralph 			mcase = 0;
47011431Sralph 			railmag = 0;
47111431Sralph 			if (loadfont(railmag, cpsize) < 0)
47211431Sralph 				fprintf(stderr, "rvcat: Can't load initial font\n");
47311431Sralph 			if (initialized)
47411431Sralph 				goto reset;
47511431Sralph 			initialized = 1;
47611431Sralph 			row = 0;
47711431Sralph 			xpos = CONVERT(row);
47811431Sralph 			for (c = 0; c < BUFFER_SIZE; c++)
47911431Sralph 				buffer[c] = 0;
48011431Sralph 			col = 0;
48111431Sralph 			ypos = 0;
48211431Sralph 			break;
48311431Sralph 
48411431Sralph 		case 0101:	/* lower rail */
48511431Sralph 			crail(railmag &= ~01);
48611431Sralph 			break;
48711431Sralph 
48811431Sralph 		case 0102:	/* upper rail */
48911431Sralph 			crail(railmag |= 01);
49011431Sralph 			break;
49111431Sralph 
49211431Sralph 		case 0103:	/* upper mag */
49311431Sralph 			crail(railmag |= 02);
49411431Sralph 			break;
49511431Sralph 
49611431Sralph 		case 0104:	/* lower mag */
49711431Sralph 			crail(railmag &= ~02);
49811431Sralph 			break;
49911431Sralph 
50011431Sralph 		case 0105:	/* lower case */
50111431Sralph 			mcase = 0;
50211431Sralph 			break;
50311431Sralph 
50411431Sralph 		case 0106:	/* upper case */
50511431Sralph 			mcase = 0100;
50611431Sralph 			break;
50711431Sralph 
50811431Sralph 		case 0107:	/* escape forward */
50911431Sralph 			back = 0;
51011431Sralph 			break;
51111431Sralph 
51211431Sralph 		case 0110:	/* escape backwards */
51311431Sralph 			back = 1;
51411431Sralph 			break;
51511431Sralph 
51611431Sralph 		case 0111:	/* stop */
51711431Sralph 			break;
51811431Sralph 
51911431Sralph 		case 0112:	/* lead forward */
52011431Sralph 			verd = 0;
52111431Sralph 			break;
52211431Sralph 
52311431Sralph 		case 0113:	/* undefined */
52411431Sralph 			break;
52511431Sralph 
52611431Sralph 		case 0114:	/* lead backward */
52711431Sralph 			verd = 1;
52811431Sralph 			break;
52911431Sralph 
53011431Sralph 		case 0115:	/* undefined */
53111431Sralph reset:
53211431Sralph 			c = lines % PAGE_LINES;
53311431Sralph 			while (c < FF_LINES) {
53411431Sralph 				slop_lines(min(FF_LINES - c, NLINES));
53511431Sralph 				c = lines % PAGE_LINES;
53611431Sralph 			}
53711431Sralph 			new_page(PAGE_LINES - c);
53811431Sralph 			break;
53911431Sralph 
54011431Sralph 		case 0116:
54111431Sralph 			lead = (getchar() & 0377) * 64;
54211431Sralph 			goto leadin;
54311431Sralph 
54411431Sralph 		case 0117:
54511431Sralph 			break;
54611431Sralph 
54711431Sralph 		default:
54811431Sralph 			if ((c & 0340) == 0140)	/* leading */ {
54911431Sralph 				lead = (~c) & 037;
55011431Sralph leadin:
55111431Sralph 				if (verd)
55211431Sralph 					lead = -lead;
55311431Sralph 				row += lead*3;	/*  Lead is 3 units  */
55411431Sralph 				xpos = CONVERT(row);
55511431Sralph 				continue;
55611431Sralph 			}
55711431Sralph 			if ((c & 0360) == 0120)	/* size change */ {
55811431Sralph 				loadfont(railmag, findsize(c & 017));
55911431Sralph 				continue;
56011431Sralph 			}
56111431Sralph 			if (c & 0300)
56211431Sralph 				continue;
56311431Sralph 
56411431Sralph normal_char:
56512468Sralph 			if (row < 0 || CONVERT(row) >= BYTES_PER_LINE * 8)
56611431Sralph 				continue;
56711431Sralph 			c = (c & 077) | mcase;
56811431Sralph 			outc(c);
56911431Sralph 		}
57011431Sralph 	}
57111431Sralph out:
57211431Sralph 	slop_lines(NLINES);
57311431Sralph }
57411431Sralph 
findsize(code)57511431Sralph findsize(code)
57611431Sralph 	register int code;
57711431Sralph {
57811431Sralph 	register struct point_sizes *psp;
57911431Sralph 
58011431Sralph 	psp = point_sizes;
58111431Sralph 	while (psp->real_code != 0) {
58211431Sralph 		if ((psp->stupid_code & 017) == code)
58311431Sralph 			break;
58411431Sralph 		psp++;
58511431Sralph 	}
58611431Sralph 	code = 0;
58711431Sralph 	if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
58811431Sralph 		code = -55;
58911431Sralph 	else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
59011431Sralph 		code = 55;
59111431Sralph 	if (back)
59211431Sralph 		code = -code;
59311431Sralph 	esc += code;
59411431Sralph 	last_ssize = psp->stupid_code;
59512125Sralph 	return(psp->real_code);
59611431Sralph }
59711431Sralph 
account(who,from,acctfile)59811431Sralph account(who, from, acctfile)
59911431Sralph 	char *who, *from, *acctfile;
60011431Sralph {
60111431Sralph 	register FILE *a;
60211431Sralph 
60311431Sralph 	if (who == NULL || acctfile == NULL)
60411431Sralph 		return;
60511431Sralph 	if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
60611431Sralph 		return;
60711431Sralph 	/*
60812125Sralph 	 * Varian accounting is done by 8.5 inch pages;
60911431Sralph 	 * Versatec accounting is by the (12 inch) foot.
61011431Sralph 	 */
61116166Sralph 	fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES);
61211431Sralph 	if (from != NULL)
61311431Sralph 		fprintf(a, "%s:", from);
61411431Sralph 	fprintf(a, "%s\n", who);
61511431Sralph 	fclose(a);
61611431Sralph }
61711431Sralph 
crail(nrail)61811431Sralph crail(nrail)
61911431Sralph 	register int nrail;
62011431Sralph {
62111431Sralph 	register int psize;
62211431Sralph 
62311431Sralph 	psize = cpsize;
62411431Sralph 	if (fontwanted && psize != npsize)
62511431Sralph 		psize = npsize;
62611431Sralph 	loadfont(nrail, psize);
62711431Sralph }
62811431Sralph 
62911431Sralph 
loadfont(fnum,size)63011431Sralph loadfont(fnum, size)
63111431Sralph 	register int fnum;
63211431Sralph 	register int size;
63311431Sralph {
63411431Sralph 	register int i;
63511431Sralph 	char cbuf[80];
63611431Sralph 
63711431Sralph 	fontwanted = 0;
63811431Sralph 	if (fnum == cfnum && size == cpsize)
63911431Sralph 		return(0);
64011431Sralph 	for (i = 0; i < NFONTS; i++)
64111431Sralph 		if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
64211431Sralph 			cfnum = fontdes[i].fnum;
64311431Sralph 			cpsize = fontdes[i].psize;
64411431Sralph 			dispatch = &fontdes[i].disp[0];
64511431Sralph 			bits = fontdes[i].bits;
64611431Sralph 			cfont = i;
64712125Sralph 			return(0);
64811431Sralph 		}
64911431Sralph 	if (fnum < 0 || fnum >= MAXF) {
65011431Sralph 		fprintf(stderr, "rvcat: Internal error: illegal font\n");
65111431Sralph 		return(-1);
65211431Sralph 	}
65311431Sralph 	nfontnum = fnum;
65411431Sralph 	npsize = size;
65511431Sralph 	fontwanted++;
65612125Sralph 	return(0);
65711431Sralph }
65811431Sralph 
65911431Sralph 
getfont()66011431Sralph getfont()
66111431Sralph {
66211431Sralph 	register int fnum, size, font;
66311431Sralph 	int d;
66411431Sralph 	char cbuf[BUFSIZ];
66511431Sralph 	char *cp = cbuf;
66611431Sralph 	char *dp;
66711431Sralph 
66811431Sralph 	if (!fontwanted)
66911431Sralph 		return(0);
67011431Sralph 	fnum = nfontnum;
67111431Sralph 	size = npsize;
67211431Sralph 	sprintf(cbuf, "%s.%dr", fontname[fnum], size);
67311431Sralph 	font = open(cbuf, 0);
67411431Sralph 	if (font == -1) {
67511580Sralph 		fprintf(stderr, "rvcat: ");
67611431Sralph 		perror(cbuf);
67711431Sralph 		fontwanted = 0;
67812125Sralph 		return(-1);
67911431Sralph 	}
68011431Sralph 	if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
68111431Sralph 		fprintf(stderr, "rvcat: %s: Bad font file", cbuf);
68211431Sralph 	else {
68311431Sralph 		cfont = relfont();
68411431Sralph 		if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
68511431Sralph 			&& ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
68611431Sralph 				fprintf(stderr, "rvcat: %s: ran out of memory\n", cbuf);
68711431Sralph 				exit(2);
68811431Sralph 		} else {
68911431Sralph 			/*
69011431Sralph 			 * have allocated one chunk of mem for font, dispatch.
69111431Sralph 			 * get the dispatch addr, align to word boundary.
69211431Sralph 			 */
69311431Sralph 			d = (int) bits+header.size;
69411431Sralph 			d += 1;
69511431Sralph 			d &= ~1;
69611431Sralph 			if (read(font, d, DSIZ)!=DSIZ
69711431Sralph 			  || read(font, bits, header.size)!=header.size)
69811431Sralph 				fprintf(stderr, "rvcat: bad font header");
69911431Sralph 			else {
70011431Sralph 				close(font);
70111431Sralph 				cfnum = fontdes[cfont].fnum = fnum;
70211431Sralph 				cpsize = fontdes[cfont].psize = size;
70311431Sralph 				fontdes[cfont].bits = bits;
70411431Sralph 				fontdes[cfont].disp = (struct dispatch *) d;
70511431Sralph 				dispatch = &fontdes[cfont].disp[0];
70611431Sralph 				fontwanted = 0;
70712125Sralph 				return(0);
70811431Sralph 			}
70911431Sralph 		}
71011431Sralph 	}
71111431Sralph 	close(font);
71211431Sralph 	fontwanted = 0;
71311431Sralph 	return(-1);
71411431Sralph }
71511431Sralph 
71612125Sralph int lastloaded = -1;
71711431Sralph 
relfont()71811431Sralph relfont()
71911431Sralph {
72011431Sralph 	register int newfont;
72111431Sralph 
72211431Sralph 	newfont = lastloaded;
72311431Sralph 	/*
72411431Sralph 	 * optimization for special font.  since we think that usually
72511431Sralph 	 * there is only one character at a time from any special math
72611431Sralph 	 * font, make it the candidate for removal.
72711431Sralph 	 */
72811431Sralph 	if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
72911431Sralph 		if (++newfont>=NFONTS)
73011431Sralph 			newfont = 0;
73111431Sralph 	lastloaded = newfont;
73211431Sralph 	if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0)
73311431Sralph 		nfree(fontdes[newfont].bits);
73411431Sralph 	fontdes[newfont].bits = 0;
73512125Sralph 	return(newfont);
73611431Sralph }
73711431Sralph 
73811431Sralph char *
allpanic(nbytes)73911431Sralph allpanic(nbytes)
74011431Sralph 	int nbytes;
74111431Sralph {
74211431Sralph 	register int i;
74311431Sralph 
74411431Sralph 	for (i = 0; i <= NFONTS; i++)
74511431Sralph 		if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
74611431Sralph 			nfree(fontdes[i].bits);
74711431Sralph 	lastloaded = cfont;
74811431Sralph 	for (i = 0; i <= NFONTS; i++) {
74911431Sralph 		fontdes[i].fnum = fontdes[i].psize = -1;
75011431Sralph 		fontdes[i].bits = 0;
75111431Sralph 		cfnum = cpsize = -1;
75211431Sralph 	}
75311431Sralph 	return(nalloc(nbytes,1));
75411431Sralph }
75511431Sralph 
75611431Sralph int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
75711431Sralph 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
75811431Sralph int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
75911431Sralph 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
76011431Sralph int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
76111431Sralph 
outc(code)76211431Sralph outc(code)
76311431Sralph 	int code;
76411431Sralph {
76511431Sralph 	char c;				/* character to print */
76611431Sralph 	register struct dispatch *d;	/* ptr to character font record */
76711431Sralph 	register char *addr;		/* addr of font data */
76811431Sralph 	int llen;			/* length of each font line */
76911431Sralph 	int nlines;			/* number of font lines */
77011431Sralph 	register char *scanp;		/* ptr to output buffer */
77111431Sralph 	int scanp_inc;			/* increment to start of next buffer */
77211431Sralph 	int offset;			/* bit offset to start of font data */
77311431Sralph 	int i;				/* loop counter */
77411431Sralph 	register int count;		/* font data ptr */
77511431Sralph 	register unsigned fontdata;	/* font data temporary */
77611431Sralph 	register int off8;		/* offset + 8 */
77711431Sralph 	int b0poff;			/* bit offset back towards buf0p */
77811431Sralph 
77911431Sralph 	if (fontwanted)
78011431Sralph 		getfont();
78111431Sralph 	if (railmag == SPECIALFONT) {
78211431Sralph 		if ((c = spectab[code]) < 0)
78311431Sralph 			return(0);
78411431Sralph 	} else if ((c = asctab[code]) < 0)
78511431Sralph 		return(0);
78611431Sralph 	d = dispatch+c;
78711431Sralph 	if (d->nbytes) {
78811431Sralph 		addr = bits+d->addr;
78911431Sralph 		llen = (d->down+d->up+7)/8;
79011431Sralph 		nlines = d->left+d->right;
79111431Sralph 		if (ypos+d->right >= NLINES)
79211431Sralph 			slop_lines(ypos+d->right-NLINES+6);
79311431Sralph 		b0poff = BYTES_PER_LINE*8 - 1 - (xpos+d->down);
79411431Sralph 		scanp = ((ypos-d->left-1)*BYTES_PER_LINE+b0poff/8)+buf0p;
79511431Sralph 		if (scanp < &buffer[0])
79611431Sralph 			scanp += BUFFER_SIZE;
79711431Sralph 		scanp_inc = BYTES_PER_LINE-llen;
79811431Sralph 		offset = -(b0poff&07);
79911431Sralph 		off8 = offset+8;
80011431Sralph 		for (i = 0; i < nlines; i++) {
80111431Sralph 			if (scanp >= &buffer[BUFFER_SIZE])
80211431Sralph 				scanp -= BUFFER_SIZE;
80311431Sralph 			count = llen;
80411431Sralph 			if (scanp + count <= &buffer[BUFFER_SIZE])
80511431Sralph 				do {
80611431Sralph 					fontdata = *(unsigned *)addr;
80711431Sralph 					addr += 4;
80811431Sralph 					if (count < 4)
80911431Sralph 						fontdata &= ~strim[count];
81011431Sralph 					*(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
81111431Sralph 					scanp++;
81211431Sralph 					*(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
81311431Sralph 					scanp += 3;
81411431Sralph 					count -= 4;
81511431Sralph 				} while (count > 0);
81611431Sralph 			scanp += scanp_inc+count;
81711431Sralph 			addr += count;
81811431Sralph 		}
81912125Sralph 		return(1);
82011431Sralph 	}
82112125Sralph 	return(0);
82211431Sralph }
82311431Sralph 
slop_lines(ncols)82411431Sralph slop_lines(ncols)
82511431Sralph 	int ncols;
82611431Sralph {
82711431Sralph 	register int i, rcols;
82811431Sralph 
82911431Sralph 	lines += ncols;
83011431Sralph 	rcols = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
83111431Sralph 	if (rcols < ncols) {
83211431Sralph 		if (write(vc, buf0p, BYTES_PER_LINE * rcols) < 0)
83311431Sralph 			exit(1);
83429928Smckusick 		bzero(buf0p, rcols * BYTES_PER_LINE);
83511431Sralph 		buf0p = buffer;
83611431Sralph 		ncols -= rcols;
83711431Sralph 		ypos -= rcols;
83811431Sralph 		col -= RECONVERT(rcols);
83911431Sralph 	}
84011431Sralph 	if (write(vc, buf0p, BYTES_PER_LINE * ncols) < 0)
84111431Sralph 		exit(1);
84229928Smckusick 	bzero(buf0p, BYTES_PER_LINE * ncols);
84311431Sralph 	buf0p += BYTES_PER_LINE * ncols;
84411431Sralph 	if (buf0p >= &buffer[BUFFER_SIZE])
84511431Sralph 		buf0p -= BUFFER_SIZE;
84611431Sralph 	ypos -= ncols;
84711431Sralph 	col -= RECONVERT(ncols);
84811431Sralph }
84911431Sralph 
85011431Sralph /* Start a new page by formfeeding, resetting buffer and column counters. */
new_page(lines_left)85111431Sralph new_page(lines_left)
85211431Sralph 	int lines_left;		/* ... on page. */
85311431Sralph {
85411431Sralph 	lines += lines_left;
85511431Sralph 	buf0p = buffer;		/* Clear out buffer and reset pointers. */
85629928Smckusick 	bzero(buf0p, BYTES_PER_LINE * NLINES);
85711431Sralph 	row = 0;
85811431Sralph 	col = 0;
85911431Sralph 	xpos = CONVERT(row);
86011431Sralph 	ypos = 0;
86111431Sralph 	ioctl(vc, VSETSTATE, prtmode);
86211431Sralph 	write (vc, "\f", 2);
86311431Sralph 	ioctl(vc, VSETSTATE, pltmode);
86411431Sralph }
86511431Sralph 
86611431Sralph char *
nalloc(i,j)86711431Sralph nalloc(i, j)
86811431Sralph 	int i, j;
86911431Sralph {
87011431Sralph 	register char *cp;
87111431Sralph 
87211431Sralph 	cp = calloc(i, j);
87311431Sralph 	return(cp);
87411431Sralph }
87511431Sralph 
nfree(cp)87611431Sralph nfree(cp)
87711431Sralph 	char *cp;
87811431Sralph {
87911431Sralph 	free(cp);
88011431Sralph }
881