HP LaserJet driver part 2 of 2.

sources-request at panda.UUCP sources-request at panda.UUCP
Wed Sep 25 23:53:27 AEST 1985


Mod.sources:  Volume 3, Issue 19
Submitted by: philabs!ron1!ron (Ron Saad)


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	hp.c
# This archive created: Mon Sep 23 23:09:35 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'hp.c'" '(28471 characters)'
if test -f 'hp.c'
then
	echo shar: will not over-write existing file "'hp.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'hp.c'
	X/* vi:se ts=4 sw=4 wm=0: */
	Xstatic char *RCSid =
	X		"$Header: hp.c,v 1.1.1.9 85/08/17 15:53:35 ron Exp $";
	X
	X/*
	X * hp.c - Copyright (c) 1985 by Ron Saad (ron1!ron)
	X * All Rights Reserved.
	X *
	X * This code maybe freely distributed in source
	X * for non commercial purposes.
	X * Please keep this notice intact.
	X */
	X
	X/*
	X * $Log:	hp.c,v $
	X * Revision 1.1.1.9  85/08/17  15:53:35  ron
	X * As usual, just 'one more thing ..' - moved the
	X * size cheating code to where it belongs - just before
	X * the file gets read in.
	X * still to do:
	X * make vgoto adjust the height to scale for not having a full
	X * 11 inches, otherwise get bogus page feeds.
	X * 
	X * Revision 1.1.1.8  85/08/15  14:50:29  ron
	X * this seems to be the version going out to mod.sources
	X * (if they'll take it).
	X * 
	X * Revision 1.1.1.7  85/08/07  23:13:06  ron
	X * this is probably a usable version of the laserjet driver. it loads
	X * bit maps for special fonts and for sizes that are not on the cartridge,
	X * and has the basis for enhancement - it still needs a LOT of work:
	X * CLEANING UP!
	X * recognition of vfont/rasti10 by f_magic - add field to FINFO
	X * 	and use to decide on height/width of character, positioning, etc.
	X * add code tables for rasti10 bit maps.
	X * etc
	X * 
	X * Revision 1.1.1.6  85/08/04  12:38:56  ron
	X * added font info table, changed font reads to a fseek followed
	X * by charater data reads. still need to add code tables for rasti10
	X * and distinguish between rasti10 and vfont. add field to finfo based
	X * on the f_magic and enforce f_magic. find out why vfont produces
	X * poorly placed characters.
	X * has not yet been tested.
	X * 
	X * Revision 1.1.1.5  85/08/02  14:08:40  ron
	X * adding a font info table so that we can use more than
	X * one bit-map at a time without constantly loading/unloading
	X * files. may also change the loading to an fseek followed by a read to
	X * minimize file access since most of the bit-map stuff are done
	X * for only a few characters.
	X * therefore keep this "pre-change" version b4 i destroy it ...
	X * 
	X * Revision 1.1.1.4  85/07/28  15:07:33  ron
	X * works. is confined to one size - next step is size changes. rule
	X * is done wrong - comes out too low - should use bit map.
	X * knows about differences between vfont and rasti10 - i.e. adding
	X * 1 bit and 1 row when needed.
	X * 
	X * Revision 1.1.1.3  85/07/21  16:28:51  ron
	X * first attempt at adding the special font as a raster
	X * map and dump'n out bit maps when appropriate.
	X * 
	X * Revision 1.1.1.2  85/07/19  12:24:15  ron
	X * took out the 'optimization'. it does work, i.e. cuts file size,
	X * imaging time etc, but the spacing of the laserjet is much larger
	X * than what troff thinks it is.
	X * 
	X * Revision 1.1.1.1  85/07/10  10:26:06  ron
	X * gave up on eliminating hpos for now. may try again
	X * later.
	X * 
	X * Revision 1.1.0.2  85/07/10  08:38:59  ron
	X * ok, put in a fudge to do hflush() only if it's not
	X * a sequence of characters.
	X * 
	X * Revision 1.1.0.1  85/07/10  08:30:23  ron
	X * the numbering in rcs is ridiculous. anyway, this is the 'starting'
	X * file for this 'branch'. goal is to eliminate as many horiz position
	X * as possible, since this takes forever on the laserjet. next try
	X * is to let the printer do the spacing in every case where
	X * we have just printed a sequence of 2hor-mot-digits+char and
	X * have another one immediately following.
	X * 
	X * 
	X */
	X
	X
	X#include	<stdio.h>
	X#include	<signal.h>
	X#include	<ctype.h>
	X#include	<strings.h>
	X
	X#include "glyph.h"
	X#include "asctab.h"
	X#include "spectab.h"
	X
	Xint	output	= 0;	/* do we do output at all? */
	Xint	pgindex	= 0;	/* output page list if > 0 */
	Xint	pagelist[20];	/* pairs of page numbers */
	X
	X
	X
	X#define	FATAL	1
	Xint	dbg	= 0;
	X
	X#define	dprintf	if (dbg) fprintf
	X#define	dinfoprint	if (dbg) finfoprint
	X
	Xint	res	= 720;
	X	/* input assumed computed according */
	X	/* to this resolution (actually 723) */
	X	/* initial value to avoid 0 divide */
	X
	Xchar	*dfltdir	= "/usr/lib/vfont";
	X
	Xchar	*fontdir	= "/usr/lib/font";
	Xchar	*vfontdir	= "/usr/lib/vfont";
	Xchar	*rfontdir	= "/usr/src/cmd/text/troff.d/devi10/rasti10";
	X
	Xextern char devname[];
	X
	Xint	want_siz = 10;	/* convenient defaults */
	Xint	crnt_siz = 10;
	X
	Xint	c_fnt_indx = 0;
	Xint cartridge = 1;
	X
	X#define	NUMFONTS	8
	X
	X/*
	X * the purpose for this array is to have more than one size
	X * of a font available at a time. this is not handled properly now,
	X * the entry is just replaced, causing some unnecessary i/o to
	X * take place. when it's done correctly, the character info structures
	X * will only need to be read once and this thing will work faster.
	X * (it will never be fast - the laserjet is too slow in processing
	X * the positioning commands/bit maps to be REALLY useful).
	X * Also, presently, the c_fnt_indx always corresponds to the font
	X * position used. The inclusion of f_numb field is to make this 
	X * unnecessary, to enable switching font files without abandoning
	X * their entries/info.
	X */
	Xstruct FINFO {
	X	int f_numb;
	X	/*
	X	 * 0 means not currently used, otherwise
	X	 * this is the position 'loaded' on
	X	 */
	X	char f_name[30];	/* name.size */
	X	struct c_param * f_chp;
	X	/* really points to the first element in
	X	 * a 256 array of structs, so we can have
	X	 * the character info for all members of 
	X	 * this font without re-reading the file
	X	 */
	X	FILE * f_ptr;
	X}	finfo[NUMFONTS] = {
	X	1,	"R.10",	NULL,	NULL,
	X	2,	"B.10",	NULL,	NULL,
	X	3,	"I.10",	NULL,	NULL,
	X	4,		"",	NULL,	NULL,
	X	5,		"",	NULL,	NULL,
	X	6,		"",	NULL,	NULL,
	X	7,		"",	NULL,	NULL,
	X	8,		"",	NULL,	NULL
	X};
	X
	XFILE *fp = stdin;	/* input file pointer */
	X
	X
	Xmain(argc, argv)
	Xchar *argv[];
	X{
	X	char buf[BUFSIZ];
	X	int done();
	X
	X	setbuf(stdout, buf);
	X	while (argc > 1 && argv[1][0] == '-') {
	X		switch (argv[1][1]) {
	X		case 'o':
	X			outlist(&argv[1][2]);
	X			break;
	X		case 'd':
	X			dbg = atoi(&argv[1][2]);
	X			if (dbg == 0) dbg = 1;
	X			break;
	X		}
	X		argc--;
	X		argv++;
	X	}
	X
	X	if (argc <= 1)
	X		dofile(stdin);
	X	else
	X		while (--argc > 0) {
	X			if (strcmp(*++argv, "-") == 0)
	X				fp = stdin;
	X			else if ((fp = fopen(*argv, "r")) == NULL)
	X				error(FATAL, "can't open %s", *argv);
	X			dofile(fp);
	X			fclose(fp);
	X		}
	X	done();
	X}
	X
	Xoutlist(s)	/* process list of page numbers to be printed */
	Xchar *s;
	X{
	X	int start, finish, i;
	X
	X	pgindex = 0;
	X	while (*s) {
	X		for (start = 0; isdigit(*s); start = start * 10 +*s++ - '0');
	X		finish = start;
	X		if (*s == '-'){
	X		s++;
	X		for (finish = 0; isdigit(*s); finish = finish * 10 +*s++ - '0');
	X		}
	X		if (finish==0)	finish = 9999;
	X
	X		pagelist[pgindex++] = start;
	X		pagelist[pgindex++] = finish;
	X		if (*s != '\0')
	X			s++;
	X	}
	X	pagelist[pgindex] = 0;
	X	if (dbg)
	X		for (i=0; i<pgindex; i += 2)
	X			printf("%3d %3d\n", pagelist[i], pagelist[i+1]);
	X}
	X
	Xin_olist(n)	/* is page n in pagelist? */
	Xint n;
	X{
	X	int i;
	X
	X	if (pgindex == 0)
	X		return(1);	/* everything is included */
	X	for (i = 0; i < pgindex; i += 2)
	X		if (n >= pagelist[i] && n <= pagelist[i+1])
	X			return(1);
	X	return(0);
	X}
	X
	X
	Xdofile(fp)
	Xregister FILE *fp;
	X{
	X	register int c, k;
	X	int m, n, n1, m1;
	X	char str[100], buf[300];
	X
	X	while ((c = getc(fp)) != EOF) {
	X		switch (c) {
	X		case '\n':	/* when input is text */
	X		case ' ':
	X		case 0:		/* occasional noise creeps in */
	X			break;
	X		case '0': case '1': case '2': case '3': case '4':
	X		case '5': case '6': case '7': case '8': case '9':
	X			/* two motion digits plus a character */
	X			hmot((c-'0')*10 + getc(fp)-'0');
	X			put1(getc(fp));
	X			break;
	X		case 'c':	/* single ascii character */
	X			put1(getc(fp));
	X			break;
	X		case 'C':	/* 'funny' character */
	X			fscanf(fp, "%s", str);
	X#ifdef DEBUG
	X			dprintf(stderr, "%s", str);
	X#endif
	X			put1s(str);
	X			break;
	X		case 't':	/* straight text */
	X			fgets(buf, sizeof(buf), fp);
	X			t_text(buf);
	X			break;
	X		case 'D':	/* draw function - not done yet */
	X			fgets(buf, sizeof(buf), fp);
	X			switch (buf[0]) {
	X			case 'l':	/* draw a line */
	X				sscanf(buf+1, "%d %d", &n, &m);
	X				drawline(n, m, ".");
	X				break;
	X			case 'c':	/* circle */
	X				sscanf(buf+1, "%d", &n);
	X				drawcirc(n);
	X				break;
	X			case 'e':	/* ellipse */
	X				sscanf(buf+1, "%d %d", &m, &n);
	X				drawellip(m, n);
	X				break;
	X			case 'a':	/* arc */
	X				sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
	X				drawarc(n, m, n1, m1);
	X				break;
	X			case '~':	/* wiggly line */
	X				drawwig(buf+1);
	X				break;
	X			default:
	X				error(FATAL, "unknown drawing function %s", buf);
	X				break;
	X			}
	X			break;
	X		case 's':
	X			fscanf(fp, "%d", &n);	/* ignore fractional sizes */
	X#ifdef DEBUG
	X			dprintf(stderr, "%d", n);
	X#endif
	X			setsize(t_size(n));
	X			break;
	X		case 'f':
	X			fscanf(fp, "%s", str);
	X#ifdef DEBUG
	X			dprintf(stderr, "%s", str);
	X#endif
	X			setfont(t_font(str));
	X			break;
	X		case 'H':	/* absolute horizontal motion */
	X			while ((c = getc(fp)) == ' ')
	X				;
	X			for (k = c-'0'; isdigit(c = getc(fp)); k = 10*k+c-'0');
	X			ungetc(c, fp);
	X			hgoto(k);
	X			break;
	X		case 'h':	/* relative horizontal motion */
	X			while ((c = getc(fp)) == ' ')
	X				;
	X			for (k = c-'0'; isdigit(c = getc(fp)); k = 10*k+c-'0');
	X			ungetc(c, fp);
	X			hmot(k);
	X			break;
	X		case 'w':	/* word space */
	X			/* should either ignore this or space over
	X			the right character width, not just space */
	X			putc(' ', stdout);
	X			break;
	X		case 'V':
	X			while ((c = getc(fp)) == ' ')
	X				;
	X			for (n = c-'0'; isdigit(c = getc(fp)); n = 10*n+c-'0');
	X			ungetc(c, fp);
	X#ifdef DEBUG
	X			dprintf(stderr, "%d", n);
	X#endif
	X			vgoto(n);
	X			break;
	X		case 'v':
	X			while ((c = getc(fp)) == ' ')
	X				;
	X			for (n = c-'0'; isdigit(c = getc(fp)); n = 10*n+c-'0');
	X			ungetc(c, fp);
	X#ifdef DEBUG
	X			dprintf(stderr, "%d", n);
	X#endif
	X			vmot(n);
	X			break;
	X		case 'p':	/* new page */
	X			fscanf(fp, "%d", &n);
	X#ifdef DEBUG
	X			dprintf(stderr, "%d", n);
	X#endif
	X			t_page(n);
	X			break;
	X		case 'n':	/* end of line */
	X			while (getc(fp) != '\n')
	X				;
	X			t_newline();
	X			break;
	X		case '#':	/* comment */
	X			while (getc(fp) != '\n')
	X				;
	X			break;
	X		case 'x':	/* device control */
	X			device(fp);
	X			break;
	X		default:
	X			error(!FATAL, "unknown input character %o %c", c, c);
	X			done();
	X		}
	X	}
	X}
	X
	Xdevice(fp)	/* interpret device control functions */
	XFILE *fp;
	X{
	X	char str[20];
	X	int n;
	X
	X	fscanf(fp, "%s", str);
	X#ifdef DEBUG
	X	dprintf(stderr, "%s", str);
	X#endif
	X	switch (str[0]) {
	X	case 'i':	/* initialize */
	X		fileinit();
	X		t_init(0);
	X		break;
	X	case 'T':	/* device name */
	X		fscanf(fp, "%s", devname);
	X#ifdef DEBUG
	X		dprintf(stderr, "%s", devname);
	X#endif
	X		/* gets ignored anyway */
	X		break;
	X	case 't':	/* trailer */
	X		t_trailer();
	X		break;
	X	case 'p':	/* pause -- can restart */
	X		t_reset('p');
	X		break;
	X	case 's':	/* stop */
	X		t_reset('s');
	X		break;
	X	case 'r':	/* resolution assumed when prepared */
	X		fscanf(fp, "%d", &res);
	X#ifdef DEBUG
	X		dprintf(stderr, "%d", res);
	X#endif
	X		break;
	X	case 'f':	/* font used */
	X		fscanf(fp, "%d %s", &n, str);
	X#ifdef DEBUG
	X		dprintf(stderr, "%d %s", n, str);
	X#endif
	X		loadfont(n, str);
	X		break;
	X	}
	X	while (getc(fp) != '\n')	/* skip rest of input line */
	X		;
	X}
	X
	X
	Xfileinit()	/* read in font and code files, etc. */
	X{
	X	/*
	X	 * don't do anything here since the first commands
	X	 * in any output from troff are font load commands and
	X	 * we'll do them there anyway
	X	 */
	X}
	X
	Xfontprint(i)	/* debugging print of font i (1,...NUMFONTS) */
	X{
	X	/*
	X	 * I'm too lazy - add this if you want - it's just
	X	 * a simple loop, e.g for (i=0; i<256; call raster)
	X	 */
	X}
	X
	Xloadcode(n, nw)
	X/* load codetab on position n (0...NUMFONTS); #chars is nw */
	X/* someday will get added when i discover where the tables */
	X/* are, or if i create them from my font dumps.            */
	Xint n, nw;
	X{
	X/*
	X * do we know how the code tables are organized?
	X * the code positions are different (of course ...) for vfont
	X * and for the AT&T DWB fonts (the imagen rasters).
	X * we need a way to distinguish between the raster files
	X * not based on their names, and f_magic, as far as i remember,
	X * is not consistent. either find a 'smart' way to do this, or
	X * go over ALL the font files and force f_magic to 0436 for vfont
	X * and to something else for rasti10. then we can have independent
	X * code tables and add them to the FINFO structures, so that we
	X * can find find a character FAST.
	X * P.S. - i think the maxx, maxy, and xtend fields are ALWAYS 0 on
	X * the rasti10 stuff, and ALWAYS initialized to something normal in
	X * vfont, so that may be a solution.
	X */
	X}
	X
	Xcheat_size(n)
	Xint n;
	X{
	X	register int * siz;
	X	static int av_siz [] = {
	X		6, 7, 8, 9, 10, 11, 12,
	X		14, 16, 18, 20, 22, 24,
	X		28, 36, 0
	X	};
	X
	X	n = (int)(n*1.33);
	X		/*
	X		 * is vfont for 200 dpi?
	X		 * this seems to give a good size ratio
	X		 * but can change to fit your mood ...
	X		 * it's not exact anyway cause of cheatsize().
	X		 */
	X
	X	for (siz=av_siz; (*siz != 0) && (n > *siz); siz++)
	X		;
	X	return ((*siz == 0) ? *--siz : *siz);
	X}
	X
	Xloadfont(pos, s)
	X	/* load font info for font s on position n (1...NUMFONTS) */
	Xint pos;
	Xchar *s;
	X{
	X	/*
	X	 * read in a font here from the library - just the header
	X	 * and the c_param structures. we'll do an fseek and read
	X	 * for the characters separately.
	X	 * call t_fp to update the table of fonts and see if we
	X	 * already have the info we need, and check if not on cartridge.
	X	 *
	X	 * there should be
	X	 * space for more than one font since troff seems to enjoy
	X	 * changing point sizes on the fly ..
	X	 */
	X
	X	char	filename[100];
	X	struct f_header   fh;
	X	register int	 i;
	X	char tmpname[30];
	X	struct c_param * chpalloc();
	X
	X#ifdef DEBUG
	X	dinfoprint("loadfont entered");
	X#endif
	X	sprintf(tmpname, "%s.%d", s, want_siz);
	X	i = t_fp(pos, tmpname);
	X	if 	  ((strcmp(tmpname,"R.10")==0)
	X		|| (strcmp(tmpname,"I.10")==0)
	X		|| (strcmp(tmpname,"B.10")==0)) {
	X				cartridge  = 1;
	X				c_fnt_indx = i;
	X				crnt_siz = want_siz;
	X#ifdef DEBUG
	X				dinfoprint("loadfont");
	X#endif
	X				return;
	X	}
	X	sprintf(tmpname, "%s.%d", s, cheat_size(want_siz));
	X	/* 
	X	 * cheat with the size here. maybe should use
	X	 * (int)(want_siz/0.8) or (int)(want_siz/0.67)
	X	 * to compensate - check
	X	 * availability of these sizes b4 u try it
	X	 */
	X		/* this is the font we want */
	X	if (finfo[i].f_ptr != NULL){
	X		/* found it, and the file has already been read */
	X		cartridge  = 0;
	X		c_fnt_indx = i;
	X		crnt_siz = want_siz;
	X#ifdef DEBUG
	X		dinfoprint("loadfont");
	X#endif
	X		return;
	X	}
	X	/*
	X	 * found an entry, but it hasn't been read yet - alloc
	X	 * mem if needed, file gets read at end of else clause.
	X	 */
	X	cartridge  = 0;
	X	c_fnt_indx = i;
	X	crnt_siz = want_siz;
	X	if (finfo[c_fnt_indx].f_chp == NULL)
	X		if ((finfo[c_fnt_indx].f_chp = chpalloc()) == NULL)
	X			error(FATAL,"couldn't allocate memory");
	X			/* does not return */
	X	/*
	X	 * we now have a spot in finfo[c_fnt_indx]
	X	 * either because we found an entry that hasn't 
	X	 * been read in,
	X	 * or because we replaced an old entry. so now
	X	 * we read in the information from the font file.
	X	 */
	X		
	X
	X	sprintf(filename, "%s/%s", dfltdir, tmpname);
	X	finfo[c_fnt_indx].f_ptr = fopen (filename, "r");
	X	if (finfo[c_fnt_indx].f_ptr == NULL) {
	X		error (!FATAL, "font file - can't open %s", filename);
	X		finfo[c_fnt_indx].f_name[0] = '\0';
	X		c_fnt_indx = 0;
	X#ifdef DEBUG
	X		dinfoprint("loadfont");
	X#endif
	X		return;
	X	}
	X#ifdef DEBUG
	X	dprintf (stderr, "font file %s\n", filename);
	X#endif
	X
	X	fread (&fh, sizeof (struct f_header), 1, finfo[c_fnt_indx].f_ptr);
	X	/*
	X	 * not used at the time. may need it later on since we have
	X	 * to distinguish between berkeley vfont and dwb rasti10
	X	 * files, so might stuff a different magic number and stick
	X	 * an indicator into the finfo structure.
	X	 */
	X	fread (finfo[c_fnt_indx].f_chp,
	X			sizeof (struct c_param), 256, finfo[c_fnt_indx].f_ptr);
	X	crnt_siz = want_siz;
	X#ifdef DEBUG
	X	dinfoprint("loadfont");
	X#endif
	X}
	X
	X
	X
	X
	Xchar	devname[20]	= "hp2686A";
	X	/* (Laserjet) - not used anywhere */
	Xint hpos, vpos;
	X
	Xt_init(reinit)	/* initialize device */
	Xint reinit;
	X{
	X
	X	fflush(stdout);
	X	hpos = vpos = 0;
	X}
	X
	Xt_page(n)	/* do whatever new page functions */
	X{
	X	hpos = vpos = 0;
	X	if (output == 0) {
	X		output = in_olist(n);
	X		t_init(1);
	X		return;
	X	}
	X	putpage();
	X	fflush(stdout);
	X}
	X
	Xputpage()
	X{
	X	putchar('\f');
	X}
	X
	Xt_newline()	/* do whatever for the end of a line */
	X{
	X	putchar('\n');
	X	/*
	X	 * not really needed, but good for breaking up
	X	 * output file (debugging, modifying).
	X	 */
	X	hpos = 0;
	X}
	X
	Xt_size(n)
	Xint n;
	X{
	X	return(n);
	X}
	X
	Xt_font(s)	/* convert string to internal font number */
	Xchar *s;
	X{
	X	/* will have to choose which font to read
	X	into the tables so be careful here */
	X	return(atoi(s));
	X}
	X
	Xt_text(s)	/* print string s as text */
	Xchar *s;
	X{
	X	int c, wspc;
	X	char str[100];
	X
	X	if (!output)
	X		return;
	X	while ((c = *s++) != '\n') {
	X		if (c == '\\') {
	X			switch (c = *s++) {
	X			case '\\':
	X			case 'e':
	X				put1('\\');
	X				break;
	X			case '(':
	X				str[0] = *s++;
	X				str[1] = *s++;
	X				str[2] = '\0';
	X				put1s(str);
	X				break;
	X			}
	X		} else {
	X			put1(c);
	X		}
	X		wspc = crnt_siz*300./72.; /* an 'em's worth? */
	X		hmot(wspc);
	X	}
	X}
	X
	Xt_reset(c)
	X{
	X
	X	output = 1;
	X	if (c == 's'){
	X		printf("\033E");
	X		t_page(9999);
	X		}
	X	fflush(stdout);
	X}
	X
	Xt_trailer()
	X{
	X}
	X
	Xhgoto(n)
	X{
	X	hpos = n;	/* this is where we want to be */
	X			/* before printing a character, */
	X			/* have to make sure it's true */
	X}
	X
	Xhmot(n)	/* generate n units of horizontal motion */
	Xint n;
	X{
	X	hpos += n;
	X}
	X
	Xhflush()	/* actual horizontal output occurs here */
	X{
	X	printf("\033&a%dH",hpos);
	X}
	X
	Xvgoto(n)
	X{
	X	static int oldvpos = 0;
	X
	X	vpos = n;
	X	if (vpos != oldvpos){
	X		printf("\033&a%dV",vpos);
	X		oldvpos = vpos;
	X		}
	X}
	X
	Xvmot(n)	/* generate n units of vertical motion */
	Xint n;
	X{
	X	vgoto(vpos + n);	/* ignores rounding */
	X}
	X
	Xput1s(s)	/* s is a funny char name */
	Xchar *s;
	X{
	X	register int i, j;
	X	register char *p;
	X	extern char *asctab[];
	X		/* is only good for the fonts on the cartridge
	X		 * need a codetable for the raster dumps.
	X		 */
	X	extern char *spectab[];
	X		/* names of chars on S font- index of name = index of
	X		 * c_param so easy to find raster map
	X		 */
	X	static char prev[10] = "";
	X	static int previ;
	X	static char prevs[10] = "";
	X	static int prevsi;
	X	char tmpname[30];
	X	int o_fnt_indx;
	X	int o_cartridge;
	X
	X	if (!output)
	X		return;
	X
	X#ifdef DEBUG
	X	dinfoprint("put1s entered");
	X#endif
	X	if (strcmp(s, prev) != 0) {
	X		previ = -1;
	X		for (i = 0; asctab[i] != 0; i += 2)
	X			if (strcmp(asctab[i], s) == 0) {
	X				strcpy(prev, s);
	X				previ = i;
	X				break;
	X			}
	X	}
	X	if (previ >= 0) {
	X		hflush(); vgoto(vpos);
	X		/*
	X		 * should only use this for the cartridge fonts, but since
	X		 * don't have a codetable yet for the rasters, use this
	X		 * anyway - it will come out in the wrong font and size
	X		 * but it's at least viewable.
	X		 */
	X		for (p = asctab[previ+1]; *p; p++)
	X			putc(*p, stdout);
	X
	X#ifdef DEBUG
	X		dprintf(stderr,"ascii character %s, font is %s\n",
	X				asctab[previ], finfo[c_fnt_indx].f_name);
	X
	X		dinfoprint("put1s");
	X#endif
	X		return;
	X	} else
	X		prev[0] = 0;
	X
	X
	X	if (strcmp(s, prevs) != 0) {
	X		prevsi = -1;
	X		for (i = 0; i<128; i++)
	X			if (strcmp(spectab[i], s) == 0) {
	X				strcpy(prevs, s);
	X				prevsi = i;
	X				break;
	X			}
	X	}
	X	if (prevsi >= 0) {
	X		for (i=0; i<NUMFONTS; i++){
	X			if (finfo[i].f_numb == 6) break;
	X			}
	X		if (i >= NUMFONTS) error(FATAL,"nothing mounted on position 6");
	X		/* may add a s_fnt_indx to get around this */
	X
	X#ifdef DEBUG
	X	dprintf(stderr,"special character %s, font on position 6 is %s\n",
	X				spectab[prevsi], finfo[i].f_name);
	X#endif
	X
	X		o_fnt_indx = c_fnt_indx;
	X		o_cartridge = cartridge;
	X
	X		if ((p = index(finfo[i].f_name,'.'))==0)
	X			error(FATAL,"finfo entry screwed up");
	X
	X		/* size check - may need new file */
	X
	X		if (atoi(++p)!=want_siz) {
	X			for (j=0; (tmpname[j]=finfo[i].f_name[j])!='.' ;j++);
	X			tmpname[j]='\0';
	X			/* copy the font name up to the '.' into tmpname */
	X
	X			loadfont(finfo[i].f_numb, tmpname);
	X			/* do a new load on position 6 for new size */
	X			/* this will change c_fnt_indx and */
	X			/* cartridge indicator, so need to restore. */
	X			i = c_fnt_indx;
	X
	X#ifdef DEBUG
	X		dprintf(stderr,
	X			"put1s - needed size change, current font pos %d has %s\n",
	X				finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
	X#endif
	X		}
	X		else {
	X			/* 
	X			 * we didn't call loadfont since size was ok,
	X			 * but raster looks at c_fnt_indx to get a file
	X			 * pointer, so change it here and reset later.
	X			 * dirty, lousy code - redo this whole section
	X			 */
	X			 c_fnt_indx = i;
	X		}
	X
	X#ifdef DEBUG
	X		dinfoprint("put1s");
	X#endif
	X		raster(finfo[i].f_chp+prevsi);
	X
	X		cartridge = o_cartridge;
	X		c_fnt_indx = o_fnt_indx;
	X
	X#ifdef DEBUG
	X		dprintf(stderr,
	X			"put1s - restored old font, position %d has %s\n",
	X				finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
	X
	X		dinfoprint("put1s");
	X#endif
	X		return;
	X	} else
	X		prevs[0] = 0;
	X#ifdef DEBUG
	X		dinfoprint("put1s");
	X#endif
	X}
	X
	X
	Xput1(c)	/* output char c */
	Xint c;
	X{
	X	register char * pt;	/* finds the size of the current font */
	X
	X	if (!output)
	X		return;
	X	vgoto(vpos);
	X	/*
	X	horiz position gets flushed if it's not a 
	X	'nnc' sequence, in which case we try to let 
	X	the laserjet handle the spacing
	X	*/
	X	/*
	X	Cancel the above - the laserjet's spacing is too
	X	wide for troff. it doesn't look as nice either. while
	X	this cuts file size & xmission time, we need a better
	X	solution, i.e. width tables, etc.
	X	*/
	X		hflush();
	X
	X	/*
	X	 * the following is SLOW and messy. find a better
	X	 * way of knowing what the size is. yuck.
	X	 */
	X
	X#ifdef DEBUG
	X	dinfoprint("put1 entered");
	X#endif
	X
	X	if ((pt = index(finfo[c_fnt_indx].f_name,'.'))==0)
	X		error(FATAL,"finfo entry screwed up");
	X
	X	if (atoi(++pt)!=want_siz) {
	X		/* copy the font name up to the '.' into tmpname */
	X		setfont(finfo[c_fnt_indx].f_numb);
	X			/* do a new load since we lost our size */
	X
	X#ifdef DEBUG
	X		dprintf(stderr,
	X			"put1 - needed size change, current font pos %d has %s\n",
	X				finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
	X#endif
	X	}
	X
	X#ifdef DEBUG
	X	dinfoprint("put1");
	X#endif
	X	if (cartridge) putc(c, stdout);
	X	else {
	X		raster(finfo[c_fnt_indx].f_chp+c);
	X		/* only good for vfont, dwb needs a code table */
	X	}
	X#ifdef DEBUG
	X	dinfoprint("put1");
	X#endif
	X}
	X
	Xsetsize(n)	/* set point size to n (internal) */
	Xint n;
	X{
	X#ifdef DEBUG
	X	dprintf(stderr,"going to point size %d\n",n);
	X#endif
	X	want_siz = n;
	X}
	X
	Xt_fp(n, s)	/* font position n now contains font s */
	Xint n;
	Xchar *s;	/* s is a name.size combination */
	X{
	X	register int ind;
	X
	X#ifdef DEBUG
	X	dinfoprint("t_fp entered");
	X#endif
	X	for (ind = 0; ind < NUMFONTS; ind++){
	X		if (finfo[ind].f_numb == n){
	X			if (strcmp(finfo[ind].f_name, s)==0){
	X#ifdef DEBUG
	X				dinfoprint("t_fp");
	X#endif
	X				return(ind);	/* already there */
	X				}
	X			else {
	X				strcpy(finfo[ind].f_name, s);
	X				if (finfo[ind].f_ptr != NULL)
	X					fclose(finfo[ind].f_ptr);
	X				finfo[ind].f_ptr = NULL;
	X#ifdef DEBUG
	X				dinfoprint("t_fp");
	X#endif
	X				return(ind);
	X			}
	X		}
	X	}
	X#ifdef DEBUG
	X	dinfoprint("t_fp");
	X#endif
	X	error(FATAL, "can't mount %s, pos %d doesn't exist", s, n);
	X	/* NOTREACHED */
	X}
	X
	Xsetfont(n)	/* set font to n */
	Xint n;
	X{
	X	register int ind;
	X	register char * pt;
	X	char tmpname[30];	/* just a convenience */
	X
	X#ifdef DEBUG
	X	dinfoprint("setfont entered");
	X	dprintf(stderr,"request for font on position %d\n",n);
	X#endif
	X
	X	for (ind = 0; ind < NUMFONTS; ind++){
	X			if (finfo[ind].f_numb == n) break;
	X			}
	X	if (ind >= NUMFONTS)
	X		error(FATAL, "nothing mounted on position %d", n);
	X
	X	c_fnt_indx = ind;
	X	crnt_siz = want_siz;
	X
	X	cartridge = 0;
	X
	X	/*
	X	 * check the size of the mounted font and make
	X	 * sure its what we want, otherwise call loadfont
	X	 */
	X	if ((pt = index(finfo[c_fnt_indx].f_name,'.'))==0)
	X		error(FATAL,"finfo entry screwed up");
	X
	X	if (atoi(++pt)!=want_siz) {
	X		for (ind=0;
	X			(tmpname[ind]=finfo[c_fnt_indx].f_name[ind])!='.' ;ind++);
	X		tmpname[ind]='\0';
	X		/* copy the font name up to the '.' into tmpname */
	X		loadfont(finfo[c_fnt_indx].f_numb, tmpname);
	X			/* do a new load since we lost our size */
	X
	X#ifdef DEBUG
	X		dprintf(stderr,
	X		"setfont - needed size change, current font pos %d has %s\n",
	X				finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
	X#endif
	X	}
	X
	X	strcpy(tmpname, finfo[c_fnt_indx].f_name);
	X	if (strcmp(tmpname,"R.10")==0){
	X		printf("\033&l0O\033(0U\033(s1p10v0s0b5T");
	X		/* Times Roman medium upright (portrait) */
	X		cartridge  = 1;
	X#ifdef DEBUG
	X	dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
	X	dinfoprint("setfont");
	X#endif
	X		return;
	X	}
	X	if (strcmp(tmpname,"I.10")==0){
	X		printf("\033&l0O\033(0U\033(s1p10v1s0b5T");
	X		/* Times Roman medium italic (portrait) */
	X		cartridge  = 1;
	X#ifdef DEBUG
	X	dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
	X	dinfoprint("setfont");
	X#endif
	X		return;
	X	}
	X	if (strcmp(tmpname,"B.10")==0) {
	X		printf("\033&l0O\033(0U\033(s1p10v0s1b5T");
	X		/* Times Roman bold upright (portrait) */
	X		cartridge  = 1;
	X#ifdef DEBUG
	X	dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
	X	dinfoprint("setfont");
	X#endif
	X		return;
	X	}
	X
	X	if (finfo[c_fnt_indx].f_ptr==NULL) {
	X		for (ind=0;
	X			(tmpname[ind]=finfo[c_fnt_indx].f_name[ind])!='.' ;ind++);
	X		tmpname[ind]='\0';
	X		/* copy the font name up to the '.' into tmpname */
	X		loadfont(finfo[c_fnt_indx].f_numb, tmpname);
	X			/* do a new load since we lost our size */
	X
	X#ifdef DEBUG
	X		dprintf(stderr,
	X		"setfont - got a NULL fptr, current font pos %d has %s\n",
	X				finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
	X#endif
	X	}
	X
	X#ifdef DEBUG
	X	dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
	X	dinfoprint("setfont");
	X#endif
	X}
	X
	Xdone()
	X{
	X	output = 1;
	X	putpage();
	X	fflush(stdout);
	X	exit(0);
	X}
	X
	Xraster (chp)
	Xstruct c_param	* chp;
	X{
	X	int	height, width, bytewidth;
	X	int lsrres = 300;
	X	int	i, j;
	X	long	p;
	X	FILE * fp;	/* just a convenience */
	X
	X	if ((fp = finfo[c_fnt_indx].f_ptr)==NULL){
	X		/* fseek dumps core on a NULL file pointer */
	X		error(!FATAL,"raster: called with a NULL file pointer, %s",
	X					"ignoring request");
	X		return;
	X	}
	X
	X	height = (int) ckint (chp->c_up) + (int) ckint (chp->c_down);
	X	width = (int) ckint (chp->c_left) + (int) ckint (chp->c_right);
	X	bytewidth = (width+7)/8;
	X
	X	if ((height*bytewidth)!=chp->c_size){
	X		/*
	X		 * brain damage - system V and /usr/lib/vfont don't
	X		 * agree on whether size is left+right or 1 bit bigger.
	X		 * same for height (# of rows in bit map).
	X		 *
	X		 * change this thing to use f_magic somehow. (or the
	X		 * presence/absence of normal numbers in maxx, maxy, etc
	X		 */
	X		fprintf(stderr,
	X			"width & height don't match, trying rasti10 format ... ");
	X		width += 1;
	X		height += 1;
	X		bytewidth = (width+7)/8;
	X			if ((height*bytewidth)!=chp->c_size)
	X				fprintf(stderr, "FAILED - BAD FONT FILE\n");
	X			else
	X				fprintf(stderr, "ok\n");
	X	}
	X#ifdef DEBUG
	X	else dprintf(stderr, "width & height match\n");
	X#endif
	X
	X	p = F_OFFSET + chp->c_addr;
	X	if (fseek(fp, p, 0) == -1)
	X		error(FATAL, "seek failed on file %s offset %d",
	X				finfo[c_fnt_indx].f_name, p);
	X				/* does not return */
	X
	X#define	CNV(x)	((int)((723./lsrres)*(x)))
	X
	X	vgoto (vpos - CNV(chp->c_up));
	X	hgoto (hpos + 24 - CNV(chp->c_left)); hflush();
	X	/*
	X	 * the 24 is because the laserjet's letters are not
	X	 * placed where troff thinks they are. they seem to be
	X	 * in the lower left corner of the character cell instead of
	X	 * at the baseline - probably need to adjust
	X	 * the height too, but do that later.
	X	 * Why 24? why not? got a better number?
	X	 */
	X	printf ("\033*t%dR",lsrres);
	X	printf ("\033*r1A");
	X
	X	for (i = 0; i < height; i++) {
	X		if (p >= F_OFFSET + chp->c_addr + chp->c_size){
	X			error(!FATAL, "ran out of bit map data");
	X			/* does return, but don't fail in the middle
	X			 * of an esc seqence - spit it out first, then
	X			 * complain.
	X			 */
	X			break;
	X		}
	X		printf ("\033*b%dW", (int) ((width + 7) / 8));
	X		for (j = 0; j < width; j += 8) {
	X			putchar (getc(fp));
	X			++p;
	X		}
	X	}
	X	printf ("\033*rB");
	X	vgoto (vpos + CNV(chp->c_up));
	X	hgoto (hpos -24 + CNV(chp->c_left)); hflush();
	X}
	Xint	 ckint (n)
	Xchar	n;
	X{
	X#ifdef u3b
	X	int	 i;
	X	if ((int) n > 0177) {
	X		i = (int) n;
	X		i = (256 - i) * -1;
	X	}
	X	else {
	X		i = (int) n;
	X	}
	X	return (i);
	X#else
	X	return ((int) n);
	X#endif
	X}
	X
	Xdrawline(n, m, s) int n,m; char * s; {}
	Xdrawcirc(n) int n; {}
	Xdrawellip(m, n) int n,m; {}
	Xdrawarc(n, m, n1, m1) int n,m,n1,m1; {}
	Xdrawwig(buf) char * buf; {}
	X
	Xget1c(fp)
	XFILE * fp;
	X{
	X	register int c;
	X	c = getc(fp);
	X	fputc(c, stderr);
	X	return(c);
	X}
	Xstruct c_param *
	Xchpalloc()
	X{
	X	char * calloc();
	X	register int i;
	X	register struct c_param * tmptr;
	X
	X	/* give it 3 shots, otherwise die */
	X	for (i=0; i<3; i++){
	X		if ((tmptr=(struct c_param *)
	X				calloc(256, sizeof(struct c_param)))!=NULL)
	X					return(tmptr);
	X	}
	X	return (tmptr);	/* NULL cast into right pointer */
	X}
	X
	Xerror(f, s, a1, a2, a3, a4, a5, a6, a7) {
	X	fprintf(stderr, "hp: ");
	X	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
	X	fprintf(stderr, "\n");
	X	if (f)
	X		exit(1);
	X}
	X
	Xfinfoprint(m)
	Xchar * m;
	X{
	X	register struct FINFO * i;
	X
	X	fprintf(stderr, "%s: crnt_siz %d want_siz %d cartridge %d\n",
	X				m, crnt_siz, want_siz, cartridge);
	X	for (i=finfo; i < finfo + NUMFONTS; i++)
	X		fprintf(stderr, "pos %d name %30s chp %s fptr %s\n",
	X			i->f_numb, i->f_name, (i->f_chp ? "alloc" : "null"),
	X			(i->f_ptr ? "open" : "null"));
	X}
SHAR_EOF
if test 28471 -ne "`wc -c < 'hp.c'`"
then
	echo shar: error transmitting "'hp.c'" '(should have been 28471 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Mod.sources mailing list