[net.sources] Vfont banner command for 4.1

phb@hcr.UUCP (Paul Breslin) (10/21/83)

/*
 *	vbanner:
 *
 *	This program outputs the strings given as its arguments in the form
 *	of a banner with one string per line. The size of the text is dependent
 *	on the font used. The fonts used are taken from Berkeley's
 *	/usr/lib/vfont. There is a maximum size which is fixed at compile time.
 *	The default font is also fixed at compile time.
 *
 *	Adapted from various vfont sources by:
 *		Paul Breslin
 *		Human Computing Resources Corp.
 *		10 St. Mary St.
 *		Toronto, Ontario, Canada
 *		M4Y 1P9
 */
#include <stdio.h>
#include <ctype.h>
#include <vfont.h>

#define	MAXY		26
#define MAXX		131
#define BASELINE	20
#define DEFAULT_FONT	"meteor.r.12"

char	*Font = DEFAULT_FONT;

struct header	FontHeader;
struct dispatch	FontTable[256];
char	*BitMaps[256];
char	*CurrentMap;

char	OutBuf[MAXY][MAXX+1];

char	IName[100];
long	fbase;
int	MaxFonts = 3;

int	H, W, WB, base;
int	X, Y;


main(argc,argv)
int argc;
char **argv;
{
	register char	c, *s;
	int		i;

	if( argc < 2 ) {
usage:
		fprintf(stderr,"Usage: %s [-f font] string(s)\n", argv[0]);
		exit(2);
	}
	i = 1;
	if( strcmp(argv[1], "-f") == 0 ) 
	  {
		Font = argv[2];
		i    = 3;
	  }

	if( InitFont(Font) == 0 )
	  {
		fprintf(stderr, "%s: Can't open font file!\n", argv[0]);
		exit(3);
	  }

	InitBuf();
	for(; i < argc; ++i )
	  {
		for( s = argv[i]; c = *s; ++s )
			DumpChar(c);
		DumpBuf();
	  }
}


fbit(row, col)
register	row, col;
{
	register	thisbyte, thisbit, ret;

	if (row<0 || row>=H || col>=W) return(0);
	thisbyte = CurrentMap[row*WB + (col>>3)] & 0xff;
	thisbit  = 0x80 >> (col&7);
	ret	 = thisbyte & thisbit;
	return (ret != 0);
}


DumpChar(c)
char	c;
{
	register k, l;
	char	*rdchar();

	if( (c == ' ') && (BitMaps[c] == 0) )
	  {
		X += (FontTable['a'].width >> 2);
		return;
	  }

	if( (CurrentMap = BitMaps[c]) == 0) return;

	base = FontTable[c].up;
	Y    = BASELINE - ((base + 3) / 4);

	H = (FontTable[c].up)    + (FontTable[c].down);
	W = (FontTable[c].right) + (FontTable[c].left);
	WB = (W+7)/8;
	sho2();
	X += ((W + 1) >> 1) + 1;
}

char graphtab[16][16] = {
' ', '.', '.', ',', '.', ';', ':', 'j', '\'', ':', ':', ';', '\'', ';', '!', '|',
'.', '.', ':', ',', ';', ';', ';', 'j', '/', ';', ';', ';', 'j', 'j', 'j', 'j',
'.', ',', '~', ',', 'r', '<', 'j', 'q', '/', ';', 'I', ';', '/', '|', 'I', '|',
',', ',', 'r', 'x', '/', '/', '/', 'd', '/', '/', '/', 'd', '/', '/', '/', 'd',
'.', ':', '\\', ';', '-', '=', 'v', 'q', '\'', ':', '<', '|', '\'', ':', '+', '+',
';', ';', '>', ';', '=', '=', 'g', 'g', '\'', ':', 'S', 'S', '/', '/', '/', '+',
':', '\\', '\\', '\\', 'r', '<', 'w', 'q', '/', '<', '6', '4', '/', '/', 'd', '+',
'l', 'L', '+', 'b', 'y', '[', 'p', 'g', '/', '<', '/', '6', '/', '/', '/', '+',
'`', ':', ':', ';', '`', '\\', '\\', '\\', '"', ':', ':', ';', '`', '\\', 'Y', 'T',
';', ';', ';', ';', '`', '2', '>', '\\', ':', '=', ';', ';', '?', '?', ']', ']',
':', ';', ';', ';', '>', '2', '>', '\\', 'F', ';', 'O', ';', '7', '?', ']', '7',
';', ';', ';', ';', '?', '2', '>', 'b', ';', ';', ';', ';', '?', '?', ']', '#',
'\'', '\\', '\\', '\\', '`', '\\', '\\', '\\', '\'', '\'', '<', '5', '"', '"', 'v', 'q',
';', '\\', '\\', '\\', '`', '=', '\\', '\\', '\'', '\'', '5', '5', '"', '?', 'g', 'g',
'I', 'L', 'L', 'L', 'D', '\\', 'b', 'f', 'F', '[', '[', '[', 'P', '?', '#', 'M',
'|', '|', '|', '|', '|', '#', '+', '#', 'T', '[', 'F', 'F', 'P', '?', 'P', 'M'
};



sho2()
{
	register i,j,k,l;

	k = base%4;
	if (k > 0) k -= 4;
	while (k < H) {
		l = 0;
		while (l<W) {
			i = fbit(k,l)*8 + fbit(k+1,l)*4 + 
			    fbit(k+2,l)*2 + fbit(k+3,l);
			l++;
			j = fbit(k,l)*8 + fbit(k+1,l)*4 + 
			    fbit(k+2,l)*2 + fbit(k+3,l);

			PutChar(graphtab[i][j]);
			l++;
		}
		PutChar('\n');
		k += 4;
	}
}

PutChar(c)
register char	c;
  {
	switch(c)
	  {
	    case ' ':
		++X;
		break;

	    case '\n':
		X -= (W + 1) >> 1;
		++Y;
		break;

	    default:
		++X;
		if( (X < 1) || (Y < 1) || (X >= (MAXX+1)) || (Y >= MAXY) )
			return;
		OutBuf[Y][X] = c;
		OutBuf[Y][0] = 1;
		break;
	  }
  }

InitFont(FontName)
char	*FontName;
  {
	int	i;
	char	LibName[80], FID;

	if ((FID = open(FontName, 0)) < 0)
	  {
		sprintf(LibName, "/usr/lib/vfont/%s", FontName);
		if ((FID = open(LibName, 0)) < 0) 
			return(0);
	  }

	if (read(FID, &FontHeader, sizeof(FontHeader)) != sizeof(FontHeader))
		return(0);

	if (read(FID, &FontTable[0], sizeof(FontTable)) != sizeof(FontTable))
		return(0);

	fbase = sizeof(FontHeader) + sizeof(FontTable);

	if (FontHeader.magic != 0436)
		fprintf(stderr, "warning: Font magic number %o wrong\n",
			FontHeader.magic);

	InitBitMaps(FID, fbase);
	close(FID);
	return(1);
  }


InitBitMaps(FID, base)
int	FID;
long	base;
  {
	register	i, n;

	for(i=0; i < 256; ++i)
	  {
		if( (n = FontTable[i].nbytes) == 0 ) continue;

		BitMaps[i] = (char *)malloc(n);
		lseek(FID, base + FontTable[i].addr, 0);
		read(FID, BitMaps[i], FontTable[i].nbytes);
	  }
  }

char *rdchar(c)
char c;
{
	static char ret[3];
	ret[0] = isprint(c) ? ' ' : '^';
	ret[1] = isprint(c) ?  c  : c^0100;
	ret[2] = 0;
	return (ret);
}

DumpBuf()
  {
	register	x, y;

	for(y=0; y < MAXY; ++y)
	  {
		if( OutBuf[y][0] == 1 )
		  {
			for(x=1; x <= X; ++x)
				putchar(OutBuf[y][x]);
			putchar('\n');
		  }
	  }
	putchar('\n');
	InitBuf();
  }

InitBuf()
  {
	register	x, y;

	for(y=0; y < MAXY; ++y)
		for(x=0; x < MAXX; ++x)
			OutBuf[y][x] = ' ';
	X = 0;
  }