dviselect (Part 6 of 6)

Skip Montanaro montnaro at sprite.crd.ge.com
Tue Nov 14 08:24:56 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 6 (of 6)."
# Contents:  lib/Makefile lib/rotate.c lib/scaletfm.c lib/scanpost.c
#   lib/search.c lib/seek.c lib/split.c lib/strsave.c lib/tfm.c
#   lib/tfmfont.c
# Wrapped by montnaro at sprite on Sat Nov 11 17:13:33 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f lib/Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/Makefile\"
else
echo shar: Extracting \"lib/Makefile\" \(3637 characters\)
sed "s/^X//" >lib/Makefile <<'END_OF_lib/Makefile'
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# Makefile for ctex/lib (C-TeX library routines)
X#
X# $Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/Makefile,v 1.6 89/02/13 14:31:29 grunwald Exp Locker: grunwald $
X#
XDESTDIR=
X# Alas, -R makes ALL initialised variables read-only, and we cannot
X# use it on font files; hence, FCFLAGS.
XCC=cc
XCFLAGS=	-O -I../h 
XFCFLAGS=-O -I../h
X
X# 4.1BSD Vax:
X#ASSRC=	bcopy.s bzero.s
X#ASOBJ=	bcopy.o bzero.o
X#MISCC=	getopt.c
X#MISCO=	getopt.o
X
X# 4.2BSD Vax:
X#ASSRC=
X#ASOBJ=
X#MISCC=	getopt.c
X#MISCO=	getopt.o
X
X# 4.2BSD Sun:
X#ASSRC=
X#ASOBJ=
X#MISCC=
X#MISCO=
X
X# 4.2BSD Pyramid:
X#ASSRC=
X#ASOBJ=
X#MISCC=	getopt.c
X#MISCO=	getopt.o
X
X# 4.3BSD Vax:
XASSRC=
XASOBJ=
XMISCC=
XMISCO=
X# all
XCSRC=	conv.c dviclass.c error.c findpost.c fio.c font.c font_subr.c \
X	gfclass.c gripes.c magfactor.c rotate.c scaletfm.c scanpost.c \
X	search.c seek.c split.c strsave.c tfm.c ${MISCC}
XCOBJ=	conv.o dviclass.o error.o findpost.o fio.o font.o font_subr.o \
X	gfclass.o gripes.o magfactor.o rotate.o scaletfm.o scanpost.o \
X	search.o seek.o split.o strsave.o tfm.o ${MISCO}
XFSRC=	gffont.c pkfont.c pxlfont.c tfmfont.c
XFOBJ=	gffont.o pkfont.o pxlfont.o tfmfont.o
X
XOBJS=	${COBJ} ${ASOBJ} ${FOBJ}
X
Xall: lib.a
X
Xlib.a: ${OBJS}
X	ar cr lib.a ${OBJS}
X	ranlib lib.a
X
Xsrc: $(CSRC) $(FSRC)
X	@echo Done
X
X# no installation is necessary; this entry is just for standardisation
Xinstall:
X
Xclean:
X	rm -f *.o lib.a
X
X#pxl.o:
X#	${CC} ${CFLAGS} -c -DPXLPATH=\"${PXLPATH}\" pxl.c
X
X# font.o needs to know where to find the font description file
Xfont.o:
X	${CC} ${CFLAGS} -c -DFONTDESC=\"${FONTDESC}\" font.c
X
X# special rules for font objects
X${FOBJ}:
X	${CC} ${FCFLAGS} -c $*.c
X
X# DO NOT DELETE THIS LINE -- make depend uses it
X# DEPENDENCIES MUST END AT END OF FILE
X# IF YOU PUT STUFF HERE IT WILL GO AWAY
X# see make depend above
X# DO NOT DELETE THIS LINE -- make depend depends on it.
X
Xconv.o: ../h/types.h ../h/conv.h
Xdviclass.o: ../h/dviclass.h
Xerror.o: /usr/include/stdio.h /usr/include/varargs.h
Xfindpost.o: /usr/include/stdio.h ../h/types.h ../h/dvicodes.h ../h/fio.h
Xfio.o: /usr/include/stdio.h ../h/types.h ../h/fio.h
Xfont.o: /usr/include/stdio.h /usr/include/errno.h /usr/include/sys/errno.h
Xfont.o: ../h/types.h ../h/conv.h ../h/font.h
Xfont_subr.o: ../h/font.h
Xgetopt.o: /usr/include/stdio.h
Xgfclass.o: ../h/gfclass.h
Xgffont.o: /usr/include/stdio.h /usr/include/sys/types.h
Xgffont.o: /usr/include/sys/stat.h ../h/types.h
Xgffont.o: ../h/font.h ../h/gfcodes.h ../h/gfclass.h ../h/num.h
Xgripes.o: /usr/include/stdio.h ../h/types.h
Xpkfont.o: /usr/include/stdio.h /usr/include/sys/types.h
Xpkfont.o: /usr/include/sys/stat.h ../h/types.h
Xpkfont.o: ../h/font.h ../h/num.h
Xpxlfont.o: /usr/include/stdio.h /usr/include/sys/types.h
Xpxlfont.o: /usr/include/sys/stat.h
Xpxlfont.o: /usr/include/errno.h /usr/include/sys/errno.h ../h/types.h
Xpxlfont.o: ../h/font.h ../h/fio.h
Xrotate.o: ../h/font.h
Xscaletfm.o: ../h/types.h ../h/font.h
Xscanpost.o: /usr/include/stdio.h ../h/types.h ../h/dvicodes.h ../h/fio.h
Xscanpost.o: ../h/postamble.h
Xsearch.o: ../h/types.h ../h/search.h
Xseek.o: /usr/include/stdio.h /usr/include/sys/param.h
Xseek.o: /usr/include/sys/signal.h
Xseek.o: /usr/include/sys/types.h 
Xseek.o: /usr/include/sys/file.h
Xseek.o: /usr/include/sys/stat.h
Xsplit.o: /usr/include/ctype.h
Xtfm.o: /usr/include/stdio.h ../h/types.h ../h/fio.h ../h/tfm.h
Xtfmfont.o: /usr/include/stdio.h /usr/include/sys/types.h
Xtfmfont.o: /usr/include/sys/stat.h ../h/types.h
Xtfmfont.o: ../h/conv.h ../h/font.h ../h/tfm.h
END_OF_lib/Makefile
if test 3637 -ne `wc -c <lib/Makefile`; then
    echo shar: \"lib/Makefile\" unpacked with wrong size!
fi
chmod +x lib/Makefile
# end of overwriting check
fi
if test -f lib/rotate.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/rotate.c\"
else
echo shar: Extracting \"lib/rotate.c\" \(3519 characters\)
sed "s/^X//" >lib/rotate.c <<'END_OF_lib/rotate.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/rotate.c,v 1.4 89/02/13 14:31:18 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Routines to generate rotated bitmaps given unrotated inputs.
X *
X * The rotated bitmap is indistinguishable from the unrotated one (aside
X * from being rotated of course!).
X */
X
X#include "font.h"
X
Xextern	int errno;
X
Xchar	*malloc();
X
Xstatic RotateClockwise();
X
X/*
X * Rounding, but by powers of two only.
X */
X#define ROUND(n,r) (((n) + ((r) - 1)) & ~((r) - 1))
X
X/*
X * Set the rotation of glyph g to r.
X */
XSetRotation(g, r)
X	register struct glyph *g;
X	int r;
X{
X
X	if (r < ROT_NORM || r > ROT_RIGHT)
X		error(1, 0, "bad rotation value %d", r);
X
X	/*
X	 * The null glyph is trivial to rotate by any amount.
X	 *
X	 * Note that this assumes that any raster has been obtained
X	 * BEFORE calling SetRotation()!
X	 */
X	if (g->g_raster == NULL) {
X		g->g_rotation = r;
X		return;
X	}
X
X	/*
X	 * This is hardly efficient, but it *is* expedient....
X	 */
X	while (g->g_rotation != r) {
X		RotateClockwise(g);
X		g->g_rotation = (g->g_rotation - 1) & 3;
X	}
X}
X
X/*
X * Rotation by 1/4 turn clockwise (from ROT_NORM to ROT_RIGHT, e.g.).
X */
Xstatic
XRotateClockwise(glyph)
X	struct glyph *glyph;
X{
X	register char *nrast;	/* new raster */
X	register char *orast;	/* old raster */
X	register int oheight;	/* old raster height, new raster width */
X	register int owidth;	/* old raster width, new raster height */
X	unsigned int size;	/* size of new raster (in bytes) */
X	int nplus;		/* offset between rows in nrast */
X
X	/*
X	 * First, get a new raster.
X	 */
X	{
X		register struct glyph *g = glyph;
X		register int t;
X
X		oheight = g->g_height;
X		owidth = g->g_width;
X
X		/*
X		 * Offset is (new width) rounded to bytes.
X		 */
X		nplus = ROUND(oheight, 8) >> 3;
X
X		/*
X		 * Size of new raster is (new height) * (new rounded width,
X		 * in bytes).
X		 */
X		size = nplus * owidth;
X		if ((nrast = malloc(size)) == NULL)
X			error(1, errno, "out of memory");
X		bzero(nrast, size);
X
X		/*
X		 * New y origin is old x origin; new x origin is old height
X		 * minus old y origin - 1.
X		 */
X		t = g->g_yorigin;
X		g->g_yorigin = g->g_xorigin;
X		g->g_xorigin = oheight - t - 1;
X
X		/* While we are at it, exchange height & width... */
X		g->g_height = owidth;
X		g->g_width = oheight;
X
X		/* and grab a pointer to the old raster. */
X		orast = g->g_raster;
X	}
X
X	/*
X	 * Now copy bits from the old raster to the new one.  The mapping
X	 * function is
X	 *
X	 *	for i in [0..height)
X	 *		for j in [0..width)
X	 *			new[j, height-i-1] = old[i, j] 
X	 *
X	 * Thus i maps to height-i-1 and (since we have to do our own 2
X	 * dimensional array indexing) j to nplus*j.  We call the mapped
X	 * variables mapi and mapj, and, since we scan sequentially through
X	 * the old raster, can discard the original i and j.
X	 */
X	{
X		register int mapj, c, k, mapi;
X
X		mapi = oheight;
X		owidth *= nplus;
X		while (--mapi >= 0) {
X			k = 7;
X			for (mapj = 0; mapj < owidth; mapj += nplus) {
X				if (++k == 8)	/* get another byte */
X					c = *orast++, k = 0;
X				if (c & 0x80)	/* old[i,j] was set */
X					nrast[mapj + (mapi >> 3)] |=
X						1 << (7 - (mapi & 7));
X				c <<= 1;
X			}
X		}
X	}
X
X	/*
X	 * Finally, free the storage associated with the original raster.
X	 */
X	free(glyph->g_raster); glyph->g_raster = 0;
X	glyph->g_raster = nrast;
X}
END_OF_lib/rotate.c
if test 3519 -ne `wc -c <lib/rotate.c`; then
    echo shar: \"lib/rotate.c\" unpacked with wrong size!
fi
chmod +x lib/rotate.c
# end of overwriting check
fi
if test -f lib/scaletfm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/scaletfm.c\"
else
echo shar: Extracting \"lib/scaletfm.c\" \(3302 characters\)
sed "s/^X//" >lib/scaletfm.c <<'END_OF_lib/scaletfm.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/scaletfm.c,v 1.3 89/02/13 14:31:19 grunwald Exp Locker: grunwald $";
X#endif
X
X#include "types.h"
X#include "font.h"
X
X/*
X * From DVITYPE.WEB:
X *
X * ``The most important part of in_TFM is the width computation, which
X *   involvles multiplying the relative widths in the TFM file by the scaling
X *   factor in the DVI file.  This fixed-point multiplication must be done with
X *   precisely the same accuracy by all DVI-reading programs, in order to
X *   validate the assumptions made by DVI-writing programs like \TeX 82.
X *
X *   Let us therefore summarize what needs to be done.  Each width in a TFM
X *   file appears as a four-byte quantity called a fix_word.  A fix_word whose
X *   respective bytes are (a,b,c,d) represents the number
X *
X *	   {{ b * 2^{-4} + c * 2^{-12} + d * 2^{-20},        if a = 0;
X *    x = {{
X *	   {{ -16 + b * 2^{-4} + c * 2^{-12} + d * 2^{-20},  if a = 255.
X *
X *   (No other choices of a are allowed, since the magnitude of a TFM dimension
X *   must be less than 16.)  We want to multiply this quantity by the integer
X *   z, which is known to be less than 2^{27}.  Let \alpha = 16z.  If z <
X *   2^{23}, the individual multiplications b * z, c * z, d * z cannot
X *   overflow; otherwise we will divide z by 2, 4, 8, or 16, to obtain a
X *   multiplier less than 2^{23}, and we can compensate for this later.  If z
X *   has thereby been replaced by z' = z/2^e, let \beta = 2^{4-e}; we shall
X *   compute
X *
X *	\lfloor (b + c * 2^{-8} + d * 2^{-16})z' / \beta \rfloor
X *
X *   if a = 0, or the same quantity minus \alpha if a = 255.  This calculation
X *   must be done exactly, for the reasons stated above; the following program
X *   does the job in a system-independent way, assuming that arithmetic is
X *   exact on numbers less than 2^{31} in magnitude.''
X */
X
X/*
X * Scale the single TFM width t by z.
X */
Xi32
XScaleOneWidth(t, z)
X	register i32 t, z;
X{
X	register i32 alpha, log2beta;
X
X	/* First compute \alpha, \beta, and z': */
X	alpha = 16 * z;
X	log2beta = 4;
X	while (z >= (1 << 23)) {
X		z >>= 1;
X		log2beta--;
X	}
X
X	/* The four values 'a', 'b', 'c', and 'd' are fields within t: */
X#define	a	(UnSign8(t >> 24))
X#define	b	(UnSign8(t >> 16))
X#define	c	(UnSign8(t >> 8))
X#define	d	(UnSign8(t))
X	if (t) {
X		t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> log2beta;
X		if (a) {
X			if (a != 255)
X				error(0, 0, "bad TFM width! [ScaleOneWidth]");
X			t -= alpha;
X		}
X	}
X	return (t);
X}
X
X/*
X * Scale a set of glyphs [l..h) in font f according to f->f_dvimag.
X */
XScaleGlyphs(f, l, h)
X	register struct font *f;
X	int l, h;
X{
X	register int i;
X	register i32 t, z, alpha, log2beta;
X
X	z = f->f_dvimag;
X	alpha = 16 * z;
X	log2beta = 4;
X	while (z >= (1 << 23)) {
X		z >>= 1;
X		log2beta--;
X	}
X
X	for (i = l; i < h; i++) {
X		if ((t = f->f_gly[i]->g_tfmwidth) == 0)
X			continue;
X		t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> log2beta;
X		if (a) {
X			if (a != 255)
X				error(0, 0, "\"%s\", glyph %d: bad TFM width",
X					f->f_path, i);
X			t -= alpha;
X		}
X		f->f_gly[i]->g_tfmwidth = t;
X	}
X}
END_OF_lib/scaletfm.c
if test 3302 -ne `wc -c <lib/scaletfm.c`; then
    echo shar: \"lib/scaletfm.c\" unpacked with wrong size!
fi
chmod +x lib/scaletfm.c
# end of overwriting check
fi
if test -f lib/scanpost.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/scanpost.c\"
else
echo shar: Extracting \"lib/scanpost.c\" \(2244 characters\)
sed "s/^X//" >lib/scanpost.c <<'END_OF_lib/scanpost.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/scanpost.c,v 1.3 89/02/13 14:31:20 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * ScanPostAmble - read a DVI postamble.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "dvicodes.h"
X#include "fio.h"
X#include "postamble.h"
X
XScanPostAmble(f, headerfunc, fontfunc)
X	register FILE *f;
X	int (*headerfunc)();
X	register int (*fontfunc)();
X{
X	register int n;
X	register char *s;
X	char name[512];
X
X	if (FindPostAmble(f)) {
X	  GripeCannotFindPostamble();
X	  return(1);
X	}
X	if (GetByte(f) != Sign8(DVI_POST)) {
X	  GripeMissingOp("POST");
X	  return(1);
X	}
X
X	/* Read the postamble info stuff. */
X	{
X		struct PostAmbleInfo pai;
X		register struct PostAmbleInfo *p = &pai;
X
X		p->pai_PrevPagePointer = GetLong(f);
X		p->pai_Numerator = GetLong(f);
X		p->pai_Denominator = GetLong(f);
X		p->pai_DVIMag = GetLong(f);
X		p->pai_TallestPageHeight = GetLong(f);
X		p->pai_WidestPageWidth = GetLong(f);
X		p->pai_DVIStackSize = GetWord(f);
X		p->pai_NumberOfPages = GetWord(f);
X
X		(*headerfunc)(p);
X	}
X
X	/* Now read all the font definitions. */
X	{
X		struct PostAmbleFont paf;
X		register struct PostAmbleFont *p = &paf;
X
X		for (;;) {
X			switch (UnSign8(getc(f))) {
X
X			case DVI_FNTDEF1:
X				p->paf_DVIFontIndex = UnSign8(getc(f));
X				break;
X
X			case DVI_FNTDEF2:
X				p->paf_DVIFontIndex = UnSign16(GetWord(f));
X				break;
X
X			case DVI_FNTDEF3:
X				p->paf_DVIFontIndex = UnSign24(Get3Byte(f));
X				break;
X
X			case DVI_FNTDEF4:
X				p->paf_DVIFontIndex = GetLong(f);
X				break;
X
X			case DVI_POSTPOST:
X				return(0);
X
X			default:
X				GripeMissingOp("POSTPOST");
X				return(1);
X				/*NOTREACHED*/
X			}
X			p->paf_DVIChecksum = GetLong(f);
X			p->paf_DVIMag = GetLong(f);
X			p->paf_DVIDesignSize = GetLong(f);
X			p->paf_n1 = UnSign8(getc(f));
X			p->paf_n2 = UnSign8(getc(f));
X			p->paf_name = name;	/* never trust people not to
X						   clobber it */
X			n = p->paf_n1 + p->paf_n2;
X			s = name;
X			while (--n >= 0)
X				*s++ = GetByte(f);
X			*s = 0;
X			(*fontfunc)(p);
X		}
X	}
X}
END_OF_lib/scanpost.c
if test 2244 -ne `wc -c <lib/scanpost.c`; then
    echo shar: \"lib/scanpost.c\" unpacked with wrong size!
fi
chmod +x lib/scanpost.c
# end of overwriting check
fi
if test -f lib/search.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/search.c\"
else
echo shar: Extracting \"lib/search.c\" \(4599 characters\)
sed "s/^X//" >lib/search.c <<'END_OF_lib/search.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/search.c,v 1.4 89/02/13 14:31:21 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Key search routines (for a 32 bit key)
X *
X * SCreate initializes the search control area.
X *
X * SSearch returns the address of the data area (if found or created)
X * or a null pointer (if not).  The last argument controls the disposition
X * in various cases, and is a ``value-result'' parameter.
X *
X * SEnumerate calls the given function on each data object within the
X * search table.  Note that no ordering is specified (though currently
X * it runs in increasing-key-value sequence).
X */
X
X#include "types.h"
X#include "search.h"
X
X#if vax || mc68000 || ns32000 || pyr
X#define	HARD_ALIGNMENT	4
X#else
X#define	HARD_ALIGNMENT	16	/* should suffice for most everyone */
X#endif
X
Xstatic int DOffset;		/* part of alignment code */
X
Xchar	*malloc(), *realloc();
X
Xstruct search *
XSCreate(dsize)
X	register unsigned int dsize;
X{
X	register struct search *s;
X
X	if ((s = (struct search *) malloc(sizeof *s)) == 0)
X		return (0);
X
X	if (DOffset == 0) {
X#ifndef HARD_ALIGNMENT
X		DOffset = sizeof(i32);
X#else
X		DOffset = (sizeof(i32) + HARD_ALIGNMENT - 1) &
X			~(HARD_ALIGNMENT - 1);
X#endif
X	}
X	dsize += DOffset;	/* tack on space for keys */
X
X#ifdef HARD_ALIGNMENT
X	/*
X	 * For machines with strict alignment constraints, it may be
X	 * necessary to align the data at a multiple of some positive power
X	 * of two.  In general, it would suffice to make dsize a power of
X	 * two, but this could be very space-wasteful, so instead we align it
X	 * to HARD_ALIGNMENT.  64 bit machines might ``#define HARD_ALIGNMENT
X	 * 8'', for example.  N.B.:  we assume that HARD_ALIGNMENT is a power
X	 * of two.
X	 */
X
X	dsize = (dsize + HARD_ALIGNMENT - 1) & ~(HARD_ALIGNMENT - 1);
X#endif
X
X	s->s_dsize = dsize;	/* save data object size */
X	s->s_space = 10;	/* initially, room for 10 objects */
X	s->s_n = 0;		/* and none in the table */
X	if ((s->s_data = malloc(s->s_space * dsize)) == 0) {
X		free((char *) s); (char *) s = 0;
X		return (0);
X	}
X	return (s);
X}
X
X/*
X * We actually use a binary search right now - this may change.
X */
Xchar *
XSSearch(s, key, disp)
X	register struct search *s;
X	register i32 key;
X	int *disp;
X{
X	register char *keyaddr;
X	int itemstomove;
X
X	*disp &= S_CREATE | S_EXCL;	/* clear return codes */
X	if (s->s_n) {		/* look for the key */
X		register int h, l, m;
X
X		h = s->s_n - 1;
X		l = 0;
X		while (l <= h) {
X			m = (l + h) >> 1;
X			keyaddr = s->s_data + m * s->s_dsize;
X			if (*(i32 *) keyaddr > key)
X				h = m - 1;
X			else if (*(i32 *) keyaddr < key)
X				l = m + 1;
X			else {	/* found it, now what? */
X				if (*disp & S_EXCL) {
X					*disp |= S_COLL;
X					return (0);	/* collision */
X				}
X				*disp |= S_FOUND;
X				return (keyaddr + DOffset);
X			}
X		}
X		keyaddr = s->s_data + l * s->s_dsize;
X	} else
X		keyaddr = s->s_data;
X
X	/* keyaddr is now where the key should have been found, if anywhere */
X	if ((*disp & S_CREATE) == 0)
X		return (0);	/* not found */
X
X	/* avoid using realloc so as to retain old data if out of memory */
X	if (s->s_space <= 0) {	/* must expand; double it */
X		register char *new;
X
X		if ((new = malloc((s->s_n << 1) * s->s_dsize)) == 0) {
X			*disp |= S_ERROR;	/* no space */
X			return (0);
X		}
X		keyaddr = (keyaddr - s->s_data) + new;	/* relocate */
X		bcopy(s->s_data, new, s->s_n * s->s_dsize);
X		free(s->s_data); s->s_data = 0;
X		s->s_data = new;
X		s->s_space = s->s_n;
X	}
X	/* now move any keyed data that is beyond keyaddr down */
X	itemstomove = s->s_n - (keyaddr - s->s_data) / s->s_dsize;
X	if (itemstomove) {
X#ifndef USE_BCOPY		/* often bcopy doesn't handle overlap */
X		register char *from, *to;
X
X		from = s->s_data + s->s_n * s->s_dsize;
X		to = from + s->s_dsize;
X		while (from > keyaddr)
X			*--to = *--from;
X#else
X		bcopy(keyaddr + s->s_dsize, keyaddr + (s->s_dsize << 1),
X			itemstomove * s->s_dsize);
X#endif
X	}
X	*disp |= S_NEW;
X	s->s_n++;
X	s->s_space--;
X	*(i32 *) keyaddr = key;
X	keyaddr += DOffset;	/* now actually dataaddr */
X	/* the bzero is just a frill... */
X	bzero(keyaddr, s->s_dsize - DOffset);
X	return (keyaddr);
X}
X
X/*
X * Call function `f' for each element in the search table `s'.
X */
XSEnumerate(s, f)
X	register struct search *s;
X	register int (*f)();
X{
X	register int n;
X	register char *p;
X
X	n = s->s_n;
X	p = s->s_data;
X	while (--n >= 0) {
X		(*f)(p + DOffset, *(i32 *) p);
X		p += s->s_dsize;
X	}
X}
END_OF_lib/search.c
if test 4599 -ne `wc -c <lib/search.c`; then
    echo shar: \"lib/search.c\" unpacked with wrong size!
fi
chmod +x lib/search.c
# end of overwriting check
fi
if test -f lib/seek.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/seek.c\"
else
echo shar: Extracting \"lib/seek.c\" \(3044 characters\)
sed "s/^X//" >lib/seek.c <<'END_OF_lib/seek.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/seek.c,v 1.3 89/02/13 14:31:23 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Seekable is a predicate which returns true iff a Unix fd is seekable.
X *
X * MakeSeekable forces an input stdio file to be seekable, by copying to
X * a temporary file if necessary.
X */
X
X#include <stdio.h>
X#ifdef sys5
X#include <sys/types.h>
X#include <sys/fcntl.h>
X#else
X#include <sys/param.h>
X#endif
X#include <sys/file.h>
X#include <sys/stat.h>
X
Xlong	lseek();
Xchar	*getenv();
X
Xint
XSeekable(fd)
X	int fd;
X{
X
X	return (lseek(fd, 0L, 1) >= 0 && !isatty(fd));
X}
X
X/*
X * We use the despicable trick of unlinking an open temporary file.
X * The alternatives are too painful.  If it becomes necessary to
X * do this another way, however, here is a method suggested by Fred
X * Blonder: fork, and have the parent wait for the child to exit.
X * (The parent must avoid being killed during this phase.)  When
X * the child exits, the parent should then remove the temporary file,
X * then exit with the same status, or send itself the same signal.
X */
Xint
XMakeSeekable(f)
X	register FILE *f;
X{
X	register int tf, n;
X	int mypid, tries, blksize;
X	char *tmpdir;
X#ifdef MAXBSIZE
X	char buf[MAXBSIZE];
X	struct stat st;
X#else
X	char buf[BUFSIZ];
X#endif
X
X	if (Seekable(fileno(f)))
X		return (0);
X
X	if ((tmpdir = getenv("TMPDIR")) == 0)
X		tmpdir = "/tmp";
X
X	/* compose a suitable temporary file name, and get an r/w descriptor */
X	mypid = getpid();
X	n = 0;
X	tries = 0;
X	do {
X		sprintf(buf, "%s/#%d.%d", tmpdir, mypid, n++);
X		(void) unlink(buf);
X#ifdef O_CREAT			/* have three-argument open syscall */
X		tries++;
X		tf = open(buf, O_RDWR | O_CREAT | O_EXCL, 0666);
X#else
X		if (access(buf, 0) == 0) {
X			/*
X			 * Skip existing files.  Note that tf might
X			 * not be set yet.
X			 */
X			tf = -1;
X			continue;
X		}
X		tries++;
X		tf = creat(buf, 0666);
X		if (tf >= 0) {
X			(void) close(tf);
X			tf = open(buf, 2);
X			if (tf < 0)
X				(void) unlink(buf);
X		}
X#endif
X	} while (tf < 0 && tries < 20);
X	if (tf < 0)		/* probably unrecoverable user error */
X		return (-1);
X
X	(void) unlink(buf);
X
X	/* copy from input file to temp file */
X#ifdef MAXBSIZE
X	if (fstat(tf, &st))	/* how can this ever fail? */
X		blksize = MAXBSIZE;
X	else
X		blksize = MIN(MAXBSIZE, st.st_blksize);
X#else
X	blksize = BUFSIZ;
X#endif
X	while ((n = fread(buf, 1, blksize, f)) > 0) {
X		if (write(tf, buf, n) != n) {
X			(void) close(tf);
X			return (-1);
X		}
X	}
X	/* ferror() is broken in Ultrix 1.2; hence the && */
X	if (ferror(f) && !feof(f)) {
X		(void) close(tf);
X		return (-1);
X	}
X
X	/*
X	 * Now switch f to point at the temp file.  Since we hit EOF, there
X	 * is nothing in f's stdio buffers, so we can play a dirty trick: 
X	 */
X	clearerr(f);
X	if (dup2(tf, fileno(f))) {
X		(void) close(tf);
X		return (-1);
X	}
X	(void) close(tf);
X	return (0);
X}
END_OF_lib/seek.c
if test 3044 -ne `wc -c <lib/seek.c`; then
    echo shar: \"lib/seek.c\" unpacked with wrong size!
fi
chmod +x lib/seek.c
# end of overwriting check
fi
if test -f lib/split.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/split.c\"
else
echo shar: Extracting \"lib/split.c\" \(4603 characters\)
sed "s/^X//" >lib/split.c <<'END_OF_lib/split.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/split.c,v 1.3 89/02/13 14:31:24 grunwald Exp Locker: grunwald $";
X#endif
X
X#include <ctype.h>
X
X/*
X * Split a line into an array of words.  This is destructive of
X * the original line; the word pointers point to places within
X * that line.
X *
X * Return the number of words made, or -1 for overflow.
X */
X
X/*
X * The lexical states are much like `sh's, except that we also do
X * C-style backslash-escapes.
X */
Xenum lexstate {
X	S_BLANK,		/* outside a word */
X	S_WORD,			/* inside a word, no quoting */
X	S_SQUOTE,		/* inside a single quote */
X	S_DQUOTE,		/* inside a double quote */
X	S_BKSL0,		/* last char was \ */
X	S_BKSL1,		/* last chars were \, [0-7] */
X	S_BKSL2			/* last chars were \, [0-7][0-7] */
X};
X
Xint
Xsplit(s, w, nw)
X	register char *s, **w;
X	int nw;
X{
X	register int c;
X	register char *canon = s;
X	register int wleft = nw;
X	enum lexstate state, prebkstate;
X
X	/*
X	 * Start out in the `blank' state (outside a word).  Handle
X	 * quotes and things.  Backslashes are handled by saving the
X	 * `pre-backslash' state, doing the backslash, and restoring
X	 * that state at the end of the backslash sequence.
X	 */
X	state = S_BLANK;
X	while ((c = *s++) != 0) {
Xreswitch:
X		switch (state) {
X
X		/*
X		 * Blanks: spaces stay in blank state; anything
X		 * else starts a word.  However, quotes may put
X		 * us into quote states, rather than word states.
X		 */
X		case S_BLANK:
X			if (isspace(c))
X				continue;
X			if (--wleft < 0)
X				return (-1);
X			*w++ = canon;
X			state = S_WORD;
X			/* FALLTHROUGH */
X
X		/*
X		 * In a word.  Spaces take us out (and end the
X		 * current word).  Quotes, however, put us into
X		 * quote states.
X		 */
X		case S_WORD:
X			if (isspace(c)) {
X				*canon++ = 0;
X				state = S_BLANK;
X				break;
X			}
X			if (c == '\'') {
X				state = S_SQUOTE;
X				break;
X			}
X			if (c == '"') {
X				state = S_DQUOTE;
X				break;
X			}
X			if (c == '\\') {
X				prebkstate = S_WORD;
X				state = S_BKSL0;
X				break;
X			}
X			*canon++ = c;
X			break;
X
X		/*
X		 * Inside a single quote, the only special character
X		 * is another single quote.  This matches the Bourne
X		 * shell quoting convention exactly.
X		 */
X		case S_SQUOTE:
X			if (c == '\'')
X				state = S_WORD;
X			else
X				*canon++ = c;
X			break;
X
X		/*
X		 * Inside a double quote, double quotes get us out,
X		 * but backslashes must be interpreted.
X		 */
X		case S_DQUOTE:
X			if (c == '\\') {
X				prebkstate = S_DQUOTE;
X				state = S_BKSL0;
X			} else if (c == '"')
X				state = S_WORD;
X			else
X				*canon++ = c;
X			break;
X
X		/*
X		 * If we are handling a backslash, we will either
X		 * restore the state, or go to BKSL1 state.  In
X		 * the latter case, do not advance the canonicalisation
X		 * pointer, since we might have more octal digits
X		 * to insert.
X		 */
X		case S_BKSL0:
X			state = prebkstate;	/* probably */
X			switch (c) {
X
X			case 'b':
X				*canon++ = '\b';
X				break;
X
X			case 'f':
X				*canon++ = '\f';
X				break;
X
X			case 'n':
X				*canon++ = '\n';
X				break;
X
X			case 'r':
X				*canon++ = '\r';
X				break;
X
X			case 't':
X				*canon++ = '\t';
X				break;
X
X			case '0': case '1': case '2': case '3':
X			case '4': case '5': case '6': case '7':
X				*canon = c - '0';
X				state = S_BKSL1;
X				break;
X
X			default:
X				*canon++ = c;
X				break;
X			}
X			break;
X
X
X		/*
X		 * In BKSL1, we have seen backslash and one octal
X		 * digit.  There may be more (in which case just
X		 * count them on in), or there might be something
X		 * that requires we restore the state and try again.
X		 */
X		case S_BKSL1:
X			switch (c) {
X
X			case '0': case '1': case '2': case '3':
X			case '4': case '5': case '6': case '7':
X				*canon <<= 3;
X				*canon |= c - '0';
X				state = S_BKSL2;
X				break;
X
X			default:
X				canon++;
X				state = prebkstate;
X				goto reswitch;
X			}
X			break;
X
X		/*
X		 * BKSL2 is like BKSL1, except that it cannot
X		 * help but restore the original state, since
X		 * there are no four-character octal sequences.
X		 */
X		case S_BKSL2:
X			state = prebkstate;	/* assuredly */
X			switch (c) {
X
X			case '0': case '1': case '2': case '3':
X			case '4': case '5': case '6': case '7':
X				*canon <<= 3;
X				*canon++ |= c - '0';
X				break;
X
X			default:
X				canon++;
X				goto reswitch;
X			}
X			break;
X		}
X	}
X#ifdef notdef
X	if (state != S_WORD && state != S_BLANK)
X		error(0, 0, "warning: unclosed quote");
X#endif
X	if (state != S_BLANK)
X		*canon = 0;
X	return (nw - wleft);
X}
END_OF_lib/split.c
if test 4603 -ne `wc -c <lib/split.c`; then
    echo shar: \"lib/split.c\" unpacked with wrong size!
fi
chmod +x lib/split.c
# end of overwriting check
fi
if test -f lib/strsave.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/strsave.c\"
else
echo shar: Extracting \"lib/strsave.c\" \(522 characters\)
sed "s/^X//" >lib/strsave.c <<'END_OF_lib/strsave.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/*
X * Save a string in managed memory.
X */
X
Xchar	*malloc(), *realloc();
Xextern int errno;
X
Xchar *
Xstrsave(s)
X	register char *s;
X{
X	register int l = strlen(s) + 1;
X	register char *p = malloc((unsigned) l);
X
X	if (p == 0)
X		error(1, errno, "no room for %d bytes of string", l);
X	bcopy(s, p, l);
X	return (p);
X}
END_OF_lib/strsave.c
if test 522 -ne `wc -c <lib/strsave.c`; then
    echo shar: \"lib/strsave.c\" unpacked with wrong size!
fi
chmod +x lib/strsave.c
# end of overwriting check
fi
if test -f lib/tfm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/tfm.c\"
else
echo shar: Extracting \"lib/tfm.c\" \(2549 characters\)
sed "s/^X//" >lib/tfm.c <<'END_OF_lib/tfm.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/tfm.c,v 1.4 89/02/13 14:31:26 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * TFM file reading routines.
X *
X * TODO:
X *	finish
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "fio.h"
X#include "tfm.h"
X
Xchar	*malloc();
X
X#define	ALLOC(n, type)	((type *) malloc((unsigned) ((n) * sizeof (type))))
X
Xstatic trd_header();
Xstatic trd_ci();
Xstatic trd_fix();
X
Xint
Xreadtfmfile(f, t, stopafterwidth)
X	register FILE *f;
X	register struct tfmdata *t;
X	int stopafterwidth;	/* ??? */
X{
X	i32 nc;
X
X	if (trd_header(f, &t->t_hdr))
X		return (-1);
X	nc = t->t_hdr.th_ec - t->t_hdr.th_bc + 1;
X
X	t->t_ci = NULL;
X	t->t_width = NULL;
X	t->t_height = NULL;
X	t->t_depth = NULL;
X
X	(void) fseek(f, t->t_hdr.th_lh * 4L, 1);	/* XXX */
X
X	if ((t->t_ci = ALLOC(nc, struct char_info_word)) == NULL ||
X	    trd_ci(f, nc, t->t_ci) ||
X	    (t->t_width = ALLOC(t->t_hdr.th_nw, i32)) == NULL ||
X	    trd_fix(f, t->t_hdr.th_nw, t->t_width))
X		goto bad;
X	if (stopafterwidth)
X		return (0);
X	if ((t->t_height = ALLOC(t->t_hdr.th_nh, i32)) == NULL ||
X	    trd_fix(f, t->t_hdr.th_nh, t->t_height) ||
X	    (t->t_depth = ALLOC(t->t_hdr.th_nd, i32)) == NULL ||
X	    trd_fix(f, t->t_hdr.th_nd, t->t_depth))
X		goto bad;
X	return (0);
X	
X      bad:
X	if (t->t_ci != NULL) {
X	  free((char *) t->t_ci); (char *) t->t_ci = 0;
X	}
X	if (t->t_width != NULL) {
X	  free((char *) t->t_width); (char *) t->t_width = 0;
X	}
X	if (t->t_height != NULL) {
X	  free((char *) t->t_height); (char *) t->t_height = 0;
X	}
X	if (t->t_depth != NULL) {
X	  free((char *) t->t_depth); (char *) t->t_depth = 0;
X	}
X	return (-1);
X      }
X
Xstatic int
Xtrd_header(f, th)
X	register FILE *f;
X	register struct tfmheader *th;
X{
X	register i32 *p;
X
X	for (p = &th->th_lf; p <= &th->th_np; p++)
X		fGetWord(f, *p);
X	if (feof(f))
X		return (-1);
X	return (0);
X}
X
Xstatic int
Xtrd_ci(f, nc, ci)
X	register FILE *f;
X	register int nc;
X	register struct char_info_word *ci;
X{
X
X	while (--nc >= 0) {
X		ci->ci_width = fgetbyte(f);
X		ci->ci_h_d = fgetbyte(f);
X		ci->ci_i_t = fgetbyte(f);
X		ci->ci_remainder = fgetbyte(f);
X		ci++;
X	}
X	if (feof(f))
X		return (-1);
X	return (0);
X}
X
Xstatic int
Xtrd_fix(f, nf, p)
X	register FILE *f;
X	register int nf;
X	register i32 *p;
X{
X
X	while (--nf >= 0) {
X		fGetLong(f, *p);
X		p++;
X	}
X	if (feof(f))
X		return (-1);
X	return (0);
X}
END_OF_lib/tfm.c
if test 2549 -ne `wc -c <lib/tfm.c`; then
    echo shar: \"lib/tfm.c\" unpacked with wrong size!
fi
chmod +x lib/tfm.c
# end of overwriting check
fi
if test -f lib/tfmfont.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lib/tfmfont.c\"
else
echo shar: Extracting \"lib/tfmfont.c\" \(5607 characters\)
sed "s/^X//" >lib/tfmfont.c <<'END_OF_lib/tfmfont.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/tfmfont.c,v 1.5 89/02/13 14:31:27 grunwald Exp Locker: grunwald $";
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "types.h"
X#include "conv.h"
X#include "font.h"
X#include "tfm.h"
X
X/*
X * TFM font operations.  This defines three fonts:
X *
X *	box   - prints as little square boxes, outlining what TeX
X *		thinks is the character.
X *	blank - prints as entirely blank.
X *	invis - prints as entirely blank.
X *
X * The first two also complain that no font is available in the
X * requested size; these are intended to be used as a last resort
X * so that users can always print DVI files.  You should configure
X * in exactly one of box or blank.
X *
X * TODO:
X *	base box edge widths on Conversion.c_dpi
X */
X
Xstatic box_read();
Xstatic blank_read();
Xstatic invis_read();
Xstatic do_read();
Xstatic tfm_getgly();
Xstatic tfm_rasterise();
Xstatic tfm_freefont();
X
X	/* magnifications are unused in tfm fonts */
Xstruct	fontops boxops =	/* `boxtops'?  Is this a cereal driver? */
X	{ "box", 0.0, box_read, tfm_getgly, tfm_rasterise, tfm_freefont };
Xstruct	fontops blankops =
X	{ "blank", 0.0, blank_read, tfm_getgly, tfm_rasterise, tfm_freefont };
Xstruct	fontops invisops =
X	{ "invis", 0.0, invis_read, tfm_getgly, tfm_rasterise, tfm_freefont };
X
X/*
X * Local info.
X */
X
Xstruct tfm_details {
X	int	tfm_edge;		/* box edge widths, in pixels */
X	struct	conversion tfm_conv;	/* conv. from scaled pts to pixels */
X	struct	tfmdata tfm_data;	/* the TFM file data */
X};
X
X/*
X * Get the tfm_details from font f.
X */
X#define	ftotfm(f) ((struct tfm_details *) (f)->f_details)
X
Xextern	int errno;
Xchar	*malloc();
X
X/*
X * Read a Box font.
X */
Xstatic int
Xbox_read(f)
X	struct font *f;
X{
X
X	return (do_read(f, 0, 1));
X}
X
X/*
X * Read a Blank font.
X */
Xstatic int
Xblank_read(f)
X	struct font *f;
X{
X
X	return (do_read(f, 1, 1));
X}
X
X/*
X * Read an Invisible font.
X */
Xstatic int
Xinvis_read(f)
X	struct font *f;
X{
X
X	return (do_read(f, 1, 0));
X}
X
X/*
X * Read a TFM font.  It is blank if `blank'; complain if `complain'.
X */
Xstatic int
Xdo_read(f, blank, complain)
X	register struct font *f;
X	int blank, complain;
X{
X	register struct tfm_details *tfm;
X	FILE *fd;
X
X	if ((fd = fopen(f->f_path, "r")) == 0)
X		return (-1);
X	if ((tfm = (struct tfm_details *) malloc(sizeof (*tfm))) == NULL)
X		goto fail;
X	if (readtfmfile(fd, &tfm->tfm_data, blank))
X		goto fail;
X	if (blank)
X		tfm->tfm_edge = 0;
X	else {
X	  extern Conv Conversion;
X
X		tfm->tfm_edge = 2;	/* XXX should be based on dpi */
X		tfm->tfm_conv = Conversion;
X		tfm->tfm_conv.c_fromsp *= DMagFactor(f->f_scaled);
X					/* XXX !data abstraction */
X	}
X	if (FontHasGlyphs(f, tfm->tfm_data.t_hdr.th_bc,
X			  tfm->tfm_data.t_hdr.th_ec + 1))
X		goto fail;
X	f->f_details = (char *) tfm;
X	(void) fclose(fd);
X	if (complain)
X		error(0, 0, "Warning: no font for %s", Font_TeXName(f));
X	return (0);
X
Xfail:
X	(void) fclose(fd);
X	if (tfm != NULL) {
X	  free((char *) tfm); (char *) tfm = 0;
X	}
X	return (-1);
X}
X
X/*
X * Obtain the specified range of glyphs.
X */
Xstatic int
Xtfm_getgly(f, l, h)
X	register struct font *f;
X	int l;
X	register int h;
X{
X	register struct tfm_details *tfm = ftotfm(f);
X	register struct glyph *g;
X	register int i;
X	register struct char_info_word *ci;
X#define	t (&tfm->tfm_data)
X	i32 ScaleOneWidth();
X
X#define ftop(fix) cfromSP(&tfm->tfm_conv, ScaleOneWidth(fix, f->f_dvimag))
X
X	for (i = l; i < h; i++) {
X		ci = &t->t_ci[i - t->t_hdr.th_bc];
X		/* zero widths mark invalid characters */
X		if (ci->ci_width == 0)
X			continue;
X		g = f->f_gly[i];
X		g->g_flags = GF_VALID;
X		g->g_tfmwidth = t->t_width[UnSign8(ci->ci_width)];
X		if (tfm->tfm_edge != 0) {
X			g->g_xorigin = 0;
X			g->g_yorigin = ftop(t->t_height[T_CI_H(ci)]);
X			g->g_width = ftop(g->g_tfmwidth);
X			g->g_height = g->g_yorigin +
X				ftop(t->t_depth[T_CI_D(ci)]);
X		}
X	}
X	return (0);
X#undef t
X}
X
X/*
X * Obtain rasters for the specified glyphs.
X *
X * IGNORES tfm->tfm_edge: 2 HARDCODED FOR NOW
X */
Xstatic int
Xtfm_rasterise(f, l, h)
X	struct font *f;
X	int l, h;
X{
X	register struct glyph *g;
X	register char *p;
X	register int w, j, i;
X	struct tfm_details *tfm = ftotfm(f);
X#define EDGE 2
X
X	if (tfm->tfm_edge == 0)
X		return;
Xif (tfm->tfm_edge != 2) panic("tfm_rasterise");
X	for (i = l; i < h; i++) {
X		g = f->f_gly[i];
X		if ((g->g_flags & GF_VALID) == 0 || !HASRASTER(g))
X			continue;
X		w = (g->g_width + 7) >> 3;
X		p = malloc((unsigned) (g->g_height * w));
X		if (p == NULL)
X			return (-1);
X		g->g_raster = p;
X		g->g_rotation = ROT_NORM;
X		if (g->g_width < 2 * EDGE) {
X			w = 2 * EDGE - g->g_width;
X			for (j = g->g_height; --j >= 0;)
X				*p++ = 0xf0 << w;
X		} else {
X			bzero(p, g->g_height * w);
X			for (j = 0; j < g->g_height;) {
X				if (j < EDGE || j >= g->g_height - EDGE) {
X					register int k = w;
X
X					while (--k > 0)
X						*p++ = 0xff;
X					*p++ = 0xff << ((8 - g->g_width) & 7);
X					j++;
X					continue;
X				}
X				/* the following depends on EDGE==2 */
X				*p = 0xc0;
X				p += w - ((g->g_width & 7) == 1 ? 2 : 1);
X				*p++ |= 0xc0 >> ((g->g_width - EDGE) & 7);
X				if ((g->g_width & 7) == 1)
X					*p++ = 0x80;
X				/* end dependencies */
X				if (++j == EDGE && g->g_height >= 2 * EDGE) {
X					register int n = g->g_height - EDGE;
X
X					p += (n - j) * w;
X					j = n;
X				}
X			}
X		}
X	}
X	return (0);
X}
X
X/*
X * Discard the font details.
X */
Xstatic
Xtfm_freefont(f)
X	struct font *f;
X{
X
X  free(f->f_details); f->f_details = 0;
X}
END_OF_lib/tfmfont.c
if test 5607 -ne `wc -c <lib/tfmfont.c`; then
    echo shar: \"lib/tfmfont.c\" unpacked with wrong size!
fi
chmod +x lib/tfmfont.c
# end of overwriting check
fi
echo shar: End of archive 6 \(of 6\).
cp /dev/null ark6isdone
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