[comp.sources.x] v03i038: dvi previewer, Part02/03

mikew@wyse.wyse.com (Mike Wexler) (03/08/89)

Submitted-by: vojta@bosco.berkeley.edu
Posting-number: Volume 3, Issue 38
Archive-name: xdvi/part02

#! /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 2 (of 3)."
# Contents:  Makefile dvi_draw.c dvi_init.c tpic.c xdvi.man.sed
#   xdvi_mask.h
# Wrapped by mikew@wyse on Tue Mar  7 10:42:21 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(7074 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space.  Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# X Window System Makefile generated from template file Imake.tmpl
X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
X#
X# Do not change the body of the imake template file.  Server-specific
X# parameters may be set in the appropriate .macros file; site-specific
X# parameters (but shared by all servers) may be set in site.def.  If you
X# make any changes, you'll need to rebuild the makefiles using
X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in
X# the top level directory.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit Sun.macros to change
X
X# platform:  $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $
X# operating system:   SunOS 3.4
X
XBOOTSTRAPCFLAGS =
X             AS = as
X             CC = cc
X            CPP = /lib/cpp
X             LD = ld
X           LINT = lint
X        INSTALL = install
X           TAGS = ctags
X             RM = rm -f
X             MV = mv
X             LN = ln -s
X         RANLIB = ranlib
XRANLIBINSTFLAGS = -t
X             AR = ar clq
X             LS = ls
X       LINTOPTS = -xz
X    LINTLIBFLAG = -C
X           MAKE = make
XSTD_CPP_DEFINES =
X    STD_DEFINES =
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $
X
X###########################################################################
X# definitions common to all Makefiles - do not edit
X
X          SHELL =  /bin/sh
X
X        DESTDIR = /global
X      USRLIBDIR = $(DESTDIR)/lib
X         BINDIR = $(DESTDIR)/bin/X11
X         INCDIR = $(DESTDIR)/include
X         ADMDIR = $(DESTDIR)/usr/adm
X         LIBDIR = $(USRLIBDIR)/X11
X     LINTLIBDIR = $(USRLIBDIR)/lint
X        FONTDIR = $(LIBDIR)/fonts
X       XINITDIR = $(LIBDIR)/xinit
X         XDMDIR = $(LIBDIR)/xdm
X         UWMDIR = $(LIBDIR)/uwm
X         AWMDIR = $(LIBDIR)/awm
X         TWMDIR = $(LIBDIR)/twm
X          DTDIR = $(LIBDIR)/dt
X        MANPATH = /usr/man
X  MANSOURCEPATH = $(MANPATH)/man
X         MANDIR = $(MANSOURCEPATH)n
X      LIBMANDIR = $(MANSOURCEPATH)n3
X    XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X   INSTBINFLAGS = -m 0755
X   INSTUIDFLAGS = -m 4755
X   INSTLIBFLAGS = -m 0664
X   INSTINCFLAGS = -m 0444
X   INSTMANFLAGS = -m 0444
X   INSTAPPFLAGS = -m 0444
X  INSTKMEMFLAGS = -m 4755
X        FCFLAGS = -t
X    CDEBUGFLAGS = -O
X
X        PATHSEP = /
X         DEPEND = $(BINDIR)/makedepend
X          IMAKE = $(BINDIR)/imake
X            RGB = $(LIBDIR)/rgb
X             FC = $(BINDIR)/bdftosnf
X      MKFONTDIR = $(BINDIR)/mkfontdir
X      MKDIRHIER = $(BINDIR)/mkdirhier.sh
X
X         CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
X      LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
X        LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
X
X       IRULESRC = $(LIBDIR)/imake.includes
X
X   EXTENSIONLIB = $(USRLIBDIR)/libext.a
X           XLIB = $(USRLIBDIR)/libX11.a
X         XMULIB = $(USRLIBDIR)/libXmu.a
X        OLDXLIB = $(USRLIBDIR)/liboldX.a
X       XTOOLLIB = $(USRLIBDIR)/libXt.a
X         XAWLIB = $(USRLIBDIR)/libXaw.a
X       LINTXLIB = $(USRLIBDIR)/lint/llib-lX11.ln
X        LINTXMU = $(USRLIBDIR)/lint/llib-lXmu.ln
X      LINTXTOOL = $(USRLIBDIR)/lint/llib-lXt.ln
X        LINTXAW = $(USRLIBDIR)/lint/llib-lXaw.ln
X       INCLUDES = -I$(INCDIR)
X      MACROFILE = Sun.macros
X   ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
X			$(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
X  IMAKE_DEFINES =
X      IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
X			-s Makefile $(IMAKE_DEFINES)
X         RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
X			.emacs_* tags TAGS make.log MakeOut
X
X###########################################################################
X# rules:  $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
XFONT_PATH=TEXFONTS
XDEFAULT_FONT_PATH=/usr/local/tex/fonts
XFONTFORMATS_C=gf.c pk.c pxl.c
XFONTFORMATS_O=gf.o pk.o pxl.o
X
XDEFINES=-DBMSHORT \
X		    -DFONT_PATH=\"$(FONT_PATH)\" \
X		    -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\"
XSYSLAST_LIBRARIES=-lXaw -lXmu -lXt -lX11 -lm
XSRCS=xdvi.c dvi_init.c dvi_draw.c $(FONTFORMATS_C) pxl_open.c tpic.c
XOBJS=xdvi.o dvi_init.o dvi_draw.o $(FONTFORMATS_O) pxl_open.o tpic.o
X
X PROGRAM = xdvi
X
Xall:: xdvi
X
Xxdvi: $(OBJS) $(LOCAL_LIBRARIES)
X	$(RM) $@
X	$(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)
X
Xrelink::
X	$(RM) $(PROGRAM)
X	$(MAKE) $(MFLAGS) $(PROGRAM)
X
Xinstall:: xdvi
X	$(INSTALL) -c $(INSTALLFLAGS) xdvi $(BINDIR)
X
Xinstall.man:: xdvi.man
X	$(INSTALL) -c $(INSTMANFLAGS) xdvi.man $(MANDIR)/xdvi.n
X
Xdepend:: $(DEPEND)
X
Xdepend::
X	$(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)
X
X$(DEPEND):
X	@echo "making $@"; \
X	cd $(DEPENDSRC); $(MAKE)
X
Xclean::
X	$(RM) $(PROGRAM)
X
Xtable.h: mktable
X	mktable > table.h
X
Xmktable: mktable.c
X	$(CC) $(CFLAGS) -o mktable mktable.c
X
Xxdvi.man:
X	sed -e "s;%%FONT_PATH%%;$(FONT_PATH);g" \
X	    -e "s;%%DEFAULT_FONT_PATH%%;$(DEFAULT_FONT_PATH);g" \
X	    < xdvi.man.sed \
X	    > xdvi.man
X
Xclean::
X	$(RM) mktable table.h xdvi.man
X
Xlint::
X	lint $(INCLUDES) $(DEFINES) $(SRCS)
X
X###########################################################################
X# Imake.tmpl common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X	$(RM_CMD) \#*
X
XMakefile:: $(IMAKE)
X
XMakefile:: Imakefile \
X	$(IRULESRC)/Imake.tmpl \
X	$(IRULESRC)/Imake.rules \
X	$(IRULESRC)/site.def \
X	$(IRULESRC)/$(MACROFILE)
X	-@if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP)
X
X$(IMAKE):
X	@echo "making $@"; \
X	cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)
X
Xtags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X	@echo "install done"
X
Xinstall.man::
X	@echo "install.man done"
X
XMakefiles::
X
X###########################################################################
X# dependencies generated by makedepend
X
END_OF_FILE
if test 7074 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'dvi_draw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dvi_draw.c'\"
else
echo shar: Extracting \"'dvi_draw.c'\" \(14046 characters\)
sed "s/^X//" >'dvi_draw.c' <<'END_OF_FILE'
X/*
X * DVI previewer for X.
X *
X * Eric Cooper, CMU, September 1985.
X *
X * Code derived from dvi-imagen.c.
X *
X * Modification history:
X * 1/1986	Modified for X.10 by Bob Scheifler, MIT LCS.
X * 7/1988	Modified for X.11 by Mark Eichin, MIT
X * 12/1988	Added 'R' option, toolkit, magnifying glass
X *			--Paul Vojta, UC Berkeley.
X * 2/1989	Added tpic support	--Jeffrey Lee, U of Toronto
X *
X *	Compilation options:
X *	X10	compile for X10
X *	MSBITFIRST	store bitmaps internally in with significant bit first
X *	BMSHORT	store bitmaps in shorts instead of bytes
X *	BMLONG	store bitmaps in longs instead of bytes
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "xdvi.h"
X#include "dvi.h"
X
X#define X_PAGE_OFFSET	ROUNDUP(pixels_per_inch, shrink_factor)
X#define Y_PAGE_OFFSET	ROUNDUP(pixels_per_inch, shrink_factor)
X
Xstruct frame	*stack;
Xint	stackp;
X
X#ifndef	BMLONG
X#ifndef	BMSHORT
Xunsigned char	bit_masks[9] = {
X	0x0,	0x1,	0x3,	0x7,
X	0xf,	0x1f,	0x3f,	0x7f,
X	0xff
X};
X#else	BMSHORT
Xunsigned short	bit_masks[17] = {
X	0x0,	0x1,	0x3,	0x7,
X	0xf,	0x1f,	0x3f,	0x7f,
X	0xff,	0x1ff,	0x3ff,	0x7ff,
X	0xfff,	0x1fff,	0x3fff,	0x7fff,
X	0xffff
X};
X#endif	BMSHORT
X#else	BMLONG
Xunsigned long	bit_masks[33] = {
X	0x0,		0x1,		0x3,		0x7,
X	0xf,		0x1f,		0x3f,		0x7f,
X	0xff,		0x1ff,		0x3ff,		0x7ff,
X	0xfff,		0x1fff,		0x3fff,		0x7fff,
X	0xffff,		0x1ffff,	0x3ffff,	0x7ffff,
X	0xfffff,	0x1fffff,	0x3fffff,	0x7fffff,
X	0xffffff,	0x1ffffff,	0x3ffffff,	0x7ffffff,
X	0xfffffff,	0x1fffffff,	0x3fffffff,	0x7fffffff,
X	0xffffffff
X};
X#endif	BMLONG
X
Xchar	*malloc();
XBoolean	check_dvi_file();
Xvoid	applicationDoSpecial();
X
Xstatic
Xprint_bitmap(bitmap)
X	register struct bitmap *bitmap;
X{
X	register BMUNIT *ptr = (BMUNIT *) bitmap->bits;
X	register int x, y, i;
X
X	if (ptr == NULL) oops("print_bitmap called with null pointer.");
X	Printf("w = %d, h = %d, bytes wide = %d\n",
X		bitmap->w, bitmap->h, bitmap->bytes_wide);
X	for (y = 0; y < bitmap->h; ++y) {
X	    for (x = bitmap->bytes_wide; x > 0; x -= BYTES_PER_BMUNIT) {
X#ifndef	MSBITFIRST
X		for (i = 0; i < BITS_PER_BMUNIT; ++i)
X#else	MSBITFIRST
X		for (i = BITS_PER_BMUNIT - 1; i >= 0; --i)
X#endif	MSBITFIRST
X		    putchar((*ptr & (1 << i)) ? '@' : ' ');
X		++ptr;
X	    }
X	    putchar('\n');
X	}
X}
X
Xstatic	void
Xprint_char(ch, g)
X	ubyte ch;
X	struct glyph *g;
X{
X	Printf("char %d", ch);
X	if (isprint(ch))
X		Printf(" (%c)", ch);
X	putchar('\n');
X	Printf("x = %d, y = %d, dvi = %d\n",
X		g->x, g->y, g->dvi_adv);
X	print_bitmap(&g->bitmap);
X}
X
Xstatic	char	*dvi_table1[] = {
X	"SET1", NULL, NULL, NULL, "SETRULE", "PUT1", NULL, NULL,
X	NULL, "PUTRULE", "NOP", "BOP", "EOP", "PUSH", "POP", "RIGHT1",
X	"RIGHT2", "RIGHT3", "RIGHT4", "W0", "W1", "W2", "W3", "W4",
X	"X0", "X1", "X2", "X3", "X4", "DOWN1", "DOWN2", "DOWN3",
X	"DOWN4", "Y0", "Y1", "Y2", "Y3", "Y4", "Z0", "Z1",
X	"Z2", "Z3", "Z4"};
X
Xstatic	char	*dvi_table2[] = {
X	"FNT1", "FNT2", "FNT3", "FNT4", "XXX1", "XXX2", "XXX3", "XXX4",
X	"FNTDEF1", "FNTDEF2", "FNTDEF3", "FNTDEF4", "PRE", "POST", "POSTPOST",
X	NULL, NULL, NULL, NULL, NULL, NULL};
X
Xstatic	void
Xprint_dvi(ch)
X	ubyte ch;
X{
X	char *s;
X
X	Printf("%4d %4d ", PXL_H, PXL_V);
X	if (ch <= SETCHAR0 + 127) {
X		Printf("SETCHAR%-3d", ch - SETCHAR0);
X		if (isprint(ch))
X			Printf(" (%c)", ch);
X		putchar('\n');
X		return;
X	}
X	else if (ch < FNTNUM0) s = dvi_table1[ch - 128];
X	else if (ch <= FNTNUM0 + 63) {
X		Printf("FNTNUM%d\n", ch - FNTNUM0);
X		return;
X	}
X	else s = dvi_table2[ch - (FNTNUM0+64)];
X	if (s) puts(s);
X	else oops("Unknown op-code %d, offset %d", ch, ftell(dvi_file)-1);
X}
X
X/**
X **	Allocate bitmap for given font and character
X **/
X
Xvoid
Xalloc_bitmap(bitmap, fontname, ch)
X    register struct bitmap *bitmap;
X    char *fontname;
X    ubyte ch;
X{
X	/* width must be multiple of 16 bits for raster_op */
X	bitmap->bytes_wide = ROUNDUP(bitmap->w, BITS_PER_BMUNIT) *
X	    BYTES_PER_BMUNIT;
X	bitmap->bits = malloc((unsigned) bitmap->bytes_wide * bitmap->h);
X	if (bitmap->bits == NULL)
X	    oops("Can't allocate bitmap for character %d of font %s (%d by %d)",
X		ch, fontname, bitmap->w, bitmap->h);
X}
X
Xchar	sample_count[]	= {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
X
Xstatic	int
Xsample(bits, bytes_wide, bit_skip, w, h)
X	BMUNIT	*bits;
X	int	bytes_wide, bit_skip, w, h;
X{
X	BMUNIT	*ptr, *endp;
X	register BMUNIT *cp;
X	int	bits_left;
X	register int n, bit_shift, wid;
X
X	ptr = bits + bit_skip / BITS_PER_BMUNIT;
X	endp = ADD(bits, h * bytes_wide);
X	bits_left = w;
X#ifndef	MSBITFIRST
X	bit_shift = bit_skip % BITS_PER_BMUNIT;
X#else	MSBITFIRST
X	bit_shift = BITS_PER_BMUNIT - bit_skip % BITS_PER_BMUNIT;
X#endif	MSBITFIRST
X	n = 0;
X	while (bits_left) {
X#ifndef	MSBITFIRST
X	    wid = BITS_PER_BMUNIT - bit_shift;
X#else	MSBITFIRST
X	    wid = bit_shift;
X#endif	MSBITFIRST
X	    if (wid > bits_left) wid = bits_left;
X	    if (wid > 4) wid = 4;
X#ifdef	MSBITFIRST
X	    bit_shift -= wid;
X#endif	MSBITFIRST
X	    for (cp = ptr; cp < endp; cp = ADD(cp, bytes_wide))
X		n += sample_count[(*cp >> bit_shift) & bit_masks[wid]];
X#ifndef	MSBITFIRST
X	    bit_shift += wid;
X	    if (bit_shift == BITS_PER_BMUNIT) {
X		bit_shift = 0;
X		++ptr;
X	    }
X#else	MSBITFIRST
X	    if (bit_shift == 0) {
X		bit_shift = BITS_PER_BMUNIT;
X		++ptr;
X	    }
X#endif	MSBITFIRST
X	    bits_left -= wid;
X	}
X	return n;
X}
X
Xstatic	void
Xshrink_glyph(g)
X	register struct glyph *g;
X{
X	int shrunk_bytes_wide, shrunk_height;
X	int rows_left, rows, init_cols, cols_left;
X	register int cols;
X	BMUNIT *old_ptr, *new_ptr;
X	register BMUNIT m, *cp;
X	int min_sample = shrink_factor * shrink_factor * density / 100;
X
X	/* These machinations ensure that the character is shrunk according to
X	   its hot point, rather than its upper left-hand corner. */
X	g->x2 = g->x / shrink_factor;
X	init_cols = g->x - g->x2 * shrink_factor;
X	if (init_cols <= 0) init_cols += shrink_factor;
X	else ++g->x2;
X	g->bitmap2.w = g->x2 + ROUNDUP(g->bitmap.w - g->x, shrink_factor);
X	/* include row zero with the positively numbered rows */
X	cols = g->y + 1; /* spare register variable */
X	g->y2 = cols / shrink_factor;
X	rows = cols - g->y2 * shrink_factor;
X	if (rows <= 0) {
X	    rows += shrink_factor;
X	    --g->y2;
X	}
X	g->bitmap2.h = shrunk_height = g->y2 +
X	    ROUNDUP(g->bitmap.h - cols, shrink_factor) + 1;
X	if (g->bitmap2.bits) free(g->bitmap2.bits);
X	alloc_bitmap(&g->bitmap2, "(shrunken)", 0);
X	old_ptr = (BMUNIT *) g->bitmap.bits;
X	new_ptr = (BMUNIT *) g->bitmap2.bits;
X	shrunk_bytes_wide = g->bitmap2.bytes_wide;
X	rows_left = g->bitmap.h;
X	bzero((char *) new_ptr, shrunk_bytes_wide * shrunk_height);
X	while (rows_left) {
X	    if (rows > rows_left) rows = rows_left;
X	    cols_left = g->bitmap.w;
X#ifndef	MSBITFIRST
X	    m = (1 << 0);
X#else	MSBITFIRST
X	    m = (1 << (BITS_PER_BMUNIT-1));
X#endif	MSBITFIRST
X	    cp = new_ptr;
X	    cols = init_cols;
X	    while (cols_left) {
X		if (cols > cols_left) cols = cols_left;
X		if (sample(old_ptr, g->bitmap.bytes_wide,
X			g->bitmap.w - cols_left, cols, rows) >= min_sample)
X		    *cp |= m;
X#ifndef	MSBITFIRST
X		if (m == (BMUNIT)(1 << (BITS_PER_BMUNIT-1))) {
X		    m = (1 << 0);
X		    ++cp;
X		}
X		else m <<= 1;
X#else	MSBITFIRST
X		if (m == (1 << 0)) {
X		    m = (1 << (BITS_PER_BMUNIT-1));
X		    ++cp;
X		}
X		else m >>= 1;
X#endif	MSBITFIRST
X		cols_left -= cols;
X		cols = shrink_factor;
X	    }
X	    *((char **) &new_ptr) += shrunk_bytes_wide;
X	    *((char **) &old_ptr) += rows * g->bitmap.bytes_wide;
X	    rows_left -= rows;
X	    rows = shrink_factor;
X	}
X	g->y2 = g->y / shrink_factor;
X	if (debug & DBG_BITMAP)
X	    print_bitmap(&g->bitmap2);
X}
X
Xstatic	void
Xset_char(ch)
X	ubyte ch;
X{
X	register struct glyph *g;
X
X	g = &current_font->glyph[ch];
X	if (g->bitmap.bits == NULL) {
X	    if (g->addr == NULL)
X		oops("Character %d not defined in font %s\n", ch,
X		    current_font->fontname);
X	    open_pxl_file(current_font);
X	    Fseek(current_font->file, g->addr, 0);
X	    (*current_font->read_char)(current_font, ch);
X	    if (debug & DBG_BITMAP) print_char(ch, g);
X	}
X
X	if (shrink_factor == 1)
X	    put_bitmap(&g->bitmap, (PXL_H - g->x), (PXL_V - g->y));
X	else {
X	    if (g->bitmap2.bits == NULL) {
X		shrink_glyph(g);
X	    }
X	    put_bitmap(&g->bitmap2, (PXL_H - g->x2), (PXL_V - g->y2));
X	}
X}
X
Xstatic	void
Xset_rule(h, w)
X	int h, w;
X{
X	/* (w,h) specifies lower left corner of rule box */
X	put_rectangle(PXL_H, PXL_V - h, w, h, False);
X}
X
X/**
X **	Close the pixel file for the least recently used font.
X **/
X
Xclose_a_file()
X{
X        register struct font *fontp;
X	struct font *f = NULL;
X
X	for (fontp = current_font; fontp != NULL; fontp = fontp->next)
X		if (fontp->file != NULL)
X                        f=fontp;
X	if (f == NULL)
X		oops("Can't find an open pixel file to close");
X	Fclose(f->file);
X	f->file = NULL;
X	++n_fonts_left;
X}
X
X/**
X **	Open a font file.
X **/
X
Xopen_pxl_file(fontp)
X	struct font *fontp;
X{
X	if (fontp->file == NULL) {
X	    if (n_fonts_left == 0)
X		close_a_file();
X	    fontp->file = fopen(fontp->filename, OPEN_MODE);
X	    if (fontp->file == NULL)
X		oops("Font file disappeared:  %s\n", fontp->filename);
X	    --n_fonts_left;
X	}
X}
X
X/*
X * Find font #n and move it to the head of the list.
X */
Xstatic
Xchange_font(n)
X	unsigned long n;
X{
X        register struct font *fontp, **prev;
X
X	prev = &current_font;
X	for (;;) {
X	    fontp = *prev;
X	    if (fontp == NULL) oops("Non-existent font #%d", n);
X	    if (fontp->TeXnumber == n) break;
X	    prev = &(fontp->next);
X	}
X	*prev = fontp->next;
X	fontp->next = current_font;
X	current_font = fontp;
X}
X
Xstatic
Xspecial(nbytes)
X	long	nbytes;
X{
X	static	char	*cmd	= NULL;
X	static	long	cmdlen	= -1;
X
X	if (cmdlen < nbytes) {
X	    if (cmd) free(cmd);
X	    cmd = malloc((unsigned) nbytes+1);
X	    if (cmd == NULL)
X		oops("Can't allocate memory for special (%d bytes)", nbytes);
X	    cmdlen = nbytes;
X	}
X	Fread(cmd, sizeof(char), (int) nbytes, dvi_file);
X	cmd[nbytes] = '\0';
X	applicationDoSpecial(cmd);
X}
X
Xdraw_page()
X{
X        ubyte ch;
X
X	/* Check for changes in dvi file. */
X	if (!check_dvi_file()) return;
X
X	put_border(0, 0, PAPER_WIDTH, PAPER_HEIGHT, 1);
X
X	Fseek(dvi_file, page_offset[current_page], 0);
X	for (;;) {
X		ch = one(dvi_file);
X		if (debug & DBG_DVI)
X			print_dvi(ch);
X		if (ch <= SETCHAR0 + 127) {
X			set_char(ch);
X			DVI_H += current_font->glyph[ch].dvi_adv;
X		} else if (FNTNUM0 <= ch  &&  ch <= FNTNUM0 + 63) {
X			change_font((unsigned long) (ch - FNTNUM0));
X		} else {
X			long a, b;
X			ubyte ch1;
X
X			switch (ch) {
X			    case SET1:
X			    case PUT1:
X				ch1 = one(dvi_file);
X				if (ch1 >= MAXCHARS)
X				    oops("Character code too large:  %d", ch1);
X				set_char(ch1);
X				if (ch == SET1)
X				    DVI_H += current_font->glyph[ch1].dvi_adv;
X				break;
X
X			    case SETRULE:
X				a = spellfour(dvi_file);
X				b = spellfour(dvi_file);
X				if (a > 0  &&  b > 0)
X				    set_rule(pixel_round(a), pixel_round(b));
X				DVI_H += b;
X				break;
X
X			    case PUTRULE:
X				a = spellfour(dvi_file);
X				b = spellfour(dvi_file);
X				if (a > 0  &&  b > 0)
X				    set_rule(pixel_round(a), pixel_round(b));
X				break;
X
X			    case NOP:
X				break;
X
X			    case BOP:
X				Fseek(dvi_file, (long) 11*4, 1);
X				stackp = 0;
X				DVI_H = pxl2spell(X_PAGE_OFFSET);
X				DVI_V = pxl2spell(Y_PAGE_OFFSET);
X				PXL_V = Y_PAGE_OFFSET;
X				WW = XX = YY = ZZ = 0;
X				break;
X
X			    case EOP:
X				if (stackp > 0)
X				    oops("Stack not empty at EOP (%d)", stackp);
X				return;
X
X			    case PUSH:
X				stackp++;
X				if (stackp > maxstack)
X				    oops("More PUSHes than were promised");
X				stack[stackp] = stack[stackp - 1];
X				break;
X
X			    case POP:
X				stackp--;
X				if (stackp < 0)
X				    oops("More POPs than PUSHes");
X				break;
X
X			    case RIGHT1:
X			    case RIGHT2:
X			    case RIGHT3:
X			    case RIGHT4:
X				DVI_H += spellnum(dvi_file, ch - RIGHT1 + 1);
X				break;
X
X			    case X1:
X			    case X2:
X			    case X3:
X			    case X4:
X				XX = spellnum(dvi_file, ch - X0);
X			    case X0:
X				DVI_H += XX;
X				break;
X
X			    case W1:
X			    case W2:
X			    case W3:
X			    case W4:
X				WW = spellnum(dvi_file, ch - W0);
X			    case W0:
X				DVI_H += WW;
X				break;
X
X			    case Y1:
X			    case Y2:
X			    case Y3:
X			    case Y4:
X				YY = spellnum(dvi_file, ch - Y0);
X			    case Y0:
X				DVI_V += YY;
X				PXL_V = pixel_conv(DVI_V);
X				break;
X
X			    case Z1:
X			    case Z2:
X			    case Z3:
X			    case Z4:
X				ZZ = spellnum(dvi_file, ch - Z0);
X			    case Z0:
X				DVI_V += ZZ;
X				PXL_V = pixel_conv(DVI_V);
X				break;
X
X			    case DOWN1:
X			    case DOWN2:
X			    case DOWN3:
X			    case DOWN4:
X				DVI_V += spellnum(dvi_file, ch - DOWN1 + 1);
X				PXL_V = pixel_conv(DVI_V);
X				break;
X
X			    case FNT1:
X			    case FNT2:
X			    case FNT3:
X			    case FNT4:
X				change_font(num(dvi_file, ch - FNT1 + 1));
X				break;
X
X			    case XXX1:
X			    case XXX2:
X			    case XXX3:
X			    case XXX4:
X				a = num(dvi_file, ch - XXX1 + 1);
X				if(a > 0)
X				    special(a);
X				break;
X
X			    case FNTDEF1:
X			    case FNTDEF2:
X			    case FNTDEF3:
X			    case FNTDEF4:
X				Fseek(dvi_file, (long) (12 + ch - FNTDEF1 + 1),
X				    1);
X				a = one(dvi_file) + one(dvi_file);
X				Fseek(dvi_file, (long) a, 1);
X				break;
X
X			    case PRE:
X				oops("Shouldn't happen: PRE encountered.");
X				break;
X
X			    case POST:
X				oops("Shouldn't happen: POST encountered.");
X				break;
X
X			    case POSTPOST:
X				oops("Unexpected POSTPOST encountered.");
X				break;
X
X			    default:
X				oops("Unknown op-code %d, offset %d",
X					ch, ftell(dvi_file));
X			} /* end switch*/
X		} /* end else (ch not a SETCHAR or FNTNUM) */
X	} /* end for */
X}
X
X/*
X**
X**      Read size bytes from the FILE fp, constructing them into a
X**      signed/unsigned integer.
X**
X*/
Xunsigned long
Xnum(fp, size)
X	register FILE *fp;
X	register ubyte size;
X{
X        register int i;
X	register long x;
X
X	x = 0;
X	for (i = 0; i < size; i += 1)
X		x = (x<<8) + (unsigned) (getc(fp) & 0xff);
X	return (x);
X}
X
Xlong
Xsnum(fp, size)
X	register FILE *fp;
X	register ubyte size;
X{
X        register int i;
X	register long x;
X
X	x = getc(fp) & 0xff;
X	if (x & 0x80)
X		x -= 0x100;
X	for (i = 1; i < size; i += 1)
X		x = (x<<8) + (unsigned) (getc(fp) & 0xff);
X	return (x);
X}
X
X/* VARARGS1 */
Xoops(message, a, b, c, d, e, f)
X	char *message;
X{
X	Fprintf(stderr, "%s: ", prog);
X	Fprintf(stderr, message, a, b, c, d, e, f);
X	putc('\n', stderr);
X	exit(1);
X}
END_OF_FILE
if test 14046 -ne `wc -c <'dvi_draw.c'`; then
    echo shar: \"'dvi_draw.c'\" unpacked with wrong size!
fi
# end of 'dvi_draw.c'
fi
if test -f 'dvi_init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dvi_init.c'\"
else
echo shar: Extracting \"'dvi_init.c'\" \(10018 characters\)
sed "s/^X//" >'dvi_init.c' <<'END_OF_FILE'
X/*
X * DVI previewer for X.
X *
X * Eric Cooper, CMU, September 1985.
X *
X * Code derived from dvi-imagen.c.
X *
X * Modification history:
X * 1/1986	Modified for X.10 by Bob Scheifler, MIT LCS.
X * 7/1988	Modified for X.11 by Mark Eichin, MIT
X * 12/1988	Added 'R' option, toolkit, magnifying glass
X *			--Paul Vojta, UC Berkeley.
X * 2/1989	Added tpic support	--Jeffrey Lee, U of Toronto
X *
X *	Compilation options:
X *	X10	compile for X10
X *	MSBITFIRST	store bitmaps internally in with significant bit first
X *	BMSHORT	store bitmaps in shorts instead of bytes
X *	BMLONG	store bitmaps in longs instead of bytes
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "xdvi.h"
X#include "dvi.h"
X#include <sys/stat.h>
X
X#define	dvi_oops(str)	longjmp(dvi_env, (int) str);
X
Xstatic	struct stat fstatbuf;		/* mechanism to see if file was */
Xtime_t	dvi_time;			/* modified since last usage */
X
Xstruct font *current_font = NULL;	/* ptr into linked list of fonts */
X
Xstatic	Boolean	font_not_found;
Xstatic	struct font **old_fonts;	/* used by read_postamble */
X
Xint	n_fonts_left	= 32767;	/* for LRU management of fonts */
X
X/*
X * DVI preamble and postamble information.
X */
Xint	current_page;
XBoolean	spec_warn;
Xint	total_pages;
Xdouble	fraction;
Xint	maxstack;
Xstatic	char	job_id[300];
Xstatic	long	numerator, denominator, magnification;
X
X/*
X * Table of page offsets in DVI file, indexed by page number - 1.
X * Initialized in prepare_pages().
X */
Xlong	*page_offset;
X
X/*
X * Offset in DVI file of last page, set in read_postamble().
X */
Xstatic	long	last_page_offset;
X
Xchar	*malloc(), *sprintf();
XFILE	*pxl_open();
X
Xstatic	Boolean
Xdefine_new_font(fontp)
X	register struct font *fontp;
X{
X	read_font_index_proc read_font_index;
X
X	if (n_fonts_left == 0)
X	    close_a_file();
X	fontp->file = pxl_open(font_path, fontp->fontname, fontp->size,
X	    (fontp->size + 2) / 5, &fontp->filename, &read_font_index);
X	if (fontp->file == NULL) {
X	    Fprintf(stderr, "%s at %d dpi [not found]\n", fontp->fontname,
X		(fontp->size + 2) / 5);
X	    font_not_found = True;
X	    return(False);
X	}
X	(*read_font_index)(fontp);
X	--n_fonts_left;
X	return(True);
X}
X
X/*
X *      define_font reads the rest of the fntdef command and then reads in
X *      the specified pixel file, adding it to the global linked-list holding
X *      all of the fonts used in the job.
X */
Xstatic
Xdefine_font(cmnd)
X	ubyte cmnd;
X{
X        register struct font *fontp;
X	struct font **fontpp = old_fonts;
X	struct font *fontp1;
X	int len;
X	int design;
X	int unmodsize;
X	float realsize;
X	int size;
X
X	fontp = (struct font *) malloc((unsigned) sizeof(struct font));
X	if (fontp == NULL)
X		oops("Can't allocate memory for font");
X	fontp->TeXnumber = num(dvi_file, (ubyte) cmnd - FNTDEF1 + 1);
X	(void) four(dvi_file);	/* checksum */
X	fontp->scale = four(dvi_file);
X	design = four(dvi_file);
X	len = one(dvi_file) + one(dvi_file);
X	fontp->fontname = malloc((unsigned) len + 1);
X	Fread(fontp->fontname, sizeof(char), len, dvi_file);
X	fontp->fontname[len] = '\0';
X	if(debug & DBG_PK)
X	  Printf("Define font \"%s\" scale=%d design=%d\n",
X	    fontp->fontname, fontp->scale, design);
X/*
X *	In the actual implementation, scaled-size/design-size hasn't been
X *	stored with sufficient precision, hence the messing around to find
X *	its actual value.
X */
X	realsize = (magnification/1000.)*((float) fontp->scale / design);
X	unmodsize = (realsize * 1000) + 0.5;
X	/* a real hack to correct for rounding in some cases */
X	switch (unmodsize) {
X	    case 1095:
X		realsize = 1.095445;	/* stephalf */
X		break;
X	    case 1315:
X		realsize = 1.314534;	/* stepihalf */
X		break;
X	    case 2074:
X		realsize = 2.0736;	/* stepiv */
X		break;
X	    case 2488:
X		realsize = 2.48832;	/* stepv */
X		break;
X	    case 2986:
X		realsize = 2.985984;	/* stepiv */
X		break;
X	}
X	/*
X	 * the remaining magnification steps are represented
X	 * with sufficient accuracy already
X	 */
X	fontp->size = size = (realsize * pixels_per_inch * 5) + 0.5;
X	fontp->scale = fontp->scale * fraction;
X	/*
X	 * reuse font if possible
X	 */
X	for (;;) {
X	    fontp1 = *fontpp;
X	    if (fontp1 == NULL) {
X		if (!define_new_font(fontp)) return;
X		break;
X	    }
X	    if (strcmp(fontp->fontname, fontp1->fontname) == 0
X		    && size == fontp1->size) {
X		*fontpp = fontp1->next;
X		free(fontp->fontname);
X		free((char *) fontp);
X		fontp = fontp1;
X		if (list_fonts)
X		    fputs("(reusing) ",stdout);
X		break;
X	    }
X	    fontpp = &fontp1->next;
X	}
X
X	if (old_fonts == &current_font) old_fonts = &fontp->next;
X	fontp->next = current_font;
X	current_font = fontp;
X	if (list_fonts)
X	    puts(fontp->fontname);
X}
X
X/*
X *      process_preamble reads the information in the preamble and stores
X *      it into global variables for later use.
X */
Xstatic
Xprocess_preamble()
X{
X        ubyte   k;
X
X        if (one(dvi_file) != PRE)
X		dvi_oops("DVI file doesn't start with preamble");
X	if (one(dvi_file) != 2)
X		dvi_oops("Wrong version of DVI output for this program");
X	numerator     = four(dvi_file);
X	denominator   = four(dvi_file);
X	magnification = four(dvi_file);
X	fraction = (((double) numerator * magnification)
X	                                 / ((double) denominator * 1000.));
X	fraction = fraction * (((long) pixels_per_inch)<<16) / 254000;
X	k = one(dvi_file);
X	Fread(job_id, sizeof(char), (int) k, dvi_file);
X	job_id[k] = '\0';
X}
X
X/*
X *      find_postamble locates the beginning of the postamble
X *	and leaves the file ready to start reading at that location.
X */
Xstatic
Xfind_postamble()
X{
X	ubyte byte;
X	long offset = -4;        /* At least 4 TRAILERS */
X
X	do {
X		offset -= 1;
X		Fseek(dvi_file, offset, 2);
X		byte = one(dvi_file);
X	} while (byte == TRAILER);
X	if (byte != 2)
X		dvi_oops("Wrong version of DVI output for this program");
X	offset -= 4;
X	Fseek(dvi_file, offset, 2);
X	Fseek(dvi_file, sfour(dvi_file), 0);
X}
X
X/*
X *      read_postamble reads the information in the postamble,
X *	storing it into global variables.
X *      It also takes care of reading in all of the pixel files for the fonts
X *      used in the job.
X */
Xstatic
Xread_postamble()
X{
X        ubyte   cmnd;
X
X        if (one(dvi_file) != POST)
X	    dvi_oops("Postamble doesn't begin with POST");
X	last_page_offset = four(dvi_file);
X	if (numerator != four(dvi_file)
X	          ||  denominator != four(dvi_file)
X		  ||  magnification != four(dvi_file))
X	    dvi_oops("Postamble doesn't match preamble");
X	(void) four(dvi_file);	/* page height */
X	(void) four(dvi_file);	/* page width */
X	maxstack = two(dvi_file);
X	total_pages = two(dvi_file);
X	old_fonts = &current_font;
X	font_not_found = False;
X	do {
X	    switch(cmnd = one(dvi_file)) {
X	        case FNTDEF1:
X	        case FNTDEF2:
X	        case FNTDEF3:
X	        case FNTDEF4:
X		    define_font(cmnd);
X		    break;
X		case POSTPOST:
X		    break;
X		default:
X		    dvi_oops("Non-fntdef command found in postamble");
X	    }
X	} while (cmnd != POSTPOST);
X	if (font_not_found)
X	    dvi_oops("Not all pixel files were found");
X	/*
X	 * free up fonts no longer in use
X	 */
X	{
X	    struct font *fontp = *old_fonts;
X	    struct font *fontp1;
X	    register struct glyph *g;
X	    *old_fonts = NULL;
X	    while (fontp != NULL) {
X		if (fontp->file != NULL) {
X		    Fclose(fontp->file);
X		    ++n_fonts_left;
X		}
X		free(fontp->fontname);
X		free(fontp->filename);
X		for (g = &fontp->glyph[0]; g < &fontp->glyph[MAXCHARS]; ++g) {
X		    if (g->bitmap.bits) free(g->bitmap.bits);
X		    if (g->bitmap2.bits) free(g->bitmap2.bits);
X		}
X		fontp1 = fontp->next;
X		free((char *) fontp);
X		fontp = fontp1;
X	    }
X	}
X}
X
Xstatic
Xprepare_pages()
X{
X	int i;
X
X        stack = (struct frame *)
X		malloc((unsigned) sizeof(struct frame) * (maxstack+1));
X        if (stack == NULL)
X		oops("Can't allocate stack space (%d frames)", maxstack);
X	page_offset = (long *) malloc((unsigned) total_pages * sizeof(long));
X        if (page_offset == NULL)
X		oops("Can't allocate page directory (%d pages)",
X			total_pages);
X	i = total_pages;
X	page_offset[--i] = last_page_offset;
X	Fseek(dvi_file, last_page_offset, 0);
X	/*
X	 * Follow back pointers through pages in the DVI file,
X	 * storing the offsets in the page_offset table.
X	 */
X	while (i > 0) {
X		Fseek(dvi_file, (long) (1+4+(9*4)), 1);
X		Fseek(dvi_file, page_offset[--i] = four(dvi_file), 0);
X	}
X}
X
Xinit_page()
X{
X	page_h = PAPER_HEIGHT;
X	page_w = PAPER_WIDTH;
X}
X
X/*
X *	init_dvi_file is the main subroutine for reading the startup information
X *	from the dvi file.
X */
Xstatic
Xinit_dvi_file()
X{
X	(void) fstat(fileno(dvi_file), &fstatbuf);
X	dvi_time = fstatbuf.st_mtime;
X	process_preamble();
X	find_postamble();
X	read_postamble();
X	prepare_pages();
X	init_page();
X	if (current_page >= total_pages) current_page = total_pages - 1;
X	spec_warn = True;
X}
X
X/**
X **	open_dvi_file opens the dvi file and calls init_dvi_file() to
X **	initialize it.
X **/
X
Xopen_dvi_file()
X{
X	char *errmsg;
X
X	if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
X		int n = strlen(dvi_name);
X		char *file = dvi_name;
X
X		if (strcmp(dvi_name + n - sizeof(".dvi") + 1, ".dvi") == 0) {
X			perror(dvi_name);
X			exit(1);
X		}
X		dvi_name = malloc((unsigned) n + sizeof(".dvi"));
X		Sprintf(dvi_name, "%s.dvi", file);
X		if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
X			perror(dvi_name);
X			exit(1);
X		}
X	}
X
X	if (errmsg = (char *) setjmp(dvi_env)) oops(errmsg);
X	init_dvi_file();
X}
X
X/**
X **	Release all shrunken bitmaps for all fonts.
X **/
X
Xreset_fonts()
X{
X        register struct font *f;
X	register struct glyph *g;
X
X	for (f = current_font; f != NULL; f = f->next)
X	    for (g = &f->glyph[0]; g < &f->glyph[MAXCHARS]; ++g)
X		if (g->bitmap2.bits) {
X		    free(g->bitmap2.bits);
X		    g->bitmap2.bits = NULL;
X		}
X}
X
X/**
X **	Check for changes in dvi file.
X **/
X
XBoolean
Xcheck_dvi_file()
X{
X	if (dvi_file == NULL || fstat(fileno(dvi_file), &fstatbuf) != 0
X	    || fstatbuf.st_mtime != dvi_time) {
X		if (dvi_file) Fclose(dvi_file);
X		free((char *) stack);
X		free((char *) page_offset);
X		dvi_file = fopen(dvi_name, OPEN_MODE);
X		if (dvi_file == NULL)
X		    dvi_oops("Cannot reopen dvi file.");
X		if (list_fonts) putchar('\n');
X		init_dvi_file();
X		redraw_page();
X		return False;
X	}
X	return True;
X}
END_OF_FILE
if test 10018 -ne `wc -c <'dvi_init.c'`; then
    echo shar: \"'dvi_init.c'\" unpacked with wrong size!
fi
# end of 'dvi_init.c'
fi
if test -f 'tpic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tpic.c'\"
else
echo shar: Extracting \"'tpic.c'\" \(10262 characters\)
sed "s/^X//" >'tpic.c' <<'END_OF_FILE'
X/*
X * Support drawing routines for TeXsun and TeX
X *
X *      Copyright, (C) 1987, 1988 Tim Morgan, UC Irvine
X *
X * At the time these routines are called, the values of hh and vv should
X * have been updated to the upper left corner of the graph (the position
X * the \special appears at in the dvi file).  Then the coordinates in the
X * graphics commands are in terms of a virtual page with axes oriented the
X * same as the Imagen and the SUN normally have:
X *
X *                      0,0
X *                       +-----------> +x
X *                       |
X *                       |
X *                       |
X *                      \ /
X *                       +y
X *
X * Angles are measured in the conventional way, from +x towards +y.
X * Unfortunately, that reverses the meaning of "counterclockwise"
X * from what it's normally thought of.
X *
X * A lot of floating point arithmetic has been converted to integer
X * arithmetic for speed.  In some places, this is kind-of kludgy, but
X * it's worth it.
X */
X
X#ifndef lint
Xstatic char *rcsid=
X  "$Header: dvi_draw.c,v 1.1 88/10/20 00:10:09 xwindows Exp $" ;
X#endif lint
X
X#include <math.h>
X#include <stdio.h>
X#include <ctype.h>
X
X#include "xdvi.h"
X
X#define	MAXPOINTS	300	/* Max points in a path */
X#define	TWOPI		(3.14159265359*2.0)
X#define	MAX_PEN_SIZE	7	/* Max pixels of pen width */
X
X
Xstatic	int xx[MAXPOINTS], yy[MAXPOINTS];	/* Path in milli-inches */
Xstatic	int path_len = 0;	/* # points in current path */
Xstatic	int pen_size = 1;	/* Pixel width of lines drawn */
X
Xstatic	Boolean	whiten = False, shade = False, blacken = False;
X
Xextern	void	dot_at(), line_btw(), do_attribute_path();
X
X/* Unfortunately, these values also appear in dvisun.c */
X#define	xRESOLUTION	(pixels_per_inch/shrink_factor)
X#define	yRESOLUTION	(pixels_per_inch/shrink_factor)
X
X
X/*
X * Issue warning messages
X */
Xstatic	void
XWarning(fmt, msg)
Xchar *fmt, *msg;
X{
X    Fprintf(stderr, fmt, msg);
X    (void) fputc('\n', stderr);
X}
X
X
X/*
X * Set the size of the virtual pen used to draw in milli-inches
X */
X/* ARGSUSED */
Xstatic	void
Xset_pen_size(cp)
Xchar *cp;
X{
X    int ps;
X
X    if (sscanf(cp, " %d ", &ps) != 1) {
X	Warning("illegal .ps command format: %s", cp);
X	return;
X    }
X    pen_size = (ps*(xRESOLUTION+yRESOLUTION) + 1000) / 2000;
X    if (pen_size < 1) pen_size = 1;
X    else if (pen_size > MAX_PEN_SIZE) pen_size = MAX_PEN_SIZE;
X}
X
X
X/*
X * Print the line defined by previous path commands
X */
Xstatic	void
Xflush_path()
X{
X    register int i;
X    int last_min_x, last_max_x, last_min_y, last_max_y;
X
X    last_min_x = 30000;	last_min_y = 30000;
X    last_max_x = -30000; last_max_y = -30000;
X    for (i=1; i<path_len; i++) {
X	if (xx[i] > last_max_x) last_max_x = xx[i];
X	if (xx[i] < last_min_x) last_min_x = xx[i];
X	if (yy[i] > last_max_y) last_max_y = yy[i];
X	if (yy[i] < last_min_y) last_min_y = yy[i];
X	line_btw(xx[i], yy[i], xx[i+1], yy[i+1]);
X    }
X    if (xx[path_len] > last_max_x) last_max_x = xx[path_len];
X    if (xx[path_len] < last_min_x) last_min_x = xx[path_len];
X    if (yy[path_len] > last_max_y) last_max_y = yy[path_len];
X    if (yy[path_len] < last_min_y) last_min_y = yy[path_len];
X    path_len = 0;
X    do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y);
X}
X
X
X/*
X * Print a dashed line along the previously defined path, with
X * the dashes/inch defined.
X */
Xstatic	void
Xflush_dashed(cp, dotted)
Xchar *cp;
Xint dotted;
X{
X    int i, numdots, x0, y0, x1, y1;
X    int cx0, cy0, cx1, cy1;
X    float inchesperdash;
X    double d, spacesize, a, b, dx, dy, milliperdash;
X
X    if (sscanf(cp, " %f ", &inchesperdash) != 1) {
X	Warning("illegal format for dotted/dashed line: %s", cp);
X	return;
X    }
X    if (path_len <= 1 || inchesperdash <= 0.0) {
X	Warning("illegal conditions for dotted/dashed line", "");
X	return;
X    }
X    milliperdash = inchesperdash * 1000.0;
X    x0 = xx[1];	y0 = yy[1];
X    x1 = xx[2];	y1 = yy[2];
X    dx = x1 - x0;
X    dy = y1 - y0;
X    if (dotted) {
X	numdots = sqrt(dx*dx + dy*dy) / milliperdash + 0.5;
X	for (i=0; i <= numdots; i++) {
X	    a = (float) i / (float) numdots;
X	    cx0 = x0 + a*dx + 0.5;
X	    cy0 = y0 + a*dy + 0.5;
X	    dot_at(cx0, cy0);
X	}
X    }
X    else {
X	d = sqrt(dx*dx + dy*dy);
X	if (d <= 2.0*milliperdash)
X	    line_btw(x0, y0, x1, y1);
X	else {
X	    numdots = d / (2.0*milliperdash) + 1.0;
X	    spacesize = (d - numdots * milliperdash) / (numdots - 1);
X	    for (i=0; i<numdots-1; i++) {
X		a = i * (milliperdash + spacesize) / d;
X		b = a + milliperdash / d;
X		cx0 = x0 + a*dx + 0.5;
X		cy0 = y0 + a*dy + 0.5;
X		cx1 = x0 + b*dx + 0.5;
X		cy1 = y0 + b*dy + 0.5;
X		line_btw(cx0, cy0, cx1, cy1);
X		b += spacesize / d;
X	    }
X	    cx0 = x0 + b*dx + 0.5;
X	    cy0 = y0 + b*dy + 0.5;
X	    line_btw(cx0, cy0, x1, y1);
X	}
X    }
X    path_len = 0;
X}
X
X
X/*
X * Add a point to the current path
X */
Xstatic	void
Xadd_path(cp)
Xchar *cp;
X{
X    int pathx, pathy;
X
X    if (++path_len >= MAXPOINTS) oops("Too many points");
X    if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2)
X	oops("Malformed path command");
X    xx[path_len] = pathx;
X    yy[path_len] = pathy;
X}
X
X
X/*
X * Draw to a floating point position
X */
Xstatic void
Xim_fdraw(x, y)
Xdouble x,y;
X{
X    if (++path_len >= MAXPOINTS) oops("Too many arc points");
X    xx[path_len] = x + 0.5;
X    yy[path_len] = y + 0.5;
X}
X
X
X/*
X * Draw an ellipse with the indicated center and radices.
X */
Xstatic	void
Xdraw_ellipse(xc, yc, xr, yr)
Xint xc, yc, xr, yr;
X{
X    double angle, theta;
X    int n, px0, py0, px1, py1;
X
X    angle = (xr + yr) / 2.0;
X    theta = sqrt(1.0 / angle);
X    n = TWOPI / theta + 0.5;
X    if (n < 12) n = 12;
X    else if (n > 80) n = 80;
X    n /= 2;
X    theta = TWOPI / n;
X
X    angle = 0.0;
X    px0 = xc + xr;	/* cos(0) = 1 */
X    py0 = yc;		/* Sin(0) = 0 */
X    while ((angle += theta) <= TWOPI) {
X	px1 = xc + xr*cos(angle) + 0.5;
X	py1 = yc + yr*sin(angle) + 0.5;
X	line_btw(px0, py0, px1, py1);
X	px0 = px1;
X	py0 = py1;
X    }
X    line_btw(px0, py0, xc + xr, yc);
X}
X
X/*
X * Draw an arc
X */
Xstatic	void
Xarc(cp)
Xchar *cp;
X{
X    int xc, yc, xrad, yrad, n;
X    float start_angle, end_angle, angle, theta, r;
X    double xradius, yradius, xcenter, ycenter;
X
X    if (sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad, &start_angle,
X	&end_angle) != 6) {
X	Warning("illegal arc specification: %s", cp);
X	return;
X    }
X    /* We have a specialized fast way to draw closed circles/ellipses */
X    if (start_angle <= 0.0 && end_angle >= 6.282) {
X	draw_ellipse(xc, yc, xrad, yrad);
X	return;
X    }
X    xcenter = xc;
X    ycenter = yc;
X    xradius = xrad;
X    yradius = yrad;
X    r = (xradius + yradius) / 2.0;
X    theta = sqrt(1.0 / r);
X    n = 0.3 * TWOPI / theta + 0.5;
X    if (n < 12) n = 12;
X    else if (n > 80) n = 80;
X    n /= 2;
X    theta = TWOPI / n;
X    flush_path();
X    im_fdraw( xcenter + xradius*cos(start_angle),
X		ycenter + yradius*sin(start_angle) );
X    angle = start_angle + theta;
X    while (angle < end_angle) {
X	im_fdraw(xcenter + xradius*cos(angle),
X		 ycenter + yradius*sin(angle) );
X	angle += theta;
X    }
X    im_fdraw(xcenter + xradius*cos(end_angle),
X		ycenter + yradius*sin(end_angle) );
X    flush_path();
X}
X
X
X/*
X * APPROXIMATE integer distance between two points
X */
X#define	dist(x0, y0, x1, y1)	(abs(x0-x1)+abs(y0-y1))
X
X
X/*
X * Draw a spline along the previously defined path
X */
Xstatic	void
Xflush_spline()
X{
X    int xp, yp, N, lastx=(-1), lasty;
X    int t1, t2, t3, steps, j;
X    register int i, w;
X
X#ifdef	lint
X    lasty = -1;
X#endif
X    N = path_len + 1;
X    xx[0] = xx[1];	yy[0] = yy[1];
X    xx[N] = xx[N-1];	yy[N] = yy[N-1];
X    for (i=0; i<N-1; i++) {	/* interval */
X	steps = (dist(xx[i], yy[i], xx[i+1], yy[i+1]) +
X		 dist(xx[i+1], yy[i+1], xx[i+2], yy[i+2])) / 80;
X	for (j=0; j<steps; j++) {	/* points within */
X	    w = (j*1000 + 500) / steps;
X	    t1 = w * w / 20;
X	    w -= 500;
X	    t2 = (750000 - w * w) / 10;
X	    w -= 500;
X	    t3 = w * w / 20;
X	    xp = (t1*xx[i+2] + t2*xx[i+1] + t3*xx[i] + 50000) / 100000;
X	    yp = (t1*yy[i+2] + t2*yy[i+1] + t3*yy[i] + 50000) / 100000;
X	    if (lastx > -1) line_btw(lastx, lasty, xp, yp);
X	    lastx = xp;
X	    lasty = yp;
X	}
X    }
X    path_len = 0;
X}
X
X
X/*
X * Shade the last box, circle, or ellipse
X */
Xstatic	void
Xshade_last()
X{
X    blacken = whiten = False;
X    shade = True;
X}
X
X
X/*
X * Make the last box, circle, or ellipse, white inside (shade with white)
X */
Xstatic	void
Xwhiten_last()
X{
X    whiten = True;
X    blacken = shade = False;
X}
X
X
X/*
X * Make last box, etc, black inside
X */
Xstatic	void
Xblacken_last()
X{
X    blacken = True;
X    whiten = shade = False;
X}
X
X
X/*
X *	The following copyright message applies to the rest of this file.  --PV
X */
X
X/*
X *	This program is Copyright (C) 1987 by the Board of Trustees of the
X *	University of Illinois, and by the author Dirk Grunwald.
X *
X *	This program may be freely copied, as long as this copyright
X *	message remaines affixed. It may not be sold, although it may
X *	be distributed with other software which is sold. If the
X *	software is distributed, the source code must be made available.
X *
X *	No warranty, expressed or implied, is given with this software.
X *	It is presented in the hope that it will prove useful.
X *
X *	Hacked in ignorance and desperation by jonah@db.toronto.edu
X */
X
X/*
X *      The code to handle the \specials generated by tpic was modified
X *      by Dirk Grunwald using the code Tim Morgan at Univ. of Calif, Irvine
X *      wrote for TeXsun.
X */
X
X#define COMLEN  4
X
Xvoid
XapplicationDoSpecial(cp)
Xchar *cp;
X{
X    char command[COMLEN], *orig_cp;
X    register int len;
X
X    orig_cp = cp;
X    while (isspace(*cp)) ++cp;
X    len = 0;
X    while (!isspace(*cp) && *cp && len < COMLEN-1) command[len++] = *cp++;
X    command[len] = '\0';
X    if (strcmp(command, "pn") == 0) set_pen_size(cp);
X    else if (strcmp(command, "fp") == 0) flush_path();
X    else if (strcmp(command, "da") == 0) flush_dashed(cp, 0);
X    else if (strcmp(command, "dt") == 0) flush_dashed(cp, 1);
X    else if (strcmp(command, "pa") == 0) add_path(cp);
X    else if (strcmp(command, "ar") == 0) arc(cp);
X    else if (strcmp(command, "sp") == 0) flush_spline();
X    else if (strcmp(command, "sh") == 0) shade_last();
X    else if (strcmp(command, "wh") == 0) whiten_last();
X    else if (strcmp(command, "bk") == 0) blacken_last();
X    else if (spec_warn)
X	Fprintf(stderr, "%s:  special \"%s\" not implemented\n", prog, orig_cp);
X}
END_OF_FILE
if test 10262 -ne `wc -c <'tpic.c'`; then
    echo shar: \"'tpic.c'\" unpacked with wrong size!
fi
# end of 'tpic.c'
fi
if test -f 'xdvi.man.sed' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xdvi.man.sed'\"
else
echo shar: Extracting \"'xdvi.man.sed'\" \(9221 characters\)
sed "s/^X//" >'xdvi.man.sed' <<'END_OF_FILE'
X.TH XDVI SIPB "17 January 1989" "X Version 11"
X.SH NAME
Xxdvi \- DVI Previewer for the X Window System
X.SH SYNOPSIS
X.B xdvi
X[+[\fIpage\fP]] [\-s \fIshrink\fP] [\-S \fIdensity\fP] [\-p \fIpixels\fP]
X[\-l] [\-rv] [\-fg \fIcolor\fP] [\-bg \fIcolor\fP] [\-hl \fIcolor\fP]
X[\-bd \fIcolor\fP] [\-cr \fIcolor\fP] [-thorough] [\-margins \fIinches\fP]
X[\-sidemargin \fIinches\fP] [\-topmargin \fIinches\fP]
X[\-mgs[\fIn\fP] \fIsize\fP] [\-geometry \fIgeometry\fP | =\fIgeometry\fP]
X[%\fIgeometry\fP] [\-display \fIdisplay\fP] file
X.SH DESCRIPTION
X.I Xdvi
Xis a program which runs under the X window system. It is used to preview
XDVI files, such as are produced by TeX.
X.PP
XThis program has the capability of
Xshowing the file shrunken by various (integer) factors, and also has a
X``magnifying glass'' which allows one to see a small part of the unshrunk
Ximage momentarily.
X.PP
XAlso, before displaying any page or part thereof, it checks to see if the dvi
Xfile has changed since the last time it was displayed.  If this is the case,
Xthen \fIxdvi\fR will reinitialize itself for the new dvi file.  For this reason,
Xexposing parts of the \fIxdvi\fR window while \fITeX\fR is running should be
Xavoided.  This feature allows you to preview many versions
Xof the same file while running \fIxdvi\fR only once.
X.SH OPTIONS
XIn addition to specifying the .\fPdvi\fR file (with or without the .\fPdvi\fR),
X\fIXdvi\fR supports the following command line options.
XIf the option begins with a
X.RB ` + '
Xinstead of a
X.RB ` \- ',
Xthe option is restored to its default value.  By default, these options can
Xbe set via the resource names given in parentheses in the description of
Xeach option.
X.TP
X.IB + page
XSpecifies the first page to show.  If \fI+\fR is given without a
Xnumber, the last page is assumed; the first page is the default.
X.TP
X.BI \-s " shrink"
X(.shrinkFactor)
XDefines the initial shrink factor.  The default value is 4.
X.TP
X.BI \-S " density"
X(.densityPercent)
XDetermines the density used when shrinking bitmaps for fonts.
XA higher value produces a lighter font.  The default value is 40.
X.TP
X.BI \-p " pixels"
X(.pixelsPerInch)
XDefines the size of the fonts to use, in pixels per inch.  The
Xdefault value is 300.
X.TP
X.B \-l
X(.listFonts)
XCauses the names of the fonts used to be listed.
X.TP
X.B \-rv
X(.reverseVideo)
XCauses the page to be displayed with white characters on a
Xblack background, instead of vice versa.
X.TP
X.BI \-bw " width"
X(.borderWidth)
XSpecifies the width of the border of the window.
X.TP
X.BI \-borderwidth " width"
XSame as \fB-bw\fR, above.
X.TP
X.BI \-fg " color"
X(.foreground)
XDetermines the color of the text (foreground).
X.TP
X.BI \-foreground " color"
XSame as \fB-fg\fR, above.
X.TP
X.BI \-bg " color"
X(.background)
XDetermines the color of the background.
X.TP
X.BI \-background " color"
XSame as \fB-bg\fR, above.
X.TP
X.BI \-hl " color"
X(.highlight)
XDetermines the color of the page border.
X.TP
X.BI \-bd " color"
X(.borderColor)
XDetermines the color of the window border.
X.TP
X.BI \-cr " color"
X(.cursorColor)
XDetermines the color of the cursor.  The default is the
Xforeground color.
X.TP
X.B \-thorough
X(.thorough)
X\fIXdvi\fR will usually try to ensure that overstrike characters (\fIe.g.\fR
X\\notin) are printed correctly.  On monochrome displays, this is always
Xpossible with one logical operation, either \fIand\fR or \fIor\fR.  On
Xcolor displays, however, this may take two operations, one to set the
Xappropriate bits and one to clear other bits.  If this is the case, then
Xby default \fIxdvi\fR will instead use the \fIcopy\fR operation,
Xwhich does not handle overstriking correctly.  The ``thorough'' option
Xchooses the slower but more correct choice.
X.TP
X.BI \-margins " inches"
X(.margins)
XSpecifies the size of both the top margin and side margin.  This
Xcan be a decimal number, \fIe.g.\fR, 1.5.  It determines
Xthe ``home'' position of the page within the window as follows.  If the entire
Xpage fits in the window, then the margin settings are ignored.  If, even
Xafter removing the margins from the left, right, top, and bottom, the page
Xstill cannot fit in the window, then the page is put in the window such that
Xthe top and left margins are hidden, and presumably the upper left-hand corner
Xof the text on the page will be in the upper left-hand corner of the window.
XOtherwise, the text is centered in the window.  See also `\fBH\fR' under
Xthe KEY\%STROKES section.
X.TP
X.BI \-sidemargin " inches"
X(.sideMargin)
XSpecifies the side margin (see above).
X.TP
X.BI \-topmargin " inches"
X(.topMargin)
XSpecifies the top and bottom margins (see above).
X.TP
X.BI "\-mgs[n]" " size"
X(.magnifierSize[n])
XSpecifies the size of the window to be used for the ``magnifying glass''
Xfor Button \fIn\fR.  See the MOUSE ACTIONS section.  Defaults are 200,
X350, 600, 900, and 1200.
X.TP
X.BI \-mgs " size"
XSame as \fB-mgs1\fR, above.
X.TP
X.BI = geometry
X(*geometry)
XSpecifies the initial geometry of the window.
X.TP
X.BI \-geometry " geometry"
XSame as above.
X.TP
X.BI # geometry
X(.iconGeometry)
XSpecifies the initial position for the icon.
X.TP
X.BI \-display " host:display"
XSpecifies the host and screen to be used for displaying the dvi file.
XThis is normally obtained from the environment variable ``DISPLAY.''
X.SH KEYSTROKES
X\fBXdvi\fR recognizes the following keystrokes when typed in its window.
XEach may optionally be preceded by a (positive or negative) number, whose
Xinterpretation will depend on the particular keystroke.
X.TP
X.B q
XQuits the program.  Control-C and control-D will do this, too.
X.TP
X.B n
XMoves to the next page (or to the \fBn\fRth next page if a number is given).
XSynonyms are `\fBf\fR', Space, Return, and Line Feed.
X.TP
X.B p
XMoves to the previous page (or back \fBn\fR pages).  Synonyms are
X`\fBb\fR', control-H, and Delete.
X.TP
X.B g
XMoves to the page with the given number.  Initially, the first page is assumed
Xto be page number 1, but this can be changed with the `\fBP\fR' keystroke,
Xbelow.  If no page number is given, then it goes to the last page.
X.TP
X.B P
X``This is page number \fBn\fR.''  This can be used to make the `\fBg\fR'
Xkeystroke refer to actual page numbers instead of absolute page numbers.
X.TP
X.B Control-L
XRedisplays the current page.
X.TP
X.B ^
XMove to the ``home'' position of the page.  This is normally the upper
Xleft-hand corner of the page, depending on the margins as described in
Xthe \-margins option, above.
X.TP
X.B u
XMoves up a window-full.
X.TP
X.B d
XMoves down a window-full.
X.TP
X.B l
XMoves left a window-full.
X.TP
X.B r
XMoves right a window-full.
X.TP
X.B c
XMoves the page so that the point currently beneath the cursor is moved to
Xthe middle of the window.  It also (gasp!) warps the cursor to the same place.
X.TP
X.B M
XSets the margins so that the point currently under the cursor is the upper
Xleft-hand corner of the text in the page.
X.TP
X.B s
XChanges the shrink factor to the given number.  If no number is given, the
Xsmallest factor that makes the entire page fit in the window will be used.
X(Margins are ignored in this computation.)
X.TP
X.B S
XSets the density factor to be used when shrinking bitmaps.  This should
Xbe a number between 0 and 100; higher numbers produce lighter characters.
X.TP
X.B R
XForces the dvi file to be reread.  This allows you to preview many versions
Xof the same file while running \fIxdvi\fR only once.
X.SH MOUSE ACTIONS
XIf the shrink factor is set to any number other than one, then clicking
Xany mouse button will pop up a ``magnifying glass'' which shows the unshrunk
Ximage in the vicinity of the mouse click.  This subwindow disappears when
Xthe mouse button is released.  Different mouse buttons produce different sized
Xwindows, as indicated by the \fB\-mgs\fR option, above.
X.PP
XAlso, the scrollbars (if present) behave in the standard way:  pushing Button 2
Xin a scrollbar moves the top or left edge of the scrollbar to that point;
Xpushing Button 1 moves the image up or right by an amount equal to the distance
Xfrom the button press to the upper left-hand corner of the window; pushing
XButton 3 moves the image down or left by the same amount.
X.SH ENVIRONMENT
XUses the environment variable ``DISPLAY'' to specify which bit map display
Xterminal to use.
X.PP
XThe environment variable ``%%FONT_PATH%%'' determines the path(s) searched for
Xfonts in the following manner.  The string consists of one or more strings
Xseparated by colons.  In each such string, the substring ``%f'' is
Xchanged to the font name; ``%d'' is changed to the magnification; and
X``%p'' is changed to the font family (``gf'', ``pk'', or ``pxl'').  If no
X``%f'' appears in the string, then the string ``/%f.%d%p'' is added on
Xthe end.  For example, if the string is ``/usr/local/tex/fonts'' and the font is
Xcmr10 at 300dpi, then it searches for /usr/local/tex/fonts/cmr10.300gf,
X/usr/local/tex/fonts/cmr10.300pk, and /usr/local/tex/fonts/cmr10.1500pxl,
Xin that order.  If the first character of the ``%%FONT_PATH%%'' variable
Xis a colon, then the system default paths are tried first.
X.SH FILES
X.br
X%%DEFAULT_FONT_PATH%%   Font pixel files.
X.SH "SEE ALSO"
XX(1).
X.SH AUTHORS
XEric Cooper, CMU, did a version for direct output to a QVSS.
XModified for X by
XBob Scheifler, MIT Laboratory for Computer Science.
XModified for X11 by Mark Eichin, MIT SIPB.
XAdditional enhancements by many others.
END_OF_FILE
if test 9221 -ne `wc -c <'xdvi.man.sed'`; then
    echo shar: \"'xdvi.man.sed'\" unpacked with wrong size!
fi
# end of 'xdvi.man.sed'
fi
if test -f 'xdvi_mask.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xdvi_mask.h'\"
else
echo shar: Extracting \"'xdvi_mask.h'\" \(222 characters\)
sed "s/^X//" >'xdvi_mask.h' <<'END_OF_FILE'
X#define xdvi_mask_width 15
X#define xdvi_mask_height 15
Xstatic short xdvi_mask_bits[] = {
X   0x01c0, 0x03e0, 0x07f0, 0x0ff8,
X   0x1ffc, 0x3ffe, 0x7fff, 0x7fff,
X   0x7fff, 0x3ffe, 0x1ffc, 0x0ff8,
X   0x07f0, 0x03e0, 0x01c0};
END_OF_FILE
if test 222 -ne `wc -c <'xdvi_mask.h'`; then
    echo shar: \"'xdvi_mask.h'\" unpacked with wrong size!
fi
# end of 'xdvi_mask.h'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x