Article 589 of unix-pc.sources:
>From: john@chance.UUCP (John R. MacMillan)
Newsgroups: unix-pc.sources
Subject: ft2fnt - convert UNIXpc font files for MGR
Keywords: MGR, fonts
Message-ID: <1990Mar20.060927.14796@chance.UUCP>
Date: 20 Mar 90 06:09:27 GMT
Reply-To: john@chance.UUCP (John R. MacMillan)
Organization: Haphazard
Lines: 414


For those of you who were hesitant about running MGR because you
were afraid you'd miss /usr/lib/wfont/FANCY.R.E.24.A...

#!/bin/sh
#  This is a shar file.  To extract, sh this file
#
#  Contents:
#	ReadMe
#	Makefile
#	ft2fnt.c
#
#  Wrapped by john@chance ; Tue Mar 20 00:45:58 EST 1990
#
if [ -f "ReadMe" ] ; then
	echo "shar: Will not overwrite existing file ReadMe"
else
	echo "shar: extracting ReadMe (1174 characters)"
	sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > ReadMe
XThis is a quick little program to convert UNIXpc font(4) files (like
Xthose found in /usr/lib/wfont) to MGR font(5) files.  I'm not
Xentirely sure why you might want to do this, but I must have had a
Xreason when I started...
X
XUsage is:
X	ft2fnt ft_file > fnt_file
X
Xwhere ft_file is a font(4) file and fnt_file is a font(5) file.
X(No, it can't read stdin; it wants to get the size, and I was too
Xlazy to blow stdin to a temp file.)
X
XSince the UNIXpc font format allows characters to ``overlap'', and
Xthe MGR format doesn't, ft2fnt has to make larger character rasters
Xthan the original for some fonts, eg. /usr/lib/wfont/FANCY.I.E.24.A.
XThis causes the font to look wider-spaced under MGR.  You win a few,
Xyou lose a few.
X
XYes, it could have a prettier usage, but how often you plan on
Xrunning it?  Yes, it could be faster, but how often do you plan on
Xrunning it?
X
XThere are no distribution restrictions; it's completely public
Xdomain.  I would appreciate it if you kept my name attached, and
Xattached yours if you make changes so we don't get blamed for each
Xother's bugs.
X
XAnd of course I'd like to hear about any bugs, enhancements, etc.
X
XJohn R. MacMillan
Xjohn@chance.UUCP
BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
	set -- `wc -c ReadMe`
	if [ "$1" != "1174" ] ; then
		echo "shar: ReadMe unpacked with wrong size!"
	fi
	chmod u=r,g=r,o=r ReadMe
fi
if [ -f "Makefile" ] ; then
	echo "shar: Will not overwrite existing file Makefile"
else
	echo "shar: extracting Makefile (190 characters)"
	sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > Makefile
XCFLAGS=  -O
XLDFLAGS= -s
XSHLIB=   /lib/crt0s.o /lib/shlib.ifile
X
Xall: ft2fnt
X
Xft2fnt: ft2fnt.o
X	$(LD) $(LDFLAGS) -o $@ $(SHLIB) $?
X
Xclean:
X	rm -f *.o *.out core
X
Xclobber: clean
X	rm -f ft2fnt
BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
	set -- `wc -c Makefile`
	if [ "$1" != "190" ] ; then
		echo "shar: Makefile unpacked with wrong size!"
	fi
	chmod u=r,g=r,o=r Makefile
fi
if [ -f "ft2fnt.c" ] ; then
	echo "shar: Will not overwrite existing file ft2fnt.c"
else
	echo "shar: extracting ft2fnt.c (7099 characters)"
	sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > ft2fnt.c
X/*
X * Convert UNIXpc font(4) files to MGR font(5) files
X *
X * Usage: ft2fnt ft_file > fnt_file
X *
X * No distribution/use restrictions, but give credit/blame where due.
X * Speaking of which, MGR is copyright 1988 Bellcore.
X *
X * John R. MacMillan
X */
X
X#ifndef lint
Xchar	*SCCSid = "@(#)ft2fnt.c	1.1	90/03/20";
X#endif
X
X#include <stdio.h>
X#include <string.h>
X#include <fcntl.h>
X#include <sys/font.h>
X#include <sys/stat.h>
X
X/*
X * Could grab this from the "font.h" in the MGR distribution, but then
X * I'd either have to distribute it or you'd have to have it, plus
X * it's got useless things which would require other header files, and
X * so on...
X */
X
Xstruct font_header {
X	unsigned char	type;
X	unsigned char	wide;
X	unsigned char	high;
X	unsigned char	baseline;
X	unsigned char	count;
X	char		start;
X};
X
X#define	FONT_A	'\026'			/* ^V */
X
X/*
X * Thoe following returns the width in bytes of (bits) pixels, padded
X * to the nearest word, for dealing with the MGR bitmap of the font.
X */
X
X#define	WIDTH(bits)	((((bits)+15L)&~15L)>>3)
X
Xextern	int	errno;
Xextern	char	*sys_errlist[];
Xextern	int	sys_nerr;
X#define	ERR(n)	(sys_errlist[((n) > sys_nerr) ? 0 : (n)])
X
Xchar		*prog;			/* Program name */
X
Xstatic void	fontsize();		/* find the size for the font */
Xstatic void	convert();		/* convert a character */
Xstatic void	bitset();		/* turn on bitmap bits */
X
Xint
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X	struct font_header *new;	/* new fnt file */
X	struct fntdef	*old;		/* old ft file */
X	char		*name;		/* ft file name */
X	struct stat	buf;		/* to get size of ft file */
X	int		fd;		/* ft file */
X	int		newsize;	/* size of new fnt file */
X	int		vs, hs;		/* vertical, horizontal size */
X	int		va, ha;		/* adjustment */
X	int		c;
X	extern char	*malloc(), *calloc();
X	extern void	free(), exit();
X	extern int	fprintf(), stat(), open(), read(), write(), close();
X
X	prog = strrchr(argv[0], '/');
X	if (prog == NULL)
X		prog = argv[0];
X	else
X		prog++;
X
X	if (argc != 2) {
X		(void) fprintf(stderr, "Usage: %s ft_file > fnt_file\n", prog);
X		exit(1);
X	}
X
X	name = argv[1];
X
X	/*
X	 * Get the size, and malloc enough memory to hold the entire
X	 * ft file
X	 */
X
X	if (stat(name,&buf) < 0) {
X		(void) fprintf(stderr, "%s: %s: %s\n", prog, name,
X				ERR(errno));
X		exit(1);
X	}
X
X	old = (struct fntdef *) malloc((unsigned)buf.st_size);
X	if (old == NULL) {
X		(void) fprintf(stderr, "%s: unable to get memory for %s\n",
X				prog, name);
X		exit(1);
X	}
X
X	/*
X	 * Open the file and suck it in
X	 */
X
X	if ((fd = open(name, O_RDONLY)) < 0) {
X		(void) fprintf(stderr, "%s: unable to open %s: %s\n",
X				prog, name, ERR(errno));
X		exit(1);
X	}
X
X	if (read(fd, (char *)old, (unsigned)buf.st_size) < buf.st_size) {
X		(void) fprintf(stderr, "%s: error reading %s: %s\n",
X				prog, name, ERR(errno));
X		exit(1);
X	}
X	(void) close(fd);
X
X	if (old->ff_magic != FMAGIC) {
X		(void) fprintf(stderr, "%s: %s is not a font(4) file\n",
X				prog, name);
X		exit(1);
X	}
X
X	/*
X	 * Determine the character size for the new font, and the
X	 * adjustment of the old raster in the new one
X	 */
X
X	fontsize(old, &vs, &hs, &va, &ha);
X
X	/*
X	 * Set up for the new font
X	 *
X	 * The new size is the size of the header plus enough bytes
X	 * to hold the bitmap.  The bitmap is hs rows of vs * count
X	 * pixels; rows are padded to a word boundary.
X	 *
X	 * We calloc(3) the space so the bitmap will be zeroed
X	 */
X
X	newsize = sizeof(struct font_header) + vs * WIDTH(hs * FNTSIZE);
X
X	new = (struct font_header *) calloc((unsigned) newsize, (unsigned) 1);
X	if (new == NULL) {
X		(void) fprintf(stderr, "%s: unable to get memory for new font\n",
X				prog);
X		exit(1);
X	}
X
X	/*
X	 * Fill in the header info
X	 */
X
X	new->type = FONT_A;
X	new->wide = hs;
X	new->high = vs;
X	new->baseline = old->ff_vs - old->ff_baseline - va;
X	new->count = FNTSIZE;
X	new->start = ' ';
X
X	/*
X	 * Copy the old font into the new area
X	 */
X
X	for (c = 0; c < FNTSIZE; c++)
X		convert(c, old, new, va, ha);
X
X	/*
X	 * Write out the fnt file
X	 */
X
X	if (write(1, (char *)new, (unsigned)newsize) < newsize) {
X		(void) fprintf(stderr, "%s: error writing output: %s\n",
X				prog, ERR(errno));
X		exit(1);
X	}
X
X	/*
X	 * Clean up, just to be nice
X	 */
X
X	free((char *)old);
X	free((char *)new);
X
X	return(0);			/* To keep lint happy */
X}
X
X/*
X * Scan the font to determine the the biggest character, and how to
X * place the old raster in the new one.
X */
X
Xstatic void
Xfontsize(font, vsp, hsp, vap, hap)
Xstruct fntdef	*font;			/* Font being sized */
Xint		*vsp, *hsp;		/* RETURN: vertical/horiz size */
Xint		*vap, *hap;		/* RETURN: vertical/horiz adjust */
X{
X	int	minrow = 0;		/* Minimum row of any char */
X	int	maxrow = font->ff_vs-1;	/* Maximum row of any char */
X	int	mincol = 0;		/* Minimum col of any char */
X	int	maxcol = font->ff_hs-1;	/* Maximum col of any char */
X	int	c;			/* Current character */
X	int	n;			/* Scratch min/max values */
X
X	for (c = 0; c < FNTSIZE; c++) {
X		n = font->ff_baseline + font->ff_fc[c].fc_va;
X		if (n < minrow)
X			minrow = n;
X		n += font->ff_fc[c].fc_vs - 1;
X		if (n > maxrow)
X			maxrow = n;
X		n = font->ff_fc[c].fc_ha;
X		if (n < mincol)
X			mincol = n;
X		n += font->ff_fc[c].fc_hs - 1;
X		if (n > maxcol)
X			maxcol = n;
X	}
X
X	if (minrow < 0)
X		*vap = -minrow;
X	else
X		*vap = 0;
X	if (mincol < 0)
X		*hap = -mincol;
X	else
X		*hap = 0;
X	*vsp = maxrow - minrow + 1;
X	*hsp = maxcol - mincol + 1;
X}
X
X/*
X * Convert a character in the font(4) area into the MGR font(5) area
X */
X
Xstatic void
Xconvert(c, from, to, va, ha)
Xint		c;			/* Character offset from ' ' */
Xstruct fntdef	*from;			/* UNIXpc font(4) */
Xstruct font_header *to;			/* MGR font(5) */
Xint		va, ha;			/* adjustment */
X{
X	int		rowsize;	/* words in a row */
X	int		row;		/* current row in miniraster */
X	int		col;		/* current col in miniraster */
X	unsigned short	*mr;		/* current word pointer */
X	struct fcdef	*fc;		/* character definition */
X
X	/*
X	 * Set up to read the miniraster.  It starts fc->fc_mr bytes
X	 * after its own fc_mr field.  Ick.
X	 */
X
X	fc = &from->ff_fc[c];
X	rowsize = (fc->fc_hs + 15) >> 4;
X	mr = (unsigned short *)((char *) &from->ff_fc[c].fc_mr + fc->fc_mr);
X
X	/*
X	 * Calculate the adjustments to put the miniraster into the
X	 * character of the bitmap
X	 */
X
X	ha = ha + fc->fc_ha;
X	va = va + from->ff_baseline + fc->fc_va;
X
X	/*
X	 * Go through the miniraster row by row, column by column.  If
X	 * a bit is set in the miniraster, set it in the bitmap.
X	 */
X
X	for (row = 0; row < fc->fc_vs; row++) {
X		for (col = 0 ; col < fc->fc_hs; col++) {
X			if (mr[col/16] & (1<<col%16))
X				bitset(to, c, row + va, col + ha);
X		}
X		mr += rowsize;
X	}
X}
X
X/*
X * Set a bit in the bitmap in the font(5) area pointed to by fnt.  The
X * bit set is in character c, (row, col)
X */
X
Xstatic void
Xbitset(fnt, c, row, col)
Xstruct font_header *fnt;
Xint		c;
Xint		row;
Xint		col;
X{
X	char		*bm;		/* Correct row of bitmap */
X	unsigned	bit;		/* Bit number in bitmap */
X	extern int	fprintf();
X
X	/*
X	 * The correct row is the start of bitmap (start of font plus
X	 * size of header) plus (width of row * row number).
X	 */
X
X	bm = (char *)fnt + sizeof(struct font_header) +
X			WIDTH(fnt->wide * fnt->count) * row;
X
X	bit = c * fnt->wide + col;
X
X	bm[bit/8] |= 1 << (7 - bit%8);
X}
BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
	set -- `wc -c ft2fnt.c`
	if [ "$1" != "7099" ] ; then
		echo "shar: ft2fnt.c unpacked with wrong size!"
	fi
	chmod u=r,g=r,o=r ft2fnt.c
fi
exit
-- 
John R. MacMillan          | For a long time I felt without style or grace
john@chance.UUCP           | Wearing shoes with no socks in cold weather
...!utcsri!hcr!chance!john | -- Talking Heads



