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