xref: /original-bsd/old/vfilters/vcat/vcat.c (revision e59fb703)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)vcat.c	5.6 (Berkeley) 02/15/91";
16 #endif /* not lint */
17 
18 /*
19  * Cat Simulator for Versatec and Varian
20  */
21 
22 #include <stdio.h>
23 #include <sys/vcmd.h>
24 #include <vfont.h>
25 
26 int	prtmode[] = {VPRINT};
27 int	pltmode[] = {VPLOT};
28 
29 #define DISPATCHSIZE		256	/* must be a power of two */
30 #define CHARMASK		(DISPATCHSIZE-1)
31 #define NFONTS			25
32 #define SPECIALFONT		3
33 #define DSIZ			((sizeof *dispatch)*DISPATCHSIZE)
34 #define MAXF			4
35 
36 #define LOCAL_RAILMAG		".railmag"
37 #define GLOBAL_RAILMAG		"/usr/lib/vfont/railmag"
38 
39 #define CONVERT(n)		(n*(200./432.))
40 #define RECONVERT(n)		(n*(432./200.))
41 
42 #define NLINES			110
43 
44 char	buffer[NLINES * 880];	/* Big enough for versatec */
45 char	*buf0p = &buffer[0];	/* Zero origin in circular buffer */
46 
47 char	*calloc();
48 char	*nalloc();
49 char	*allpanic();
50 
51 struct	header	header;
52 struct dispatch *dispatch;
53 
54 struct	fontdes {
55 	int	fnum;
56 	int	psize;
57 	struct	dispatch *disp;
58 	char	*bits;
59 } fontdes[NFONTS] = {
60 	-1,
61 	-1
62 };
63 
64 struct point_sizes {
65 	int	stupid_code;
66 	int	real_code;
67 } point_sizes[] = {
68 	010, 6,
69 	0, 7,
70 	01, 8,
71 	07, 9,
72 	02, 10,
73 	03, 11,
74 	04, 12,
75 	05, 14,
76 	0211, 16,
77 	06, 18,
78 	0212, 20,
79 	0213, 22,
80 	0214, 24,
81 	0215, 28,
82 	0216, 36,
83 	0, 0
84 };
85 
86 int	lines;
87 
88 int	vc = 1;			/* varian/versatec output file descriptor */
89 int	varian;			/* 0 for versatec, 1 for varian. */
90 int	BYTES_PER_LINE = 880;	/* number of bytes per raster line. */
91 int	PAGE_LINES = 2400;	/* number of raster lines per page. */
92 int	BUFFER_SIZE = NLINES * 880;	/* buffer size. */
93 int	cfnum = -1;
94 int	cpsize = 10;
95 int	cfont = 1;
96 char	*bits;
97 int	nfontnum = -1;
98 int	fontwanted = 1;
99 int	npsize = 10;
100 int	last_ssize = 02;
101 int	xpos, ypos;
102 int	esc, lead, back, verd, mcase, railmag;
103 double	row, col;
104 char	*fontname[MAXF];
105 char	fnbuf[120];
106 char	*scanline;
107 int	linecount;
108 
109 char	asctab[128] = {
110 	'\0',	/*blank*/
111 	'h',	/*h*/
112 	't',	/*t*/
113 	'n',	/*n*/
114 	'm',	/*m*/
115 	'l',	/*l*/
116 	'i',	/*i*/
117 	'z',	/*z*/
118 	's',	/*s*/
119 	'd',	/*d*/
120 	'b',	/*b*/
121 	'x',	/*x*/
122 	'f',	/*f*/
123 	'j',	/*j*/
124 	'u',	/*u*/
125 	'k',	/*k*/
126 	'\0',	/*blank*/
127 	'p',	/*p*/
128 	'\06',	/*_ 3/4 em dash*/
129 	';',	/*;*/
130 	'\0',	/*blank*/
131 	'a',	/*a*/
132 	'\05',	/*rule*/
133 	'c',	/*c*/
134 	'`',	/*` open*/
135 	'e',	/*e*/
136 	'\'',	/*' close*/
137 	'o',	/*o*/
138 	'\021',	/*1/4*/
139 	'r',	/*r*/
140 	'\022',	/*1/2*/
141 	'v',	/*v*/
142 	'-',	/*- hyphen*/
143 	'w',	/*w*/
144 	'q',	/*q*/
145 	'/',	/*/*/
146 	'.',	/*.*/
147 	'g',	/*g*/
148 	'\023',	/*3/4*/
149 	',',	/*,*/
150 	'&',	/*&*/
151 	'y',	/*y*/
152 	'\0',	/*blank*/
153 	'%',	/*%*/
154 	'\0',	/*blank*/
155 	'Q',	/*Q*/
156 	'T',	/*T*/
157 	'O',	/*O*/
158 	'H',	/*H*/
159 	'N',	/*N*/
160 	'M',	/*M*/
161 	'L',	/*L*/
162 	'R',	/*R*/
163 	'G',	/*G*/
164 	'I',	/*I*/
165 	'P',	/*P*/
166 	'C',	/*C*/
167 	'V',	/*V*/
168 	'E',	/*E*/
169 	'Z',	/*Z*/
170 	'D',	/*D*/
171 	'B',	/*B*/
172 	'S',	/*S*/
173 	'Y',	/*Y*/
174 	'\0',	/*blank*/
175 	'F',	/*F*/
176 	'X',	/*X*/
177 	'A',	/*A*/
178 	'W',	/*W*/
179 	'J',	/*J*/
180 	'U',	/*U*/
181 	'K',	/*K*/
182 	'0',	/*0*/
183 	'1',	/*1*/
184 	'2',	/*2*/
185 	'3',	/*3*/
186 	'4',	/*4*/
187 	'5',	/*5*/
188 	'6',	/*6*/
189 	'7',	/*7*/
190 	'8',	/*8*/
191 	'9',	/*9*/
192 	'*',	/***/
193 	'\04',	/*minus*/
194 	'\01',	/*fi*/
195 	'\02',	/*fl*/
196 	'\03',	/*ff*/
197 	'\020',	/* cent sign */
198 	'\012',	/*ffl*/
199 	'\011',	/*ffi*/
200 	'(',	/*(*/
201 	')',	/*)*/
202 	'[',	/*[*/
203 	']',	/*]*/
204 	'\013',	/* degree */
205 	'\014',	/* dagger */
206 	'=',	/*=*/
207 	'\017',	/* registered */
208 	':',	/*:*/
209 	'+',	/*+*/
210 	'\0',	/*blank*/
211 	'!',	/*!*/
212 	'\07',	/* bullet */
213 	'?',	/*?*/
214 	'\015',	/*foot mark*/
215 	'|',	/*|*/
216 	'\0',	/*blank*/
217 	'\016',	/* copyright */
218 	'\010',	/* square */
219 	'$',	/*$*/
220 	'\0',
221 	'\0',
222 	'"',	/*"*/
223 	'#',	/*#*/
224 	'<',	/*<*/
225 	'>',	/*>*/
226 	'@',	/*@*/
227 	'\\',	/*\\*/
228 	'^',	/*^*/
229 	'{',	/*{*/
230 	'}',	/*}*/
231 	'~'	/*~*/
232 };
233 
234 char spectab[128] = {
235 	'\0',	/*blank*/
236 	'w',	/*psi*/
237 	'h',	/*theta*/
238 	'm',	/*nu*/
239 	'l',	/*mu*/
240 	'k',	/*lambda*/
241 	'i',	/*iota*/
242 	'f',	/*zeta*/
243 	'r',	/*sigma*/
244 	'd',	/*delta*/
245 	'b',	/*beta*/
246 	'n',	/*xi*/
247 	'g',	/*eta*/
248 	'u',	/*phi*/
249 	't',	/*upsilon*/
250 	'j',	/*kappa*/
251 	'\0',	/*blank*/
252 	'p',	/*pi*/
253 	'@',	/*at-sign*/
254 	'7',	/*down arrow*/
255 	'\0',	/*blank*/
256 	'a',	/*alpha*/
257 	'|',	/*or*/
258 	'v',	/*chi*/
259 	'"',	/*"*/
260 	'e',	/*epsilon*/
261 	'=',	/*=*/
262 	'o',	/*omicron*/
263 	'4',	/*left arrow*/
264 	'q',	/*rho*/
265 	'6',	/*up arrow*/
266 	's',	/*tau*/
267 	'_',	/*underrule*/
268 	'\\',	/*\*/
269 	'W',	/*Psi*/
270 	'\07',	/*bell system sign*/
271 	'\001',	/*infinity*/
272 	'c',	/*gamma*/
273 	'\002',	/*improper superset*/
274 	'\003',	/*proportional to*/
275 	'\004',	/*right hand*/
276 	'x',	/*omega*/
277 	'\0',	/*blank*/
278 	'(',	/*gradient*/
279 	'\0',	/*blank*/
280 	'U',	/*Phi*/
281 	'H',	/*Theta*/
282 	'X',	/*Omega*/
283 	'\005',	/*cup (union)*/
284 	'\006',	/*root en*/
285 	'\014',	/*terminal sigma*/
286 	'K',	/*Lambda*/
287 	'-',	/*minus*/
288 	'C',	/*Gamma*/
289 	'\015',	/*integral sign*/
290 	'P',	/*Pi*/
291 	'\032',	/*subset of*/
292 	'\033',	/*superset of*/
293 	'2',	/*approximates*/
294 	'y',	/*partial derivative*/
295 	'D',	/*Delta*/
296 	'\013',	/*square root*/
297 	'R',	/*Sigma*/
298 	'1',	/*approx =*/
299 	'\0',	/*blank*/
300 	'>',	/*>*/
301 	'N',	/*Xi*/
302 	'<',	/*<*/
303 	'\016',	/*slash (longer)*/
304 	'\034',	/*cap (intersection)*/
305 	'T',	/*Upsilon*/
306 	'\035',	/*not*/
307 	'\023',	/*right ceiling (rt of ")*/
308 	'\024',	/*left top (of big curly)*/
309 	'\017',	/*bold vertical*/
310 	'\030',	/*left center of big curly bracket*/
311 	'\025',	/*left bottom*/
312 	'\026',	/*right top*/
313 	'\031',	/*right center of big curly bracket*/
314 	'\027',	/*right bot*/
315 	'\021',	/*right floor (rb of ")*/
316 	'\020',	/*left floor (left bot of big sq bract)*/
317 	'\022',	/*left ceiling (lt of ")*/
318 	'*',	/*multiply*/
319 	'/',	/*divide*/
320 	'\010',	/*plus-minus*/
321 	'\011',	/*<=*/
322 	'\012',	/*>=*/
323 	'0',	/*identically equal*/
324 	'3',	/*not equal*/
325 	'{',	/*{*/
326 	'}',	/*}*/
327 	'\'',	/*' acute accent*/
328 	'`',	/*` grave accent*/
329 	'^',	/*^*/
330 	'#',	/*sharp*/
331 	'\036',	/*left hand*/
332 	'\037',	/*member of*/
333 	'~',	/*~*/
334 	'z',	/*empty set*/
335 	'\0',	/*blank*/
336 	'Y',	/*dbl dagger*/
337 	'Z',	/*box rule*/
338 	'9',	/*asterisk*/
339 	'[',	/*improper subset*/
340 	']',	/*circle*/
341 	'\0',	/*blank*/
342 	'+',	/*eqn plus*/
343 	'5',	/*right arrow*/
344 	'8'	/*section mark*/
345 };
346 
347 main(argc, argv)
348 	int argc;
349 	char *argv[];
350 {
351 	char *namearg = NULL;
352 	char *hostarg = NULL;
353 	char *acctfile = NULL;
354 
355 	while (--argc) {
356 		if (*(*++argv) == '-')
357 			switch (argv[0][1]) {
358 			case 'x':
359 				BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
360 				BUFFER_SIZE = NLINES * BYTES_PER_LINE;
361 				varian = BYTES_PER_LINE == 264;
362 				break;
363 
364 			case 'y':
365 				PAGE_LINES = atoi(&argv[0][2]);
366 				break;
367 
368 			case 'n':
369 				if (argc > 1) {
370 					argc--;
371 					namearg = *++argv;
372 				}
373 				break;
374 
375 			case 'h':
376 				if (argc > 1) {
377 					argc--;
378 					hostarg = *++argv;
379 				}
380 				break;
381 			}
382 		else
383 			acctfile = *argv;
384 	}
385 	ioctl(vc, VSETSTATE, pltmode);
386 	readrm();
387 	ofile();
388 	ioctl(vc, VSETSTATE, prtmode);
389 	if (varian)
390 		write(vc, "\f", 2);
391 	else
392 		write(vc, "\n\n\n\n\n", 6);
393 	account(namearg, hostarg, acctfile);
394 	exit(0);
395 }
396 
397 readrm()
398 {
399 	register int i;
400 	register char *cp;
401 	register int rmfd;
402 	char c;
403 
404 	if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
405 		if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
406 			fprintf(stderr, "vcat: No railmag file\n");
407 			exit(2);
408 		}
409 	cp = fnbuf;
410 	for (i = 0; i < MAXF; i++) {
411 		fontname[i] = cp;
412 		while (read(rmfd, &c, 1) == 1 && c != '\n')
413 			*cp++ = c;
414 		*cp++ = '\0';
415 	}
416 	close(rmfd);
417 }
418 
419 ofile()
420 {
421 	register int c;
422 	double scol;
423 	static int initialized;
424 
425 	lines = 0;
426 	while ((c = getchar()) != EOF) {
427 		if (!c)
428 			continue;
429 		if (c & 0200) {
430 			esc += (~c) & 0177;
431 			continue;
432 		}
433 		if (esc) {
434 			if (back)
435 				esc = -esc;
436 			col += esc;
437 			ypos = CONVERT(col);
438 			esc = 0;
439 		}
440 		if ((c & 0377) < 0100)	/*  Purely for efficiency  */
441 			goto normal_char;
442 		switch (c) {
443 
444 		case 0100:
445 			if (initialized)
446 				goto out;
447 			initialized = 1;
448 			row = 25;
449 			xpos = CONVERT(row);
450 			for (c = 0; c < BUFFER_SIZE; c++)
451 				buffer[c] = 0;
452 			col = 0;
453 			esc = 0;
454 			lead = 0;
455 			ypos = 0;
456 			linecount = 0;
457 			verd = 0;
458 			back = 0;
459 			mcase = 0;
460 			railmag = 0;
461 			if (loadfont(railmag, cpsize) < 0)
462 				fprintf(stderr, "vcat: Can't load inital font\n");
463 			break;
464 
465 		case 0101:	/* lower rail */
466 			crail(railmag &= ~01);
467 			break;
468 
469 		case 0102:	/* upper rail */
470 			crail(railmag |= 01);
471 			break;
472 
473 		case 0103:	/* upper mag */
474 			crail(railmag |= 02);
475 			break;
476 
477 		case 0104:	/* lower mag */
478 			crail(railmag &= ~02);
479 			break;
480 
481 		case 0105:	/* lower case */
482 			mcase = 0;
483 			break;
484 
485 		case 0106:	/* upper case */
486 			mcase = 0100;
487 			break;
488 
489 		case 0107:	/* escape forward */
490 			back = 0;
491 			break;
492 
493 		case 0110:	/* escape backwards */
494 			back = 1;
495 			break;
496 
497 		case 0111:	/* stop */
498 			break;
499 
500 		case 0112:	/* lead forward */
501 			verd = 0;
502 			break;
503 
504 		case 0113:	/* undefined */
505 			break;
506 
507 		case 0114:	/* lead backward */
508 			verd = 1;
509 			break;
510 
511 		case 0115:	/* undefined */
512 		case 0116:
513 		case 0117:
514 			break;
515 
516 		default:
517 			if ((c & 0340) == 0140)	/* leading */ {
518 				lead = (~c) & 037;
519 				if (verd)
520 					lead = -lead;
521 				row += lead*3;	/*  Lead is 3 units  */
522 				c = CONVERT(row);
523 				while (c >= NLINES) {
524 					slop_lines(15);
525 					c = CONVERT(row);
526 				}
527 				xpos = c;
528 				continue;
529 			}
530 			if ((c & 0360) == 0120)	/* size change */ {
531 				loadfont(railmag, findsize(c & 017));
532 				continue;
533 			}
534 			if (c & 0300)
535 				continue;
536 
537 normal_char:
538 			c = (c & 077) | mcase;
539 			outc(c);
540 		}
541 	}
542 out:
543 	slop_lines(NLINES);
544 }
545 
546 findsize(code)
547 	register int code;
548 {
549 	register struct point_sizes *psp;
550 
551 	psp = point_sizes;
552 	while (psp->real_code != 0) {
553 		if ((psp->stupid_code & 017) == code)
554 			break;
555 		psp++;
556 	}
557 	code = 0;
558 	if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
559 		code = -55;
560 	else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
561 		code = 55;
562 	if (back)
563 		code = -code;
564 	esc += code;
565 	last_ssize = psp->stupid_code;
566 	return(psp->real_code);
567 }
568 
569 account(who, from, acctfile)
570 	char *who, *from, *acctfile;
571 {
572 	register FILE *a;
573 
574 	if (who == NULL || acctfile == NULL)
575 		return;
576 	if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
577 		return;
578 	/*
579 	 * Varian accounting is done by 8.5 inch pages;
580 	 * Versatec accounting is by the (12 inch) foot.
581 	 */
582 	fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES);
583 	if (from != NULL)
584 		fprintf(a, "%s:", from);
585 	fprintf(a, "%s\n", who);
586 	fclose(a);
587 }
588 
589 crail(nrail)
590 	register int nrail;
591 {
592 	register int psize;
593 
594 	psize = cpsize;
595 	if (fontwanted && psize != npsize)
596 		psize = npsize;
597 	loadfont(nrail, psize);
598 }
599 
600 
601 loadfont(fnum, size)
602 	register int fnum;
603 	register int size;
604 {
605 	register int i;
606 	char cbuf[80];
607 
608 	fontwanted = 0;
609 	if (fnum == cfnum && size == cpsize)
610 		return(0);
611 	for (i = 0; i < NFONTS; i++)
612 		if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
613 			cfnum = fontdes[i].fnum;
614 			cpsize = fontdes[i].psize;
615 			dispatch = &fontdes[i].disp[0];
616 			bits = fontdes[i].bits;
617 			cfont = i;
618 			return(0);
619 		}
620 	if (fnum < 0 || fnum >= MAXF) {
621 		fprintf(stderr, "vcat: Internal error: illegal font\n");
622 		return(-1);
623 	}
624 	nfontnum = fnum;
625 	npsize = size;
626 	fontwanted++;
627 	return(0);
628 }
629 
630 
631 getfont()
632 {
633 	register int fnum, size, font;
634 	int d;
635 	char cbuf[BUFSIZ];
636 
637 	if (!fontwanted)
638 		return(0);
639 	fnum = nfontnum;
640 	size = npsize;
641 	sprintf(cbuf, "%s.%d", fontname[fnum], size);
642 	font = open(cbuf, 0);
643 	if (font == -1) {
644 		fprintf(stderr, "vcat: ");
645 		perror(cbuf);
646 		fontwanted = 0;
647 		return(-1);
648 	}
649 	if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
650 		fprintf(stderr, "vcat: %s: Bad font file", cbuf);
651 	else {
652 		cfont = relfont();
653 		if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
654 			&& ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
655 				fprintf(stderr, "vcat: %s: ran out of memory\n", cbuf);
656 				exit(2);
657 		} else {
658 			/*
659 			 * have allocated one chunk of mem for font, dispatch.
660 			 * get the dispatch addr, align to word boundary.
661 			 */
662 			d = (int) bits+header.size;
663 			d += 1;
664 			d &= ~1;
665 			if (read(font, d, DSIZ)!=DSIZ
666 			  || read(font, bits, header.size)!=header.size)
667 				fprintf(stderr, "vcat: bad font header");
668 			else {
669 				close(font);
670 				cfnum = fontdes[cfont].fnum = fnum;
671 				cpsize = fontdes[cfont].psize = size;
672 				fontdes[cfont].bits = bits;
673 				fontdes[cfont].disp = (struct dispatch *) d;
674 				dispatch = &fontdes[cfont].disp[0];
675 				fontwanted = 0;
676 				return(0);
677 			}
678 		}
679 	}
680 	close(font);
681 	fontwanted = 0;
682 	return(-1);
683 }
684 
685 int lastloaded = -1;
686 
687 relfont()
688 {
689 	register int newfont;
690 
691 	newfont = lastloaded;
692 	/*
693 	 * optimization for special font.  since we think that usually
694 	 * there is only one character at a time from any special math
695 	 * font, make it the candidate for removal.
696 	 */
697 	if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
698 		if (++newfont>=NFONTS)
699 			newfont = 0;
700 	lastloaded = newfont;
701 	if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0)
702 		nfree(fontdes[newfont].bits);
703 	fontdes[newfont].bits = 0;
704 	return(newfont);
705 }
706 
707 char *
708 allpanic(nbytes)
709 	int nbytes;
710 {
711 	register int i;
712 
713 	for (i = 0; i <= NFONTS; i++)
714 		if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
715 			nfree(fontdes[i].bits);
716 	lastloaded = cfont;
717 	for (i = 0; i <= NFONTS; i++) {
718 		fontdes[i].fnum = fontdes[i].psize = -1;
719 		fontdes[i].bits = 0;
720 		cfnum = cpsize = -1;
721 	}
722 	return(nalloc(nbytes,1));
723 }
724 
725 int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
726 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
727 int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
728 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
729 int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
730 
731 outc(code)
732 	int code;
733 {
734 	char c;				/* character to print */
735 	register struct dispatch *d;	/* ptr to character font record */
736 	register char *addr;		/* addr of font data */
737 	int llen;			/* length of each font line */
738 	int nlines;			/* number of font lines */
739 	register char *scanp;		/* ptr to output buffer */
740 	int scanp_inc;			/* increment to start of next buffer */
741 	int offset;			/* bit offset to start of font data */
742 	int i;				/* loop counter */
743 	register int count;		/* font data ptr */
744 	register unsigned fontdata;	/* font data temporary */
745 	register int off8;		/* offset + 8 */
746 
747 	if (fontwanted)
748 		getfont();
749 	if (railmag == SPECIALFONT) {
750 		if ((c = spectab[code]) < 0)
751 			return(0);
752 	} else if ((c = asctab[code]) < 0)
753 		return(0);
754 	d = dispatch+c;
755 	if (d->nbytes) {
756 		addr = bits+d->addr;
757 		llen = (d->left+d->right+7)/8;
758 		nlines = d->up+d->down;
759 		if (xpos+d->down >= NLINES)
760 			slop_lines(xpos+d->down-NLINES+1);
761 		scanp = ((xpos-d->up-1)*BYTES_PER_LINE+(ypos-d->left)/8)+buf0p;
762 		if (scanp < &buffer[0])
763 			scanp += BUFFER_SIZE;
764 		scanp_inc = BYTES_PER_LINE-llen;
765 		offset = -((ypos-d->left)&07);
766 		off8 = offset+8;
767 		for (i = 0; i < nlines; i++) {
768 			if (scanp >= &buffer[BUFFER_SIZE])
769 				scanp -= BUFFER_SIZE;
770 			count = llen;
771 			if (scanp + count <= &buffer[BUFFER_SIZE])
772 				do {
773 					fontdata = *(unsigned *)addr;
774 					addr += 4;
775 					if (count < 4)
776 						fontdata &= ~strim[count];
777 					*(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
778 					scanp++;
779 					*(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
780 					scanp += 3;
781 					count -= 4;
782 				} while (count > 0);
783 			scanp += scanp_inc+count;
784 			addr += count;
785 		}
786 		return(1);
787 	}
788 	return(0);
789 }
790 
791 slop_lines(nlines)
792 	int nlines;
793 {
794 	register int i, rlines;
795 
796 	lines += nlines;
797 	rlines = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
798 	if (rlines < nlines) {
799 		if (write(vc, buf0p, BYTES_PER_LINE * rlines) < 0)
800 			exit(1);
801 		bzero(buf0p, rlines * BYTES_PER_LINE);
802 		buf0p = buffer;
803 		nlines -= rlines;
804 		xpos -= rlines;
805 		row -= RECONVERT(rlines);
806 	}
807 	if (write(vc, buf0p, BYTES_PER_LINE * nlines) < 0)
808 		exit(1);
809 	bzero(buf0p, BYTES_PER_LINE * nlines);
810 	buf0p += BYTES_PER_LINE * nlines;
811 	if (buf0p >= &buffer[BUFFER_SIZE])
812 		buf0p -= BUFFER_SIZE;
813 	xpos -= nlines;
814 	row -= RECONVERT(nlines);
815 	/* ioctl(vc, VSETSTATE, pltmode);  WHY? */
816 }
817 
818 char *
819 nalloc(i, j)
820 	int i, j;
821 {
822 	register char *cp;
823 
824 	cp = calloc(i, j);
825 	return(cp);
826 }
827 
828 nfree(cp)
829 	char *cp;
830 {
831 	free(cp);
832 }
833