* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)rvcat.c 5.5 (Berkeley) 6/1/90";
* Cat Simulator for Versatec and Varian
* Modified for Varian with rotated fonts: wnj 5/30/80.
* Takes two extra special codes defined by rvsort:
* 0115 - break for new page, goto (0,0)
* 0116 - lead 64* following byte
int prtmode
[] = {VPRINT
};
#define DISPATCHSIZE 256 /* must be a power of two */
#define CHARMASK (DISPATCHSIZE-1)
#define DSIZ ((sizeof *dispatch)*DISPATCHSIZE)
#define LOCAL_RAILMAG ".railmag"
#define GLOBAL_RAILMAG "/usr/lib/vfont/railmag"
* Here we make up for the fact that we only have 2112
* bits vertically when we need 2200 (11''*200/in), by
* a 4% vertical size squashing.
#define CONVERT(n) ((n*(200./432.))*(2112./2200.))
#define RECONVERT(n) ((n*(432./200.))*(2200./2112.))
#define FF_LINES 1600 /* Scan lines to output before formfeeding. */
#define min(a,b) (a<b ? a : b)
char buffer
[NLINES
* 264]; /* Big enough for varain */
char *buf0p
= &buffer
[0]; /* Zero origin in circular buffer */
struct dispatch
*dispatch
;
int vc
= 1; /* varian/versatec output file descriptor */
int varian
= 1; /* 0 for versatec, 1 for varian. */
int BYTES_PER_LINE
= 264; /* number of bytes per raster line. */
int PAGE_LINES
= 1700; /* number of raster lines per page. */
int BUFFER_SIZE
= NLINES
* 264; /* buffer size. */
int esc
, lead
, back
, verd
, mcase
, railmag
;
'\07', /*bell system sign*/
'\002', /*improper superset*/
'\003', /*proportional to*/
'\014', /*terminal sigma*/
'\015', /*integral sign*/
'y', /*partial derivative*/
'\016', /*slash (longer)*/
'\034', /*cap (intersection)*/
'\023', /*right ceiling (rt of ")*/
'\024', /*left top (of big curly)*/
'\017', /*bold vertical*/
'\030', /*left center of big curly bracket*/
'\031', /*right center of big curly bracket*/
'\021', /*right floor (rb of ")*/
'\020', /*left floor (left bot of big sq bract)*/
'\022', /*left ceiling (lt of ")*/
'0', /*identically equal*/
BYTES_PER_LINE
= atoi(&argv
[0][2]) / 8;
BUFFER_SIZE
= NLINES
* BYTES_PER_LINE
;
PAGE_LINES
= atoi(&argv
[0][2]);
ioctl(vc
, VSETSTATE
, pltmode
);
ioctl(vc
, VSETSTATE
, prtmode
);
write(vc
, "\n\n\n\n\n", 6);
account(namearg
, hostarg
, acctfile
);
if ((rmfd
= open(LOCAL_RAILMAG
, 0)) < 0)
if ((rmfd
= open(GLOBAL_RAILMAG
, 0)) < 0) {
fprintf(stderr
, "rvcat: No railmag file\n");
for (i
= 0; i
< MAXF
; i
++) {
while (read(rmfd
, &c
, 1) == 1 && c
!= '\n')
while ((c
= getchar()) != EOF
) {
if ((c
& 0377) < 0100) /* Purely for efficiency */
if (loadfont(railmag
, cpsize
) < 0)
fprintf(stderr
, "rvcat: Can't load initial font\n");
for (c
= 0; c
< BUFFER_SIZE
; c
++)
case 0101: /* lower rail */
case 0102: /* upper rail */
case 0103: /* upper mag */
case 0104: /* lower mag */
case 0105: /* lower case */
case 0106: /* upper case */
case 0107: /* escape forward */
case 0110: /* escape backwards */
case 0112: /* lead forward */
case 0113: /* undefined */
case 0114: /* lead backward */
case 0115: /* undefined */
slop_lines(min(FF_LINES
- c
, NLINES
));
new_page(PAGE_LINES
- c
);
lead
= (getchar() & 0377) * 64;
if ((c
& 0340) == 0140) /* leading */ {
row
+= lead
*3; /* Lead is 3 units */
if ((c
& 0360) == 0120) /* size change */ {
loadfont(railmag
, findsize(c
& 017));
if (row
< 0 || CONVERT(row
) >= BYTES_PER_LINE
* 8)
register struct point_sizes
*psp
;
while (psp
->real_code
!= 0) {
if ((psp
->stupid_code
& 017) == code
)
if (!(last_ssize
& 0200) && (psp
->stupid_code
& 0200))
else if ((last_ssize
& 0200) && !(psp
->stupid_code
& 0200))
last_ssize
= psp
->stupid_code
;
account(who
, from
, acctfile
)
char *who
, *from
, *acctfile
;
if (who
== NULL
|| acctfile
== NULL
)
if (access(acctfile
, 02) || (a
= fopen(acctfile
, "a")) == NULL
)
* Varian accounting is done by 8.5 inch pages;
* Versatec accounting is by the (12 inch) foot.
fprintf(a
, "t%6.2f\t", (double)lines
/ (double)PAGE_LINES
);
if (fontwanted
&& psize
!= npsize
)
if (fnum
== cfnum
&& size
== cpsize
)
for (i
= 0; i
< NFONTS
; i
++)
if (fontdes
[i
].fnum
== fnum
&& fontdes
[i
].psize
== size
) {
cpsize
= fontdes
[i
].psize
;
dispatch
= &fontdes
[i
].disp
[0];
if (fnum
< 0 || fnum
>= MAXF
) {
fprintf(stderr
, "rvcat: Internal error: illegal font\n");
register int fnum
, size
, font
;
sprintf(cbuf
, "%s.%dr", fontname
[fnum
], size
);
fprintf(stderr
, "rvcat: ");
if (read(font
, &header
, sizeof header
)!=sizeof header
|| header
.magic
!=0436)
fprintf(stderr
, "rvcat: %s: Bad font file", cbuf
);
if (((bits
=nalloc(header
.size
+DSIZ
+1,1))== NULL
)
&& ((bits
=allpanic(header
.size
+DSIZ
+1))== NULL
)) {
fprintf(stderr
, "rvcat: %s: ran out of memory\n", cbuf
);
* have allocated one chunk of mem for font, dispatch.
* get the dispatch addr, align to word boundary.
d
= (int) bits
+header
.size
;
if (read(font
, d
, DSIZ
)!=DSIZ
|| read(font
, bits
, header
.size
)!=header
.size
)
fprintf(stderr
, "rvcat: bad font header");
cfnum
= fontdes
[cfont
].fnum
= fnum
;
cpsize
= fontdes
[cfont
].psize
= size
;
fontdes
[cfont
].bits
= bits
;
fontdes
[cfont
].disp
= (struct dispatch
*) d
;
dispatch
= &fontdes
[cfont
].disp
[0];
* optimization for special font. since we think that usually
* there is only one character at a time from any special math
* font, make it the candidate for removal.
if (fontdes
[cfont
].fnum
!= SPECIALFONT
|| fontdes
[cfont
].bits
==0)
if ((int)fontdes
[newfont
].bits
!= -1 && fontdes
[newfont
].bits
!= 0)
nfree(fontdes
[newfont
].bits
);
fontdes
[newfont
].bits
= 0;
for (i
= 0; i
<= NFONTS
; i
++)
if (fontdes
[i
].bits
!= (char *)-1 && fontdes
[i
].bits
!= (char *)0)
for (i
= 0; i
<= NFONTS
; i
++) {
fontdes
[i
].fnum
= fontdes
[i
].psize
= -1;
return(nalloc(nbytes
,1));
int M
[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
int N
[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
int strim
[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
char c
; /* character to print */
register struct dispatch
*d
; /* ptr to character font record */
register char *addr
; /* addr of font data */
int llen
; /* length of each font line */
int nlines
; /* number of font lines */
register char *scanp
; /* ptr to output buffer */
int scanp_inc
; /* increment to start of next buffer */
int offset
; /* bit offset to start of font data */
int i
; /* loop counter */
register int count
; /* font data ptr */
register unsigned fontdata
; /* font data temporary */
register int off8
; /* offset + 8 */
int b0poff
; /* bit offset back towards buf0p */
if (railmag
== SPECIALFONT
) {
if ((c
= spectab
[code
]) < 0)
} else if ((c
= asctab
[code
]) < 0)
llen
= (d
->down
+d
->up
+7)/8;
nlines
= d
->left
+d
->right
;
if (ypos
+d
->right
>= NLINES
)
slop_lines(ypos
+d
->right
-NLINES
+6);
b0poff
= BYTES_PER_LINE
*8 - 1 - (xpos
+d
->down
);
scanp
= ((ypos
-d
->left
-1)*BYTES_PER_LINE
+b0poff
/8)+buf0p
;
scanp_inc
= BYTES_PER_LINE
-llen
;
for (i
= 0; i
< nlines
; i
++) {
if (scanp
>= &buffer
[BUFFER_SIZE
])
if (scanp
+ count
<= &buffer
[BUFFER_SIZE
])
fontdata
= *(unsigned *)addr
;
fontdata
&= ~strim
[count
];
*(unsigned *)scanp
|= (fontdata
<< offset
) &~ M
[off8
];
*(unsigned *)scanp
|= (fontdata
<< off8
) &~ N
[off8
];
scanp
+= scanp_inc
+count
;
rcols
= (&buffer
[BUFFER_SIZE
] - buf0p
) / BYTES_PER_LINE
;
if (write(vc
, buf0p
, BYTES_PER_LINE
* rcols
) < 0)
bzero(buf0p
, rcols
* BYTES_PER_LINE
);
if (write(vc
, buf0p
, BYTES_PER_LINE
* ncols
) < 0)
bzero(buf0p
, BYTES_PER_LINE
* ncols
);
buf0p
+= BYTES_PER_LINE
* ncols
;
if (buf0p
>= &buffer
[BUFFER_SIZE
])
/* Start a new page by formfeeding, resetting buffer and column counters. */
int lines_left
; /* ... on page. */
buf0p
= buffer
; /* Clear out buffer and reset pointers. */
bzero(buf0p
, BYTES_PER_LINE
* NLINES
);
ioctl(vc
, VSETSTATE
, prtmode
);
ioctl(vc
, VSETSTATE
, pltmode
);