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