dviselect (Part 3 of 6)

Skip Montanaro montnaro at sprite.crd.ge.com
Tue Nov 14 08:21:32 AEST 1989


#! /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 3 (of 6)."
# Contents:  lib/conv.c lib/dviclass.c lib/error.c lib/findpost.c
#   lib/fio.c lib/font.c lib/font_subr.c
# Wrapped by montnaro at sprite on Sat Nov 11 17:13:29 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f lib/conv.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/conv.c\"
else
echo shar: Extracting \"lib/conv.c\" \(1325 characters\)
sed "s/^X//" >lib/conv.c <<'END_OF_lib/conv.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/conv.c,v 1.3 89/02/13 14:30:55 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Conversions.
X */
X
X#include "types.h"
X#include "conv.h"
X
XConv Conversion;
X
Xdouble	DMagFactor();
X
X/*
X * Set a conversion (possibly the global conversion).
X */
Xvoid
XCSetConversion(c, dpi, usermag, num, denom, dvimag)
X	register struct conversion *c;
X	int dpi, usermag;
X	i32 num, denom, dvimag;
X{
X	double ddpi = dpi;
X
X	c->c_mag = DMagFactor((int) dvimag) * DMagFactor(usermag);
X	c->c_dpi = ddpi;
X
X	/*
X	 * The conversion facture is figured as follows:  there are exactly
X	 * num/denom DVI units per decimicron, and 254000 decimicrons per
X	 * inch, and dpi pixels per inch.  Then we have to adjust this by
X	 * the stated magnification. 
X	 */
X	c->c_fromsp = (num / 254000.0) * (ddpi / denom) * c->c_mag;
X
X	/*
X	 * c->c_tosp is 1/c->c_fromsp, but we will invert the expression
X	 * above in the hopes of some extra accuracy.
X	 *
X	 * IS THIS ANY GOOD?  I NEED A NUMERICAL ANALYST!
X	 */
X	c->c_tosp = (254000.0 / num) * (denom / ddpi) * (1.0 / c->c_mag);
X}
END_OF_lib/conv.c
if test 1325 -ne `wc -c <lib/conv.c`; then
    echo shar: \"lib/conv.c\" unpacked with wrong size!
fi
chmod +x lib/conv.c
# end of overwriting check
fi
if test -f lib/dviclass.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/dviclass.c\"
else
echo shar: Extracting \"lib/dviclass.c\" \(3242 characters\)
sed "s/^X//" >lib/dviclass.c <<'END_OF_lib/dviclass.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/dviclass.c,v 1.3 89/02/13 14:30:57 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * dviclass - DVI code classification tables.
X */
X
X#include "dviclass.h"
X
X/* shorthand---in lowercase for contrast (read on!) */
X#define	four(x)		x, x, x, x
X#define	six(x)		four(x), x, x
X#define	sixteen(x)	four(x), four(x), four(x), four(x)
X#define	sixty_four(x)	sixteen(x), sixteen(x), sixteen(x), sixteen(x)
X#define	one_twenty_eight(x)	sixty_four(x), sixty_four(x)
X
X/*
X * This table contains the byte length of the single operand, or DPL_NONE
X * if no operand, or if it cannot be decoded this way.
X *
X * The sequences UNS1, UNS2, UNS3, SGN4 (`SEQ_U') and SGN1, SGN2, SGN3,
X * SGN4 (`SEQ_S') are rather common, and so we define macros for these.
X */
X#define	SEQ_U	DPL_UNS1, DPL_UNS2, DPL_UNS3, DPL_SGN4
X#define	SEQ_S	DPL_SGN1, DPL_SGN2, DPL_SGN3, DPL_SGN4
X
Xchar dvi_oplen[256] = {
X	one_twenty_eight(DPL_NONE),
X				/* characters 0 through 127 */
X	SEQ_U,			/* DVI_SET1 through DVI_SET4 */
X	DPL_NONE,		/* DVI_SETRULE */
X	SEQ_U,			/* DVI_PUT1 through DVI_PUT4 */
X	DPL_NONE,		/* DVI_PUTRULE */
X	DPL_NONE,		/* DVI_NOP */
X	DPL_NONE,		/* DVI_BOP */
X	DPL_NONE,		/* DVI_EOP */
X	DPL_NONE,		/* DVI_PUSH */
X	DPL_NONE,		/* DVI_POP */
X	SEQ_S,			/* DVI_RIGHT1 through DVI_RIGHT4 */
X	DPL_NONE,		/* DVI_W0 */
X	SEQ_S,			/* DVI_W1 through DVI_W4 */
X	DPL_NONE,		/* DVI_X0 */
X	SEQ_S,			/* DVI_X1 through DVI_X4 */
X	SEQ_S,			/* DVI_DOWN1 through DVI_DOWN4 */
X	DPL_NONE,		/* DVI_Y0 */
X	SEQ_S,			/* DVI_Y1 through DVI_Y4 */
X	DPL_NONE,		/* DVI_Z0 */
X	SEQ_S,			/* DVI_Z1 through DVI_Z4 */
X	sixty_four(DPL_NONE),	/* DVI_FNTNUM0 through DVI_FNTNUM63 */
X	SEQ_U,			/* DVI_FNT1 through DVI_FNT4 */
X	SEQ_U,			/* DVI_XXX1 through DVI_XXX4 */
X	SEQ_U,			/* DVI_FNTDEF1 through DVI_FNTDEF4 */
X	DPL_NONE,		/* DVI_PRE */
X	DPL_NONE,		/* DVI_POST */
X	DPL_NONE,		/* DVI_POSTPOST */
X	six(DPL_NONE)		/* 250 through 255 */
X};
X
Xchar dvi_dt[256] = {
X	one_twenty_eight(DT_CHAR),
X				/* characters 0 through 127 */
X	four(DT_SET),		/* DVI_SET1 through DVI_SET4 */
X	DT_SETRULE,		/* DVI_SETRULE */
X	four(DT_PUT),		/* DVI_PUT1 through DVI_PUT4 */
X	DT_PUTRULE,		/* DVI_PUTRULE */
X	DT_NOP,			/* DVI_NOP */
X	DT_BOP,			/* DVI_BOP */
X	DT_EOP,			/* DVI_EOP */
X	DT_PUSH,		/* DVI_PUSH */
X	DT_POP,			/* DVI_POP */
X	four(DT_RIGHT),		/* DVI_RIGHT1 through DVI_RIGHT4 */
X	DT_W0,			/* DVI_W0 */
X	four(DT_W),		/* DVI_W1 through DVI_W4 */
X	DT_X0,			/* DVI_X0 */
X	four(DT_X),		/* DVI_X1 through DVI_X4 */
X	four(DT_DOWN),		/* DVI_DOWN1 through DVI_DOWN4 */
X	DT_Y0,			/* DVI_Y0 */
X	four(DT_Y),		/* DVI_Y1 through DVI_Y4 */
X	DT_Z0,			/* DVI_Z0 */
X	four(DT_Z),		/* DVI_Z1 through DVI_Z4 */
X	sixty_four(DT_FNTNUM),	/* DVI_FNTNUM0 through DVI_FNTNUM63 */
X	four(DT_FNT),		/* DVI_FNT1 through DVI_FNT4 */
X	four(DT_XXX),		/* DVI_XXX1 through DVI_XXX4 */
X	four(DT_FNTDEF),	/* DVI_FNTDEF1 through DVI_FNTDEF4 */
X	DT_PRE,			/* DVI_PRE */
X	DT_POST,		/* DVI_POST */
X	DT_POSTPOST,		/* DVI_POSTPOST */
X	six(DT_UNDEF)		/* 250 through 255 */
X};
END_OF_lib/dviclass.c
if test 3242 -ne `wc -c <lib/dviclass.c`; then
    echo shar: \"lib/dviclass.c\" unpacked with wrong size!
fi
chmod +x lib/dviclass.c
# end of overwriting check
fi
if test -f lib/error.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/error.c\"
else
echo shar: Extracting \"lib/error.c\" \(2104 characters\)
sed "s/^X//" >lib/error.c <<'END_OF_lib/error.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/error.c,v 1.3 89/02/13 14:30:59 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Print an error message with an optional system error number, and
X * optionally quit.
X *
X * THIS CODE IS SYSTEM DEPENDENT UNLESS varargs WORKS WITH vprintf
X * OR _doprnt.  It should work properly under System V using vprintf.
X * (If you have vprintf, define HAVE_VPRINTF.)
X */
X
X#include <stdio.h>
X#include <varargs.h>
X
X#ifdef lint
X
X/* VARARGS3 ARGSUSED */
Xerror(quit, e, fmt) int quit, e; char *fmt; {;}
X
X/* VARARGS1 ARGSUSED */
Xpanic(fmt) char *fmt; { exit(1); /* NOTREACHED */ }
X
X#else lint
X
Xextern char *ProgName;
Xextern int errno;
Xextern char *sys_errlist[];
Xextern int sys_nerr;
X
Xerror(va_alist)
X	va_dcl
X{
X	va_list l;
X	int quit, e;
X	char *fmt;
X
X	(void) fflush(stdout);	/* sync error messages */
X	(void) fprintf(stderr, "%s: ", ProgName);
X	va_start(l);
X	/* pick up the constant arguments: quit, errno, printf format */
X	quit = va_arg(l, int);
X	e = va_arg(l, int);
X	if (e < 0)
X		e = errno;
X	fmt = va_arg(l, char *);
X#if defined(sys5) || defined(HAVE_VPRINTF)
X	(void) vfprintf(stderr, fmt, l);
X#else
X	_doprnt(fmt, l, stderr);
X#endif
X	va_end(l);
X	if (e) {
X		if (e < sys_nerr)
X			(void) fprintf(stderr, ": %s", sys_errlist[e]);
X		else
X			(void) fprintf(stderr, ": Unknown error code %d", e);
X	}
X	(void) putc('\n', stderr);
X	(void) fflush(stderr);	/* just in case */
X	if (quit)
X		exit(quit);
X}
X
Xpanic(va_alist)
X	va_dcl
X{
X	va_list l;
X	char *fmt;
X
X	(void) fflush(stdout);
X	(void) fprintf(stderr, "%s: panic: ", ProgName);
X	va_start(l);
X	/* pick up the constant argument: printf format */
X	fmt = va_arg(l, char *);
X#if defined(sys5) || defined(HAVE_VPRINTF)
X	(void) vfprintf(stderr, fmt, l);
X#else
X	_doprnt(fmt, l, stderr);
X#endif
X	va_end(l);
X	(void) putc('\n', stderr);
X	(void) fflush(stderr);
X	abort();
X}
X
X#endif /* lint */
END_OF_lib/error.c
if test 2104 -ne `wc -c <lib/error.c`; then
    echo shar: \"lib/error.c\" unpacked with wrong size!
fi
chmod +x lib/error.c
# end of overwriting check
fi
if test -f lib/findpost.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/findpost.c\"
else
echo shar: Extracting \"lib/findpost.c\" \(3945 characters\)
sed "s/^X//" >lib/findpost.c <<'END_OF_lib/findpost.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/findpost.c,v 1.4 89/02/13 14:31:00 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * FindPostAmble - Find the postamble of a DVI file.
X *
X * N.B.: This routine assumes that ftell() returns byte offsets,
X * not magic cookies.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "dvicodes.h"
X#include "fio.h"
X
X/*
X * I am making the assumption that 530 bytes will always be enough
X * to find the end of the DVI file.  12 should suffice, as there
X * should be at most seven DVI_FILLER bytes, preceded by the version
X * number, preceded by the four byte postamble pointer; but at least
X * one VMS TeX must pad to a full `sector'.
X */
X/*
X * The above is not correct.  The DVItype program, as authoritative on
X * DVI format, states regarding postambles:
X *
X *	The [last] byte is followed by four or more bytes that are all
X *	equal to the decimal number 223 (i.e., 337 in octal). TeX puts
X *	out four to seven of these trailing bytes, until the total length
X *	of the file is a multiple of four bytes, since this works out
X *	best on machines that pack four bytes per word; but any number
X *	of 223's is allowed, as long as there are at least four of them.
X *
X * Thus assuming "at most seven DVI_FILLER bytes" is wrong.  In fact,
X * PC-TeX seems to put out liberal amounts of DVI_FILLER at the end.
X *
X * The original code was efficient, but had to assume a certain
X * number of bytes.  Since the postamble is only read once anyway,
X * efficiency is not really a consideration.  Plus, like I always
X * say, it's better to get the right answer slowly than the wrong
X * answer fast....
X *
X * Vahe Sarkissian, UCLA Math. Sci., 4/13/88.
X */
X
X#ifdef ORIGINAL_CODE
X#ifdef vms
X#define POSTSIZE	530	/* make only VMS pay for its errors; */
X#else
X#define POSTSIZE	16	/* others get to use something reasonable */
X#endif
X
Xlong	ftell();
X
XFindPostAmble(f)
X	register FILE *f;
X{
X	register long offset;
X	register char *p;
X	register int i;
X	register i32 n;
X	char postbuf[POSTSIZE];
X
X	/*
X	 * Avoid fseek'ing beyond beginning of file; it may
X	 * give odd results.
X	 */
X	fseek(f, 0L, 2);		/* seek to end */
X	offset = ftell(f) - POSTSIZE;	/* and compute where to go next */
X	if (offset < 0L)		/* but make sure it is positive */
X		offset = 0L;
X	fseek(f, offset, 0);
X	p = postbuf;
X	for (i = 0; i < POSTSIZE; i++) {
X		*p++ = getc(f);
X		if (feof(f)) {
X			p--;
X			break;
X		}
X	}
X
X	/*
X	 * Now search backwards for the VERSION byte.  The postamble
X	 * pointer will be four bytes behind that.
X	 */
X	while (--i >= 0) {
X		if (UnSign8(*--p) == DVI_VERSION)
X			goto foundit;
X		if (UnSign8(*p) != DVI_FILLER)
X			break;
X	}
X	return (-1);		/* cannot find postamble ptr */
X
Xfoundit:
X	/*
X	 * Change offset from the position at the beginning of postbuf
X	 * to the position of the VERSION byte, and seek to four bytes
X	 * before that.  Then get a long and use its value to seek to
X	 * the postamble itself.
X	 */
X	offset += p - postbuf;
X	fseek(f, offset - 4L, 0);
X	fGetLong(f, n);
X	offset = n;
X	fseek(f, offset, 0);
X	return (0);		/* success */
X}
X
X#else !ORIGINAL_CODE
X
XFindPostAmble(f)
X	register FILE *f;
X{
X	register long offset;
X	register i32 n;
X	
X	offset = -4;	/* At least four bytes of DVI_FILLER must be present. */
X	do {
X		offset -= 1;
X		(void) fseek(f, offset, 2);
X		n = fgetbyte(f);
X	} while (n == DVI_FILLER);
X
X	if (n != DVI_VERSION)
X		return (-1);	/* Bad version of DVI file */
X	
X	/*
X	 * Position file four bytes before DVI_VERSION byte,
X	 * and read a long.  Use that long to seek to the
X	 * beginning of the postamble itself.
X	 */
X	offset -= 4;
X	(void) fseek(f, offset, 2);
X	fGetLong(f, n);
X	offset = n;
X	(void) fseek(f, offset, 0);
X	return (0);		/* success */
X}
X#endif ORIGINAL_CODE
END_OF_lib/findpost.c
if test 3945 -ne `wc -c <lib/findpost.c`; then
    echo shar: \"lib/findpost.c\" unpacked with wrong size!
fi
chmod +x lib/findpost.c
# end of overwriting check
fi
if test -f lib/fio.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/fio.c\"
else
echo shar: Extracting \"lib/fio.c\" \(965 characters\)
sed "s/^X//" >lib/fio.c <<'END_OF_lib/fio.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/fio.c,v 1.3 89/02/13 14:31:01 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * File I/O subroutines for getting bytes, words, 3bytes, and longwords.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "fio.h"
X
Xstatic char eofmsg[] = "unexpected EOF";
X
X/* for symmetry: */
X#define	fGetByte(fp, r)	((r) = getc(fp))
X#define	Sign32(i)	(i)
X
X#define make(name, func, signextend) \
Xi32 \
Xname(fp) \
X	register FILE *fp; \
X{ \
X	register i32 n; \
X \
X	func(fp, n); \
X	if (feof(fp)) \
X		error(1, 0, eofmsg); \
X	return (signextend(n)); \
X}
X
Xmake(GetByte,  fGetByte,  Sign8)
Xmake(GetWord,  fGetWord,  Sign16)
Xmake(Get3Byte, fGet3Byte, Sign24)
Xmake(GetLong,  fGetLong,  Sign32)
END_OF_lib/fio.c
if test 965 -ne `wc -c <lib/fio.c`; then
    echo shar: \"lib/fio.c\" unpacked with wrong size!
fi
chmod +x lib/fio.c
# end of overwriting check
fi
if test -f lib/font.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/font.c\"
else
echo shar: Extracting \"lib/font.c\" \(9825 characters\)
sed "s/^X//" >lib/font.c <<'END_OF_lib/font.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font.c,v 1.6 89/02/13 14:31:02 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Routines for working with fonts.  In particular, the configuration
X * dependent code is here.
X *
X * Specific fonts (GF, PXL, etc.) have functions in separate files.
X */
X
X#include <stdio.h>
X#include <errno.h>
X#include <sys/file.h>
X#include "types.h"
X#include "conv.h"
X#include "font.h"
X
X/*
X * Define the default configuration file.
X * Also define the maximum path name length.
X */
X#ifndef FONTDESC
X	you need to define FONTDESC in the compile line
X#endif
X
X#define	PATHLEN	1024
X
X/*
X * A font configuration.  The font list is ordered.
X *
X * A specifier is typically a particular print engine, since
X * different engines need slightly different fonts.
X */
Xstruct fontconf {
X	struct	fontconf *fc_next;
X	struct	fontops *fc_ops;
X	char	*fc_path;	/* path, with metacharacters */
X	char	*fc_spec;	/* specifier */
X	int	fc_slop;	/* slop value */
X};
X
X/*
X * EQ is a fast way to check for string equivalence.
X */
X#define	EQ(a, b) (*(a) == *(b) && strcmp(a, b) == 0)
X
X/*
X * Private variables.
X */
Xstatic	int didinit;		/* true => initialised already */
Xstatic	char *cfname;		/* config file name, for errors */
Xstatic	int cfline;		/* config file line, likewise */
Xstatic	struct fontops *fontops;/* font operations code: list head */
Xstatic	struct fontconf *fonts;	/* font list */
Xstatic	struct fontconf **nextfc;/* used during initialisation */
Xstatic	char spec_any[] = "*";	/* the `anything' specifier */
X
X/*
X * Imports.
X */
Xextern	int errno;
Xchar	*getenv(), *malloc(), *strsave();
X#ifndef sys5
Xchar	*sprintf();
X#endif
X
Xstatic readconf();
Xstatic setfont();
Xstatic badcf();
Xstatic struct font *getafont();	/* get a font and optional rasters */
X
X/*
X * Here, alas, we know about all the kinds of fonts.
X * This also means that every DVI interpreter pulls in
X * the full set of font manipulation routines.
X *
X * PERHAPS THIS SHOULD BE CONFIGURABLE.
X */
X#define	ADDFONT(x) { \
X	extern struct fontops x; \
X	x.fo_next = fontops; \
X	fontops = &x; \
X}
X
Xfontinit(file)
X	char *file;
X{
X
X	if (didinit) {
X		/*
X		 * Could free the old configuration and fire up
X		 * a new one, but for now . . .
X		 */
X		error(1, 0, "attempt to reinit fonts");
X		/* NOTREACHED */
X	}
X	didinit++;
X	ADDFONT(boxops);
X	ADDFONT(blankops);
X	ADDFONT(invisops);
X	ADDFONT(pxlops);
X	ADDFONT(pkops);
X	ADDFONT(gfops);
X	nextfc = &fonts;
X	if (file == NULL)
X		if ((file = getenv(CONFENV)) == NULL)
X			file = FONTDESC;
X	readconf(file);
X}
X
X/*
X * A proto resembles a fontspec (indeed, it is a prototype
X * fontspec) but is not quite the same.  It is used to gather
X * the information needed per fontspec before allocating
X * the fontspec itself.
X */
Xstruct proto {
X	char	*p_type;
X	char	*p_spec;
X	char	*p_slop;
X	char	*p_path;
X};
X
X/*
X * Read the named configuration file.  The file is split into
X * lines, and lines are split into words; if the first word is
X * "font", this is a fontconf, and we read the remainder of the
X * words and make a fontconf entry.
X */
Xstatic
Xreadconf(name)
X	char *name;
X{
X	register FILE *f;	/* config file */
X	register char **p;	/* pointer into word vector */
X	register int c;
X	char line[1024];	/* input line */
X	char *v[100];		/* word vector */
X	struct proto proto;	/* prototype fontconf */
X
X#define GETWORD(x, ifnone) \
X	if (--c <= 0) \
X		badcf(ifnone); \
X	else \
X		(x) = *p++
X
X	if ((f = fopen(name, "r")) == NULL)
X		error(1, errno, "cannot read font configuration file \"%s\"",
X			name);
X	cfname = name;
X	cfline = 0;
X	while (fgets(line, sizeof (line), f) != NULL) {
X		cfline++;
X		if ((c = strlen(line)) > 0) {
X			if (line[--c] != '\n')
X				badcf("line too long");
X			line[c] = 0;
X		}
X		if ((c = split(line, v, sizeof (v) / sizeof (*v))) < 0)
X			badcf("too many words");
X		p = v;
X		/* skip things that are not fonts */
X		if (c == 0 || !EQ(*p, "font"))
X			continue;
X		p++;
X		GETWORD(proto.p_type, "missing font typename");
X		GETWORD(proto.p_spec, "missing font spec (engine)");
X		GETWORD(proto.p_slop, "missing slop value");
X		GETWORD(proto.p_path, "need pathname");
X		(void) setfont(&proto);
X	}
X}
X
X/*
X * Find a font's operations, given its name.
X */
Xstatic struct fontops *
Xfindops(name)
X	register char *name;
X{
X	register struct fontops *fo;
X
X	for (fo = fontops; fo != NULL; fo = fo->fo_next)
X		if (EQ(fo->fo_name, name))
X			return (fo);
X	return (NULL);
X}
X
X/*
X * Turn a prototype fontconf into a real one.
X */
Xstatic int
Xsetfont(p)
X	register struct proto *p;
X{
X	register struct fontconf *fc;
X	struct fontops *ops = findops(p->p_type);
X
X	if (ops == NULL) {
X		error(0, 0,
X			"\"%s\", line %d: unknown font type \"%s\" ignored",
X			cfname, cfline, p->p_type);
X		return (-1);
X	}
X	if ((fc = (struct fontconf *) malloc(sizeof (*fc))) == NULL)
X		error(1, errno,
X			"out of memory for font configuration (sorry)");
X	fc->fc_ops = ops;
X	fc->fc_next = NULL;
X	fc->fc_path = strsave(p->p_path);
X	fc->fc_spec = EQ(p->p_spec, spec_any) ? NULL : strsave(p->p_spec);
X	fc->fc_slop = atoi(p->p_slop);
X	if (fc->fc_slop < 1)	/* quietly enforce proper slops */
X		fc->fc_slop = 1;
X	*nextfc = fc;
X	nextfc = &fc->fc_next;
X	return (0);
X}
X
X/*
X * Complain about a problem in the configuration file.
X */
Xstatic
Xbadcf(why)
X	char *why;
X{
X
X	error(1, 0, "\"%s\", line %d: %s", cfname, cfline, why);
X	/* NOTREACHED */
X}
X
X/*
X * Turn a prototype path, name, and magnification into a full
X * path.
X */
Xstatic
Xpave(result, proto, name, mag)
X	char *result, *proto, *name;
X	int mag;
X{
X	register int c;
X	register char *s, *d, *p;
X	char num[30];
X
X	d = result;
X	p = proto;
X	s = NULL;
X	num[0] = 0;		/* will need changing for other bases */
X
X	while (p != NULL) {
X		/*
X		 * If sourcing from s, take its next character, and
X		 * insert it directly.  Otherwise take the next path
X		 * character and interpret it.
X		 */
X		if (s != NULL) {
X			if ((c = *s++) == 0) {
X				s = NULL;
X				continue;
X			}
X			goto put;
X		}
X		if ((c = *p++) == 0)
X			p = NULL;
X		if (c != '%')
X			goto put;
X
X		switch (c = *p++) {
X
X		case 'f':
X		case 'n':
X		case 's':
X			s = name;
X			continue;
X
X		case 'd':
X		case 'm':
X			if (num[0] == 0)
X				(void) sprintf(num, "%d", mag);
X			s = num;
X			continue;
X
X		case 0:
X			c = '%';
X			p--;
X			/* FALLTHROUGH */
X		}
Xput:
X		if (d - result >= PATHLEN)
X			error(1, 0, "font path `%s' too long (sorry)", proto);
X		*d++ = c;
X	}
X}
X
X
X/*
X * Given a font name and size, return the first font that fits, along
X * with its name (via fname).  If we cannot find such a font, we set
X * *fname to point to a `canonical' example font name, unless there are
X * are no fonts for the device, in which case we set *fname to NULL.
X */
Xstruct font *
XGetFont(nm, dvimag, dvidsz, dev, fname)
X	char *nm;
X	i32 dvimag, dvidsz;
X	char *dev, **fname;
X{
X
X	return (getafont(nm, dvimag, dvidsz, dev, fname, 1));
X}
X
X/*
X * Same as GetFont, but caller promises never to ask for rasters.
X */
Xstruct font *
XGetRasterlessFont(nm, dvimag, dvidsz, dev, fname)
X	char *nm;
X	i32 dvimag, dvidsz;
X	char *dev, **fname;
X{
X
X	return (getafont(nm, dvimag, dvidsz, dev, fname, 0));
X}
X
X/*
X * NEED TO THINK ABOUT gf NAMING CONVENTIONS HERE: ARE THEY LIKE pxl?
X * WHAT ABOUT OTHERS?
X */
Xstatic struct font *
Xgetafont(nm, dvimag, dvidsz, dev, fname, wantrast)
X	char *nm;
X	i32 dvimag, dvidsz;
X	char *dev, **fname;
X	int wantrast;
X{
X	register int slop, fmag;
X	register struct font *f;
X	register struct fontconf *fc;
X	register char *path;
X	static char firstpath[PATHLEN], laterpath[PATHLEN];
X	double mag;
X	int scaled;
X
X	extern Conv Conversion;
X
X	if (!didinit)
X		fontinit((char *) NULL);
X
X	/*
X	 * The equation below means, approximately, `the font is
X	 * magnified by the ratio of the actual size dvimag to the
X	 * design size dvidsz, and then further scaled by the
X	 * global magnification.'  We multiply this by the printer's
X	 * resolution in dots per inch, then use the per-font
X	 * conversion factor to convert a dots-per-inch value to
X	 * a font name `%m' magnification (extension).
X	 */
X	mag = (double) dvimag / (double) dvidsz;
X	scaled = mag * 1000.0 + 0.5;
X	mag *= Conversion.c_mag * Conversion.c_dpi;
X
X	path = firstpath;
X	for (fc = fonts; fc != NULL; fc = fc->fc_next) {
X		if (dev != NULL && fc->fc_spec != NULL &&
X		    !EQ(dev, fc->fc_spec))
X			continue;
X		fmag = mag * fc->fc_ops->fo_dpitomag + 0.5;
X		for (slop = 0; slop < fc->fc_slop; slop++) {
X			pave(path, fc->fc_path, nm, fmag + slop);
X			if (access(path, R_OK) == 0)
X				goto found;
X
X
X			/* if someone could explain this, I'd appreicate it.
X			   On ultrix 2.2, checking R_OK on a RO filesyste
X			   fails, with the following errno. Why? */
X
X			if ( errno == EROFS ) {
X			  goto found;
X			}
X
X			if (slop) {
X				pave(path, fc->fc_path, nm, fmag - slop);
X				if (access(path, R_OK) == 0)
X					goto found;
X				if ( errno == EROFS ) {
X				  goto found;
X				}
X			}
X			path = laterpath;
X		}
X	}
X
X	/* not found */
X	if (path == firstpath) {	/* never got to try any paths */
X		*fname = NULL;
X		errno = ENXIO;
X	} else {
X		*fname = firstpath;
X		errno = ENOENT;
X	}
X	return (NULL);
X
Xfound:
X	*fname = path;
X
X	/* allocate space for the per-font info, and read it in */
X	f = (struct font *) malloc(sizeof (struct font));
X	if (f == NULL)
X		return (NULL);
X	f->f_flags = wantrast ? FF_RASTERS : 0;
X	f->f_ops = fc->fc_ops;
X	f->f_path = strsave(path);
X	f->f_font = strsave(nm);
X	f->f_dvimag = dvimag;
X	f->f_dvidsz = dvidsz;
X	f->f_scaled = scaled;
X	f->f_checksum = 0;	/* in case the font reader cannot get one */
X	errno = 0;
X	if ((*f->f_ops->fo_read)(f)) {
X		int e = errno;	/* paranoid */
X
X		free(f->f_path); f -> f_path = 0;
X		free(f->f_font); f -> f_font = 0;
X		free((char *) f); f = 0;
X		errno = e;
X		return (NULL);
X	}
X	return (f);
X}
END_OF_lib/font.c
if test 9825 -ne `wc -c <lib/font.c`; then
    echo shar: \"lib/font.c\" unpacked with wrong size!
fi
chmod +x lib/font.c
# end of overwriting check
fi
if test -f lib/font_subr.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/font_subr.c\"
else
echo shar: Extracting \"lib/font_subr.c\" \(4984 characters\)
sed "s/^X//" >lib/font_subr.c <<'END_OF_lib/font_subr.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved.  Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font_subr.c,v 1.5 89/02/13 14:31:04 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Subroutines common to all fonts.
X */
X
X#include "font.h"
X
Xstatic struct glyph *freeglyphs;
X
Xchar	*malloc();
Xextern	errno;
X
X/*
X * Set up the font structures to note that a font has glyphs in
X * the half-open interval [low, high).
X *
X * SHOULD I ALLOW ADDITIONS TO THE RANGE VIA SUBSEQUENT CALLS TO
X * FontHasGlyphs?
X */
XFontHasGlyphs(f, low, high)
X	register struct font *f;
X	register int low, high;
X{
X	register struct glyph **gp;
X
X	/* record bounds */
X	f->f_lowch = low;
X	f->f_highch = high;
X
X	/*
X	 * Allocate space for all the glyph pointers, and set
X	 * them all to NULL.
X	 */
X	if (low >= high)	/* no glyphs */
X		gp = NULL;
X	else {
X		gp = (struct glyph **) malloc((unsigned) (high - low) *
X			sizeof (*gp));
X		if (gp == NULL)
X			return (-1);
X	}
X	f->f_glybase = gp;
X	f->f_gly = gp - low;
X	while (++low <= high)
X		*gp++ = NULL;
X	return (0);
X}
X
X/*
X * AllocGlyph allocates a new glyph.  ReleaseGlyph puts one onto the free
X * list.  We maintain a local list of free glyphs.
X */
X#define ReleaseGlyph(g)	\
X	((g)->g_un.g_next = freeglyphs, freeglyphs = (g))
X
Xstatic struct glyph *
XAllocGlyph(n)
X	int n;
X{
X	register struct glyph *g;
X	register int i;
X
X	if ((g = freeglyphs) == NULL) {
X		g = (struct glyph *) malloc((unsigned) (128 * sizeof (*g)));
X		if (g == NULL)
X			error(1, errno, "out of glyph memory");
X		g += (i = 128);
X		while (--i >= 0) {
X			g--;
X			ReleaseGlyph(g);
X		}
X	}
X	freeglyphs = g->g_un.g_next;
X	g->g_flags = 0;
X	g->g_raster = NULL;
X	g->g_index = n;
X	return (g);
X}
X
X/*
X * Free one glyph.
X */
Xvoid
XFreeGlyph(f, n)
X	struct font *f;
X	register int n;
X{
X	register struct glyph *g;
X
X	if (n < f->f_lowch || n >= f->f_highch)
X		return;
X#ifdef notdef
X	(*f->f_ops->fo_freegly)(f, n, n);
X#endif
X	if ((g = f->f_gly[n]) == NULL)
X		return;
X	if (g->g_raster != NULL) {
X		free(g->g_raster); g -> g_raster = 0;
X	      }
X	ReleaseGlyph(g);
X}
X
X/*
X * Free a font.
X */
Xvoid
XFreeFont(f)
X	register struct font *f;
X{
X	register struct glyph *g;
X	register int i;
X
X#ifdef notdef
X	(*f->f_ops->fo_freegly)(f, f->f_lowch, f->f_highch);
X#endif
X	for (i = f->f_lowch; i < f->f_highch; i++) {
X		if ((g = f->f_gly[i]) == NULL)
X			continue;
X		if (g->g_raster != NULL) {
X			free(g->g_raster); g -> g_raster = 0;
X		      }
X		ReleaseGlyph(g);
X	}
X	if (f->f_glybase != NULL) {
X		free((char *) f->f_glybase); g -> g_raster = 0;
X	      }
X	(*f->f_ops->fo_freefont)(f);
X	free(f->f_path); f -> f_path = 0;
X	free(f->f_font); f -> f_font = 0;
X	free((char *) f); f = 0;
X}
X
X/*
X * Get glyph `c' in font `f'.  We pull in a few adjacent glyphs here
X * under the (perhaps naive) assumption that things will go faster
X * that way.
X *
X * TODO:
X *	try different adjacency values
X *	make adjacency a font attribute? (or an op)
X */
X#define	ADJ	8		/* must be a power of 2 */
X#define	GET_ADJ(c, l, h) ((h) = ADJ + ((l) = (c) & ~(ADJ - 1)))
X
Xstruct glyph *
XGetGlyph(f, c)
X	register struct font *f;
X	int c;
X{
X	register int i, h, l;
X
X	GET_ADJ(c, l, h);
X	if (l < f->f_lowch)
X		l = f->f_lowch;
X	if (h > f->f_highch)
X		h = f->f_highch;
X	if (l >= h)
X		return (NULL);
X	for (i = l; i < h; i++)
X		if (f->f_gly[i] == NULL)
X			f->f_gly[i] = AllocGlyph(i);
X
X	if ((*f->f_ops->fo_getgly)(f, l, h)) {
X		/*
X		 * I do not know what to do about this just yet, so:
X		 */
X		panic("getgly fails and I am confused ... help!");
X	}
X
X	/*
X	 * Apply the appropriate scale factor to the TFM widths.
X	 * This makes them come out in scaled points, instead of FIXes.
X	 */
X	ScaleGlyphs(f, l, h);	/* ??? */
X
X	return (f->f_gly[c]);
X}
X
X/*
X * Get the raster for glyph g in font f at rotation r.
X */
Xchar *
XGetRaster(g, f, r)
X	register struct glyph *g;
X	register struct font *f;
X	int r;
X{
X	int l, h;
X
X	/* abort if caller did not ask for rasters in advance */
X	if ((f->f_flags & FF_RASTERS) == 0)
X		panic("GetRaster(%s)", f->f_path);
X
X	/*
X	 * If there is no raster, get one.  Blank characters,
X	 * however, never have rasters.
X	 */
X	if (g->g_raster == NULL) {
X		if (!HASRASTER(g))
X			return (NULL);
X		/*
X		 * THE FOLLOWING DEPENDS ON THE ADJACENCY MATCHING THAT IN
X		 * GetGlyph() ABOVE.
X		 */
X		GET_ADJ(g->g_index, l, h);
X		if (l < f->f_lowch)
X			l = f->f_lowch;
X		if (h > f->f_highch)
X			h = f->f_highch;
X		if ((*f->f_ops->fo_rasterise)(f, l, h))
X			error(1, 0, "rasterise fails (out of memory?)");
X	}
X	if (g->g_rotation != r)
X		SetRotation(g, r);
X	return (g->g_raster);
X}
X
X/*
X * Return a TeX-style font name, including scale factor.
X * SHOULD I BOTHER WITH \magstep STYLE NAMES?
X */
Xchar *
XFont_TeXName(f)
X	register struct font *f;
X{
X	static char result[200];
X
X	if (f->f_scaled == 1000)
X		return (f->f_font);
X	sprintf(result, "%s scaled %d", f->f_font, f->f_scaled);
X	return (result);
X}
END_OF_lib/font_subr.c
if test 4984 -ne `wc -c <lib/font_subr.c`; then
    echo shar: \"lib/font_subr.c\" unpacked with wrong size!
fi
chmod +x lib/font_subr.c
# end of overwriting check
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    echo "Now do 'make dviselect'"
    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
--
Skip Montanaro (montanaro at crdgw1.ge.com)



More information about the Alt.sources mailing list