120201Sdist /*
220201Sdist * Copyright (c) 1983 Regents of the University of California.
333682Sbostic * All rights reserved.
433682Sbostic *
542808Sbostic * %sccs.include.redist.c%
620201Sdist */
720201Sdist
813947Ssam #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 */
1313947Ssam
1433682Sbostic #ifndef lint
15*46421Sbostic static char sccsid[] = "@(#)vcat.c 5.6 (Berkeley) 02/15/91";
1633682Sbostic #endif /* not lint */
1733682Sbostic
181847Sroot /*
191847Sroot * Cat Simulator for Versatec and Varian
201847Sroot */
211847Sroot
221847Sroot #include <stdio.h>
231847Sroot #include <sys/vcmd.h>
241847Sroot #include <vfont.h>
251847Sroot
2612124Sralph int prtmode[] = {VPRINT};
2712124Sralph int pltmode[] = {VPLOT};
281847Sroot
291847Sroot #define DISPATCHSIZE 256 /* must be a power of two */
301847Sroot #define CHARMASK (DISPATCHSIZE-1)
311847Sroot #define NFONTS 25
321847Sroot #define SPECIALFONT 3
331847Sroot #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE)
341847Sroot #define MAXF 4
351847Sroot
361847Sroot #define LOCAL_RAILMAG ".railmag"
371847Sroot #define GLOBAL_RAILMAG "/usr/lib/vfont/railmag"
381847Sroot
391847Sroot #define CONVERT(n) (n*(200./432.))
401847Sroot #define RECONVERT(n) (n*(432./200.))
411847Sroot
421847Sroot #define NLINES 110
431847Sroot
4412469Sralph char buffer[NLINES * 880]; /* Big enough for versatec */
4512469Sralph char *buf0p = &buffer[0]; /* Zero origin in circular buffer */
461847Sroot
471847Sroot char *calloc();
481847Sroot char *nalloc();
491847Sroot char *allpanic();
501847Sroot
511847Sroot struct header header;
521847Sroot struct dispatch *dispatch;
531847Sroot
541847Sroot struct fontdes {
551847Sroot int fnum;
561847Sroot int psize;
571847Sroot struct dispatch *disp;
581847Sroot char *bits;
591847Sroot } fontdes[NFONTS] = {
601847Sroot -1,
611847Sroot -1
621847Sroot };
631847Sroot
641847Sroot struct point_sizes {
651847Sroot int stupid_code;
661847Sroot int real_code;
671847Sroot } point_sizes[] = {
681847Sroot 010, 6,
691847Sroot 0, 7,
701847Sroot 01, 8,
711847Sroot 07, 9,
721847Sroot 02, 10,
731847Sroot 03, 11,
741847Sroot 04, 12,
751847Sroot 05, 14,
761847Sroot 0211, 16,
771847Sroot 06, 18,
781847Sroot 0212, 20,
791847Sroot 0213, 22,
801847Sroot 0214, 24,
811847Sroot 0215, 28,
821847Sroot 0216, 36,
831847Sroot 0, 0
841847Sroot };
851847Sroot
861847Sroot int lines;
871847Sroot
8815694Sralph int vc = 1; /* varian/versatec output file descriptor */
8915694Sralph int varian; /* 0 for versatec, 1 for varian. */
9015694Sralph int BYTES_PER_LINE = 880; /* number of bytes per raster line. */
9115694Sralph int PAGE_LINES = 2400; /* number of raster lines per page. */
9215694Sralph int BUFFER_SIZE = NLINES * 880; /* buffer size. */
931847Sroot int cfnum = -1;
941847Sroot int cpsize = 10;
951847Sroot int cfont = 1;
961847Sroot char *bits;
971847Sroot int nfontnum = -1;
981847Sroot int fontwanted = 1;
991847Sroot int npsize = 10;
1001847Sroot int last_ssize = 02;
1011847Sroot int xpos, ypos;
1021847Sroot int esc, lead, back, verd, mcase, railmag;
1031847Sroot double row, col;
1041847Sroot char *fontname[MAXF];
1051847Sroot char fnbuf[120];
1061847Sroot char *scanline;
1071847Sroot int linecount;
1081847Sroot
1091847Sroot char asctab[128] = {
1101847Sroot '\0', /*blank*/
1111847Sroot 'h', /*h*/
1121847Sroot 't', /*t*/
1131847Sroot 'n', /*n*/
1141847Sroot 'm', /*m*/
1151847Sroot 'l', /*l*/
1161847Sroot 'i', /*i*/
1171847Sroot 'z', /*z*/
1181847Sroot 's', /*s*/
1191847Sroot 'd', /*d*/
1201847Sroot 'b', /*b*/
1211847Sroot 'x', /*x*/
1221847Sroot 'f', /*f*/
1231847Sroot 'j', /*j*/
1241847Sroot 'u', /*u*/
1251847Sroot 'k', /*k*/
1261847Sroot '\0', /*blank*/
1271847Sroot 'p', /*p*/
1281847Sroot '\06', /*_ 3/4 em dash*/
1291847Sroot ';', /*;*/
1301847Sroot '\0', /*blank*/
1311847Sroot 'a', /*a*/
1321847Sroot '\05', /*rule*/
1331847Sroot 'c', /*c*/
1341847Sroot '`', /*` open*/
1351847Sroot 'e', /*e*/
1361847Sroot '\'', /*' close*/
1371847Sroot 'o', /*o*/
1381847Sroot '\021', /*1/4*/
1391847Sroot 'r', /*r*/
1401847Sroot '\022', /*1/2*/
1411847Sroot 'v', /*v*/
1421847Sroot '-', /*- hyphen*/
1431847Sroot 'w', /*w*/
1441847Sroot 'q', /*q*/
1451847Sroot '/', /*/*/
1461847Sroot '.', /*.*/
1471847Sroot 'g', /*g*/
1481847Sroot '\023', /*3/4*/
1491847Sroot ',', /*,*/
1501847Sroot '&', /*&*/
1511847Sroot 'y', /*y*/
1521847Sroot '\0', /*blank*/
1531847Sroot '%', /*%*/
1541847Sroot '\0', /*blank*/
1551847Sroot 'Q', /*Q*/
1561847Sroot 'T', /*T*/
1571847Sroot 'O', /*O*/
1581847Sroot 'H', /*H*/
1591847Sroot 'N', /*N*/
1601847Sroot 'M', /*M*/
1611847Sroot 'L', /*L*/
1621847Sroot 'R', /*R*/
1631847Sroot 'G', /*G*/
1641847Sroot 'I', /*I*/
1651847Sroot 'P', /*P*/
1661847Sroot 'C', /*C*/
1671847Sroot 'V', /*V*/
1681847Sroot 'E', /*E*/
1691847Sroot 'Z', /*Z*/
1701847Sroot 'D', /*D*/
1711847Sroot 'B', /*B*/
1721847Sroot 'S', /*S*/
1731847Sroot 'Y', /*Y*/
1741847Sroot '\0', /*blank*/
1751847Sroot 'F', /*F*/
1761847Sroot 'X', /*X*/
1771847Sroot 'A', /*A*/
1781847Sroot 'W', /*W*/
1791847Sroot 'J', /*J*/
1801847Sroot 'U', /*U*/
1811847Sroot 'K', /*K*/
1821847Sroot '0', /*0*/
1831847Sroot '1', /*1*/
1841847Sroot '2', /*2*/
1851847Sroot '3', /*3*/
1861847Sroot '4', /*4*/
1871847Sroot '5', /*5*/
1881847Sroot '6', /*6*/
1891847Sroot '7', /*7*/
1901847Sroot '8', /*8*/
1911847Sroot '9', /*9*/
1921847Sroot '*', /***/
1931847Sroot '\04', /*minus*/
1941847Sroot '\01', /*fi*/
1951847Sroot '\02', /*fl*/
1961847Sroot '\03', /*ff*/
1971847Sroot '\020', /* cent sign */
1981847Sroot '\012', /*ffl*/
1991847Sroot '\011', /*ffi*/
2001847Sroot '(', /*(*/
2011847Sroot ')', /*)*/
2021847Sroot '[', /*[*/
2031847Sroot ']', /*]*/
2041847Sroot '\013', /* degree */
2051847Sroot '\014', /* dagger */
2061847Sroot '=', /*=*/
2071847Sroot '\017', /* registered */
2081847Sroot ':', /*:*/
2091847Sroot '+', /*+*/
2101847Sroot '\0', /*blank*/
2111847Sroot '!', /*!*/
2121847Sroot '\07', /* bullet */
2131847Sroot '?', /*?*/
2141847Sroot '\015', /*foot mark*/
2151847Sroot '|', /*|*/
2161847Sroot '\0', /*blank*/
2171847Sroot '\016', /* copyright */
2181847Sroot '\010', /* square */
2191847Sroot '$', /*$*/
2201847Sroot '\0',
2211847Sroot '\0',
2221847Sroot '"', /*"*/
2231847Sroot '#', /*#*/
2241847Sroot '<', /*<*/
2251847Sroot '>', /*>*/
2261847Sroot '@', /*@*/
2271847Sroot '\\', /*\\*/
2281847Sroot '^', /*^*/
2291847Sroot '{', /*{*/
2301847Sroot '}', /*}*/
2311847Sroot '~' /*~*/
2321847Sroot };
2331847Sroot
2341847Sroot char spectab[128] = {
2351847Sroot '\0', /*blank*/
2361847Sroot 'w', /*psi*/
2371847Sroot 'h', /*theta*/
2381847Sroot 'm', /*nu*/
2391847Sroot 'l', /*mu*/
2401847Sroot 'k', /*lambda*/
2411847Sroot 'i', /*iota*/
2421847Sroot 'f', /*zeta*/
2431847Sroot 'r', /*sigma*/
2441847Sroot 'd', /*delta*/
2451847Sroot 'b', /*beta*/
2461847Sroot 'n', /*xi*/
2471847Sroot 'g', /*eta*/
2481847Sroot 'u', /*phi*/
2491847Sroot 't', /*upsilon*/
2501847Sroot 'j', /*kappa*/
2511847Sroot '\0', /*blank*/
2521847Sroot 'p', /*pi*/
2531847Sroot '@', /*at-sign*/
2541847Sroot '7', /*down arrow*/
2551847Sroot '\0', /*blank*/
2561847Sroot 'a', /*alpha*/
2571847Sroot '|', /*or*/
2581847Sroot 'v', /*chi*/
2591847Sroot '"', /*"*/
2601847Sroot 'e', /*epsilon*/
2611847Sroot '=', /*=*/
2621847Sroot 'o', /*omicron*/
2631847Sroot '4', /*left arrow*/
2641847Sroot 'q', /*rho*/
2651847Sroot '6', /*up arrow*/
2661847Sroot 's', /*tau*/
2671847Sroot '_', /*underrule*/
2681847Sroot '\\', /*\*/
2691847Sroot 'W', /*Psi*/
2701847Sroot '\07', /*bell system sign*/
2711847Sroot '\001', /*infinity*/
2721847Sroot 'c', /*gamma*/
2731847Sroot '\002', /*improper superset*/
2741847Sroot '\003', /*proportional to*/
2751847Sroot '\004', /*right hand*/
2761847Sroot 'x', /*omega*/
2771847Sroot '\0', /*blank*/
2781847Sroot '(', /*gradient*/
2791847Sroot '\0', /*blank*/
2801847Sroot 'U', /*Phi*/
2811847Sroot 'H', /*Theta*/
2821847Sroot 'X', /*Omega*/
2831847Sroot '\005', /*cup (union)*/
2841847Sroot '\006', /*root en*/
2851847Sroot '\014', /*terminal sigma*/
2861847Sroot 'K', /*Lambda*/
2871847Sroot '-', /*minus*/
2881847Sroot 'C', /*Gamma*/
2891847Sroot '\015', /*integral sign*/
2901847Sroot 'P', /*Pi*/
2911847Sroot '\032', /*subset of*/
2921847Sroot '\033', /*superset of*/
2931847Sroot '2', /*approximates*/
2941847Sroot 'y', /*partial derivative*/
2951847Sroot 'D', /*Delta*/
2961847Sroot '\013', /*square root*/
2971847Sroot 'R', /*Sigma*/
2981847Sroot '1', /*approx =*/
2991847Sroot '\0', /*blank*/
3001847Sroot '>', /*>*/
3011847Sroot 'N', /*Xi*/
3021847Sroot '<', /*<*/
3031847Sroot '\016', /*slash (longer)*/
3041847Sroot '\034', /*cap (intersection)*/
3051847Sroot 'T', /*Upsilon*/
3061847Sroot '\035', /*not*/
3071847Sroot '\023', /*right ceiling (rt of ")*/
3081847Sroot '\024', /*left top (of big curly)*/
3091847Sroot '\017', /*bold vertical*/
3101847Sroot '\030', /*left center of big curly bracket*/
3111847Sroot '\025', /*left bottom*/
3121847Sroot '\026', /*right top*/
3131847Sroot '\031', /*right center of big curly bracket*/
3141847Sroot '\027', /*right bot*/
3151847Sroot '\021', /*right floor (rb of ")*/
3161847Sroot '\020', /*left floor (left bot of big sq bract)*/
3171847Sroot '\022', /*left ceiling (lt of ")*/
3181847Sroot '*', /*multiply*/
3191847Sroot '/', /*divide*/
3201847Sroot '\010', /*plus-minus*/
3211847Sroot '\011', /*<=*/
3221847Sroot '\012', /*>=*/
3231847Sroot '0', /*identically equal*/
3241847Sroot '3', /*not equal*/
3251847Sroot '{', /*{*/
3261847Sroot '}', /*}*/
3271847Sroot '\'', /*' acute accent*/
328*46421Sbostic '`', /*` grave accent*/
3291847Sroot '^', /*^*/
3301847Sroot '#', /*sharp*/
3311847Sroot '\036', /*left hand*/
3321847Sroot '\037', /*member of*/
3331847Sroot '~', /*~*/
3341847Sroot 'z', /*empty set*/
3351847Sroot '\0', /*blank*/
3361847Sroot 'Y', /*dbl dagger*/
3371847Sroot 'Z', /*box rule*/
3381847Sroot '9', /*asterisk*/
3391847Sroot '[', /*improper subset*/
3401847Sroot ']', /*circle*/
3411847Sroot '\0', /*blank*/
3421847Sroot '+', /*eqn plus*/
3431847Sroot '5', /*right arrow*/
3441847Sroot '8' /*section mark*/
3451847Sroot };
3461847Sroot
main(argc,argv)3471847Sroot main(argc, argv)
3481847Sroot int argc;
3491847Sroot char *argv[];
3501847Sroot {
35111581Sralph char *namearg = NULL;
35211581Sralph char *hostarg = NULL;
35311581Sralph char *acctfile = NULL;
3541847Sroot
3551847Sroot while (--argc) {
3561847Sroot if (*(*++argv) == '-')
3571847Sroot switch (argv[0][1]) {
35812469Sralph case 'x':
35912469Sralph BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
36012469Sralph BUFFER_SIZE = NLINES * BYTES_PER_LINE;
36112469Sralph varian = BYTES_PER_LINE == 264;
36212469Sralph break;
3631847Sroot
36412469Sralph case 'y':
36512469Sralph PAGE_LINES = atoi(&argv[0][2]);
36612469Sralph break;
36712469Sralph
3681847Sroot case 'n':
3691847Sroot if (argc > 1) {
3701847Sroot argc--;
3711847Sroot namearg = *++argv;
3721847Sroot }
3731847Sroot break;
3741847Sroot
3751847Sroot case 'h':
3761847Sroot if (argc > 1) {
3771847Sroot argc--;
3781847Sroot hostarg = *++argv;
3791847Sroot }
3801847Sroot break;
3811847Sroot }
3821847Sroot else
3831847Sroot acctfile = *argv;
3841847Sroot }
3851847Sroot ioctl(vc, VSETSTATE, pltmode);
3861847Sroot readrm();
3871847Sroot ofile();
3881847Sroot ioctl(vc, VSETSTATE, prtmode);
3891847Sroot if (varian)
3901847Sroot write(vc, "\f", 2);
3911847Sroot else
3921847Sroot write(vc, "\n\n\n\n\n", 6);
3931847Sroot account(namearg, hostarg, acctfile);
3941847Sroot exit(0);
3951847Sroot }
3961847Sroot
readrm()3971847Sroot readrm()
3981847Sroot {
3991847Sroot register int i;
4001847Sroot register char *cp;
4011847Sroot register int rmfd;
4021847Sroot char c;
4031847Sroot
4041847Sroot if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
4051847Sroot if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
4061847Sroot fprintf(stderr, "vcat: No railmag file\n");
4071847Sroot exit(2);
4081847Sroot }
4091847Sroot cp = fnbuf;
41011581Sralph for (i = 0; i < MAXF; i++) {
4111847Sroot fontname[i] = cp;
4121847Sroot while (read(rmfd, &c, 1) == 1 && c != '\n')
4131847Sroot *cp++ = c;
4141847Sroot *cp++ = '\0';
4151847Sroot }
4161847Sroot close(rmfd);
4171847Sroot }
4181847Sroot
ofile()4191847Sroot ofile()
4201847Sroot {
4211847Sroot register int c;
4221847Sroot double scol;
4231847Sroot static int initialized;
4241847Sroot
4251847Sroot lines = 0;
4261847Sroot while ((c = getchar()) != EOF) {
4271847Sroot if (!c)
4281847Sroot continue;
4291847Sroot if (c & 0200) {
4301847Sroot esc += (~c) & 0177;
4311847Sroot continue;
4321847Sroot }
4331847Sroot if (esc) {
4341847Sroot if (back)
4351847Sroot esc = -esc;
4361847Sroot col += esc;
4371847Sroot ypos = CONVERT(col);
4381847Sroot esc = 0;
4391847Sroot }
4401847Sroot if ((c & 0377) < 0100) /* Purely for efficiency */
4411847Sroot goto normal_char;
4421847Sroot switch (c) {
4431847Sroot
4441847Sroot case 0100:
4451847Sroot if (initialized)
4461847Sroot goto out;
4471847Sroot initialized = 1;
4481847Sroot row = 25;
4491847Sroot xpos = CONVERT(row);
4501847Sroot for (c = 0; c < BUFFER_SIZE; c++)
4511847Sroot buffer[c] = 0;
4521847Sroot col = 0;
4531847Sroot esc = 0;
4541847Sroot lead = 0;
4551847Sroot ypos = 0;
4561847Sroot linecount = 0;
4571847Sroot verd = 0;
4581847Sroot back = 0;
4591847Sroot mcase = 0;
4601847Sroot railmag = 0;
4611847Sroot if (loadfont(railmag, cpsize) < 0)
4621847Sroot fprintf(stderr, "vcat: Can't load inital font\n");
4631847Sroot break;
4641847Sroot
4651847Sroot case 0101: /* lower rail */
4661847Sroot crail(railmag &= ~01);
4671847Sroot break;
4681847Sroot
4691847Sroot case 0102: /* upper rail */
4701847Sroot crail(railmag |= 01);
4711847Sroot break;
4721847Sroot
4731847Sroot case 0103: /* upper mag */
4741847Sroot crail(railmag |= 02);
4751847Sroot break;
4761847Sroot
4771847Sroot case 0104: /* lower mag */
4781847Sroot crail(railmag &= ~02);
4791847Sroot break;
4801847Sroot
4811847Sroot case 0105: /* lower case */
4821847Sroot mcase = 0;
4831847Sroot break;
4841847Sroot
4851847Sroot case 0106: /* upper case */
4861847Sroot mcase = 0100;
4871847Sroot break;
4881847Sroot
4891847Sroot case 0107: /* escape forward */
4901847Sroot back = 0;
4911847Sroot break;
4921847Sroot
4931847Sroot case 0110: /* escape backwards */
4941847Sroot back = 1;
4951847Sroot break;
4961847Sroot
4971847Sroot case 0111: /* stop */
4981847Sroot break;
4991847Sroot
5001847Sroot case 0112: /* lead forward */
5011847Sroot verd = 0;
5021847Sroot break;
5031847Sroot
5041847Sroot case 0113: /* undefined */
5051847Sroot break;
5061847Sroot
5071847Sroot case 0114: /* lead backward */
5081847Sroot verd = 1;
5091847Sroot break;
5101847Sroot
5111847Sroot case 0115: /* undefined */
5121847Sroot case 0116:
5131847Sroot case 0117:
5141847Sroot break;
5151847Sroot
5161847Sroot default:
5171847Sroot if ((c & 0340) == 0140) /* leading */ {
5181847Sroot lead = (~c) & 037;
5191847Sroot if (verd)
5201847Sroot lead = -lead;
5211847Sroot row += lead*3; /* Lead is 3 units */
5221847Sroot c = CONVERT(row);
5231847Sroot while (c >= NLINES) {
5241847Sroot slop_lines(15);
5251847Sroot c = CONVERT(row);
5261847Sroot }
5271847Sroot xpos = c;
5281847Sroot continue;
5291847Sroot }
5301847Sroot if ((c & 0360) == 0120) /* size change */ {
5311847Sroot loadfont(railmag, findsize(c & 017));
5321847Sroot continue;
5331847Sroot }
5341847Sroot if (c & 0300)
5351847Sroot continue;
5361847Sroot
5371847Sroot normal_char:
5381847Sroot c = (c & 077) | mcase;
5391847Sroot outc(c);
5401847Sroot }
5411847Sroot }
5421847Sroot out:
5431847Sroot slop_lines(NLINES);
5441847Sroot }
5451847Sroot
findsize(code)5461847Sroot findsize(code)
5471847Sroot register int code;
5481847Sroot {
5491847Sroot register struct point_sizes *psp;
5501847Sroot
5511847Sroot psp = point_sizes;
5521847Sroot while (psp->real_code != 0) {
5531847Sroot if ((psp->stupid_code & 017) == code)
5541847Sroot break;
5551847Sroot psp++;
5561847Sroot }
5571847Sroot code = 0;
5581847Sroot if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
5591847Sroot code = -55;
5601847Sroot else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
5611847Sroot code = 55;
5621847Sroot if (back)
5631847Sroot code = -code;
5641847Sroot esc += code;
5651847Sroot last_ssize = psp->stupid_code;
56612124Sralph return(psp->real_code);
5671847Sroot }
5681847Sroot
account(who,from,acctfile)5691847Sroot account(who, from, acctfile)
5701847Sroot char *who, *from, *acctfile;
5711847Sroot {
5721847Sroot register FILE *a;
5731847Sroot
5741847Sroot if (who == NULL || acctfile == NULL)
5751847Sroot return;
5761847Sroot if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
5771847Sroot return;
5781847Sroot /*
57912124Sralph * Varian accounting is done by 8.5 inch pages;
5801847Sroot * Versatec accounting is by the (12 inch) foot.
5811847Sroot */
58216167Sralph fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES);
5831847Sroot if (from != NULL)
5841847Sroot fprintf(a, "%s:", from);
5851847Sroot fprintf(a, "%s\n", who);
5861847Sroot fclose(a);
5871847Sroot }
5881847Sroot
crail(nrail)5891847Sroot crail(nrail)
5901847Sroot register int nrail;
5911847Sroot {
5921847Sroot register int psize;
5931847Sroot
5941847Sroot psize = cpsize;
5951847Sroot if (fontwanted && psize != npsize)
5961847Sroot psize = npsize;
5971847Sroot loadfont(nrail, psize);
5981847Sroot }
5991847Sroot
6001847Sroot
loadfont(fnum,size)6011847Sroot loadfont(fnum, size)
6021847Sroot register int fnum;
6031847Sroot register int size;
6041847Sroot {
6051847Sroot register int i;
6061847Sroot char cbuf[80];
6071847Sroot
6081847Sroot fontwanted = 0;
6091847Sroot if (fnum == cfnum && size == cpsize)
6101847Sroot return(0);
6111847Sroot for (i = 0; i < NFONTS; i++)
6121847Sroot if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
6131847Sroot cfnum = fontdes[i].fnum;
6141847Sroot cpsize = fontdes[i].psize;
6151847Sroot dispatch = &fontdes[i].disp[0];
6161847Sroot bits = fontdes[i].bits;
6171847Sroot cfont = i;
61812124Sralph return(0);
6191847Sroot }
6201847Sroot if (fnum < 0 || fnum >= MAXF) {
6211847Sroot fprintf(stderr, "vcat: Internal error: illegal font\n");
6221847Sroot return(-1);
6231847Sroot }
6241847Sroot nfontnum = fnum;
6251847Sroot npsize = size;
6261847Sroot fontwanted++;
62712124Sralph return(0);
6281847Sroot }
6291847Sroot
6301847Sroot
getfont()6311847Sroot getfont()
6321847Sroot {
6331847Sroot register int fnum, size, font;
6341847Sroot int d;
6351847Sroot char cbuf[BUFSIZ];
6361847Sroot
6371847Sroot if (!fontwanted)
6381847Sroot return(0);
6391847Sroot fnum = nfontnum;
6401847Sroot size = npsize;
6411847Sroot sprintf(cbuf, "%s.%d", fontname[fnum], size);
6421847Sroot font = open(cbuf, 0);
6431847Sroot if (font == -1) {
64411581Sralph fprintf(stderr, "vcat: ");
6451847Sroot perror(cbuf);
6461847Sroot fontwanted = 0;
64712124Sralph return(-1);
6481847Sroot }
6491847Sroot if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
6501847Sroot fprintf(stderr, "vcat: %s: Bad font file", cbuf);
6511847Sroot else {
6521847Sroot cfont = relfont();
6531847Sroot if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
6541847Sroot && ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
6551847Sroot fprintf(stderr, "vcat: %s: ran out of memory\n", cbuf);
6561847Sroot exit(2);
6571847Sroot } else {
6581847Sroot /*
6591847Sroot * have allocated one chunk of mem for font, dispatch.
6601847Sroot * get the dispatch addr, align to word boundary.
6611847Sroot */
6621847Sroot d = (int) bits+header.size;
6631847Sroot d += 1;
6641847Sroot d &= ~1;
6651847Sroot if (read(font, d, DSIZ)!=DSIZ
6661847Sroot || read(font, bits, header.size)!=header.size)
6671847Sroot fprintf(stderr, "vcat: bad font header");
6681847Sroot else {
6691847Sroot close(font);
6701847Sroot cfnum = fontdes[cfont].fnum = fnum;
6711847Sroot cpsize = fontdes[cfont].psize = size;
6721847Sroot fontdes[cfont].bits = bits;
6731847Sroot fontdes[cfont].disp = (struct dispatch *) d;
6741847Sroot dispatch = &fontdes[cfont].disp[0];
6751847Sroot fontwanted = 0;
67612124Sralph return(0);
6771847Sroot }
6781847Sroot }
6791847Sroot }
6801847Sroot close(font);
6811847Sroot fontwanted = 0;
6821847Sroot return(-1);
6831847Sroot }
6841847Sroot
68512124Sralph int lastloaded = -1;
6861847Sroot
relfont()6871847Sroot relfont()
6881847Sroot {
6891847Sroot register int newfont;
6901847Sroot
6911847Sroot newfont = lastloaded;
6921847Sroot /*
6931847Sroot * optimization for special font. since we think that usually
6941847Sroot * there is only one character at a time from any special math
6951847Sroot * font, make it the candidate for removal.
6961847Sroot */
6971847Sroot if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
6981847Sroot if (++newfont>=NFONTS)
6991847Sroot newfont = 0;
7001847Sroot lastloaded = newfont;
7011847Sroot if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0)
7021847Sroot nfree(fontdes[newfont].bits);
7031847Sroot fontdes[newfont].bits = 0;
70412124Sralph return(newfont);
7051847Sroot }
7061847Sroot
7071847Sroot char *
allpanic(nbytes)7081847Sroot allpanic(nbytes)
7091847Sroot int nbytes;
7101847Sroot {
7111847Sroot register int i;
7121847Sroot
7131847Sroot for (i = 0; i <= NFONTS; i++)
7141847Sroot if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
7151847Sroot nfree(fontdes[i].bits);
7161847Sroot lastloaded = cfont;
7171847Sroot for (i = 0; i <= NFONTS; i++) {
7181847Sroot fontdes[i].fnum = fontdes[i].psize = -1;
7191847Sroot fontdes[i].bits = 0;
7201847Sroot cfnum = cpsize = -1;
7211847Sroot }
7221847Sroot return(nalloc(nbytes,1));
7231847Sroot }
7241847Sroot
7251847Sroot int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
7261847Sroot 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
7271847Sroot int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
7281847Sroot 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
7291847Sroot int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
7301847Sroot
outc(code)7311847Sroot outc(code)
7321847Sroot int code;
7331847Sroot {
7341847Sroot char c; /* character to print */
7351847Sroot register struct dispatch *d; /* ptr to character font record */
7361847Sroot register char *addr; /* addr of font data */
7371847Sroot int llen; /* length of each font line */
7381847Sroot int nlines; /* number of font lines */
7391847Sroot register char *scanp; /* ptr to output buffer */
7401847Sroot int scanp_inc; /* increment to start of next buffer */
7411847Sroot int offset; /* bit offset to start of font data */
7421847Sroot int i; /* loop counter */
7431847Sroot register int count; /* font data ptr */
7441847Sroot register unsigned fontdata; /* font data temporary */
7451847Sroot register int off8; /* offset + 8 */
7461847Sroot
7471847Sroot if (fontwanted)
7481847Sroot getfont();
7491847Sroot if (railmag == SPECIALFONT) {
7501847Sroot if ((c = spectab[code]) < 0)
7511847Sroot return(0);
7521847Sroot } else if ((c = asctab[code]) < 0)
7531847Sroot return(0);
7541847Sroot d = dispatch+c;
7551847Sroot if (d->nbytes) {
7561847Sroot addr = bits+d->addr;
7571847Sroot llen = (d->left+d->right+7)/8;
7581847Sroot nlines = d->up+d->down;
7591847Sroot if (xpos+d->down >= NLINES)
7601847Sroot slop_lines(xpos+d->down-NLINES+1);
7611847Sroot scanp = ((xpos-d->up-1)*BYTES_PER_LINE+(ypos-d->left)/8)+buf0p;
7621847Sroot if (scanp < &buffer[0])
7631847Sroot scanp += BUFFER_SIZE;
7641847Sroot scanp_inc = BYTES_PER_LINE-llen;
7651847Sroot offset = -((ypos-d->left)&07);
7661847Sroot off8 = offset+8;
7671847Sroot for (i = 0; i < nlines; i++) {
7681847Sroot if (scanp >= &buffer[BUFFER_SIZE])
7691847Sroot scanp -= BUFFER_SIZE;
7701847Sroot count = llen;
7711847Sroot if (scanp + count <= &buffer[BUFFER_SIZE])
7721847Sroot do {
7731847Sroot fontdata = *(unsigned *)addr;
7741847Sroot addr += 4;
7751847Sroot if (count < 4)
7761847Sroot fontdata &= ~strim[count];
7771847Sroot *(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
7781847Sroot scanp++;
7791847Sroot *(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
7801847Sroot scanp += 3;
7811847Sroot count -= 4;
7821847Sroot } while (count > 0);
7831847Sroot scanp += scanp_inc+count;
7841847Sroot addr += count;
7851847Sroot }
78612124Sralph return(1);
7871847Sroot }
78812124Sralph return(0);
7891847Sroot }
7901847Sroot
slop_lines(nlines)7911847Sroot slop_lines(nlines)
7921847Sroot int nlines;
7931847Sroot {
7941847Sroot register int i, rlines;
7951847Sroot
7961847Sroot lines += nlines;
7971847Sroot rlines = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
7981847Sroot if (rlines < nlines) {
7991847Sroot if (write(vc, buf0p, BYTES_PER_LINE * rlines) < 0)
8001847Sroot exit(1);
80129927Smckusick bzero(buf0p, rlines * BYTES_PER_LINE);
8021847Sroot buf0p = buffer;
8031847Sroot nlines -= rlines;
8041847Sroot xpos -= rlines;
8051847Sroot row -= RECONVERT(rlines);
8061847Sroot }
8071847Sroot if (write(vc, buf0p, BYTES_PER_LINE * nlines) < 0)
8081847Sroot exit(1);
80929927Smckusick bzero(buf0p, BYTES_PER_LINE * nlines);
8101847Sroot buf0p += BYTES_PER_LINE * nlines;
8111847Sroot if (buf0p >= &buffer[BUFFER_SIZE])
8121847Sroot buf0p -= BUFFER_SIZE;
8131847Sroot xpos -= nlines;
8141847Sroot row -= RECONVERT(nlines);
8151847Sroot /* ioctl(vc, VSETSTATE, pltmode); WHY? */
8161847Sroot }
8171847Sroot
8181847Sroot char *
nalloc(i,j)8191847Sroot nalloc(i, j)
8201847Sroot int i, j;
8211847Sroot {
8221847Sroot register char *cp;
8231847Sroot
8241847Sroot cp = calloc(i, j);
8251847Sroot return(cp);
8261847Sroot }
8271847Sroot
nfree(cp)8281847Sroot nfree(cp)
8291847Sroot char *cp;
8301847Sroot {
8311847Sroot free(cp);
8321847Sroot }
833