v04i074: JetRoff Source Code (05 of 7)

root2 at pcrat.UUCP root2 at pcrat.UUCP
Sun Sep 18 09:10:09 AEST 1988


Posting-number: Volume 4, Issue 74
Submitted-by: "A. Nonymous" <root2 at pcrat.UUCP>
Archive-name: jetroff/src/Part05

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 7)."
# Contents:  bm/pcx.c djet/draw.c doc/BM.5 font/mkfont/makedesc.c
#   font/mkfont/mkfont.c font/mkfont/rdfont.c
# Wrapped by rick at pcroe on Sat Aug 27 13:01:10 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'bm/pcx.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bm/pcx.c'\"
else
echo shar: Extracting \"'bm/pcx.c'\" \(6834 characters\)
sed "s/^X//" >'bm/pcx.c' <<'END_OF_FILE'
X/*c
X *	JetRoff - DWB 2.0 postprocessor for HP LaserJet Series II
X *
X *	Copyright (c) 1988 PC Research, Inc.  All Rights Reserved.
X *
X *	This source code is supplied to you under the terms of the
X *	contents of the "License" agreement found with this source
X *	distribution.  You must read the "License" before you use
X *	this source code in any way.
X *
Xc*/
X
X/*
X *	Pick apart PC PaintBrush .PCX files
X */
X
X/*
X * $Id: pcx.c,v 1.1 88/08/26 23:26:25 rick Exp $
X *
X * $Log:	pcx.c,v $
X * Revision 1.1  88/08/26  23:26:25  rick
X * Initial revision
X * 
X */
X#ifndef lint
Xstatic char rcsid[] = "$Id: pcx.c,v 1.1 88/08/26 23:26:25 rick Exp $";
X#endif
X
X#include <stdio.h>
X
Xextern char	*malloc();
Xextern void	free();
X
Xextern int	debug;
X
X#define	Fread	(void) fread
X#define	Fprintf	(void) fprintf
X
Xtypedef unsigned char	uchar;
Xtypedef unsigned short	ushort;
X
Xunsigned short getushort()
X{
X	register int v;
X
X	v = (unsigned short) getchar();
X	v += (unsigned short) getchar()<<8;
X	return v;
X}
X
Xtypedef struct { uchar red, green, blue; } TRIPLET;
X
Xtypedef struct
X{
X	char	maker;
X	char	version;
X	char	code;
X	char	bpp;
X	ushort	x1;
X	ushort	y1;
X	ushort	x2;
X	ushort	y2;
X	ushort	hres;
X	ushort	vres;
X	TRIPLET triple[16];
X	char	vmode;
X	char	nplanes;
X	ushort	bpl;
X} PCXHDR;
X
XPCXHDR	hdr;
X
Xtypedef struct {
X   PCXHDR hdr;
X   uchar **rows[4];
X} PCXPIC;
X
Xushort	xpixels;
Xushort	ypixels;
X
Xchar	lookup[256] =
X{
X	0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
X};
X
X#define	MAX_PLANES	8
X
Xmap_open(fname, p_xpixels, p_ypixels)
Xchar	*fname;
Xint	*p_xpixels;
Xint	*p_ypixels;
X{
X	register int	i;
X	char		*filename;
X	extern FILE	*myreopen();
X
X	if ( myreopen(filename = fname, "r", stdin,
X		"JETMAPS", STD) == NULL)
X	{
X		error(1, "Couldn't find bitmap file '%s'", filename);
X	}
X	hdr.maker = getchar();
X	hdr.version = getchar();
X	hdr.code = getchar();
X	hdr.bpp = getchar();
X	hdr.x1 = getushort();
X	hdr.y1 = getushort();
X	hdr.x2 = getushort();
X	hdr.y2 = getushort();
X	hdr.hres = getushort();
X	hdr.vres = getushort();
X
X	for (i = 0; i < 16; ++i)
X	{
X		hdr.triple[i].red = getchar();
X		hdr.triple[i].green = getchar();
X		hdr.triple[i].blue = getchar();
X	}
X	hdr.vmode = getchar();
X	hdr.nplanes = getchar();
X	hdr.bpl = getushort();
X	if (debug)
X	{
X		Fprintf(stderr, ".pcx hdr.maker = %d\n", hdr.maker);
X		Fprintf(stderr, ".pcx hdr.version = %d\n", hdr.version);
X		Fprintf(stderr, ".pcx hdr.code = %d\n", hdr.code);
X		Fprintf(stderr, ".pcx hdr.bpp = %d\n", hdr.bpp);
X		Fprintf(stderr, ".pcx hdr.x1 = %d\n", hdr.x1);
X		Fprintf(stderr, ".pcx hdr.y1 = %d\n", hdr.y1);
X		Fprintf(stderr, ".pcx hdr.x2 = %d\n", hdr.x2);
X		Fprintf(stderr, ".pcx hdr.y2 = %d\n", hdr.y2);
X		Fprintf(stderr, ".pcx hdr.hres = %d\n", hdr.hres);
X		Fprintf(stderr, ".pcx hdr.vres = %d\n", hdr.vres);
X		Fprintf(stderr, ".pcx hdr.vmode = %d\n", hdr.vmode);
X		Fprintf(stderr, ".pcx hdr.nplanes = %d\n", hdr.nplanes);
X		Fprintf(stderr, ".pcx hdr.bpl = %d\n", hdr.bpl);
X	}
X
X	if (hdr.code != 1)
X		error(1, "Can only understand .PCX Run Length Encoding");
X	if (hdr.nplanes > MAX_PLANES)
X		error(1, "Too many bitplanes in '%s' (not .PCX?)", filename);
X	if (hdr.bpp > 1 && hdr.nplanes)
X		error(1, "Can't handle more than 1 bit/plane in '%s'",
X			filename);
X
X	*p_xpixels = xpixels = hdr.x2 - hdr.x1 + 1;
X	*p_ypixels = ypixels = hdr.y2 - hdr.y1 + 1;
X
X	return (0);
X}
X
Xint	pcxval;
Xint	pcxcnt;
X
Xuchar getpcx()
X{
X	register uchar	val;
X
X	if (pcxcnt)
X	{
X		--pcxcnt;
X		return (pcxval);
X	}
X	else
X	{
X		val = getchar();
X		if ( (val & 0xc0) == 0xc0)
X		{
X			pcxcnt = val & 0x3f;
X			pcxval = getchar();
X			--pcxcnt;
X			return (pcxval);
X		}
X		else
X			return val;
X	}
X}
X
X#	ifdef ERR_SEG_OVERWRITE
X#		define PICBUF_OR(X,Y)	{ register int _b; \
X					_b = map[X&7]; \
X					picbuf[ Y*xbytes + (X>>3) ] |= _b; }
X#	else
X#		define PICBUF_OR(X,Y)	picbuf[ Y*xbytes + (X>>3) ] |= map[X&7]
X#	endif
X
X/*
X *	Unpack picture, then dump
X */
Xmap_read(picbuf)
Xunsigned char	*picbuf;
X{
X	register int	x, y, p;
X	int		xbytes = (xpixels + 7)/8;
X	uchar		val;
X	static uchar	map[8]={0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
X
X	uchar		**rowbuf[MAX_PLANES];
X
X	(void) fseek(stdin, 128L, 0);
X
X	pcxcnt = 0;
X
X	if (hdr.nplanes)
X	{	/* EGA type picture, multiple planes */
X		for (p = 0; p < hdr.nplanes; ++p)
X			rowbuf[p] = (uchar **) malloc(ypixels*sizeof(uchar **));
X
X		for (p = 0; p < hdr.nplanes; ++p)
X			for (y = 0; y < ypixels; ++y)
X				rowbuf[p][y] = (uchar *) malloc( hdr.bpl );
X
X		for (y = 0; y < ypixels; ++y)
X			for (p = 0; p < hdr.nplanes; ++p)
X				for (x = 0; x < hdr.bpl; ++x)
X					rowbuf[p][y][x] = getpcx();
X
X		for (y = 0; y < ypixels; ++y)
X			for (x = 0; x < xpixels; ++x)
X			{
X				val = 0;
X				for (p = 0; p < hdr.nplanes; ++p)
X				{
X					val <<= 1;
X					if (rowbuf[p][y][x>>3] & map[x&7])
X						++val;
X				}
X				if (lookup[ val ])
X					PICBUF_OR(x, y);
X			}
X	}
X	else
X	{	/* CGA type picture */
X		static uchar	bmask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
X		int		mask = bmask[hdr.bpp];
X		int		blim = 8/hdr.bpp - 1;
X
X		for (y = 0; y < ypixels; ++y)
X			for (x = 0; x < xpixels; ++x)
X			{
X				if ( (x & blim) == 0)
X				{
X					val = getpcx();
X					p = blim*hdr.bpp;
X				}
X				if (lookup[ (val>>p) & mask ])
X					PICBUF_OR(x, y);
X			}
X	}
X		
X	return (0);
X}
X
Xmap_close()
X{
X}
X
Xchar	map_opts[] = "p:";
X
Xmap_option(letter, optarg)
Xchar	letter;
Xchar	*optarg;
X{
X	switch (letter)
X	{
X	case 'p':
X		do_palette(optarg);
X		break;
X	default:
X		return (1);
X	}
X	return (0);
X}
X
Xmap_usage()
X{
X	Fprintf(stderr,
X"	-pPLIST		(for color pcx's) pixel values in PLIST are black\n");
X	Fprintf(stderr,
X"			PLIST format is 1,2,3 or 1-15 or 1,7-15\n");
X}
X
X/*
X *	convert list like 1,2,3-15 into on values for pallete
X */
Xdo_palette(s)
Xchar	*s;
X{
X	char	*n1, *n2;
X	int	dash;
X	register int	i, f, l;
X
X	if (s == NULL) return;
X	for (i = 0; i < sizeof(lookup)/sizeof(lookup[0]); ++i)
X		lookup[i] = 0;
X	n1 = n2 = NULL; dash = 0;
X	for(;;)
X		switch (*s++)
X		{
X		case '0': case '1': case '2': case '3': case '4':
X		case '5': case '6': case '7': case '8': case '9':
X			if (!n1) n1 = &s[-1];
X			else if (!n2) n2 = &s[-1];
X			break;
X		case '-':
X			dash = 1; n2 = NULL;
X			break;
X		case ',':
X		case '\0':
X			if (dash)
X			{
X				if (n2 == NULL)
X					l = 255;
X				else
X					l = atoi(n2) & 255;
X				f = atoi(n1) & 255;
X				for (i = f; i <= l; ++i)
X					lookup[i] = 1;
X			}
X			else if (*n1)
X			{
X				i = atoi(n1) & 255;
X				lookup[i] = 1;
X			}
X			n1 = n2 = NULL; dash = 0;
X			if (!s[-1]) goto out;
X			break;
X		}
Xout:
X	return;
X}
END_OF_FILE
if test 6834 -ne `wc -c <'bm/pcx.c'`; then
    echo shar: \"'bm/pcx.c'\" unpacked with wrong size!
fi
# end of 'bm/pcx.c'
fi
if test -f 'djet/draw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'djet/draw.c'\"
else
echo shar: Extracting \"'djet/draw.c'\" \(9114 characters\)
sed "s/^X//" >'djet/draw.c' <<'END_OF_FILE'
X/*c
X *	JetRoff - DWB 2.0 postprocessor for HP LaserJet Series II
X *
X *	Copyright (c) 1988 PC Research, Inc.  All Rights Reserved.
X *
X *	This source code is supplied to you under the terms of the
X *	contents of the "License" agreement found with this source
X *	distribution.  You must read the "License" before you use
X *	this source code in any way.
X *
Xc*/
X
X/*
X * $Id: draw.c,v 1.1 88/08/26 23:10:54 rick Exp $
X *
X * $Log:	draw.c,v $
X * Revision 1.1  88/08/26  23:10:54  rick
X * Initial revision
X * 
X */
X#ifndef lint
Xstatic char rcsid[] = "@(#) $Id: draw.c,v 1.1 88/08/26 23:10:54 rick Exp $";
X#endif
X
X#include <stdio.h>
X#include <sys/param.h>	/* For sys. dep. lobyte(), hibyte() */
X#include "memory.h"
X#include "draw.h"
X#include "dlj.h"
X
X/*
X *	If machine has virtual memory, then just allocate
X *	a big array and let the OS handle paging the pieces
X *	we actually use.  Else, allocate lines of pixels
X *	as needed.
X */
X
X#if	VIRTUAL_MEMORY
X	char		bm[YPIXELS][XBYTES];
X#else
X	char		*bm[YPIXELS];
X#endif
X
Xstatic int	miny = YPIXELS, maxy = 0;
X
X/*
X *	Various Pens
X */
X#define	Y2	2
Xunsigned int	pen2[8][Y2] =
X	{ 0xc000, 0xc000 };
Xmk_pen2() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y2;++j) pen2[i][j] = pen2[i-1][j] >> 1;
X}
X
X#define	Y3	3
Xunsigned int	pen3[8][Y3] =
X	{ 0xe000, 0xe000, 0xe000 };
Xmk_pen3() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y3;++j) pen3[i][j] = pen3[i-1][j] >> 1;
X}
X
X#define	Y4	4
Xunsigned int	pen4[8][Y4] =
X	{ 0x6000, 0xf000, 0xf000, 0x6000 };
Xmk_pen4() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y4;++j) pen4[i][j] = pen4[i-1][j] >> 1;
X}
X
X#define	Y5	5
Xunsigned int	pen5[8][Y5] =
X	{ 0x7000, 0xf800, 0xf800, 0xf800, 0x7000 };
Xmk_pen5() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y5;++j) pen5[i][j] = pen5[i-1][j] >> 1;
X}
X
X#define	Y6	6
Xunsigned int	pen6[8][Y6] =
X	{ 0x7800, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0x7800 };
Xmk_pen6() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y6;++j) pen6[i][j] = pen6[i-1][j] >> 1;
X}
X
X#define	Y7	7
Xunsigned int	pen7[8][Y7] =
X	{ 0x3800, 0x7c00, 0xfe00, 0xfe00, 0xfe00, 0x7c00, 0x3800 };
Xmk_pen7() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y7;++j) pen7[i][j] = pen7[i-1][j] >> 1;
X}
X
X#define	Y8	8
Xunsigned int	pen8[8][Y8] =
X	{ 0x3c00, 0x7e00, 0xff00, 0xff00, 0xff00, 0xff00, 0x7e00, 0x3c00 };
Xmk_pen8() { register int i, j;
X	for (i=1;i<8;++i) for (j=0;j<Y8;++j) pen8[i][j] = pen8[i-1][j] >> 1;
X}
X
X/*
X *	Per Page drawing initialization
X */
Xdraw_init()
X{
X	static int first_time = 1;
X	register int		y;
X
X	if (maxy >= miny)
X	{
X#		if VIRTUAL_MEMORY
X			(void) memset(bm[miny], 0, (maxy-miny+1) * XBYTES);
X#		else
X			for (y = miny; y <= maxy; ++y)
X				if (bm[y])
X				{
X					Free(bm[y]);
X					bm[y] = NULL;
X				}
X#		endif
X		maxy = 0; miny = YPIXELS;
X	}
X	if (first_time)
X	{
X		mk_pen2();
X		mk_pen3();
X		mk_pen4();
X		mk_pen5();
X		mk_pen6();
X		mk_pen7();
X		mk_pen8();
X		first_time = 0;
X	}
X}
X
X#if	!VIRTUAL_MEMORY
X
Xchar	*draw_alloc()
X{
X	register char	*p;
X
X	p = (char *) Malloc(XBYTES, 0);
X	if (!p)
X		error(1, "Can't get memory for picture drawing");
X	else
X		(void) memset(p, 0, XBYTES);
X	return (p);
X}
X
X#endif
X
X#ifdef	ERR_SEG_OVERWRITE	/* Too hard for AT&T 286 SGS */
X
X#define	BM_OR(y, x, bits)	{ register int _b=(bits); bm[y][x] |= _b; }
X
X#else
X
X#define	BM_OR(y, x, bits)	bm[y][x] |= (bits)
X
X#endif
X
X/*
X *	draw a point
X */
Xdraw_point(x, y)
X#ifdef lint
Xregister int x, y;
X#else
Xregister unsigned int x, y;
X#endif
X{
X	register int	i;
X	int		xb;
X	int		xp;
X	static int errcnt = 0;
X	static char bits[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
X
X	if (Landscape)
X		{ i = x; x = y; y = i;}
X
X	switch (PointSize)
X	{
X	case 1: case 2: case 3: case 4: case 5:
X	case 6: case 7: case 8: case 9: case 10: case 11:
X		/* smallest pen possible */
X		if (y < miny) miny = y;
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		if (x >= XPIXELS) goto out_range;
X#		if !VIRTUAL_MEMORY
X			if (!bm[y]) bm[y] = draw_alloc();
X#		endif
X		BM_OR(y, x>>3, bits[x & 7]);
X		break;
X	case 12: case 13: case 14: case 15:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y2-1)) goto out_range;
X		if (y-(Y2-1) < miny) miny = y-(Y2-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y2; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen2[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen2[xp][i] ) );
X		}
X		break;
X	case 16: case 17: case 18: case 19:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y3-1)) goto out_range;
X		if (y-(Y3-1) < miny) miny = y-(Y3-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y3; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen3[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen3[xp][i] ) );
X		}
X		break;
X
X	case 20: case 21: case 22: case 23:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y4-1)) goto out_range;
X		if (y-(Y4-1) < miny) miny = y-(Y4-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y4; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen4[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen4[xp][i] ) );
X		}
X		break;
X
X	case 24: case 25: case 26: case 27:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y6-1)) goto out_range;
X		if (y-(Y6-1) < miny) miny = y-(Y6-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y6; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen6[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen6[xp][i] ) );
X		}
X		break;
X
X	case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y7-1)) goto out_range;
X		if (y-(Y7-1) < miny) miny = y-(Y7-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y7; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen7[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen7[xp][i] ) );
X		}
X		break;
X
X	default:
X		if (x >= (XPIXELS-16)) goto out_range;
X		if (y < (Y8-1)) goto out_range;
X		if (y-(Y8-1) < miny) miny = y-(Y8-1);
X		if (y > maxy)
X			if (y >= YPIXELS) goto out_range; else maxy = y;
X		xb = x >> 3; xp = x & 7;
X		for (i = 0; i < Y8; ++i)
X		{
X#			if !VIRTUAL_MEMORY
X				if (!bm[y-i]) bm[y-i] = draw_alloc();
X#			endif
X			BM_OR(y-i, xb, hibyte( pen8[xp][i] ) );
X			BM_OR(y-i, xb+1, lobyte( pen8[xp][i] ) );
X		}
X		break;
X	}
X	return;
X
Xout_range:
X	if (++errcnt <= 5)
X		Fprintf(stderr, "Point off page at (%d,%d)\n", x, y);
X	return;
X}
X
X/*
X *	Dump graphics buffer
X */
Xdraw_output()
X{
X	register int y, x;
X
X	for (y = miny; y <= maxy; ++y)
X	{
X#		if VIRTUAL_MEMORY
X			for (x = 0; x < XBYTES; ++x)
X				if (bm[y][x])
X				{
X					draw_bits(x, y);
X					break;
X				}
X#		else
X			if (bm[y]) for (x = 0; x < XBYTES; ++x)
X				if (bm[y][x])
X				{
X					draw_bits(x, y);
X					break;
X				}
X#		endif
X	}
X}
X
X/*
X *	Found a line with raster data.  Print it
X *
X *	Attempt to optimize usage of laser jet
X *
X *	costs:
X *		position	7-13	11
X *		drop "."		 1
X *		horiz rule	12-18	16
X *		start+end bitmap	 9
X *		bitmap row	5-7+d	 6++
X *
X *	don't drop more than ten of any of these per row!
X */
Xtypedef struct
X{
X	int	fx;
X	int	lx;
X	int	length;
X} chunkinfo;
X
Xdraw_bits(fx, y)
Xint	fx;			/* First black pixel byte */
Xregister int	y;		/* Current y coord */
X{
X	register int	x;	/* Temporary x byte coord */
X	register int	lx;	/* Last black pixel byte */
X	int	length;		/* Length between fx and lx */
X	int	chunks;		/* # of "chunks" of non-white */
X	char	is, was;
X#	define	WHITETHRESH	8
X	int	white;
X	int	i;
X#	define	MAXCHUNKS	15
X	chunkinfo chunk[MAXCHUNKS+1];
X
X	for (lx = XBYTES-1; lx >= fx; --lx)
X		if (bm[y][lx]) break;
X	length = lx - fx + 1;
X	for (chunks = 0, x = fx, was = 0; x <= lx; ++x)
X	{
X		if (is = bm[y][x])
X		{
X			if (!was)
X			{
X				if (chunks < MAXCHUNKS)
X				{
X					++chunks;
X					chunk[chunks].fx = x;
X				}
X			}
X			white = 0;
X			chunk[chunks].lx = x;
X			chunk[chunks].length = x - chunk[chunks].fx + 1;
X			was = is;
X		}
X		else
X		{
X			if (++white >= WHITETHRESH)
X				was = 0;
X		}
X	}
X/*Fprintf(stderr, "y=%d, chunks=%d\n", y, chunks);*/
X	for (i = 1; i <= chunks; ++i)
X	{
X		int run;
X		fx = chunk[i].fx;
X		lx = chunk[i].lx;
X		length = chunk[i].length;
X
X		for (run = 1, x = fx+1; x < lx-1; ++x)
X			if (bm[y][x] != ((char) 0xff)) {run = 0; break;}
X		if (run)
X		{	/* everything in middle is total black */
X			/* Check endpoints */
X		}
X		if (Landscape)
X			hp_pos(y, fx << 3);
X		else
X			hp_pos(fx << 3, y);
X		esc("*r1A");			/* start */
X		esc("*b%dW", length);		/* raster */
X		for (x = fx; x <= lx; ++x)
X			(void) putc(bm[y][x], stdout);
X		esc("*rB");			/* End raster */
X		if (Landscape)
X			hp_is_at(y-1, fx << 3);
X		else
X			hp_is_at(fx << 3, y+1);
X	}
X	return;
X
X/*
Xburp:
X	Fprintf(stderr, "Don't know how to draw that yet\n");
X	Fprintf(stderr, "y=%d, fx=%d, lx=%d, chunks=%d\n",
X		y, fx, lx, chunks);
X*/
X}
END_OF_FILE
if test 9114 -ne `wc -c <'djet/draw.c'`; then
    echo shar: \"'djet/draw.c'\" unpacked with wrong size!
fi
# end of 'djet/draw.c'
fi
if test -f 'doc/BM.5' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/BM.5'\"
else
echo shar: Extracting \"'doc/BM.5'\" \(6803 characters\)
sed "s/^X//" >'doc/BM.5' <<'END_OF_FILE'
X.TH .BM 5 "PC Research, Inc." "JetRoff"
X.ds bm \fB\0.BM\fP
X.SH NAME
X .BM \- Macro for including bitmaps in troff output
X.SH SYNOPSIS
X \fB.BM \fIfilename type resolution placement
X \fB\\!x bitmap \fIfilename type resolution placement bitx bity
X.SH DESCRIPTION
X\fIjetroff\fP(1) adds the capability of including bitmaps (pictures)
Xcreated by other programs (and even other computers) into your
Xdocuments.  This capability is accessed by a simple macro, \fB.BM\fP.
XThe definition of this macro is automatically included when you
Xuse the \fIjetroff\fP(1) command.  If you do not use the \fIjetroff\fP
Xcommand, you must include the file \fI/usr/lib/tmac/tmac.jetroff\fP
Xin your document, before you try to use \*(bm.
X.P
X.BM monster.clp pcpaint 300 LJ
X\0
X.sp 1v
X.in +.5i
X\f(CW\0.BM monster.clp pcpaint 300 LJ\fP
X.in -.5i
X.sp 3v
X.P
X\*(bm places the bitmap in \fIfilename\fP in your document
Xat the current vertical place.  The \fItype\fP argument specifies
Xwhat type of bitmap is in \fIfilename\fP; more on that later.
XThe \fIresolution\fP argument can be 75, 100, 150, or 300; it
Xspecifies at what resolution (in dots per inch) to print the bitmap.
XThe \fIplacement\fP argument controls the horizontal position
Xof the bitmap, and whether or not text should flow around
Xthe bitmap.  These are the valid \fIplacement\fP options:
X.P
X.IP \fBL\fP .5i
XPlace the bitmap with the left edge on the left side of the page.
XSpace vertically so that the next text will appear after the bitmap.
X.IP \fBC\fP .5i
XCenter the bitmap on the page.  Space down the page
Xso that the next text will appear after the bitmap.
X.IP \fBR\fP .5i
XPlace the bitmap with the right edge on the right side of the page.
XSpace vertically so that the next text will appear after the bitmap.
X.IP \fBLJ\fP .5i
XPlace the bitmap on with the left edge on the left side of the page.
XArrange for subsequent text to flow around the bitmap to the right.
X.IP \fBRJ\fP .5i
XPlace the bitmap with the right edge on the right side of the page.
XArrange for subsequent text to flow around the bitmap to the left.
X.IP \fBLO\fP .5i
XPlace the bitmap with the left edge on the left side of the page.
XDo not reserve any space for the bitmap (overlay it on the page).
X.IP \fBCO\fP .5i
XCenter the bitmap on the page.
XDo not reserve any space for the bitmap (overlay it on the page).
X.IP \fBRO\fP .5i
XPlace the bitmap with the right edge on the right side of the page.
XDo not reserve any space for the bitmap (overlay it on the page).
X.P
XAn optional offset specification may be added to the \fIplacement\fP argument.
XIf it appears, the offset specification has the following format:
X.RS
X\fB(\fP\fIhoriz\fP\fB,\fP\fIvert\fP\fB)\fP
X.RE 
XThe offset specification must be placed immediately next to \fIplacement\fP
Xwithout any intervening spaces.  No spaces may appear inside
Xthe offset specification. The \fIhoriz\fP and \fIvert\fP arguments
Xare any legal \fItroff\fP relative motion commands for horizontal
Xand vertical motion respectively.  For example:
X.RS
X\f(CWL(+1i,+1v)\fP
X.RE
Xplaces the bitmap indented one inch from the left margin, and one
Xvertical line down from the current vertical position.
X.P
XThe \fItype\fP argument describes the type of bitmap in \fIfilename\fP.
XIt is actually a command (with optional arguments) which gets
Xhanded off to a separate program which knows how to read bitmaps.
XIf the command has optional arguments, the entire command and
Xargument list must be quoted. Currently, the only bitmap formats
Xwhich can be read with \fIjetroff\fP are
X\fBpcpaint\fP (for \fIPC Paint Plus\fP version 2.0 bitmaps and clippings),
X\fBpcx\fP (for \fIPC Paintbrush\fP bitmaps and many scanners),
Xand 
X\fBjetbm\fP (for \fIJetRoff Standard\fP bitmaps),
XOther bitmap formats can be used, either by writing a
Xcustom bitmap reader program (see \fIbitmap\fP(5)), or by converting them
Xto one of the above formats.
X.P
XAll bitmap processing commands support a common set of useful
Xoperations which can be performed upon the bitmap before
Xit is included in the document.  The common options are
Xlisted here.  For additional options which may be supported
Xby a particular bitmap format, see the appropriate manual
Xpage (e.g. \fIpcpaint\fP(1)).
X.P
X.IP \fB-a\fP\fIangle\fP .5i
XRotate the bitmap counterclockwise \fIangle\fP degrees.
X\fIangle\fP may be 90, 180, or 270.
X.IP \fB-c\fP .5i
XComplement the bitmap.  Print white areas of the bitmap as black,
Xand vice-versa.
X.IP \fB-i\fP .5i
XInvert the bitmap.  Flip the bitmap over right to left, so that it
Xlooks like its reflection in a mirror.
X.IP \fB-r\fP\fIpixels\fP .5i
XClip \fIpixels\fP dots off of the right edge of the bitmap.
X.IP \fB-l\fP\fIpixels\fP .5i
XClip \fIpixels\fP dots off of the left edge of the bitmap.
X.IP \fB-t\fP\fIlines\fP .5i
XClip \fIlines\fP off of the top edge of the bitmap.
X.IP \fB-b\fP\fIlines\fP .5i
XClip \fIlines\fP off of the bottom edge of the bitmap.
X.P
XThe options above may be combined in a command line as needed.
X.BM sword.clp pcpaint 300 LJ
XThey are processed from left to right; different ordering of
Xthese options produces different results.  For example, given
Xa raw bitmap that looks like the one on the left,
Xthe following commands produce decidedly different results:
X.P
X.BM sword.clp "pcpaint -a90 -i" 300 RJ
X\f(CW\0.BM sword.clp "pcpaint -a90 -i" 300 RJ\fP
X.br
XThis caused the bitmap to be rotated ninety degrees first,
Xand then flipped over right to left.
X
X
X.P
X.BM sword.clp "pcpaint -i -a90" 300 LJ
X\f(CW\0.BM sword.clp "pcpaint -i -a90" 300 LJ\fP
X.br
XThis caused the bitmap to be flipped over right to left first, and then
Xit was rotated 90 degrees.
X
X
X.ne .5i
X.SH EXPERTS
XThe second way to include bitmaps in your documents is with:
X.RS
X \f(CW\\!x bitmap \fIfilename type resolution placement bitx bity\fR
X.RE
XThis allows complete control of the bitmap placement.  The arguments
Xare the same as for \*(bm, except that \fIplacement\fP is
Xignored, and \fIbitx\fP and \fIbity\fP specify the exact pixel/line
Xlocation for the image.  No space for the image will be reserved;
Xyou must arrange for an appropriate amount of whitespace yourself.
X.SH FILES
X.IP \fB/usr/lib/tmac/tmac.jetroff\fP 2i
X\*(bm macro definition
X.IP \fB/usr/bin/jetroff_bm\fP 2i
XBitmap includer program
X.IP \fB/usr/bin/jetbm\fP 2i
XBitmap reader program
X.IP \fB/usr/bin/pcpaint\fP 2i
XBitmap reader program
X.IP \fB/usr/bin/pcx\fP 2i
XBitmap reader program
X.SH BUGS
XWild interactions can occur if two bitmaps are placed very near each
Xother vertically.
X.P
XThe number registers named ``%x'' and ``%y'' are used internally
Xby \*(bm.
X.P
XNon-existent bitmap \fItype\fPs cause your document to be silently
Xtruncated.
X.P
X\fItroff\fP knows nothing about bitmaps.  \*(bm does the best
Xjob it can under the circumstances.
X.SH SEE ALSO
Xjetroff(1), jetbm(1), pcpaint(1), pcx(1)
X.SH AUTHOR
X.BM pcr32P.jbm jetbm 150 L(+.5i,)
END_OF_FILE
if test 6803 -ne `wc -c <'doc/BM.5'`; then
    echo shar: \"'doc/BM.5'\" unpacked with wrong size!
fi
# end of 'doc/BM.5'
fi
if test -f 'font/mkfont/makedesc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'font/mkfont/makedesc.c'\"
else
echo shar: Extracting \"'font/mkfont/makedesc.c'\" \(8864 characters\)
sed "s/^X//" >'font/mkfont/makedesc.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: makedesc.c,v 1.1 87/10/23 19:08:09 sysad Exp $";
X#endif
X
X/* Read an ascii description of a ditroff font and create the         */
X/* corresponding binary font files                                    */
X
X
X/*
X * $Log:	makedesc.c,v $
X * Revision 1.1  87/10/23  19:08:09  sysad
X * Initial revision
X * 
X * 
X */
X
X#include <stdio.h>
X#ifdef SYS5
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X#include "dev.h"
X
X#define	SHORT	0xffff
X#define	MAXP	128		/* allocate space for point sizes in MAXP chunks */
Xint compat = 0;		/* compatibility with att "makedev"; duplicate "width"
X					 * entries are re-used if this is non-zero.
X					 */
Xchar *Progname;
Xstruct dev dev;
Xextern char *malloc(),*nextword(),*savestr();
Xextern char **font_names(),*fgets();
Xextern FILE *fopen();
Xextern short *p_sizes();
X
Xchar	*singlefont = NULL;
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X	FILE *inptr;
X	int fdout,nchtab,lchname,i,fsize,biggestfont;
X	long fontf_start;
X	short *point_list,*funny_ind;
X	char *funny_chars;
X	char **font_list;
X	char mybuf[1024];
X	char *str,*descfile;
X
X	Progname = argv[0];
X	++argv; --argc;
X
X	if(strcmp(*argv,"-c") == 0)
X	{
X		++compat;
X		++argv;
X		--argc;
X	}
X	if(argc == 0)
X	{
X		descfile = "DESC";
X	}
X	else if(argc == 1)
X	{
X		descfile = argv[0];
X	}
X	else if(argc == 2)
X	{
X		descfile = argv[0];
X		singlefont = argv[1];
X	}
X	else
X	{
X		fprintf(stderr,"usage: %s [-c] [descfile [fontfile]]\n",Progname);
X		exit(1);
X	}
X
X	if((inptr = fopen(descfile,"r")) == (FILE *)0)
X	{
X		fprintf(stderr,"%s: can't open %s\n",Progname,descfile);
X		exit(2);
X	}
X	if (!singlefont)
X	{
X		sprintf(mybuf,"%s.out",descfile);
X		if((fdout = open(mybuf,O_CREAT | O_WRONLY,0644)) < 0)
X		{
X			fprintf(stderr,"%s: can't create %s\n",Progname,mybuf);
X			exit(2);
X		}
X	}
X	dev.filesize = (short)0;
X	dev.sizescale = (short)1;
X	biggestfont = 0;
X	dev.spare = (short)0;
X	/* Build the dev structure first */
X	while(fgets(mybuf,1024,inptr))
X	{
Xstart:	/* we come back here if we read ahead in a font_names() */
X		if(!*mybuf || (*mybuf == '#'))
X			continue;
X		nextword("");	/* reset to beginning of line */
X		/* printf("line = %s\n",mybuf); */
X		str = nextword(mybuf);
X		if(strcmp(str,"charset") == 0)
X			break;
X		if(strcmp(str,"res") == 0)
X			dev.res = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"hor") == 0)
X			dev.hor = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"vert") == 0)
X			dev.vert = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"unitwidth") == 0)
X			dev.unitwidth = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"sizescale") == 0)
X			dev.sizescale = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"paperwidth") == 0)
X			dev.paperwidth = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"paperlength") == 0)
X			dev.paperlength = (short)atoi(nextword(mybuf));
X		else if(strcmp(str,"biggestfont") == 0)
X		{
X			biggestfont = atoi(nextword(mybuf));
X			dev.biggestfont = (short)biggestfont;
X		}
X		else if(strcmp(str,"sizes") == 0)
X		{
X			/* accumulate the list of legal point sizes */
X			point_list = p_sizes(inptr,mybuf,&dev);
X		}
X		else if(strcmp(str,"fonts") == 0)
X		{
X			dev.nfonts = (short)atoi(nextword(mybuf));
X			font_list = font_names(inptr,mybuf,dev.nfonts);
X			goto start;
X		}
X	}
X	nextword("");
X	/* Next comes the funny index table and the character strings; read
X	 * the description and stuff the information into the binary format 
X	 * tables.
X	 */
X	if(fgets(mybuf,1024,inptr) == (char *)0)
X	{
X		fprintf(stderr,"%s: no funny char strings table\n",Progname);
X		exit(1);
X	}
X	nchtab = get_funny(inptr,mybuf,&funny_ind,&funny_chars,&lchname);
X	dev.nchtab = (short)nchtab;
X	dev.lchname = (short)lchname;
X
X	/* We don't have enough information yet to write the dev structure
X	 * (don't know how many fonts, or their names...).  We do know how
X	 * big it is, and how long the description tables are, so we seek
X	 * past all that stuff andd write the font descriptions first.
X	 * Later, we'll go back and write the stuff we skipped over.
X	 */
X	fontf_start = (long)(sizeof(dev) + ((dev.nsizes +1) * sizeof(short))
X					+ (nchtab * sizeof(short)) + lchname);
X
X	if (singlefont)
X		fsize = do_font(singlefont,funny_chars,funny_ind,nchtab, -1);
X	else
X	{
X		(void)lseek(fdout,fontf_start,0);
X		/* Read the font files, and write the binary equivalents */
X		for(i = 0; i < (int)dev.nfonts; ++i)
X		{
X			fsize = do_font(font_list[i],
X				funny_chars,funny_ind,nchtab,fdout);
X			/* keep track of the biggest font */
X			if(fsize > biggestfont)
X				biggestfont = fsize;
X		}
X		dev.biggestfont = (short)(biggestfont & SHORT);
X		dev.filesize = (unsigned short)(lseek(fdout,0L,2)-sizeof(dev));
X		write_desc(fdout,&dev,point_list,funny_ind,funny_chars);
X	}
X	exit(0);
X}
X
X/* Read the point sizes list */
X
Xshort *
Xp_sizes(inptr,buf,dev)
XFILE *inptr;
Xchar *buf;
Xstruct dev *dev;
X{
X	short *pl,*ret;
X	char *word,*realloc();
X	int nwords = 0;
X	int n;
X
X	/* allow for MAXP point sizes; we have to reallocate if we exceed that */
X	ret = pl = (short *)malloc((unsigned)(MAXP * sizeof(short)));
X	if(!pl)
X	{
X		fprintf(stderr,"can't malloc space for psizes\n",Progname);
X		exit(1);
X	}
X	n = 1;
X	while((word = nextword(buf)) || fgets(buf,1024,inptr))
X	{
X		if(!word)
X		{
X			nextword("");
X			word = nextword(buf);
X		}
X		if(!word)	/* ran out of words this line, had to fgets more */
X		{
X			nextword("");
X			if(fgets(buf,1024,inptr))
X				word = nextword(buf);
X			else
X			{
X				*buf = '\0';
X				break;
X			}
X		}
X		nwords++;
X		if(nwords >= MAXP)
X		{
X			/* Oops! ran out os space; get more */
X			ret = (short *)realloc((char *)ret,(unsigned)(MAXP * ++n * sizeof(short)));
X			pl = &ret[nwords];	/* could have moved */
X		}
X		*pl = (short)atoi(word);
X		if(*pl == (short)0)
X			break;
X		++pl;
X	}
X	/* don't count the zero at the end */
X	--nwords;
X	dev->nsizes = (short)nwords;
X	return(ret);
X}
X
X/* Read and save the font names; return the list */
X
Xchar **
Xfont_names(inptr,buf,nfonts)
XFILE *inptr;
Xchar *buf;
Xshort nfonts;
X{
X	char **ret,**next;
X	char *word;
X	int nwords = 0;
X
X	ret = next = (char **)malloc((unsigned)((nfonts + 1) * sizeof(char *)));
X
X	while((word = nextword(buf)) || fgets(buf,1024,inptr))
X	{
X		if(!word)
X		{
X			nextword("");
X			word = nextword(buf);
X		}
X		*next++ = savestr(word);
X		if(++nwords >= (int)nfonts)
X		{
X			/* main() expects a new buffer */
X			fgets(buf,1024,inptr);
X			break;
X		}
X	}
X	*next = (char *)0;
X	if(nwords != (int)nfonts)
X		printf("%s: warning; only got %d of %d font names\n",Progname,nwords,(int)nfonts);
X	return(ret);
X}
X
X
X#define	MAX_FUNNY	384
X
X/* Read the special character strings, and set up the string table and
X * the index into it.
X */
Xget_funny(inptr,mybuf,funny_ind,funny_chars,lchname)
XFILE *inptr;
Xchar *mybuf;
Xshort **funny_ind;
Xchar **funny_chars;
Xint *lchname;
X{
X	char *fct;	/* funny char string table */
X	short *fci; /* funny char index		   */
X	int i = 0;
X	int lastp = 0;
X	char *str;
X
X	/* allocate for 256 3-character strings (plus null)		*/
X	/* We should probably check for overflow, but I can't imagine a	*/
X	/* character set with more than 256 special chars (FLW)		*/
X
X	/* HAH!  Now allow MAX_FUNNY (RER) 06/16/88 */
X
X	*funny_chars = fct = malloc((unsigned)MAX_FUNNY*3);
X	*funny_ind = fci =
X		(short *)malloc((unsigned)((MAX_FUNNY+1) * sizeof(short)));
X
X	/* assume the strings start on a new line */
X	fci[0] = (short)0;
X	while((str = nextword(mybuf)) || fgets(mybuf,1024,inptr))
X	{
X		if(!str)
X		{
X			nextword("");
X			str = nextword(mybuf);
X			if(!str)
X				continue;
X		}
X		(void)strcpy(fct + lastp,str);
X		fci[i++] = (short)(lastp & SHORT);
X		lastp += strlen(str) + 1;
X		if(i > MAX_FUNNY)
X		{
X			fprintf(stderr,
X				"%s: too many special strings (> %d)\n",
X				Progname, MAX_FUNNY);
X			break;
X		}
X	}
X	fci[i++] = (short)0;
X	*lchname = lastp;
X	return(i);
X}
X
X/* Write out the dev structure,the sizes table, and the funny char tables */
Xwrite_desc(fdout,dev,point_list,funny_ind,funny_chars)
Xint fdout;
Xstruct dev *dev;
Xshort *point_list,*funny_ind;
Xchar *funny_chars;
X{
X
X	long l;
X
X	/* Seek back to the beginning of the file */
X
X	(void)lseek(fdout,0L,0);
X
X	/* dev structure */
X	if(write(fdout,(char *)dev,sizeof(struct dev)) != sizeof(struct dev))
X	{
X		fprintf(stderr,"%s: write dev struct to description file failed\n",Progname);
X		exit(1);
X	}
X
X	/* point sizes table */
X	if(write(fdout,(char *)point_list,(int)(dev->nsizes +1) * 2) != (int)(dev->nsizes + 1) * 2)
X	{
X		fprintf(stderr,"%s: write size list to description file failed\n",Progname);
X		exit(1);
X	}
X
X	/* table of indexes into special char strings */
X	if(write(fdout,(char *)funny_ind,(int)(dev->nchtab * 2)) != (int)(dev->nchtab * 2))
X	{
X		fprintf(stderr,"%s: write index list to description file failed\n",Progname);
X		exit(1);
X	}
X
X	/* special char strings */
X	if(write(fdout,funny_chars,(int)(dev->lchname)) != (int)(dev->lchname))
X	{
X		fprintf(stderr,"%s: write funny char strings to description file failed\n",Progname);
X		exit(1);
X	}
X	l = lseek(fdout,0L,1);
X}
END_OF_FILE
if test 8864 -ne `wc -c <'font/mkfont/makedesc.c'`; then
    echo shar: \"'font/mkfont/makedesc.c'\" unpacked with wrong size!
fi
# end of 'font/mkfont/makedesc.c'
fi
if test -f 'font/mkfont/mkfont.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'font/mkfont/mkfont.c'\"
else
echo shar: Extracting \"'font/mkfont/mkfont.c'\" \(8192 characters\)
sed "s/^X//" >'font/mkfont/mkfont.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: mkfont.c,v 1.1 87/10/23 19:08:10 sysad Exp $";
X#endif
X
X/*
X * $Log:	mkfont.c,v $
X * Revision 1.1  87/10/23  19:08:10  sysad
X * Initial revision
X * 
X * 
X */
X
X#include <stdio.h>
X#ifdef SYS5
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X#include "font.h"
X#include "dev.h"
Xextern struct dev dev;
X#ifdef SYS5
X#define	bzero(a,b)	memset(a,0,b)
X#endif
X
X#define NCHARMAX	256			/* max chars in font */
X#define	NASC		96			/* number of printable ascii chars */
X#define	BYTE		0xff		/* mask */
X#define	SHORT		0xffff		/* mask */
X
Xextern char *malloc(),*savestr(),*nextword(),*fgets();
Xextern FILE *fopen();
Xextern char *Progname;
Xextern int compat;
X
X/* Read the ascii font description files, and write the binary files. */
X/*                                                                    */
X
Xdo_font(fontname,funny_chars,funny_ind,nchtab,fdout)
Xchar *fontname,*funny_chars;
Xshort *funny_ind;
Xint nchtab,fdout;
X{
X	FILE *src;
X	char mybuf[256];
X	/* allocate them just once */
X	static char *width,*kern,*code,*fontindex = (char *)0;
X	
X	struct Font font;
X	char *word;
X	int dest,spacewidth,nwfont,indx;
X
X	/* The ascii source file, named by the font name. */
X	if((src = fopen(fontname,"r")) == (FILE *)0)
X	{
X		fprintf(stderr,"%s: can't open font %s\n",Progname,fontname);
X		exit(1);
X	}
X
X	/* create the binary font face file */
X	sprintf(mybuf,"%s.out",fontname);
X	if((dest = open(mybuf,O_CREAT | O_WRONLY,0644)) < 0)
X	{
X		fprintf(stderr,"%s: can't create font %s output file\n",Progname,mybuf);
X		exit(1);
X	}
X	fontindex = width = kern = code = (char *)0;
X
X	spacewidth = 0;
X	font.ligfont = (char)0;
X
X    /* Build the font structure.                                      */
X
X	while(fgets(mybuf,256,src))
X	{
X		word = nextword("");	/* reset to beginning of line */
X		word = nextword(mybuf);
X		if(!word || !*word || (*word == '#'))
X			continue;
X		if(strcmp(word,"charset") == 0)
X			break;
X		if(strcmp(word,"name") == 0)
X			strncpy(font.namefont,nextword(mybuf),10);
X		else if(strcmp(word,"internalname") == 0)
X			strncpy(font.intname,nextword(mybuf),10);
X		else if(strcmp(word,"spacewidth") == 0)
X			spacewidth = atoi(nextword(mybuf)) & BYTE;
X		else if(strcmp(word,"special") == 0)
X			font.specfont =  0x01;
X		else if(strcmp(word,"ligatures") == 0)
X		{
X			while(word = nextword(mybuf))
X			{
X				if(*word == '0')
X					break;
X				else if(strcmp(word,"fi") == 0)
X					font.ligfont |= LIG_FI;
X				else if(strcmp(word,"fl") == 0)
X					font.ligfont |= LIG_FL;
X				else if(strcmp(word,"ff") == 0)
X					font.ligfont |= LIG_FF;
X				else if(strcmp(word,"ffi") == 0)
X					font.ligfont |= LIG_FFI;
X				else if(strcmp(word,"ffl") == 0)
X					font.ligfont |= LIG_FFL;
X			}
X		}
X	}
X
X	/* The next 4 tables are allocated just once, big enough for any font,
X	 * then re-used for each font face.
X	 */
X
X	if(fontindex == (char *)0)
X	{
X		fontindex = malloc((unsigned)(NASC + nchtab));
X		if(fontindex == (char *)0)
X		{
X			fprintf(stderr,"%s: can't malloc font index table\n",Progname);
X			exit(1);
X		}
X	}
X
X	if(width == (char *)0)
X	{
X		width = malloc(NCHARMAX);
X		if(width == (char *)0)
X		{
X			free(fontindex);
X			fontindex = (char *)0;
X			fprintf(stderr,"%s: can't malloc font widths table\n",Progname);
X			exit(1);
X		}
X	}
X	if(kern == (char *)0)
X	{
X		kern = malloc(NCHARMAX);
X		if(kern == (char *)0)
X		{
X			free(width);
X			free(fontindex);
X			fontindex = (char *)0;
X			width = (char *)0;
X			fprintf(stderr,"%s: can't malloc font kern table\n",Progname);
X			exit(1);
X		}
X	}
X
X	if(code == (char *)0)
X	{
X		code = malloc(NCHARMAX);
X		if(code == (char *)0)
X		{
X			free(width);
X			free(kern);
X			free(fontindex);
X			fontindex = (char *)0;
X			width = (char *)0;
X			kern = (char *)0;
X			fprintf(stderr,"%s: can't malloc font code table\n",Progname);
X			exit(1);
X		}
X	}
X
X	/* clear them */
X	bzero(width,NCHARMAX);
X	bzero(kern,NCHARMAX);
X	bzero(code,NCHARMAX);
X	bzero(fontindex,NASC + nchtab);
X
X	/* first width entry is width of space if non-zero */
X	if (spacewidth)
X		width[0] = (char)(spacewidth & BYTE);
X	else /* if (compat) NOPE: troff needs a width all the time!!! */
X		width[0] = dev.res * dev.unitwidth / (72*3);
X	kern[0] = '\0';
X	code[0] = '\0';
X
X	nwfont = 1;
X	
X	/* decode the character set info and stuff the width, kern, code
X	 * tables, building the font index table as we go
X	 */
X	while(fgets(mybuf,256,src))
X	{
X		nextword("");	/* reset to beginning of line */
X		word = nextword(mybuf);
X		if(!word || !*word)
X			continue;
X		if(strlen(word) == 1)
X			indx = (*word & BYTE) - 32;		/* printable ascii */
X		else
X			indx = spcl(word,funny_chars,funny_ind,nchtab); /* troff special chars */
X		if(indx < 0)
X		{
X			fprintf(stderr,"%s: special string \"%s\" is not defined in desc\n",Progname,word);
X			fprintf(stderr,"...skipping\n");
X			continue;
X		}
X
X		/* check for repeat characters ( " in width column) */
X		word = nextword(mybuf);
X
X		if(*word == '"')
X		{
X			/* It appears that att's "makefont" doesn't make a new
X			 * width entry for dups--it just reuses the earlier one.
X			 * It would be much easier for "rdfont" to decode these
X			 * things if we just made a duplicate entry, but for
X			 * compatibility with "makefont" (as determined by examination
X			 * of compiled fonts delivered to us)...
X			 */
X			if(!compat)
X			{
X				/* make a separate width entry for each duplicate */
X				width[nwfont] = width[nwfont - 1];
X				kern[nwfont] = kern[nwfont - 1];
X				code[nwfont] = code[nwfont - 1];
X				fontindex[indx] = (char)(nwfont & BYTE);
X				nwfont++;
X			}
X			fontindex[indx] = (char)((nwfont - 1) & BYTE);
X			continue;
X		}
X		fontindex[indx] = (char)(nwfont & BYTE);
X		width[nwfont] = (char)(atoi(word) & BYTE);
X		word = nextword(mybuf);
X		kern[nwfont] = (char)(atoi(word) & BYTE);
X		word = nextword(mybuf);
X		code[nwfont++] = (char)(atoo(word) & BYTE);
X	}
X
X	fclose(src);
X	if (compat && dev.biggestfont > nwfont)
X		nwfont = dev.biggestfont;	/* AT&T always pads */
X	font.nwfont = (short)(nwfont & BYTE);
X	printf("%s: nwfont = %d\n",fontname,nwfont);
X
X
X
X	/* write the tables, first to the description file, then to the
X	 * individual font file.
X	 */
X	if(fdout!=-1 &&
X		write(fdout,(char *)&font,sizeof(struct Font)) != sizeof(struct Font))
X	{
X		fprintf(stderr,"%s: write font struct to description file failed\n",Progname);
X		exit(1);
X	}
X	if(write(dest,(char *)&font,sizeof(struct Font)) != sizeof(struct Font))
X	{
X		fprintf(stderr,"%s: write font struct to font output file failed\n",Progname);
X		exit(1);
X	}
X	if(fdout!=-1 && write(fdout,width,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write width table to description file failed\n",Progname);
X		exit(1);
X	}
X	if(write(dest,width,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write width table to font output file failed\n",Progname);
X		exit(1);
X	}
X	if(fdout!=-1 && write(fdout,kern,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write kern table to description file failed\n",Progname);
X		exit(1);
X	}
X	if(write(dest,kern,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write kern table to font output file failed\n",Progname);
X		exit(1);
X	}
X	if(fdout!=-1 && write(fdout,code,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write code table to description file failed\n",Progname);
X		exit(1);
X	}
X	if(write(dest,code,nwfont) != nwfont)
X	{
X		fprintf(stderr,"%s: write code table to font output file failed\n",Progname);
X		exit(1);
X	}
X	if(fdout!=-1 && write(fdout,fontindex,nchtab + NASC) != nchtab + NASC)
X	{
X		fprintf(stderr,"%s: write font index table to description file failed\n",Progname);
X		exit(1);
X	}
X	if(write(dest,fontindex,nchtab + NASC) != nchtab + NASC)
X	{
X		fprintf(stderr,"%s: write font index table to font output file failed\n",Progname);
X		exit(1);
X	}
X	close(dest);	/* done with this font file */
X	return(nwfont);	/* the return is extraneous here */
X}
X
X/* Find the font index of special character strings */
X
Xspcl(word,funny_chars,funny_ind,nchtab)
Xchar *word,*funny_chars;
Xshort *funny_ind;
Xint nchtab;
X{
X	int i;
X
X	for(i = 0; i < nchtab; ++i)
X	{	
X		if(strcmp(word,funny_chars + (int)(funny_ind[i] & SHORT)) == 0)
X			return(i + NASC);
X	}
X	return(-1);
X}
X
X/* convert an octal string representation to an int */
X
Xatoo(str)
Xchar *str;
X{
X	int i;
X	/* cheat */
X	if (str[0] == '0')
X		sscanf(str,"%o",&i);
X	else
X		sscanf(str,"%d",&i);
X	return(i);
X}
END_OF_FILE
if test 8192 -ne `wc -c <'font/mkfont/mkfont.c'`; then
    echo shar: \"'font/mkfont/mkfont.c'\" unpacked with wrong size!
fi
# end of 'font/mkfont/mkfont.c'
fi
if test -f 'font/mkfont/rdfont.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'font/mkfont/rdfont.c'\"
else
echo shar: Extracting \"'font/mkfont/rdfont.c'\" \(8546 characters\)
sed "s/^X//" >'font/mkfont/rdfont.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: rdfont.c,v 1.1 87/10/23 19:08:13 sysad Exp $";
X#endif
X
X/*
X * $Log:	rdfont.c,v $
X * Revision 1.1  87/10/23  19:08:13  sysad
X * Initial revision
X * 
X * 
X */
X
X#include <stdio.h>
X#include "font.h"
X
X#ifdef SYS5
X#define	bzero(a,b)	memset(a,0,b)
X#endif
X
X#define	SHORT	0xffff		/* mask */
X#define	HISHORT	0xffff0000	/* mask */
X#define	BYTE	0xff		/* mask */
X#define NASC	96			/* number of printable ascii characters */
Xextern char *malloc(),*savestr(),*pr_font();
Xextern char *Progname;
Xextern int debugging;
X
Xchar *
X/* Read a binary font face file */
X
Xrdfont(fd,nspec,funny_tab,funny_index)
Xint fd,nspec;
Xchar *funny_tab;
Xshort *funny_index;
X{
X	char *widths;
X	char *kerning;
X	char *code;
X	char *font_ind;
X	char *fname;
X	struct Font font;
X	unsigned int nwidths;
X	int i;
X
X	/* get the font info from the description file */
X	if(read(fd,(char *)&font,sizeof(struct Font)) != sizeof(struct Font))
X	{
X		fprintf(stderr,"%s: can't read font info\n",Progname);
X		return((char *)0);
X	}
X
X	/* Allocate space for the tables */
X	nwidths = font.nwfont & BYTE;
X	widths = malloc(nwidths);
X	if(!widths)
X	{
X		fprintf(stderr,"%s: can't malloc widths\n",Progname);
X		return((char *)0);
X	}
X	kerning = malloc(nwidths);
X	if(!kerning)
X	{
X		fprintf(stderr,"%s: can't malloc kerning\n",Progname);
X		free(widths);
X		return((char *)0);
X	}
X	code = malloc(nwidths);
X	if(!code)
X	{
X		fprintf(stderr,"%s: can't malloc code\n",Progname);
X		free(widths);
X		free(kerning);
X		return((char *)0);
X	}
X
X	/* Read 'em in */
X	if((i = read(fd,widths,nwidths)) != nwidths)
X	{
X		fprintf(stderr,"%s: read %d of %d widths \n",i,nwidths,Progname);
X		free(widths);
X		free(kerning);
X		free(code);
X		return((char *)0);
X	}
X	if((i = read(fd,kerning,nwidths)) != nwidths)
X	{
X		fprintf(stderr,"%s: read %d of %d kernings\n",i,nwidths,Progname);
X		free(widths);
X		free(kerning);
X		free(code);
X		return((char *)0);
X	}
X	if((i = read(fd,code,nwidths)) != nwidths)
X	{
X		fprintf(stderr,"%s: read %d of %d codes\n",i,nwidths,Progname);
X		free(widths);
X		free(kerning);
X		free(code);
X		return((char *)0);
X	}
X	font_ind = malloc(NASC + nspec);
X	if(!font_ind)
X	{
X		fprintf(stderr,"%s: malloc font_ind failed\n",Progname);
X		free(widths);
X		free(kerning);
X		free(code);
X		return((char *)0);
X	}
X	if(read(fd,font_ind,NASC + nspec) != NASC + nspec)
X	{
X		fprintf(stderr,"%s: read %d of %d of index table\n",i,NASC + nspec,Progname);
X		free(font_ind);
X		free(widths);
X		free(kerning);
X		free(code);
X		return((char *)0);
X	}
X	/* Now we can print the font description files; pr_font() also saves
X	 * the font name for us, to return to main().
X	 */
X	fname = pr_font(&font,widths,kerning,code,font_ind,funny_tab,funny_index,nspec);
X	free(font_ind);
X	free(widths);
X	free(kerning);
X	free(code);
X	return(fname);
X}
X
X
X/* Prints tha ascii font description.  Saves the fontname, properly
X * null-terminated, and returns it to rdfont() for pass back to main().
X */
Xchar *
Xpr_font(font,widths,kerning,code,font_ind,funny_tab,funny_index,nspec)
Xstruct Font *font;
Xchar *widths,*kerning,*code,*font_ind,*funny_tab;
Xshort *funny_index;
Xint nspec;
X{
X	int f,i,j,k,f_ind;
X	char *funny_str;
X	int nwidths;
X	FILE *fontf;
X	char fontname[16];
X	char intname[16];
X	char *fname;
X	int rti[4][256];		/* for a "reverse index table" into the font index */
X
X	nwidths = (int)(font->nwfont & BYTE);
X
X	/* make sure we have null-terminated names */
X	strncpy(fontname,font->namefont,10);
X	strncpy(intname,font->intname,10);
X	fontname[10] = '\0';
X	intname[10] = '\0';
X
X	/* now save a copy of the processed fontname for return (never freed) */
X	fname = savestr(fontname);
X
X	/* In case there's an original file, avoid overwriting it */
X	strcat(fontname,".new");
X
X	if((fontf = fopen(fontname,"w")) == (FILE *)0)
X	{
X		fprintf(stderr,"%s: can't open font file %s for writing\n",Progname,fontname);
X		exit(1);
X	}
X	if(debugging)		/* if compiled for debugging */
X		printf("\n\n\n\nwriting %s (%s)\n",fname,intname);
X
X	/* print the header information, from the font structure */
X	/* nwfont is printed as a comment, for reference 		 */
X	fprintf(fontf,"#nwfont %d\n",nwidths);
X	fprintf(fontf,"name %s\n",fname);
X	fprintf(fontf,"internalname %s\n",intname);
X	if(font->specfont)
X		fprintf(fontf,"special\n");
X	if(font->ligfont)
X		pr_lig(fontf,(char)(font->ligfont & BYTE));
X
X	/* widths[0] is spacewidth (if non-zero); real stuff starts at 1 */
X	if(widths[0] & BYTE)
X		fprintf(fontf,"spacewidth %u\n",(int)(widths[0] & BYTE));
X
X	widths[0] = '\0';
X	fprintf(fontf,"charset\n");
X	if(debugging)
X		printf("font index table\n\n");
X
X	/* Build a "reverse index table" which permits us to find the character
X	 * which corresponds to a given width table entry.
X	 */
X	bzero(rti,sizeof(rti));
X	for(j = 1; j < nspec + NASC ; ++j)
X	{
X		i = (int)(font_ind[j] & BYTE);
X		if(i > nwidths)
X		{
X			fprintf(stderr,"%s: width table too small ? (%d; need %d)\n",
X					Progname,nwidths,i & BYTE);
X			continue;
X		}
X		/* If rti[i] is non-zero, we have two names for the same character,
X		 * and it's a pain.  This is a hack, and only allows for four names.
X		 * It would be unnecessary if "makefont" simply made a duplicate
X		 * width table entry for each duplicate.  It also assumes that
X		 * each of the indexes will be < 256.
X		 * Tack the new value into the next free byte of the int.
X		 */
X		if(i && rti[0][i])
X		{
X			for(k = 1; k < 4; ++k)
X			{
X				if(rti[k][i] == 0)
X				{
X					rti[k][i] = j;
X					break;
X				}
X			}
X			if(k == 4)
X			{
X				fprintf(stderr,"%s: too many duplicates, width index %d\n",Progname,i);
X				exit(1);
X			}
X		}
X		else
X			rti[0][i] = j;
X		if(debugging)
X		{
X			printf("%d\t%d\t",j,i);
X			if(j < NASC)
X				printf("\t\t\t%c\t%d  %d  %#o\n",j + 32,
X					(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X			else
X			{
X				f_ind = (int)(funny_index[j - NASC] & SHORT);
X				funny_str = funny_tab + (f_ind & SHORT);
X				if(!funny_str)
X					funny_str = "??";
X				printf("(f_ind=%d)\t%s\t%d\t%d\t%#o\n",f_ind,funny_str,
X					(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X			}
X		}
X	}
X
X	/* Now print the width table, starting at 1 (since width 0 is spacewidth) */
X	if(debugging)
X	{
X		printf("\n\nWidth table\n\n");
X		printf("POS\tWIDTH\t\tKERN\t\tCODE\n");
X	}
X	for(i = 1; i < nwidths; ++i)
X	{
X		/* position in the font index table tells us what character 
X		 * corresponds to this width table entry (if any).  Except we
X		 * have to handle the hack for duplicate names...
X		 */
X		for(k = 0; k < 4; ++k)
X		{
X			j = rti[k][i];
X			if(j == 0)
X			{
X				break;
X			}
X			f = (int)(font_ind[j] & BYTE);
X			if(f == 0)
X			{
X				continue;	/* not in this font */
X			}
X			if(f != i)
X			{
X				fprintf(stderr,"%s: reverse index table out of sync (%d != %d) at %d\n",Progname,f,i,j);
X				exit(1);
X			}
X			if(j < NASC)
X			{
X				if(debugging)
X					printf("\t\t\t%c\t%d  %d  %#o\n",j + 32,
X						(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X				if(k)
X					fprintf(fontf,"%c\t\"\n",j + 32);	/* duplicate */
X				else
X					fprintf(fontf,"%c\t%d\t%d\t%#o\n",j + 32,
X						(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X			}
X			else
X			{
X				f_ind = (int)(funny_index[j - NASC] & SHORT);
X				funny_str = funny_tab + (f_ind & SHORT);
X				if(!funny_str)
X					funny_str = "??";
X				if(debugging)
X					printf("(f_ind=%d)\t%s\t%d\t%d\t%#o\n",f_ind,funny_str,
X						(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X				if(k)
X					fprintf(fontf,"%s\t\"\n",funny_str);
X				else
X					fprintf(fontf,"%s\t%d  %d  %#o\n",funny_str,
X						(int)(widths[i] & BYTE),(int)(kerning[i] & BYTE),(int)(code[i] & BYTE));
X			}
X		}
X	}
X	fclose(fontf);
X	printf("%s.out --> %s\n",fname,fontname);
X	return(fname);
X}
X
Xpr_lig(fontf,ligatures)
XFILE *fontf;
Xchar ligatures;
X{
X	fprintf(fontf,"ligatures ");
X	if(ligatures & LIG_FF)
X		fprintf(fontf," ff");
X	if(ligatures & LIG_FI)
X		fprintf(fontf," fi");
X	if(ligatures & LIG_FL)
X		fprintf(fontf," fl");
X	if(ligatures & LIG_FFI)
X		fprintf(fontf," ffi");
X	if(ligatures & LIG_FFL)
X		fprintf(fontf," ffl");
X	fprintf(fontf," 0\n");
X}
X
X/* 'nuff said...  */
Xunion kludge {
X	int i;
X	char c[4];
X} kludge;
X
X/* add byte y to x in the lowest zero-valued byte, if any. */
X
Xaddbyte(x,y)
Xint x,y;
X{
X	int i;
X
X	kludge.i = x;
X	for(i = 3; i >= 0; --i)
X		if((kludge.c[i] & BYTE) == 0)
X		{
X			kludge.c[i] = y & BYTE;
X			return(kludge.i);
X		}
X	return(x);
X}
X
X/* shift bytes down in an int, zeroing high byte */
X
Xshiftdown(x)
Xint x;
X{
X	int i;
X
X	kludge.i = x;
X	for(i = 3; i > 0; --i)
X		kludge.c[i] = kludge.c[i - 1];
X	kludge.c[0] = '\0';
X	return(kludge.i);
X}
END_OF_FILE
if test 8546 -ne `wc -c <'font/mkfont/rdfont.c'`; then
    echo shar: \"'font/mkfont/rdfont.c'\" unpacked with wrong size!
fi
# end of 'font/mkfont/rdfont.c'
fi
echo shar: End of archive 5 \(of 7\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.sources.misc mailing list