fontbanner - generate banners from vtroff fonts
Jeff Anton
anton at ucbvax.ARPA
Wed Oct 9 05:18:19 AEST 1985
jeffg at tekc??? asked about this... is that Jeff Gutow... Oh well...
Here it is... Flames & Bugs to /dev/null.... (I don't want to look at this
code anymore.. It was written in my early days of UNIX so don't complain.)
Money to anton at INGRES.BERKELEY.EDU (anton%ucbingres at berkeley.arpa)
ucbvax!anton anton at ucbvax.UUCP
FONTBANNER(PUBLIC) UNIX Programmer's Manual FONTBANNER(PUBLIC)
NAME
fontbanner - print a banner using vtroff fonts
SYNOPSIS
fontbanner {[-dchrs] [-uCHAR][-p#] [-w#] font [message]}+
DESCRIPTION
Fontbanner(PUBLIC) outputs a message in large characters to the
standard output. The message may be entered on the command line
or you will be prompted for a single line of input. The prompt
will be sent to the standard error to allow redirection of the
banner output. If you type the message on the command line you
must quote it if it contains any spaces or special characters.
The size of the banner is determined directly from the point of
the selected font. Normally, a point is 1/72 of an inch and the
point of a font is the distaince from the lowest descender to the
tallest character divided by 72. (A 36 point font is 1/2 an inch
tall). Fontbanner, however is much bigger. If you want n column
output, n/5.5 point would probably by a good choice. For 132
column output, 26 point is good; for 80 column output, 12
point. Not all fonts are available in all point sizes so look for
your font in /usr/lib/vfont/* before using fontbanner.
The -d option doubles the size of the font and the -h option
halves it, both at the cost of ragged edges. The -u option uses
the character 'CHAR' instead of the default '#' for printing. The
-s option makes each banner sized character be made up by the
printer sized version of the same character, while the -f option
uses the contents of a file for each character printed (useful for
having a small message inside a bigger one). If the file ends
before the banner is printed, the default character (or character
specified by the -u option) will be used to complete the banner
unless the -r option is given. The -r option causes the input file
to be read repeated until the banner is done. The -p option
followed by a number specifies an offset in characters from the
left side of a page. The -w option followed by a number tells how
wide your device is. The default is 132 columns. The -c option
causes output to be centered. If -p is given it becomes and
advisory when used with the -c option. The whole argument list
maybe repeated to allow different fonts and page offsets in a
banner. Note that the toggle options, c,d,h,s and u do not reset
but must be toggled if one want to change it when using a
different font.
FILES
/usr/lib/vfont/* directory of font files to choose from
SEE ALSO
banner(6), vfontinfo(1), vfont(5), vtroff(1)
_T_h_e _B_e_r_k_e_l_e_y _F_o_n_t _C_a_t_a_l_o_g
AUTHOR
Jeff Anton (anton at ucbingres)
Printed 3/30/84 local 1
/*
* $Header: fontbanner.c,v 1.4 84/08/06 11:56:22 anton Exp $
*
* $Log: fontbanner.c,v $
* Revision 1.4 84/08/06 11:56:22 anton
* Lots of new stuff by Charles Spirakis
*
* Revision 1.3 84/03/31 00:09:01 anton
* Added lots of stuff - jaa
*
* Revision 1.2 84/02/01 21:27:36 cc-sec
* spaceing fixed and RCS stuff added - jaa
*
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/file.h>
#include <vfont.h>
#define DEF '#'
struct header fhead;
struct dispatch dtab[256],*dp;
long fbase = sizeof fhead + sizeof dtab;
char cbits[4000],*cntl(), *iname;
char rept = DEF;
int h,w,widthbytes,md, mu, flags;
int pwid = 132;
#define MAG 1
#define CEN 2
#define HALF 4
#define INP 8
#define REDO 16
main(argc, argv)
int argc;
char **argv;
{
char line[132], chr, *cpos, *fontname, *comname;
int i, poff;
poff = flags = 0;
comname = *argv;
again:
while (--argc && **++argv == '-') {
while (chr = *++*argv)
switch (chr) {
case 'p':
if (*++*argv) {
poff = atoi(*argv);
goto nxtarg;
}
else if (argc-- > 2) {
poff = atoi(*++argv);
goto nxtarg;
} else
goto usage;
break;
case 'w':
if (*++*argv) {
pwid = atoi(*argv);
goto nxtarg;
}
else if (argc-- > 2) {
pwid = atoi(*++argv);
goto nxtarg;
} else
goto usage;
break;
case 'u':
rept = *(*argv + 1);
if (! isprint(rept))
rept = DEF;
goto nxtarg;
break;
case 'f':
if (*++*argv) {
iname = *argv;
flags |= INP;
goto nxtarg;
} else if (argc-- > 2) {
iname = *++argv;
flags |= INP;
goto nxtarg;
} else
goto usage;
break;
case 'd':
flags ^= MAG;
flags &= ~HALF;
break;
case 'h':
flags ^= HALF;
flags &= ~MAG;
break;
case 'c':
flags ^= CEN;
break;
case 'r':
flags ^= REDO;
break;
default:
fprintf(stderr, "usage: -%c flag unknown\n", chr);
}
nxtarg: ;
}
cpos = NULL;
switch (argc) {
case 1:
fontname = *argv;
break;
case 0:
usage:
fprintf(stderr, "usage: %s {[-dchr] [-uCHAR] [-p#] [-w#] font [\"message\"]}+ (i.e. repeatable)\n", comname);
exit(1);
default:
cpos = argv[1];
fontname = *argv;
break;
}
if (flags & INP)
openinp(iname);
printban(fontname, comname, cpos, flags, poff);
argv++;
if (--argc >= 2)
goto again;
exit(0);
}
printban(fontname, comname, cpos, flags, poff)
char *fontname, *comname, *cpos;
int flags, poff;
{
int fd, spwidth, i;
char line[80], *ext, chr;
if ((fd = open(fontname, O_RDONLY)) == -1) {
strcpy(line, "/usr/lib/vfont/");
strcat(line, fontname);
if ((fd = open(line, O_RDONLY)) == -1) {
perror(fontname);
exit(2);
}
}
ext = fontname + strlen(fontname);
if (ext[-1] == 'r') {
fprintf(stderr,"%s: can't use rotated fonts\n",comname);
exit(5);
}
while (*--ext != '.');
spwidth = atoi(++ext);
spwidth += spwidth >> 1;
if (flags & MAG)
spwidth <<= 1;
else if (flags & HALF)
spwidth >>= 1;
if (read(fd, &fhead, sizeof fhead) != sizeof fhead ||
read(fd, dtab, sizeof dtab) != sizeof dtab) {
fprintf(stderr, "%s: file too small\n", fontname);
exit(3);
}
if (fhead.magic != 0436) {
fprintf(stderr,"%s: magic number wrong\n",fontname);
exit(4);
}
md = mu = 0;
for (i = 0, dp = dtab; i < 256; dp++, i++) {
if (!dp->nbytes)
continue;
if (md < dp->down)
md = dp->down;
if (mu < dp->up)
mu = dp->up;
}
if (2*(poff + mu + md) > pwid)
fprintf(stderr, "%s: Warning: %s is too tall for width %d offset %d\n", comname, fontname, pwid, poff);
if (flags & CEN)
poff = (pwid + poff)/2 - mu - md;
if (cpos == NULL) {
fprintf(stderr,"Message: ");
gets(line);
cpos = line;
}
while (chr = *cpos++) {
dp = dtab + chr;
if (dp->nbytes == 0) {
if (chr == ' ')
for (i = 0; i < spwidth; i++)
putchar('\n');
else
fprintf(stderr,"%s: Warning: '%s' (0x%x) not in %s\n",comname,cntl(chr),chr,fontname);
continue;
}
lseek(fd, fbase + dp->addr, 0);
read(fd, cbits, dp->nbytes);
h = dp->up + dp->down;
w = dp->left + dp->right;
widthbytes = ( w + 7 ) >> 3;
report(poff);
}
close(fd);
}
report(poff)
int poff;
{
int k,l,top;
char mstr[9], spstr[9];
switch (flags & (MAG | HALF)) {
case MAG:
strcpy(spstr, " ");
sprintf(mstr, "%c%c%c%c", rept, rept, rept, rept);
break;
case HALF:
strcpy(spstr, " ");
sprintf(mstr, "%c", rept);
break;
default:
strcpy(spstr, " ");
sprintf(mstr, "%c%c", rept, rept);
}
for (l = 0; l < dp->width; l++) {
for (k = 0; k < poff; k++)
putchar(' ');
for (top = - dp->up; top <= md && !fbit(top,l); top++);
for (k = md; k >= top; k--) {
if ((flags & INP) && fbit(k,l))
inpstr(mstr);
fputs(fbit(k,l)?mstr:spstr,stdout);
}
putchar('\n');
if (flags & MAG) {
for (k = md; k >= top; k--) {
if ((flags & INP) && fbit(k,l))
inpstr(mstr);
fputs(fbit(k,l)?mstr:spstr,stdout);
}
putchar('\n');
}
}
}
fbit(row, col)
int row, col;
{
int thisbyte,thisbit;
row += dp->up;
if (row < 0 || col < 0 || row >= h || col >= w)
return(0);
thisbyte = cbits[row * widthbytes + ( col >> 3 )];
thisbit = 0x80 >> (col & 7);
return((thisbyte & thisbit) != 0);
}
char *
cntl(chr)
char chr;
{
static char ret[3];
if (chr >= 128 || iscntrl(chr))
ret[0] = '^', ret[1] = chr + '@', ret[2] = '\0';
else
ret[0] = chr, ret[1] = '\0';
return(ret);
}
FILE *inp = NULL;
openinp(name)
char *name;
{
if (inp != NULL)
fclose(inp);
if ((inp = fopen(name, "r")) == NULL) {
fprintf(stderr, "\nCouldn't open %s.\n", name);
exit(7);
}
}
inpstr(str)
char *str;
{
int i, j;
char myget();
switch (flags & (MAG | HALF)) {
case MAG:
i = 4;
break;
case HALF:
i = 1;
break;
default:
i = 2;
}
for (j = 0; j < i; j++)
*str++ = myget();
*str = '\0';
}
char
myget()
{
static int ch, oldchar;
while (1) {
if ((ch = getc(inp)) == EOF) {
if (flags & REDO) {
openinp(iname);
if ((ch = getc(inp)) == EOF) {
fprintf(stderr, "Can't use a null file for input");
exit(8);
}
} else {
return (oldchar = rept);
}
}
if ((oldchar == ' ') && (isspace(ch)))
continue;
if (isprint(ch))
return (oldchar = ch);
if (isspace(ch))
return (oldchar = ' ');
}
}
--
C knows no bounds.
Jeff Anton
U.C.Berkeley
Ingres Group
ucbvax!anton
anton at BERKELEY.EDU
More information about the Comp.sources.unix
mailing list