From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- dviware/dvgtk/AUTHORS | 14 + dviware/dvgtk/ChangeLog | 19 + dviware/dvgtk/INSTALL | 18 + dviware/dvgtk/MACHINES | 10 + dviware/dvgtk/Makefile.in | 181 ++ dviware/dvgtk/NEWS | 18 + dviware/dvgtk/README | 32 + dviware/dvgtk/ansi2knr.ac | 78 + dviware/dvgtk/ansi2knr.c | 481 ++++++ dviware/dvgtk/c-auto.h.in | 126 ++ dviware/dvgtk/configure | 2544 +++++++++++++++++++++++++++ dviware/dvgtk/configure.in | 30 + dviware/dvgtk/defaults.h | 32 + dviware/dvgtk/doc/CHANGES | 448 +++++ dviware/dvgtk/doc/Makefile | 24 + dviware/dvgtk/doc/README | 426 +++++ dviware/dvgtk/doc/TODO | 36 + dviware/dvgtk/doc/ansi2knr.1 | 19 + dviware/dvgtk/doc/example.tex | 232 +++ dviware/dvgtk/doc/guidemacs.tex | 105 ++ dviware/dvgtk/doc/options.txt | 139 ++ dviware/dvgtk/doc/sysguide.tex | 914 ++++++++++ dviware/dvgtk/doc/tripvdu.tex | 279 +++ dviware/dvgtk/doc/userguide.tex | 1286 ++++++++++++++ dviware/dvgtk/dvgt.c | 3595 +++++++++++++++++++++++++++++++++++++++ dviware/dvgtk/dvgt.h | 110 ++ dviware/dvgtk/dvgt.man | 82 + dviware/dvgtk/dvireader.c | 1885 ++++++++++++++++++++ dviware/dvgtk/dvireader.h | 171 ++ dviware/dvgtk/etc/dv-env | 25 + dviware/dvgtk/etc/sane | 9 + dviware/dvgtk/fontreader.c | 1079 ++++++++++++ dviware/dvgtk/fontreader.h | 21 + dviware/dvgtk/options.c | 534 ++++++ dviware/dvgtk/options.h | 45 + dviware/dvgtk/screenio.c | 483 ++++++ dviware/dvgtk/screenio.h | 73 + dviware/dvgtk/stamp-auto | 1 + dviware/dvgtk/stamp-auto.in | 1 + dviware/dvgtk/unixio.c | 357 ++++ dviware/dvgtk/unixio.h | 44 + dviware/dvgtk/vdu.c | 547 ++++++ dviware/dvgtk/vdu.h | 87 + dviware/dvgtk/web2c-dvgtk.patch | 55 + 44 files changed, 16695 insertions(+) create mode 100644 dviware/dvgtk/AUTHORS create mode 100644 dviware/dvgtk/ChangeLog create mode 100644 dviware/dvgtk/INSTALL create mode 100644 dviware/dvgtk/MACHINES create mode 100644 dviware/dvgtk/Makefile.in create mode 100644 dviware/dvgtk/NEWS create mode 100644 dviware/dvgtk/README create mode 100644 dviware/dvgtk/ansi2knr.ac create mode 100644 dviware/dvgtk/ansi2knr.c create mode 100644 dviware/dvgtk/c-auto.h.in create mode 100644 dviware/dvgtk/configure create mode 100644 dviware/dvgtk/configure.in create mode 100644 dviware/dvgtk/defaults.h create mode 100644 dviware/dvgtk/doc/CHANGES create mode 100644 dviware/dvgtk/doc/Makefile create mode 100644 dviware/dvgtk/doc/README create mode 100644 dviware/dvgtk/doc/TODO create mode 100644 dviware/dvgtk/doc/ansi2knr.1 create mode 100644 dviware/dvgtk/doc/example.tex create mode 100644 dviware/dvgtk/doc/guidemacs.tex create mode 100644 dviware/dvgtk/doc/options.txt create mode 100644 dviware/dvgtk/doc/sysguide.tex create mode 100644 dviware/dvgtk/doc/tripvdu.tex create mode 100644 dviware/dvgtk/doc/userguide.tex create mode 100644 dviware/dvgtk/dvgt.c create mode 100644 dviware/dvgtk/dvgt.h create mode 100644 dviware/dvgtk/dvgt.man create mode 100644 dviware/dvgtk/dvireader.c create mode 100644 dviware/dvgtk/dvireader.h create mode 100644 dviware/dvgtk/etc/dv-env create mode 100644 dviware/dvgtk/etc/sane create mode 100644 dviware/dvgtk/fontreader.c create mode 100644 dviware/dvgtk/fontreader.h create mode 100644 dviware/dvgtk/options.c create mode 100644 dviware/dvgtk/options.h create mode 100644 dviware/dvgtk/screenio.c create mode 100644 dviware/dvgtk/screenio.h create mode 100644 dviware/dvgtk/stamp-auto create mode 100644 dviware/dvgtk/stamp-auto.in create mode 100644 dviware/dvgtk/unixio.c create mode 100644 dviware/dvgtk/unixio.h create mode 100644 dviware/dvgtk/vdu.c create mode 100644 dviware/dvgtk/vdu.h create mode 100644 dviware/dvgtk/web2c-dvgtk.patch (limited to 'dviware/dvgtk') diff --git a/dviware/dvgtk/AUTHORS b/dviware/dvgtk/AUTHORS new file mode 100644 index 0000000000..cec62e794f --- /dev/null +++ b/dviware/dvgtk/AUTHORS @@ -0,0 +1,14 @@ +This program, dvgtk, was modified by Tomasz J. Cholewo from Geoffrey Tobin's +dvgt distribution. Send bug reports to t.cholewo@ieee.org. + +Andrew Trevorrow wrote the original DVItoVDU in Modula-2. + +The initial C code for this version of DVItoVDU was copied from Ian +Dall's site, ftp://augean.oz.au/pub/misc/dv.tar.Z. Ian had, as his +source code seems to indicate, automatically translated it from Modula. + +Geoffrey Tobin added a lot of new functionality: font searching and +substitution, option handling, bitmap allocation, help files, and much +more. + +Tomasz J. Cholewo modified dvgt to use kpathsea library. diff --git a/dviware/dvgtk/ChangeLog b/dviware/dvgtk/ChangeLog new file mode 100644 index 0000000000..9e3cc1c82a --- /dev/null +++ b/dviware/dvgtk/ChangeLog @@ -0,0 +1,19 @@ +Thu Mar 28 23:36:41 1997 Tomasz J. Cholewo + + * First public beta release: version 0.2. + +Fri Mar 28 03:29:28 1997 Tomasz J. Cholewo + + * Makefile.in: Using ansi2knr. + +Fri Mar 28 03:20:55 1997 Tomasz J. Cholewo + + * dvireader.c: Removed extern references. + * dvgt.h: Renamed from config.h. + +Mon Mar 24 01:48:49 1997 Tomasz J. Cholewo + + * dvgt.h, dvgt.c, options.c, vdu.h, options.h, vdu.c, unixio.h, + unixio.c, screenio.h, screenio.c, fontreader.h, + fontreader.c, dvireader.h, dvireader.c, defaults.h, + Makefile.in: Checked in as revision 0.1. diff --git a/dviware/dvgtk/INSTALL b/dviware/dvgtk/INSTALL new file mode 100644 index 0000000000..1860a306d2 --- /dev/null +++ b/dviware/dvgtk/INSTALL @@ -0,0 +1,18 @@ +1. Unpack, compile and install web2c by following its installation + instructions. + +2. Untar dvgtk-0.2.tar.gz in the top-level web2c source directory which + should create a dvgtk subdirectory. + +3. Set the default values in dvgtk/defaults.h. + +4. Run configure in dvgtk directory with the same parameters as for web2c. + +5. make + +6. make install + +If you prefer to compile web2c and dvgtk in the same session you will +need to apply the supplied web2c-dvgtk.patch in the top-level web2c +directory and then run configure, make and make install. + diff --git a/dviware/dvgtk/MACHINES b/dviware/dvgtk/MACHINES new file mode 100644 index 0000000000..5ab3eda277 --- /dev/null +++ b/dviware/dvgtk/MACHINES @@ -0,0 +1,10 @@ +dvgtk-0.2 was verified to compile and work on the following architectures: + +mips-sgi-irix6.2 + gcc-2.7.2.1 with -fbounds-checking + cc + +hppa1.1-hp-hpux10.10 + gcc-2.7.2 + cc with and without -Aa option + diff --git a/dviware/dvgtk/Makefile.in b/dviware/dvgtk/Makefile.in new file mode 100644 index 0000000000..5c7bc9a234 --- /dev/null +++ b/dviware/dvgtk/Makefile.in @@ -0,0 +1,181 @@ +# Makefile for dvgtk -- t.cholewo@ieee.org. Public domain. +# $Id: Makefile.in,v 0.2 1997/03/28 03:29:28 tjchol01 Exp $ +version = 0.2 + +ac_include ../make/paths.make +ac_include ../make/common.make +ac_include ../make/programs.make + +ANSI2KNR = @ANSI2KNR@ +o = .@U@o + +#BOUNDS = -fbounds-checking +#XCFLAGS = $(BOUNDS) -O -Wall -Wformat +#XLDFLAGS = $(BOUNDS) + +program = dvgt +objects = dvgt$o dvireader$o fontreader$o options$o screenio$o unixio$o vdu$o + +programs = $(program) + +default all: $(programs) + +$(program): $(objects) $(kpathsea) + $(kpathsea_link) $(objects) $(LOADLIBES) + +ac_include ../make/tkpathsea.make + +install: install-exec install-data +uninstall: uninstall-exec uninstall-data + +install-exec: + $(SHELL) $(top_srcdir)/../mkdirchain $(bindir) + test ! -f $(program) \ + || $(INSTALL_LIBTOOL_PROG) $(bindir) $(program) +uninstall-exec: + cd $(bindir); rm -f $(program) + +install-data: + $(SHELL) $(top_srcdir)/../mkdirchain $(mandir) + $(INSTALL_DATA) $(srcdir)/dvgt.man $(mandir)/dvgt.$(manext) +uninstall-data: + rm -f $(mandir)/dvgt.$(manext) + +clean:: + rm -f $(ANSI2KNR) *._o *._c *.vlg doc/*.dvi doc/*.vlg doc/*.log depend.make + +xclean: clean configclean + rm -f stamp-auto stamp-auto.in + +distname = dvgtk +program_files = dvgt.man web2c-dvgtk.patch ansi2knr.ac MACHINES +version_files = dvgt.c + +pre-dist-$(distname): +post-dist-$(distname): + ln -s `pwd`/doc `pwd`/etc $(distdir) + +# modified dist.make -- making distribution tar files. +distdir = $(distname) +ln_files = AUTHORS ChangeLog INSTALL NEWS README *.in *.h *.c \ + configure .gdbinit stamp-auto + +dist_rm_predicate = -name depend.make -o -name Makefile +dist: all pre-dist-$(distname) + rm -rf $(distdir) + mkdir -p $(distdir) + -ln $(ln_files) $(distdir) + ln $(program_files) $(distdir) +# Remove the extra files our patterns got us. + cd $(distdir); rm -f c-auto.h + find $(distdir) \( $(dist_rm_predicate) \) -exec rm '{}' \; + find $(distdir) -name \.*texi -exec egrep -ni ' | ::|xx[^}]' \; + $(MAKE) post-dist-$(distname) + chmod -R a+rwX $(distdir) + GZIP=-9 tar chzf $(distdir)-$(version).tar.gz $(distdir) + rm -rf $(distdir) + +# End of modified dist.make. + +.SUFFIXES: .c .o ._c ._o + +.c._c: $(ANSI2KNR) + $(ANSI2KNR) $< > $*.tmp && mv $*.tmp $@ + +._c._o: + @echo $(compile) -c $< + @rm -f _$*.c + @ln $< _$*.c && $(compile) _$*.c && mv _$*.o $@ && rm _$*.c + +.c._o: $(ANSI2KNR) + $(ANSI2KNR) $< > $*.tmp && mv $*.tmp $*._c + @echo $(compile) $*._c + @rm -f _$*.c + @ln $*._c _$*.c && $(compile) _$*.c && mv _$*.o $@ && rm _$*.c + +ansi2knr: ansi2knr.o c-auto.h + $(CC) -o ansi2knr ansi2knr.o $(LIBS) + +ac_include ../make/config.make + +info dvi check: + +ac_include ../make/clean.make +ac_include ../make/rdepend.make + +# dependencies + +# configure:: ansi2knr.ac + +$(objects): $(ANSI2KNR) + +# depend.make + +dvgt$o: dvgt.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h ../kpathsea/proginit.h ../kpathsea/tex-file.h \ + defaults.h screenio.h options.h unixio.h vdu.h dvireader.h \ + fontreader.h +dvireader$o: dvireader.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h dvireader.h screenio.h fontreader.h options.h +fontreader$o: fontreader.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h ../kpathsea/tex-file.h ../kpathsea/tex-glyph.h \ + screenio.h vdu.h options.h dvireader.h fontreader.h +options$o: options.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h screenio.h options.h defaults.h +screenio$o: screenio.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h screenio.h unixio.h vdu.h +unixio$o: unixio.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h unixio.h screenio.h \ + +vdu$o: vdu.c dvgt.h c-auto.h \ + ../kpathsea/debug.h \ + ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/types.h \ + ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \ + ../kpathsea/lib.h vdu.h options.h screenio.h + diff --git a/dviware/dvgtk/NEWS b/dviware/dvgtk/NEWS new file mode 100644 index 0000000000..488db9b8e1 --- /dev/null +++ b/dviware/dvgtk/NEWS @@ -0,0 +1,18 @@ +1. Uses kpathsea library: finds fonts according to the texmf.cnf + settings, MakeTeXPK/gsftopk is called as needed. + +2. Installation integrated with web2c-7.0 source tree structure. + +3. Uses configure to simplify installation process. + +4. Now works with dvicopy output what enables previewing documents with + virtual fonts. + +5. Shows bounding boxes of included Postscript figures. + +6. Uses getopt library for option processing what allows for greater + flexibility in command line syntax. + +7. General code cleanup. + +8. Supports only Tektronix 4010 emulations. diff --git a/dviware/dvgtk/README b/dviware/dvgtk/README new file mode 100644 index 0000000000..5946b734e5 --- /dev/null +++ b/dviware/dvgtk/README @@ -0,0 +1,32 @@ +dvgtk-0.2 is a beta release of a DVI file previewer for Tektronix 4010 +terminal emulators. + +dvgtk is derived from the dvgt-3.51 package. The original authors were +Andrew Trevorrow, Ian Dall, and Geoffrey Tobin. + +Installation requires access to web2c-7.0 source tree. An attempt was +made to integrate dvgtk as a subpackage of the web2c but dvgt is still +in a very rough shape and does not stand to web2c standards yet. Actually +it should be rewritten from scratch :-). + +Installation instructions are in file INSTALL and description of recent +modifications is in file NEWS. For a list of architectures on which +dvgtk was verified to compile see file MACHINES. For original +instructions and acknowledgments please refer to doc/README. + +dvgtk was verified to work with Kermit 3.14, X11R6 xterm and CONEX 7.2. +The maintainer currently uses CONEX by Erhard Hilbig with a modem +connection and this package was tested most extensively for this +configuration. CONEX works well even on low-end PCs and can be found +for example at: + + ftp://ftp.cdrom.com/simtelnet/msdos/commprog/conex71.zip + +The latest version of dvgtk can be found at + + http://mecca.spd.louisville.edu/~tjchol01/software/dvgtk/ + +Please direct all suggestions and bug reports to Tomasz J. Cholewo +. I will be very grateful for all build reports +containing the host type and possibly invalid output from the +compilation process. diff --git a/dviware/dvgtk/ansi2knr.ac b/dviware/dvgtk/ansi2knr.ac new file mode 100644 index 0000000000..6381c3b3fc --- /dev/null +++ b/dviware/dvgtk/ansi2knr.ac @@ -0,0 +1,78 @@ +# -*- m4 -*- +# Based on aclocal.m4 from wget-1.4.4 by Hrvoje Niksic +AC_DEFUN(AM_C_PROTOTYPES, +[AC_REQUIRE([AM_PROG_CC_STDC]) +AC_BEFORE([$0], [AC_C_INLINE]) +AC_MSG_CHECKING([for function prototypes]) +if test "$am_cv_prog_cc_stdc" != no; then + AC_MSG_RESULT(yes) + AC_DEFINE(PROTOTYPES) + U= ANSI2KNR= +else + AC_MSG_RESULT(no) + U=_ ANSI2KNR=./ansi2knr + # Ensure some checks needed by ansi2knr itself. + AC_HEADER_STDC + AC_CHECK_HEADERS(string.h) +fi +AC_SUBST(U)dnl +AC_SUBST(ANSI2KNR)dnl +]) + + +# serial 1 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and +# handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + +AC_DEFUN(AM_PROG_CC_STDC, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) +AC_CACHE_VAL(am_cv_prog_cc_stdc, +[am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# HP-UX -Aa -D_HPUX_SOURCE +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" "-Aa -D_HPUX_SOURCE" -qlanglvl=ansi -std1 "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + AC_TRY_COMPILE( +[#if !defined(__STDC__) || __STDC__ != 1 +choke me +#endif +/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */ +#ifdef _SEQUENT_ +# include +# include +#endif +], [ +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);};], +[am_cv_prog_cc_stdc="$ac_arg"; break]) +done +CC="$ac_save_CC" +]) +AC_MSG_RESULT($am_cv_prog_cc_stdc) +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac +]) diff --git a/dviware/dvgtk/ansi2knr.c b/dviware/dvgtk/ansi2knr.c new file mode 100644 index 0000000000..4c1c165af1 --- /dev/null +++ b/dviware/dvgtk/ansi2knr.c @@ -0,0 +1,481 @@ +/* Copyright (C) 1989, 1991, 1993, 1994, 1995 Aladdin Enterprises. All rights reserved. */ + +/* ansi2knr.c */ +/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ + +/* +ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY. No author or distributor accepts responsibility to anyone for the +consequences of using it or for whether it serves any particular purpose or +works at all, unless he says so in writing. Refer to the GNU General Public +License (the "GPL") for full details. + +Everyone is granted permission to copy, modify and redistribute ansi2knr, +but only under the conditions described in the GPL. A copy of this license +is supposed to have been given to you along with ansi2knr so you can know +your rights and responsibilities. It should be in a file named COPYLEFT. +Among other things, the copyright notice and this notice must be preserved +on all copies. + +We explicitly state here what we believe is already implied by the GPL: if +the ansi2knr program is distributed as a separate set of sources and a +separate executable file which are aggregated on a storage medium together +with another program, this in itself does not bring the other program under +the GPL, nor does the mere fact that such a program or the procedures for +constructing it invoke the ansi2knr executable bring any other part of the +program under the GPL. +*/ + +/* + * Usage: + ansi2knr input_file [output_file] + * If no output_file is supplied, output goes to stdout. + * There are no error messages. + * + * ansi2knr recognizes function definitions by seeing a non-keyword + * identifier at the left margin, followed by a left parenthesis, + * with a right parenthesis as the last character on the line. + * It will recognize a multi-line header provided that the last character + * of the last line of the header is a right parenthesis, + * and no intervening line ends with a left or right brace or a semicolon. + * These algorithms ignore whitespace and comments, except that + * the function name must be the first thing on the line. + * The following constructs will confuse it: + * - Any other construct that starts at the left margin and + * follows the above syntax (such as a macro or function call). + * - Macros that tinker with the syntax of the function header. + */ + +/* + * The original and principal author of ansi2knr is L. Peter Deutsch + * . Other authors are noted in the change history + * that follows (in reverse chronological order): + lpd 95-06-22 removed #ifndefs whose sole purpose was to define + undefined preprocessor symbols as 0; changed all #ifdefs + for configuration symbols to #ifs + lpd 95-04-05 changed copyright notice to make it clear that + including ansi2knr in a program does not bring the entire + program under the GPL + lpd 94-12-18 added conditionals for systems where ctype macros + don't handle 8-bit characters properly, suggested by + Francois Pinard ; + removed --varargs switch (this is now the default) + lpd 94-10-10 removed CONFIG_BROKETS conditional + lpd 94-07-16 added some conditionals to help GNU `configure', + suggested by Francois Pinard ; + properly erase prototype args in function parameters, + contributed by Jim Avera ; + correct error in writeblanks (it shouldn't erase EOLs) + lpd 89-xx-xx original version + */ + +/* Most of the conditionals here are to make ansi2knr work with */ +/* the GNU configure machinery. */ + +#if HAVE_CONFIG_H +# include /* tjc change!!! */ +#endif + +#include +#include + +#if HAVE_CONFIG_H + +/* + For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h). + This will define HAVE_CONFIG_H and so, activate the following lines. + */ + +# if STDC_HEADERS || HAVE_STRING_H +# include +# else +# include +# endif + +#else /* not HAVE_CONFIG_H */ + +/* + Without AC_CONFIG_HEADER, merely use as in the original + Ghostscript distribution. This loses on older BSD systems. + */ + +# include + +#endif /* not HAVE_CONFIG_H */ + +#if STDC_HEADERS +# include +#else +/* + malloc and free should be declared in stdlib.h, + but if you've got a K&R compiler, they probably aren't. + */ +char *malloc(); +void free(); +#endif + +/* + * The ctype macros don't always handle 8-bit characters correctly. + * Compensate for this here. + */ +#ifdef isascii +# undef HAVE_ISASCII /* just in case */ +# define HAVE_ISASCII 1 +#else +#endif +#if STDC_HEADERS || !HAVE_ISASCII +# define is_ascii(c) 1 +#else +# define is_ascii(c) isascii(c) +#endif + +#define is_space(c) (is_ascii(c) && isspace(c)) +#define is_alpha(c) (is_ascii(c) && isalpha(c)) +#define is_alnum(c) (is_ascii(c) && isalnum(c)) + +/* Scanning macros */ +#define isidchar(ch) (is_alnum(ch) || (ch) == '_') +#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') + +/* Forward references */ +char *skipspace(); +void writeblanks(); +int test1(); +int convert1(); + +/* The main program */ +int +main(argc, argv) + int argc; + char *argv[]; +{ FILE *in, *out; +#define bufsize 5000 /* arbitrary size */ + char *buf; + char *line; + /* + * In previous versions, ansi2knr recognized a --varargs switch. + * If this switch was supplied, ansi2knr would attempt to convert + * a ... argument to va_alist and va_dcl; if this switch was not + * supplied, ansi2knr would simply drop any such arguments. + * Now, ansi2knr always does this conversion, and we only + * check for this switch for backward compatibility. + */ + int convert_varargs = 1; + + if ( argc > 1 && argv[1][0] == '-' ) + { if ( !strcmp(argv[1], "--varargs") ) + { convert_varargs = 1; + argc--; + argv++; + } + else + { fprintf(stderr, "Unrecognized switch: %s\n", argv[1]); + exit(1); + } + } + switch ( argc ) + { + default: + printf("Usage: ansi2knr input_file [output_file]\n"); + exit(0); + case 2: + out = stdout; + break; + case 3: + out = fopen(argv[2], "w"); + if ( out == NULL ) + { fprintf(stderr, "Cannot open output file %s\n", argv[2]); + exit(1); + } + } + in = fopen(argv[1], "r"); + if ( in == NULL ) + { fprintf(stderr, "Cannot open input file %s\n", argv[1]); + exit(1); + } + fprintf(out, "#line 1 \"%s\"\n", argv[1]); + buf = malloc(bufsize); + line = buf; + while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) + { switch ( test1(buf) ) + { + case 2: /* a function header */ + convert1(buf, out, 1, convert_varargs); + break; + case 1: /* a function */ + convert1(buf, out, 0, convert_varargs); + break; + case -1: /* maybe the start of a function */ + line = buf + strlen(buf); + if ( line != buf + (bufsize - 1) ) /* overflow check */ + continue; + /* falls through */ + default: /* not a function */ + fputs(buf, out); + break; + } + line = buf; + } + if ( line != buf ) fputs(buf, out); + free(buf); + fclose(out); + fclose(in); + return 0; +} + +/* Skip over space and comments, in either direction. */ +char * +skipspace(p, dir) + register char *p; + register int dir; /* 1 for forward, -1 for backward */ +{ for ( ; ; ) + { while ( is_space(*p) ) p += dir; + if ( !(*p == '/' && p[dir] == '*') ) break; + p += dir; p += dir; + while ( !(*p == '*' && p[dir] == '/') ) + { if ( *p == 0 ) return p; /* multi-line comment?? */ + p += dir; + } + p += dir; p += dir; + } + return p; +} + +/* + * Write blanks over part of a string. + * Don't overwrite end-of-line characters. + */ +void +writeblanks(start, end) + char *start; + char *end; +{ char *p; + for ( p = start; p < end; p++ ) + if ( *p != '\r' && *p != '\n' ) *p = ' '; +} + +/* + * Test whether the string in buf is a function definition. + * The string may contain and/or end with a newline. + * Return as follows: + * 0 - definitely not a function definition; + * 1 - definitely a function definition; + * 2 - definitely a function prototype (NOT USED); + * -1 - may be the beginning of a function definition, + * append another line and look again. + * The reason we don't attempt to convert function prototypes is that + * Ghostscript's declaration-generating macros look too much like + * prototypes, and confuse the algorithms. + */ +int +test1(buf) + char *buf; +{ register char *p = buf; + char *bend; + char *endfn; + int contin; + if ( !isidfirstchar(*p) ) + return 0; /* no name at left margin */ + bend = skipspace(buf + strlen(buf) - 1, -1); + switch ( *bend ) + { + case ';': contin = 0 /*2*/; break; + case ')': contin = 1; break; + case '{': return 0; /* not a function */ + case '}': return 0; /* not a function */ + default: contin = -1; + } + while ( isidchar(*p) ) p++; + endfn = p; + p = skipspace(p, 1); + if ( *p++ != '(' ) + return 0; /* not a function */ + p = skipspace(p, 1); + if ( *p == ')' ) + return 0; /* no parameters */ + /* Check that the apparent function name isn't a keyword. */ + /* We only need to check for keywords that could be followed */ + /* by a left parenthesis (which, unfortunately, is most of them). */ + { static char *words[] = + { "asm", "auto", "case", "char", "const", "double", + "extern", "float", "for", "if", "int", "long", + "register", "return", "short", "signed", "sizeof", + "static", "switch", "typedef", "unsigned", + "void", "volatile", "while", 0 + }; + char **key = words; + char *kp; + int len = endfn - buf; + while ( (kp = *key) != 0 ) + { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) + return 0; /* name is a keyword */ + key++; + } + } + return contin; +} + +/* Convert a recognized function definition or header to K&R syntax. */ +int +convert1(buf, out, header, convert_varargs) + char *buf; + FILE *out; + int header; /* Boolean */ + int convert_varargs; /* Boolean */ +{ char *endfn; + register char *p; + char **breaks; + unsigned num_breaks = 2; /* for testing */ + char **btop; + char **bp; + char **ap; + char *vararg = 0; + /* Pre-ANSI implementations don't agree on whether strchr */ + /* is called strchr or index, so we open-code it here. */ + for ( endfn = buf; *(endfn++) != '('; ) ; +top: p = endfn; + breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); + if ( breaks == 0 ) + { /* Couldn't allocate break table, give up */ + fprintf(stderr, "Unable to allocate break table!\n"); + fputs(buf, out); + return -1; + } + btop = breaks + num_breaks * 2 - 2; + bp = breaks; + /* Parse the argument list */ + do + { int level = 0; + char *lp = NULL; + char *rp; + char *end = NULL; + if ( bp >= btop ) + { /* Filled up break table. */ + /* Allocate a bigger one and start over. */ + free((char *)breaks); + num_breaks <<= 1; + goto top; + } + *bp++ = p; + /* Find the end of the argument */ + for ( ; end == NULL; p++ ) + { switch(*p) + { + case ',': + if ( !level ) end = p; + break; + case '(': + if ( !level ) lp = p; + level++; + break; + case ')': + if ( --level < 0 ) end = p; + else rp = p; + break; + case '/': + p = skipspace(p, 1) - 1; + break; + default: + ; + } + } + /* Erase any embedded prototype parameters. */ + if ( lp ) + writeblanks(lp + 1, rp); + p--; /* back up over terminator */ + /* Find the name being declared. */ + /* This is complicated because of procedure and */ + /* array modifiers. */ + for ( ; ; ) + { p = skipspace(p - 1, -1); + switch ( *p ) + { + case ']': /* skip array dimension(s) */ + case ')': /* skip procedure args OR name */ + { int level = 1; + while ( level ) + switch ( *--p ) + { + case ']': case ')': level++; break; + case '[': case '(': level--; break; + case '/': p = skipspace(p, -1) + 1; break; + default: ; + } + } + if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) + { /* We found the name being declared */ + while ( !isidfirstchar(*p) ) + p = skipspace(p, 1) + 1; + goto found; + } + break; + default: goto found; + } + } +found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) + { if ( convert_varargs ) + { *bp++ = "va_alist"; + vararg = p-2; + } + else + { p++; + if ( bp == breaks + 1 ) /* sole argument */ + writeblanks(breaks[0], p); + else + writeblanks(bp[-1] - 1, p); + bp--; + } + } + else + { while ( isidchar(*p) ) p--; + *bp++ = p+1; + } + p = end; + } + while ( *p++ == ',' ); + *bp = p; + /* Make a special check for 'void' arglist */ + if ( bp == breaks+2 ) + { p = skipspace(breaks[0], 1); + if ( !strncmp(p, "void", 4) ) + { p = skipspace(p+4, 1); + if ( p == breaks[2] - 1 ) + { bp = breaks; /* yup, pretend arglist is empty */ + writeblanks(breaks[0], p + 1); + } + } + } + /* Put out the function name and left parenthesis. */ + p = buf; + while ( p != endfn ) putc(*p, out), p++; + /* Put out the declaration. */ + if ( header ) + { fputs(");", out); + for ( p = breaks[0]; *p; p++ ) + if ( *p == '\r' || *p == '\n' ) + putc(*p, out); + } + else + { for ( ap = breaks+1; ap < bp; ap += 2 ) + { p = *ap; + while ( isidchar(*p) ) + putc(*p, out), p++; + if ( ap < bp - 1 ) + fputs(", ", out); + } + fputs(") ", out); + /* Put out the argument declarations */ + for ( ap = breaks+2; ap <= bp; ap += 2 ) + (*ap)[-1] = ';'; + if ( vararg != 0 ) + { *vararg = 0; + fputs(breaks[0], out); /* any prior args */ + fputs("va_dcl", out); /* the final arg */ + fputs(bp[0], out); + } + else + fputs(breaks[0], out); + } + free((char *)breaks); + return 0; +} diff --git a/dviware/dvgtk/c-auto.h.in b/dviware/dvgtk/c-auto.h.in new file mode 100644 index 0000000000..56c2025d1b --- /dev/null +++ b/dviware/dvgtk/c-auto.h.in @@ -0,0 +1,126 @@ +/* c-auto.h.in. Generated automatically from configure.in by autoheader. */ +/* acconfig.h -- used by autoheader when generating c-auto.h.in. + + If you're thinking of editing acconfig.h to fix a configuration + problem, don't. Edit the c-auto.h file created by configure, + instead. Even better, fix configure to give the right answer. */ + +/* kpathsea/configure.in tests for these functions with + kb_AC_KLIBTOOL_REPLACE_FUNCS, and naturally Autoheader doesn't know + about that macro. Since the shared library stuff is all preliminary + anyway, I decided not to change Autoheader, but rather to hack them + in here. */ +#undef HAVE_BASENAME +#undef HAVE_PUTENV +#undef HAVE_STRCASECMP +#undef HAVE_STRTOL +#undef HAVE_STRSTR + + +/* Define if the closedir function returns void instead of int. */ +#undef CLOSEDIR_VOID + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +#undef SETVBUF_REVERSED + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define if your putenv doesn't waste space when the same environment + variable is assigned more than once, with different (malloced) + values. This is true only on NetBSD/FreeBSD, as far as I know. See + xputenv.c. */ +#undef SMART_PUTENV + +/* Define if you are using GNU libc or otherwise have global variables + `program_invocation_name' and `program_invocation_short_name'. */ +#undef HAVE_PROGRAM_INVOCATION_NAME + +/* all: Define to enable running scripts when missing input files. */ +#define MAKE_TEX_MF_BY_DEFAULT 0 +#define MAKE_TEX_PK_BY_DEFAULT 0 +#define MAKE_TEX_TEX_BY_DEFAULT 0 +#define MAKE_TEX_TFM_BY_DEFAULT 0 +#define MAKE_OMEGA_OFM_BY_DEFAULT 0 +#define MAKE_OMEGA_OCP_BY_DEFAULT 0 + +/* dvgtk: Defined if compiler supports prototypes */ +#undef PROTOTYPES + +/* Define if you have the basename function. */ +#undef HAVE_BASENAME + +/* Define if you have the bcopy function. */ +#undef HAVE_BCOPY + +/* Define if you have the getwd function. */ +#undef HAVE_GETWD + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strstr function. */ +#undef HAVE_STRSTR + +/* Define if you have the strtol function. */ +#undef HAVE_STRTOL + +/* Define if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the header file. */ +#undef HAVE_FLOAT_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#undef HAVE_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_PWD_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_DIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff --git a/dviware/dvgtk/configure b/dviware/dvgtk/configure new file mode 100644 index 0000000000..045ca979e7 --- /dev/null +++ b/dviware/dvgtk/configure @@ -0,0 +1,2544 @@ +#! /bin/sh + +# From configure.in Revision: 0.2 + + + + + + + + + + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-shared build shared libraries [default=no]" +ac_help="$ac_help + --enable-static build shared libraries [default=yes]" +ac_help="$ac_help + --without-maketexmf-default do not run MakeTeXMF if MF source missing" +ac_help="$ac_help + --without-maketexpk-default do not run MakeTeXPK if PK font missing" +ac_help="$ac_help + --without-maketextfm-default do not run MakeTeXTFM if TFM file missing" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=dvgt.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 && (ls -l conftest | grep x) >/dev/null 2>&1' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:550: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:579: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:627: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 && (ls -l conftest | grep x) >/dev/null 2>&1' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:661: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:666: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:690: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=`pwd`/$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=`pwd`/$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:747: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:797: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:829: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:842: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:867: checking for opendir in -ldir" >&5 +ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:908: checking for opendir in -lx" >&5 +ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:950: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:971: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1011: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6 +echo "configure:1115: checking whether closedir returns void" >&5 +if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_closedir_void=yes +else + cat > conftest.$ac_ext < +#include <$ac_header_dirent> +int closedir(); main() { exit(closedir(opendir(".")) != 0); } +EOF +if { (eval echo configure:1129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + ac_cv_func_closedir_void=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_closedir_void=yes +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_closedir_void" 1>&6 +if test $ac_cv_func_closedir_void = yes; then + cat >> confdefs.h <<\EOF +#define CLOSEDIR_VOID 1 +EOF + +fi + +for ac_hdr in assert.h float.h limits.h memory.h pwd.h stdlib.h \ + string.h sys/param.h unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1156: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + + + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1198: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Make sure we can run config.sub. +if $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1231: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`$ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`$ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + + +# +echo $ac_n "checking for libtool object types""... $ac_c" 1>&6 +echo "configure:1255: checking for libtool object types" >&5 +# +## Check that the klibtool script is in ac_aux_dir. Don't bother to +# scan PATH. For one thing, if we found it somewhere there, we couldn't +# use that directory to put the config file ... and that's what we need +# to do, to avoid having to configure in every subdirectory. +LIBTOOL=$ac_aux_dir/klibtool + +if test ! -r $LIBTOOL; then + { echo "configure: error: klibtool not in $ac_aux_dir, goodbye" 1>&2; exit 1; } + exit 1 +fi +# +## Argument parsing: we support --enable-shared and --enable-static. +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + : +else + enable_shared=no +fi + +# +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + : +else + enable_static=yes +fi + +# +# If they explicitly --enable-static, make that the link type. +# More commonly, they will just --enable-shared; make that the link type. +# In either case, prepend to any existing LIBTOOL_OBJTYPES. +# If they really want to build both and link statically, +# then they set LIBTOOL_OBJTYPES to SHARED and --enable-static. +test "$enable_static" = yes && LIBTOOL_OBJTYPES=STATIC:$LIBTOOL_OBJTYPES +test "$enable_shared" = yes && LIBTOOL_OBJTYPES=SHARED:$LIBTOOL_OBJTYPES +# Don't bother to remove the trailing :, it'll be ignored. +# +## Finally: Run the klibtool configure command. +LIBTOOL_OBJTYPES=$LIBTOOL_OBJTYPES RANLIB=$RANLIB \ + $LIBTOOL --config-dir $ac_aux_dir configure "$host" +echo "$ac_t""$LIBTOOL_OBJTYPES" 1>&6 + + for ac_func in basename putenv strcasecmp strtol strstr +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1304: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +LTLIBOBJS="$LTLIBOBJS $ac_func.lo" +fi +done + + + +for ac_func in bcopy getwd +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1362: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1416: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1470: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + + +# This is a GNU libc invention. +echo $ac_n "checking whether program_invocation_name is predefined""... $ac_c" 1>&6 +echo "configure:1493: checking whether program_invocation_name is predefined" >&5 +if eval "test \"`echo '$''{'kb_cv_var_program_inv_name'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + kb_cv_var_program_inv_name=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + kb_cv_var_program_inv_name=no +fi +rm -f conftest* +fi +echo "$ac_t""$kb_cv_var_program_inv_name" 1>&6 +if test "$kb_cv_var_program_inv_name" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_PROGRAM_INVOCATION_NAME 1 +EOF + +fi + +# Some BSD putenv's, e.g., FreeBSD, do malloc/free's on the environment. +# This test program is due to Mike Hibler . +# We don't actually need to run this if we don't have putenv, but it +# doesn't hurt. +echo $ac_n "checking whether putenv uses malloc""... $ac_c" 1>&6 +echo "configure:1529: checking whether putenv uses malloc" >&5 +if eval "test \"`echo '$''{'kb_cv_func_putenv_malloc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + kb_cv_func_putenv_malloc=no +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + kb_cv_func_putenv_malloc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + kb_cv_func_putenv_malloc=no +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$kb_cv_func_putenv_malloc" 1>&6 +if test $kb_cv_func_putenv_malloc = yes; then + cat >> confdefs.h <<\EOF +#define SMART_PUTENV 1 +EOF + +fi + +# Common --with and --enable options. + +# Check whether --with-maketexmf-default or --without-maketexmf-default was given. +if test "${with_maketexmf_default+set}" = set; then + withval="$with_maketexmf_default" + : +else + enableval=yes +fi + +if test $enableval = yes; then + cat >> confdefs.h <<\EOF +#define MAKE_TEX_MF_BY_DEFAULT 1 +EOF + +fi +# Check whether --with-maketexpk-default or --without-maketexpk-default was given. +if test "${with_maketexpk_default+set}" = set; then + withval="$with_maketexpk_default" + : +else + enableval=yes +fi + +if test $enableval = yes; then + cat >> confdefs.h <<\EOF +#define MAKE_TEX_PK_BY_DEFAULT 1 +EOF + +fi +# Check whether --with-maketextfm-default or --without-maketextfm-default was given. +if test "${with_maketextfm_default+set}" = set; then + withval="$with_maketextfm_default" + : +else + enableval=yes +fi + +if test $enableval = yes; then + cat >> confdefs.h <<\EOF +#define MAKE_TEX_TFM_BY_DEFAULT 1 +EOF + +fi + + +# -*- m4 -*- +# Based on aclocal.m4 from wget-1.4.4 by Hrvoje Niksic + + + +# serial 1 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and +# handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + + + + + +echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6 +echo "configure:1685: checking for ${CC-cc} option to accept ANSI C" >&5 +if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# HP-UX -Aa -D_HPUX_SOURCE +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" "-Aa -D_HPUX_SOURCE" -qlanglvl=ansi -std1 "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + cat > conftest.$ac_ext < +# include +#endif + +int main() { + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +; return 0; } +EOF +if { (eval echo configure:1719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + am_cv_prog_cc_stdc="$ac_arg"; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +CC="$ac_save_CC" + +fi + +echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6 +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac + + + +echo $ac_n "checking for function prototypes""... $ac_c" 1>&6 +echo "configure:1741: checking for function prototypes" >&5 +if test "$am_cv_prog_cc_stdc" != no; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define PROTOTYPES 1 +EOF + + U= ANSI2KNR= +else + echo "$ac_t""no" 1>&6 + U=_ ANSI2KNR=./ansi2knr + # Ensure some checks needed by ansi2knr itself. + echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1754: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1767: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + + for ac_hdr in string.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1861: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1871: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +fi + + +for ac_hdr in termio.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1904: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +echo "configure:1942: checking whether byte ordering is bigendian" >&5 +if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_bigendian=unknown +# See if sys/param.h defines the BYTE_ORDER macro. +cat > conftest.$ac_ext < +#include +int main() { + +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif +; return 0; } +EOF +if { (eval echo configure:1960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + # It does; now see whether it defined to BIG_ENDIAN or not. +cat > conftest.$ac_ext < +#include +int main() { + +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif +; return 0; } +EOF +if { (eval echo configure:1975: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_bigendian=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_bigendian=no +fi +rm -f conftest* +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +if test $ac_cv_c_bigendian = unknown; then +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + ac_cv_c_bigendian=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_bigendian=yes +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_c_bigendian" 1>&6 +if test $ac_cv_c_bigendian = yes; then + cat >> confdefs.h <<\EOF +#define WORDS_BIGENDIAN 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:2032: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + + +echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6 +echo "configure:2066: checking whether setvbuf arguments are reversed" >&5 +if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +/* If setvbuf has the reversed format, exit 0. */ +main () { + /* This call has the arguments reversed. + A reversed system may check and see that the address of main + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0) + exit(1); + putc('\r', stdout); + exit(0); /* Non-reversed systems segv here. */ +} +EOF +if { (eval echo configure:2088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + ac_cv_func_setvbuf_reversed=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_setvbuf_reversed=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi + +echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6 +if test $ac_cv_func_setvbuf_reversed = yes; then + cat >> confdefs.h <<\EOF +#define SETVBUF_REVERSED 1 +EOF + +fi + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:2112: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:2134: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h < confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile c-auto.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CPP@%$CPP%g +s%@RANLIB@%$RANLIB%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@LIBTOOL@%$LIBTOOL%g +s%@LTLIBOBJS@%$LTLIBOBJS%g +s%@U@%$U%g +s%@ANSI2KNR@%$ANSI2KNR%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + # Replace lines of the form ac_include foo with the contents of foo: + # first, from the ac_include lines construct a list of sed + # commands to remove them, and include the files; then run sed. + # Have to use sed because old (Ultrix, SunOS) awk does not support + # getline or system. (Anyway, configure scripts aren't supposed to use awk.) + # Use \@...@ form of sed address because the filename may contain /. + # Can't use only one -e and commands {dr foo} because foo has to be last. + # Use @e initially instead of -e because GNU echo has a -e option. + # Use `X' to mean a bunch of backslashes; this is for FreeBSD. + # + # No support for the multiple-output file :-separated stuff. + # + file_substs=`sed -n \ +"/^ac_include/s%ac_include[ ]*\(.*\)%@e 'X@^&@r \1' -e 'X@^&@d'%p" \ + $ac_given_srcdir/$ac_file_in` + if test -n "$file_substs"; then + # Change @e back to -e and X@^ to \@^. + file_subst_cmd="sed `echo $file_substs \ + | sed -e 's/@e/-e/g' -e 's/X@^/\\\@^/g'`" + else + # If no substitutions and hence no sed commands, don't choke. + file_subst_cmd=cat + fi + # cd into the srcdir because the files being included more or less + # must be part of the distribution. I can't find any way to do + # variable substitution in the sed commands (so the user could have, + # e.g., $top_srcdir in their ac_include line). + (cd $ac_given_srcdir && eval $file_subst_cmd $ac_file_in) \ + | sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/dviware/dvgtk/configure.in b/dviware/dvgtk/configure.in new file mode 100644 index 0000000000..118ae24886 --- /dev/null +++ b/dviware/dvgtk/configure.in @@ -0,0 +1,30 @@ +dnl -*- m4 -*- +dnl Process this file with autoconf to produce a configure script. +dnl +dnl dvgtk - Tomasz J. Cholewo +dnl $Id: configure.in,v 0.2 1997/03/28 03:20:02 tjchol01 Exp $ +dnl +AC_REVISION($Revision: 0.2 $)dnl +AC_INIT(dvgt.c) + +sinclude(../kpathsea/common.ac) +sinclude(./ansi2knr.ac) + +dnl Check if we can handle prototypes. It is a bit tricky to +dnl change compiler flags after most of detection stuff happened in common.ac. +dnl It should be done somewhere in its middle. +AM_C_PROTOTYPES + +dnl Checks for header files. +AC_CHECK_HEADERS(termio.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_BIGENDIAN +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_FUNC_SETVBUF_REVERSED +AC_TYPE_SIGNAL + +dnl Create output +AC_OUTPUT(Makefile) diff --git a/dviware/dvgtk/defaults.h b/dviware/dvgtk/defaults.h new file mode 100644 index 0000000000..d9aae39780 --- /dev/null +++ b/dviware/dvgtk/defaults.h @@ -0,0 +1,32 @@ +/* defaults.h - site configuration file for dvgtk + $Id: defaults.h,v 0.1 1997/03/24 01:46:56 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __DEFAULTS_H__ +#define __DEFAULTS_H__ + +/* Initial default values for various dvgtk quantities */ + +/* MetaFont mode used for MakeTeXPK */ +#define DEF_MFMODE "cx" + +/* Resolution */ +#define DEF_XRES 300.0 /* Horizontal resolution in dpi */ +#define DEF_YRES 300.0 /* Vertical resolution in dpi */ + +/* PK and TFM of last resort */ +#define DEF_DUMMY_PK "cmr10.300pk" +#define DEF_DUMMY_TFM "cmr10.tfm" +#define DEF_DUMMY "cmr10" + +/* Paper size: change 1 to 0 to use A4 paper */ +#if 1 +#define DEF_PAPERWD "8.5in" /* letter paper width */ +#define DEF_PAPERHT "11in" /* letter paper height */ +#else +#define DEF_PAPERWD "210mm" /* A4 paper width */ +#define DEF_PAPERHT "297mm" /* A4 paper height */ +#endif + +#endif /* __DEFAULTS_H__ */ diff --git a/dviware/dvgtk/doc/CHANGES b/dviware/dvgtk/doc/CHANGES new file mode 100644 index 0000000000..3f5acd5c0b --- /dev/null +++ b/dviware/dvgtk/doc/CHANGES @@ -0,0 +1,448 @@ +CHANGES - dvgt up to 3.51 - 18:30 GMT +10:00 Wed 25 August 1993. + +---------------------------------------------------------------------- +dvgt 3.4 (3 mod 4) : changes not recorded here. +---------------------------------------------------------------------- + +1. - 18:17 GMT +10:00 Thu 18 Mar 1993 - +options.c : + Added DV_TERM environment variable, to override TERM. + +2. - Sun 2 May 1993 - +fontreader.c, lstring.c, lstring.h : + Length specified strings introduced to make the TFM and PK font + file specification string formation more controlled. + +3. - Sun 2 May 1993 - + Using strncpy widely in place of strcpy, to keep string memory + accesses within bounds. + +4. - 17:48 GMT +10:00 Mon 3 May 1993 - +ncsatelvdu.c, vduinterface.c : + Added Vijay's (vijay@ncst.ernet.in) NCSA Telnet driver. + Now my picture is clear. + +5. - About or before Sun 9 May 1993 - +defaults.h : + Added constant "DEF_DUMMY_TFM", in case I implement such a thing. + +6. - 21:22 GMT +10:00 Sun 9 May 1993 - +All drivers and other files that referred to "tek4010vdu" : + Renamed: tek4010vdu.c -> tek4010emu.c + tek4010vdu.h -> tek4010emu.h + This was because some users have been misled by the name to think + that these files were for a true TEK4010 terminal. But they are + not: they are only for the use of the TEK4010 emulating drivers. + +7. - 21:20 GMT +10:00 Mon 10 May 1993 - +In all *.c files that use exit() : + All deliberate exits produce a message. + + (I don't account for outside interruptions, such as power failures.) + +8. - 21:24 GMT +10:00 Mon 10 May 1993 - + All message text is logged in a file named `.vlg', + where the DVI file is named `.dvi'. + If that log file cannot be opened, then `dvgt.log' is opened. + If then `dvgt.log' cannot be opened, dvgt exits with a message. + +9. - Tue 11 May 1993 - +fontreader.c : + TFM and PK font paths may now contain multiple directories. + For example, "setenv PKFONTS .:/usr/local/lib/tex/fonts/tmp" + allows searching in current directory, then in the other location. + +10. - Tue 11 May 1993 - +fontreader.c : + Dummy font's file specification is now formed in the same way + as other PK fonts. + +11. - 20:02 GMT +10:00 Wed 12 May 1993 - +dvitovdu.c : + Inability to write a log file no longer exits dvgt. + Instead, logfile is set NULL, and subsequently ignored. + Some other exits deleted as due to non-fatal conditions. + +12. - 20:02 GMT +10:00 Wed 12 May 1993 - +config.h, globals.h, dvitovdu.c, fontreader.c : + "bitmap_rec" replaced by "Word" which I typedef as int. + Bitmaps are dynamicaly allocated, so they can be much smaller + or much larger, as the case requires. + +13. - 22:06 GMT +10:00 Wed 12 May 1993 - +fontreader.c : + Fatal message "Couldn't open dummy font!" is now written to the + terminal, after resetting VDU, and appears cleanly - at least + after use of the "ncsatel" vdu mode. + +14. - 22:06 GMT +10:00 Wed 12 May 1993 - +dvitovdu.c : + The following signals are caught so that the screen may be reset + before exit: SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM. + Any other signal is also caught! + +15. - Fri 14 May 1993 - +tek4010emu.c : + In Terse mode, i.e. in TEK4010ShowChar(), the unrepresented font + characters, previously shown as '?', are now displayed as + hexadecimal escape sequences. E.g., code 1 appears as '\01'. + +16. - Fri 14 May 1993 - +dvitovdu.c : + 'N' and 'P' commands now page forward and back, to the next and + previous page, respectively. + So, the '<' and '>' commands are deleted. + +17. - Fri 14 May 1993 - +dvitovdu.c : + Added control-L command to refresh screen. + +18. - Fri 14 May 1993 - +dvitovdu.c : + Units are now changed by a 'C' command. The 'C' may be followed by + zero or more spaces, and then the unit name. (The actual unit names + are as before: IN, CM, MM, PT, BP, PC, BP, SP and PX.) + +19. - Fri 14 May 1993 - +dvitovdu.c, help.h : + The '?' interactive command help is now integrated into the source + code, in "help.h", using a ShowText() function. + +20. - Sun 16 May 1993 - +dvitovdu.c, tek4010emu.c : + The "F" (Full), "B" (Box) and "T" (Terse) commands are now toggles. + Any combination of these display modes is now accepted. + Change necessary to tek4010emu.c, to correct a faulty assumption at + the beginning of TEK4010ShowChar(). + +21. - Sun 16 May 1993 - +dvitovdu.c : + The "A" Auto window command is now a toggle. + +22. - Mon 17 May 1993 - +dvitovdu.c : + BoxChar() is now used in place of FullCharPS in Full mode when a TFM + gives the Bounding Box information, because I prefer outlines to + solid rectangles. + +23. - Fri 21 May 1993 - +fontreader.c, dvitovdu.c : + BuildFontSpec() and PixelTableRoutine() have been altered, so that + dvgt seeks a PK font first, then a TFM, then the dummy PK font. + Consequently, the PostScript prefix code and option are eliminated. + +24. - Fri 21 May 1993 - +vdu.h, vduinterface.c, dvitovdu.c : + For each VDU, the value "vdu_clears_lines" is set true if the VDU + can clear a single line. The "ncsatel" driver cannot, due to a + property of the Tek4010 terminal and (I suppose) its emulators. + So, for the "ncsatel" vdu, when the Status lines should be updated, + the whole display is now updated. + +25. - Sun 23 May 1993 - +userguide.tex, sysguide.tex, guidemacs.tex : + Updated Andrew Trevorrow's documentation to reflect Ian Dall's port + of DVItoVDU to C and features of dvgt 3.5. + +26. - Mon 24 May 1993 - +In all files that used "__((void))" : + In "config.h", VOID is defined as "void" for ANSI C, empty otherwise. + All function and function pointer declarations and definitions + that used "__((void))" now use "(VOID)" instead. + This helps "tags" and "ctags" programs to identify functions + correctly. (It also marginally reduces source code size.) + +27. - Tue 25 May 1993 - +options.c : + Fixed "-r" option to interpret "-r x,y" to set the X and Y resolutions + to x and y respectively. Retained "-r x" to set the X and Y resolutions + to the common value x, and "-r" to display the default resolutions. + +28. - Tue 25 May 1993 - +defaults.h, options.c: + Renamed the constant DEF_HELP_FILE to DEF_CMD_HELP, + and renamed the environment variable DV_HELP to DV_CMD_HELP. + +29. - Tue 25 May 1993 - +defaults.h, options.c, fontreader.c : + Fall back to dummy TFM, in case dummy PK not found. + Added env. var. DV_DUMMY_TFM. + Renamed DV_DUMMYFONT to DV_DUMMY_PK. + +30. - Wed 26 May 1993 - +options.c, defaults.h : + Added DV_PAPERWD and DV_PAPERHT env. vars. + These and DEF_PAPERWD and DEF_PAPERHT now accept dimensions, + else they default to inches. + +31. - Wed 26 May 1993 - +defaults.h, options.c : + Renamed DEF_IMMEDIATE_HELP to DEF_IMMED_HELP. + +32. - Wed 26 May 1993 - +dvgt/help directory: + Renamed "help" file to "cmd.help". + +33. - Sun 30 May 1993 - +defaults.h, options.c : + Renamed DEF_XRESOLUTION to DEF_XRES and DEF_YRESOLUTION to DEF_YRES. + Renamed DEF_PSPREFIX to DEF_PS_PREFIX. + +34. - Sun 30 May 1993 - +options.c : + Resolution option "-r" now allows one or two ("xres,yres") arguments. + Added DV_RES environment variable for both X and Y resolutions. + Renamed env. var. DV_PSPREFIX to DV_PS_PREFIX. + +35. - Mon 31 May 1993 - +dvireader.h, fontreader.c, dvitovdu.c : + Added "honest" field to "fontinfo" structure. This records whether + the true font (for the given fontname) is specified in the fontspec. + Now have "psfont", "pkfont" and "honest" fields to guide treatment + of fonts and their description by ShowStatistics. + +36. - Mon 31 May 1993 - +dvitovdu.c : + ShowStatistics shows either "H" or "S", and either "P" or "K" or "T", + to indicate whether the font used is Honest or a Substitute, and + whether it is a PostScript font TFM, a PK font bitmap, or a + non-PostScript TFM, respectively. + ShowStatistics also shows fontsize (in pt), and the font description + is more compact, to allow for the extra info. Attempted to align + lines of info. for different fonts. + +37. - Mon 31 May 1993 - +fontreader.c : + Font search order is now: + PK -> PS -> TFM -> dummy PK -> dummy TFM -> fail. + +38. - Mon 31 May 1993 - +dvitovdu.c : + Added time info (ANSI C only), to logfile. + +39. - Tue 1 June 1993 - +dvgt/src and dvgt directories: + Moved CHANGES and TODO files from dvgt/src to dvgt directory. + +40. - Tue 1 June 1993 - +dvitovdu.c : + Default Left, Right, Up and Down movements are by _half_ the window + dimension (instead of by the full dimension). + +41. - Tue 1 June 1993 - +dvitovdu.c : + Zoom In/Out to/from Centre of window (instead of Top Left corner). + +42. - Wed 2 June 1993 - +fontreader.c : + Multiple PS font prefixes, separated by same characters (in DIRSEP) + as (PK and TFM) directories. In dvgt 3.5, which is for unix, + DIRSEP = ":", a colon. + +43. - Thu 3 June 1993 - +fontreader.c, dvitovdu.c : + Font search is now: + PK -> PS -> dummy PK -> TFM -> dummy TFM -> DVI Terse. + So, if no other representation can be found, then a missing font + is guesstimated using the design size in the DVI file, and displayed + as in Terse mode. Other fonts are unaffected. + Currently, I estimate character size in design size units as 1 unit + high and 0.5 unit wide. This seems not too far off-mark for normal + text; preview of "example.dvi" is too wide by about one part in + eight. + (Another possibility, allowed by the DVI Standard, Level 0, is to + ignore such fonts entirely, but that would give the user less + information.) + +44. - Fri 25 June 1993 - +options.h, options.c, fontreader.c, dvitovdu.c : + C variable "fontdir" renamed to "pkdir". + +45. - Mon 19 Jul 1993 - +help and src directories: + Updated cmd.hlp, immed.hlp, options.hlp, and help.h, for dvgt 3.5's +commands, options, and VDU types. + +46. - Wed 21 Jul 1993 - +doc directory: + Updated sysguide.tex, userguide.tex to reflect dvgt 3.5's options +and commands. + +47. - Wed 21 Jul 1993 - +version.h, dvitovdu.h, help.h : + Renamed C quantity "version" to "dvgt_version", because of clash +with an enumerated type of the same name in System V's . + +48. - Wed 21 Jul 1993 - +dvitovdu.c : + Renamed C static variable "signals" to "common_signals", in case of +a clash, and eliminated the "extern int signals" line. + +49. - Wed 21 Jul 1993 - +Makefile.dvgt : + Added "regisvdu.h" to list of files to distribute. (Bad oversight!) + +50. - Wed 21 Jul 1993 - +fontreader.c : + Changed test of the boolean function OpenFontFile from the +erroneous "< 0" to the correct test for true. + +51. - Wed 21 Jul 1993 - +Makefile.sun : + Removed references to site specific include directories. + +52. - Mon 2 Aug 1993 - +unixio.c : + In non-BSD OS's, used TCGETA, TCSETAW with ioctl. + (Suggested by Guy Harris.) + +53. - Mon 2 Aug 1993 - +unixio.c, Makefile.aix, Makefile.sun : + Used "string" in unixio.c; so add dependency on "globals.h". + +54. - Mon 2 Aug 1993 - +src/dvitovdu.c, doc/userguide.tex : + Reverted to ZI, ZO holding window's top left; +introduced ZCI, ZCO to hold window's centre. + +55. - Tue 3 Aug 1993 - +screenio.c : + MesgLine now unsets raw mode, if it's on (so that NL -> CR+NL), +and finally restores it, if it was. + +56. - Tue 3 Aug 1993 - +doc directory : +sysguide.tex, userguide.tex updated. + +57. - Tue 3 Aug 1993 - +dvitovdu.c : + Defer call to InitScreenIO, so that "fprintf (stderr, ...);" will +have the normal line discipline. + +58. - Wed 4 Aug 1993 - +dvitovdu.c, dvireader.c, options.c, vdu.c : + Delete old DEBUG code that wrtes to stderr. + +59. - Wed 4 Aug 1993 - +unixio.c, unixio.h, screenio.c : + Separate initial and temporary tty state. + +60. - Wed 4 Aug 1993 - +dvitovdu.c, dvireader.c, (fontreader.c), (options.c), vdu.c : + Ensure that RestoreTerminal is called immediately before each exit. + +61. - Wed 4 Aug 1993 - +options.c : + In DimenPixels, account for unimplemented unit, in the newer code. + +62. - Wed 4 Aug 1993 - +dvitovdu.c : + In main, save initial terminal settings, early, using save_init_tty. + +---------------------------------------------------------------------- +RELEASE of dvgt 3.5 to SHSU (hence to CTAN). +---------------------------------------------------------------------- + +63. - Mon 16 Aug 1993 - +new.h : + Deleted #ifndef Malloc ... #endif around #include "config.h" . + Replaced #ifdef __STDC__ by #ifdef HAS_STDLIB . + +64. - Mon 16 Aug 1993 - +config.h : + Big rearrangement and recoding, to allow for an ANSI compiler (eg, +gcc) with a non-ANSI library (eg, Sun/OS 4.0 's BSD-like cc library). + Added #include and #include for when +BSD is true. + Also for when BSD is true, added twelve further (non-ANSI style) +function declarations. + Added also for non-BSD library with non-ANSI +compiler. + Now #define GNUC_LIB if and only if ANSI compiler with non-BSD +library. + +65. - Tue 17 Aug 1993 - +options.c : + Moved #define NEW_DIMEN_PIXELS to top of file. + Deleted inclusion and getenv() declaration, as config.h +already handles those. + Added code to protect (eg, ANSI C compilers') use of constant +storage for strings from Sun/OS 4.0 's library's sscanf function's +use of ungetc. + Added ToLower debugging code. + Changed definition of ToLower to always check for isupper. + Deleted block from around ToLower and Luname. + +66. - Tue 17 Aug 1993 - +Makefile.cc-sun : + New Makefile for Sun/OS 4.0 's non-ANSI compiler, "cc". + Mentions dependency on and . + +67. - Wed 18 Aug 1993 - +dvitovdu.c, dvireader.c : + SetConversionFactor's magnification argument now has the +interpretation that 1 corresponds to the document's normal size. +Non-ANSI compilers don't convert int mag to double magnification, +so dvitovdu.c now calls SetConversionFactor with its magnification +argument = mag/1000.0, to coerce it to be double. + +68. - Wed 18 Aug 1993 - +options.c : + Deleted ToLower debugging code. + +69. - Wed 18 Aug 1993 - +config.h : + Deleted "#include " from STDC, non-BSD case, because it +duplicated that in the general non-BSD case. + +70. - Wed 18 Aug 1993 - +version.h : + Version upped to "3.51". + +71. - Wed 18 Aug 1993 - +Makefile.gcc : + New. (Based on gcc code in old "Makefile.sun".) + +72. - Wed 18 Aug 1993 - +Makefile.sun : + Now refers only to Sun's "cc" compiler. + Deleted comments referring to , and . + +73. - Fri 20 Aug 1993 - +options.c : + PK search now = TEXPKS || PKFONTS || TEXFONTS || DEF_PK_DIR. + +74. - Fri 20 Aug 1993 - +new.h : + Deleted code, because "config.h" already handles that. + +75. - Fri 20 Aug 1993 - +TODO : + Added wish to "Make TFM, PK path and file spec. strings dynamic." + +76. - Fri 20 Aug 1993 - +Makedist.dvgt : + Added line for "dvgt/src/Makefile.gcc". + +77. - Fri 20 Aug 1993 - +README : + Refer to Makefile.gcc; change description of Makefile.sun. + +78. - Fri 20 Aug 1993 - +Makedist.dvgt : + Added "sane" Bourne shell script for resetting terminal, in case +dvgt leaves it seriously messed up. + +79. - Fri 20 Aug 1993 - +misc/stdlib.h : + Emended non-ANSI function declarations. + Added headlines with date. + +80. - Wed 25 Aug 1993 - +README, userguide.tex : + Updated for dvgt 3.51, specifically the use of TEXPKS. + +---------------------------------------------------------------------- +dvgt 3.51 : 3 mod 5 revision 1. +---------------------------------------------------------------------- + diff --git a/dviware/dvgtk/doc/Makefile b/dviware/dvgtk/doc/Makefile new file mode 100644 index 0000000000..58e0c10bbe --- /dev/null +++ b/dviware/dvgtk/doc/Makefile @@ -0,0 +1,24 @@ +# Makefile for DVItoVDU documents. 18:56 Tue 11 May 1993. Geoffrey Tobin. + +.tex.dvi: + tex $< + +dvi: guidemacs.tex example.dvi sysguide.dvi tripvdu.dvi userguide.dvi + +# AIX make is not very smart: it cannot follow the .tex.dvi line. +# Sun/OS make has no trouble. + +example.dvi: example.tex + tex example + +sysguide.dvi: guidemacs.tex sysguide.tex + tex sysguide + +tripvdu.dvi: tripvdu.tex + tex tripvdu + +userguide.dvi: guidemacs.tex userguide.tex + tex userguide + +clean: + rm *.dvi *.log diff --git a/dviware/dvgtk/doc/README b/dviware/dvgtk/doc/README new file mode 100644 index 0000000000..3d7c29fbf5 --- /dev/null +++ b/dviware/dvgtk/doc/README @@ -0,0 +1,426 @@ +README - 18:22 GMT +10:00 Wed 25 August 1993 - Geoffrey Tobin. +- for "dvgt 3.51", + alias: "DVItoVDU version 3.0, gt modification 5 revision 1". + +Addresses: ecsgrt@luxor.latrobe.edu.au + gt@ee.latrobe.edu.au + + +DVItoVDU, also known as "dvitovdu", "dvi2vdu", and "dv", is a public +domain screen previewer for TeX DVI files using PK fonts. It was +invented long ago by Andrew Trevorrow (author also of OzTeX, a TeX +for Macintoshes), and has passed through several hands since. + +"dvgt" is a modification of Ian Dall's "dv" (a C translation of a +Pascal (or Modula-2 ?) version of DVItoVDU 3.0). Some bug fixes have +been applied, and the source has been ported to the IBM Risc/6000 +under AIX using the "xlc" compiler. It is also compilable on Sparc 1 +workstations under Sun/OS using the Gnu C compiler, "gcc", and may +- perhaps with minor changes - also compile under some traditional +(Kernighan and Ritchie, _The C Programming Language_, first edition) +C compilers. + +This previewer is neither sophisticated nor pretty, but it can drive +a number of common visual display terminals, such as VT series, Gigi, +Regis, VK100, VIS series, and terminals that emulate Tek4010. (Not a +real Tek4010, sadly.) A full list of supported terminals is contained +in the immediate help file, "immed.hlp", and in the "options.hlp" +document. + +** Currently, those who wish to use a Tek4010 emulation are advised +to try the terminal types kermit, ncsatel, tek4010, vis500, vis550, +vis630 or vt640. ** + +I first used dvgt on a Sun Sparc 1 to preview DVI files in Terse mode +(like ascii) on a remote vt220 terminal. Now I use its "ncsatel" +driver (coutesy of Vijay, vijay@ncst.ernet.in, in India) to view in +Full (graphics) mode on a PC connected over NCSA Telnet to the dvgt +host machine, using Tek4010 emulation. The Tek4010 emulation drivers +kermit, ncsatel and tek4010 also work with MS-Kermit 3.12. + + +NOTE WELL: + +1. Current directory (and upper-level file) structure is: + + Makefile.dvgt dvgt/ + CHANGES README TODO doc/ help/ misc/ src/ + +The documents in doc/ are based on Andrew Trevorrow's Modula-2 version, +but they now have been updated for dvgt 3.5. Not every version +of DVItoVDU has the full collection of documents. Hopefully, they're +all gathered here. If not, please lead me to any omitted files. + +The single file in the misc/ subdirectory, "stdlib.h", is inherited +from Ian Dall's version. It's there in case someone wishes to port to +a system that lacks a suitable header for the C standard library. +However, it's not needed for either the AIX or the Sun/OS port. + +2. The "src" source directory's Makefile must be correct for your +machine, operating system and compiler. + +Three Makefiles are provided: + + Makefile.aix for IBM machines (such as the Risc/6000) running AIX. + Makefile.gcc for gcc (tested on Suns and Sparcs running Sun/OS 4 and 5). + Makefile.sun for Suns and Sparcs running Sun/OS, with Sun's non-ANSI cc. + +These can serve as templates for other Makefiles. (I made the AIX and +gcc ones from the Sun Makefile.) + +Copy the appropriate one to "Makefile", then edit it to suit your +site. + +3. The source header "defaults.h" needs to be customised for each site, +as it contains absolute directory information. (Even though these +paths may be overridden by environment variables, it's more convenient +if they point to where the system manager puts the appropriate files.) + +(The files "dvitovdu.c" and "options.c" include "defaults.h".) + +4. The source header "config.h" also needs attention. + +Especially be sure that either LITTLE_ENDIAN or BIG_ENDIAN is defined +correctly for your machine, and remember that if you define both, then +LITTLE_ENDIAN will prevail. + +(The C source files use "config.h". Also, "unixio.h" assumes that +"config.h" has been read before it.) + +5. In setting the environment variables on the system, or on your own +account, be careful to set them sensibly. I once set DV_IMMED_HELP to +point to a directory by mistake, and when I typed just "dvgt", instead +of getting immediate help, I saw a line consisting of leading spaces +and a dot. + +The C shell script, "dv-env", in the src directory, is a sample for +setting dvgt's environment variables. + +6. Note that page drawing can (as in the original dvitovdu) be +interrupted by a carriage return, but only _between_ characters and +rules. A very large character or rule won't be interrupted, even +though this means waiting for some time. + +7. To get the best appearance for dvgt's output when using it over +MS-Kermit 3.12, set the following in your MSCUSTOM.INI : + + set terminal flow-control none + set terminal graphics character-writing opaque + set terminal graphics cursor off + +The first line gets rid of most of the ^S and ^Q characters that may +otherwise appear on the dvgt command line. The second causes message +lines to overwrite opaquely, which makes the messages in certain +drivers much more readable. The third renders the graphics cursor +invisible. + +Because one ^S^Q pair still remains on my command line when I use +MS-Kermit 3.12, despite the above precaution, I've made the ^Q and ^S +characters into no-op commands in dvgt. + + +BRIEF HISTORY. + +The initial C code for this version of DVItoVDU was copied from Ian +Dall's site, augean.oz.au : pub/misc/dv.tar.Z. Ian had, as his source +code seems to indicate, automatically translated it from Pascal. +(Andrew Trevorrow wrote the original DVItoVDU in Modula-2.) + +A thorough history of the various versions of "dvitovdu", "dvi2vdu", +and "dv" in the world is beyond the scope of this README file, and +exceeds my competence. + +Version 3.4 was the first public release of dvgt. It was uploaded to + + Niord.SHSU.edu + +and subsequently propagated to the CTAN sites: + + ftp.shsu.edu + ftp.tex.ac.uk + ftp.uni-stuttgart.de + + +SUMMARY of CHANGES to dvitovdu 3.0 in the "gt" MODS up to "mod 5". + +1. Commands. + +U (Up), D (Down), L (Left) and R (Right) now move by half a screen +(instead of a full screen), to retain more context. + +The zoom commands, ZI and ZO, now take an optional argument, the zoom +factor. The initial default zoom is 2. When a new zoom factor is +specified, that becomes the new default value. This value is +displayed at the far right in the top line of the screen. + +Whereas ZI and ZO maintain the top left of the window stationary, +ZCI and ZCO zoom in and out relative to the window's centre. +These have very nearly the same effects as DR ZI UL and DR ZO UL, +respectively. + +Two new units commands, BP for big point, and SP for scaled point, +have been added, because TeX has these, and because big point +(1/72 inch) is the American standard point, used by PostScript. + +Units are now set by the C command, which allows zero or more +spaces between it and the following unit. For example: + + C IN + CMM + C PX + +The < and > commands have been deleted, in favor of N always paging +forwards, and P paging back. + +The T (Terse), B (Box), F (Full) are now toggles, and any combination +of these can be applied simultaneously. If all are off, then font +characters will not show, but rules will. + +The A (Auto window scaling) command has been made a toggle. +A+ and A- no longer exist. + +Control-L (^L, ascii character 12 decimal, 14 octal, C hexadecimal) +is a new command to refresh the page. The usual command line parsing +still applies, so the page is not refreshed until after a carriage +return is typed. + +Control-Q (^Q) and Control-S (^S) do nothing. + +2. Help. + +There are now three help files, "cmd.hlp", "immed.hlp" and "options.hlp". + +If dvgt can find "immed.hlp" - ie, if the environment variable +DV_IMMED_HELP points to it - then a novice user, who types simply "dvgt" +on the command line, will see "immed.hlp" displayed. Otherwise, the +file listed in "defaults.h" as "IMMEDIATE_HELP", is displayed. If +even that cannot be opened, then the precompiled message from "help.h" +is shown - this is intended to be very similar to "immed.hlp". + +Also, if a command line option is typed without an argument, as, eg, +"dvgt -f", then dvgt will describe the option. Another example is +"dvgt -i", which has no valid argument, and prints out the current +pathname of the immediate help file. + +Once in the program, the command "?" as before, will display the +"cmd.hlp" file, which has been updated because of the changes to the +commands. If that file cannot be found, then the precompiled command +help text is displayed. + +The file "options.hlp" is an expanded version of "immed.hlp", to +describe the options more fully. dvgt does not read "options.hlp": +the user is directed to do that for her/himself. + +3. Environment Variables and Command Line Options. + +There are now a variety of environment variables that the installer of +the program is supposed to set before dropping "dvgt" on the poor users. +Otherwise, the user must specify options to "dvgt" to override defaults. +Here is a table (not in TeX, as this is a README file). + + +Option Program Environment Constant in Purpose + Variable Variable "defaults.h" + + -H hoffset --- --- Horizontal page offset, + in given units. + + -V voffset --- --- Vertical page offset, + in given units. + + -d dummy_pk DV_DUMMY_PK DEF_DUMMY_PK Dummy PK font, used when + correct font's absent. + + -e dummy_tfm DV_DUMMY_TFM DEF_DUMMY_TFM Dummy TFM, used when + correct TFM's absent. + + -f pkdir TEXPKS DEF_PK_DIR PK fonts' directory. + else + PKFONTS + else + TEXFONTS + + -h cmd_help DV_HELP DEF_CMD_HELP Help file for "?" command. + + -i immed_help DV_IMMED_HELP DEF_IMMED_HELP Give help at startup. + + -l landscape --- --- Landscape page dimensions. + + -m mag --- --- Magnification. + + -p psprefix DV_PSPREFIX DEF_PS_PREFIX Prefix in PS font names. + + -r xres, DV_RES DEF_XRES, X and Y resolutions, + yres DEF_YRES in dots per inch (dpi). + + -t tfmdir TEXFONTS DEF_TFM_DIR TFM metric files' directory. + + -v vdu DV_TERM --- Terminal type. + else + TERM + + -x paperwd DV_PAPERWD DEF_PAPERWD Paper width, + in given units. + + -y paperht DV_PAPERHT DEF_PAPERHT Paper height, + in given units. + + +Command line options override environment variables, which override +the constants in "defaults.h". + +TEXPKS (as used by Rokicki's dvips) is used for the PK fonts +directory, but if it is absent, then PKFONTS is used; if that is +also absent, then TEXFONTS is used. + +Since TERM is usually set in every users' account, there is no +hard-wired value for the terminal in "defaults.h". Often, however, +for example when using NCSA Telnet for viewing, it is necessary to +have a different terminal type for dvgt than for the regular screen +mode; to avoid confusion, dvgt will use the terminal type given in the +environment variable DV_TERM (if it exists) in preference to that in +TERM. + +4. Terminal names. + +The vdu names `kermit', `ncsatel' and `tek4010' are synonyms for the +NCSA Telnet driver. + +5. Bitmaps. + +Dynamic memory allocation of bitmaps replaces the old static +allocation. Small glyphs now require little memory, and huge glyphs +(such as those in mfpic(*) picture fonts) can be viewed. + +(*) Mfpic is a macro package by Thomas Leathrum (moth@dartmouth.edu) +to enable TeX to draw graphics using MetaFont. Such graphics are +viewable by almost any TeX DVI previewer. + +6. PK and TFM multiple path searching. + +Multiple paths have been implemented for TFM and PK file directories +under unix. For instance, + + .:/usr/local/lib/tex/fonts + +will seek the TFM files in the current directory, and then in the +directory /usr/local/lib/tex/fonts (where they are found on a +significant number of systems). This enables the regular TEXFONTS +environment variable (if used for TeX) to be employed for dvgt. + +Similarly for PK fonts (env. vars. TEXPKS, PKFONTS), though less +flexibly as subdirectory searching is not implemented in dvgt 3.5 and +TeX installations can differ markedly in how they place PK fonts. + +7. Font substitution strategy. + +When a font is missing, dvgt 3.5 tries each of several replacements +in turn. Briefly: + + PK -> PS -> dummy PK -> TFM -> dummy TFM -> DVI Terse. + +In words, if the correct PK bitmap (plus or minus one dot per inch in +its resolution) is found, then that is used. + +Otherwise, if the font is identified as a PostScript font (using the +list of PostScript prefixes) and the correct TFM is found, then +display the TFM bounding boxes (in outline - previous versions used +solid blocks). + +If that fails, then display the dummy PK font, provided that it can +be found. + +Otherwise, try the correct TFM metric file. + +If that is missing, then seek the dummy TFM metric file. + +If nothing else succeeds, then use the font's scaled size from the +DVI file, assuming heights equal to the scaled size and widths of half +the scaled size. Display the characters of such a font in Terse mode. +(Other fonts are unaffected.) + + +FILE TIMES and DATES. + +The times and dates in the various files of this distribution are the +modification times of those files. "GMT" signifies Greenwich Mean +Time, and "GMT +10:00" means ten hours in advance of GMT. In the +absence of "GMT", the time is local to Melbourne, Victoria, Australia. + + +ACKNOWLEDGMENTS. + +Andrew Trevorrow, for developing DVItoVDU, which has stood the test of +time. + +Masahiro Kitagawa (kitagawa@will.ntt.jp), for inventing the Japanese +versions 1.0J and 1.1J, for encouraging me in this work, and for much +advice, including the original recommendation of Ian Dall's port, of +which I was hitherto oblivious. Also for reporting user-hostile +deficiencies in dvgt's error handling. + +Ian Dall, for porting version 3.0 to C. + +The many others who have enhanced, ported and otherwise improved +one branch or another of DVItoVDU's family tree over the years. + +Guy Harris and Dave Curry for each pointing out a bug in the System +Vr4 and Solaris code of `unixio.c'. + +The patient testers, many of whom are still waiting for code that will +drive a true Tek4010 graphics terminal or a VGA monitor, and one or +two other things. I wish I could have delivered these features, but +my Winnie-the-Pooh brain was sorely taxed by trying to make sense of +AIX's C compilers (cc, c89, xlc), not to mention the differing header +files and object libraries on BSD and System Vr4 and hybrids thereof. + +If it's any consolation to those who're missing a desired feature, +Masahiro wrote to me that "dvgt" (since version 3.4) works fine with +Japanese text. + +La Trobe University Computer Services and the Department of Electronic +Engineering, for providing the resources by which DVItoVDU became +dvgt, and dvgt has been maintained. + +The archivers, who kindly donated machine resources and their own +time and effort, to provide a place for this software to rest. +Without their generosity, many of you would not be reading this. + +IBM, for inventing the Risc/6000. AIX? Well, it's a long story ... + + +PLEAS. + +Suggestions for improvements of "dvgt" are welcome. +So is practical advice. Here is a brief wish list for enhancements +which are beyond my current reach. + +1. If you know how to drive a true Tek4010 terminal (copy from +Gnuplot?), and would can implement this in dvgt, you may make at least +one other user happy. + +2. An EGA/VGA driver that functions over MS-Kermit or Telnet would be +very helpful! I was told that (part of) the driver must reside on the +PC, but TSRs and such are out of my league. + +3. Someone with a strong stomach might attempt to make the data +structures more "object-oriented", I mean "easy to modify correctly". +Tread _very_ carefully! + +4. Make dvgt fully conformant with the TUG DVI Driver Standard, +wherever appropriate. + +5. Also see the "TODO" file. + + +DISCLAIMER. + +dvgt is _not_ conformant with the TUG DVI Driver Standards Committee's +_DVI Driver Standard, Level 0_, for ``minimally functional'' DVI +processors, although I have a copy of draft 0.5 of that document +(from CTAN). [See if you can spot the differences: some of them are +flagged in the source code.] + + +All the Best! +Geoffrey Tobin diff --git a/dviware/dvgtk/doc/TODO b/dviware/dvgtk/doc/TODO new file mode 100644 index 0000000000..5b15511436 --- /dev/null +++ b/dviware/dvgtk/doc/TODO @@ -0,0 +1,36 @@ +TODO - for dvgt 3.5 - 21:22 GMT +10:00 Fri 20 August 1993 - Geoffrey Tobin. + +1. Subdirectory searching? + +2. Scale substitute PK and TFM files (like zoom, but restricted to + one font), to match the scaled size of the missing font. + +3. More VDU drivers. + +4. Allow an output character recoding file? + That might be useful where the glyph encoding differs from ascii, + or, more generally, from the encoding of the display. + One way would be pairs of (hexadecimal?) integers. + Might allow "D" for decimal, "C" for ascii character, + "X" for hexadecimal, and "O" for octal, as in Knuth's TFM files. + Default would be which `number system'? + + To Terse mode, add a user-definable glyph encoding? + (Currently uses an encoding based on cmr10.) + Employ a character recoding file, which the user could alter? + + Virtual Fonts? + A fanciful dream, that one. + +5. Macros? + +6. String Search in the DVI file. + +7. Conform dvgt to TUG's DVI Driver Standard, Level 0, at least more + nearly. + +8. Choose different DVI files interactively? + +9. Make TFM, PK path and file spec. strings dynamic. + +Geoffrey Tobin diff --git a/dviware/dvgtk/doc/ansi2knr.1 b/dviware/dvgtk/doc/ansi2knr.1 new file mode 100644 index 0000000000..434ce8f042 --- /dev/null +++ b/dviware/dvgtk/doc/ansi2knr.1 @@ -0,0 +1,19 @@ +.TH ANSI2KNR 1 "31 December 1990" +.SH NAME +ansi2knr \- convert ANSI C to Kernighan & Ritchie C +.SH SYNOPSIS +.I ansi2knr +input_file output_file +.SH DESCRIPTION +If no output_file is supplied, output goes to stdout. +.br +There are no error messages. +.sp +.I ansi2knr +recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line. +.sp +The following constructs will confuse it: +.br + - Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call). +.br + - Macros that tinker with the syntax of the function header. diff --git a/dviware/dvgtk/doc/example.tex b/dviware/dvgtk/doc/example.tex new file mode 100644 index 0000000000..858ad3b9bb --- /dev/null +++ b/dviware/dvgtk/doc/example.tex @@ -0,0 +1,232 @@ +% This is the TeX source file for the "TeXnical Typesetting" document. +% Notice how you can put in comments? If TeX sees a % it simply ignores +% the rest of the line. + +% A4 paper is 8.3in wide and 11.7in high; we set the page dimensions so that +% there are 1in margins all around: +\hsize 6.3in % page width +\vsize 9.7in % page height + +\parskip 8pt plus 2pt minus 1pt % glue before a paragraph + +% Define a few extra fonts for later use: +\font\bigrm=cmr10 scaled\magstep4 % big version of the standard roman font +\font\ninerm=cmr9 % 9pt roman +\font\fiverm=cmr5 % 5pt roman +\font\sm=cmcsc10 % caps and small caps +\font\ss=cmss10 % sans serif + +% Here's a macro that we'll use to produce all subheadings: +\def\subhead#1{\bigskip % extra glue before subheading + \noindent{\bf #1}\par % unindented boldface subheading + \nobreak} % prevent a page break after subheading + +\centerline{\bigrm \TeX nical Typesetting} + +\vskip 2.5cm % dimensions can be metric + +\subhead{What is \TeX?} + +\TeX\ (pronounced ``teck'') is a computerized typesetting system developed by +Donald Knuth and others at Stanford University. It is used to create +high-quality documents, particularly those containing mathematics. +The name \TeX\ is an uppercase form of the Greek letters $\tau\epsilon\chi$, +the first three letters of a Greek word meaning {\sl art} as well as +{\sl technology}. +The lowering of the ``E'' is a reminder that \TeX\ is about typesetting, +which can be thought of as the next stage beyond word processing. +On devices where such lowering is difficult or impossible you may see \TeX\ +written as {\tt TeX}. + +% the above blank line ends the first paragraph + +Most word processors allow you to +create and modify a document interactively --- what +you see on the screen is usually what your output will look like. +\TeX\ does {\it not} work in this way. +Like other typesetting systems (such as SCRIBE and +{\sl troff\/}), \TeX\ is known as a ``document compiler''. Using your +favourite text editor you need to create a file containing the +text of your manuscript along with the \TeX\ typesetting commands. +\TeX\ gives you the ability to produce printed matter with a quality +matching that found in books, depending on the output device. +Adelaide University has an {\sm imagen} laser printer +with a resolution of 240 dots per inch. +This publication shows both the capabilities of \TeX\ and +the output quality of the laser printer. + +\subhead{Fonts} + +One of the more obvious advantages of \TeX\ is the large range of fonts from +which you can choose. A font is a collection of characters each having a +similar size and style. Some of the fonts currently available include: +$$ % enter display math mode just to get space above and below \line +\line + {\hfil % infinitely stretchable glue + \rm roman\hfil \sl slanted\hfil \it italic\hfil \bf boldface\hfil + \tt typewriter\hfil \ss sans serif\hfil \sm small caps\hfil + } % take care to ensure each { has a matching } +$$ +Many of these also come in a variety of sizes: +$$ +\centerline{{\bigrm from the very big},~ % extra space after comma + {\ninerm to the very small},~ + {\fiverm to the ridiculous}.} +$$ +Apart from a large selection of mathematical symbols, +many special characters and accents are available: +$$ +\vbox + {\tabskip 10pt plus 1fil % glue before and after all columns + \halign to\hsize + {& \hfil#\hfil\cr % specify a variable number of centred columns + \copyright& \it\$& \S& \P& \dag& \ddag& + $\circ$& $\bigcirc$& % some symbols must be accessed from math mode + $\leftarrow$& $\rightarrow$& $\triangle$& $\clubsuit$& + \`a& \'e& \c c& \^o& \"u\cr + } + } +$$ +\TeX\ does a few subtle things automatically. +Certain sequences of characters in your text will +be replaced by {\sl ligatures} in the printed output (consider the ``{\tt ffi}'' +in ``difficult''), while other pairs of characters need to be {\sl kerned} +(e.g., the ``o'' and ``x'' in ``box'' look better if they are moved closer +together). The range and quality of fonts available will continue to improve. + +\subhead{Mathematics} + +A major design goal of \TeX\ was to simplify the task of typesetting +mathematics --- and to do it properly. Mathematicians will be pleasantly +surprised at the ease with which formulae and expressions can be created; +from simple in-line equations +such as $e^{i\pi}=-1$ and $f_{n+2}=f_{n+1}+f_n$, to more extravagant displays: +$$ +\sum_{k\ge1} \sqrt{x_k-\ln k}\quad\ne\quad +\int_{0}^\infty {e^{-x^3}+\sqrt{x} \over \left(123-x\right)^3} \,dx +$$ +\TeX\ looks after most of the nitty gritty details, such as spacing things +correctly and choosing the right sizes for superscripts, parentheses, +square root signs etc. (The discoverer of the above relation wishes to +remain anonymous.) + +\subhead{Alignment} + +The preparation of tabular material such as in lists and matrices can be a +tedious job for a person armed only with a typewriter and a bottle of +correction fluid. With a little help from \TeX, computers can make it so +much easier: +$$ +\vcenter % a vertically centred \vbox + {\tabskip 0pt % no space before column 1 + \halign to 3.5in % width of table + {\strut#& % col 1 is a strut + \vrule#\tabskip .5em plus2em& % col 2 is a vrule; also set col spacing + #\hfil& % col 3 is left justified + \vrule#& % col 4 is a vrule + \hfil#\hfil& % col 5 is centred + \vrule#& % col 6 is a vrule + \hfil#& % col 7 is right justified + \vrule#\tabskip 0pt % col 8 is a vrule; no space after it + \cr % end of the preamble + \noalign{\hrule} + & & \multispan5 \hfil Oldest players to represent\hfil& \cr + & & \multispan5 \hfil England in a Test Match\hfil& \cr + \noalign{\hrule} + & & \omit\hfil Name\hfil& & % \omit ignores template in preamble + \omit\hfil Age\hfil& & + \omit\hfil Versus\hfil& \cr + \noalign{\hrule} + & & W.Rhodes& & 52y 165d& & West Indies, 1930& \cr + \noalign{\hrule} + & & W.G.Grace& & 50y 320d& & Australia, 1899& \cr + \noalign{\hrule} + & & G.Gunn& & 50y 303d& & West Indies, 1929& \cr + \noalign{\hrule} + & & J.Southerton{\ninerm*}& & 49y 139d& & Australia, 1877& \cr + \noalign{\hrule\smallskip} + & \multispan7\ninerm* (This was actually his Test debut.)\hfil \cr + } + } +\hskip .5in % space between table and matrix +A=\pmatrix % parenthesized matrix + {a_{11}& a_{12}& \ldots& a_{1n}\cr + a_{21}& a_{22}& \ldots& a_{2n}\cr + \vdots& \vdots& \ddots& \vdots\cr + a_{m1}& a_{m2}& \ldots& a_{mn}\cr + } +$$ + +\vskip -\the\belowdisplayskip % avoid too much space below display + +\subhead{Other features} + +Space does not permit examples of all the things \TeX\ can do. Here are some +more features you might like to know about: + +\item{$\bullet$} +Multi-column output can be generated. + +{\parskip=0pt % temporarily turn off the skipping between paragraphs +\item{$\bullet$} +\TeX\ has a very sophisticated paragraph building algorithm and rarely needs +to resort to hyphenation. Paragraphs can be indented and shaped in many +different ways. + +\item{$\bullet$} +Automatic insertion of footnotes,\footnote{\dag}{\ninerm Here is +a footnote.} running heads, page numbers etc. + +\item{$\bullet$} +\TeX\ makes provision for generating a table of contents, a bibliography, even +an index. Automatic section numbering and cross referencing are also possible. + +\item{$\bullet$} +A powerful macro facility is built into \TeX. This lets you do some very +useful things, like creating an abbreviation for a commonly used phrase, or +defining a new command that will have varying effects depending on the +parameters it is given. A macro package can enhance \TeX\ by making it much +easier to generate a document in a predefined format. +\par % end the last paragraph BEFORE ending the group +} % \parskip will now revert to its previous value + +\subhead{What CAN'T \TeX\ do?} + +Complex graphics such as diagrams and illustrations pose +a major problem --- at the moment you have to leave an appropriate amount of +blank space and paste them in later. +Graphic facilities are the subject of current research. + +\subhead{\TeX\ and VAX/VMS} + +The \TeX\ source file used to generate this document is available for +inspection on any VAX node that has \TeX --- +just type `{\tt scroll tex\char'137 inputs:example.tex}'. +A few steps are needed to print such a file: + +\item{(1)} +Type `{\tt tex example}' to ``compile'' the file. +(\TeX\ looks for a {\tt .tex} file by default. If it can't find the given +file in your current directory it will look in {\tt tex\char'137 inputs}.) +Two new files will be created in your current directory: +{\tt example.dvi} and {\tt example.lis}. +The former is a device independent description of the document; +the latter is simply a log of the \TeX\ run. + +{\parskip=0pt % temporarily turn off \parskip +\item{(2)} +Type `{\tt dvitovdu example}' to preview the document on a terminal screen. +This program can be used to detect a variety of formatting problems, +saving both time and paper. + +\item{(3)} +Type `{\tt imprint example}' to print the document. +(Note that the DVIto\kern-.15em VDU and IMPRINT commands +accept a {\tt .dvi} file by default). + +} % restore \parskip + +Detailed help on all these commands is available on-line --- try typing +`{\tt help tex}' to get started. + +\bye diff --git a/dviware/dvgtk/doc/guidemacs.tex b/dviware/dvgtk/doc/guidemacs.tex new file mode 100644 index 0000000000..11f556ae9f --- /dev/null +++ b/dviware/dvgtk/doc/guidemacs.tex @@ -0,0 +1,105 @@ +% guidemacs.tex - 14:31 GMT +10:00 Sun 23 May 1993 - modifier Geoffrey Tobin. +% I don't have the original Andrew Trevorrow guidemacs. +% This will have to do. -- Ian Dall + +\def \dvgt {{dvgt 3.5}} +\font\bigbf=cmbx12 +\font\Bigbf=cmbx12 scaled \magstep1 +\font\title=cmbx10 scaled \magstep5 +\font\smallrm=cmr8 +\def \subhead #1{\bigskip\leftline{\Bigbf #1}\medskip} +\let \;=\unskip +\def \finishline{} +\parskip=10pt + + +% Macros for verbatim TeX (from MANMAC.TEX): +% After \inputing this file you can use the following macros: +% +% 1. || +% +% 2. \begintt +% +% \endtt +% +% 3. \begindisplay +% +% |text in \tt|& |text in \tt|& text in current font\cr +% \enddisplay +% +% 4. \listing{foo} +% foo.tex will be \input and set verbatim in \tt; \parskip must be non-zero +% if you want to see any empty lines + +\catcode`@=11 % borrow some PLAIN macros which use @ as a letter + +\newskip\ttglue +\ttglue=0.5em plus.25em minus.15em + +\chardef\other=12 +\def\ttverbatim{\begingroup + \catcode`\\=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\$=\other + \catcode`\&=\other + \catcode`\#=\other + \catcode`\%=\other + \catcode`\~=\other + \catcode`\_=\other + \catcode`\^=\other + \obeyspaces \obeylines \tt} +{\obeyspaces\gdef {\ }} % active space = \ , not \space + +\outer\def\begintt{$$\let\par=\endgraf \ttverbatim \parskip=\z@ + \catcode`\|=\other + \rightskip-5pc \ttfinish} +{\catcode`\|=0 |catcode`|\=\other % | is temporary escape character + |obeylines % end of line is active + |gdef|ttfinish#1^^M#2\endtt{#1|dimen0=|hsize|advance|dimen0 by -|hangindent% + |hsize=|dimen0|vbox{#2}|endgroup$$}} +% \begintt ... \endtt will now work in a paragraph with \hangindent, such +% as an \item + +\catcode`\|=\active +{\obeylines \gdef|{\ttverbatim \spaceskip\ttglue \let^^M=\ \let|=\endgroup}} + +\catcode`@=12 % return @ its normal category of "other" + +% Macros for non-centered displays: +% Note that we turn \ttglue off so |stuff| spaces will all be equal. +\outer\def\begindisplay{\obeylines\startdisplay} +{\obeylines\gdef\startdisplay#1 + {\catcode`\^^M=5$$\ttglue=0em#1\halign to\hsize% +\bgroup\indent##\hfil\tabskip 0pt plus 1000pt&&\qquad##\hfil\cr}} +\outer\def\enddisplay{\crcr\egroup$$} + +% MACROS FOR VERBATIM LISTINGS (ADAPTED FROM TEXBOOK APPENDIX D, P380) + +\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials} + + +\def\setupverbatim{\tt % \lineno=0 + \def\par{\leavevmode\egroup\box0\endgraf} + \obeylines \uncatcodespecials \obeyspaces + \catcode`\`=\active \catcode`\^^I=\active + \everypar{ % \advance \lineno by1 \llap{\sevenrm\the\lineno\ \ } + \startbox}} +\newdimen\w \setbox0=\hbox{\tt\space} \w=8\wd0 % tab amount +% \newcount\lineno +\def\startbox{\setbox0=\hbox\bgroup} +{\catcode`\^^I=\active + \gdef^^I{\leavevmode\egroup + \dimen0=\wd0 % the width so far, or since the previous tab + \divide\dimen0 by\w + \multiply\dimen0 by\w % compute previous multiple of \w + \advance\dimen0 by\w % advance to next multiple of \w + \wd0=\dimen0 \box0 \startbox}} + +\def\listing#1{\par\begingroup\parindent0pt \parskip0pt + \vskip\baselineskip + \setupverbatim + \catcode`\|=\other % allow | in listing file + \input#1 + \vskip\baselineskip\endgroup} + diff --git a/dviware/dvgtk/doc/options.txt b/dviware/dvgtk/doc/options.txt new file mode 100644 index 0000000000..b913ebb1f9 --- /dev/null +++ b/dviware/dvgtk/doc/options.txt @@ -0,0 +1,139 @@ +dvgt is a version of the DVItoVDU interactive TeX page previewer. +The program allows you to look at TeX-generated DVI files on a variety +of commonly available VDUs. + +The "DVItoVDU User Guide", "userguide.tex", explains how to use the program. + +USAGE: dvgt filename[.dvi] + [-H x_offset] [-V y_offset] [-d dummy_pk] [-e dummy_tfm] + [-f pk_directory] [-h helpfile] [-i] [-l] + [-m magnification] [-p postscript_font_prefix] + [-r xres yres] [-t tfm_directory] + [-v vdu] [-x paperwd] [-y paperht] + +NOTE ON OPTIONS' DEFAULTS: + +All options have default values. +System dependent initial defaults are set at compile-time. +(Compilation note: these constants are set in the source file "defaults.h".) +Some defaults can be set by environment variables. +The command line options override the environment variables, which in +turn override the compiled initial defaults. + +BRIEF SUMMARY OF OPTIONS: + +-H horizontal_offset (default = 0.0 in) +-V vertical_offset (default = 0.0 in) +-l (set landscape mode, instead of the default portrait mode) +-m magnification (default = DVI file's intrinsic magnification) +-v vdu (default = value of the environment variable TERM) + + vdu may be one of: + + aed512 gigi kermit ncsatel regis tek4010 vis240 vis241 vis500 vis550 + vis603 vis630 vk100 vt100 vt100132 vt102 vt125 vt200 vt220 vt240 + vt640 + +The other options' default values are system dependent. +Try "dvgt -f", for example, to find the current default PK font directory. + +COMMAND OPTIONS: + +-H horizontal_offset (default = 0.0in) + +-V vertical_offset (default = 0.0in) + + TeX, by default, considers the top left corner of the printed page as + one inch below and one inch to the right of the physical page. So + does dvgt. The two offsets move this corner. Positive dimensions + move it downwards and rightwards; negative offsets are allowed. + +-d file (default is system dependent; environment: DV_DUMMY_PK) + + dvgt will warn you if your document uses a font at a non-existent size. + Rather than abort, it will load the PK font specified after -d and continue + so you can look for more errors. Paragraphs using this dummy information + are likely to have ragged right margins. + +-e file (default is system dependent; environment: DV_DUMMY_TFM) + + Default TFM file, similar to -d option. + +-f file (default is system dependent; environment: PKFONTS or TEXFONTS) + + dvgt gets all its font information from PK files. These files are + kept within the directory specified by this option. + +-h file (default is system dependent; environment: DV_HELP) + + The ? command reads the help text file specified by this option. + +-i (default is system dependent; environment: DV_IMMED_HELP) + + Display the path name of the immediate help file. + Typing "dv" by itself displays the immediate help file. + +-l + + Set landscape mode: exchange x and y dimensions. + (This does NOT rotate the page, sorry.) + The default is portrait mode. + +-m i (default = DVI magnification) + + This option allows you to replace the magnification used in the + DVI file with some other value; i is a positive *integer*, 1000 times + the desired magnification. The given value should be chosen carefully + so that the new font sizes still correspond to existing PK files. + Unless you know exactly what you are doing you should avoid using -m, + especially if your TeX source file uses \magnification AND true dimensions. + +-r x,y (default is system dependent) +-r x + + dvgt treats the imaginary sheet of paper on which a DVI page will + appear as a two dimensional array of tiny dots known as paper pixels. + x and y are positive floating point numbers that define the numbers of + pixels per inch in the horizonatl and vertical directions, respectively. + Their values should match the respective resolutions of the device that + will be used to print your document. + If only one value is given, then it is used as the resolution both + horizontally and vertically. + +-t tfm_directory (default is system dependent; environment: TEXFONTS) + + This sets the directory where dvgt will look for TFM (TeX Font + Metric) files, such as "cmr10.tfm". + +-v string (default = value of TERM) + + This option is used to tell dvgt what type of VDU you are using. + If TERM does not describe your VDU, you need to override the default value. + Typing `dvgt -v vis550 foo' will tell dvgt you're using a VISUAL 550. + The current version will accept the following strings + (in upper or lower case): + + aed512 (AED 512 with 512 by 512 screen) + kermit (same as ncsatel) + ncsatel (NCSA Telnet's Tektronix 4010 emulation) + regis (any ReGIS compatible VDU; synonyms = GIGI, VK100, VT125, VT240) + tek4010 (same as ncsatel) + vis240 (VISUAL 240; synonym = VIS241) + vis500 (VISUAL 500) + vis550 (VISUAL 550) + vis603 (VISUAL 603) + vis630 (VISUAL 630) + vt100 (any VT100 compatible VDU in 80 column mode; synonym = VT102) + vt100132 (any VT100 compatible VDU in 132 column mode) + vt220 (VT220 using down-loaded chunky graphics; synonym = VT200) + vt640 (VT100 with Retro-Graphics) + +-x dimen (default is system dependent) +-y dimen (default is system dependent) + + These two options define the width and height of the paper upon which your + document will be printed. Both values are specified as dimensions like + those used in TeX, but the units are restricted to BP, CM, IN, MM, PC, PT, + PX, or SP. PX is specific to dvgt, and represents one paper pixel. + Every time you select a page, dvgt will use these paper dimensions + to check that all printed material falls within the paper edges. diff --git a/dviware/dvgtk/doc/sysguide.tex b/dviware/dvgtk/doc/sysguide.tex new file mode 100644 index 0000000000..438f14cefa --- /dev/null +++ b/dviware/dvgtk/doc/sysguide.tex @@ -0,0 +1,914 @@ +% sysguide.tex - 20:13 GMT +10:00 Tue 3 Aug 1993 - modifier Geoffrey Tobin. +% This is the TeX source file for the "dvgt System Guide". +% +% Details peculiar to our site are indicated by the string "SYSDEP". +% Cross references are indicated by the string "XREF". +% Feel free to make modifications applicable to your site. +% Andrew Trevorrow, July 1986. +% +% Note: Andrew wrote to me in 1992 to say that he's released DVItoVDU +% to the public domain, and that he is no longer maintaining it. +% You may also modify dvgt to your heart's content, though it would +% be more pleasant for the users if you rename it, first. +% Don't forget to change the documentation: userguide.tex, +% sysguide.tex, README, CHANGES, TODO, the Makefile-s, and any other +% documentary evidence of what you've done to the software. +% Geoffrey Tobin, May 1993. + +\input guidemacs + +% \centerline{\crest} % SYSDEP: University of Adelaide crest +\vfil +\centerline{\title \dvgt~~System~~Guide} +\bigskip +\vskip\parskip +\centerline{\bigbf DVItoVDU Version 1.0 for VAX/UNIX in Modula-2 + was by Andrew Trevorrow, July 1986} +\smallskip +\centerline{\bigbf DVItoVDU Version 3.0 ported to C + by Ian Dall, Novemebr 1990} +\smallskip +\centerline{\bigbf \dvgt\ for AIX and Sun/OS unix systems + is a modification by Geoffrey Tobin, May 1993} +\bigskip + +\noindent +This document explains how to install or modify \dvgt, +a \TeX\ page previewer written in C. +Details on how to use the program can be found in the +{\sl \dvgt~User Guide}. +It is assumed you are familiar with \TeX\ under unix\null. +Please convey any problems or suggestions to: + +\medskip +% SYSDEP +% +% \centerline{Andrew Trevorrow} +% \centerline{Computing Services, University of Adelaide} +% \centerline{GPO Box 498, Adelaide, South Australia, 5001} +% \centerline{ACSnet address: |akt@uacomsci.ua.oz|~~Phone: (08) 228 5984} +% +\centerline{Geoffrey Tobin} +\centerline{Electronic Engineering, La Trobe University} +\centerline{Bundoora, Victoria, 3083} +\centerline{Internet address: |ecsgrt@luxor.latrobe.edu.au|~~Phone: + |+ (03) 479 1987|} + +\bigskip +\vskip\parskip +\centerline{\bigbf Contents} +\bigskip + +% XREF: make sure page numbers are up-to-date!!! +\line{Important files\leaders\hbox to .75em{\hss.\hss}\hfil 1} +\line{Installing \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 3} +\line{Overview\leaders\hbox to .75em{\hss.\hss}\hfil 4} +\line{Module map\leaders\hbox to .75em{\hss.\hss}\hfil 7} +\line{Modifying \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 8} +\line{Testing \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 10} +\line{Revision history\leaders\hbox to .75em{\hss.\hss}\hfil 11} + +\vfil +% \centerline{\smallrm University of Adelaide Computing Services} % SYSDEP +\eject + +% The above is the title page; let's make a few adjustments to some parameters: +\footline={\hss\rm\folio\hss} % turn page numbers back on +\pageno=1 % and restart numbering + +\subhead{Important files.} + +\noindent +Let's suppose you've unpacked the distribution into some directory and +are now looking at its contents. The files are: +\begindisplay +Top-level distribution files\cr +\noalign{\medskip} +|DVGT.README|& overview of current distribution\cr +|Makefile.dvgt|& make a tar, shar or zip distribution\cr +|dvgt/|& parent of doc, help, misc and src directories\cr +\noalign{\bigskip} +Top-level files\cr +\noalign{\medskip} +|CHANGES|& list of changes since previous version\cr +|README|& brief overview of \dvgt\cr +|TODO|& wish-list\cr +|doc/|& documentation and test files, in TeX\cr +|help/|& help files\cr +|misc/|& miscellaneous C headers\cr +|src/|& sources for \dvgt\ executable\cr +\noalign{\bigskip} +|TAGS|, in |src| directory\cr +\noalign{\medskip} +|TAGS|& list of identifiers, with source location\cr +& - useful with some editors, such as elvis\cr +& - a "tags" or "ctags" program is needed,\cr +& if you wish to make a TAGS file\cr +\noalign{\bigskip} +Program make files, in |src| directory\cr +\noalign{\medskip} +|Makefile.aix|& make |dvgt| for IBM Risc/6000 under AIX\cr +|Makefile.sun|& make |dvgt| for Sparc 1 under Sun/OS\cr +\noalign{\bigskip} +C sources, in |src| directory\cr +\noalign{\medskip} +|version.h|& version description string\cr +|config.h|& system-dependent C macros, types and variables\cr +|dvitovdu.c|& main program's source file\cr +|globals.h|& global things, often defined in |dvitovdu.c|\cr +|options.c|/|h|& command-line options\cr +|defaults.h|& system-dependent defaults for certain values\cr +& used and/or set in |dvitovdu.c| and |options.c|\cr +|files.h|& unix random access file i/o declarations,\cr +& for |dvireader.c| and |fontreader.c|\cr +|help.h|& (fall-back) option and interactive help texts\cr +|screenio.c|/|h|& low-level terminal i/o routines\cr +& (see also |unixio.c|/|h|)\cr +|unixio.c|/|h|& unix command line interface routines\cr +|lstring.c|/|h|& length specified strings\cr +|new.h|& generic memory allocation\cr +|dvireader.c|/|h|& DVI file translation routines and data structures\cr +|fontreader.c|/|h|& PK and TFM font file access routines\cr +|vdu.c|/|vdu.h|& generic VDU parameters and routines\cr +|aed512vdu.c|& routines for AED 512\cr +|ncsatelvdu.c|& routines for NCSA Telnet's tek4010 emulation\cr +|regisvdu.c|/|h|& routines for ReGIS compatible VDUs\cr +|tek4010emu.c|/|h|& routines for Tektronix 4010/4014 emulating VDUs\cr +|vis240vdu.c|& routines for VISUAL 240\cr +|vis500vdu.c|/|h|& routines for VISUAL 500\cr +|vis550vdu.c|& routines for VISUAL 550\cr +|vis603vdu.c|& routines for VISUAL 603\cr +|vis630vdu.c|& routines for VISUAL 630\cr +|vt100vdu.c|/|h|& routines for VT100\cr +|vt100132vdu.c|& routines for VT100 in 132 column mode\cr +|vt220vdu.c|& routines for VT220\cr +|vt640vdu.c|& routines for VT100 with Retrographics\cr +\noalign{\bigskip} +Miscellaneous C headers, in |misc| directory\cr +\noalign{\medskip} +|stdlib.h|& Ian Dall's sample |"stdlib.h"| file,\cr +& for those systems without ||\cr +\noalign{\bigskip} +Help files, in |help| directory\cr +\noalign{\medskip} +|cmd.hlp|& text file read by \dvgt's |?| interactive command\cr +|immed.hlp|& on-line help file\cr +|options.hlp|& detailed description of \dvgt\ options\cr +\noalign{\bigskip} +Documents, in |doc| directory\cr +\noalign{\medskip} +|Makefile|& make file for Documentation and Test files\cr +|guidemacs.tex|& macros used by the following guides\cr +|sysguide.tex|& source for this document, the {\sl \dvgt\ System Guide}\cr +|userguide.tex|& source for the {\sl \dvgt\ User Guide}\cr +\noalign{\bigskip} +Test file, in |doc| directory\cr +\noalign{\medskip} +|tripvdu.tex|& source for |tripvdu.dvi|, a torture test for \dvgt\cr +\enddisplay + +\vfil\eject +\subhead{Installing \dvgt.} + +\noindent +To make {\dvgt}, you need a C compiler, linker, and many of the most +usual header and library files. \dvgt\ should compile under ANSI C, +and under at least some traditional and pre-ANSI C compilers. Minor +modifications may be necessary for some compilers and/or operating +systems. + +\noindent +This distribution is designed for IBM Risc/6000 computers under +(a no-longer supported version (!) of) AIX, and for Sparc 1 computers +under (a locally-modified) Sun/OS 4.0.3, but variants of these systems +may possibly compile, link and run \dvgt\ as distributed. + +\noindent +Reports of successful ports, as well as of bugs encountered, and of +further items for the wish-list, are welcome. + +\noindent +The executable file is called |dvgt|. +Before making |dvgt| available to other users at your site, +read the section on command options in the {\sl \dvgt\ User Guide}. +If you have a C compiler and libraries, you may want to +make a few changes to |defaults.h| to suit your site: + +\item{$\bullet$} +Change |DEF_X_RESOLUTION| and |DEF_Y_RESOLUTION| (the default values of +|-rx| and |-ry|) to match the X and Y resolutions of your printer, +in dots per inch. + +\item{$\bullet$} +Change |DEF_PAPERWD| and |DEF_PAPERHT| (the default values of |-x| and |-y|) +to define the dimensions of the default paper used by your printer. + +\item{$\bullet$} +Change |DEF_PK_DIR| and |DEF_TFM_DIR| (the default values of |-f| and |-t|) +to tell \dvgt\ where to look for PK and TFM files. + +\item{$\bullet$} +Change |DEF_DUMMY_PK| (the default value of |-d|) +to indicate which PK file to use when a requested one does not exist. + +\item{$\bullet$} +Change |DEF_HELP_FILE| (the default value of |-h|) to indicate the +location of |cmd.hlp|. + +\noindent +Individual users can of course override any of these defaults. +Any changes you make should be reflected in the user documentation +in |userguide.tex|, |immed.hlp|, |CHANGES| and |README|. +(the |immed.hlp| file provides a suitable basis for a |man| entry). +System-dependent information in these +files is flagged by the string ``|SYSDEP|'' so you can quickly locate where +changes need to be made. + +\vfil\eject +\subhead{Overview.} + +\noindent +A C program is typically built up from a number of separately compiled +|.c| source files. +Let's use the term |object| loosely for a type, constant, macro, +variable, or function. +The source files certainly must share some objects, in order to +cooperate as a single program. + +\noindent +Shared objects in C are defined in exactly one file. + +\noindent +To increase the likelihood that the sources use shared objects +correctly, common practice is to declare each shared object in +exactly one |header| file, mnemonically suffixed |.h|. Any file +that must use that shared object should |#include| that header. +Headers should not allocate storage; that should be left to |.c| +files. + +\noindent +In the case of types, constants and macros, which don't require +runtime storage, the declaration constitutes the definition, so +if these are shared, then they are defined and declared in the +same file, which will be a header. + +\noindent +However, for variables and functions, which do need storage at runtime, +a definition not only describes the object, but it also allocates +storage for it, whereas a declaration is a mere description. +Consequently, shared variables and functions are defined in one +|.c| file, and declared in a header typically named after it. +That header may also define types, constants and macros needed +by those shared variables and functions. + +\noindent +For example, |fontreader.c| defines some shared functions, which are +declared in |fontreader.h|, which is |#include|-ed by the C source +files (including |fontreader.c| itself) that use those functions. + +\noindent +If this is done wisely, then rapid system regeneration is possible, +because the |.c| files only use information provided in the headers; +each |.c| file may be modified (e.g., optimized) without the need to +recompile the others. This is called |modular| programming, and we +may then meaningfully speak of the |.c| and any accompanying |.h| file +as a |module|. To carry the terminology further, we can loosely +describe the defining file (or module) as |implementing| the shared +objects, which it |exports|, through the |interface| provided by its +header, to the |client| modules that |import| those shared objects +in order to use them. + +\noindent +The module map on page 7 % XREF +shows the importation dependencies of all the modules of \dvgt\null. + +\noindent +Not only do modules allow a large program to be broken up into manageable +chunks, they also provide a sensible basis for describing a program: + +\medskip +\noindent |DVItoVDU| + +\nobreak\noindent +The main module is primarily concerned with the user interface. +It handles all the interactive command processing +and contains the high-level logic used to update the dialogue and window +regions. Data and procedures are imported from the following modules to help +the main module carry out its many tasks. + +\medskip +\noindent |Options| + +\nobreak\noindent +This module provides the interface to the UNIX shell. +The command line used to invoke \dvgt\ is parsed and the DVI file name +extracted. All the options are also initialized, either to explicit +values given in the command line or to site-dependent default values. + +\medskip +\noindent |VDUinterface| + +\nobreak\noindent +\dvgt\ can work efficiently on different types of VDUs by letting +C function pointers act as generic VDU routines. +These routines, along with the generic VDU parameters, are defined in +|VDUinterface|. + +\noindent +The generic VDU routines are: +\begindisplay +|StartText|& switch to ``text mode''\cr +|ClearTextLine|& erase given line\cr +|MoveToTextLine|& move cursor to start of given line\cr +|ClearScreen|& erase the entire screen\cr +|StartGraphics|& switch to ``graphics mode''\cr +|LoadFont|& simulate the given font for future |ShowChar| calls\cr +|ShowChar|& display a Terse mode character at given screen location\cr +|ShowRectangle|& display a given rectangular region of screen pixels\cr +|ResetVDU|& reset VDU to its normal state\cr +\enddisplay +Most of these are quite trivial to implement for a specific VDU. +The main module looks after all the tricky graphic operations such as the +clipping of characters and rules outside the current +window region, and the way in which visible paper pixels are scaled +to screen pixels. + +\noindent +From an efficiency point of view, the two most critical routines are +|ShowChar| and |ShowRectangle|. +|ShowChar| is used by the main module to display a character in Terse +mode. The only information given is the \TeX\ character (currently +restricted to |\char0..\char255|) and its screen position. +Since characters are displayed one font at a time, some VDUs can use scaling +information sent by the most recent |LoadFont| routine to select an +appropriate hardware ``font''. + +\noindent +|ShowRectangle| is used for all other window graphics. +It is used to draw the paper edges, to draw all rules (regardless of display +mode), to draw all glyph outlines in a Box display, and to draw the horizontal +lines making up all glyphs in a Full display. +The majority of rectangles are in fact horizontal or vertical lines just one +screen pixel thick. +\bigbreak + +\noindent +The generic VDU parameters are: +\begindisplay +|DVIstatusl|& DVI status line, usually 1\cr +|windowstatusl|& window status line, usually 2\cr +|messagel|& message line, usually 3\cr +|commandl|& command line, usually 4\cr +|bottoml|& bottom text line in screen\cr +|windowh|& window region's top left h coordinate\cr +|windowv|& window region's top left v coordinate\cr +|windowwd|& unscaled window width\cr +|windowht|& unscaled window height\cr +\enddisplay +These ``parameters'' are actually integer variables. The main module +treats them as constants. + +\noindent +There are two screen coordinate systems used by \dvgt: + +\item{(1)} +When updating the screen in text mode (i.e., when updating the +dialogue region or during a |?| or |S| command), \dvgt\ assumes +text lines start at 1 and increase downwards. The bottom +text line on the screen is given by the parameter |bottoml|. + +\item{(2)} +When updating the screen in graphics mode, +\dvgt\ assumes the top left screen pixel +is positioned at (0,0). Horizontal coordinates increase to the right +and vertical coordinates increase down the screen. The top left pixel +in the window region is at (|windowh|,|windowv|). +Specific VDU modules may have to do a translation to the actual +coordinate scheme used by the VDU\null. +The size of the window region in screen pixels +is given by |windowwd| and |windowht|. + +\medskip +\noindent |aed512vdu|, |ncsatelvdu|, |regisvdu|, etc. + +\nobreak\noindent +Each specific VDU module exports an initialization routine +that will assign appropriate procedures to the generic VDU routines +and specific integers to the generic VDU parameters. +|VDUinterface| imports all these initialization routines and +uses the |-v| value set in |Options| to +execute one of them. + +\medskip +\noindent |DVIReader| + +\nobreak\noindent +This module exports the routines and data structures needed +to move about randomly in a DVI file and interpret selected pages. +Although the main module is currently the only client, +it is anticipated that |DVIReader| could just as well form the basis of +another DVI translator, such as a non-interactive device driver. + +\noindent +Font, character and rule information is stored in dynamically allocated +lists to avoid imposing any limit on their numbers. +The length of the font list is determined soon after opening the DVI file by +reading all the font definitions in the postamble. +Each font node is a record made up of many fields; one of these fields is the +head of a character list. The nodes in each character list will +store the positions and \TeX\ codes of all characters on a page. +Besides the font list, there is also a rule list. +The nodes in the rule list will store the positions and dimensions of +all rules on a page. +(Character and rule positions are stored as pairs of horizontal and vertical +paper pixel coordinates. +The manner in which |DVIReader| calculates such positions is based +firmly on Donald Knuth's |DVItype|.) + +\noindent +Just before interpreting a selected DVI page, the rule list and all the +character lists are deallocated if necessary. +During interpretation, |DVIReader| adds a new rule or character +node to the {\it tail\/} of an appropriate list. +When the main module processes such lists, rules and characters will be +displayed in somewhat the same sequence as seen in the DVI page; i.e., +top-to-bottom and left-to-right. +(Since there is a separate rule list, as well as a character list for +each font, the precise sequence is not remembered.) +After interpretation, the nodes in the font list are sorted so +that fonts with the least number of characters ($>$ 0) will +be processed first. + +\noindent +The various lists contain most of the information needed to display the page; +they are traversed by the main module whenever the window region is updated. +If the page isn't empty then |DVIReader| will also determine +the edges of the page rectangle. This is the smallest +rectangle containing all black pixels in glyphs and rules, as well +as all character reference points (needed for Terse displays). +The main module uses the page rectangle to decide if the page is off the paper, +and to restrict window movement. + +\medskip +\noindent |FontReader| + +\nobreak\noindent +\dvgt\ gets all its character information from standard PK files. +|FontReader| exports routines for moving about in such files and +grabbing various bytes and words. +A PK file contains the crucial TFM widths needed by |DVIReader| to +correctly position characters when interpreting a DVI page. These widths, +along with other details about each glyph, are kept in the PK file. +The PK file is loaded just once for each font (the very first +time the font is seen) and \dvgt\ will write +`|Loading font data from ...|' to the log file. + +\noindent +A PK file also contains glyph shape information (in the form of bitmaps) +for all characters in a \TeX\ font. +\dvgt\ uses these bitmaps during a Full display to draw +characters a font at a time. + +\noindent +Because |DVIReader| creates a separate character list +for each font used on a page, +there never needs to be more than one PK file open at any given time. +(But there are! - Geoffrey Tobin observes.) + +\medskip +\noindent |ScreenIO| + +\nobreak\noindent +All low-level terminal i/o is handled by the routines defined in this module. +It uses some C routines written by Alex Dickinson (see |unixio.c|). + +\vfil\eject +\subhead{Module map.} + +\font\arrowfont=linew10 at 10truept + +% MACROS FOR MAP. +% \plot is based on \point macro described on page 389 of TeXbook. + +\newdimen\unit +\unit=1in + +\def\plot % #1 is down, #2 is right, #3 is stuff to plot + #1 #2 #3\endplot + {\rlap{\kern#2\unit + \vbox to 0pt + {\parindent=0pt\offinterlineskip\kern#1\unit#3\vss}}} + +\def\ulap#1{\vbox to 0pt{\vss#1}} % vertical analog of \llap +\def\dlap#1{\vbox to 0pt{#1\vss}} % vertical analog of \rlap + +\def\cvlap#1{\vbox to 0pt{\vss#1\vss}} % centre vertically +\def\chlap#1{\hbox to 0pt{\hss#1\hss}} % centre horizontally + +\def\drawbox ht#1 wd#2 #3\endbox + {\vbox{\hsize=#2\unit + \hrule height10sp + \hbox to \hsize + {\vrule width10sp + \vbox to #1\unit + {\vfil #3\vfil}% + \vrule width10sp + } + \hrule height10sp + } + } + +\def\mainmodule + {\drawbox ht.7 wd1.2 + \centerline{\strut |DVItoVDU|} + \centerline{\strut (main module)} + \endbox + } + +\def\midmodules + {\drawbox ht.4 wd1 + \centerline{|DVIReader|} + \endbox + \kern .3\unit + \drawbox ht.4 wd1 + \centerline{|FontReader|} + \endbox + \kern .3\unit + \drawbox ht.4 wd1 + \centerline{|VDUinterface|} + \endbox + \kern .3\unit + \drawbox ht.4 wd1 + \centerline{|Options|} + \endbox + \kern .5\unit + \drawbox ht.4 wd1.5 + \centerline{|ScreenIO|} + \endbox + } + +\def\vdumodules + {\drawbox ht1.2 wd1.3 + \centerline{\strut VDU modules:} + \centerline{\strut |aed512vdu|} + \centerline{\strut |ncsatelvdu|} + \centerline{\strut |regisvdu|} + \centerline{\strut etc.} + \endbox + } + +\def\uline#1 {\ulap{\hrule width 10sp height#1\unit}} +\def\dline#1 {\dlap{\hrule width 10sp height#1\unit}} +\def\lline#1 {\llap{\vrule height10sp width #1\unit}} +\def\rline#1 {\rlap{\vrule height10sp width #1\unit}} + +\def\uarrow#1 {\ulap{\arrowfont\dlap{\hbox{\char'66 }} + \hrule width10sp height#1\unit}} +\def\darrow#1 {\dlap{\arrowfont\hrule width10sp height#1\unit + \ulap{\hbox{\char'77 }}}} +\def\rarrow#1 {\rlap{\vrule height10sp width#1\unit + \setbox0=\hbox{\arrowfont\char'55 }\ht0=0pt\dp0=0pt + \llap{\box0}}} +\def\larrow#1 {\llap{\setbox0=\hbox{\arrowfont\char'33 }\ht0=0pt\dp0=0pt + \rlap{\box0}\relax + \vrule height10sp width#1\unit}} + +% START PLOTTING MAP + +\noindent +An arrow from module |A| to module |B| indicates the latter +imports data and/or procedures from the former. +Module |B| is said to be a {\it client\/} of module |A|\null. + +\vskip 1in + +\hbox + {\kern-.3\unit % shift 0,0 left + % plot all the module boxes: + \plot 0.0 0.5 \mainmodule \endplot + \plot 1.0 2.5 \midmodules \endplot + \plot 2.4 4.4 \vdumodules \endplot + % plot all the arrows: + \plot 1.2 1.5 \uarrow 0.5 \endplot % DVIReader to main + \plot 1.2 1.5 \rline 1.0 \endplot + \plot 1.9 1.3 \uarrow 1.2 \endplot % FontReader to main + \plot 1.9 1.3 \rline 1.2 \endplot + \plot 2.6 1.1 \uarrow 1.9 \endplot % VDUinterface to main + \plot 2.6 1.1 \rline 1.4 \endplot + \plot 3.3 0.9 \uarrow 2.6 \endplot % Options to main + \plot 3.3 0.9 \rline 1.6 \endplot + \plot 4.2 0.7 \uarrow 3.5 \endplot % ScreenIO to main + \plot 4.2 0.7 \rline 1.8 \endplot + \plot 4.0 3.0 \uarrow 0.5 \endplot % ScreenIO to Options + \plot 4.0 3.8 \uline 1.3 \endplot % ScreenIO to VDUinterface + \plot 2.7 3.8 \larrow 0.3 \endplot + \plot 3.9 3.8 \darrow 0.1 \endplot % down arrow at point 6 + \plot 3.1 3.0 \uarrow 0.3 \endplot % Options to VDUinterface + \plot 2.5 4.4 \larrow 0.9 \endplot % point 5 to VDUinterface + \plot 2.5 4.3 \rarrow 0.1 \endplot % right arrow at point 5 + \plot 4.2 4.0 \rline 2.3 \endplot % line to right of ScreenIO + \plot 4.2 6.3 \uline 3.0 \endplot % ScreenIO to vdus, font, dvi + \plot 3.0 6.3 \larrow 0.6 \endplot % ScreenIO to vdus + \plot 1.9 6.3 \larrow 2.8 \endplot % ScreenIO to FontReader + \plot 1.2 6.3 \larrow 2.8 \endplot % ScreenIO to DVIReader + % plot all the numbers: + \plot 1.5 2.4 \llap{1} \endplot + \plot 2.4 2.4 \llap{2} \endplot + \plot 3.1 2.4 \llap{3} \endplot + \plot 2.9 3.1 \rlap{4} \endplot + \plot 2.3 4.3 \llap{5} \endplot + \plot 3.8 3.9 \rlap{6} \endplot + } + +\vfill + +\noindent Points of interest: + +\item{1 } +|DVIReader| does not depend on |FontReader|. +It does know that PK files contain crucial typesetting data, but leaves it +up to the main module to specify how and where to get such information. + +\item{2 } +|VDUinterface| exports the generic VDU routines and parameters +for use in the main module. + +\item{3 } +|Options| extracts the DVI file name and options from +the |dvgt| command line. + +\item{4 } +|VDUinterface| needs the |-v| value to select an appropriate VDU +initialization routine. + +\item{5 } +Specific VDU modules import the generic VDU routines and parameters +from |VDUinterface|. In return, each VDU module +exports an initialization routine. + +\item{6 } +|ScreenIO| needs to use some |VDUinterface| routines to be able to +leave the VDU screen in a decent state after abnormal termination. + +\vfil\eject +\subhead{Modifying \dvgt.} + +\noindent +\dvgt\ is descended from Andrew Trevorrow's |DVItoVDU|. + +\noindent +|DVItoVDU| was originally developed under VAX/VMS +using the Modula-2 system from Hamburg University. +The UNIX version of |DVItoVDU| was developed using the +Modula-2 compiler from DEC WRL and can run under ULTRIX or UNIX 4.2 BSD\null. +The main module and all the supporting modules of |DVItoVDU| are +written in Modula-2, except for the C routines in |unixio.c|. + +\noindent +Ian Dall ported |DVItoVDU| version 3.0 to traditional C in November 1990, +working from December 1989, with amendments in January 1991. +Geoffrey Tobin (conditionally) ported it to ANSI C in May 1992, +renaming it |dvgt| to avoid confusion. +Significant modifications have been made to the user interface and +code of |dvgt| up to the present date (May 1993), especially in +versions 3.4 (first official public release, December 1992) and 3.5. + +\noindent +If you wish to modify \dvgt\ you'll obviously need C, preferably either +ANSI C or gcc (Gnu C), because those compilers provide stronger checks +than earlier versions of C. +Conversion to another C system should, however, be quite easy, +particularly since traditional C is still provided for, via a test +for the ANSI C macro |__STDC__|. + +\noindent +All the source files avoid non-standard compiler features (IF NOT, +PLEASE REPORT!), +and system-dependent code is flagged by the string ``|SYSDEP|''\null. +Terminal i/o is isolated in the |ScreenIO| module, +and most file operations are restricted to |DVIReader| and |FontReader|. + +\noindent +(The VMS-to-UNIX conversion took [Andrew Trevorrow] about two weeks. +A working version was up in less than a week; it then took another week +to fix some terminal i/o problems and produce a new {\sl User Guide}. +[He] was a bit surprised at just how easy the conversion was.) + +\noindent +[ Andrew Trevorrow, re the Modula-2 version of DVItoVDU: + +\noindent +What about conversion to another language? +An obvious candidate is Pascal. +The similarities in syntax would allow any decent text editor to +carry out much of the conversion automatically. +The major difficulty in translation to standard Pascal would be +the lack of procedure variables; +it might be easier to implement just one type of VDU before +attempting anything more sophisticated. +] + +\medskip +\noindent IMPLEMENTING A NEW VDU. + +\noindent +Assuming you have a C compiler, the most likely change you'll want to +make is to add a new type of VDU to the program's capabilities. +The code takes advantage of separate compilation (modularity), +so that such a task can be undertaken without having to make any changes to +the main module. + +\noindent +The steps required to implement a new VDU (which we'll call brand XXX) +are as follows, assuming that each of the other C files has been compiled +to a |.o| file. This includes how to compile and link by hand; the +changes to the Makefile-s should be evident to anyone who has even +a little experience with |make| on either unix or another system. + +\item{$\bullet$} +Read |vdu.h| to see if the task is even possible. +\dvgt\ requires XXX to be able to carry out a number of +primitive graphic operations +such as clearing the screen, addressing individual pixels, etc. +As little as possible is assumed about the capabilities of a VDU\null. +In particular, the availability of a graphic input device is ignored. +\dvgt\ should be able to work on any terminal that can: + +\itemitem{---} Mix text and graphics on the screen +(some VDUs make no distinction). +{\parskip=0pt +\itemitem{---} Erase all of the screen, or individual text lines. +\itemitem{---} Move the cursor to any given screen pixel. +\itemitem{---} Display a rectangular region of screen pixels +(possibly just one). + +} % reset \parskip + +\item{$\bullet$} +Look at some of the |*vdu.h| files and use them to help you +create |xxxvdu.h|. + +\item{$\bullet$} +Look at some of the |*vdu.c| files and use them to help you +create |xxxvdu.c|. +Type `|cc -c xxxvdu.c|' to create |xxxvdu.o|. % SYSDEP + +\item{$\bullet$} +Edit |vdu.c| and add appropriate code in the recommended locations +(search for occurrences of ``|XXX|''). +Type `|cc -c vdu.c|' to create a new |.o| file. % SYSDEP + +\item{$\bullet$} +Relink |dvgt| by typing `|cc -o dvgt *.o|'. % SYSDEP + +\item{$\bullet$} +Test the new version of |dvgt| (see the next section). + +\noindent +It should be pointed out that \dvgt\ is currently targeted towards +relatively primitive terminals. Significant changes to both the display +logic and page data structures would probably +be needed to take full advantage of the latest graphic work\-stations. +For instance, a large amount of bit-mapped memory could store an entire +rasterized page and allow much more sophisticated updating of +the window region. +Pan and zoom operations would also be much easier using a mouse or thumbwheel +cursor controls. + +\vfil\eject +\subhead{Testing \dvgt.} + +\noindent +The file |tripvdu.dvi| was created to test \dvgt\ using much the same +philosophy as Donald Knuth's torture test for \TeX\null. +Most pages exercise rarely-used parts of the program: +\begindisplay +page& contents\cr +\noalign{\medskip} +1& empty page (but with |\special| stuff that will be ignored)\cr +2& one black pixel at (0{,}0)\cr +3& entirely blackened A4 sheet of paper\cr +4& like page 3 but one pixel wider\cr +5& like page 3 but one pixel longer\cr +6& has a rulelist with one full ruletable node (300 rules)\cr +7& like page 6 but has one more rule\cr +8& has a charlist with one full chartable node (3000 characters)\cr +9& like page 8 but has one more character\cr +10& multiple \TeX\ page counters\cr +11& negative \TeX\ page counter\cr +12& characters from many fonts\cr +13& characters from many fonts, some of which have no PK file\cr +14& paragraph using most characters from standard roman font\cr +15& page in bottom half of A4 paper\cr +16& page entirely above and to the left of A4 paper\cr +17& page entirely below and to the right of A4 paper\cr +18& page extending beyond all edges of A4 paper\cr +\enddisplay +Type `|dvgt tripvdu|' +and go through all the pages to verify that the program is working correctly. +You may need to specify a |-v| value to tell |dvgt| what type of terminal +you're using. +See the {\sl \dvgt\ User Guide} for details on +what |-v| values are available and the special requirements of some VDUs. + +\noindent +If a catastrophe occurs and \dvgt\ actually crashes, please report +the problem back to me, Geoffrey Tobin. + +\noindent +If the reason for the crash is not obvious, +and you have a C compiler, you might try to rebuild |dvgt| after +editing the |.c| files that contain debugging code. + +\noindent +Before all comments of the form |#ifdef |, perhaps at the top +of the source file, so you can find them easily, write |#define |. +Here || represents an identifier, usually in all capitals, such +as |DEBUG|, or |BORING_MESSAGES|. + +\noindent +Alternatively, write code of your own to output |snapshots| (current +information) to the |logfile|. Wrap this code in an +|#ifdef ... #else ... #endif| test, remembering to |#define| the +appropriate macro constant when you're debugging. I like to label +the |#else| and |#endif| lines with the name of the macro constant, +so that its easy to see matching lines. + +\noindent +Only a few modules have such code; use `|grep #ifdef *.c|' to list them. +Note that the occurrences with |__STDC__| in them are not debugging code, +but ANSI/non-ANSI detection switches, so you'll need to exclude those +from your list; one way is to use the |-v| pattern exclusion option +of |grep|, thus: `|grep #ifdef *.c| $\|$ |grep -v __STDC__|'. You might +also want to redirect th eoutput to a file, or pipe it to either |more| +or |less| (an improvement over |more| that allows backward scrolling, +and much besides). + +\noindent +The extra code might provide additional clues as to what is going wrong. + +\vfil\eject +\subhead{Revision history} + +\medskip +\noindent |DVItoVDU 1.0| + +\nobreak\noindent +Version 1.0 of DVItoVDU for VAX/UNIX was based on +version 1.5 for VAX/VMS (TUGboat vol.~7 no.~1 has an article +describing the VMS version). +The UNIX version of DVItoVDU is virtually identical as far as the user +is concerned. The command option syntax is a little +different of course, and there are a couple of new VDU types, +but the interactive commands are exactly the same. + +\noindent +A few improvements have been made to the UNIX version: + +\item{$\bullet$} +Whenever a |\special| command is ignored, the first few bytes are +displayed in case some users need to see them. + +\item{$\bullet$} +While updating the window region, the main module uses +|BusyRead| from |ScreenIO| to check for user input +after drawing each visible rule or character. +(The VMS version checked after every 8th rule or character; the overheads +for |BusyRead| seem to be much less under UNIX.) + +\item{$\bullet$} +|ScreenIO| required significant changes to be able to handle +some of the more useful UNIX interrupts: +|^C| can be used to return quickly to the `|Command:|' level, and +|^Z| can be used to suspend |DVItoVDU|. +(Thanks to Alex Dickinson who wrote the necessary |unixio.c| routines.) +These interrupts are only detected during |Read|, |ReadString| and +|BusyRead|. + +\medskip +\noindent |DVItoVDU 2.0 to 3.0| + +\nobreak\noindent +Lamentably mysterious. + +\medskip +\noindent |C port| + +\nobreak\noindent +Geoffrey Tobin is not aware of any significant functional changes +introduced by Ian Dall. + +\medskip +\noindent |dvgt 3.1 to 3.4| + +\nobreak\noindent +See the README file in the dvgt/ directory. + +\medskip +\noindent |dvgt 3.5| + +\nobreak\noindent +See the CHANGES file in the dvgt/ directory, and/or the README file. + +\finishline +\bye diff --git a/dviware/dvgtk/doc/tripvdu.tex b/dviware/dvgtk/doc/tripvdu.tex new file mode 100644 index 0000000000..d8c3d25729 --- /dev/null +++ b/dviware/dvgtk/doc/tripvdu.tex @@ -0,0 +1,279 @@ +% TeX source file for creating TRIPVDU.DVI, a torture file for DVItoVDU +% (using the same philosophy as Donald Knuth's torture test for TeX). + +\nopagenumbers +\topskip 0pt +\parindent 0pt +\parskip 0pt + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 1 +% This page is completely empty but has some \special stuff. + +\message{Empty page.} +\null +\special{DVItoVDU should warn user that it is ignoring this stuff.} +\special{And this.} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 2 +% This page has 1 black pixel at (0,0). + +\message{1 black pixel at (0,0).} +\hrule height 1sp width 1sp depth 0sp +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 3 +% This page will fill an A4 sheet with black pixels, assuming A4 paper is +% 8.3in by 11.7in and (0,0) is 1in from the top and left edges. + +\message{A4 sheet full of black pixels.} +{% change page size and location temporarily +\hsize 10in +\vsize 12in +\hoffset -1in +\voffset -1in +% Because ref pts of rules are at BOTTOM left corner we first need to output +% a rule that will guarantee Minv = -1in, then output the large rule with +% slightly less than A4 height. +\hrule height 1sp width 8.299in depth 0sp +\hrule height 11.695in width 8.299in depth 0sp +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 4 +% This page is 1 pixel wider than page 3. +% DVItoVDU should detect that page is too wide for A4 paper. + +\message{As above but 1 pixel too wide.} +\hrule height 1sp width 8.301in depth 0sp +\hrule height 11.695in width 8.301in depth 0sp +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 5 +% This page is 1 pixel longer than page 3. +% DVItoVDU should detect that page is too low for A4 paper. + +\message{As above but 1 pixel too low.} +\hrule height 11.701in width 8.299in depth 0sp +\vfil\eject + +}% reset page size and location + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 6 +% This page has a rulelist with a full ruletable (= 300 rules). +% Note that DVItoVDU does not impose any limits +% on the number of rules or characters in a page. Pages 6 to 9 +% test the list manipulating code in DVIReader and DVItoVDU. + +\message{Page with ruletablesize rules.} +\newcount\temp +\temp=300 +\loop\ifnum\temp>0 + \hrule height 1sp width \hsize % 1 pixel high + \vfil + \advance\temp by -1 +\repeat +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 7 +% This page has ruletablesize+1 rules (so rulelist has 2 nodes). + +\message{Page with ruletablesize+1 rules.} +\temp=301 +\loop\ifnum\temp>0 + \hrule height 1sp width \hsize % 1 pixel high + \vfil + \advance\temp by -1 +\repeat +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 8 +% This page has a charlist with a full chartable (= 3000 characters). + +\message{Page with chartablesize characters from one font.} +\font\small=cmr5 +{\small \offinterlineskip + \temp=30 + \loop\ifnum\temp>0 + \leftline{iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii + iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii} % 100 chars + \advance\temp by -1 + \repeat +} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 9 +% This page has chartablesize+1 characters (so charlist has 2 nodes). + +\message{Page with chartablesize+1 characters from one font.} +{\small \offinterlineskip + \temp=30 + \loop\ifnum\temp>0 + \leftline{iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii + iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii} % 100 chars + \advance\temp by -1 + \repeat + \leftline{i} % the extra character +} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 10 + +\message{Multiple TeX page counters.} +\footline={\hss\tenrm\folio\hss} % turn on page numbers +\pageno=0 +\count1=1 \count2=2 \count3=3 \count4=4 \count9=9 +\noindent +This is \TeX\ page [0.1.2.3.4.....9]. +\vfil\eject + +\count1=0 \count2=0 \count3=0 \count4=0 \count9=0 % reset TeX counters + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 11 + +\message{Negative TeX page.} +\pageno=-11 +\noindent +This is \TeX\ page [-11]. +\vfil\eject + +\pageno=12 % DVI page = TeX page again +\nopagenumbers % turn off page numbers again + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 12 +% This page has characters from many fonts. +% Note that the page is off the right edge of A4 paper. + +\message{Page with characters from many fonts.} +% avoid redefining plain TeX's \i, \j etc. +\font\Fb=cmr5 +\font\Fc=cmr5 scaled\magstep5 +\font\Fe=cmr10 scaled\magstep5 +\font\Fg=cmbx10 +\font\Fh=cmbx10 scaled\magstep5 +\font\Fj=cmsl10 +\font\Fk=cmsl10 scaled\magstep5 +\font\Fm=cmtt10 +\font\Fn=cmtt10 scaled\magstep5 +\font\Fo=cmss10 +\font\Fp=cmcsc10 +\font\Fq=cmdunh10 + +\leftline{\Fb These characters are from CMR5 at mag 1000.} +\leftline{\Fc These characters are from CMR5 at mag 2488.} +\leftline{\tenrm These characters are from CMR10 at mag 1000.} +\leftline{\Fe These characters are from CMR10 at mag 2488.} +\leftline{\Fg These characters are from CMBX10 at mag 1000.} +\leftline{\Fh These characters are from CMBX10 at mag 2488.} +\leftline{\Fj These characters are from CMSL10 at mag 1000.} +\leftline{\Fk These characters are from CMSL10 at mag 2488.} +\leftline{\Fm These characters are from CMTT10 at mag 1000.} +\leftline{\Fn These characters are from CMTT10 at mag 2488.} +\leftline{\Fo These characters are from CMSS10 at mag 1000.} +\leftline{\Fp These characters are from CMCSC10 at mag 1000.} +\leftline{\Fq These characters are from CMDUNH10 at mag 1000.} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 13 +% This page has characters from many fonts, some of which have no corresponding +% PXL file. DVItoVDU should warn user about non-existent font files and +% continue as best it can by loading dummy font info. +% Note that the page is off the right edge of A4 paper. + +\message{Page with characters from fonts at unknown magnifications.} +% PXL files do not exist at the requested magnifications: +\font\Fr=cmr5 scaled 500 +\font\Fs=cmr5 scaled 3000 +\font\Ft=cmr10 scaled 200 +\font\Fu=cmr10 scaled 5000 +\font\Fv=cmsl10 scaled 200 +\font\Fw=cmsl10 scaled 10000 + +\leftline{\Fr CMR5 at mag 500 does not exist.} +\leftline{\Fb These characters are from CMR5 at mag 1000.} +\leftline{\Fs CMR5 at mag 3000 does not exist.} +\leftline{\Ft CMR10 at mag 200 does not exist.} +\leftline{\tenrm These characters are from CMR10 at mag 1000.} +\leftline{\Fu CMR10 at mag 5000 does not exist.} +\leftline{\Fv CMSL10 at mag 200 does not exist.} +\leftline{\Fj These characters are from CMSL10 at mag 1000.} +\leftline{\Fw CMSL10 at mag 10000 does not exist.} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 14 +% This page has a paragraph illustrating most of the characters from the +% standard roman TeX text font. + +\message{Standard paragraph.} +\rm +Our task is to create a paragraph illustrating what a typical piece of text +looks like in the standard \TeX\ font. It should be stressed that not all +\TeX\ fonts can be used for typesetting text. We need to show most of the +characters in this font---for instance, something like ``the quick brown fox +jumps over a lazy dog'' would use all the lower-case letters. Hmmm \dots\ +how about ``THE QUICK BROWN FOX JUMPS OVER 9876543210 LAZY DOGS'' to make +sure we show all the upper-case letters and digits? Such a paragraph would +hardly be typical! Then there's ligatures (try and fit in words like +fluffy, waffle, firefly, difficult) and examples of kerning (boxer, cooked, +vowel). Not to mention the various accents and other special letters: +prot\'eg\'e, r\^ole, na\"\i ve, \AE sop's \OE vres en fran\c cais. +But how do we put all this stuff into a paragraph that makes sense!? +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 15 + +\message{Page in bottom half of A4 paper.} +\null\vfil +\centerline{Page in bottom half of A4 paper.} +\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 16 + +\message{Page completely above left of A4 paper.} +\voffset -3in +\hoffset -9in +\leftline{Page completely above left of A4 paper.} +\vfil\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 17 + +\message{Page completely below right of A4 paper.} +\voffset 3in +\hoffset 9in +\null\vfil +\rightline{Page completely below right of A4 paper.} +\eject + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DVI page 18 + +\message{Page beyond all edges of A4 paper.} +\voffset -3in +\hoffset -3in +\vsize 15in +\hsize 15in +\line{Page beyond all edges of A4 paper.\hfil + Page beyond all edges of A4 paper.} +\vfil +\line{Page beyond all edges of A4 paper.\hfil + Page beyond all edges of A4 paper.} +\eject +\voffset 0in \hoffset 0in % offsets back to normal + +\bye diff --git a/dviware/dvgtk/doc/userguide.tex b/dviware/dvgtk/doc/userguide.tex new file mode 100644 index 0000000000..f70df582d9 --- /dev/null +++ b/dviware/dvgtk/doc/userguide.tex @@ -0,0 +1,1286 @@ +% userguide.tex - 18:29 GMT +10:00 Wed 25 Aug 1993 - modifier Geoffrey Tobin. +%**start of header +% This is the TeX source file for the "dvgt 3.51 User Guide". +% Details peculiar to our site are indicated by the string "SYSDEP". +% Cross references are indicated by the string "XREF". +% Feel free to make modifications applicable to your site. + +\input guidemacs +%**end of header + +\null +\vfil +\centerline{\title \dvgt\ User Guide} +\bigskip +\vskip\parskip +\centerline{\bigbf DVItoVDU 3.0, in Modula-2: Andrew Trevorrow, October 1988} +\smallskip +\centerline{\bigbf DVItoVDU 3.0, C conversion: Ian Dall, November 1990} +\smallskip +\centerline{\bigbf dvgt 3.51: Geoffrey Tobin + ({\tt ecsgrt@luxor.latrobe.edu.au}), + Aug 1993} +\bigskip + +\noindent +This document explains how to use {\dvgt}, a \TeX\ page previewer. +The program allows you to look at \TeX-generated DVI pages on a variety +of commonly available VDUs. +It is assumed you are already familiar with \TeX. + +\bigskip +\vskip\parskip +\centerline{\bigbf Contents} +\bigskip + +\def\aligneddots{\leaders\hbox to .75em{\hss.\hss}\hfil} + +% XREF: make sure titles and page numbers are up-to-date!!! + +\line{Introduction \aligneddots\ 1} +\line{Program Options \aligneddots\ 2} +\line{\hskip1cm Options in Detail \aligneddots\ 3} +\line{Screen Regions \aligneddots\ 7} +\line{\hskip1cm Dialog region \aligneddots\ 7} +\line{\hskip1cm Window region \aligneddots\ 8} +\line{The Commands \aligneddots\ 10} +\line{\hskip1cm Miscellaneous \aligneddots\ 10} +\line{\hskip1cm Selecting a Page \aligneddots\ 10} +\line{\hskip1cm Changing How a Page is Displayed \aligneddots\ 11} +\line{\hskip1cm Changing Units \aligneddots\ 11} +\line{\hskip1cm Moving the Window \aligneddots\ 12} +\line{\hskip1cm Changing Window Size \aligneddots\ 12} +\line{The Coordinate Scheme \aligneddots\ 14} +\line{Some Examples \aligneddots\ 15} + +\vfil\eject + +% The above is the title page; let's make a few adjustments to some parameters: +\footline={\hss\rm\folio\hss} % turn page numbers back on +\pageno=1 % and restart numbering + +\subhead{Introduction.} + +Let's assume you've just run \TeX\ and created a file called |foo.dvi|. +Even if \TeX\ did not find any errors, you cannot be sure that +the document is formatted correctly. There might be bad line breaks, bad +page breaks, alignment problems, pages too big for your printer's paper, +missing fonts---not to mention spelling mistakes. + +The lack of visual feedback is one of the major disadvantages of +using a document compiler like \TeX\null. +Without a previewing program, the only way to check |foo.dvi| is to +continue through the \TeX\ cycle and look for errors in the printed output. +This can be time consuming and is a waste of paper. +Instead, you can use {\dvgt} to look at |foo.dvi| on a variety of commonly +available terminals. + +\dvgt\ is an interactive program; you can enter commands to +select a particular page for display, look at the overall format of the +entire page and then request a smaller region for closer examination. +The manner in which the page is displayed can be varied from a full, +accurate representation to a terse, fast display for when fine details +are unimportant. +All the commands are described in detail in a later section. % XREF + +Some environment variables and/or command options are needed for {\dvgt} +to work properly. In particular, set the |DV_TERM| environment variable +to describe the type of VDU you are using; or else use the |-v| option. + +Then to look at |foo.dvi|, just type `|dvgt foo|'. + +\vfil\eject + +\subhead{Program Options.} + +The |dvgt| program has a number of options, each of which must be +followed by a value. +If the same option appears more than once, then the last value will be used. +If a particular option does not appear, then a default value will be used, +which might be taken from an environment variable. If no appropriate +environment variable is set, the default value used is that specified +in the source code --- either in `options.c', or as one of the constants +in `defaults.h'. The constants in `defaults.h' all begin with the prefix +`|DEF_|'. All the environment variables that are specific to {\dvgt} begin +with `|DV_|'. All options begin with `|-|'. + +\begindisplay +Option& Program& Environment& Default value& Meaning\cr + & Variable& Variable&&\cr +\noalign{\medskip} +|-H|& |hoffset|& ---& |0mm|& Horizontal page offset,\cr +&&&& in given units.\cr +\noalign{\medskip} +|-V|& |voffset|& ---& |0mm|& Vertical page offset,\cr +&&&& in given units.\cr +\noalign{\medskip} +|-d|& |dummy_pk|& |DV_DUMMY_PK|& |DEF_DUMMY_PK|& Dummy PK font, used when\cr +&&&& correct font's absent.\cr +\noalign{\medskip} +|-e|& |dummy_tfm|& |DV_DUMMY_TFM|& |DEF_DUMMY_TFM|& Dummy TFM, used when\cr +&&&& correct TFM's absent.\cr +\noalign{\medskip} +|-f|& |pkdir|& |TEXPKS|& |DEF_PK_DIR|& PK fonts' directory.\cr +&& else&&\cr +&& |PKFONTS|&&\cr +&& else&&\cr +&& |TEXFONTS|&&\cr +\noalign{\medskip} +|-h|& |cmd_help|& |DV_HELP|& |DEF_CMD_HELP|& Command help file read\cr +&&&& by `?' command.\cr +\noalign{\medskip} +|-i|& |immed_help|& |DV_IMMED_HELP|& |DEF_IMMED_HELP|& Help file displayed\cr +&&&& at startup.\cr +\noalign{\medskip} +|-l|& |landscape|& ---& (portrait)& Landscape page\cr +&&&& (swaps |-x| and |-y|).\cr +\noalign{\medskip} +|-m|& mag& ---& (DVI mag)& Magnification.\cr +\noalign{\medskip} +|-p|& |psprefix|& |DV_PSPREFIX|& |DEF_PS_PREFIX|& PS font name prefix.\cr +\noalign{\medskip} +|-r|& |xres|,& |DV_RES|& |DEF_XRES|,& X and Y resolutions,\cr +& |yres|&& |DEF_YRES|& in dots per inch (dpi).\cr +\noalign{\medskip} +|-t|& |tfmdir|& |TEXFONTS|& |DEF_TFM_DIR|& TFM files' directory.\cr +\noalign{\medskip} +|-v|& |vdu|& |DV_TERM|& ---& Type of VDU.\cr +&& else&&\cr +&& |TERM|&&\cr +\noalign{\medskip} +|-x|& |paperwd|& |DV_PAPERWD|& |DEF_PAPERWD|& Paper width,\cr +&&&& in given units.\cr +\noalign{\medskip} +|-y|& |paperht|& |DV_PAPERHT|& |DEF_PAPERHT|& Paper height,\cr +&&&& in given units.\cr +\noalign{\medskip} +\enddisplay + +Options -d -e -f -h -i -p -r -t are really for system wizards; +their default values have been set up so that most users need never worry +about changing them. +% SYSDEP: take note system wizards! + +\noindent Example: A4 paper using a 180 by 360 dpi printer: +\begindisplay +|dvgt -r 180,360 -x 210mm -y 297mm| +\enddisplay + +\bigskip +\noindent Default values in the supplied `defaults.h'. + +The default TFM and PK directories are: +\begindisplay +|.:/usr/local/lib/tex/fonts|\cr +|.:/usr/local/lib/tex/fonts/tmp|\cr +\enddisplay +These cause {\dvgt} to look first in the current directory, then in the +directories that are standard for Karl Berry's TeX distribution. + +The default dummy TFM metric and PK font files are: +\begindisplay +|cmr10.tfm|\cr +|cmr10.300pk|\cr +\enddisplay +since cmr10 is the most commonly used font on most TeX systems, +and 300 dpi seems the most common resolution among medium quality +printers at present. + +Consequently, the default resolution is 300,300 (dots per inch). + +In Karl Berry's font naming convention, PostScript fonts' TFM files +are prefixed with the letter `p'. By default, {\dvgt} follows this +convention. +Several PS font prefixes can be separated by the `:' character, +as with the PK and TFM directories. The `:' character was chosen +because it seems easy to remember. +If no PS font prefixes are specified, as when the list of prefixes is +an empty string, `', then {\it no\/} fonts are considered PS fonts. + +The command and immediate help files default to: +\begindisplay +|/usr/local/lib/tex/dvgt/cmd.hlp|\cr +|/usr/local/lib/tex/dvgt/immed.hlp|\cr +\enddisplay + +Since most of the industrial world uses metric paper, the default +paper size is A4 (approximately 210 mm wide by 297 mm high). + +\medskip +\bigskip +\leftline{OPTIONS in DETAIL.} +\bigskip + +\noindent +Each option is followed by a value of a certain type: +{\it string\/} is a string of alphanumeric characters, +{\it i, x, y\/} are positive integers, +{\it file\/} is a file, +{\it dir\/} is a directory, and +{\it dimen\/} is an integer or real number followed by a +two-letter unit: |bp|, |cm|, |in|, |mm|, |pc|, |pt|, |px| or |sp|. +(Most of these should be familiar from \TeX\null. {\dvgt} provides +an additional unit, |px|, which stands for ``paper pixels''. +These two-letter sequences can be arguments to the `|C|' interactive +command to change the unit of dimensions---see page 11 for details.) % XREF + +\bigskip +\noindent |-H| {\it dimen\/}~~and~~|-V| {\it dimen\/} + +These two qualifiers allow you to shift the location of each page within +the paper. Negative dimensions are allowed; +for example, |-H -.5in| shifts each page half an inch to the left. + +\bigskip +\noindent |-d| {\it file\/} + +\dvgt\ will warn you if your document uses a font at a non-existent size. +Rather than abort, it will load the dummy PK file specified by |-d|, and +following the PK paths, then continue so you can look for more errors. +Paragraphs using this dummy information are likely to have ragged right +margins, and tables are likely to be horizontally distorted. + +The quickest way to check your DVI file for missing fonts is to type +the |S| (Statistics) command. The resulting display will indicate +any PK files that do not exist, and list TFM files that are used +for Bounding Boxes. + +\bigskip +\noindent |-e| {\it file\/} + +If a TFM file is missing, then a dummy TFM is sought in the TFM paths. +The dummy TFM filename may be set using the |-e| option. + +\bigskip +\noindent |-f| {\it dir\/} + +{\dvgt} gets all its bit-mapped font information from PK files stored +in the specified directory (which can, but need not, end with |/|). + +\TeX\ gets all its font information from TFM files. A particular TFM file +usually has a number of corresponding bit-mapped font files, each one +corresponding to the same set of ideal character shapes, but at a +different size. +Although \TeX\ allows you to scale a font to virtually any size, +it is obviously impossible to provide an infinite number of bit-mapped fonts. +That is why it is best to stick to the pre-defined |\magstep| values when +scaling such fonts---you're much more likely to stay within the range of +existing PK files. + +The above warning does not apply to TFM files for resident +PostScript or other scalable fonts. Such fonts can be used at any +desired size. +However, since no bit-map information is available, \dvgt\ cannot +show characters from such fonts in a Full display. +Instead, it shows those characters as outline rectangles, using the +TFM files to determine their bounding boxes, just as in Box mode. + +\bigskip +\noindent |-h| {\it file\/} + +The |?| command reads the help file specified by this option. +The default help file contains a brief summary of all the commands. +If no help file can be found, then a pre-compiled help text is shown. + +\bigskip +\noindent |-i| + +This `option' only displays the current immediate help file's pathname +and the name of the corresponding environment variable (|DV_IMMED_HELP|). +The immediate help file is displayed when {\tt dvgt} is typed alone +on the command line. + +\bigskip +\noindent |-m| {\it i\/} + +This option allows you to replace the magnification used +in the DVI file with some other value; +{\it i\/} is a positive integer 1000 $\times$ the desired magnification. +The given value should be chosen carefully so that the new font sizes +still correspond to existing PK files. + +Unless you know exactly what you are doing, you should avoid changing +the DVI magnification, +especially if your \TeX\ source file uses |\magnification| {\it and\/} |true| +dimensions. +You should only supply a replacement magnification if you intend to +print the DVI file with the same override. + +\bigskip +\noindent |-r| {\it x,y\/} +\noindent |-r| {\it x\/} + +{\dvgt} treats the imaginary sheet of paper on which a DVI page will appear +as a two-dimensional array of tiny dots called {\it paper pixels\/}. +{\it x\/} and {\it y\/} are positive integers that define the number +of paper pixels per inch ({\it horizontally} and {\it vertically}, +respectively). When only {x\/} is given, y is assigned the same value. + +The |-r| values should match the respective resolutions of the device +that will be used to print your document. +The Apple LaserWriter, for instance, has a resolution of 300 dots per +inch, so {\tt dvgt -r 300} suits it. + +\bigskip +\noindent |-t| {\it dir\/} + +If a font name does not include an explicit directory, and requires +a TFM file, then \dvgt\ will use the |-t| value to locate the file. +The given value can, but need not, end with |/|. + +\bigskip +\noindent |-v| {\it string\/} + +This option explicitly tells {\dvgt} what type of VDU you are using. +If |-v| is not given, the value of the |DV_TERM| environment variable is used; +if that is not defined, the value of the |TERM| environment variable is used. +For example, if you're using a VISUAL 603 terminal and |DV_TERM| and |TERM| +do not equal |vis603|, then you'll need to type `|dvgt -v vis603 foo|'. +The purpose of |DV_TERM| is to allow {\dvgt} to use a graphics mode +distinct from the usual text display mode. This can be useful across +a network or in X11 windows. + +\noindent +The current version of {\dvgt} will accept the following {\it string\/} +values in upper or lower case: +\begindisplay +|aed512|& (AED 512 with 512 by 512 screen)\cr +|kermit|& (MS-Kermit, in Tek4010 emulation: same as ncsatel below)\cr +|ncsatel|& (NCSA Telnet, in Tek4010 emulation)\cr +|regis|& (any ReGIS compatible VDU; + synonyms = |gigi|, |vk100|, |vt125|, |vt240|)\cr +|tek4010|& (Tek4010 emulation: same as ncsatel above)\cr +|vis240|& (VISUAL 240; synonym = |vis241|)\cr +|vis500|& (VISUAL 500)\cr +|vis550|& (VISUAL 550)\cr +|vis603|& (VISUAL 603)\cr +|vis630|& (VISUAL 630)\cr +|vt100|& (any VT100 compatible VDU)\cr +|vt100132|& (any VT100 compatible VDU in 132 column mode)\cr +|vt220|& (VT220 using down-loaded chunky graphics)\cr +|vt640|& (VT100 with Retro-Graphics)\cr +\enddisplay + +\noindent +It is assumed your terminal has been set up to obey XON/XOFF flow control. + +\noindent +Some VDUs require special settings for {\dvgt} to work properly: + +\item{$\bullet$} +When using MS-Kermit (eg, version 3.12) over TCP/IP (eg, TELNET), for +best appearances you may wish to add the following to MSCUSTOM.INI: +\begindisplay +set flow-control none\cr +set terminal graphics character-writing opaque\cr +set terminal graphics cursor off\cr +\enddisplay + +\item{$\bullet$} +When writing to a PC monitor over NCSA Telnet, the |ncsatel| terminal +may sometimes leave you in the wrong screen mode. If that happens, +type NCSA Telnet's |Alt-R| command to reset the screen to VT102 mode. +Typing NCSA Telnet's `help' command, |Alt-H|, gives a (VT102 mode) screen +containing more information. + +\item{$\bullet$} +The |vis630| terminal needs to be in interlace mode. +Simply hit |Shift-PF3|. + +\item{$\bullet$} +The |vis500| and |vis550| terminals have function keys which control how +information on the screen is to be displayed. {\dvgt} +assumes graphic images and alphanumeric text can be seen at the +same time. To ensure that this is possible, you may need to: + +{\parskip=0pt +\smallskip +\itemitem{---} hit the |SET-UP| key +\itemitem{---} hit the |F6| function key until |F6=BOTH| appears +\itemitem{---} hit the |SET-UP| key to return to normal operating mode. +\smallskip +\item{} +You can do these steps while {\dvgt} is running. +Both terminal types should also have the Scale Factor set at 3\;:\;4. +\par +} % \parskip back to normal + +\item{$\bullet$} +The |regis| VDUs use VT100 escape sequences to update the dialog region, +and the |vis550| VDU is assumed to be emulating a VT100. +Change the appropriate |SET-UP| value if your screen becomes full of junk. + +\item{$\bullet$} +The |vt100132|, |vt220|, |vis603| and |vis630| VDUs are automatically +switched to 132 columns when \dvgt\ starts up +(and then to 80 columns when you quit). +MS-Kermit may not approve of 132 columns. + +\bigskip +\noindent |-x| {\it dimen\/}~~and~~|-y| {\it dimen\/} + +These two options define the width and height of the paper upon which your +document will eventually be printed. +% SYSDEP +Note that their default values specify A4 paper +(|210mm| wide and |297mm| high). +Every time you select a page, {\dvgt} uses the paper dimensions +to check that all the printed material will fit on the paper. + +\vfil\eject + +\subhead{Screen Regions.} + +\medskip +\bigskip +\leftline{DIALOG REGION.} +\bigskip + +If your command line is correct and if the |-v| value matches the type of +terminal you're actually using, then {\dvgt} will clear the screen +and display +\begindisplay +||$n$| pages DVI page=0 TeX page=[0] Auto=+ F Zoom=2.00|\cr +|Window at (|$h$|,|$v$|) |$wwd$| by |$wht + $| Page at (|$minh$|,|$minv$|) |$pwd$| by |$pht$| IN|\cr +|This is dvgt 3.51 (DVItoVDU, v. 3.0, gt mod 5 rev. 1) - Wed 25 Aug 93|\cr +|Command: |\cr +\enddisplay +These lines represent the ``dialog region''; the rest of the screen is +called the ``window region'' and should be blank at this stage. + +\noindent +The top two lines show status information. The first status line shows: + +\item{$\bullet$} $n$, the total number of pages in the DVI file. + +\item{$\bullet$} The current DVI page and its corresponding \TeX\ page counters. + Particular pages can be selected by their position in the DVI + file (1 to $n$) or by the value of their \TeX\ counters. + +\item{$\bullet$} The |A| command allows you to toggle + (alternately enable or disable) + the automatic calculation of window position and size upon page + selection; initially enabled (|+|). + +\item{$\bullet$} The current display mode; initially |F|, for |Full|. + The |T|, |B| and |F| commands allow you to toggle each of the + |Terse|, |Box| and |Full| display modes. All combinations of these + are permissible, but you be the judge of which combinations are useful, + and when. + +\item{$\bullet$} The current |Zoom| factor; initially |2.00|. + The |ZI|, |ZO|, |ZCI| and |ZCO| commands zoom in and out by the + current zoom factor. + |ZI| $z$ and |ZCI| $z$ zoom in, and |ZCI| $z$ and |ZCO| $z$ zoom + out, by the factor $z$, which then becomes the current zoom factor. + +\noindent +The second status line shows: + +\item{$\bullet$} The current location and size of the window. + $h$ and $v$ are horizontal and vertical coordinates that define + the current paper position of the top left corner of the window region. + The following section has details on the coordinate scheme used + by {\dvgt}\null. The |W| command allows you to move the window to an + absolute position; the |U|, |D|, |L| and |R| commands allow relative + positioning. + $wwd$ and $wht$ represent the current width and height of the window region; + their values are changed by the |H| and |V| commands (and by |ZI|, + |ZO|, |ZCI| and |ZCO|). + The initial window size depends on the |-r| value and the size and + resolution of your VDU screen. + +\item{$\bullet$} The location and size of the ``page rectangle''. + $minh$, $minv$, $maxh$ and $maxv$ define the smallest rectangle containing + all the rules and characters in the current page. + $(minh{,}minv)$ is the top left corner of this rectangle; it is + $pwd$ units wide and $pht$ units high. + +\item{$\bullet$} The current units; initially inches. + All numbers shown in this line are dimensions in terms of these units. + The two letters shown at the end of the line are the unit names. + These are: inches (|IN|), centimetres (|CM|), millimetres (|MM|), + points (|PT|), picas (|PC|), big (or PostScript, or standard) points + (|BP|), scaled points (|SP|), and paper pixels (|PX|). + Pixel values are shown as integral numbers and represent exact dimensions; + all other values are shown as real numbers rounded to two decimal places. + To change the current units, use the |C| command, then the unit name. + For example, either |CMM| or |C MM| will change to millimetres. + +\noindent +The third line initially shows the current version number. +{\dvgt} displays messages of various +kinds in this line. Some of these messages appear only briefly but may convey +helpful information. +Others are more important and indicate some sort of problem, such as +an invalid command or a page that won't fit on the paper; +in these cases, hit the |RETURN| key before continuing. + +The last line in the dialog region is for entering commands. The first +thing you normally want to do is choose a particular page for display. +For example, typing `|1|' will select the first page in the DVI file. +Many commands can be entered in the one command line. Hit |RETURN| to +execute the command(s). + +\medskip +\bigskip +\leftline{WINDOW REGION.} +\bigskip + +The number of paper pixels per inch is given by the |-r| option. +A pixel can be either black (corresponding to a tiny blob of ink) or white +(no ink). However, on a screen with black background, inked pixels are +commonly white, and uninked pixels are black. In the following, `black' +means inked, and `white' means uninked. +A typical DVI page contains characters from one or more fonts, and +perhaps a few rules. +A rule is simply a rectangular region of black pixels, usually in the shape of +a thin horizontal or vertical line. +A character is usually a more complicated pattern of black and white pixels. +Every character and rule has a +paper position---or ``reference point''---defined +by a pair of pixel values $(h{,}v)$ +where $h$ is the horizontal coordinate and $v$ is the vertical coordinate. +{\dvgt} uses a coordinate scheme in which the +position $(0{,}0)$ is a pixel one inch in from the top and left edges of +the paper. Vertical coordinates increase down the paper, +horizontal coordinates increase to the right. +Confused? The illustration on page~14 may help clear things up. % XREF + +The window region is used to view the current DVI page. +{\dvgt} treats this region of the VDU screen as a two-dimensional array +of dots called ``screen pixels'' (to distinguish them +from the paper pixels described above). +A screen pixel is the smallest possible area on a VDU screen that +can be drawn or erased; the greater the number of screen pixels in a given area, +the higher the resolution of the VDU. + +The initial size of the window region depends on the VDU; the width and height +are set so that each paper pixel corresponds to exactly one screen pixel. +The most accurate representation of a page will occur at these values since +neither horizontal nor vertical scaling is necessary: +\begindisplay +VDU& initial window size (width by height in pixels)\cr +\noalign{\smallskip} +|aed512|& \enskip 512 by 471\cr +|ncsatel|& 1024 by 780\cr % - gt - Is ncsatel correct? +|regis|& \enskip 768 by 400\cr +|vis240|& \enskip 800 by 500\cr +|vis500|, |vis550|& 1024 by 688\cr +|vis603|& 1024 by 620\cr +|vis630|& 1024 by 698\cr +|vt100|& \quad 80 by \enskip20\cr +|vt100132|& \enskip 132 by \enskip20\cr +|vt220|& \enskip 132 by 100\cr +|vt640|& 1024 by 650\cr +\enddisplay +Use the |H| command to change the width (the Horizontal size), and the +and |V| command to change the height (the Vertical size). +Try to avoid weird aspect ratios: `|H0.1 V100|' is a perfectly legal +command string, but produces a very distorted display! +If you want to zoom in or out, the |ZI|, |ZO|, |ZCI| and |ZCO| commands +are safer because they tend to maintain the current aspect ratio. +The higher the resolution of the VDU, +the greater the accuracy of such scaled displays. +The command string `|HV|' will restore the window size to the above unscaled +dimensions. + +Note the very low resolution of the |vt100| and |vt100132| VDUs. +Since the individual dots making up their screens cannot be turned on and off, +{\dvgt} has to define a screen pixel to be an entire character position. +A |vt100| screen typically consists of 24 lines of 80 characters, +therefore the initial window region is 80 pixels wide and 20 pixels high +(the top 4 lines are used for the dialog region). +These VDUs can still show bitmap character shapes, if you zoom in +closely enough! +At more useful window sizes the resulting displays will be extremely crude. +Nevertheless, a variety of formatting errors can still be detected on such +terminals---just don't try proofreading your document! + +If automatic window calculation is enabled (|Auto=+|), +then the size and location of +the window region are automatically set every time a page is selected. +{\dvgt} tries to show as much of the +paper (and presumably the page) as possible, and at a readable scale, +but without too much distortion. +After comparing the shape of the paper with the shape of your +VDU's {\it initial\/} window region, and depending on the location of the +page, {\dvgt} may show the entire paper, +or the top or bottom half, or the left or right half. +If any part of the page is off the paper, then the entire paper +{\it and\/} the entire page will initially be shown. +Since most paper sizes have portrait dimensions (width $<$ height), and most +VDU screens have landscape dimensions (width $>$ height), {\dvgt} will +normally show the top half of a sheet of paper containing the selected page. + +\vfil\eject + +\subhead{The Commands.} + +In response to the `|Command: |' prompt, you can enter one or more of the +following commands in upper or lower case. Multiple commands are +processed in the order given, but the window region is only updated, +if necessary, at the end of a line of commands. For example, +if you type `|NFD|' then {\dvgt} will get the Next page, toggle +Full display mode, move the window Down, and only then display the page. +If an illegal command is detected, any further commands are ignored. +Most commands consist of only one or two characters; some can be followed by +parameters. Spaces before and after commands and parameters are optional. + +\parskip=0pt % TURN OFF FROM HERE ON. + +\medskip +\bigskip +\leftline{MISCELLANEOUS.} +\bigskip + +\item{} \hskip -\the\parindent \hbox to \parindent{|?|\hfil}\null +Display brief help on the available commands. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|^C|\hfil}\null +|^C| will return you to the `|Command: |' level of {\dvgt}. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|^L|\hfil}\null +Refresh the window. (This is not immediate, because all interactive +commands are read before any is parsed and executed.) Useful if +the screen gets messed up, as may happen with some network software +on some VDUs. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|^Q|\hfil}\null +|^Q| is ignored. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|^S|\hfil}\null +|^S| is ignored. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|^Z|\hfil}\null +|^Z| will suspend {\dvgt}. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|A|\hfil}\null +Toggle Automatic window calculation after page selection. +When |Auto| is enabled, \dvgt\ will usually show the top half +of the imaginary sheet of paper. When |Auto| is disabled, +\dvgt\ will use the current window size and location to display the +new page. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|Q|\hfil}\null +Quit from {\dvgt}\null. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|S|\hfil}\null +Show the option values being used, as well as statistics about the number of +fonts, characters and rules used on the current page. +The file specs of each font used (on any page) will be listed. +You'll also be warned about any fonts that don't exist. + +\medskip +\bigskip +\leftline{SELECTING A PAGE.} +\bigskip + +\item{} \hskip -\the\parindent \hbox to \parindent{$i$\hfil}\null +Select the $i$th DVI page. $i$ must be a positive integer from +1 to $n$ where $n$ is the total number of pages in the DVI file. + +\bigskip +\noindent |[|$i_0$|.|$i_1$|.| $\scriptstyle\cdots$ |.|$i_9$|]| +\item{} +Select the DVI page whose \TeX\ page counters match the given specification. +$i_0$ to $i_9$ are integers separated by periods. Any number of these +integers may be absent and trailing periods may be omitted. +An absent integer will match any value in the corresponding counter. +If more than one DVI page matches, the lowest will be chosen. +E.g., |[]| is equivalent to |[.........]| and will select the first DVI page, +even though the request matches every possible page. +\medskip +\item{} +\TeX\ stores the values of |\count0,\count1,...,\count9| in each DVI page. +Plain \TeX\ only uses |\count0| to control page numbering; the remaining +counters are set to zero. +Some macro packages may use the other counters for section or chapter +numbering; e.g., |[2.5]| might mean ``select page~2 from chapter~5''. +When showing the current \TeX\ page in the top status line, {\dvgt} +always shows the value of |\count0|, but trailing counters with zero values are +not shown. +Note that plain \TeX\ uses negative values in |\count0| to indicate page +numbers in roman numerals (such as in a preface). +In most documents, the $i$th DVI page will be the same as \TeX\ page |[|$i$|]|. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|N|\hfil}\null +Select the Next DVI page. +Before any page has been requested, |N| will select the first DVI page. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|P|\hfil}\null +Select the Previous DVI page. +Before any page has been requested, |P| will select the last DVI page. + +\medskip +\bigskip +\leftline{CHANGING HOW A PAGE IS DISPLAYED.} +\bigskip + +\noindent +The |B|, |F| and |T| commands toggle each of three different ways +of displaying a page. They may be combined. +The choice of display mode depends on the capabilities of your VDU +and the level of detail you wish to see. +Whatever the display mode, the window region +is always updated in the following manner: +Visible paper edges are drawn first, followed by visible rules. +Visible characters are then shown on a font by font basis; those fonts +with the least number of characters on the page are drawn first. +\medskip +\noindent +While the window region is being updated, +but not during the drawing of a rule or character, +{\dvgt} will check to see if you've typed something at the keyboard. +You can hit the |RETURN| key to abort the display, +or you can change the display mode by hitting the |T|, |B| or |F| keys +in any combination (without hitting |RETURN|). There might be a +delay between the time you hit a key and the time something actually +happens, especially if a (visually) large rule or character is being +drawn. Over slow remote connections, this may take a while! + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|B|\hfil}\null +Toggle the display of Box outlines of the smallest rectangles containing all +black pixels in characters. +The reference point of a \TeX\ character is usually located near +the bottom left corner of one of these boxes. +Box mode is intermediate in speed between Terse and Full modes; +it is a quick and accurate way of checking +the alignment of entries in a table, for example --- assuming that +accurate TFM metrics are being used. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|F|\hfil}\null +Toggle the display of a Full representation of all pixels in characters. +Full display is the most accurate but may take some time; +hit |RETURN| or switch to Terse or Box mode if you get bored. +The fact that the display mode can be changed {\it while the window is +being updated\/} can be very useful. +A good compromise between speed and accuracy is +to start off in Full mode so that math symbols and any other special +characters are displayed correctly, then to switch to Terse mode +(by hitting |T|) when the bulk of the text begins. +Note that characters from a font that lacks a PK file, but has a TFM metric, +such as PostScript or other scalable fonts, are shown as outline rectangles +of roughly the right size. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|T|\hfil}\null +Toggle the display of a Terse representation of characters. +On high resolution VDUs the \TeX\ text fonts should be quite readable; +characters will be in +approximately the right position and may even be about the right size. +The display on low resolution VDUs can be a bit confusing; characters get +overwritten if they are too close together. Don't worry too much +if you suddenly see many more spelling mistakes than usual! +Note that the text fonts will all look alike in Terse mode. +The only way to distinguish between different fonts is to note the +order in which characters are displayed (the less used fonts are drawn first). +Most of {\dvgt}'s VDU drivers assume all characters come from a +\TeX\ text font, such as cmr10, and then attempt to map them into +similar-looking ASCII characters. +Characters from non-text fonts, such as math symbols, will usually appear +incorrect. + +\medskip +\bigskip +\leftline{CHANGING UNITS.} +\bigskip + +\noindent +All the numbers in the second line of the dialog region are dimensions in +terms of the units shown at the end of the line. +The parameters following some commands are also dimensions, in the +current units: +unlike the dimensions in \TeX, you don't explicitly type the units when you +need to specify a dimension after a \dvgt\ interactive command---simply +enter an integer or real value. +This value is rounded up internally to the nearest paper pixel, based on the +current units and the conversion factors shown below. +To change the units, use the |C| command, followed by the unit name. +For example, `|CCM H5 V3.4|' will change the units to centimetres and set the +window size to be 5\;cm wide and 3.4\;cm high. +The available units are as follows. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|BP|\hfil}\null +Dimensions are in terms of big points +(72\;bp $=$ 1\;in). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|CM|\hfil}\null +Dimensions are in terms of centimetres +(2.54\;cm $=$ 1\;in). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|IN|\hfil}\null +Dimensions are in terms of inches. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|MM|\hfil}\null +Dimensions are in terms of millimetres +(10\;mm $=$ 1\;cm). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|PC|\hfil}\null +Dimensions are in terms of picas +(1\;pc $=$ 12\;pt). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|PT|\hfil}\null +Dimensions are in terms of points +(72.27\;pt $=$ 1\;in). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|PX|\hfil}\null +Dimensions are in terms of paper pixels. +(The |-r| command line option sets the numbers of horizontal and +vertical paper pixels per inch). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|SP|\hfil}\null +Dimensions are in terms of scaled points +(65536\;sp $=$ 1\;pt). + +\medskip +\bigskip +\leftline{MOVING THE WINDOW.} +\bigskip + +\noindent +The window region can be moved to any position over the current page. +You will be told if the window moves entirely outside the page rectangle +defined by $minh$, $minv$, $maxh$ and $maxv$. If this does happen, movement +is restricted to {\it just outside\/} the edges to make it easier to get back +over the page using only the |U|, |D|, |L| and |R| commands. +If |Auto=+| then the location of the window is automatically set every time a +page is selected. This position will normally be +the top left corner of the paper; i.e., $(-1,-1)$ in inches. +The parameters $h$ and $v$ are dimensions ranging from $-480$ inches to +$+480$ inches (for those of you \TeX ing billboards). + +\bigskip +\noindent |W| $h$|,|$v$ +\item{} +Move the Window region's top left corner to the given paper position. +$h$ is the horizontal coordinate, $v$ is the vertical coordinate. +If $h$ and $v$ are absent then the window is moved to $(minh{,}minv)$, +the top left corner of the page rectangle. + +\bigskip +\noindent |U| $v$ +\item{} +Move the window Up $v$ units. +If $v$ is absent then move up an amount equal to half the window's +current height. + +\bigskip +\noindent |D| $v$ +\item{} +Move the window Down $v$ units. +If $v$ is absent then move down an amount equal to half the window's +current height. + +\bigskip +\noindent |L| $h$ +\item{} +Move the window Left $h$ units. +If $h$ is absent then move left an amount equal to half the window's +current width. + +\bigskip +\noindent |R| $h$ +\item{} +Move the window Right $h$ units. +If $h$ is absent then move right an amount equal to half the window's +current width. + +The default behavior of |U|, |D|, |L| and |R| was changed in {\dvgt} +version 3.5 to move by half the window dimension instead of by the +full window size. The newer behavior retains some visible context +when moving the window. + +\medskip +\bigskip +\leftline{CHANGING WINDOW SIZE.} +\bigskip + +\noindent +The |H| and |V| commands are used to change the +width and height of the window region. +It is up to you to maintain a sensible aspect ratio. + +The |ZI|, |ZO|, |ZCI| and |ZCO| zoom commands change both dimensions +by the same factor and so maintain the current aspect ratio. +|ZI| and |ZO| keep the top left of the window fixed; +|ZCI| and |ZCO| hold the centre of the window fixed. +If zooming causes the page to become invisible, the location of the +window may change; +otherwise, |ZCI| and |ZCO| are equivalent to |DRZIUL| and +|DRZOUL|, respectively, +where || represents the specified zoom factor (if any). + +If |Auto=+| then the width and height of the window are automatically set every +time a page is selected; the values chosen will depend on the paper dimensions. +The parameters $wd$ and $ht$ are dimensions ranging from 1 pixel to 480 inches. + +\bigskip +\noindent |H| $wd$ +\item{} +Set the Horizontal size of the window to the given width. +If $wd$ is absent then set window width to its initial, unscaled value +(one screen pixel's width equals one paper pixel's width). + +\bigskip +\noindent |V| $ht$ +\item{} +Set the Vertical size of the window to the given height. +If $ht$ is absent then set window height to its initial, unscaled value +(one screen pixel's height equals one paper pixel's height). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|ZI| $z$\hfil}\null +Zoom In (holding the top left of the window) by dividing the current +window height and width both by $z$. +This also sets the current zoom factor to $z$. +If $z$ is absent, then Zoom In by the current zoom factor. +Initially, the current zoom factor is 2 (two). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|ZO| $z$\hfil}\null +Zoom Out (holding the top left of the window) by multiplying the +current window height and width both by $z$. +This also sets the current zoom factor to $z$. +If $z$ is absent, then Zoom Out by the current zoom factor. +Initially, the current zoom factor is 2 (two). + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|ZCI| $z$\hss}\null +Zoom Center In --- as for |ZI|, except holding the window's centre. + +\bigskip +\item{} \hskip -\the\parindent \hbox to \parindent{|ZCO| $z$\hss}\null +Zoom Center Out --- as for |ZO|, except holding the window's centre. + +\vfil\eject + +\subhead{The Coordinate Scheme.} + +% MACROS FOR DIAGRAM. +% \plot is based on \point macro described on page 389 of _The TeXbook_. + +\newdimen\unit +\unit=1truein + +\def\plot % #1 is down, #2 is right, #3 is stuff to plot + #1 #2 #3\endplot + {\rlap{\kern#2\unit + \vbox to 0pt{\parindent=0pt\offinterlineskip\kern#1\unit#3}}} + +\newdimen\pix +\pix=.003truein % SYSDEP: .003" is approx 1 pixel for a 300dpi device + +\def\bigdot{\hbox to 0pt{\hss\kern3\pix$\scriptstyle\bullet$\hss}} +\def\dot{\chlap{$\cdot$}} + +\def\ulap#1{\vbox to 0pt{\vss#1}} % vertical analog of \llap +\def\dlap#1{\vbox to 0pt{#1\vss}} % vertical analog of \rlap + +\def\cvlap#1{\vbox to 0pt{\vss#1\vss}} % centre vertically +\def\chlap#1{\hbox to 0pt{\hss#1\hss}} % centre horizontally + +\def\vleaders{\leaders\vbox to .1\unit + {\vss\hrule width1sp height.05\unit\vss}\vfil} +\def\hleaders{\leaders\hbox to .1\unit + {\hss\vrule height1sp width.05\unit\hss}\hfil} + +\def\cornervrule{\hbox{\vrule width1sp height.075\unit}} +\def\cornerhrule{\vrule width.075\unit height1sp} + +\newdimen\paperwd \paperwd =\hsize +\newdimen\paperht \paperht =8.0\unit +\newdimen\pagewd \pagewd =3.0\unit +\newdimen\pageht \pageht =4.0\unit +\newdimen\windowwd \windowwd =2.5\unit +\newdimen\windowht \windowht =2.6\unit + +\def\draworiginbox + {\plot 0 0 + \cvlap{\bigdot} + \ulap{\vbox to 1\unit + {\kern.25truemm + \leaders\vbox to 1truemm{\vss\moveright1\pix\dot\vss}\vfil + \kern.75truemm + } + } + \cvlap{\kern2\pix % shift dots down slightly + \llap{\hbox to 1\unit + {\kern.25truemm + \leaders\hbox to 1truemm{\hss\dot\hss}\hfil + \kern.75truemm + }} + } + \ulap{\vbox to 1\unit + {\vfil + \rlap{~~\rlap{$1''$}~~~~~~The numbers of horizontal and + vertical pixels per inch + are set by |-r| option.} + \vfil + } + } + \ulap{\llap{$(0{,}0)$~~} + \medskip + } + \cvlap{\rlap{~~\rlap{$\rightarrow$}~~~~~~increasing $h$ coordinates}} + \dlap{\kern 1ex + \llap{\strut \hbox to 1\unit{\hfil$1''$\hfil}} + } + \dlap{\kern 1ex + \chlap{\strut $\downarrow$} + \chlap{\strut increasing} + \chlap{\strut $v$ coordinates} + } + \endplot + } + +\def\drawpaperbox + {\plot -1 -1 % top left corner of paper box + \vbox + {\hsize=\paperwd % width of paper box + \ulap + {\line{\rlap{$(-1,-1)$ in inches}\hss + Paper edges will be displayed if visible.\hss} + \medskip + } + \cvlap{\bigdot} + \hrule height 1sp + \hbox to \hsize + {\vrule height \paperht width 1sp % height of paper box + \vbox to \paperht + {\vfil + \rlap{ \strut Paper height is set} + \rlap{ \strut by |-y| option.} + \vfil + }\hfil + \vrule height \paperht width 1sp + } + \hrule height 1sp + \medskip + \centerline{Paper width is set by |-x| option.} + } + \vss + \endplot + } + +\def\drawpagebox + {\plot 2.2 0.6 % top left corner of page box + \vbox + {\hsize=\pagewd % width of page box + \cvlap{\llap{Page at $(minh{,}minv)$~~}} + \cvlap{\bigdot} + \cvlap{\rlap{\hbox to \pagewd + {\cornerhrule\hleaders\cornerhrule}}} + \dlap{\vbox to \pageht + {\centerline{\title Chapter 56} + \vskip1.175\unit + {\advance\hsize by 6\pix % get N touching maxh + \line{\title How\hfil to\hfil LOGIN} + } + \vfil + \setbox0=\hbox{\bigbf g} + \setbox1=\copy0 + \dp0=0sp + \centerline + {\bigbf HAL\thinspace9000 Be\copy0inner's Guide} + \kern\dp1 % get g touching maxv + } + } + \hbox to \hsize + {\vbox to \pageht % height of page box + {\cornervrule\vleaders\cornervrule}% + \vbox to \pageht + {\vfil + \llap{Page height. } + \vfil + }% + \hfil + \vbox to \pageht + {\cornervrule\vleaders\cornervrule}% + } + \cvlap{\rlap{\hbox to \pagewd + {\cornerhrule\hleaders\cornerhrule}}} + \cvlap{\rightline{\bigdot}} + \cvlap{\rightline{\rlap{~~$(maxh{,}maxv)$}}} + \medskip + \centerline{Page width.} + } + \vss + \endplot + } + +\def\drawwindowbox + {\plot 1.2 1.6 % top left corner of window box + \vbox + {\hsize=\windowwd % width of window box + \ulap + {\centerline{Window width is set by |H| command.} + \medskip + } + \cvlap{\llap{Window at $(h{,}v)$~~}} + \cvlap{\bigdot} + \cvlap{\rlap{\hbox to \windowwd + {\cornerhrule\hleaders\cornerhrule}}} + \dlap{\medskip + \centerline{\strut Use |U|, |D|, |L|, |R| and |W| commands} + \centerline{\strut to move the window.} + } + \dlap{\kern1\unit + \vbox to 1.6\unit + {\hsize=2\unit + \vfil + \centerline{\strut Only this portion of the} + \centerline{\strut page is currently visible.} + \vfil + } + } + \hbox to \hsize + {\vbox to \windowht % height of window box + {\cornervrule\vleaders\cornervrule}% + \hfil + \vbox to \windowht + {\cornervrule\vleaders\cornervrule}% + \vbox to \windowht + {\vfil + \rlap{ \strut Window height is} + \rlap{ \strut set by |V| command.} + \vfil + }\relax + } + \cvlap{\rlap{\hbox to \windowwd + {\cornerhrule\hleaders\cornerhrule}}} + } + \vss + \endplot + } + +% SWITCH TO SMALLER FONT, MOVE TO 0,0 AND START PLOTTING. + +\smallrm + +\vskip 1.5\unit +\hbox + {\kern 1\unit % 0,0 is 1\unit in from left margin + \draworiginbox + \drawpaperbox + \drawpagebox + \drawwindowbox + } + +\rm % back to normal text + +\vfil\eject + +\subhead{Some Examples.} + +\medskip +\noindent +For clarity, commands are separated by spaces and typed +in upper case; neither condition is mandatory. + +\bigskip\noindent +|P P P| +\item{} +If these commands are given before a page has been requested, they will select +the 3rd last page for display (assuming there are at least 3 pages). +The first |P| selects the last page; +the remaining |P|s go back another 2 pages. +Note that only the 3rd last page will be displayed. The intervening pages are +still processed, though, and you'll be warned about any problems with them +(such as a page off the paper). + +\bigskip\noindent +% |1 F W H V| % - gt - in the days before dvgt 3.5, +% % when Full was not a toggle, and +% % Terse mode was the default. +|1 W H V| +\item{} +This command sequence is very useful for looking carefully at the results of +a small \TeX\ experiment. You might, for instance, want to look closely +at the appearance of two characters separated by a small |\kern|. +Suppose that Full display only is on (as is easily arranged). Then: +|1|~selects the first DVI page (usually the only page in such experiments); +% |F|~sets the display mode to full; % - gt - since dvgt 3.5, |F| toggles, +% % and Full mode is the default. +|W|~moves the window to the top left corner of the page; +|H|~sets the horizontal size of the window to its unscaled value, and +|V|~sets the vertical size of the window to its unscaled value. +Remember that this unscaled window size produces the most accurate display, +since each screen pixel corresponds to exactly one paper pixel, both +horizontally and vertically. + +\bigskip\noindent +|R9999 L D9999 U| +\item{} +Sometimes you want to move quickly to the right edge of the page to have a +look at line breaks, or you might want to go to the bottom and look at where +the page was broken. +This particular command sequence will move the window's {\it bottom right\/} +corner to the bottom right corner of the current page; i.e., $(maxh{,}maxv)$. +In most current units (except scaled points, |SP|, which are minute), +|R9999|~suffices to move the entire window to the right of the page, +but only just; +|L|~then moves the window left by its current width so that the {\it right\/} +edges of the window and the page coincide; +|D9999|~moves the entire window below the page, but only just; +|U|~then moves the window up by its current height so that the {\it bottom\/} +edges of the window and page also coincide. + +\bigskip\noindent +|1 ZO2 FB| +\item{} +It is often useful to get an overview of the positioning of printed matter +within the sheet of paper. +These commands will do just that on all the VDUs currently +implemented, assuming that automatic window calculation is enabled +and that the display mode is already set to Full only. +|1|~selects the first page, moves the window to the top left corner of +the paper, sets the window height to half the paper height and the +window width to the paper width +(resulting in a sensible aspect ratio on a typical VDU screen); +|ZO2|~doubles the window height and width, keeping the top left +corner of the window coincident with the top left corner of the paper, +so that the entire sheet of paper is visible and maintains the right +proportions; +|FB|~changes the Full only display mode to Box outlines only, +since the characters are now likely to be too small to read. + +\bigskip\noindent +% |[.56] W IN H2.5 V2.6 R1 U1 F| % - gt - before dvgt 3.5. Now: +|[.56] W IN H2.5 V2.6 R1 U1| +\item{} +This is the likely command sequence that led to the window display shown in the +illustration on the previous page. % XREF +The [original] author [Andrew Trevorrow] has been clever enough to define +a |\chapter| macro that sets |\count1| to the given chapter number. +|[.56]|~will thus select the appropriate DVI page (|\count0| is ignored); +|W|~moves the window to the top left corner of the page; +|IN|~sets the current units to inches; +|H2.5|~and |V2.6|~set the window dimensions; +|R1|~moves the window right 1 inch; +|U1|~moves the window up 1 inch; +% |F|~sets the display mode to full. % - gt - before dvgt 3.5. + +\finishline +\bye diff --git a/dviware/dvgtk/dvgt.c b/dviware/dvgtk/dvgt.c new file mode 100644 index 0000000000..2c5b6dd3d9 --- /dev/null +++ b/dviware/dvgtk/dvgt.c @@ -0,0 +1,3595 @@ +/* dvgtk.c - main dvgtk functions + $Id: dvgt.c,v 0.2 1997/03/28 03:15:36 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" + +#include +#include +#include + +#include "defaults.h" +#include "screenio.h" +#include "options.h" +#include "unixio.h" +#include "vdu.h" +#include "dvireader.h" +#include "fontreader.h" + +/* Variables Exported, via vdu.h */ + +int DVIstatusl, windowstatusl, messagel, commandl, bottoml; +int windowh, windowv, windowwd, windowht; + + +static void DisplayPage (); +static void NextCommandLine (); +static boolean ShowCmdHelp (); + + +/*---------------------------------------------------------------------- + DECLARATIONS FOR PROCESSING USER COMMANDS + + Most commands consist of one or two characters and can be entered in + upper or lowercase. Multiple commands are processed in the order + given but we only update the window, if necessary, at the end. If a + bad command is encountered, any further commands are ignored. Some + commands can have parameters; they are all dimensions in terms of the + current units. Spaces before and after commands and parameters are + ignored. +*/ + +/* Possible commands are: */ +/* i a positive integer; display ith DVI page */ + +#define TeXpage "[" + /* start of a TeX page specification: [i0. ... .i9] */ +#define NextPage "N" + /* display next DVI page, depending on direction */ +#define Window "W" + /* move window's top left corner to given position */ +#define Up "U" + /* move window up a given amount */ +#define Down "D" + /* move window down a given amount */ +#define Left "L" + /* move window left a given amount */ +#define Right "R" + /* move window right a given amount */ +#define Hsize "H" + /* set scaledwd: window's horizontal size */ +#define Vsize "V" + /* set scaledht: window's vertical size */ +#define AutoView "A" + /* enable/disable automatic view after page selection */ +#define ZoomInOut "Z" + /* halve/double window dimensions */ +#define Terse "T" + /* display quick and nasty chars at reference points */ +#define Box "B" + /* display box outlines of glyphs */ +#define Full "F" + /* display all pixels in glyphs */ +#define Ic "I" + /* get/show dimensions in inches */ +#define Cm "C" + /* get/show dimensions in centimetres */ +#define Mm "M" + /* get/show dimensions in millimetres */ +#define PcPtPx "P" + /* get/show dimensions in picas/points/pixels */ +#define Help "?" + /* display help on available commands */ +#define Show "S" + /* display useful statistics */ +#define Quit "Q" + /* have a guess */ + +#define commprompt "Command: " + + +static String commstring; /* holds user responses */ +static int commpos; /* current position in commstring */ +static int commlen; /* length of commstring */ +static char command; /* starting character of command */ +static int maxpix; +/* maximum absolute pixel value; depends on resolution */ +/* These flags are used to handle multiple commands: */ +static boolean screenjustcleared; + /* has screen just been cleared? */ +static boolean paintDVIStatus; /* does DVI status line need updating? */ +static boolean paintWindowStatus; + /* does window status line need updating? */ +static boolean paintwindow; /* does window region need updating? */ +static boolean pageoffpaper; /* is page off paper? */ +static boolean badcommand; /* was there a bad command? */ + + +/*---------------------------------------------------------------------- + DECLARATIONS FOR DISPLAYING A PAGE + + The reference points of characters and rules on a page are stored as + pairs of horizontal and vertical paper pixel coordinates. + The paper coordinate scheme is described in detail in DVIReader. + The screen coordinate scheme is described in detail in VDU. + To update the window region, DVItoVDU maps visible paper pixels + to screen pixels using windowh and windowv to help with translation, + and windowwd and windowht to help with scaling. + What the user sees depends on the current displaymode, the current size + of the window region (scaledwd by scaledht are in paper pixels and determine + the horizontal and vertical scaling factors), and the current paper position + of the window region's top left corner; i.e., (windowleft,windowtop). + + A NOTE ON THE SCALING METHOD USED BY DVItoVDU: + We desire the following conditions when scaling paper pixels to + screen pixels: + 1. Rules/glyphs having the same top/bottom/left/right paper coordinates also + have the same screen coordinates (e.g., to ensure baselines line up). + This condition is incompatible with a rule/glyph staying the same + width and height as the window position changes! Too bad. + 2. After being scaled, visible pixel positions must not exceed the + window region's edges. In our case, only the bottom and right edges are + a problem because scaling starts at the top left corner of the window. + We use two different scaling calculations depending on + whether the h/vscalefactors are < 1.0 or not. + 3. Scaled heights and widths must be > 0 even when h/vscalefactors + approach 0. If h/vscalefactors are > 1.0 then the width/height of + paper pixels increase accordingly. +*/ + +/* terse - show quick and nasty chars at ref pts */ +/* box - show box outlines of glyphs */ +/* full - show all pixels in glyphs */ + +#define tersemode 1 +#define boxmode 2 +#define fullmode 4 +int displaymode; + +/* we get/show dimensions in currentunits */ +units currentunits; + +static int papertop, paperleft, paperbottom, paperright; + /* these define the edges of the paper */ + +static int windowtop, windowleft, windowbottom, windowright; + /* these define the current window edges */ + +static boolean allpagevisible; /* is all of page visible in window? */ +static boolean outsidepage; /* is entire window outside page? */ +static int scaledht; /* current window height in paper pixels */ +static int scaledwd; /* current window width in paper pixels */ +static double zoomfactor; /* current zoom factor - default is 2 */ +static double vscalefactor; /* windowht / scaledht */ +static double hscalefactor; /* windowwd / scaledwd */ +static ruleinfo *thisruleinfo; /* current rule info in rulelist */ +static fontinfo *unusedfont; /* first unused font in sorted fontlist */ +static fontinfo *thisfontinfo; /* current font info in sorted fontlist */ +static charinfo *thischarinfo; /* current char info in charlist */ +static int thischar; /* current index into current chartable */ +static boolean fontopen; /* is thisfontinfo->fontspec open? */ +static boolean useraborted; /* did user abort page display? */ +static boolean autoviewing; /* automatic window view enabled? */ + +static char *immed_help_strings[] = +{ + DVGT_VERSION, + "dvgt interactively views TeX-generated DVI files on some common VDUs.", + "This is the precompiled help shown if no arguments are given.", + "The options help file, `options.txt', gives more information.", + "USAGE:", + " dvgt filename[.dvi]", + " [-H x_offset] [-V y_offset] [-d dummy_pk] [-e dummy_tfm]", + " [-i] [-k kpathsea_debug_mode] [-l]", + " [-m magnification] [-r xres[,yres]]", + " [-t tfm_directory] [-x paperwd] [-y paperht]", + "", + "-H horizontal_offset (default = 0.0 in)", + "-V vertical_offset (default = 0.0 in)", + "-l (set landscape mode, instead of the default portrait mode)", + "-m magnification (default = DVI file's intrinsic magnification)", + "", + "The other parameters' default values are system dependent.", + NULL +}; + +static char *cmd_help_strings[] = +{ + "MISCELLANEOUS CHANGING PAGE DISPLAY (TOGGLES)", + "? Display this command help info T Terse - fast but inaccurate", + "S Show options, fonts and page info B Bounding Box of glyphs", + "A Toggle Auto window F Full - accurate but slow", + "^L Refresh screen", + "Q Quit from dvgt CHANGING UNITS OF DIMENSIONS", + " C u Where u is one of the units", + "SELECTING A PAGE BP, CM, IN, MM, PC, PT, PX, or SP", + "[i0. ... .i9] Select TeX page (big point, cm, inch, mm, pica,", +"i Select the ith DVI page point, paper pixel, or scaled point)", + "N Next DVI page", + "P Previous DVI page MOVING THE WINDOW", + " W h,v Move Window to given posn", +"CHANGING THE SIZE OF THE WINDOW or to (minh,minv) if no h,v ", + "H x Set Horiz. window size to x U v Move window Up by v", +" or to unscaled width if no x or by half current ht if no v", + "V y Set Vertical window size to y D v Move window Down by v", + " or to unscaled height if no y or by half cur. ht if no v", + "ZI z Zoom In by factor z L h Move window Left by h", +" or by current factor if no z or by half cur. width if no h", + "ZO z Zoom Out, as for ZI R h Move window Right by h", +"ZCI z, ZCO z Zoom wrt window center or by half cur. width if no h", + NULL +}; + +/*--------------------------------------------------------------------*/ + +static void +ClearMessageLine () +{ + /* Clear message line and move cursor to start of line. + We don't show any message here; that will usually be done + immediately after calling this routine. + */ + ClearTextLine (messagel); + MoveToTextLine (messagel); +} +/* ClearMessageLine */ +/*--------------------------------------------------------------------*/ +static void +WaitForReturn () +{ + /* DVItoVDU has just displayed an important message. + To ensure message is seen we wait for user to hit Return. + */ + + char ch; + + MesgFlush (); + do + { + ReadChar (&ch); + } + while (ch != CR); +} +/* WaitForReturn */ +/*--------------------------------------------------------------------*/ +static boolean +PrintText (char **text) +{ + int retval = false; + + if (text == (char **) NULL) + { + retval = false; /* No text to print. */ + } + else + { + /* Print each text string */ + for (; *text != (char *) NULL; text++) + { + printf ("%s", *text); + /* If there's no newline in *text, print one. */ + if (strchr (*text, '\n') == (char *) NULL) + printf ("\n"); + } + retval = true; + } + return retval; +} +/* PrintText */ +/*--------------------------------------------------------------------*/ +static boolean +ShowText (char **text) +{ + /* Show text of consecutive lines, in a way something like UNIX more. */ + int lines; + char answer; + + if (text == (char **) NULL) + { + ClearMessageLine (); + MesgString ("NULL text!"); + return false; + } + ClearScreen (); + screenjustcleared = true; + MoveToTextLine (1); + rawoutoff (); + + for (lines = 0; true; lines++) + { + if (text[lines] == (char *) NULL) + { /* end of text */ + ClearTextLine (bottoml); + MoveToTextLine (bottoml); + MesgString ("End of text,"); + MesgString (" hit RETURN key to resume page display: "); + MesgFlush (); + do + { + ReadChar (&answer); + } + while (answer != CR); + break; /* EXIT point 1 of 2 from enclosing (for) loop */ + } + if (lines >= bottoml - 2) + { + /* blank line before prompt */ + ClearTextLine (bottoml); + MoveToTextLine (bottoml); + + /* prompt */ + MesgString ("Hit RETURN key to resume page display,"); + MesgString (" or any other key for more text: "); + MesgFlush (); + + ReadChar (&answer); + if (answer == CR) + break; /* EXIT point 2 of 2 from enclosing (for) loop */ + + ClearScreen (); + screenjustcleared = true; + MoveToTextLine (1); + lines = 0; /* reset line count */ + } + MesgString (text[lines]); + MesgLine (); + } + + rawouton (); + ClearScreen (); + screenjustcleared = true; + paintDVIStatus = true; + paintWindowStatus = true; + if (currDVIpage != 0) + paintwindow = true; + + return true; +} +/* ShowText */ + +/*--------------------------------------------------------------------*/ +static boolean +ShowCmdHelp () +{ + /* Help information is displayed in lines 1 to bottoml-2. + We assume that bottoml is at least 3 and that VDU screen is at least + maxline characters wide. + */ + return ShowText (cmd_help_strings); +} +/* ShowCmdHelp */ +/*--------------------------------------------------------------------*/ +void +PadMesg () +{ + /* Pad current text line with spaces. */ + String padding; + int i; + for (i = 0; i < maxstring; i++) + padding[i] = ' '; + padding[maxstring] = '\0'; + MesgString (padding); +} +/* Pad Mesg */ +/*--------------------------------------------------------------------*/ +static void +InitWinVars () +{ + /* TeX will not generate dimensions > than about 38 feet, so we + choose an absolute limit on our dimensions to be 40 feet. + */ + + int ymaxpix = yres * (40 * 12); /* 40 ft = 40 * 12 in */ + maxpix = xres * (40 * 12); + if (ymaxpix < maxpix) + maxpix = ymaxpix; + + /* top left corner of paper is fixed at (-1",-1") */ + papertop = -yres; + paperleft = -xres; + + paperbottom = papertop + paperht - 1; + paperright = paperleft + paperwd - 1; + + /* User sees the following status values before requesting the first page. */ + + /* + FIRST STATUS LINE: # pages, DVI page, TeX page, Auto, Displaymode, Zoom. + Note that DVIReader has already counted the number of pages, + and initialized currDVIpage and currTeXpage. + */ + + autoviewing = true; /* start off enabled */ + displaymode = fullmode; /* Full mode, neither Box nor Terse mode */ + zoomfactor = 2.0; /* default factor for zooming is 2 */ + + /* + SECOND STATUS LINE: Window loc. & dims, Page loc. & dims, Unit. + */ + + windowleft = 0; /* window location */ + windowtop = 0; + scaledwd = windowwd; /* window size is initially unscaled */ + scaledht = windowht; + + minhp = 0; + minvp = 0; /* page location */ + maxhp = 0; + maxvp = 0; + hscalefactor = 1.0; /* page size is initially unscaled, too */ + vscalefactor = 1.0; + + currentunits = ic; /* inch */ + + /* WINDOW: Chars & Rules. */ + + pageempty = true; /* no page read yet, so no chars and no rules! */ +} +/* InitWinVars */ + +/*--------------------------------------------------------------------*/ +static void +UpdateDVIStatusLine () +{ + /* Show totalpages, currDVIpage, currTeXpage, direction and displaymode. */ + + int i, lastnonzero; + + ClearTextLine (DVIstatusl); + MoveToTextLine (DVIstatusl); + + MesgInt (totalpages); + MesgString (" pages"); + + MesgString (" DVI page="); + MesgInt (currDVIpage); + + MesgString (" TeX page="); + + MesgChar ('['); + + lastnonzero = 9; + while (lastnonzero > 0 && currTeXpage[lastnonzero] == 0) + { + lastnonzero--; /* find last counter with non-zero value */ + } + /* always show \count0 but don't show trailing 0 counters */ + for (i = 0; i <= lastnonzero; i++) + { + MesgInt (currTeXpage[i]); + + if (i != lastnonzero) + MesgChar ('.'); + } + MesgChar (']'); + + MesgString (" Auto="); + if (autoviewing) + MesgChar ('+'); + else + MesgChar ('-'); + + MesgString (" "); + if (displaymode & tersemode) + MesgString ("T"); + else + MesgString (" "); + + if (displaymode & boxmode) + MesgString ("B"); + else + MesgString (" "); + + if (displaymode & fullmode) + MesgString ("F"); + else + MesgString (" "); + + { + String msgstring; + /* gt - this is surely safe from overflow of msgstring - yes? */ + sprintf (msgstring, " Zoom=%.2f", zoomfactor); + MesgString (msgstring); + } + + MesgLine (); +} +/* UpdateDVIStatusLine */ + + +/*--------------------------------------------------------------------*/ +static void +WriteDimension (double precision, double res, int pixels) +{ + /* Show the given pixel dimension in terms of currentunits. */ + + double realdim = 0.0; + int fracpart; + + if (currentunits == px) + MesgInt (pixels); + else + { + switch (currentunits) + { + case ic: + realdim = (double) pixels / res; + break; + case cm: + realdim = (double) pixels / res * 2.54; + break; + case mm: + realdim = (double) pixels / res * 25.4; + break; + case bp: + realdim = (double) pixels / res * 72.0; + break; + case pc: + realdim = (double) pixels / res * 72.27 / 12.0; + break; + case pt: + realdim = (double) pixels / res * 72.27; + break; + case sp: + realdim = (double) pixels / res * 72.27 * 65536.0; + break; + case px: + return; /* can't happen */ + } /* currentunits */ + /* gt - This seems immensely complicated, for what it's doing! */ + /* show realdim to the specified precision */ + if (fabs (realdim) < 0.5 * precision) + MesgString ("0.0"); + else + { + if (realdim < 0.0) + { + MesgChar ('-'); + realdim = fabs (realdim); + } + realdim += 0.5 * precision; /* round up to specified precision */ + MesgInt ((int) realdim); /* whole part */ + MesgChar ('.'); + fracpart = (int) ((realdim - (int) realdim) / precision); + MesgInt (fracpart); + } /* if */ + } /* if */ +} + +/* WriteDimension */ + +/*--------------------------------------------------------------------*/ +static void +WriteXDim (double precision, int pixels) +{ + WriteDimension (precision, xres, pixels); +} +/* Write XDim */ +/*--------------------------------------------------------------------*/ +static void +WriteYDim (double precision, int pixels) +{ + WriteDimension (precision, yres, pixels); +} +/* Write YDim */ +/*--------------------------------------------------------------------*/ +static void +UpdateWindowStatusLine () +{ + /* Show current window location and size, page location and size, and units. */ + + double precision = 0.1; /* precision for status line */ + + ClearTextLine (windowstatusl); + MoveToTextLine (windowstatusl); + + MesgString ("Window at ("); + WriteXDim (precision, windowleft); + MesgChar (','); + WriteYDim (precision, windowtop); + MesgString (") "); + WriteXDim (precision, scaledwd); + MesgString (" by "); + WriteYDim (precision, scaledht); + + MesgString (" Page at ("); + WriteXDim (precision, minhp); + MesgChar (','); + WriteYDim (precision, minvp); + MesgString (") "); + WriteXDim (precision, maxhp - minhp + 1); + MesgString (" by "); + WriteYDim (precision, maxvp - minvp + 1); + MesgString (" "); + + switch (currentunits) + { + case ic: + MesgString ("IN"); + break; + case cm: + MesgString ("CM"); + break; + case mm: + MesgString ("MM"); + break; + case bp: + MesgString ("BP"); + break; + case pc: + MesgString ("PC"); + break; + case pt: + MesgString ("PT"); + break; + case sp: + MesgString ("SP"); + break; + case px: + MesgString ("PX"); + break; + } /* currentunits */ + MesgLine (); +} +/* UpdateWindowStatusLine */ +/*--------------------------------------------------------------------*/ +#define limit 2147483647 +/* TeX's limit = 2^31 - 1. + Should also be >= maxpix. + Note that this also defines the range of + page numbers the user can ask for! */ +#define threshold (limit / 10) /* nearing overflow */ + + +static boolean +GetInteger (char *str_in, int slen, int *pos, int *n) +{ + /* Extract an integer from given str_in starting at given pos. + pos is also used to return the position after the integer. + If no integer is found, then set n to 0 and return FALSE + (in that case, pos will only change if leading spaces were skipped). + If ABS(n) > limit then set n to sign * limit. + Valid syntax is +{digit} or -{digit} or digit{digit}. + Note that a + or - by itself is valid and sets n to 0. + */ + + String str; + + int absval, last, sign; + boolean inttoobig; + boolean intfound = false; + + memcpy (str, str_in, sizeof (String)); + + while (*pos < slen && str[*pos] == ' ') + { /* skip any leading spaces */ + (*pos)++; + } + + absval = 0; + sign = 1; + last = *pos; + inttoobig = false; + + if (*pos < slen) + { + if (str[*pos] == '-') + { + sign = -1; + last++; + } + else + { + if (str[*pos] == '+') + last++; + } + + while (last < slen && (str[last] >= '0' && str[last] <= '9')) + { + if (absval > threshold || (absval == threshold && str[last] > '7')) + inttoobig = true; + else + absval = absval * 10 + str[last] - '0'; + last++; + } + } + if (*pos == last) + { + *n = 0; + intfound = false; + } + else + { + *pos = last; + if (inttoobig) + absval = limit; + *n = sign * absval; + intfound = true; + } + + return intfound; +} /* GetInteger */ + +#undef limit +#undef threshold +/*--------------------------------------------------------------------*/ +static boolean +GetReal (char *str_in, int slen, int *pos, double *r) +{ + /* Extract a real number r from given str_in starting at given pos. + pos is also used to return the position after the real number. + If no number is found, then set r to 0.0 and return FALSE + (in that case pos will only change if leading spaces were skipped). + Valid syntax of a real number is integer[.{digit}] or .{digit} + where an integer is defined by GetInteger. + Real numbers are truncated to 4 decimal places. + Note that a sign or decimal point by itself is valid and sets r to 0.0. + */ + + String str; + int sign, intpart, fracpart, divisor; + double absreal; + + memcpy (str, str_in, strlen (str_in) + 1); + + /* GetInteger does not remember a sign by itself, so we need to check + for -ve dimensions like -.5 first. + */ + + while (*pos < slen && str[*pos] == ' ') + { /* skip any spaces */ + (*pos)++; + } + + sign = 1; + if (*pos < slen) + { + if (str[*pos] == '-') + sign = -1; + } + if (!GetInteger (str, slen, pos, &intpart)) + { + if (*pos == slen || str[*pos] != '.') + { + *r = 0.0; + return false; + } + } + /* real number is valid; + if no integer part, then intpart will be 0; + sign = +|-1 + */ + if (*pos == slen || str[*pos] != '.') + { + /* no fractional part */ + absreal = (double) abs (intpart); + } + else + { + /* extract fractional part */ + (*pos)++; /* skip over decimal point */ + divisor = 1; + fracpart = 0; + while (*pos < slen && (str[*pos] >= '0' && str[*pos] <= '9')) + { + /* only consider up to 4 decimal places */ + if (divisor < 10000) + { + divisor *= 10; + fracpart = fracpart * 10 + str[*pos] - '0'; + } + (*pos)++; + } + absreal = (double) abs (intpart) + (double) fracpart / divisor; + } + + *r = sign * absreal; + + return true; +} /* GetReal */ + + +/*--------------------------------------------------------------------*/ + +static boolean +GetDimension (double res, char *str_in, int slen, int *pos, int *n) +{ + /* Extract a dimension from given str_ starting at given pos. + n returns the corresponding number of pixels in the dimension + (which is an integer or real value in terms of currentunits); + pos is also used to return the position after the dimension. + If no dimension is found then set n to 0 and return FALSE (pos will only + change if leading spaces were skipped). + If ABS(n) > maxpix then set n to sign * maxpix. + Valid syntax of a dimension is integer[.{digit}] or .{digit} where + an integer is defined by GetInteger. + Real dimensions are truncated to 4 decimal places. + Note that a sign or decimal point by itself is valid and sets n to 0. + */ + + String str; + int sign, intdim, fracpart, divisor; + double absrealdim; + boolean intpresent, dimtoobig; + + memcpy (str, str_in, sizeof (String)); + + /* GetInteger does not remember a sign by itself, so we need to check + for -ve dimensions like -.5 first. + */ + + while (*pos < slen && str[*pos] == ' ') + { /* skip any leading spaces */ + (*pos)++; + } + + sign = 1; + if (*pos < slen) + { + if (str[*pos] == '-') + sign = -1; + } + intpresent = GetInteger (str, slen, pos, &intdim); + if (!intpresent) + { + if (*pos == slen || str[*pos] != '.') + { + *n = 0; + return false; + } + } /* if */ + /* dimension is valid; if no integer part then intdim will be 0; sign = +|-1 */ + if (*pos == slen || str[*pos] != '.') + { + /* no fractional part */ + absrealdim = abs (intdim); + } + else + { + /* extract fractional part */ + (*pos)++; /* skip over decimal point */ + divisor = 1; + fracpart = 0; + while (*pos < slen && (str[*pos] >= '0' && str[*pos] <= '9')) + { + /* only consider up to 4 decimal places */ + if (divisor < 10000) + { + divisor *= 10; + fracpart = fracpart * 10 + str[*pos] - '0'; + } + (*pos)++; + } /* while */ + absrealdim = abs (intdim) + (double) fracpart / divisor; + } /* if */ + + /* calculate n based on absrealdim, sign and currentunits */ + dimtoobig = false; + switch (currentunits) + { + case ic: + if (absrealdim > (double) maxpix / res) + dimtoobig = true; + else + *n = sign * (int) (absrealdim * res + 0.5); + break; + case cm: + if (absrealdim > (double) maxpix / res * 2.54) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / 2.54 * res + 0.5); + break; + case mm: + if (absrealdim > (double) maxpix / res * 25.4) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / 25.4 * res + 0.5); + break; + case bp: + if (absrealdim > (double) maxpix / res * 72.0) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / 72.0 * res + 0.5); + break; + case pc: + if (absrealdim > (double) maxpix / res * (72.27 / 12.0)) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / 72.27 * 12.0 * res + 0.5); + break; + case pt: + if (absrealdim > (double) maxpix / res * 72.27) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / 72.27 * res + 0.5); + break; + case sp: + if (absrealdim > (double) maxpix / res * 72.27 * 65536.0) + dimtoobig = true; + else + *n = sign * (int) (absrealdim / (72.27 * 65536.0) * res + 0.5); + break; + case px: + if (absrealdim > maxpix) + dimtoobig = true; + else + *n = sign * (int) (absrealdim + 0.5); + break; + } /* currentunits */ + + if (dimtoobig) + *n = sign * maxpix; + + return true; +} +/* GetDimension */ + +/*--------------------------------------------------------------------*/ + +static boolean +GetXDim (char *str_in, int slen, int *pos, int *n) +{ + return GetDimension (xres, str_in, slen, pos, n); +} +/* GetXDim */ + +/*--------------------------------------------------------------------*/ + +static boolean +GetYDim (char *str_in, int slen, int *pos, int *n) +{ + return GetDimension (yres, str_in, slen, pos, n); +} +/* GetYDim */ + +/*--------------------------------------------------------------------*/ + +static void +BadCommandMessage () +{ + /* A bad command has just been detected and some sort of message displayed. + Note that commpos is pointing to just after the problem character. + If there are further commands then we show user what will be ignored. + */ + + int i; + + badcommand = true; + + ClearTextLine (commandl); + MoveToTextLine (commandl); + + MesgString (commprompt); + for (i = 0; i < commpos; i++) + MesgChar (commstring[i]); + MesgChar ('!'); /* put ! after the problem character */ + if (commpos < commlen) + { + MesgString (" Ignoring: "); + for (i = commpos; i < commlen; i++) + MesgChar (commstring[i]); + } + NextCommandLine (); +} +/* BadCommandMessage */ + +/*--------------------------------------------------------------------*/ + +static void +NewLocation (int newhp, int newvp) +{ + /* Change window location to given position and update window edges. + If entire window moves outside non-empty page rectangle then outsidepage + becomes TRUE and we restrict movement to just beyond the edge(s) so that + user can easily move window (via Up,Down,Left,Right) to positions + in which one or more window and page edges coincide. + Note that allpagevisible is also updated. + */ + + outsidepage = false; + if (currDVIpage != 0 && !pageempty) + { + /* check if new position puts window entirely outside edges; + if so then minimize the movement needed to keep this true */ + + if (newvp > maxvp) + { + outsidepage = true; + newvp = maxvp + 1; + } + else if (newvp <= minvp - scaledht) + { + outsidepage = true; + newvp = minvp - scaledht; + } + if (newhp > maxhp) + { + outsidepage = true; + newhp = maxhp + 1; + } + else if (newhp <= minhp - scaledwd) + { + outsidepage = true; + newhp = minhp - scaledwd; + } + } + windowtop = newvp; + windowleft = newhp; + windowbottom = windowtop + scaledht - 1; + windowright = windowleft + scaledwd - 1; + allpagevisible = (currDVIpage != 0 && !pageempty + && (minvp >= windowtop && maxvp <= windowbottom) + && (minhp >= windowleft && maxhp <= windowright)); + + /* even if pageempty or window hasn't moved we must still call DisplayPage */ + + if (currDVIpage != 0) + paintwindow = true; +} +/* NewLocation */ + +/*--------------------------------------------------------------------*/ + +static void +WindowMove () +{ + /* Syntax of Window command is W hpos,vpos where hpos and vpos are + dimensions with leading and/or trailing spaces. If hpos,vpos absent + then we move to minhp,minvp (top left corner of page rectangle). + */ + + int hpos, vpos; /* move window to this new position */ + + /* commpos is positioned after W */ + + /* seek hpos */ + if (!GetXDim (commstring, commlen, &commpos, &hpos)) + { + /* hpos,vpos absent - move to top left of page */ + NewLocation (minhp, minvp); + return; + } + /* skip any spaces before comma */ + while (commpos < commlen && commstring[commpos] == ' ') + commpos++; + + /* seek comma */ + if (commpos == commlen || commstring[commpos] != ',') + { + /* comma , (which ought to precede vpos) is missing */ + ClearMessageLine (); + MesgString ("Comma expected!"); + if (commpos < commlen) + commpos++; + BadCommandMessage (); + return; + } + commpos++; /* skip over comma */ + + /* seek vpos */ + if (GetYDim (commstring, commlen, &commpos, &vpos)) + { + NewLocation (hpos, vpos); + } + else + { + /* vpos is missing or wrongly typed */ + ClearMessageLine (); + MesgString ("Vertical coordinate expected!"); + if (commpos < commlen) + commpos++; + BadCommandMessage (); + } +} +/* WindowMove */ + +/*--------------------------------------------------------------------*/ + +static void +WindowUpDown () +{ + int amount; /* move window up/down this many pixels */ + char STR[2]; + + /* commpos is positioned after U or D */ + if (!GetYDim (commstring, commlen, &commpos, &amount)) + /* if amount absent, move by _half_ window height */ + amount = scaledht / 2; /* for odd scaleht, this is half a pixel less */ + + sprintf (STR, "%c", command); + if (!strcmp (STR, Up)) /* move Up. (Down is positive.) */ + amount = -amount; + + NewLocation (windowleft, windowtop + amount); +} +/* WindowUpDown */ + +/*--------------------------------------------------------------------*/ + +static void +WindowLeftRight () +{ + int amount; /* move window left/right this many pixels */ + char STR[2]; + + /* commpos is positioned after L or R */ + if (!GetXDim (commstring, commlen, &commpos, &amount)) + /* if amount absent, move by _half_ window width */ + amount = scaledwd / 2; /* for odd scaledwd, this is half a pixel less */ + + sprintf (STR, "%c", command); + if (!strcmp (STR, Left)) /* move Left. (Right is positive.) */ + amount = -amount; + + NewLocation (windowleft + amount, windowtop); +} +/* WindowLeftRight */ + +/*--------------------------------------------------------------------*/ + +static void +NewWindowWidth (int wd) +{ + /* Set window width to given value (> 0 and <= max dimension). */ + + scaledwd = wd; + hscalefactor = (double) windowwd / scaledwd; +} + +/* NewWindowWidth */ + +/*--------------------------------------------------------------------*/ + +static void +SetWindowWidth () +{ + /* Set horizontal size of window region to given dimension; + if <= 0, then set horizontal size to 1 pixel. + If no parameter, then use the unscaled width represented by windowwd. + */ + + int wd; + + /* commpos is positioned after H */ + if (!GetXDim (commstring, commlen, &commpos, &wd)) + { /* parameter absent */ + NewWindowWidth (windowwd); + return; + } + /* note that maximum value of wd is restricted to maxpix */ + if (wd <= 0) + wd = 1; + NewWindowWidth (wd); +} +/* SetWindowWidth */ + +/*--------------------------------------------------------------------*/ + +static void +NewWindowHeight (int ht) +{ + /* Set window height to given value (> 0 and <= max dimension). */ + + scaledht = ht; + vscalefactor = (double) windowht / scaledht; +} + +/* NewWindowHeight */ + +/*--------------------------------------------------------------------*/ + +static void +SetWindowHeight () +{ + /* Set vertical size of window region to given dimension; + if <= 0, then set vertical size to 1 pixel. + If no parameter, then use the unscaled height represented by windowht. + */ + + int ht; + + /* commpos is positioned after V */ + if (!GetYDim (commstring, commlen, &commpos, &ht)) + { /* parameter absent */ + NewWindowHeight (windowht); + return; + } + /* note that maximum value of ht is restricted to maxpix */ + if (ht <= 0) + ht = 1; + NewWindowHeight (ht); +} +/* SetWindowHeight */ + +/*--------------------------------------------------------------------*/ + +static int +ScaleHpos (int h) +{ + /* Return a scaled value for the given horizontal window coordinate. */ + + if (hscalefactor > 1.0) + return ((int) (h * hscalefactor + 0.5)); + else /* hscalefactor <= 1.0 */ + return ((int) ((h + 0.5) * hscalefactor)); +} + +/* ScaleHpos */ + +/*--------------------------------------------------------------------*/ + +static int +ScaleVpos (int v) +{ + /* Return a scaled value for the given vertical window coordinate. */ + + if (vscalefactor > 1.0) + return ((int) (v * vscalefactor + 0.5)); + else /* vscalefactor <= 1.0 */ + return ((int) ((v + 0.5) * vscalefactor)); +} + +/* ScaleVpos */ + +/*--------------------------------------------------------------------*/ + +static void +SetAutoView () +{ + /* Toggle AutoView. */ + + autoviewing = (autoviewing == false ? true : false); +} + +/* SetAutoView */ + +/*--------------------------------------------------------------------*/ + +static void +ZITL () +{ + /* Zoom In, fixing Top Left of window. */ + + /* scaledwd and scaledht are > 0 */ + NewWindowWidth ((int) ceil (scaledwd / zoomfactor)); + NewWindowHeight ((int) ceil (scaledht / zoomfactor)); +} + +/* ZITL */ + +/*--------------------------------------------------------------------*/ + +static void +ZOTL () +{ + /* Zoom out, fixing Top Left of window. */ + + /* avoid overflow *//* GT asks: what overflow? */ + + if (maxpix / zoomfactor > scaledwd) + NewWindowWidth ((int) (scaledwd * zoomfactor)); + else + NewWindowWidth (maxpix); + + if (maxpix / zoomfactor > scaledht) + NewWindowHeight ((int) (scaledht * zoomfactor)); + else + NewWindowHeight (maxpix); +} +/* ZOTL */ + +/*--------------------------------------------------------------------*/ + +static void +ZoomWindow () +{ + /* Zoom In, or Zoom Out. */ + /* For ZI, ZO, zoom relative to top left of window. */ + /* For ZCI, ZCO, zoom relative to centre of window. */ + + /* Just read a 'Z'. */ + /* Parse the rest of a ZoomInOut command and do it. + commpos is pointing to next position in commandstr + (and should be I or O). + */ + + String zs; /* Zoom command string */ + char zch2 = '\0', zch3 = '\0'; /* Zoom command characters 2 and 3 */ + double zoomf; /* Zoom Factor */ + boolean zin = true; /* flag for Zoom direction; default = Zoom in */ + boolean zc = false; /* flag for Zoom location; default = top left */ + boolean zok = true; /* flag for valid Zoom; default = valid */ + + zs[0] = 'Z'; /* Zoom commands begin with 'Z' */ + zs[1] = '\0'; /* properly terminate zs */ + + /* read second command character, which should be 'I' or 'O'. */ + if (commpos < commlen) + { + zch2 = TOUPPER (commstring[commpos]); + commpos++; + zs[1] = zch2; + zs[2] = '\0'; + } + switch (zch2) + { + case 'I': + zc = false; + zin = true; + break; + case 'O': + zc = false; + zin = false; + break; + case 'C': + if (commpos < commlen) + { + zch3 = TOUPPER (commstring[commpos]); + commpos++; + zs[2] = zch3; + zs[3] = '\0'; + } + switch (zch3) + { + case 'I': + zc = true; + zin = true; + break; + case 'O': + zc = true; + zin = false; + break; + default: + zok = false; + break; + } + break; + default: + zok = false; + break; + } + + if (!zok) + { /* invalid Z* command */ + String got; + ClearMessageLine (); + sprintf (got, "Read `%s', ", zs); + MesgString (got); + MesgString ("ZI, ZO, ZCI or ZCO expected!"); + BadCommandMessage (); + } + else + { /* valid Zoom command */ + int pos = 0; + boolean realfound = false; + + /* skip any spaces after Zoom command */ + while (commpos < commlen && commstring[commpos] == ' ') + commpos++; + + /* scan rest of command line for a number */ + /* this is unambiguous, b/c "zoom, goto new page" is silly on a line */ + /* fortunately, commstring is well terminated, with a NUL char */ + +/* GT - this is the line I once spoilt: I wasn't advancing by characters! */ +/* GT - use the real number reading code from GetDimension? */ +/* static boolean GetReal (char * str_in, int slen, int * pos, double *r) */ + +/* if (sscanf (commstring+commpos, "%lf", &zoomf) == 1) */ + + pos = 0; /* pos == new commpos - old commpos */ + realfound = GetReal (commstring + commpos, commlen - commpos, &pos, &zoomf); + commpos += pos; + + /* Set Zoom Factor, if any. */ + if (realfound) + { + if (zoomf > 1.0) + /* change Zoom Factor */ + zoomfactor = zoomf; + else + { + /* Zooms of unity or less are rejected */ + /* this covers zero, and avoids ZI/ZO confusion for user */ + String msgstring; + + /* !! GT - dangerous, as msgstring may overflow - unlikely, though */ + sprintf (msgstring, + "zoom factor must > 1, so keeping old factor of %.2f\n", + zoomfactor); + + ClearMessageLine (); + MesgString (msgstring); + + BadCommandMessage (); + } + /* gt - signal to update status line b/c of new Zoom Factor */ + paintDVIStatus = true; + } + + /* Zoom! */ + if (zc) + { /* Zoom wrt Centre */ + if (zin) + { + /* ZCI = Zoom In to Centre. Algorithm: */ + /* Down and Right to centre of window, */ + /* Zoom in to top left of new window, */ + /* Up and Left to top left of that window. */ + + NewLocation (windowleft + scaledwd / 2, windowtop + scaledht / 2); + ZITL (); + NewLocation (windowleft - scaledwd / 2, windowtop - scaledht / 2); + } + else + { + /* ZCO = Zoom Out from Centre. Algorithm: */ + /* Down and Right to centre of window, */ + /* Zoom out from top left of new window, */ + /* Up and Left to top left of that window. */ + /* DEFECT: can be altered by Zoom Out restrictions. */ + + NewLocation (windowleft + scaledwd / 2, windowtop + scaledht / 2); + ZOTL (); + NewLocation (windowleft - scaledwd / 2, windowtop - scaledht / 2); + } + } + else + { /* Zoom wrt Top Left */ + /* DEFECT: Zoom Out is restricted; see ZOTL and NewLocation code. */ + if (zin) + ZITL (); /* ZI = Zoom In to Top Left */ + else + ZOTL (); /* ZO = Zoom out from Top Left */ + } + } +} +/* ZoomWindow */ + +/*--------------------------------------------------------------------*/ + +static boolean +NextPageFound (boolean ascending) +{ + /* User has selected next page in DVI file; what they get will depend on + the current DVI page and whether we are ascending or not. + Return TRUE iff we can move to next page. + */ + + boolean found = false; + + if (currDVIpage == 1 && !ascending) + { + ClearMessageLine (); + MesgString ("You are looking at first DVI page!"); + BadCommandMessage (); + found = false; + } + else if (currDVIpage == totalpages && ascending) + { + ClearMessageLine (); + MesgString ("You are looking at last DVI page!"); + BadCommandMessage (); + found = false; + } + else + { + MoveToNextPage (ascending); /* position to next DVI page */ + found = true; + } + return found; +} +/* NextPageFound */ + +/*--------------------------------------------------------------------*/ + +static boolean +DVIPageFound (int n) +{ + /* User has selected a particular DVI page number. + Move to page n and return TRUE iff n is in 1..totalpages. + */ + + boolean found = false; + + if (n < 1 || n > totalpages) + { + ClearMessageLine (); + if (totalpages > 1) + { + MesgString ("You can only request DVI pages 1 to "); + MesgInt (totalpages); + MesgChar ('!'); + } + else + { + MesgString ("You can only request DVI page 1!"); + } + BadCommandMessage (); + found = false; + } + else + { + MoveToDVIPage (n); /* position to given DVI page */ + found = true; + } + return found; +} +/* DVIPageFound */ + +/*--------------------------------------------------------------------*/ + +static boolean +ParseTeXpage (TeXpageinfo * newTeXpage) +{ + /* Return TRUE iff TeX page specification in commstring is valid. If so then + newTeXpage will contain the appropriate information for MoveToTeXPage. + The syntax of a TeX page specification is [n{.n}] where n is any integer as + defined by GetInteger. Up to 10 integers may be given and are separated by + periods, even if absent. Trailing periods may be omitted. Spaces before + and after integers and periods are skipped. The 10 positions correspond to + the \count0, \count1, ... ,\count9 values that TeX stores with every page. + commpos is initially pointing at [. + */ + + newTeXpage->lastvalue = 0; + while (true) + { + commpos++; + + newTeXpage->present[(int) newTeXpage->lastvalue] = + GetInteger (commstring, commlen, &commpos, + &newTeXpage->value[(int) newTeXpage->lastvalue]); + + /* commpos now at commlen, space, period, non-digit or ']' */ + + while (commpos < commlen && commstring[commpos] == ' ') + { + commpos++; /* skip any spaces */ + } + if (commpos == commlen) + { /* check this first! */ + ClearMessageLine (); + MesgString ("] expected!"); + BadCommandMessage (); /* commpos at commlen */ + return false; + } + if (commstring[commpos] == ']') + { /* end of TeX page spec */ + commpos++; + break; /* escape from enclosing "infinite" while loop */ + } + if (newTeXpage->lastvalue >= 9) + { + ClearMessageLine (); + MesgString ("] expected after 10 integers!"); + commpos++; + BadCommandMessage (); + return false; + } + newTeXpage->lastvalue++; + if (commstring[commpos] == '.') + continue; + ClearMessageLine (); + MesgString ("Period, integer or ] expected!"); + commpos++; + BadCommandMessage (); + return false; + } /* while */ + + while (newTeXpage->lastvalue > 0 + && !newTeXpage->present[(int) newTeXpage->lastvalue]) + { + newTeXpage->lastvalue--; + } + return true; +} +/* ParseTeXpage */ + +/*--------------------------------------------------------------------*/ + +static boolean +TeXPageFound () +{ + /* Return TRUE iff TeX page specification is valid and exists. + If so then position to lowest matching page. + */ + + boolean found = false; + TeXpageinfo newTeXpage; + + if (ParseTeXpage (&newTeXpage)) + { /* invalid TeX page specification */ + if (MoveToTeXPage (&newTeXpage)) + found = true; /* we found lowest matching page */ + else + { + ClearMessageLine (); + MesgString ("No TeX page matches your request!"); + BadCommandMessage (); + found = false; + } + } + else + found = false; + return found; +} +/* TeXPageFound */ + +/*--------------------------------------------------------------------*/ + +static int +Min (int a, int b) +{ + /* Return the minimum value of a and b. */ + + if (a < b) + return a; + else + return b; +} +/* Min */ + +/*--------------------------------------------------------------------*/ + +static int +Max (int a, int b) +{ + /* Return the maximum value of a and b. */ + + if (a > b) + return a; + else + return b; +} +/* Max */ + +/*--------------------------------------------------------------------*/ + +static void +ProcessPage () +{ + /* We are ready to interpret the current DVI page and fill in the various data + structures imported from DVIReader. This routine will also: + set the window size and location to useful values (if autoviewing), + update pageoffpaper (after checking to see if it was TRUE for the previous + page processed as part of a multiple command string), + set screenjustcleared, paintwindow and paintWindowStatus to TRUE, + set paintDVIStatus to FALSE. + */ + + int halfht, halfwd; + + /* We check pageoffpaper here so user can type "NNNNNNNNNNNNN..." and + note ALL the pages that are off the paper, not just the last one + processed. + */ + if (pageoffpaper) + { + ClearMessageLine (); + MesgString ("Page off paper!"); + WaitForReturn (); + /* the previous page */ + } + ClearScreen (); + screenjustcleared = true; + UpdateDVIStatusLine (); + /* a MoveTo... routine has updated currDVI/TeXpage */ + paintDVIStatus = false; + InterpretPage (); /* fill in DVIReader's page data structures */ + SortFonts (&unusedfont); + /* sort fonts in order of least chars and return + pointer to first unused font */ + ClearMessageLine (); /* clear any message */ + if (pageempty) + { + minhp = 0; + maxhp = 0; + minvp = 0; + maxvp = 0; /* for window status */ + } + if (autoviewing) + { /* view as much of paper as possible, but without too much distortion */ + if ((paperwd < paperht && windowwd >= windowht) + || (paperwd == paperht && windowwd > windowht)) + { + halfht = paperht / 2; + if (paperht & 1) /* ensure bottom visible */ + halfht++; + NewWindowHeight (halfht); /* try top half of paper */ + NewWindowWidth (paperwd); + NewLocation (paperleft, papertop); /* top left corner of paper */ + if (!pageempty && outsidepage) /* try moving down */ + NewLocation (paperleft, papertop + halfht); + } + else if ((paperwd > paperht && windowwd <= windowht) + || (paperwd == paperht && windowwd < windowht)) + { + halfwd = paperwd / 2; + if (paperwd & 1) /* ensure right visible */ + halfwd++; + NewWindowHeight (paperht); + NewWindowWidth (halfwd); /* try left half of paper */ + NewLocation (paperleft, papertop); /* top left corner of paper */ + if (!pageempty && outsidepage) /* try moving right */ + NewLocation (paperleft + halfwd, papertop); + } + else + { + /* paper shape matches unscaled window shape */ + NewWindowHeight (paperht); /* try all of paper */ + NewWindowWidth (paperwd); + NewLocation (paperleft, papertop); /* top left corner of paper */ + } + } + else + { + /* not autoviewing, so use current window location and size */ + NewWindowHeight (scaledht); + NewWindowWidth (scaledwd); + NewLocation (windowleft, windowtop); + } + + /* check if part/all of page is off paper; + if so, and autoviewing is enabled, then we set window size and location + so user can just see ALL of paper AND ALL of page. + */ + pageoffpaper = (!pageempty && ((minhp < paperleft || minvp < papertop) + || (maxhp > paperright || maxvp > paperbottom))); + if (pageoffpaper && autoviewing) + { + NewWindowHeight (Max (maxvp, paperbottom) - Min (minvp, papertop) + 1); + NewWindowWidth (Max (maxhp, paperright) - Min (minhp, paperleft) + 1); + NewLocation (Min (minhp, paperleft), Min (minvp, papertop)); + } + paintWindowStatus = true; + paintwindow = true; +} +/* ProcessPage */ + +/*--------------------------------------------------------------------*/ + +static void +ChangeUnits () +{ + /* Parse a C command. + commpos is pointing to next position in commstring. + Hope that is the start of IN, CM, MM, BP, PC, PT, SP, or PX. + */ + + char nextch1, nextch2; + String cstr; + + /* skip any spaces between 'C' command and following unit */ + + while (commpos < commlen && commstring[commpos] == ' ') + commpos++; + + /* read next two characters */ + /* these should comprise a known unit of distance */ + + if (commpos < commlen) + { + nextch1 = TOUPPER (commstring[commpos]); + commpos++; + } + else + nextch1 = ' '; + + if (commpos < commlen) + { + nextch2 = TOUPPER (commstring[commpos]); + commpos++; + } + else + nextch2 = ' '; + + sprintf (cstr, "%c%c", nextch1, nextch2); + + if (!strcmp (cstr, "IN")) + currentunits = ic; + else if (!strcmp (cstr, "CM")) + currentunits = cm; + else if (!strcmp (cstr, "MM")) + currentunits = mm; + else if (!strcmp (cstr, "BP")) + currentunits = bp; + else if (!strcmp (cstr, "PC")) + currentunits = pc; + else if (!strcmp (cstr, "PT")) + currentunits = pt; + else if (!strcmp (cstr, "SP")) + currentunits = sp; + else if (!strcmp (cstr, "PX")) + currentunits = px; + else + { + ClearMessageLine (); + MesgString ("Unknown units: `"); + MesgString (cstr); + MesgString ("'. "); + switch (nextch1) + { + case 'I': + MesgString ("IN"); + break; + + case 'C': + MesgString ("CM"); + break; + + case 'M': + MesgString ("MM"); + break; + + case 'B': + MesgString ("BP"); + break; + + case 'P': + MesgString ("PC, PT or PX"); + break; + + case 'S': + MesgString ("SP"); + break; + + default: + MesgString ("IN, CM, MM, BP, PC, PT, SP or PX"); + break; + } /* command */ + + MesgString (" expected."); + BadCommandMessage (); + + } /* strcmp (cstr, UNITNAME) */ +} +/* ChangeUnits */ + +/*--------------------------------------------------------------------*/ + +static boolean +UserHitsReturn (int *linecount) +{ + /* Do a MesgLine and return TRUE iff linecount = bottoml-2 AND user hits CR. + If linecount < bottoml-2 then return FALSE; if not, and user hits + something other than CR, then prepare a new screen before returning FALSE. + */ + + char ch; + + MesgLine (); + /* test for approaching end of screen */ + if (*linecount == bottoml - 2) + { + /* prompt for next screen */ + MoveToTextLine (bottoml); + MesgString ("Hit RETURN key to resume page display,"); + MesgString (" or any other key for more: "); + MesgFlush (); + + /* read first character typed by user in response to prompt */ + ReadChar (&ch); + if (ch == CR) + { + return true; + } + ClearScreen (); + screenjustcleared = true; + MoveToTextLine (1); + *linecount = 1; + } + else + { + (*linecount)++; + } + return false; +} +/* UserHitsReturn */ + +/*--------------------------------------------------------------------*/ + +static void +WriteUnits () +{ + switch (currentunits) + { + case ic: + MesgString ("in"); + break; + case cm: + MesgString ("cm"); + break; + case mm: + MesgString ("mm"); + break; + case bp: + MesgString ("bp"); + break; + case pc: + MesgString ("pc"); + break; + case pt: + MesgString ("pt"); + break; + case sp: + MesgString ("sp"); + break; + case px: + MesgString ("px"); + break; + } /* currentunits */ +} +/* WriteUnits */ + +/*--------------------------------------------------------------------*/ + +static int +WritePtSize (int scaledsize) +{ + /* Show given font size (in DVI units), in (possibly magnified) pts. + Return length of displayed message. + */ + + double realdim; + int fracpart; + double precision = 0.1; + int len = 0; + + realdim = scaledsize / 65536.0 * (mag / 1000.0); + /* show realdim to the precision given above */ + if (fabs (realdim) < 0.5 * precision) + { + MesgChar ('0'); + ++len; + } + else + { + if (realdim < 0.0) + { + MesgChar ('-'); + ++len; + realdim = fabs (realdim); + } + realdim += 0.5 * precision; /* round up to specified precision */ + len += MesgInt ((int) realdim); /* whole part */ + fracpart = (int) ((realdim - (int) realdim) / precision); + if (fracpart > 0) + { + MesgChar ('.'); + ++len; + len += MesgInt (fracpart); + } + } + MesgString ("pt"); + len += 2; + return (len); +} +/* WritePtSize */ + +/*--------------------------------------------------------------------*/ + +static void +ShowStatistics () +{ + /* Show option values and font/character/rule/special statistics. + UserHitsReturn controls pagination and takes the place of MesgLine. + */ + + specialinfo *temp; + int linecount, fontcount; + char ch; + static char LeftStr[] = ""; + static char RightStr[] = ""; + double precision = 1.0e-3; /* precision of quantities */ + + ClearScreen (); + screenjustcleared = true; + MoveToTextLine (1); + linecount = 1; + + MesgString ("DVI file = "); + MesgString (LeftStr); + MesgString (DVIname); + MesgString (RightStr); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("VDU = "); + MesgString (LeftStr); + MesgString (vdu); + MesgString (RightStr); + if (UserHitsReturn (&linecount)) + return; + + { /* beginblock */ + String realstring; + + MesgString ("X Resolution (dpi) = "); + /* xres is unlikely to overflow realstring */ + sprintf (realstring, "%f", xres); + MesgString (realstring); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Y Resolution (dpi) = "); + /* yres is unlikely to overflow realstring */ + sprintf (realstring, "%f", yres); + MesgString (realstring); + if (UserHitsReturn (&linecount)) + return; + + } /* endblock */ + + MesgString ("Magnification = "); + MesgInt (mag); + if (mag == DVImag) + { + MesgString (" (DVI mag)"); + } + else + { + MesgString (" (DVI mag of "); + MesgInt (DVImag); + MesgString (" was overridden)"); + } + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Dummy PK font = "); + MesgString (LeftStr); + MesgString (dummy_pk); + MesgString (RightStr); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Dummy TFM metric = "); + MesgString (LeftStr); + MesgString (dummy_tfm); + MesgString (RightStr); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Horizontal offset = "); + WriteXDim (precision, hoffset); + WriteUnits (); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Vertical offset = "); + WriteYDim (precision, voffset); + WriteUnits (); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Paper wd by ht = "); + WriteXDim (precision, paperwd); + WriteUnits (); + MesgString (" by "); + WriteYDim (precision, paperht); + WriteUnits (); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Total fonts on ALL pages = "); + MesgInt (totalfonts); + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Fonts, at pt size: (if on current page, give (total chars))"); + if (UserHitsReturn (&linecount)) + return; + + MesgString + ("H: Honest, S: Substitute; K: PK, T: TFM, D: DVI."); + if (UserHitsReturn (&linecount)) + return; + + fontcount = 0; + for (thisfontinfo = fontlist; + thisfontinfo != (fontinfo *) NULL; + thisfontinfo = thisfontinfo->nextfont) + { + String msgstr; /* output string for messages */ + int len; /* length of a displayed message */ + int maxptroom = 7; /* room for point size message */ + int i; + + if (thisfontinfo->fontspeclen == 0) + { /* need to build fontspec */ + BuildFontSpec (thisfontinfo); + /* fontexists may have become TRUE */ + } + /* most font names have at most 8 characters, for ms-dos! */ + sprintf (msgstr, "%-8s", thisfontinfo->fontname); + MesgString (msgstr); + + MesgString (" "); + len = WritePtSize (thisfontinfo->scaledsize); + for (i = len; i < maxptroom; i++) + MesgChar (' '); + + MesgString ("->"); + + if (thisfontinfo->fontexists) + { + if (thisfontinfo->honest) + MesgChar ('H'); + else /* substitute */ + MesgChar ('S'); + + if (thisfontinfo->pkfont) + MesgChar ('K'); + else /* non-PostScript TFM */ + MesgChar ('T'); + + MesgString (" "); + i = thisfontinfo->fontspeclen - 50; /* try to show last 70 chars */ + if (i < 0) + i = 0; + MesgString (thisfontinfo->fontspec + i); + } + else + { + MesgChar ('S'); + MesgChar ('D'); + + MesgString (" "); + MesgString ("Terse display"); + } + + if (thisfontinfo->fontused) + { + fontcount++; + MesgString (" ("); + MesgInt (thisfontinfo->totalchars); + MesgString (")"); + } + if (UserHitsReturn (&linecount)) + return; + } + /* end (for) loop */ + + if (currDVIpage == 0) + MesgString ("You haven't selected a page yet."); + else + { + MesgString ("Total fonts on current page = "); + MesgInt (fontcount); + } + if (UserHitsReturn (&linecount)) + return; + + MesgString ("Total rules on current page = "); + MesgInt (totalrules); + + if (speciallist != (specialinfo *) NULL) + { + if (UserHitsReturn (&linecount)) + return; + + MesgString ("\\special commands on current page: "); + if (UserHitsReturn (&linecount)) + return; + + temp = speciallist; + while (temp != (specialinfo *) NULL) + { + MesgString ("At ("); + WriteXDim (precision, temp->hp); + MesgChar (','); + WriteYDim (precision, temp->vp); + MesgString ("): "); + MesgString (temp->special); + if (UserHitsReturn (&linecount)) + return; + + temp = temp->nextspecial; + } /* while */ + } /* if */ + MesgLine (); + MesgLine (); + MoveToTextLine (bottoml); + MesgString ("Hit RETURN key to resume page display: "); + MesgFlush (); + + do + { + ReadChar (&ch); + } + while (ch != CR); + +} +/* ShowStatistics */ + +/*--------------------------------------------------------------------*/ +/*--------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------*/ + +#define edgepixel '.' + /* black pixel for outlines on non-graphic VDUs; + note that VDU TeXtoASCII['.'] = '.' */ + +static void +DisplayPaperEdges () +{ + /* Display visible outlines of the imaginary sheet of paper. + Thickness of outlines = 1 screen pixel, + no matter what the h and v scaling. + */ + + int top, bot, left, right; /* visible edges of paper in paper pixels */ + int scaledtop, scaledleft; /* scaled visible edges in screen pixels */ + int scaledbot, scaledright, scaledheight; + /* scaled width and height */ + int scaledwidth; + + /* first check if any part of paper is visible */ + + if (papertop > windowbottom) + return; + + if (paperbottom < windowtop) + return; + + if (paperleft > windowright) + return; + + if (paperright < windowleft) + return; + + /* part or all of paper is visible, so return visible region */ + top = Max (papertop, windowtop); + bot = Min (paperbottom, windowbottom); + left = Max (paperleft, windowleft); + right = Min (paperright, windowright); + scaledtop = ScaleVpos (top - windowtop) + windowv; + scaledleft = ScaleHpos (left - windowleft) + windowh; + if (vscalefactor > 1.0) + scaledbot = ScaleVpos (bot - windowtop + 1) + windowv - 1; + else + scaledbot = ScaleVpos (bot - windowtop) + windowv; + if (hscalefactor > 1.0) + scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1; + else + scaledright = ScaleHpos (right - windowleft) + windowh; + scaledheight = scaledbot - scaledtop + 1; + scaledwidth = scaledright - scaledleft + 1; + /* only show visible edges if they are also paper outlines */ + if (left == paperleft) + ShowRectangle (scaledleft, scaledtop, 1, scaledheight, edgepixel); + if (bot == paperbottom) + ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, edgepixel); + if (top == papertop) + ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, edgepixel); + if (right == paperright) + ShowRectangle (scaledright, scaledtop, 1, scaledheight, edgepixel); +} +/* DisplayPaperEdges */ + +#undef edgepixel + + +/*--------------------------------------------------------------------*/ + +static boolean +RectangleVisible (int intop, int inbot, int inleft, int inright, + int *outtop, int *outbot, int *outleft, int *outright) +{ + /* Return TRUE iff part or all of given rectangle would be visible + in the current window. Iff so, then we also return the visible + region; the input and possible output rectangles are defined by their + top, bottom, left and right edges in paper pixel coordinates. + */ + + if (allpagevisible) + { /* all of rectangle must be visible */ + *outtop = intop; + *outbot = inbot; + *outleft = inleft; + *outright = inright; + return true; + } + else if (intop > windowbottom) + return false; + else if (inbot < windowtop) + return false; + else if (inleft > windowright) + return false; + else if (inright < windowleft) + return false; + else + { + /* part or all of rectangle is visible, so return visible region */ + *outtop = Max (intop, windowtop); + *outbot = Min (inbot, windowbottom); + *outleft = Max (inleft, windowleft); + *outright = Min (inright, windowright); + return true; + } +} +/* RectangleVisible */ + +/*--------------------------------------------------------------------*/ + +#define RULEPIXEL '*' + /* black pixel for rules on non-graphic VDUs; + note that VDU sets TeXtoASCII['*'] := '*' */ + + +static void +DisplayRules () +{ + /* Display all pixels in rules, regardless of current displaymode. + Rules will be displayed in the same order as in the DVI page (essentially + top-down and left-right) because of the way DVIReader builds a rulelist. + */ + + int top, bottom, left, right; /* visible edges of rule */ + int scaledtop, scaledleft; /* scaled visible edges */ + int scaledbot, scaledright, scaledwidth, scaledheight; + /* scaled width and height */ + int thisrule; + char keyhit; /* returned by BusyRead if TRUE */ + _REC_ruletable *ruletab = (_REC_ruletable *) NULL; + + thisruleinfo = rulelist; + while (thisruleinfo != (ruleinfo *) NULL) + { + thisrule = 0; + while (thisrule < thisruleinfo->rulecount) + { + ruletab = &thisruleinfo->ruletable[thisrule]; + /* check if any part of rule is visible */ + /* vp,hp is bottom left corner of rule on page */ + if (RectangleVisible (ruletab->vp - ruletab->ht + 1, + ruletab->vp, ruletab->hp, + ruletab->hp + ruletab->wd - 1, + &top, &bottom, &left, &right)) + { /* rule edges */ + /* show all pixels in this rectangle */ + scaledtop = ScaleVpos (top - windowtop) + windowv; + scaledleft = ScaleHpos (left - windowleft) + windowh; + + if (vscalefactor > 1.0) + scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1; + else + scaledbot = ScaleVpos (bottom - windowtop) + windowv; + + if (hscalefactor > 1.0) + scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1; + else + scaledright = ScaleHpos (right - windowleft) + windowh; + + /* v coord of top left cnr */ + scaledheight = scaledbot - scaledtop + 1; + + /* h coord of top left cnr */ + scaledwidth = scaledright - scaledleft + 1; + + ShowRectangle (scaledleft, scaledtop, scaledwidth, scaledheight, + RULEPIXEL); + + /* check keyboard after every visible rule */ + if (BusyRead (&keyhit)) + { + char STR1[2]; + keyhit = TOUPPER (keyhit); + sprintf (STR1, "%c", keyhit); + if (!strcmp (STR1, Terse)) + { + displaymode ^= tersemode; /* toggle terse mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else + { + char STR2[2]; + sprintf (STR2, "%c", keyhit); + if (!strcmp (STR2, Box)) + { + displaymode ^= boxmode; /* toggle box mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else + { + char STR3[2]; + sprintf (STR3, "%c", keyhit); + if (!strcmp (STR3, Full)) + { + displaymode ^= fullmode; /* toggle full mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else if (keyhit == CR) + { + useraborted = true; /* checked in DisplayPage */ + return; + + } /* if */ + } /* if */ + } /* if */ + } /* if */ + } /* if */ + /* visible rectangle */ + thisrule++; + } /* while */ + thisruleinfo = thisruleinfo->nextrule; + } /* while */ +} +/* DisplayRules */ + + + + +/*--------------------------------------------------------------------*/ +/* Adapted from xdvi-20.0 by Paul Vojta */ +/* Keys for epsf specials */ + +static char *keytab[] = +{ + "clip", + "llx", + "lly", + "urx", + "ury", + "rwi", + "rhi", + + "hsize", + "vsize", + "hoffset", + "voffset", + "hscale", + "vscale", + "angle" +}; + +#define KEY_LLX keyval[0] +#define KEY_LLY keyval[1] +#define KEY_URX keyval[2] +#define KEY_URY keyval[3] +#define KEY_RWI keyval[4] +#define KEY_RHI keyval[5] + +#define KEY_HSIZE keyval[6] +#define KEY_VSIZE keyval[7] +#define KEY_HOFFSET keyval[8] +#define KEY_VOFFSET keyval[9] +#define KEY_HSCALE keyval[10] +#define KEY_VSCALE keyval[11] +#define KEY_ANGLE keyval[12] + +#define NKEYS (sizeof(keytab)/sizeof(*keytab)) +#define N_ARGLESS_KEYS 1 + +static int +epsf_special (char *cp, int *wd, int *ht) +{ + char *filename; + int filenamelen = 0; + int flags = 0; + double keyval[NKEYS - N_ARGLESS_KEYS]; + + /* skip to the file name */ + while (isspace (*cp)) + ++cp; + if (*cp != '=') + return 0; + do + ++cp; + while (isspace (*cp)); + + filename = cp; + if (*cp == '\'' || *cp == '"') + { + do + ++cp; + while (*cp != '\0' && *cp != *filename); /* up to closing ['"] */ + ++filename; + } + else + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + ++cp; + filenamelen = cp - filename; + while (*cp == ' ' || *cp == '\t') + ++cp; + while (*cp != '\0') + { + char *p1 = cp; + int keyno; + + while (*p1 != '=' && !isspace (*p1) && *p1 != '\0') + ++p1; + for (keyno = 0;; ++keyno) + { + if (keyno >= NKEYS) + { +#if 0 + Fprintf (stderr, + "%s: unknown keyword (%*s) in \\special will be ignored\n", + prog, (int) (p1 - cp), cp); +#endif + + break; + } + if (strncmp (cp, keytab[keyno], p1 - cp) == 0) + { + if (keyno >= N_ARGLESS_KEYS) + { + while (isspace (*p1)) + ++p1; + if (*p1 == '=') + { + ++p1; + while (isspace (*p1)) + ++p1; + } + { + int keyno_tmp = keyno - N_ARGLESS_KEYS; + keyval[keyno_tmp] = atof (p1); + flags |= (1 << keyno_tmp); + } + } + break; + } + } + cp = p1; + while (!isspace (*cp) && *cp != '\0') + ++cp; + while (isspace (*cp)) + ++cp; + } + + if ((flags & 0x30) == 0x30 || ((flags & 0x30) && (flags & 0xf) == 0xf)) + { + /* convert from pt to sp and next to pixels */ + *wd = XPixelRound (65536 * 0.1 * ((flags & 0x10) ? KEY_RWI + : KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY - KEY_LLY))); + *ht = YPixelRound (65536 * 0.1 * ((flags & 0x20) ? KEY_RHI + : KEY_RWI * (KEY_URY - KEY_LLY) / (KEY_URX - KEY_LLX))); + return 1; + } + else if ((flags & 0xc0) == 0xc0) + { + *wd = XPixelRound (65536 * ((flags & 0x400) ? KEY_HSCALE : 1.0) * KEY_HSIZE); + *ht = YPixelRound (65536 * ((flags & 0x800) ? KEY_VSCALE : 1.0) * KEY_VSIZE); + return 1; + } + return 0; +} + +/*--------------------------------------------------------------------*/ +static void +DisplaySpecials () +{ + /* Display dvips eps specials as boxes */ + + int top, bottom, left, right; /* visible edges of special */ + int scaledtop, scaledleft; /* scaled visible edges */ + int scaledbot, scaledright, scaledwidth, scaledheight; + /* scaled width and height */ + specialinfo *thisspecial; + char keyhit; /* returned by BusyRead if TRUE */ + + thisspecial = speciallist; + while (thisspecial != (specialinfo *) NULL) + { + int wd, ht; + /* Using undeclared strncasecmp just as xdvik/hypertex.c does. */ + if (strncasecmp (thisspecial->special, "psfile", 6) == 0 && + epsf_special (thisspecial->special + 6, &wd, &ht)) + { + /* check if any part of special is visible */ + /* vp,hp is bottom left corner of special on page */ + if (RectangleVisible (thisspecial->vp - ht + 1, + thisspecial->vp, + thisspecial->hp, + thisspecial->hp + wd - 1, + &top, &bottom, &left, &right)) + { /* special edges */ + /* show all pixels in this rectangle */ + scaledtop = ScaleVpos (top - windowtop) + windowv; + scaledleft = ScaleHpos (left - windowleft) + windowh; + + if (vscalefactor > 1.0) + scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1; + else + scaledbot = ScaleVpos (bottom - windowtop) + windowv; + + if (hscalefactor > 1.0) + scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1; + else + scaledright = ScaleHpos (right - windowleft) + windowh; + /* coord of top left cnr */ + scaledheight = scaledbot - scaledtop + 1; + scaledwidth = scaledright - scaledleft + 1; + + if (left == thisspecial->hp) + ShowRectangle (scaledleft, scaledtop, 1, scaledheight, RULEPIXEL); + if (bottom == thisspecial->vp) + ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, RULEPIXEL); + if (top == thisspecial->vp - ht + 1) + ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, RULEPIXEL); + if (right == thisspecial->hp + wd - 1) + ShowRectangle (scaledright, scaledtop, 1, scaledheight, RULEPIXEL); + + /* check keyboard after every visible special */ + if (BusyRead (&keyhit)) + { + char STR1[2]; + keyhit = TOUPPER (keyhit); + sprintf (STR1, "%c", keyhit); + if (!strcmp (STR1, Terse)) + { + displaymode ^= tersemode; /* toggle terse mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else + { + char STR2[2]; + sprintf (STR2, "%c", keyhit); + if (!strcmp (STR2, Box)) + { + displaymode ^= boxmode; /* toggle box mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else + { + char STR3[2]; + sprintf (STR3, "%c", keyhit); + if (!strcmp (STR3, Full)) + { + displaymode ^= fullmode; /* toggle full mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else if (keyhit == CR) + { + useraborted = true; /* checked in DisplayPage */ + return; + + } /* if */ + } /* if */ + } /* if */ + } /* if */ + } /* if */ + } + thisspecial = thisspecial->nextspecial; + } /* while */ +} +/* DisplaySpecials */ + +#undef RULEPIXEL + +/*--------------------------------------------------------------------*/ + +static boolean +PixelVisible (int hpos, int vpos) +{ + /* Return TRUE iff given paper pixel would be visible in current window. */ + + if (allpagevisible) + return true; + else if (vpos < windowtop) + return false; + else if (vpos > windowbottom) + return false; + else if (hpos < windowleft) + return false; + else if (hpos > windowright) + return false; + else + return true; +} +/* PixelVisible */ + +/*--------------------------------------------------------------------*/ + +static boolean +TerseChar () +{ + /* Display a quick and nasty representation of character, + only if ref pt visible. + Just how good the representation is, + depends on the capabilities of the VDU. + We don't bother checking + whether glyph is actually blank or non-existent. + */ + + _REC_chartable *chartab = &thischarinfo->chartable[thischar]; + + if (chartab == (_REC_chartable *) NULL) + return false; + + if (PixelVisible (chartab->hp, chartab->vp)) /* ref pt of char is visible */ + ShowChar (ScaleHpos (chartab->hp - windowleft) + windowh, + ScaleVpos (chartab->vp - windowtop) + windowv, + chartab->code); + + return true; +} +/* TerseChar */ + +/*--------------------------------------------------------------------*/ + +static boolean +BoxChar () +{ + /* Display visible box outlines of glyph. + Thickness of outlines = 1 screen pixel, + no matter what the h and v scaling. + */ + + int vpmyo, hpmxo; /* vp-yo, hp-xo: glyph's top and left edges */ + int top, bottom, left, right; /* visible edges of glyph */ + int scaledtop, scaledleft; /* scaled visible edges */ + int scaledbot, scaledright, scaledheight; + /* scaled width and height */ + int scaledwidth; + char ch; + + _REC_chartable *chartab = &thischarinfo->chartable[thischar]; + _REC_pixeltable *pixtab = (_REC_pixeltable *) NULL; + + if (chartab == (_REC_chartable *) NULL) + return false; + + pixtab = &thisfontinfo->pixelptr[chartab->code]; + if (pixtab == (_REC_pixeltable *) NULL) + return false; + + if (pixtab->mapadr != 0) + { /* glyph present and non-blank */ + /* check if any part of glyph is visible */ + + vpmyo = chartab->vp - pixtab->yo; + hpmxo = chartab->hp - pixtab->xo; + + if (RectangleVisible (vpmyo, vpmyo + pixtab->ht - 1, + hpmxo, hpmxo + pixtab->wd - 1, + &top, &bottom, &left, &right)) + { /* glyph edges */ + + scaledtop = ScaleVpos (top - windowtop) + windowv; + scaledleft = ScaleHpos (left - windowleft) + windowh; + + if (vscalefactor > 1.0) + scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1; + else + scaledbot = ScaleVpos (bottom - windowtop) + windowv; + + if (hscalefactor > 1.0) + scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1; + else + scaledright = ScaleHpos (right - windowleft) + windowh; + + scaledheight = scaledbot - scaledtop + 1; + scaledwidth = scaledright - scaledleft + 1; + + /* Only show edges that are also glyph outlines! + Following method reduces the number of ShowRectangle calls needed for + very small boxes. + */ + ch = chartab->code; + if ((scaledheight < 3 + && (top == vpmyo && bottom == vpmyo + pixtab->ht - 1)) + || (scaledwidth < 3 + && (left == hpmxo && right == hpmxo + pixtab->wd - 1))) + { + ShowRectangle (scaledleft, scaledtop, scaledwidth, scaledheight, ch); + } + else + { + if (left == hpmxo) + ShowRectangle (scaledleft, scaledtop, 1, scaledheight, ch); + if (bottom == vpmyo + pixtab->ht - 1) + ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, ch); + if (top == vpmyo) + ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, ch); + if (right == hpmxo + pixtab->wd - 1) + ShowRectangle (scaledright, scaledtop, 1, scaledheight, ch); + } + } + /* visible part */ + } + return true; +} +/* BoxChar */ + +/*--------------------------------------------------------------------*/ + +static void +NotFound (char *fspec) +{ + StartText (); + ResetVDU (); /* do before message since it might erase screen! */ + FATAL1 ("Couldn't open font %s.", fspec); +} + +/* NotFound */ + +/*--------------------------------------------------------------------*/ + +#define MAXVISWORDS 100 +#define WORDSIZE 32 + +/* MAXVISWORDS * WORDSIZE = 100 * 32 = 3200 bits = maximum pixel width + of glyph! + If any fonts have glyphs wider than this, then increase MAXVISWORDS. + */ + +/* SYSDEP: BITSET is 32 bit word with elements 31,30,29,...,0 */ +typedef Word glyphrow[MAXVISWORDS]; + + +static boolean +FullChar () +{ + /* Display all pixels in a glyph using bitmap from font file. + The algorithm avoids overlapping rows when vscalefactor < 1.0. + When hscalefactor < 1.0, it is not worth the extra code to avoid + overlapping runs of 1 bits because the majority of character glyphs + have only one or two runs per row. + */ + + int vpmyo, hpmxo; /* vp-yo, hp-xo: glyph's top and left edges */ + int top, bottom, left, right; /* visible edges of glyph */ + int scaledv, scalednextv; /* scaled vertical positions for rows */ + int scaledh = 0; /* scaled horizontal positions within row */ + int scaledwidth, scaledheight; /* scaled width and height of row */ + int thisrow, thisbit; /* in paper coordinates */ + int wordsperrow; /* rows of bitmap are word aligned */ + int firstbit, lastbit; /* somewhere in 0 .. wordsperrow*WORDSIZE-1 */ + int firstword, lastword; /* somewhere in 0 .. wordsperrow-1 */ + int endword; /* = visible words in row, - 1 */ + int wordpos; /* 0 .. endword */ + int bitpos; /* (WORDSIZE-1) .. 0 */ + int i; + + glyphrow row; /* holds VISIBLE bits in one row of glyph; + possibly > one row if vscalefactor < 1.0 */ + + int_or_bptr ptr; /* pointer into bitmap - actually a "struct" */ + boolean inrun = false; /* are we in a run of black pixels in row? */ + + _REC_chartable *chartab = &thischarinfo->chartable[thischar]; + _REC_pixeltable *pixtab = &thisfontinfo->pixelptr[chartab->code]; + + if (pixtab->mapadr != 0) + { /* glyph present and non-blank */ + /* check if any part of glyph is visible */ + + vpmyo = chartab->vp - pixtab->yo; + hpmxo = chartab->hp - pixtab->xo; + if (RectangleVisible (vpmyo, vpmyo + pixtab->ht - 1, hpmxo, + hpmxo + pixtab->wd - 1, &top, &bottom, &left, &right)) + { /* glyph edges */ + if (pixtab->bitmap.UU.mptr == (Word *) NULL) + { + if (!fontopen) + { /* dimensions of bitmap */ + if (thisfontinfo->fontexists) + { + if (!OpenFontFile (thisfontinfo->fontspec)) + NotFound (thisfontinfo->fontspec); + } + else + { + NotFound (dummy_pk); /* !!! */ + } + fontopen = true; /* only open font once */ + } + /* bitmap info in font file */ + /* &pixtab->bitmap receives the starting address of bitmap */ + if (!GetBitmap (pixtab->ht, pixtab->wd, pixtab->mapadr, &pixtab->bitmap)) + return false; + } + /* Words in 1 row of bitmap */ + wordsperrow = (pixtab->wd + (WORDSIZE - 1)) / WORDSIZE; + + firstbit = left - hpmxo; /* first visible bit */ + lastbit = right - hpmxo; /* last visible bit */ + firstword = firstbit / WORDSIZE; /* first visible word */ + lastword = lastbit / WORDSIZE; /* last visible word */ + endword = lastword - firstword; + + /* set the visible words in row to 0 */ + for (i = 0; i <= endword; i++) + row[i] = 0; + /* calculate scaled v coord of first visible row */ + scaledv = ScaleVpos (top - windowtop) + windowv; + + /* only consider visible rows; thisrow := top to bottom */ + thisrow = top; + while (true) + { + /* move to first byte of first visible word in this row */ + ptr.UU.int_ = pixtab->bitmap.UU.int_ + + ((thisrow - vpmyo) * wordsperrow + firstword) * 4; + /* get row of visible words from bitmap and OR with row array */ + wordpos = 0; + while (true) + { + row[wordpos] |= *ptr.UU.bptr; /* set union */ + if (wordpos == endword) + break; /* escape from inner "infinite" loop */ + wordpos++; + ptr.UU.int_ += 4; /* next word */ + } + /* calculate scaled v coord of next row */ + scalednextv = ScaleVpos (thisrow - windowtop + 1) + windowv; + scaledheight = scalednextv - scaledv; + if (scaledheight > 0 || thisrow == bottom) + { + /* display black pixels in row, doing any h/v expansion */ + if (scaledheight < 1) /* avoid 0 */ + scaledheight = 1; + inrun = false; + /* bitpos ranges over (WORDSIZE-1)..0 */ + bitpos = (WORDSIZE - 1) - (firstbit & (WORDSIZE - 1)); + wordpos = 0; + + /* only consider visible bits; thisbit := left to right */ + thisbit = left; + while (true) + { /* bit loop */ + if ((unsigned) bitpos < WORDSIZE + && ((1 << bitpos) & row[wordpos]) != 0) + { /* start/continue run */ + if (!inrun) + { /* remember start of run */ + inrun = true; + scaledh = ScaleHpos (thisbit - windowleft) + windowh; + } + } + else if (inrun) + { + inrun = false; + scaledwidth = ScaleHpos (thisbit - windowleft) + windowh - scaledh; + if (scaledwidth < 1) /* avoid 0 */ + scaledwidth = 1; + ShowRectangle (scaledh, scaledv, scaledwidth, scaledheight, + chartab->code); + } + if (thisbit == right) /* EXIT bit loop */ + break; + if (bitpos == 0) + { + wordpos++; + bitpos = (WORDSIZE - 1); + } + else + { /* look at next bit in word */ + bitpos--; + } + thisbit++; + } /* bit loop */ + + if (inrun) + { /* show run at end of row */ + scaledwidth = ScaleHpos (thisbit - windowleft + 1) + windowh - scaledh; + if (scaledwidth < 1) /* avoid 0 */ + scaledwidth = 1; + ShowRectangle (scaledh, scaledv, scaledwidth, scaledheight, + chartab->code); + } + if (thisrow == bottom) /* EXIT row loop */ + break; + /* else reset the visible words in row to 0 */ + for (i = 0; i <= endword; i++) + row[i] = 0; + } /* if */ + scaledv = scalednextv; + thisrow++; + } /* row loop */ + + } /* if */ + /* visible part */ + } + /* 0 bit has ended run */ + return true; +} +/* FullChar */ + + +#undef WORDSIZE +#undef MAXVISWORDS +/*--------------------------------------------------------------------*/ +static void +DisplayChars () +{ + /* Display all characters on a font by font basis. How characters will be + represented depends on the current displaymode (which the user can change, + while the window is being updated, by typing the Terse/Box/Full commands). + Fonts will be displayed in order of ascending totalchars (due to SortFonts). + Characters in a font will be displayed in a top-down, left-right manner + because of the way DVIReader builds a charlist. + */ + + char keyhit; /* check for abort or mode change */ + + for (thisfontinfo = fontlist; + thisfontinfo != unusedfont; + thisfontinfo = thisfontinfo->nextfont) + { + /* SortFont makes sure we only consider used fonts */ + + fontopen = false; /* might be set in FullChar */ + + /* Some VDUs may be able to simulate the given font. + To help the VDU select appropriately sized characters, we need to + pass the scaledsize of the font (converted to unscaled paper pixels), + the overall mag, and the current h/vscalefactors. + */ + + LoadFont (thisfontinfo->fontspec, + XPixelRound (thisfontinfo->scaledsize), + mag / 1000.0, + hscalefactor, + vscalefactor); + + /* display chars in chartable */ + + for (thischarinfo = thisfontinfo->charlist; + thischarinfo != (charinfo *) NULL; + thischarinfo = thischarinfo->nextchar) + { + for (thischar = 0; thischar < thischarinfo->charcount; thischar++) + { + if (thisfontinfo->fontexists) + { + if (displaymode & fullmode) + { + if (thisfontinfo->pkfont) + FullChar (); + else + BoxChar (); + } + if (displaymode & tersemode) + { + TerseChar (); + } + if (displaymode & boxmode) + { + BoxChar (); + } + } + else + { /* font is missing! */ + if (displaymode & (fullmode | tersemode)) + { + TerseChar (); + } + if (displaymode & boxmode) + { + BoxChar (); + } + } + + /* check for abort or mode change */ + if (BusyRead (&keyhit)) + { + char STR1[2]; + keyhit = TOUPPER (keyhit); + sprintf (STR1, "%c", keyhit); + + if (!strcmp (STR1, Terse)) + { + displaymode ^= tersemode; /* toggle terse mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else if (!strcmp (STR1, Box)) + { + displaymode ^= boxmode; /* toggle box mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else if (!strcmp (STR1, Full)) + { + displaymode ^= fullmode; /* toggle full mode */ + StartText (); + UpdateDVIStatusLine (); + StartGraphics (); + } + else if (keyhit == CR) + { + if (fontopen) + CloseFontFile (); + /* no need to set useraborted; DisplayRules done first */ + return; + + } /* if */ + } /* if */ + } /* inner (for) loop */ + } /* middle (for) loop */ + if (fontopen) + CloseFontFile (); + } /* outer (for) loop */ +} +/* DisplayChars */ + +/*--------------------------------------------------------------------*/ +static void +PaperMessage (double precision) +{ + /* Called by CheckPageEdges to remind user of the paper size. */ + + WriteUnits (); + MesgString ("! (Paper "); + WriteXDim (precision, paperwd); + MesgString (" x "); + WriteYDim (precision, paperht); + MesgChar (')'); + ClearMessageLine (); + WaitForReturn (); +} + +/* PaperMessage */ + +/*--------------------------------------------------------------------*/ + +static void +CheckPageEdges () +{ + /* One or more page edges do not fall within the paper edges. + This routine is called after the page & paper have been displayed so + user can see how bad the problem is. + */ + + double precision = 1.0e-2; + + if (minhp < paperleft) + { + ClearMessageLine (); + MesgString ("Page past paper's left edge by "); + WriteXDim (precision, paperleft - minhp); + PaperMessage (precision); + } + if (maxhp > paperright) + { + ClearMessageLine (); + MesgString ("Page past paper's right edge by "); + WriteXDim (precision, maxhp - paperright); + PaperMessage (precision); + } + if (minvp < papertop) + { + ClearMessageLine (); + MesgString ("Page past paper's top edge by "); + WriteYDim (precision, papertop - minvp); + PaperMessage (precision); + } + if (maxvp > paperbottom) + { + ClearMessageLine (); + MesgString ("Page past paper's bottom edge by "); + WriteYDim (precision, maxvp - paperbottom); + PaperMessage (precision); + } +} +/* CheckPageEdges */ +/*--------------------------------------------------------------------*/ +static void +DisplayPage () +{ + /* Display page in window region based on window location and size, + and displaymode. This routine is only called if paintwindow is TRUE + after all commands have been processed. + */ + + if (screenjustcleared) + { + /* avoid doing it again */ + + if (paintDVIStatus) + UpdateDVIStatusLine (); + + if (paintWindowStatus) + UpdateWindowStatusLine (); + } + else + { + ClearScreen (); + screenjustcleared = true; + UpdateDVIStatusLine (); + UpdateWindowStatusLine (); + } + + StartGraphics (); + DisplayPaperEdges (); + StartText (); + + if (pageempty) + { + ClearMessageLine (); + MesgString ("Page is empty."); + } + else if (outsidepage) + { + if (pageoffpaper) + CheckPageEdges (); + + ClearMessageLine (); + MesgString ("Window is "); + + if (windowtop > maxvp) + { + MesgString ("below "); + if (windowleft > maxhp || windowleft <= minhp - scaledwd) + MesgString ("and "); + } + else if (windowtop <= minvp - scaledht) + { + MesgString ("above "); + if (windowleft > maxhp || windowleft <= minhp - scaledwd) + MesgString ("and "); + } + if (windowleft > maxhp) + MesgString ("to the right of "); + else if (windowleft <= minhp - scaledwd) + MesgString ("to the left of "); + + MesgString ("page."); + } + else + { + /* Page is not empty and part or all of it is visible. */ + StartGraphics (); + + useraborted = false; + DisplayRules (); + if (!useraborted) + DisplaySpecials (); + if (!useraborted) + DisplayChars (); + + StartText (); + + if (pageoffpaper) + CheckPageEdges (); /* May write messages */ + + if (allpagevisible) + { + ClearMessageLine (); + MesgString ("Entire page is visible. "); + PadMesg (); + } + } + + MesgFlush (); +} +/* DisplayPage */ +/*--------------------------------------------------------------------*/ +void +ProcessCommandLine (String commstring) +{ + /* Parse commstring, and call the appropriate command handler + for each command in commstring. + */ + int n; /* returned by GetInteger call */ + + ClearMessageLine (); /* erase message line at this stage */ + commlen = strlen (commstring); + /* ignore any trailing spaces */ + while (commlen > 0 && commstring[commlen - 1] == ' ') + commlen--; + /* terminate commstring properly */ + commstring[commlen] = '\0'; + + /* initialize flags for multiple command processing */ + badcommand = false; + paintWindowStatus = false; + paintDVIStatus = false; + paintwindow = false; + screenjustcleared = false; + pageoffpaper = false; + + commpos = 0; + while (commpos < commlen && !badcommand) + { + /* next command is defined by the next non-space character in commstring */ + while (commstring[commpos] == ' ') + commpos++; /* ignore any leading spaces */ + + command = TOUPPER (commstring[commpos]); + switch (command) + { + case 'W': /* Window move */ + commpos++; + WindowMove (); + if (!badcommand) + paintWindowStatus = true; + break; + + case 'U': /* move Up */ + case 'D': /* move Down */ + commpos++; + WindowUpDown (); + paintWindowStatus = true; + break; + + case 'L': /* move Left */ + case 'R': /* move Right */ + commpos++; + WindowLeftRight (); + paintWindowStatus = true; + break; + + case 'H': /* Horizontal dimension */ + commpos++; + SetWindowWidth (); + NewLocation (windowleft, windowtop); + paintWindowStatus = true; + break; + + case 'V': /* Vertical dimension */ + commpos++; + SetWindowHeight (); + NewLocation (windowleft, windowtop); + paintWindowStatus = true; + break; + + case 'A': /* toggle Autoview on or off */ + commpos++; + SetAutoView (); + if (!badcommand) + paintDVIStatus = true; + break; + + case 'Z': /* Zoom in or out */ + commpos++; + ZoomWindow (); + if (!badcommand) + NewLocation (windowleft, windowtop); + if (!badcommand) + paintWindowStatus = true; + break; + + case 'N': /* Next page */ + commpos++; + if (NextPageFound (true)) /* ascending */ + ProcessPage (); + break; + + case 'P': /* Previous page */ + commpos++; + if (NextPageFound (false)) /* descending */ + ProcessPage (); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* go to page with this number, if number is valid */ + + if (GetInteger (commstring, commlen, &commpos, &n)) + { + /* must be true, and commpos now after last digit */ + if (DVIPageFound (n)) + ProcessPage (); + } + else + { /* safety net */ + ClearMessageLine (); + MesgString ("Expected an Integer! Type ? for help."); + BadCommandMessage (); + } + break; + + case '[': /* go to page described by count0...count9 */ + if (TeXPageFound ()) + /* commpos incremented in ParseTeXpage */ + ProcessPage (); + break; + + case 'T': /* Terse display */ + commpos++; + displaymode ^= tersemode; /* toggle terse mode */ + paintDVIStatus = true; + if (currDVIpage != 0) + paintwindow = true; + break; + + case 'B': /* Box display */ + commpos++; + displaymode ^= boxmode; /* toggle box mode */ + paintDVIStatus = true; + if (currDVIpage != 0) + paintwindow = true; + break; + + case 'F': /* Full display */ + commpos++; + displaymode ^= fullmode; /* toggle full mode */ + paintDVIStatus = true; + if (currDVIpage != 0) + paintwindow = true; + break; + + case 'C': /* Change units */ + commpos++; + ChangeUnits (); + if (!badcommand) + paintWindowStatus = true; + break; + + case '?': /* command help */ + commpos++; + ShowCmdHelp (); + break; + + case 'S': /* file-and-page Statistics */ + commpos++; + ShowStatistics (); + ClearScreen (); + screenjustcleared = true; + paintDVIStatus = true; + paintWindowStatus = true; + if (currDVIpage != 0) + paintwindow = true; + break; + + case '\014': /* ctrl-L : refresh screen */ + commpos++; + DisplayPage (); /* unconditionally, and immediately on interpretation */ + break; + + case '\021': /* ctrl-Q : ignore flow-control continue */ + case '\023': /* ctrl-S : ignore flow-control suspend */ + /* do nothing, except advance character pointer */ + commpos++; + break; + + case 'Q': /* Quit */ + return; + + break; + + default: /* unknown command */ + commpos++; + ClearMessageLine (); + MesgString ("Unknown command! Type ? for help."); + BadCommandMessage (); + break; + } /* command */ + } /* while */ + + if (paintwindow) /* only update window after processing all commands */ + DisplayPage (); + else if (!vdu_clears_lines && (paintDVIStatus || paintWindowStatus)) + DisplayPage (); + else + { + if (paintDVIStatus) + UpdateDVIStatusLine (); + if (paintWindowStatus) + UpdateWindowStatusLine (); + } +} +/* ProcessCommandLine */ + +/*--------------------------------------------------------------------*/ + +static void +NextCommandLine () +{ + /* Prompt user for next command line, and process response */ + + ClearTextLine (commandl); + MoveToTextLine (commandl); + + MesgString (commprompt); + MesgFlush (); + + ReadString (commstring); /* read new command line */ + + ProcessCommandLine (commstring); +} + +/* NextCommandLine */ + +/*--------------------------------------------------------------------*/ +static void +Finish () +{ + /* close DVI file, reset VDU and restore terminal */ + + CloseDVIFile (); + + /*!!! ClearScreen(); */ + screenjustcleared = true; + MoveToTextLine (1); + MesgLine (); + /*!!! ResetVDU(); */ +} + +/* Finish */ + +/*--------------------------------------------------------------------*/ +void * +Malloc (size_t n) +{ + void *MallocTemp; + MallocTemp = malloc (n); + if (MallocTemp) + { + return MallocTemp; + } + else + { + StartText (); + ResetVDU (); /* do before message since it might erase screen! */ + FATAL ("Out of memory."); + return NULL; + } +} +/*--------------------------------------------------------------------*/ + +int +main (int argc, char **argv) +{ + char STR1[2]; + + kpse_set_progname (argv[0]); + kpse_init_prog ("DVGT", DEF_XRES, DEF_MFMODE, DEF_DUMMY); + kpse_set_program_enabled (kpse_pk_format, true, kpse_src_compile); + + save_init_tty (); /* save initial terminal settings, early */ + textlinewidth = 80; /* for the initial screen type */ + if (!InitOptions (argc, argv)) + { /* initialize DVIname and command options */ + /* Print the precompiled information */ + PrintText (immed_help_strings); + return 1; + } + InitScreenIO (); /* SYSDEP: sets cbreak on & echo off */ + + InitDVIReader (); + InitFontReader (); + OpenDVIFile (DVIname); /* and read DVImag etc. */ + if (mag == 0) /* use DVImag */ + mag = DVImag; + SetConversionFactors (xres, yres, mag / 1000.0); /* for DVIReader */ + InitVDU (); /* init windowwd/ht etc. */ + InitWinVars (); + StartText (); + ClearScreen (); + screenjustcleared = true; + UpdateDVIStatusLine (); + UpdateWindowStatusLine (); + MoveToTextLine (messagel); + MesgString (DVGT_VERSION); + MesgLine (); + do + { + NextCommandLine (); /* parse and execute command(s) */ + } + while (strcmp ((sprintf (STR1, "%c", command), STR1), Quit)); + Finish (); + return 0; /* OK */ +} +/* main() program of DVItoVDU */ + +/* end dvitovdu.c */ diff --git a/dviware/dvgtk/dvgt.h b/dviware/dvgtk/dvgt.h new file mode 100644 index 0000000000..283ea7620d --- /dev/null +++ b/dviware/dvgtk/dvgt.h @@ -0,0 +1,110 @@ +/* dvgt.h - common header file for dvgtk + $Id: dvgt.h,v 0.2 1997/03/28 03:16:09 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __DVGT_H__ +#define __DVGT_H__ + +#include "c-auto.h" + +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include /* debug */ +#include /* program_invocation_name */ +#include /* DIR_SEP_STRING */ +#include /* boolean */ +#include /* FATAL */ + +#define DVGT_VERSION "This is dvgtk 0.2." + +/* Support for no prototypes */ +#ifndef PARAMS +# if PROTOTYPES +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + +/* Word must be 32 bits. Word is used in the PK bitmap operations. + For an architecture with 32-bit ints, Word can be int. + */ + +typedef int Word; /* SYSDEP: ASSUMES exactly 32 bits in int. */ +typedef void (*VFP) (); +typedef void *Anyptr; + +/* Memory allocation */ +void *Malloc PARAMS ((size_t)); +#define Free(p, T) (free((Anyptr) (p)), (p) = (T *) NULL) + +/* Global declarations */ +#define maxstring 1024 +typedef char String[maxstring + 1]; /* Allow space for null terminator */ + +/* SYSDEP: cmd_help should have <= maxline chars/line */ +#define maxline 80 + +/* The following variant records are needed because Pyramid Pascal + does not provide type coercion. + Note that we couldn't overlay INTEGER and BITSET because + of the crazy storage scheme used to represent a set of 0..31 + where the bit order within a word is 7..0 15..8 23..16 31..24! + */ +typedef union byte_order + { + int int_; + struct + { +#ifdef WORDS_BIGENDIAN + char _byte3, _byte2, _byte1, _byte0; +#else /* not WORDS_BIGENDIAN */ + char _byte0, _byte1, _byte2, _byte3; +#endif /* WORDS_BIGENDIAN */ + } + _bytes; + } +byte_order; + +#define byte0(lvalue) ((byte_order *)(&lvalue))->_bytes._byte0 +#define byte1(lvalue) ((byte_order *)(&lvalue))->_bytes._byte1 +#define byte2(lvalue) ((byte_order *)(&lvalue))->_bytes._byte2 +#define byte3(lvalue) ((byte_order *)(&lvalue))->_bytes._byte3 + +typedef struct int_or_bptr + { + boolean b; + union + { + int int_; + int *bptr; + } + UU; + } +int_or_bptr; + +typedef struct int_or_mptr + { + boolean b; + union + { + int int_; + Word *mptr; /* bitmap */ + } + UU; + } +int_or_mptr; + +#define bufflen 1024 /* size of buffer for holding DVI/PK bytes */ +typedef unsigned char buffer[bufflen]; + +#endif /* __DVGT_H__ */ diff --git a/dviware/dvgtk/dvgt.man b/dviware/dvgtk/dvgt.man new file mode 100644 index 0000000000..8971200406 --- /dev/null +++ b/dviware/dvgtk/dvgt.man @@ -0,0 +1,82 @@ +.TH DVGT 1 +.\" $Id:$ +.\" Tomasz J. Cholewo +.SH DVGT +dvgt \- DVI file previewer for Tektronix 4010 emulators +.SH SYNOPSIS +dvgt [options] filename.[dvi] +.SH "DESCRIPTION" +dvgt interactively views TeX-generated DVI files on Tektronix 4010 emulators. +.SH OPTIONS +.TP 5 +.BI "\-H " horizontal_offset +(default = 0.0 in) +.TP 5 +.BI "\-V " vertical_offset +(default = 0.0 in) +.TP 5 +.BI "\-d " dummy_pk +.TP 5 +.BI "\-e " dummy_tfm +.TP 5 +.BI "\-k " kpathsea_debug_mode +.TP 5 +.B \-l +set landscape mode, instead of the default portrait mode +.TP 5 +.BI "\-m " magnification +default = DVI file's intrinsic magnification +.TP 5 +.BI "\-r " xres[,yres]] +resolution in dpi +.TP 5 +.BI "\-x " paper_width +.TP 5 +.BI "\-y " paper_height + +.SH EXAMPLES +Start dvgt on file.dvi with A4 paper settings: + + dvgt -x210mm -y297mm file.dvi + +\" .SH ENVIRONMENT +\" envariables this program might care about +\" .SH FILES +\" all files used by the program. typical usage is like this: +\" .br +\" .nf +\" .\" set tabstop to longest possible filename, plus a wee bit +\" .ta \w'/usr/lib/perl/getopts.pl 'u +\" \fI/usr/man\fR default man tree +\" \fI/usr/man/man*/*.*\fR unformatted (nroff source) man pages +.SH "SEE ALSO" +dvips(1), xdvi(1), dvilj(1) +\" .SH NOTES +\" miscellaneous commentary +.SH CAVEATS +This is a beta version. +\" .SH DIAGNOSTICS +\" all the possible error messages the program can print out, and +\" what they mean. +\" .SH BUGS +\" things that are broken or just don't work quite right. +\" .SH RESTRICTIONS +\" bugs you don't plan to fix :-) +.SH AUTHORS +Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo and +many more. +.SH HISTORY +Andrew Trevorrow wrote the original DVItoVDU in Modula-2. + +The initial C code for this version of DVItoVDU was copied from Ian +Dall's site, ftp://augean.oz.au/pub/misc/dv.tar.Z. Ian had, as his +source code seems to indicate, automatically translated it from Modula. + +Geoffrey Tobin added a lot of new functionality: font searching and +substitution, option handling, bitmap allocation, help files, and much +more. + +Tomasz J. Cholewo modified dvgt to use kpathsea library. + +A thorough history of the various versions of "dvitovdu", "dvi2vdu", +and "dv" in the world is much more complex. diff --git a/dviware/dvgtk/dvireader.c b/dviware/dvgtk/dvireader.c new file mode 100644 index 0000000000..8e59cb79a8 --- /dev/null +++ b/dviware/dvgtk/dvireader.c @@ -0,0 +1,1885 @@ +/* dvireader.c - functions for reading DVI files + $Id: dvireader.c,v 0.2 1997/03/28 03:16:30 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "dvireader.h" +#include "screenio.h" +#include "fontreader.h" +#include "options.h" + +/* Variables Exported, via "dvireader.h". */ +int DVImag; +int totalpages, totalfonts, totalrules; +int currDVIpage; +TeXcounters currTeXpage; +ruleinfo *rulelist, *ruletail; +fontinfo *fontlist, *currfont; +specialinfo *speciallist; +boolean pageempty; +int minhp, minvp, maxhp, maxvp; + +time_t dvi_time; /* last mod. time for dvi file */ +/*---------------------------------------------------------------------- + DECLARATIONS FOR INTERPRETING A DVI PAGE + + The commands between the bop and eop bytes for a particular page need to be + translated (based on the method used by DVITYPE) before we can determine the + the position and shape of all rules on that page, as well as the position + of all characters and which fonts they belong to. +*/ + +/* Use symbolic names for the opcodes of DVI commands: */ + +#define setchar0 0 + /* setchar1..setchar127 = 1..127 */ +#define set1 128 + /* set2,set3,set4 = 129,130,131 */ +#define setrule 132 +#define put1 133 + /* put2,put3,put4 = 134,135,136 */ +#define putrule 137 +#define nop 138 +#define bop 139 +#define eop 140 +#define push 141 +#define pop 142 +#define right1 143 +#define w0 147 +#define x0 152 +#define down1 157 +#define y0_ 161 +#define z0 166 +#define right2 144 +#define w1 148 +#define x1 153 +#define down2 158 +#define y1_ 162 +#define z1 167 +#define right3 145 +#define w2 149 +#define x2 154 +#define down3 159 +#define y2 163 +#define z2 168 +#define right4 146 +#define w3 150 +#define x3 155 +#define down4 160 +#define y3 164 +#define z3 169 +#define w4 151 +#define x4 156 +#define y4 165 +#define z4 170 +#define fntnum0 171 + /* fntnum1..fntnum63 = 172..234 */ +#define fnt1 235 + /* fnt2,fnt3,fnt4 = 236,237,238 */ +#define xxx1 239 + /* xxx2,xxx3,xxx4 = 240,241,242 */ +#define fntdef1 243 + /* fntdef2,fntdef3,fntdef4 = 244,245,246 */ +#define pre 247 +#define post 248 +#define postpost 249 +/* undefined commands = 250..255 */ + +#define maxstacksize 100 /* maximum stack size for state values */ + +/* According to the DVI Driver Standard, Level 0, version 0.5, + section 2.6.2, max_drift should depend on the output device: + + 2 if a "device unit" <= 0.005 in (0.127 mm), + 1 if a "device unit" > 0.005 in (0.127 mm) + but <= 0.01 in (0.254 mm), + 0 if a "device unit" > 0.01 in (0.254 mm). + + So, the value given here for max_drift implies a device with + a resolution of at least 200 dpi. + + Note: max_drift is a number of pixels. + */ + +#define max_drift 2 /* prevent hh & vv from drifting too far */ + + +/*---------------------------------------------------------------------- + DECLARATIONS FOR ACCESSING BYTES IN A DVI FILE + + A DVI file is a stream of 8-bit bytes. Once opened, we can access any byte + by setting DVIoffset to the required position and then calling +GetDVIByte. +*/ + +static int DVIfile; /* DVI file descriptor */ +static int DVIoffset; /* current byte offset in DVIfile */ +static int currDVIbuff; /* starting byte offset in buffer */ +static buffer DVIbuffer; /* input buffer */ +static int postpostid; /* offset of postpost's id byte */ + +/*---------------------------------------------------------------------- + DECLARATIONS FOR GETTING TO A DVI PAGE + + The user can select a particular page by specifying a DVI page + number (from 1 to totalpages), or a TeX page number (based on the + values of \count0,\count1,...,\count9), or simply requesting the next page + in the DVI file (which depends on whether we are ascending or not). + We will often need to follow the DVI backpointers to locate the bop byte + of a selected page. +*/ + +static int curreop; /* position of eop byte of current page */ +static int currbop; /* position of bop byte of current page */ +static int lastbop; /* position of last bop byte */ +static int prevbop; /* position of bop byte of previous page; + note that prevbop of first page = -1 */ + +static unsigned char DVIcommand; /* holds next DVI command */ + +static int maxstack; /* max pushes over pops in DVI file */ +static int num = 0; /* DVI numerator */ +static int den = 0; /* DVI denominator */ +static double xconv = 0.0; /* converts DVI units to X pixels */ +static double yconv = 0.0; /* converts DVI units to Y pixels */ +static int h, v; /* current pos on page in DVI units */ +static int w, x; /* horizontal increments in DVI units */ +static int y, z; /* vertical increments in DVI units */ +static int hh, vv; /* h and v in pixels (approx) */ +static int hhh, vvv; /* h and v rounded to nearest pixel */ +static int hstack[maxstacksize], vstack[maxstacksize]; + /* push down stacks for state values */ +static int wstack[maxstacksize], xstack[maxstacksize], ystack[maxstacksize], + zstack[maxstacksize], hhstack[maxstacksize], vvstack[maxstacksize]; +static int stackpos; +/* stacks empty when stackpos = 0, i.e., top of stacks = stackpos - 1 */ +static int fontspace; /* used in DoRight and DoDown */ + + +/*--------------------------------------------------------------------*/ + +/* Here are the functions used to get byte/s from DVIfile. + They are essentially the same as those used in DVITYPE. + */ + +static int +GetDVIByte () +{ + /* Returns the value (unsigned) of the byte at DVIoffset and + advances DVIoffset for the next GetDVIByte. + */ + + int Result, buffstart, result; + + /* bufflen is a #define-d constant in "dvgt.h" */ + + buffstart = DVIoffset / bufflen * bufflen; /* 0, bufflen, 2*bufflen... */ + if (buffstart != currDVIbuff) + { + currDVIbuff = buffstart; + result = lseek (DVIfile, buffstart, SEEK_SET); + + if (result != buffstart) + { + FATAL ("lseek failed in GetDVIByte!"); + } + result = read (DVIfile, DVIbuffer, bufflen); + + if (result == -1) + { + FATAL ("read failed in GetDVIByte!"); + } + } + Result = DVIbuffer[DVIoffset - buffstart]; + DVIoffset++; + return Result; +} +/* GetDVIByte */ + +/*--------------------------------------------------------------------*/ + +static int +SignedDVIByte () +{ + /* the next byte, signed */ + int b; + + b = GetDVIByte (); + if (b < 128) + return b; + else + return (b - 256); +} +/* SignedDVIByte */ + +/*--------------------------------------------------------------------*/ + +static int +GetTwoDVIBytes () +{ + /* the next 2 bytes, unsigned */ + int a, b; + + a = GetDVIByte (); + b = GetDVIByte (); + return (a * 256 + b); +} +/* GetTwoDVIBytes */ + +/*--------------------------------------------------------------------*/ + +static int +SignedDVIPair () +{ + /* the next 2 bytes, signed */ + int a, b; + + a = GetDVIByte (); + b = GetDVIByte (); + if (a < 128) + return (a * 256 + b); + else + return ((a - 256) * 256 + b); +} +/* SignedDVIPair */ + +/*--------------------------------------------------------------------*/ + +static int +GetThreeDVIBytes () +{ + /* the next 3 bytes, unsigned */ + int a, b, c; + + a = GetDVIByte (); + b = GetDVIByte (); + c = GetDVIByte (); + return ((a * 256 + b) * 256 + c); +} +/* GetThreeDVIBytes */ + +/*--------------------------------------------------------------------*/ + +static int +SignedDVITrio () +{ + /* the next 3 bytes, signed */ + int a, b, c; + + a = GetDVIByte (); + b = GetDVIByte (); + c = GetDVIByte (); + if (a < 128) + return ((a * 256 + b) * 256 + c); + else + return (((a - 256) * 256 + b) * 256 + c); +} +/* SignedDVIOqTrio */ + + +/*--------------------------------------------------------------------*/ + +static int +SignedDVIQuad () +{ + /* the next 4 bytes, signed */ + int w; + byte3 (w) = GetDVIByte (); + byte2 (w) = GetDVIByte (); + byte1 (w) = GetDVIByte (); + byte0 (w) = GetDVIByte (); + return (w); +} +/* SignedDVIQuad */ + +/*--------------------------------------------------------------------*/ + +static void +ProcessPostamble () +{ + /* Having successfully opened the DVI file, we find the postamble + and initialize these global variables: + lastbop, num, den, DVImag, maxstack, totalpages. + The font definitions are read by ProcessFontDefs. + */ + + int postamblepos, postamble, pagehtplusdp, pagewidth; + + DVIoffset = postpostid - 4; + postamblepos = SignedDVIQuad (); /* get post_post's postamble ptr */ + DVIoffset = postamblepos; + postamble = GetDVIByte (); + lastbop = SignedDVIQuad (); + num = SignedDVIQuad (); + den = SignedDVIQuad (); + DVImag = SignedDVIQuad (); + pagehtplusdp = SignedDVIQuad (); + pagewidth = SignedDVIQuad (); + maxstack = SignedDVIPair (); + totalpages = SignedDVIPair (); + if (maxstack <= maxstacksize) + return; + + FATAL ("Stack capacity exceeded!"); + /* now we don't need to test for stack overflow in DoPush */ +} +/* ProcessPostamble */ + +/*--------------------------------------------------------------------*/ + +static void +ProcessFontDefs () +{ + /* Read the fntdef commands in the postamble (fntdef commands in the DVI + pages will be skipped) and store the information in the font list. + (Note that complete fontspecs are NOT built here because DVIReader does not + want to know about the format or naming conventions of font files.) + Since ProcessPostamble ended by reading the totalpages parameter, the + next GetDVIByte should return nop or first fntdef. + */ + + int f = 0, c, s, d, a, l; /* hold fntdef parameters */ + int i; + char ch; /* for getting farea and fname */ + String farea, fname; /* a and l bytes long respectively */ + + totalfonts = 0; /* number of nodes in font list */ + fontlist = (fontinfo *) NULL; + do + { + DVIcommand = GetDVIByte (); + if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3) + { + switch (DVIcommand - fntdef1) + { + case 0: + f = GetDVIByte (); + break; + + case 1: + f = GetTwoDVIBytes (); + break; + + case 2: + f = GetThreeDVIBytes (); + break; + + case 3: + f = SignedDVIQuad (); + break; + } + c = SignedDVIQuad (); /* checksum; ignore it */ + s = SignedDVIQuad (); /* scaled size */ + d = SignedDVIQuad (); /* design size */ + a = GetDVIByte (); /* length of font area */ + l = GetDVIByte (); /* length of font name */ + + /* read and store font area */ + for (i = 0; i < a; i++) + { + ch = GetDVIByte (); + if (i < maxfontspec) + farea[i] = ch; + } + farea[i <= maxfontspec ? i : maxfontspec] = '\0'; + + /* read and store font name */ + for (i = 0; i < l; i++) + { + ch = GetDVIByte (); + if (i < maxfontspec) + fname[i] = ch; + } + + fname[i <= maxfontspec ? i : maxfontspec] = '\0'; + + currfont = (fontinfo *) Malloc (sizeof (fontinfo)); + currfont->fontused = false; + currfont->fontnum = f; + currfont->scaledsize = s; + currfont->designsize = d; + strncpy (currfont->fontarea, farea, maxstring); + currfont->fontarea[maxstring] = '\0'; /* to be careful */ + currfont->fontarealen = a; + strncpy (currfont->fontname, fname, maxstring); + currfont->fontname[maxstring] = '\0'; /* to be careful */ + currfont->fontnamelen = l; + currfont->fontspec[0] = '\0'; + currfont->fontspeclen = 0; /* fontspec is built in FontReader */ + currfont->fontexists = false; /* becomes TRUE if fontspec can be opened */ + currfont->totalchars = 0; + + /* first node allocated in DoFont */ + currfont->charlist = (charinfo *) NULL; + + /* nodes are added to tail of char list */ + currfont->chartail = (charinfo *) NULL; + + /* allocated once per font; see DoFont */ + currfont->pixelptr = (_REC_pixeltable *) NULL; + + currfont->nextfont = fontlist; + fontlist = currfont; /* add new font to head of list */ + totalfonts++; + } + else if (DVIcommand != nop) + { + if (DVIcommand != postpost) + FATAL1 ("Unexpected DVI command in postamble = %d", DVIcommand); + /* we have reached end of postamble */ + } + } + while (DVIcommand != postpost); + + /* nop commands can occur between DVI commands */ +} +/* ProcessFontDefs */ + +/*--------------------------------------------------------------------*/ + +void +OpenDVIFile (char *name) +{ + /* If the given file can be opened and is a valid TeX82 DVI file then + the following global variables are initialized: + + DVImag := magnification value stored in DVI file (TeX's \mag) + totalpages := total number of pages in DVI file + currDVIpage := 0 (and remains so until a page is selected) + currTeXpage := ten 0s (ditto) + totalfonts := total number of fonts in DVI file (= nodes in font list) + fontlist-> (nodes are added to head of list) + fontused := FALSE + fontnum := internal DVI font number + scaledsize := scaled size of font (in DVI units) + designsize := design size of font (in DVI units) + fontarea := a string of min (fontarealen, maxfontspec) characters + fontname := a string of min (fontnamelen, maxfontspec) characters + fontspec := a null string (fontspeclen := 0) + fontexists := FALSE + totalchars := 0 + charlist := NIL + chartail := NIL + pixelptr := NIL + nextfont := next node in font list (if not NIL) + */ + +#if 0 + struct stat fstatbuf; +#endif + + currDVIbuff = -1; /* impossible value for first GetDVIByte */ + DVIfile = open (name, O_RDONLY, 0); + if (DVIfile >= 0) + { + int i; +#if 0 + fstat (DVIfile, &fstatbuf); + if (S_ISDIR(fstatbuf.st_mode)) + FATAL1 ("`%s' is a directory\n", name); + dvi_time = fstatbuf.st_mtime; +#endif + + /* get offset of last DVI byte */ + DVIoffset = lseek (DVIfile, 0, SEEK_END); + if (DVIoffset == -1) + FATAL ("Failed to find end of file!"); + if (DVIoffset == 0) + FATAL ("DVI file is empty!"); + DVIoffset--; + + /* In the following, DVIoffset == 1 signifies the start of the file. */ + + /* skip any NULs */ + while (GetDVIByte () == 0 && DVIoffset != 1) + { + DVIoffset -= 2; /* GetDVIByte increments */ + } + DVIoffset--; + + /* skip 223s */ + while (GetDVIByte () == 223 && DVIoffset != 1) + { + DVIoffset -= 2; /* GetDVIByte increments */ + } + + DVIoffset--; + postpostid = DVIoffset; /* remember offset of id byte */ + if (GetDVIByte () != 2) + { + FATAL ("Not a valid DVI file!"); + /*NOTREACHED */ + return; + } + ProcessPostamble (); /* get DVImag, totalpages, etc */ + ProcessFontDefs (); /* build and initialize font list */ + currDVIpage = 0; /* we haven't processed a page yet */ + for (i = 0; i <= 9; i++) + currTeXpage[i] = 0; + + return; + } + else + FATAL1 ("Couldn't open DVI file: `%s'\n", name); +} +/* OpenDVIFile */ +/*--------------------------------------------------------------------*/ +#if 0 +boolean +check_dvi_file (char *DVIname) +{ + struct stat statbuf; + if (DVIname == NULL || stat (DVIname, &statbuf) != 0 || statbuf.st_mtime != dvi_time) { + if (DVIname) { + Fclose(DVIname); + DVIname = NULL; + if (list_fonts) Putchar('\n'); + + } + } +} +#endif +/*--------------------------------------------------------------------*/ +static void +SkipFntdef (int which) +{ + /* Read past a fntdef command without interpreting it. */ + + int dummy, a, l, i; + + switch (which) + { /* which = DVIcommand - fntdef1 */ + case 0: + dummy = GetDVIByte (); + break; + case 1: + dummy = GetTwoDVIBytes (); + break; + case 2: + dummy = GetThreeDVIBytes (); + break; + case 3: + dummy = SignedDVIQuad (); + break; + } + dummy = SignedDVIQuad (); + dummy = SignedDVIQuad (); + dummy = SignedDVIQuad (); + + a = GetDVIByte (); /* length of directory */ + l = GetDVIByte (); /* length of font name */ + for (i = 1; i <= l + a; i++) + dummy = GetDVIByte (); +} +/* SkipFntdef */ + +/*--------------------------------------------------------------------*/ + +static void +ReadFirstBop () +{ + + /* Read first bop by skipping past preamble; update currbop and currDVIpage. */ + int k, i, dummy; + + DVIoffset = 14; /* position of preamble's k parameter */ + k = GetDVIByte (); /* length of x parameter */ + for (i = 1; i <= k; i++) /* skip preamble comment */ + dummy = GetDVIByte (); + do + { /* skip any nops and fntdefs */ + DVIcommand = GetDVIByte (); + if (DVIcommand != nop && DVIcommand != bop) + { + if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3) + SkipFntdef (DVIcommand - fntdef1); + else + FATAL1 ("Unexpected DVI command before first bop = %d.", + DVIcommand); + } + /* do nothing */ + } + while (DVIcommand != bop); + currbop = DVIoffset - 1; /* position in DVI file of first bop */ + currDVIpage = 1; +} +/* ReadFirstBop */ + +/*--------------------------------------------------------------------*/ + +static void +ReadNextBop () +{ + /* We are currently positioned after an eop byte which we know is not the + last. This routine positions us after the next bop byte and updates + currbop and currDVIpage. + */ + + /* skip any nops and fntdefs */ + do + { + DVIcommand = GetDVIByte (); + if (DVIcommand != nop && DVIcommand != bop) + { + if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3) + SkipFntdef (DVIcommand - fntdef1); + else + FATAL1 ("Unexpected DVI command between eop and bop = %d.", + DVIcommand); + } + /* do nothing */ + } + while (DVIcommand != bop); + currbop = DVIoffset - 1; /* position in DVI file of this bop */ + currDVIpage++; +} +/* ReadNextBop */ + +/*--------------------------------------------------------------------*/ + +static void +ReadBopParameters () +{ + + /* We should now be positioned after the bop of desired page, so read + the 10 TeX counters and update currTeXpage and prevbop. + At the end of this routine we will be at the byte after currbop's parameters + and ready to InterpretPage. + */ + int i; + + for (i = 0; i <= 9; i++) + currTeXpage[i] = SignedDVIQuad (); + prevbop = SignedDVIQuad (); /* position of previous bop in DVI file */ +} +/* ReadBopParameters */ + +/*--------------------------------------------------------------------*/ + +void +MoveToNextPage (boolean ascending) +{ + /* MoveToNextPage will select the next page, depending on the current page + and the specified direction. If the value of currDVIpage is 0 (set in + OpenDVIFile), then MoveToNextPage will select the first page if ascending is + TRUE and the last page if ascending is FALSE. If currDVIpage is > 0 then + MoveToNextPage will select currDVIpage+1 if ascending (unless currDVIpage = + totalpages, in which case it does nothing), or currDVIpage-1 if descending + (unless currDVIpage = 0). + + Before calling InterpretPage, DVItoVDU must position DVIReader to the + desired page by calling one of the MoveTo... routines. + The global variables updated if a page is located by any MoveTo... call are: + currDVIpage := the current DVI page (1..totalpages) + currTeXpage := the ten TeX counter values stored with this page + Note that currDVIpage is initially 0 until one of these routines succeeds. + */ + + /* keep within limits of document */ + if ((currDVIpage != 1 && !ascending) + || (currDVIpage != totalpages && ascending)) + { + if (currDVIpage == 0) + { /* special value */ + /* we haven't processed a page yet */ + if (ascending) /* get first page */ + ReadFirstBop (); + else + { /* get last page */ + currbop = lastbop; + DVIoffset = currbop + 1; + currDVIpage = totalpages; + } + } + else + { + if (ascending) + { + /* currently positioned after eop of currDVIpage, so get next bop */ + ReadNextBop (); + } + else + { + /* move to bop pointed to by currbop's backpointer */ + currbop = prevbop; + DVIoffset = currbop + 1; /* move to byte after previous bop */ + currDVIpage--; + } + } + ReadBopParameters (); /* update currTeXpage and prevbop */ + } +} +/* MoveToNextPage */ + +/*--------------------------------------------------------------------*/ + +void +MoveToDVIPage (int n) +{ + /* Move to nth DVI page; n should be in 1..totalpages. */ + + if (n < 1 || n > totalpages) /* do nothing */ + goto _L999; + + if (n == 1) + { + /* Note that this test must come before next test so that we avoid any + problems when currDVIpage initially = 0. */ + ReadFirstBop (); + } + else if (n == currDVIpage + 1) + { + ReadNextBop (); + } + else + { + if (n < currDVIpage) + { + currbop = prevbop; /* start searching backwards from previous page */ + currDVIpage--; + } + else if (n > currDVIpage) + { + currbop = lastbop; /* start searching backwards from last page */ + currDVIpage = totalpages; + } + /* if n = currDVIpage we'll just move back to currbop */ + /* n is now <= currDVIpage so search by following backpointers */ + while (true) + { + if (n == currDVIpage) + { + DVIoffset = currbop + 1; /* move to byte after currbop */ + break; /* escape from "infinite" loop */ + } + DVIoffset = currbop + 41; /* move to location of backpointer */ + currbop = SignedDVIQuad (); /* get location of previous page */ + currDVIpage--; + } /* while */ + } /* if */ + ReadBopParameters (); /* update currTeXpage and prevbop */ +_L999:; +} +/* MoveToDVIPage */ + +/*--------------------------------------------------------------------*/ + +static boolean +CurrMatchesNew (TeXpageinfo * newTeXpage) +{ + /* Return TRUE iff currTeXpage matches newTeXpage. */ + + boolean Result; + int i, FORLIM; + + Result = true; + FORLIM = newTeXpage->lastvalue; + for (i = 0; i <= FORLIM; i++) + { + if (newTeXpage->present[i]) + { + if (newTeXpage->value[i] != currTeXpage[i]) + Result = false; + } + } + return Result; +} +/* CurrMatchesNew */ + +/*--------------------------------------------------------------------*/ + +boolean +MoveToTeXPage (TeXpageinfo * newTeXpage) +{ + /* MoveToTeXPage will search for the lowest DVI page matching the given + TeX page specification. + + (TeX stores the values of \count0,\count1, ..., \count9 with every DVI + page. Plain TeX uses \count0 to control page numbering.) + + newTeXpage is a VAR parameter only for efficiency; it won't be changed. + The value array stores the requested counter values, the present array + indicates which counters are relevant and lastvalue indicates + the position (0..9) of the last relevant counter. + + DVItoVDU converts a more friendly representation + of a TeX page request into the TeXpageinfo format. For example, + [2..5] would be converted to: and [] would be converted to: + value = [2,?,5,?,?,?,?,?,?,?] value = [?,?,?,?,?,?,?,?,?,?] + present = [T,F,T,?,?,?,?,?,?,?] present = [F,?,?,?,?,?,?,?,?,?] + lastvalue = 2 lastvalue = 0 + MoveToTeXPage returns TRUE iff the requested TeX page is located. + */ + + boolean Result; + + int savecurrbop = 0, savecurrDVIpage, nextbop, i; + boolean atleastone; + + /* save away current page and DVI position */ + savecurrDVIpage = currDVIpage; + if (currDVIpage != 0) /* only if we've processed a page */ + savecurrbop = currbop; + /* note that curreop is saved in last InterpretPage */ + /* search backwards through all DVI pages for lowest matching page */ + atleastone = false; + nextbop = lastbop; + for (i = totalpages; i >= 1; i--) + { + DVIoffset = nextbop + 1; + ReadBopParameters (); /* update currTeXpage and prevbop */ + if (CurrMatchesNew (newTeXpage)) + { + currbop = nextbop; + currDVIpage = i; + atleastone = true; + } + nextbop = prevbop; + } + if (!atleastone) + { /* no match, so restore currDVIpage */ + currDVIpage = savecurrDVIpage; + if (currDVIpage != 0) + { /* restore page and positioning info */ + currbop = savecurrbop; + DVIoffset = currbop + 1; + ReadBopParameters (); /* restore currTeXpage and prevbop */ + DVIoffset = curreop + 1; + /* we should now be after the eop byte of the original page */ + } + Result = false; + goto _L999; + } + DVIoffset = currbop + 1; + ReadBopParameters (); /* update currTeXpage and prevbop */ + Result = true; +_L999: + return Result; + + /* we found lowest matching page */ +} +/* MoveToTeXPage */ + +/*--------------------------------------------------------------------*/ + +void +SetConversionFactors (double xres, double yres, double magnification) +{ +/* Arguments: + xres: horizontal resolution of output device in dots per inch. + yres: vertical resolution. + magnification: magnification of document; 1 means normal size. + */ + /* This routine must be called before the first InterpretPage call. + DVIReader needs to know the resolution and magnification values + before it attempts to convert DVI units into pixel values. + */ + + /* GT - The "254000.0" corresponds to ten thousand units per mm. */ + /* Refer to TUG's DVI Driver standard. */ + + xconv = (num / 254000.0 * xres / den * magnification); + yconv = (num / 254000.0 * yres / den * magnification); +} + +/* SetConversionFactors */ + +/*--------------------------------------------------------------------*/ + +static int +Sign (double d) +{ + return (d < 0.0 ? -1 : 1); +} +/* Sign */ + +/*--------------------------------------------------------------------*/ + +static void +InitStateValues () +{ + /* Initialize state values and stack. */ + + /* This is the only place in "dvireader.c" */ + /* where hoffset, voffset appear. */ + /* The offsets are set in "options.c". */ + /* The other extern variables are static in "dvireader.c". */ + + double hox, voy; /* offsets divided by conversion factors */ + + hox = hoffset / xconv; + voy = voffset / yconv; + + hh = hoffset; /* 0 if no horizontal shift specified */ + vv = voffset; /* 0 if no vertical shift specified */ + h = Sign (hox) * (int) ((hox >= 0.0 ? hox : -hox) + 0.5); + v = Sign (voy) * (int) ((voy >= 0.0 ? voy : -voy) + 0.5); + w = 0; + x = 0; + y = 0; + z = 0; + stackpos = 0; + fontspace = 0; /* for DoRight and DoDown before a DoFont call */ +} + +/* InitStateValues */ + +/*--------------------------------------------------------------------*/ + +static void +InitPage () +{ + /* Initialize page so that there are no fonts, chars, rules, specials. */ + + pageempty = true; /* gt - assumed until a char or rule is found */ + + /* page edges will change if there is at least one char or rule on page */ + + /* gt - these shouldn't be necessary, but to be on the safe side ... */ + minhp = 0; + minvp = 0; + maxhp = 0; + maxvp = 0; + + currfont = fontlist; + while (currfont != (fontinfo *) NULL) + { + if (currfont->fontused) + { /* only reset those fonts used in last page */ + currfont->fontused = false; + + /* deallocate char list completely; DoFont will allocate first node */ + currfont->totalchars = 0; + while (currfont->charlist != (charinfo *) NULL) + { + charinfo *thischar; /* temporary pointer to node in charlist */ + thischar = currfont->charlist; + currfont->charlist = thischar->nextchar; + Free (thischar, charinfo); + } + currfont->chartail = (charinfo *) NULL; + /* pixel table remains allocated */ + } + currfont = currfont->nextfont; + } + currfont = (fontinfo *) NULL; /* current font's undefined at start of page */ + + /* deallocate rule information except for one node (for DoSet/PutRule) */ + totalrules = 0; + while (rulelist != ruletail) + { + ruleinfo *thisrule; /* temporary pointer to node in rulelist */ + thisrule = rulelist; + rulelist = thisrule->nextrule; + Free (thisrule, ruleinfo); + } + rulelist->rulecount = 0; /* no rules in this node */ + rulelist->nextrule = (ruleinfo *) NULL; + + /* deallocate \special information */ + while (speciallist != (specialinfo *) NULL) + { + specialinfo *thisspecial; /* temporary ptr to node in speciallist */ + thisspecial = speciallist; + speciallist = speciallist->nextspecial; + Free (thisspecial, specialinfo); + } +} +/* InitPage */ + +/*--------------------------------------------------------------------*/ + +int +XPixelRound (int DVIunits) +{ + /* Return the nearest number of X pixels in the given DVI X dimension. */ + + /* According to the DVI Driver Standard, Level 0, draft 0.05, */ + /* section 2.6.2, "Changes in position due to characters and */ + /* rules", */ + /* pixel_round (n) = sign (Kn) * floor (abs (Kn) + 0.5), */ + /* where sign (i) = -1 if i < 0 and = 1 if i >= 0, */ + /* and K is xconv for horizontal and yconv for vertical */ + /* dimensions. */ + + double Kn = xconv * (double) DVIunits; + return (Sign (Kn) * (int) ((Kn >= 0.0 ? Kn : -Kn) + 0.5)); +} + +/* XPixelRound */ + +/*--------------------------------------------------------------------*/ + +int +YPixelRound (int DVIunits) +{ + /* Return the nearest number of Y pixels in the given DVI Y dimension. */ + + /* According to the DVI Driver Standard, Level 0, draft 0.05, */ + /* section 2.6.2, "Changes in position due to characters and */ + /* rules", */ + /* pixel_round (n) = sign (Kn) * floor (abs (Kn) + 0.5), */ + /* where sign (i) = -1 if i < 0 and = 1 if i >= 0, */ + /* and K is xconv for horizontal and yconv for vertical */ + /* dimensions. */ + + double Kn = yconv * (double) DVIunits; + return (Sign (Kn) * (int) ((Kn >= 0.0 ? Kn : -Kn) + 0.5)); +} + +/* YPixelRound */ + +/*--------------------------------------------------------------------*/ + +static void +DoSetPutChar (int ch, boolean set) +{ + /* Add char info to current chartable, update our horizontal + position on the page and check the page edges. + */ + /* putchar: Exactly the same as setchar, but we DON'T update the horizontal + position on the page. (We still have to check page edges.) + */ + + if (ch > maxTeXchar) + { /* ignore ch */ + String codestr; + sprintf (codestr, "%d", ch); + MesgString ("Unknown character (code "); + MesgString (codestr); + MesgString (") from "); + MesgString (currfont->fontspec); + } + else + { /* ch is valid */ + charinfo *char_info = currfont->chartail; /* may be new chartable */ + _REC_chartable *char_tab = (_REC_chartable *) NULL; + _REC_pixeltable *pix_tab = (_REC_pixeltable *) NULL; + + if (char_info->charcount == chartablesize) + { + char_info->nextchar = (charinfo *) Malloc (sizeof (charinfo)); + /* add new node to end of char list */ + char_info->nextchar->charcount = 0; /* reset charcount */ + char_info->nextchar->nextchar = (charinfo *) NULL; + currfont->chartail = char_info->nextchar; + } + /* allocate a new chartable */ + + char_info = currfont->chartail; + char_tab = &char_info->chartable[char_info->charcount]; + char_tab->hp = hh; + char_tab->vp = vv; + char_tab->code = ch; + + pix_tab = &currfont->pixelptr[ch]; + + /* do page edges increase? */ + + if (pageempty || hh - pix_tab->xo < minhp) + minhp = hh - pix_tab->xo; + if (pageempty || vv - pix_tab->yo < minvp) + minvp = vv - pix_tab->yo; + if (pageempty || hh + pix_tab->wd - pix_tab->xo - 1 > maxhp) + maxhp = hh + pix_tab->wd - pix_tab->xo - 1; + if (pageempty || vv + pix_tab->ht - pix_tab->yo - 1 > maxvp) + maxvp = vv + pix_tab->ht - pix_tab->yo - 1; + + /* the above checks ensure that page edges include all black + pixels in glyph, but we also want to include reference point */ + + if (pageempty || hh < minhp) + minhp = hh; + if (pageempty || vv < minvp) + minvp = vv; + if (pageempty || hh > maxhp) + maxhp = hh; + if (pageempty || vv > maxvp) + maxvp = vv; + + if (set) + { + /* add DVI width calculated in PixelTableRoutine */ + h += pix_tab->dwidth; + + /* add pixel width calculated in PixelTableRoutine */ + hh += pix_tab->pwidth; + + /* use hhh and max_drift to prevent hh drifting too far from h */ + + hhh = XPixelRound (h); + + if (abs (hhh - hh) > max_drift) + { + /* Adjust hh to be just within the allowed tolerance from h. */ + hh = hhh + (hhh > hh ? -max_drift : max_drift); + } + } + currfont->totalchars++; + char_info->charcount++; + pageempty = false; + } +} +/* DoSetChar */ + + +/*--------------------------------------------------------------------*/ + +static void +DoPush () +{ + /* Push state values onto stack. + No need to test for stack overflow since we compare maxstack and + maxstacksize in ProcessPostamble. + */ + + hstack[stackpos] = h; + vstack[stackpos] = v; + wstack[stackpos] = w; + xstack[stackpos] = x; + ystack[stackpos] = y; + zstack[stackpos] = z; + hhstack[stackpos] = hh; + vvstack[stackpos] = vv; + stackpos++; +} + +/* DoPush */ + +/*--------------------------------------------------------------------*/ + +static void +DoPop () +{ + /* Pop state values from top of stack. */ + + if (stackpos == 0) + { + FATAL ("Stack empty!"); + } + stackpos--; + h = hstack[stackpos]; + v = vstack[stackpos]; + w = wstack[stackpos]; + x = xstack[stackpos]; + y = ystack[stackpos]; + z = zstack[stackpos]; + hh = hhstack[stackpos]; + vv = vvstack[stackpos]; +} +/* DoPop */ + +/*--------------------------------------------------------------------*/ + +static void +DoRight (int amount) +{ + /* Move the reference point horizontally by given amount (usually +ve). + When the amount is small, like a kern, hh changes by rounding + the amount; but when the amount is large, hh changes by rounding + the true position h so that accumulated rounding errors disappear. + */ + + h += amount; + + /* GT - Wrong? DVI Driver Standard specifies: + "if (processor uses TFM) + word_space = space - space_shrink; + else + quad = magnification * (design size of font); + word_space = 0.2 * quad; + fi; + + back_space = 0.9 * quad; + + if (amount < word_space && amount > -back_space)". + + So, TFM -> space, space_shrink; + else -> design size. + + Now, how do we learn those quantities? + */ + + if (amount < fontspace && amount > -fontspace * 4) + { + hh += XPixelRound (amount); + + /* use hhh and max_drift to prevent hh drifting too far from h */ + + hhh = XPixelRound (h); + if (abs (hhh - hh) > max_drift) + { + /* Adjust hh to be just within the allowed tolerance from h. */ + hh = hhh + (hhh > hh ? -max_drift : max_drift); + } + } + else + { + hh = XPixelRound (h); + } +} +/* DoRight */ + +/*--------------------------------------------------------------------*/ + +static void +DoDown (int amount) +{ + /* Move the reference point vertically by given amount (usually +ve). + Rounding is done similarly to DoRight but with the threshold between + small and large amounts increased by a factor of 5. + */ + + v += amount; + + /* GT - Wrong? DVI Driver Standard specifies: + "if (abs (y) < 0.8 * quad)". + */ + + if (abs (amount) < fontspace * 5) + { + vv += YPixelRound (amount); + + /* use vvv and max_drift to prevent vv drifting too far from v */ + + vvv = YPixelRound (v); + if (abs (vvv - vv) > max_drift) + { + /* Adjust vv to be just within the allowed tolerance from v. */ + vv = vvv + (vvv > vv ? -max_drift : max_drift); + } + } + else + { + vv = YPixelRound (v); + } +} +/* DoDown */ + +/*--------------------------------------------------------------------*/ + +static int +RulePixels (double conv, int DVIunits) +{ + /* Return the number of pixels in the given height or width of a rule + using the method recommended in DVITYPE. + */ + + int n = (int) (conv * DVIunits); + if (n < conv * DVIunits) + return (n + 1); + else + return n; +} +/* RulePixels */ + +/*--------------------------------------------------------------------*/ + +static void +DoPutSetRule (int height, int width, unsigned char DVIcommand) +{ + /* Exactly the same as DoSetRule, but we DON'T update the horizontal + position on the page. (We still have to check page edges.) + */ + _REC_ruletable *ruletab; + + if (height > 0 && width > 0) + { + + /* may be new ruletable */ + if (ruletail->rulecount == ruletablesize) + { + ruletail->nextrule = (ruleinfo *) Malloc (sizeof (ruleinfo)); + /* add new node to end of rule list */ + ruletail->nextrule->rulecount = 0; /* reset rulecount */ + ruletail->nextrule->nextrule = (ruleinfo *) NULL; + ruletail = ruletail->nextrule; + } + /* allocate a new ruletable */ + ruletab = &ruletail->ruletable[ruletail->rulecount]; + ruletab->hp = hh; + ruletab->vp = vv; + ruletab->wd = RulePixels (xconv, width); + ruletab->ht = RulePixels (yconv, height); + + /* do page edges increase? */ + + /* ref pt of rule is bottom left black pixel */ + + if (pageempty || hh < minhp) + minhp = hh; + if (pageempty || vv > maxvp) + maxvp = vv; + + if (pageempty || hh + ruletab->wd - 1 > maxhp) + maxhp = hh + ruletab->wd - 1; + if (pageempty || vv - ruletab->ht + 1 < minvp) + minvp = vv - ruletab->ht + 1; + + totalrules++; + ruletail->rulecount++; + pageempty = false; + } + + if (DVIcommand == setrule) + { + hh += RulePixels (xconv, width); + h += width; + + /* use hhh and max_drift to prevent hh drifting too far from h */ + + hhh = XPixelRound (h); + + if (abs (hhh - hh) > max_drift) + { + /* Adjust hh to be just within the allowed tolerance from h. */ + hh = hhh + (hhh > hh ? -max_drift : max_drift); + } + } +} /* DoPutSetRule */ + +/*--------------------------------------------------------------------*/ + +static void +DoFont (int externf) +{ + /* Search font list for externf, setting currfont and fontspace. + If this is the first time we've seen this font (on current page) then + we need to allocate the first chartable. + If this is the first time we've seen this font used at all then we + allocate a pixeltable and call routine to fill it in. + */ + + charinfo *char_info = (charinfo *) NULL; + + currfont = fontlist; + while (currfont != (fontinfo *) NULL && currfont->fontnum != externf) + { + currfont = currfont->nextfont; + } + + if (currfont == NULL) + FATAL1 ("Failed to find font #%d.", externf); + if (!currfont->fontused) + { + currfont->fontused = true; + currfont->charlist = (charinfo *) Malloc (sizeof (charinfo)); + /* allocate first chartable */ + char_info = currfont->charlist; + char_info->charcount = 0; /* for DoSet/PutChar */ + char_info->nextchar = (charinfo *) NULL; /* this node is also last */ + currfont->chartail = currfont->charlist; + if (currfont->pixelptr == (_REC_pixeltable *) NULL) + { /* first time we've seen this font */ + currfont->pixelptr = (_REC_pixeltable *) Malloc (sizeof (pixeltable)); + PixelTableRoutine (currfont); + } + } + /* do nothing since we've already used this font on this page */ + + fontspace = currfont->scaledsize / 6; + + /* See DVITYPE; a 3-unit thin space. + Note that a thin space is 1/6 of a quad, where a quad is + 1 em in the current font and usually equals the design size. + */ + +} +/* DoFont */ + +/*--------------------------------------------------------------------*/ + +static void +DoSpecial (int hpos, int vpos, int totalbytes) +{ + /* in */ + + /* DVIReader has seen a \special command while interpreting the current page. + It will pass the current page position and number of bytes in the command. + We save the info away in speciallist for later use by the main program. + */ + int i; + specialinfo *temp; + + temp = (specialinfo *) Malloc (sizeof (specialinfo)); + for (i = 0; i < totalbytes; i++) + { + int temp1; + temp1 = GetDVIByte (); + if (i < maxspeciallen) + temp->special[i] = temp1; + } + temp->special[i <= maxspeciallen ? i : maxspeciallen] = '\0'; + + temp->hp = hpos; + temp->vp = vpos; + temp->nextspecial = speciallist; + speciallist = temp; /* add new info to head of list */ +} +/* DoSpecial */ + +/*--------------------------------------------------------------------*/ + +void +InterpretPage () +{ + /* When this routine is called we are positioned after the bytes of a bop + command (i.e., at currbop + 45). At the end of this routine we will be + positioned after the eop byte for the current page. In between we carry + out the important task of translating the DVI description of this page + and filling in the following global data structures: + + totalrules := number of rules on page + rulelist-> (nodes are added to tail of rule list) + rulecount := number of rules in this ruletable + ruletable[0..rulecount-1]. + hp, vp := reference point of a rule + wd, ht := pixel dimensions of a rule (both > 0) + nextrule := next node in rule list (if not NIL) + ruletail := pointer to last node in rule list + + speciallist-> (nodes are added to head of this list) + hp, vp := reference point on page + special := \special bytes + nextspecial := next node in list (if not NIL) + + fontlist-> + (the following fontinfo is relevant only if fontused is TRUE) + totalchars := number of chars on page from this font + charlist-> (nodes are added to tail of char list) + charcount := number of chars in this chartable + chartable[0..charcount-1]. + hp, vp := reference point of a character + code := TeX character code (and index into pixel table) + nextchar := next node in char list (if not NIL) + chartail := pointer to last node in char list + pixelptr^[0..maxTeXchar]. + (filled in by FontReader's PixelTableRoutine) + wd, ht := glyph width and height in pixels + xo, yo := offsets from the character's reference point + dwidth := advance width in DVI units + pwidth := advance width in pixels + mapadr := offset in fontspec of the glyph's bitmap info + bitmap := NIL + nextfont := next node in font list (if not NIL) + + pageempty := TRUE iff the page has no rules and no characters + minhp, minvp, maxhp, maxvp + := the edges of the page (undefined if pageempty is TRUE) + They define the smallest rectangle containing all black + pixels on the page;(minhp,minvp) is the top left corner. + + Reference points for rules and characters are stored as a pair of + horizontal and vertical pixel coordinates. The point (0,0) is assumed + to be the pixel 1 inch in from the top and left edges of an imaginary sheet + of paper. Horizontal coordinates increase to the right and vertical + coordinates increase down the paper. + The numbers of pixels per inch in the X and Y directions are defined by + the xres and yres resolution parameters given to SetConversionFactors. + */ + + int param = 0, ht, wd; + + InitStateValues (); + InitPage (); + do + { + DVIcommand = GetDVIByte (); + /* For efficiency reasons the most frequent commands should be tested 1st. + The following order is the result of frequency testing on typical + DVI files. Note that the most frequent commands in the DVI file + generated by TeX 1.3 for the Dec. 1983 LaTeX manual were: + z4 && DVIcommand < fnt1) + { + /* catch all the remaining movement commands */ + DoFont (DVIcommand - fntnum0); + } + else if (DVIcommand > pop && DVIcommand < fntnum0) + { + if (DVIcommand == right2) + DoRight (SignedDVIPair ()); + else if (DVIcommand == right4) + DoRight (SignedDVIQuad ()); + else if (DVIcommand == x2) + { + x = SignedDVIPair (); + DoRight (x); + } + else if (DVIcommand == x3) + { + x = SignedDVITrio (); + DoRight (x); + } + else if (DVIcommand == down3) + DoDown (SignedDVITrio ()); + else if (DVIcommand == down4) + DoDown (SignedDVIQuad ()); + else if (DVIcommand == w2) + { + w = SignedDVIPair (); + DoRight (w); + } + else if (DVIcommand == z0) + DoDown (z); + else if (DVIcommand == y3) + { + y = SignedDVITrio (); + DoDown (y); + } + else if (DVIcommand == z3) + { + z = SignedDVITrio (); + DoDown (z); + } + else if (DVIcommand == down2) + { + /* the next DVI commands are used very rarely (by TeX 1.3 at least) */ + DoDown (SignedDVIPair ()); + } + else if (DVIcommand == w1) + { + w = SignedDVIByte (); + DoRight (w); + } + else if (DVIcommand == w4) + { + w = SignedDVIQuad (); + DoRight (w); + } + else if (DVIcommand == x1) + { + x = SignedDVIByte (); + DoRight (x); + } + else if (DVIcommand == x4) + { + x = SignedDVIQuad (); + DoRight (x); + } + else if (DVIcommand == y1_) + { + y = SignedDVIByte (); + DoDown (y); + } + else if (DVIcommand == y2) + { + y = SignedDVIPair (); + DoDown (y); + } + else if (DVIcommand == y4) + { + y = SignedDVIQuad (); + DoDown (y); + } + else if (DVIcommand == z1) + { + z = SignedDVIByte (); + DoDown (z); + } + else if (DVIcommand == z2) + { + z = SignedDVIPair (); + DoDown (z); + } + else if (DVIcommand == z4) + { + z = SignedDVIQuad (); + DoDown (z); + } + else if (DVIcommand == right1) + DoRight (SignedDVIByte ()); + else if (DVIcommand == down1) + DoDown (SignedDVIByte ()); + else + FATAL ("Bug in InterpretPage!"); + } + else if (DVIcommand == setrule || DVIcommand == putrule) + { + ht = SignedDVIQuad (); + wd = SignedDVIQuad (); + DoPutSetRule (ht, wd, DVIcommand); + } + else if (DVIcommand >= put1 && DVIcommand <= put1 + 3) + { + switch (DVIcommand - put1) + { + case 0: + DoSetPutChar (GetDVIByte (), false); + break; + case 1: + DoSetPutChar (GetTwoDVIBytes (), false); + break; + case 2: + DoSetPutChar (GetThreeDVIBytes (), false); + break; + case 3: + DoSetPutChar (SignedDVIQuad (), false); + break; + } + + } + else if (DVIcommand >= set1 && DVIcommand <= set1 + 3) + { + switch (DVIcommand - set1) + { + case 0: + DoSetPutChar (GetDVIByte (), true); + break; + case 1: + DoSetPutChar (GetTwoDVIBytes (), true); + break; + case 2: + DoSetPutChar (GetThreeDVIBytes (), true); + break; + case 3: + DoSetPutChar (SignedDVIQuad (), true); + break; + } + + } + else if (DVIcommand >= fnt1 && DVIcommand <= fnt1 + 3) + { + switch (DVIcommand - fnt1) + { + case 0: + DoFont (GetDVIByte ()); + break; + case 1: + DoFont (GetTwoDVIBytes ()); + break; + case 2: + DoFont (GetThreeDVIBytes ()); + break; + case 3: + DoFont (SignedDVIQuad ()); + break; + } + + } + else if (DVIcommand >= xxx1 && DVIcommand <= xxx1 + 3) + { + switch (DVIcommand - xxx1) + { + case 0: + param = GetDVIByte (); + break; + case 1: + param = GetTwoDVIBytes (); + break; + case 2: + param = GetThreeDVIBytes (); + break; + case 3: + param = SignedDVIQuad (); + break; + } + /* pass current pixel position and number of bytes */ + DoSpecial (hh, vv, param); + } + else if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3) + SkipFntdef (DVIcommand - fntdef1); + else if (DVIcommand != nop) + { + if (DVIcommand != eop) /* do nothing */ + FATAL1 ("Unexpected DVI command while interpreting page = %d.", + DVIcommand); + } + } + while (DVIcommand != eop); + + /* save position of eop byte for use in MoveToTeXPage */ + curreop = DVIoffset - 1; + + if (stackpos != 0) + FATAL ("Stack not empty at eop!"); + /* InitPage values */ + + + /* fntnum0..fntnum63 */ + + + /* skip fntdef command since we've got this info from postamble */ + + /* do nothing */ +} +/* InterpretPage */ + +/*--------------------------------------------------------------------*/ + +void +SortFonts (fontinfo ** unusedlist) +{ + /* out */ + + /* Sort fontlist in order of ascending totalchars. + Fonts with least characters can then be accessed first. + Since the number of fonts used on a typical page is quite small, a simple + sorting algorithm should be good enough. Note that unused fonts are moved + to the end of the list and unusedlist points to the first such node. + DVItoVDU need only process fonts up to (but excluding) unusedlist + and does not have to worry about checking the fontused flag. + If unusedlist is NIL then either 1) all fonts are used on the current page + or 2) fontlist is also NIL (totalfonts = 0). + */ + fontinfo *newfontlist, *prevfont, *largest, *prevlargest; + int mostchars; + + newfontlist = (fontinfo *) NULL; + /* go thru fontlist once and move all unused fonts to head of newfontlist */ + prevfont = (fontinfo *) NULL; + currfont = fontlist; + while (currfont != (fontinfo *) NULL) + { + if (currfont->fontused) + { + prevfont = currfont; /* remember previous node */ + currfont = currfont->nextfont; + continue; + } + /* move node from fontlist to head of newfontlist + and don't change prevfont + */ + if (prevfont == (fontinfo *) NULL) + { + fontlist = currfont->nextfont; /* remove first node in fontlist */ + currfont->nextfont = newfontlist; + newfontlist = currfont; + currfont = fontlist; + } + else + { + prevfont->nextfont = currfont->nextfont; + currfont->nextfont = newfontlist; + newfontlist = currfont; + currfont = prevfont->nextfont; + } + } + + /* unusedlist will be last unused font moved to newfontlist. It will be NIL + if either fontlist is NIL or all fonts are used. + */ + + *unusedlist = newfontlist; + + /* Now go thru fontlist repeatedly moving node with max totalchars to + head of newfontlist until fontlist is exhausted. + */ + + while (fontlist != (fontinfo *) NULL) + { + prevfont = (fontinfo *) NULL; + currfont = fontlist; + prevlargest = (fontinfo *) NULL; + largest = fontlist; + mostchars = 0; + + /* search for largest totalchars */ + while (currfont != (fontinfo *) NULL) + { + if (currfont->totalchars > mostchars) + { + prevlargest = prevfont; + largest = currfont; + mostchars = currfont->totalchars; + } + prevfont = currfont; + currfont = currfont->nextfont; + } + /* move largest node from fontlist to head of newfontlist */ + if (prevlargest == (fontinfo *) NULL) + fontlist = largest->nextfont; /* remove first node in fontlist */ + else + prevlargest->nextfont = largest->nextfont; + largest->nextfont = newfontlist; + newfontlist = largest; + } + fontlist = newfontlist; + /* used fonts now sorted and unused fonts at end */ +} +/* SortFonts */ + +/*--------------------------------------------------------------------*/ + +void +CloseDVIFile () +{ + /* Close the currently open DVI file, + and deallocate dynamic data structures. */ + + int result; + + result = close (DVIfile); + while (fontlist != (fontinfo *) NULL) + { + currfont = fontlist; + while (currfont->charlist != (charinfo *) NULL) + { + charinfo *thischar; /* temporary pointer to node in charlist */ + thischar = currfont->charlist; + currfont->charlist = thischar->nextchar; + Free (thischar, charinfo); /* deallocate char list */ + } + if (currfont->pixelptr != (_REC_pixeltable *) NULL) + Free (currfont->pixelptr, _REC_pixeltable); /* deallocate pixel table */ + fontlist = currfont->nextfont; + Free (currfont, fontinfo); /* deallocate font information */ + } + /* Deallocate rule information except for one node + (in case DVItoVDU ever opens another DVI file). + */ + while (rulelist != ruletail) + { + ruleinfo *thisrule; /* temporary pointer to node in rulelist */ + thisrule = rulelist; + rulelist = thisrule->nextrule; + Free (thisrule, ruleinfo); + } + while (speciallist != (specialinfo *) NULL) + { + specialinfo *thisspecial; /* temporary ptr to node in speciallist */ + thisspecial = speciallist; + speciallist = speciallist->nextspecial; + Free (thisspecial, specialinfo); + } +} +/* CloseDVIFile */ + +/*--------------------------------------------------------------------*/ + +void +InitDVIReader () +{ + totalrules = 0; + rulelist = (ruleinfo *) Malloc (sizeof (ruleinfo)); /* for first InitPage */ + ruletail = rulelist; /* ditto */ + speciallist = (specialinfo *) NULL; /* ditto */ + fontlist = (fontinfo *) NULL; /* safer for CloseDVIFile */ +} +/* InitDVIReader */ + +/*--------------------------------------------------------------------*/ + +/* end dvireader.c */ diff --git a/dviware/dvgtk/dvireader.h b/dviware/dvgtk/dvireader.h new file mode 100644 index 0000000000..15780dd17a --- /dev/null +++ b/dviware/dvgtk/dvireader.h @@ -0,0 +1,171 @@ +/* dvireader.h - functions for reading DVI files + $Id: dvireader.h,v 0.2 1997/03/28 03:16:45 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __DVIREADER_H__ +#define __DVIREADER_H__ + +#include "dvgt.h" + +#define ruletablesize 300 /* maximum number of rules in a ruletable */ +#define chartablesize 3000 /* maximum number of chars in a chartable */ +#define maxfontspec maxstring + /* max length of a font file specification */ +#define maxspeciallen maxstring + /* maximum length of \special string */ +#define maxTeXchar 255 /* ignore character codes > 255 */ + +typedef struct _REC_ruletable + { + int hp, vp; /* pixel coords of rule's ref point */ + int wd, ht; /* dimensions of rule in pixels */ + } +_REC_ruletable; + +typedef struct _REC_chartable + { + int hp, vp; /* pixel coords of char's ref point */ + unsigned char code; /* char's code and pixeltable index */ + } +_REC_chartable; + +typedef struct _REC_pixeltable + { + int wd, ht; + /* glyph width and height in pixels; they + define the size of the smallest box + containing all the black pixels */ + int xo, yo; + /* x and y offsets from top left corner + of glyph to character's reference point */ + int dwidth; + /* advance width in DVI units computed from + fix width stored in font file */ + int pwidth; + /* advance width in pixels computed from + fix width stored in font file */ + int mapadr; /* byte offset of bitmap info in font file */ + int_or_mptr bitmap; /* SYSDEP: starting address of bitmap */ + } +_REC_pixeltable; + +/* Information about the rules and characters appearing on a page is stored + in dynamic one-way lists to avoid imposing any limit on their numbers. + To reduce pointer overheads, the nodes in these lists contain large + tables (the values of ruletablesize and chartablesize have been chosen + so that the vast majority of DVI pages will only require one-node lists). + When interpreting a DVI page, DVIReader adds a new rule or character node + to the TAIL of the relevant list. This is done so that when DVItoVDU + accesses such lists (starting at the head), rules and characters will be + processed in somewhat the same sequence as seen in the DVI file; i.e., + top-to-bottom and left-to-right across the page. + Since a character list is part of the information stored for a font, + the precise sequence in which DVI characters are seen is not remembered. + Font information is also linked together in a one-way list, but the + ordering is more or less random (see, however, the SortFonts routine). + */ + +typedef struct ruleinfo + { + int rulecount; /* number of rules in ruletable */ + _REC_ruletable ruletable[ruletablesize]; + struct ruleinfo *nextrule; /* next node in rule list */ + } +ruleinfo; /* a node in a list of ruletables */ + +typedef struct charinfo + { + int charcount; /* number of chars in chartable */ + _REC_chartable chartable[chartablesize]; + struct charinfo *nextchar; /* next node in char list */ + } +charinfo; /* a node in list of chartables */ + +/* DVIReader uses wd, ht, xo and yo to calculate minhp, minvp, maxhp and + maxvp. dwidth and pwidth are used to advance horizontally. + The mapadr and bitmap fields are not used by DVIReader; they are used + by FontReader and the main program to load character bitmaps. + */ +typedef _REC_pixeltable pixeltable[maxTeXchar + 1]; + +typedef struct fontinfo + { + boolean pkfont; /* is this a PK bitmap font? */ + boolean fontused; /* is font used on current page? */ + int fontnum; /* DVI font number: -2^31 .. 2^30 - 1 */ + int scaledsize; /* scaled font size in DVI units */ + int designsize; /* design size in DVI units */ + String fontarea; /* explicit font directory */ + int fontarealen; /* length of fontarea */ + String fontname; /* font name; e.g., "cmr10" */ + int fontnamelen; /* length of font name */ + String fontspec; /* complete font file pathname */ + int fontspeclen; /* length of fontspec */ + boolean fontexists; /* can fontspec be opened? */ + boolean honest; /* true (and not substitute) font */ + int totalchars; /* number of chars from font on page */ + charinfo *charlist; /* head of char information list */ + charinfo *chartail; /* tail of char information list */ + _REC_pixeltable *pixelptr; /* allocated once: 1st time font used */ + struct fontinfo *nextfont; /* next node in font list */ + } +fontinfo; /* a node in list of fonts */ + +/* For the parameter in MoveToTeXPage: */ +typedef int TeXcounters[10]; + +typedef struct TeXpageinfo + { + TeXcounters value; /* \count0..\count9 values */ + boolean present[10]; /* is counter relevant? */ + char lastvalue; /* last relevant counter */ + } +TeXpageinfo; + +/* DVIReader also builds a list of \special info: */ + +typedef struct specialinfo + { + String special; + int hp, vp; + struct specialinfo *nextspecial; + } +specialinfo; + + +/* Most of these should be treated as read-only parameters: */ +extern int DVImag; /* magnification stored in DVI file */ +extern int totalpages; /* number of pages in DVI file */ +extern int totalfonts; /* number of fonts in DVI file */ +extern int currDVIpage; /* updated by MoveTo... calls */ +extern TeXcounters currTeXpage; + /* ditto */ +extern int totalrules; /* number of rules on current page */ +extern ruleinfo *rulelist; /* head of rule information list */ +extern ruleinfo *ruletail; /* tail of rule information list */ +extern specialinfo *speciallist; + /* head of \special information list */ +extern fontinfo *fontlist; /* head of font information list */ +extern fontinfo *currfont; /* InterpretPage's current font info */ +extern boolean pageempty; /* is page empty of rules and chars? */ +extern int minhp; /* minimum horizontal pixel coordinate */ +extern int minvp; /* minimum vertical pixel coordinate */ +extern int maxhp; /* maximum horizontal pixel coordinate */ +extern int maxvp; /* maximum vertical pixel coordinate */ + +extern void InitDVIReader (); +extern void OpenDVIFile PARAMS ((char *name)); +extern void SetConversionFactors PARAMS ((double xres, double yres, double magnification)); +extern void MoveToDVIPage PARAMS ((int n)); +extern void MoveToNextPage PARAMS ((boolean ascending)); +extern boolean MoveToTeXPage PARAMS ((TeXpageinfo * newTeXpage)); +extern int XPixelRound PARAMS ((int DVIunits)); +extern int YPixelRound PARAMS ((int DVIunits)); +extern void InterpretPage (); +extern void SortFonts PARAMS ((fontinfo ** unusedlist)); +extern void CloseDVIFile (); + +#endif /* __DVIREADER_H__ */ + +/* end dvireader.h */ diff --git a/dviware/dvgtk/etc/dv-env b/dviware/dvgtk/etc/dv-env new file mode 100644 index 0000000000..2daced5ddb --- /dev/null +++ b/dviware/dvgtk/etc/dv-env @@ -0,0 +1,25 @@ +# dv-env - 20:31 GMT +10:00 Sun 30 May 1993 - Geoffrey Tobin. +# A sample C shell script for setting environment variables for the +# dvgt 3.5 TeX previewer. + +# 1. Environment variables peculiar to dvitovdu. + +# PK font of last resort; assumed in usual font directory: +setenv DV_DUMMY_PK cmr10.300pk +# TFM metric of last resort; assumed in usual tfm directory: +setenv DV_DUMMY_TFM cmr10.tfm +# PS font prefix; Karl Berry's convention: +setenv DV_PS_PREFIX p +# Locations of help texts. +setenv DV_HELP /usr/local/lib/tex/dv/help +setenv DV_IMMED_HELP /usr/local/lib/tex/dv/immed.hlp +# Video driver. +setenv DV_TERM ncsatel + +# 2. Modify PKFONTS and TEXFONTS with care, +# because other TeX programs use them! + +# PKFONTS lists directories where PK bitmap fonts live. +setenv PKFONTS .:/usr/local/lib/tex/fonts/qume/ +# TEXFONTS lists directories where TFM metric files live. +setenv TEXFONTS .:/usr/local/lib/tex/fonts/ diff --git a/dviware/dvgtk/etc/sane b/dviware/dvgtk/etc/sane new file mode 100644 index 0000000000..fd766d1796 --- /dev/null +++ b/dviware/dvgtk/etc/sane @@ -0,0 +1,9 @@ +#!/bin/sh +# sane +# Complete, sane stty settings, for NCSA Telnet connection. + +stty sane +stty 38400 # the baud rate is important: modify to suit +stty -parenb cs8 -istrip tab3 + +# end sane diff --git a/dviware/dvgtk/fontreader.c b/dviware/dvgtk/fontreader.c new file mode 100644 index 0000000000..3976e00281 --- /dev/null +++ b/dviware/dvgtk/fontreader.c @@ -0,0 +1,1079 @@ +/* fontreader.c - functions for reading PK fonts + $Id: fontreader.c,v 0.2 1997/03/28 03:16:59 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include +#include + +#include "screenio.h" +#include "vdu.h" +#include "options.h" +#include "dvireader.h" +#include "fontreader.h" + +typedef struct _REC_TFMinfo + { + int wdindex, htindex, dpindex; + } +_REC_TFMinfo; + +typedef struct _REC_charmetrics + { + int width[4], height[4], depth[4]; + } +_REC_charmetrics; + + +static int PTfile; /* PK/TFM file descriptor */ +static int PToffset; /* current byte offset in PTfile */ +static int currPTbuff; /* starting byte offset in buffer */ +static buffer PTbuffer; /* input buffer */ +static int gpower[33]; /* 0,1,11,111,1111,... */ +static boolean turnon; /* is current run black? */ +static int dynf; /* dynamic packing variable */ +static int repeatcount; /* times to repeat the next row */ +static int bitweight; /* for bits or nybbles from inputbyte */ +static int inputbyte; /* the current input byte */ +static int lf, lh, bc, ec, nw, nh; /* TFM file data; lf unused */ +static _REC_TFMinfo TFMinfo[maxTeXchar + 1]; +static _REC_charmetrics charmetrics[maxTeXchar + 1]; + +/*--------------------------------------------------------------------*/ +boolean +CheckFontPtr (fontinfo * fontptr) +{ + boolean check = false; + if (fontptr == (fontinfo *) NULL) + { + MesgString ("NULL font info passed to CheckFontPtr!"); + MesgLine (); + check = false; + } + else if (fontptr->fontnamelen == 0) + { + MesgString ("Zero length font name in font info passed to CheckFontPtr!"); + MesgLine (); + check = false; + } + else if (!strcmp (fontptr->fontname, "")) + { + MesgString ("Empty font name in font info passed to CheckFontPtr!"); + MesgLine (); + check = false; + } + else + { + check = true; + } + return check; +} +/* CheckFontPtr */ + +/*--------------------------------------------------------------------*/ + +boolean +BuildFontSpec (fontinfo * fontptr) +{ + /* Build a complete PK or TFM font file specification in fontptr->fontspec. + (May end up with a dummy PK font's or TFM metric's file spec. + ShowStatistics() in "dvitovdu.c" will show any font substitutions.) + This will be done at most once per font. + Test for valid fontptr->fontname. + ASSUMPTIONS: + fontptr->fontname contains the basename of the font. + SIDE EFFECTS on success: + fontptr->fontspec will be set. + fontptr->fontspeclen will no longer be 0. + fontptr->fontexists becomes TRUE if the real or dummy PK or TFM + file can be opened, FALSE, otherwise. + fontptr->pkfont becomes TRUE if the real or dummy PK file + can be opened, FALSE, otherwise. + fontptr->honest becomes TRUE if the true font is used, FALSE otherwise. + SIDE EFFECTS on failure: + EITHER: + fontptr is NULL. + OR: + fontptr->fontspec will be unset (holds empty string ""). + fontptr->fontspeclen will be 0. + fontptr->fontexists becomes FALSE. + fontptr->pkfont becomes FALSE. + fontptr->honest becomes FALSE. + */ + + kpse_glyph_file_type font_ret; + string name; + unsigned dpi; + + if (!CheckFontPtr (fontptr)) + return false; + + /* Initialise correctly */ + strncpy (fontptr->fontspec, "", maxfontspec); + fontptr->fontspeclen = 0; + fontptr->fontexists = false; + fontptr->pkfont = false; + fontptr->honest = false; + +#if 0 + dpi = kpse_magstep_fix ((unsigned) (mag / 5.0 + .5), + xres, NULL); + tfontptr->font_mag = dpi * 5; /* save correct dpi */ +#endif + dpi = (int) (mag / 1000.0 * + (double) fontptr->scaledsize / fontptr->designsize * xres + 0.5); + + if (dpi == 0) /* allow for subtracting 1 */ + ++dpi; + + name = kpse_find_pk (fontptr->fontname, dpi, &font_ret); + if (name) + { + if (!STREQ (fontptr->fontname, font_ret.name)) + { +#if 0 + WARNING3 ("dvgt: Font %s not found, using %s at %d instead.\n", + fontptr->fontname, font_ret.name, font_ret.dpi); +#endif + } + else if (!kpse_bitmap_tolerance ((double) font_ret.dpi, (double) dpi)) + { +#if 0 + WARNING3 ("dvilj: Font %s at %d not found, using %d instead.\n", + fontptr->fontname, dpi, font_ret.dpi); +#endif + } + else + fontptr->honest = true; + + fontptr->fontspeclen = strlen (name); + strcpy (fontptr->fontspec, name); + free (name); + fontptr->fontexists = true; /* specified PK file exists */ + fontptr->pkfont = true; + + return true; + } + else + { + /* PK font file doesn't exist. */ + name = kpse_find_tfm (fontptr->fontname); + if (name) + { + fontptr->fontspeclen = strlen (name); + strcpy (fontptr->fontspec, name); + free (name); + + fontptr->fontexists = true; + fontptr->honest = true; + } + else + { + name = kpse_find_tfm (dummy_tfm); + if (name) + { + fontptr->fontspeclen = strlen (name); + strcpy (fontptr->fontspec, name); + free (name); + fontptr->fontexists = true; + } + } + } + + return true; +} +/* BuildFontSpec */ + +/*--------------------------------------------------------------------*/ + +boolean +OpenFontFile (char *name) +{ + /* Return TRUE if given file can be (unix-specifically) open-ed. + Only one font file will be open at any given time. + */ + + extern int currPTbuff; + extern int PTfile; + + currPTbuff = -1; /* impossible value for first GetPTByte */ + PTfile = open (name, O_RDONLY, 0); /* unix "open" returns -1 if fails */ + return (PTfile >= 0); +} +/* OpenFontFile */ + +/*--------------------------------------------------------------------*/ + +void +CloseFontFile () +{ + /* If there is a currently open font file, then close it. */ + + if (PTfile >= 0) + { + close (PTfile); + /* Be cautious: ensure PTfile is negative, after this function. */ + if (PTfile >= 0) + PTfile = -1; + } +} +/* CloseFontFile */ + +/*--------------------------------------------------------------------*/ + +static int +GetPTByte () +{ + /* Returns the value (unsigned) of the byte at PToffset and + advances PToffset for the next GetPTByte. + */ + + int Result, buffstart, result; + + buffstart = PToffset / bufflen * bufflen; /* 0, bufflen, 2*bufflen... */ + if (buffstart != currPTbuff) + { + currPTbuff = buffstart; + + if (PTfile < 0) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL ("PTfile not open in GetPTByte!"); + } + result = lseek (PTfile, buffstart, 0); + if (result != buffstart) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL ("lseek failed in GetPTByte!"); + } + result = read (PTfile, PTbuffer, bufflen); + if (result == -1) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL ("Read failed in GetPTByte!"); + } + } + Result = PTbuffer[PToffset - buffstart]; + PToffset++; + return Result; +} +/* GetPTByte */ + +/*--------------------------------------------------------------------*/ + +static int +SignedPTByte () +{ + /* the next byte, signed */ + int b; + + b = GetPTByte (); + if (b < 128) + return b; + else + return (b - 256); +} +/* SignedPTByte */ + +/*--------------------------------------------------------------------*/ + +static int +GetTwoPTBytes () +{ + /* the next 2 bytes, unsigned */ + int a, b; + + a = GetPTByte (); + b = GetPTByte (); + return (a * 256 + b); +} +/* GetTwoPTBytes */ + +/*--------------------------------------------------------------------*/ + +static int +SignedPTPair () +{ + /* the next 2 bytes, signed */ + int a, b; + + a = GetPTByte (); + b = GetPTByte (); + if (a < 128) + return (a * 256 + b); + else + return ((a - 256) * 256 + b); +} +/* SignedPTPair */ + +/*--------------------------------------------------------------------*/ + +/* UNUSED: */ +#ifdef GET_THREE_PT_BYTES +static int +GetThreePTBytes () +{ + /* the next 3 bytes, unsigned */ + int a, b, c; + + a = GetPTByte (); + b = GetPTByte (); + c = GetPTByte (); + return ((a * 256 + b) * 256 + c); +} +/* GetThreePTBytes */ +#endif /* GET_THREE_PT_BYTES */ + +/*--------------------------------------------------------------------*/ + +typedef struct int_or_bytes +{ + boolean b; + union + { + int int_; + char byt[4]; + } + UU; +} +int_or_bytes; + +/*--------------------------------------------------------------------*/ + +static int +SignedPTQuad () +{ + /* the next 4 bytes, signed */ + int w; + + byte3 (w) = GetPTByte (); + byte2 (w) = GetPTByte (); + byte1 (w) = GetPTByte (); + byte0 (w) = GetPTByte (); + return (w); +} +/* SignedPTQuad */ + +/*--------------------------------------------------------------------*/ + +static int +GetNyb () +{ + /* Return next nybble in PK file. */ + + if (bitweight == 0) + { + inputbyte = GetPTByte (); + bitweight = 16; /* for next call of GetNyb */ + return (inputbyte / 16); /* high nybble */ + } + else + { + bitweight = 0; /* for next call of GetNyb */ + return (inputbyte & 15); /* low nybble */ + } +} +/* GetNyb */ + +/*--------------------------------------------------------------------*/ + +static int +PackedNum () +{ + /* Return next run count using algorithm given in section 23 of PKtype. + A possible side-effect is to set the global repeatcount value used + to duplicate the current row. + */ + + int i, j; + + i = GetNyb (); + if (i == 0) + { + do + { + j = GetNyb (); + i++; + } + while (j == 0); + while (i > 0) + { + j = j * 16 + GetNyb (); + i--; + } + return (j + (13 - dynf) * 16 + dynf - 15); + } + else if (i <= dynf) + return i; + else if (i < 14) + return ((i - dynf - 1) * 16 + GetNyb () + dynf + 1); + else + { + if (i == 14) /* nybble = 15 */ + repeatcount = PackedNum (); /* recursive */ + else + repeatcount = 1; + return (PackedNum ()); /* recursive */ + } +} +/* PackedNum */ + +/*--------------------------------------------------------------------*/ + +boolean +GetBitmap (int ht, int wd, int mapadr, int_or_mptr * bitmap) +{ + /* Allocate space for bitmap and fill it in using information from + character definition starting at mapadr in currently open PK + file. Note that the memory used by a loaded bitmap is never + deallocated. Each bitmap row uses an integral number of words + (each 32 bits). Byte-aligned rows would use about 35% less + memory but would increase the processing time needed to display + each bitmap. It was felt that speed is more important than + memory. Return true if the bitmap is obtained, false if function + fails. + */ + + extern int bitweight; /* local to "fontreader.c" */ + + int_or_bptr wordptr, rowptr; + int i, j, flagbyte, wordwidth, wordweight, rowsleft, hbit, count, bitmapwords; + int word; + Word *bitmapptr = (Word *) NULL; + + wordwidth = (wd + 31) / 32; /* words in one row of bitmap */ + bitmapwords = ht * wordwidth; /* memory required by bitmap */ + + bitmapptr = (Word *) calloc (bitmapwords, sizeof (Word)); + if (bitmapptr == (Word *) NULL) + { + StartText (); + ResetVDU (); /* do before message since it might erase screen! */ + FATAL1 ("Out of memory. Character too big! size = %d", bitmapwords); + return false; /* Not Reached */ + } + bitmap->UU.mptr = bitmapptr; /* return start of bitmap */ + wordptr.UU.int_ = bitmap->UU.int_; + PToffset = mapadr; /* mapadr = flagbyte offset in PK file */ + + flagbyte = GetPTByte (); /* assume < 240 */ + dynf = flagbyte / 16; /* dynamic packing variable */ + turnon = ((flagbyte & 15) >= 8); /* is 1st pixel black? */ + flagbyte &= 7; /* value of bottom 3 bits */ + if (flagbyte < 4) /* skip short char preamble */ + PToffset += 10; + else if (flagbyte < 7) + PToffset += 16; + else + PToffset += 36; + + bitweight = 0; /* to get 1st inputbyte */ + if (dynf == 14) + { + /* raster info is a string of bits in the next (wd * ht + 7) DIV 8 bytes */ + + for (i = 1; i <= ht; i++) + { + word = 0; /* set all bits to 0 */ + wordweight = 31; /* leftmost bit */ + for (j = 1; j <= wd; j++) + { + if (bitweight == 0) + { + inputbyte = GetPTByte (); + bitweight = 8; + } + bitweight--; /* 7..0 */ + if ((unsigned) bitweight < 32 && ((1 << bitweight) & inputbyte)) + /* set bit */ + word |= 1 << wordweight; + if (wordweight > 0) + wordweight--; + else + { + *wordptr.UU.bptr = word; + wordptr.UU.int_ += 4; + word = 0; + wordweight = 31; + } + } + if (wordweight < 31) + { + *wordptr.UU.bptr = word; + wordptr.UU.int_ += 4; /* start of next word */ + } + } + } + else + { + /* raster info is encoded as run and repeat counts */ + + rowsleft = ht; + hbit = wd; + repeatcount = 0; + wordweight = 32; + word = 0; + rowptr = wordptr; /* remember start of row */ + while (rowsleft > 0) + { + count = PackedNum (); + while (count > 0) + { + if (count < wordweight && count < hbit) + { + if (turnon) + word = (word | gpower[wordweight]) & (~gpower[wordweight - count]); + hbit -= count; + wordweight -= count; + count = 0; + continue; + } + if (count >= hbit && hbit <= wordweight) + { + if (turnon) + word = (word | gpower[wordweight]) & (~gpower[wordweight - hbit]); + *wordptr.UU.bptr = word; + /* end of current row, so duplicate repeatcount times */ + for (i = 1; i <= repeatcount; i++) + { + for (j = 1; j <= wordwidth; j++) + { + wordptr.UU.int_ += 4; + *wordptr.UU.bptr = *rowptr.UU.bptr; + rowptr.UU.int_ += 4; + } + } + rowsleft += -repeatcount - 1; + repeatcount = 0; + word = 0; + wordptr.UU.int_ += 4; + rowptr = wordptr; /* remember start of next row */ + wordweight = 32; + count -= hbit; + hbit = wd; + } + else + { + if (turnon) + word |= gpower[wordweight]; + *wordptr.UU.bptr = word; + wordptr.UU.int_ += 4; + word = 0; + count -= wordweight; + hbit -= wordweight; + wordweight = 32; + } + } + turnon = !turnon; + } + } + return true; +} +/* GetBitmap */ + +/*--------------------------------------------------------------------*/ + +static int +FixToDVI (int scale, int b0, int b1, int b2, int b3) +/* scale = currfont->scaledsize; */ +/* fix width: 4 bytes */ +{ + /* Convert the given fix width (made up of 4 bytes) into DVI units + using the method recommended in DVITYPE. + Added local scale to avoid changing scaledsize; thanks to Niel Kempson + for reporting this bug. + */ + + int dviwidth = 0; + int alpha, beta, temp; + + alpha = scale * 16; + beta = 16; + while (scale >= 0x800000) + { /* 2^23sp = 128pt */ + scale /= 2; + beta /= 2; + } + temp = ((b3 * scale / 0x100 + b2 * scale) / 0x100 + b1 * scale) / beta; + + if (b0 <= 0) + dviwidth = temp; + else if (b0 == 255) + dviwidth = (temp - alpha); + else + { + dviwidth = 0; /* keep compiler happy, if necessary */ + + StartText (); + ResetVDU (); /* let message stay */ + + FATAL1 ("Bad TFM width! 1st byte = %d.", b0); + } + + return dviwidth; +} +/* FixToDVI */ + +/*--------------------------------------------------------------------*/ + +#define pkid 89 +#define pkpost 245 +#define pknoop 246 +#define pkpre 247 + +static void +PKFillPixelTable (fontinfo * currfont) +{ + /* Fill the pixeltable for currfont^ using the font directory info + in the currently open PK file. + */ + + int i, j, flagbyte, flagpos; + int chcode; /* char. code, assumed to be <= maxTeXchar */ + int packetlen, endofpacket, b0, b1, b2, b3; /* 4 bytes in TFM width */ + _REC_pixeltable *pix_tab; + + PToffset = 0; /* move to first byte */ + + if (GetPTByte () != pkpre) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL1 ("Bad PK pre command in `%s'.", currfont->fontspec); + } + if (GetPTByte () != pkid) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL1 ("Bad PK id byte in `%s'.", currfont->fontspec); + } + j = GetPTByte (); /* length of comment */ + PToffset += j + 16; /* skip rest of preamble */ + + for (i = 0; i <= maxTeXchar; i++) + { + pix_tab = &currfont->pixelptr[i]; + pix_tab->mapadr = 0; /* all chars absent initially */ + pix_tab->bitmap.UU.mptr = (Word *) NULL; + } + + while (true) + { + flagpos = PToffset; /* remember position of flagbyte */ + flagbyte = GetPTByte (); + if (flagbyte < 240) + { /* read character definition */ + + int scale = currfont->scaledsize; /* For FixToDVI */ + + flagbyte &= 7; /* value of bottom 3 bits */ + if (flagbyte < 4) + { /* short char preamble */ + packetlen = flagbyte * 256 + GetPTByte (); + chcode = GetPTByte (); + endofpacket = packetlen + PToffset; + pix_tab = &currfont->pixelptr[chcode]; + b1 = GetPTByte (); + b2 = GetPTByte (); + b3 = GetPTByte (); + pix_tab->dwidth = FixToDVI (scale, 0, b1, b2, b3); /* b0 = 0 */ + pix_tab->pwidth = GetPTByte (); + pix_tab->wd = GetPTByte (); + pix_tab->ht = GetPTByte (); + pix_tab->xo = SignedPTByte (); + pix_tab->yo = SignedPTByte (); + } + else if (flagbyte < 7) + { + packetlen = (flagbyte - 4) * 65536 + GetTwoPTBytes (); + chcode = GetPTByte (); + endofpacket = packetlen + PToffset; + pix_tab = &currfont->pixelptr[chcode]; + b1 = GetPTByte (); + b2 = GetPTByte (); + b3 = GetPTByte (); + pix_tab->dwidth = FixToDVI (scale, 0, b1, b2, b3); /* b0 = 0 */ + pix_tab->pwidth = GetTwoPTBytes (); + pix_tab->wd = GetTwoPTBytes (); + pix_tab->ht = GetTwoPTBytes (); + pix_tab->xo = SignedPTPair (); + pix_tab->yo = SignedPTPair (); + } + else + { + packetlen = SignedPTQuad (); + chcode = SignedPTQuad (); + endofpacket = packetlen + PToffset; + pix_tab = &currfont->pixelptr[chcode]; + b0 = GetPTByte (); + b1 = GetPTByte (); + b2 = GetPTByte (); + b3 = GetPTByte (); + pix_tab->dwidth = FixToDVI (scale, b0, b1, b2, b3); + pix_tab->pwidth = SignedPTQuad () / 65536; /* dx in pixels */ + PToffset += 4; /* skip dy */ + pix_tab->wd = SignedPTQuad (); + pix_tab->ht = SignedPTQuad (); + pix_tab->xo = SignedPTQuad (); + pix_tab->yo = SignedPTQuad (); + } + pix_tab = &currfont->pixelptr[chcode]; /* position of flagbyte */ + if (pix_tab->wd == 0 || pix_tab->ht == 0) + pix_tab->mapadr = 0; /* no bitmap */ + else + pix_tab->mapadr = flagpos; + PToffset = endofpacket; /* skip raster info */ + continue; + } + switch (flagbyte) + { + case 240: + case 241: + case 242: + case 243: + i = 0; + for (j = 240; j <= flagbyte; j++) + i = i * 256 + GetPTByte (); + PToffset += i; /* skip special parameter */ + break; + case 244: /* skip numspecial param */ + PToffset += 4; + break; + case pknoop: /* do nothing */ + break; + case pkpost: /* no more char defs */ + goto _L888; + break; + + default: + StartText (); + ResetVDU (); /* let message stay */ + + FATAL1 ("Bad PK flag byte in `%s'.", currfont->fontspec); + } + } /* of LOOP; flagbyte = pkpost */ +_L888:; + + /* extended short char preamble */ + /* long char preamble */ +} +/* PKFillPixelTable */ + +#undef pkid +#undef pkpost +#undef pknoop +#undef pkpre + +/*--------------------------------------------------------------------*/ + +static void +ReadTFMIntegers () +{ + /* Read the first 6 (six) 16-bit integers in the TFM file. */ + /* These give the dimensions of the arrays that constitute the rest */ + /* of the TFM file. */ + /* See TFtoPL section 8. */ + + PToffset = 0; /* start reading at 1st byte in TFM file */ + lf = GetTwoPTBytes (); /* length of TFM file, in words: 0 <= lf < 2^15. */ + lh = GetTwoPTBytes (); /* length of header, in words: 2 <= lh. */ + bc = GetTwoPTBytes (); /* smallest character code in font */ + ec = GetTwoPTBytes (); /* largest character code in font */ + nw = GetTwoPTBytes (); /* number of words in width table */ + nh = GetTwoPTBytes (); /* number of words in height table */ + + /* sanity check of lf */ + if (!(0 <= lf && lf < 1 << 15)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL2 ("TFM file length given as: lf = %d words. Should have 0 <= lf < %d words.", lf, 1 << 15); + } + /* sanity check of lh */ + if (!(2 <= lh)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL1 ("TFM's Header length given as: lh = %d words. Should have lh >= 2 (two) words.", lh); + } + /* sanity check of bc and ec */ + if (!(0 <= bc && bc - 1 <= ec && ec <= maxTeXchar)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL2 ("First & last char codes = (bc, ec) = (%d, %d). Should have 0 <= bc <= ec <= maxTeXchar = 255.", bc, ec); + } + /* sanity check of nw */ + if (!(0 <= nw && nw < 1 << 15)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL2 ("Number of Width Table words given as: nw = %d. Should have 0 <= nw < %d words.", nw, 1 << 15); + } + /* sanity check of nh */ + if (!(0 <= nh && nh < 1 << 15)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL2 ("Number of Height Table words given as: nh = %d. Should have 0 <= nh < %d.", nh, 1 << 15); + } +} +/* ReadTFMIntegers */ + +/*--------------------------------------------------------------------*/ + +static void +ReadTFMCharInfo () +{ + /* Read the TFMinfo array. See TFtoPL section 11. */ + + int c, i; + _REC_TFMinfo *tfm_inf; + + PToffset = (6 + lh) * 4; /* offset of TFMinfo array (in bytes) */ + /* 6 words of dimension info, plus header */ + for (c = bc; c <= ec; c++) + { + tfm_inf = &TFMinfo[c]; + tfm_inf->wdindex = GetPTByte () * 4; /* offset from start of width array */ + i = GetPTByte (); /* 2nd byte contains htindex and dpindex */ + tfm_inf->htindex = i / 16 * 4; /* offset from start of height array */ + tfm_inf->dpindex = (i & 15) * 4; /* offset from start of depth array */ + PToffset += 2; /* skip itindex and remainder bytes */ + } +} +/* ReadTFMCharInfo */ + +/*--------------------------------------------------------------------*/ + +static void +ReadTFMCharMetrics () +{ + /* Read the charmetrics array using the indices in TFMinfo. */ + + int wdbase = lh * 4 + (ec - bc + 1) * 4 + 24; /* offset of width array */ + int htbase = wdbase + nw * 4; /* offset of height array */ + int dpbase = htbase + nh * 4; /* offset of depth array */ + int c; + + for (c = bc; c <= ec; c++) + { + _REC_TFMinfo *tfm_inf = &TFMinfo[c]; + _REC_charmetrics *char_met = &charmetrics[c]; + int b; + + PToffset = wdbase + tfm_inf->wdindex; + for (b = 0; b <= 3; b++) + char_met->width[b] = GetPTByte (); + PToffset = htbase + tfm_inf->htindex; + for (b = 0; b <= 3; b++) + char_met->height[b] = GetPTByte (); + PToffset = dpbase + tfm_inf->dpindex; + for (b = 0; b <= 3; b++) + char_met->depth[b] = GetPTByte (); + } +} +/* ReadTFMCharMetrics */ + +/*--------------------------------------------------------------------*/ + +static void +TFMFillPixelTable (fontinfo * currfont) +{ + /* Fill the pixeltable for * currfont + (a PostScript or other font for which the PK file is missing), + using information in the currently open TFM file. + */ + + int c; + + ReadTFMIntegers (); /* read lf..nh */ + ReadTFMCharInfo (); /* fill TFMinfo array */ + ReadTFMCharMetrics (); /* fill charmetrics array */ + + for (c = 0; c < bc; c++) /* chars < bc don't exist */ + currfont->pixelptr[c].mapadr = 0; + + for (c = ec + 1; c <= maxTeXchar; c++) /* chars > ec don't exist */ + currfont->pixelptr[c].mapadr = 0; + + for (c = bc; c <= ec; c++) + { + _REC_pixeltable *pix_tab = &currfont->pixelptr[c]; + _REC_charmetrics *char_met = &charmetrics[c]; + int scale = currfont->scaledsize; /* For FixToDVI */ + int dheight, pheight, ddepth, pdepth; + + pix_tab->dwidth = FixToDVI (scale, + char_met->width[0], char_met->width[1], + char_met->width[2], char_met->width[3]); + + dheight = FixToDVI (scale, + char_met->height[0], char_met->height[1], + char_met->height[2], char_met->height[3]); + + ddepth = FixToDVI (scale, + char_met->depth[0], char_met->depth[1], + char_met->depth[2], char_met->depth[3]); + + /* convert DVI units to pixels */ + + pix_tab->pwidth = XPixelRound (pix_tab->dwidth); + pheight = YPixelRound (dheight); + pdepth = YPixelRound (ddepth); + + /* Since we don't have access to PK bitmap info, + we will have to use the TFM width/height/depth info + to approximate wd, ht, xo, yo. + */ + + pix_tab->wd = pix_tab->pwidth; + pix_tab->wd -= pix_tab->wd / 8; /* better approximation */ + pix_tab->ht = pheight + pdepth; + pix_tab->xo = 0; + pix_tab->yo = pheight - 1; + if (pix_tab->wd == 0 || pix_tab->ht == 0) /* anything but 0 */ + pix_tab->mapadr = 0; /* char blank or not in font */ + else + pix_tab->mapadr = 1; + pix_tab->bitmap.UU.mptr = (Word *) NULL; + } +} +/* TFMFillPixelTable */ + +/*--------------------------------------------------------------------*/ + + +static void +AbsentFillPixelTable (fontinfo * currfont) +{ + /* Fill the pixeltable for *currfont + * (a PostScript or other font that is missing and cannot be replaced), + * using information in the DVI file, since we have nothing else. + * + * Updated (Wed 9 June 1993) to use cmr10 info., as that is the most + * common font in most present-day documents. + */ + + int c; + + for (c = 0; c <= maxTeXchar; c++) + { + _REC_pixeltable *pix_tab = &currfont->pixelptr[c]; + + /* scaled size of font in DVI units */ + int scale = currfont->scaledsize; /* For character size estimate */ + int dheight, ddepth; /* estimated height and depth, in DVI units */ + int pheight, pdepth; /* same, in pixels */ + + /* Let character be a square, scaledsize high and wide, zero depth. */ + /* For "example.tex", this width and height are not too bad. */ + pix_tab->dwidth = scale / 2; /* wild, hazardous guess */ + dheight = scale; + ddepth = 0; + + /* convert DVI units to pixels */ + pix_tab->pwidth = XPixelRound (pix_tab->dwidth); + pheight = YPixelRound (dheight); + pdepth = YPixelRound (ddepth); + + /* Since we don't have access to PK bitmap or to TFM metric info, + we will have to use the guessed (DVI) width/height/depth info + to approximate wd, ht, xo, yo. + */ + + pix_tab->wd = pix_tab->pwidth; + pix_tab->wd -= pix_tab->wd / 8; /* better approximation */ + pix_tab->ht = pheight + pdepth; + pix_tab->xo = 0; + pix_tab->yo = pheight - 1; + if (pix_tab->wd == 0 || pix_tab->ht == 0) /* anything but 0 */ + pix_tab->mapadr = 0; /* char blank or not in font */ + else + pix_tab->mapadr = 1; + pix_tab->bitmap.UU.mptr = (Word *) NULL; + } +} +/* AbsentFillPixelTable */ + +/*--------------------------------------------------------------------*/ + +void +PixelTableRoutine (fontinfo * currfont) +{ + /* DVIReader has just allocated a new pixeltable for currfont, and + calls this routine from InterpretPage only ONCE per font + (the first time the font is used). + If this is the first time we've seen the font, + then we build fontspec first. + (Note that ShowStatistics, in the main program, may call BuildFontSpec + first.) + If we can't open the font file, we return dummy_pk or dummy_tfm values, + but using the current font's scaledsize. + */ + + if (!CheckFontPtr (currfont)) + return; + + /* Try to find and fopen (& fclose) PK file; if that fails, try TFM file. */ + if (currfont->fontspeclen == 0) + BuildFontSpec (currfont); + + if (currfont->fontexists && !OpenFontFile (currfont->fontspec)) + { + StartText (); + ResetVDU (); /* let message stay */ + + FATAL2 ("fopen-ed but couldn't open file `%s' for font `%s'", + currfont->fontspec, currfont->fontname); + } + /* gt - is this right when a dummy font is used? */ + + if (currfont->fontexists) + { + if (currfont->pkfont) + PKFillPixelTable (currfont); + else + TFMFillPixelTable (currfont); + + CloseFontFile (); + } + else + { + AbsentFillPixelTable (currfont); + } +} +/* PixelTableRoutine */ + +/*--------------------------------------------------------------------*/ + +void +InitFontReader () +{ + /* This routine initializes some global variables. */ + + int i; + + gpower[0] = 0; + for (i = 1; i <= 32; i++) /* used in GetBitmap */ + gpower[i] = gpower[i - 1] | (1 << (i - 1)); +} +/* InitFontReader */ + +/*--------------------------------------------------------------------*/ + +/* end fontreader.c */ diff --git a/dviware/dvgtk/fontreader.h b/dviware/dvgtk/fontreader.h new file mode 100644 index 0000000000..39ed6f9e7b --- /dev/null +++ b/dviware/dvgtk/fontreader.h @@ -0,0 +1,21 @@ +/* fontreader.h - functions for reading PK fonts + $Id: fontreader.h,v 0.2 1997/03/28 03:17:08 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __FONTREADER_H__ +#define __FONTREADER_H__ + +#include "dvgt.h" + +extern void InitFontReader (); +extern void PixelTableRoutine PARAMS ((fontinfo * currfont)); +extern boolean GetBitmap PARAMS ((int ht, int wd, int mapadr, int_or_mptr * bitmap)); +extern boolean BuildFileSpec PARAMS ((const char *areas, const char *name, String spec)); +extern boolean BuildFontSpec PARAMS ((fontinfo * fontptr)); +extern boolean OpenFontFile PARAMS ((char *name)); +extern void CloseFontFile (); + +#endif /* __FONTREADER_H__ */ + +/* end fontreader.h */ diff --git a/dviware/dvgtk/options.c b/dviware/dvgtk/options.c new file mode 100644 index 0000000000..3d660c73af --- /dev/null +++ b/dviware/dvgtk/options.c @@ -0,0 +1,534 @@ +/* options.c - command line arguments processing + $Id: options.c,v 0.2 1997/03/28 03:17:12 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "screenio.h" +#include "options.h" +#include "defaults.h" + +/* Variables Exported, via "options.h" */ + +/* X and Y resolutions, in dpi */ +double xres, yres; + +/* Magnification */ +int mag; + +/* The next four are in paper pixels, and calculated. */ +int hoffset, voffset; +int paperwd, paperht; + +String dummy_pk, dummy_tfm; +String vdu; + +/* DVI file's name */ +string DVIname; + + +typedef struct + { + units unit; + char *name; + double per_inch; + } +Dan; /* `Dimension and name' */ + +static +Dan dans[] = /* `dimensions and names series' */ +{ + {ic, "in", 1.0}, + {cm, "cm", 2.54}, + {mm, "mm", 25.4}, + {bp, "bp", 72.0}, + {pc, "pc", 72.27 / 12}, + {pt, "pt", 72.27}, + {sp, "sp", 72.27 * 65536}, + {px, "px", 300.0} /* "px"'s per_inch value is not used, */ +}; /* but Qume, Laserwriter, etc, are 300 dpi */ + +static +size_t ldans = sizeof (dans) / sizeof (Dan); /* length of dans[] */ + +static int Inint PARAMS ((double f)); + +/*--------------------------------------------------------------------*/ +/* Auxiliary routines */ +/*--------------------------------------------------------------------*/ + +/* Copy at most n characters from ct to s; set s[n] = NUL character. */ +/* This ASSUMES that s has memory >= n+1 characters. */ + +char * +strMcpy (char *s, const char *ct, size_t n) +{ + strncpy (s, ct, n); + s[n] = '\0'; + return s; +} +/* strMcpy */ + +/*--------------------------------------------------------------------*/ + +/* Copy at most maxstring characters from ct to s; */ +/* set s[maxstring] = NUL character. */ + +char * +stringcopy (String s, const char *ct) +{ + strncpy (s, ct, maxstring); + s[maxstring] = '\0'; + return (char *) &s; +} +/* stringcopy */ +/*--------------------------------------------------------------------*/ +static int +Inint (double f) +{ + return ((int) (f + 0.5)); +} +/* Inint */ +/*--------------------------------------------------------------------*/ +static void +ToCardinal (const char *option, const char *value, int *n) +{ + /* If value represents a positive integer, then return via n. */ + + int check; + double r; + + check = sscanf (value, "%lf", &r); + *n = Inint (r); /* round value to nearest integer */ + + /* check can be 1 or EOF if ok! */ + if ((check == 1 || check == EOF) && *n > 0) + return; + + FATAL2 ("Bad `%s' value: %s. Specify a positive integer.", option, value); +} +/* ToCardinal */ + +/*--------------------------------------------------------------------*/ + +static void +ToRes (const char *option, const char *value, double *xr, double *yr) +{ + /* X and Y resolutions, specified in dots per inch. */ + + int check; + + check = sscanf (value, "%lf,%lf", xr, yr); + if (check == 2 && *xr > 0 && *yr > 0) + { + return; + } + else + { + check = sscanf (value, "%lf", xr); + if (check == 1 && *xr > 0) + { + *yr = *xr; + return; + } + } + + FATAL2 ("Bad `%s' value(s): %s.\n" + "Resolutions must be positive reals,\n" + "specified as `-r xres' or `-r xres,yres'\n" + "in dots per inch.", option, value); +} +/* ToRes */ + +/*--------------------------------------------------------------------*/ + +static units +Name2Unit (const char *uname) +{ + units unit = ic; + char Luname[3]; /* Lower case unit name */ + int j; + +#define ToLower(x) (isupper(x) ? tolower(x) : (x)) + + Luname[0] = ToLower (uname[0]); + Luname[1] = ToLower (uname[1]); + Luname[2] = '\0'; + + for (j = 0; j < ldans && strcmp (Luname, dans[j].name); j++); /* Search for the name of the unit. */ + + if (j < ldans) + unit = dans[j].unit; + else + { + MesgString ("Bad unit name `"); + MesgString (uname); + MesgString ("'"); + MesgLine (); + + MesgString ("Last two letters should be one of "); + for (j = 0; j < ldans; j++) + { + MesgString (" `"); + MesgString (dans[j].name); + MesgString ("'"); + } + MesgChar ('.'); + MesgLine (); + + MesgString ("Using inch."); + MesgLine (); + unit = ic; + } + return unit; +} +/* Name2Unit */ + +/*--------------------------------------------------------------------*/ + +static void +ToDimen (const char *option, const char *value, double *r, units *un) +{ + /* A valid dimension consists of an integer or real number followed + by a two-letter unit: see dans[] above. + If value represents a valid dimension, + return number part in r, and units part in un. + */ + + int check; + String nun; /* name of unit - ample space in a string for it */ + + check = sscanf (value, "%lf%2s", r, nun); + if (check == 2) + { + /* extract unit's code from its name */ + *un = Name2Unit (nun); + } + else if (check == 1) + { + MesgString ("No dimension given, using inch."); + MesgLine (); + *un = ic; + } + else + { /* check < 1 */ + FATAL2 ("Bad `%s' value: %s.\nSpecify a dimensioned quantity.", + option, value); + } +} +/* ToDimen */ + +/*--------------------------------------------------------------------*/ + +static void +ToPosDimen (const char *option, const char *value, double *r, units *un) +{ + /* A valid +ve dimension consists of a positive integer or real number + followed by a two-letter unit: see dans[] above. + If value represents a valid dimension, + return numeric part in r, and units part in un. + */ + + ToDimen (option, value, r, un); + + if (*r <= 0) + { + FATAL2 ("Bad `%s' value: %s.\nSpecify a positive dimension.", + option, value); + } +} +/* ToPosDimen */ + +/*--------------------------------------------------------------------*/ + +static int +DimenPixels (double r, units u, double res) +{ + /* Return given dimension as nearest whole number of pixels, */ + /* given the appropriate (eg, X or Y direction's) resolution in dpi. */ + + int Result; + + int i; + + if (u == px) + Result = Inint (r); + else + { + for (i = 0; i < ldans && u != dans[i].unit; i++); /* search for unit */ + + if (i < ldans) + Result = Inint (r / dans[i].per_inch * res); + else + { + MesgString ("Unimplemented unit, treating as inch."); + MesgLine (); + Result = Inint (r * res); + } + } + return Result; +} +/* DimenPixels */ +/*--------------------------------------------------------------------*/ +void +WriteCardinal (char *name, int value) +{ + String outstring; + + sprintf (outstring, "%s= %d", name, value); + MesgString (outstring); + MesgLine (); +} +/* WriteCardinal */ +/*--------------------------------------------------------------------*/ + +void +WriteReal (char *name, double value) +{ + String outstring; + + sprintf (outstring, "%s= %f", name, value); + MesgString (outstring); + MesgLine (); +} + +/* WriteReal */ + +/*--------------------------------------------------------------------*/ + +/* GT - TO BE FINISHED - Write... FUNCTIONS BELOW, TOO! */ +/* Might be better to use a pair of arrays, or array of pairs */ +/* That is, data-driven may be more flexible. */ + +void +NameUnit (units un, String nun) +/* Interface: un (I), *nun (O). */ +{ + int i; + + for (i = 0; i < ldans && un != dans[i].unit; i++); /* Search for unit un. */ + + if (i < ldans) + stringcopy (nun, dans[i].name); + else + { + MesgString ("Unknown unit! Assuming inch."); + MesgLine (); + + stringcopy (nun, "in"); + } +} +/* NameUnit */ + +/*--------------------------------------------------------------------*/ + +void +WriteDimen (char *varname, double r, units un) +{ + String outstring, nun; + + NameUnit (un, nun); + /* !! gt - this line is unsafe, as outstring may overflow! */ + sprintf (outstring, "%s= %f %s", varname, r, nun); + MesgString (outstring); + MesgLine (); +} + +/* WriteDimen */ + +/*--------------------------------------------------------------------*/ + +void +WriteName (char *varname, char *svalue) +{ + String outstring; + + sprintf (outstring, "%s= %s", varname, svalue); + MesgString (outstring); + MesgLine (); +} + +/* WriteName */ + +/*--------------------------------------------------------------------*/ + +double +Unit2Value (units unit) +{ + double per_inch = 1.0; /* 1 unit per inch */ + int j; + + for (j = 0; (j < ldans) && (unit != dans[j].unit); j++); /* Search for the unit. */ + + if (j < ldans) + per_inch = dans[j].per_inch; + else + { + FATAL1 ("Bad unit, enumeration value = %d", unit); + } + return per_inch; +} +/* Unit2Value */ + +/*--------------------------------------------------------------------*/ + +int +InitOptions (int argc, char **argv) +{ + /* Get DVI file, and any options, from the command line. + If an option appears more than once, then we return the last value. + + Actually, proceed in three steps, in increasing priority: + (1) Initialise to default values, as set in "defaults.h". + (2) If the appropriate environment variable is set, use that. + (3) If the appropriate command line option is set, use that. + */ + + char *env; /* environment variable */ + units def_unit = ic; /* default unit is inch */ + units hoffu, voffu, xu, yu; + double hoffr, voffr, xr, yr; + boolean landscape; + int c; + + + /* + (1) DEFAULTS. + initialize option values with defaults; note that the dv script can + set up different defaults [- quoth Andrew Trevorrow, I presume] + - gt observes - no "dv" script provided with DVItoVDU version 3.0! + */ + + /* "dpi" means "dots per inch" */ + /* printer's X and Y resolutions in dpi */ + xres = (double) DEF_XRES; + yres = (double) DEF_YRES; + + /* Page Offsets from Paper edges */ + hoffu = def_unit; + voffu = def_unit; + hoffr = 0.0; /* no margin shifting, so 1" left and top margins */ + voffr = 0.0; + + mag = 0; /* use DVI file's intrinsic magnification */ + + /* + (2) ENVIRONMENT VARIABLES. + */ + + /* Resolution, in dots per inch */ + /* If DV_RES is set in the environment, then try to use that. */ + /* If two real values are in DV_RES, copy them to xres and yres. */ + /* If only one is in DV_RES, copy it to both xres and yres. */ + /* If none is, then ignore DV_RES. */ + + if ((env = getenv ("DV_RES")) != (char *) NULL) + ToRes (" -r", env, &xres, &yres); + +#if 0 + if (!(env = getenv ("DV_TERM"))) + env = getenv ("TERM"); + stringcopy (vdu, !env ? "" : env); +#else + stringcopy (vdu, "tek4010"); +#endif + + /* Paper Width */ + ToPosDimen ("", !(env = getenv ("DV_PAPERWD")) ? DEF_PAPERWD : env, + &xr, &xu); + + /* Paper Height */ + ToPosDimen ("", !(env = getenv ("DV_PAPERHT")) ? DEF_PAPERHT : env, + &yr, &yu); + + /* fall-back PK font */ + stringcopy (dummy_pk, !(env = getenv ("DV_DUMMY_PK")) ? DEF_DUMMY_PK : env); + /* fall-back TFM metric */ + stringcopy (dummy_tfm, !(env = getenv ("DV_DUMMY_TFM")) ? DEF_DUMMY_TFM : env); + /* portrait or landscape page dimensions? */ + landscape = false; /* portrait: don't swap -x and -y values */ + + /* + (3) COMMAND LINE OPTIONS. + */ + + while ((c = getopt (argc, argv, "H:V:d:e:k:lm:r:t:x:y:")) != -1) + { + switch (c) + { + case 0: /* flags already processed */ + break; + + case 'H': + ToDimen (" -H", optarg, &hoffr, &hoffu); + break; + case 'V': + ToDimen (" -V", optarg, &voffr, &voffu); + break; + case 'd': + stringcopy (dummy_pk, optarg); + break; + case 'e': /* gt - not very mnemonic, I know */ + stringcopy (dummy_tfm, optarg); + break; + case 'k': + kpathsea_debug |= atoi (optarg); + break; + case 'l': + landscape = true; + break; + case 'm': + ToCardinal (" -m", optarg, &mag); + case 'r': + /* gt - resolutions should allow non-integer dpi */ + /* - this is because there are such output devices */ + /* - for example, metric printers. */ + /* Get resolutions, specified in dots per inch */ + ToRes (" -r", optarg, &xres, &yres); + break; + case 'v': + stringcopy (vdu, optarg); + break; + case 'x': + ToPosDimen (" -x", optarg, &xr, &xu); + break; + case 'y': + ToPosDimen (" -y", optarg, &yr, &yu); + break; + case '?': /* error message in getopt */ + FATAL ("Exiting"); + default: + FATAL ("Fatal error in getopt"); + } /* switch */ + } + + argv += optind - 1; + argc -= optind - 1; + + if (argc < 2) + { + return 0; + } + + /* bad DVIname will be detected upon open in main module */ + DVIname = extend_filename (argv[1], "dvi"); + + /* set h/voffset and paperwd/ht only after resolutions have been decided */ + hoffset = DimenPixels (hoffr, hoffu, xres); + voffset = DimenPixels (voffr, voffu, yres); + + paperwd = DimenPixels (xr, xu, xres); + paperht = DimenPixels (yr, yu, yres); + + if (landscape) + { /* swap paperwd and paperht */ + int temp = paperwd; + paperwd = paperht; + paperht = temp; + } + return 1; +} + +/* InitOptions */ + +/* end options.c */ diff --git a/dviware/dvgtk/options.h b/dviware/dvgtk/options.h new file mode 100644 index 0000000000..5a8302c05f --- /dev/null +++ b/dviware/dvgtk/options.h @@ -0,0 +1,45 @@ +/* options.h - command line arguments processing + $Id: options.h,v 0.2 1997/03/28 03:17:18 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __OPTIONS_H__ +#define __OPTIONS_H__ + +#include "dvgt.h" + +/* + Units of measure: + inch, centimetre, millimetre, big point, pica, TeX point, + scaled point, paper pixel. + */ + +typedef enum + { + ic, cm, mm, bp, pc, pt, sp, px + } +units; + +extern double xres; /* X resolution in pixels per inch */ +extern double yres; /* Y resolution in pixels per inch */ +extern int mag; /* override DVI mag; 0 = use DVI mag */ +extern int hoffset; /* horizontal margin shift in pixels */ +extern int voffset; /* vertical margin shift in pixels */ +extern int paperwd; /* paper width in pixels */ +extern int paperht; /* paper height in pixels */ +extern String vdu; /* type of terminal */ +extern String dummy_tfm; /* dummy TFM file */ +extern String dummy_pk; /* dummy PK file */ + +extern string DVIname; /* DVI file name */ + + +extern int InitOptions PARAMS ((int argc, char **argv)); +extern int Len PARAMS ((char *str)); +extern char *stringcopy PARAMS ((String s, const char *ct)); +extern char *strMcpy PARAMS ((char *s, const char *ct, size_t maxlen)); +extern void WriteReal PARAMS ((char *name, double value)); + +#endif /* __OPTIONS_H__ */ + +/* end options.h */ diff --git a/dviware/dvgtk/screenio.c b/dviware/dvgtk/screenio.c new file mode 100644 index 0000000000..9a93a36f82 --- /dev/null +++ b/dviware/dvgtk/screenio.c @@ -0,0 +1,483 @@ +/* screenio.c - display functions + $Id: screenio.c,v 0.2 1997/03/28 03:17:23 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "screenio.h" +#include "unixio.h" +#include "vdu.h" + +/* Variables Exported, via "screenio.h" */ + +char TeXtoASCII[XXX]; + + +/* IMPORT InitVDU, ClearScreen, StartText, ClearScreen, ResetVDU. + To handle ^Z suspension properly, ScreenIO needs to use some VDU routines. + */ + +/* SYSDEP: We need to use the Unix write routine. + In particular, using Pascal's write/writeln has some nasty side-effect + that prevents BusyRead from working! + */ + +int textlinewidth; /* text characters (columns) per line */ +int textcolumn = 0; /* column number in current text line */ + +/*--------------------------------------------------------------------*/ + +int +MesgChar (int ch) +{ + int status; + /* maxcol <= both size of a string, and width of a line */ + int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth); + + /* Keep messages within maxcol columns */ + if (textcolumn >= maxcol) + status = EOF; + else + { + status = putchar (ch); + ++textcolumn; + } + return status; +} +/* MesgChar */ + +/*--------------------------------------------------------------------*/ + +int +MesgString (const char *s) +{ + int status; + String message; + /* maxcol <= both size of a string, and width of a line */ + int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth); + + /* Keep messages within maxcol columns */ + if (textcolumn < 0 || textcolumn >= maxcol) + { + strcpy (message, ""); + } + else + { + strncpy (message, s, maxcol - textcolumn); + message[maxcol - textcolumn] = '\0'; + } + + status = fputs (message, stdout); + textcolumn += strlen (message); + return status; +} +/* MesgString */ + +/*--------------------------------------------------------------------*/ + +int +MesgFlush () +{ + int status = fflush (stdout); + textcolumn = 0; + return status; +} +/* MesgFlush */ + +/*--------------------------------------------------------------------*/ + +void +MesgLine () +{ + save_temp_tty (); + rawoutoff (); /* Enable NL to CR+LF mapping */ + /*!!! putchar (CR); *//* SYSDEP: Really an NL */ + putchar ('\r'); /* SYSDEP: Really an NL */ + putchar ('\n'); /* SYSDEP: Really an NL */ + MesgFlush (); /* MesgLine also updates terminal */ + restore_temp_tty (); +} +/* MesgLine */ + +/*--------------------------------------------------------------------*/ + +static int +MesgCard (int c) +{ + /* Since the vast majority of given values will be small numbers, we avoid + recursion until c >= 100. + */ + + int len = 0; + if (c < 10) + { + MesgChar (c + '0'); + ++len; + } + else if (c < 100) + { + MesgChar (c / 10 + '0'); + MesgChar (c % 10 + '0'); + len += 2; + } + else + { /* c >= 100 */ + len += MesgCard (c / 100); /* recursive if c >= 100 */ + c %= 100; + MesgChar (c / 10 + '0'); + MesgChar (c % 10 + '0'); + len += 2; + } + return (len); +} +/* MesgCard */ + +/*--------------------------------------------------------------------*/ + +int +MesgInt (int i) +{ + int len = 0; + if (i < 0) + { + MesgChar ('-'); + ++len; + i = abs (i); + } + len += MesgCard (i); + return (len); +} +/* MesgInt */ + +/*--------------------------------------------------------------------*/ + +void +WriteLine () +{ + WriteChar (CR); + WriteFlush (); /* WriteLine also updates terminal */ +} +/* WriteLine */ + +/*--------------------------------------------------------------------*/ + +static void +WriteCard (int c) +{ + /* Since the vast majority of given values will be small numbers, we avoid + recursion until c >= 100. + */ + + if (c < 10) + { + WriteChar (c + '0'); + return; + } + if (c < 100) + { + WriteChar (c / 10 + '0'); + WriteChar (c % 10 + '0'); + return; + } + else + { + WriteCard (c / 100); /* recursive if c >= 100 */ + c %= 100; + WriteChar (c / 10 + '0'); + WriteChar (c % 10 + '0'); + } +} +/* WriteCard */ + +/*--------------------------------------------------------------------*/ + +void +WriteInt (int i) +{ + if (i < 0) + { + WriteChar ('-'); + i = abs (i); + } + WriteCard (i); +} +/* WriteInt */ + +/*--------------------------------------------------------------------*/ + +static void +Restore_Temp_Terminal () +{ + /* Restore_Temp_Terminal is for screenio.c only. */ + + MesgFlush (); /* make sure terminal is up-to-date */ + restore_temp_tty (); /* restore terminal characteristics saved below */ +} + +/* Restore_Temp_Terminal */ + +/*--------------------------------------------------------------------*/ + +void +RestoreTerminal () +{ + /* RestoreTerminal restores the initial terminal setting. */ + /* It should be called before any client module terminates. */ + MesgFlush (); /* make sure terminal is up-to-date */ + restore_init_tty (); /* restore terminal characteristics saved below */ +} + +/* RestoreTerminal */ + +/*--------------------------------------------------------------------*/ + +void +ReadChar (char *ch) +{ + /* gt - if cbreak's off, turn it on */ + singlecharon (); + /* gt - if echo's on, turn it off */ + echooff (); + + /* gt - at this point, we need singlechar (cbreak) on and echo off. */ + /* gt - BUT WHY? */ + + /* check for CTRL-C or CTRL-Z */ + + /* Interrupted by user? (CTRL-C) */ + if (sig_flags.intr) + { /* echo ch since echooff has been called */ + /* interrupt */ + sig_flags.intr = 0; /* reset intr flag */ + *ch = CR; /* return to "Command: " prompt level */ + } + else if (sig_flags.tstop) + { /* Suspended by user? (CTRL-Z) */ + /* suspend */ + sig_flags.tstop = 0; /* reset tstop flag */ + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + + singlecharon (); + rawouton (); + echooff (); + + InitVDU (); + StartText (); + ClearScreen (); + + *ch = CR; /* return to Command: level */ + } + else + { + putchar (*ch = getchar ()); + } +} +/* ReadChar */ + +/*--------------------------------------------------------------------*/ + +void +ReadString (char *s) +{ + /* Read a string of characters. + The routine is terminated upon carriage return. + */ + + char ch; + int i; + + singlecharoff (); /* read string in cooked mode */ + rawoutoff (); + echoon (); /* echo characters */ + + for (i = 0; true; i++) + { + if (sig_flags.intr) + { + /* interrupt */ + sig_flags.intr = 0; /* reset intr flag */ + s[0] = '\0'; + break; + } + if (sig_flags.tstop) + { + /* suspend */ + sig_flags.tstop = 0; /* reset tstop flag */ + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + /* singlecharon and echooff are called below */ + + InitVDU (); + StartText (); + ClearScreen (); + + s[0] = '\0'; + break; + } + ch = getchar (); + if (ch == CR) + { + s[i] = '\0'; + break; + } + s[i] = ch; + if (i == maxstring) + { + s[i] = '\0'; + break; + } + } + singlecharon (); /* return to cbreak mode */ + rawouton (); + echooff (); /* and no echo */ +} +/* ReadString */ + +/*--------------------------------------------------------------------*/ + +boolean +BusyRead (char *ch) +{ + /* Return TRUE if ch is waiting in input buffer or if a ^C or ^Z has been + typed. Set ch to CR or the character read (no echo). + If nothing in input buffer, then ch is undefined and we return FALSE. + */ + + if (sig_flags.intr) + { + /* interrupt */ + sig_flags.intr = 0; + *ch = CR; /* main module will return to Command: level */ + return true; + } + if (sig_flags.tstop) + { + /* suspend */ + sig_flags.tstop = 0; + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + /* singlecharon and echooff are called below */ + + InitVDU (); + StartText (); + ClearScreen (); + + *ch = CR; /* after suspend, return to Command: level */ + return true; + } + /* SYSDEP: buffercount assumes singlecharon and echooff have been called */ + + /* gt - check whether singlecharon and echooff have been called */ + + if (cmode_flags.cbreak == 0) + singlecharon (); + + if (cmode_flags.echo == 1) + echooff (); + + if (buffercount () == 0) + return false; + else + { + *ch = getchar (); + return true; + } +} +/* BusyRead */ + +/*--------------------------------------------------------------------*/ + +static void +InitTeXtoASCII () +{ + /* Initialize TeXtoASCII array used in specific ShowChar/Rectangle routines + to map a given TeX char into a similar, displayable ASCII char. + */ + + int i; + + for (i = 0; i <= 0xa; i++) /* Greek letters */ + TeXtoASCII[i] = '?'; + for (i = 0xb; i <= 0xf; i++) /* ligatures */ + TeXtoASCII[i] = '?'; + TeXtoASCII[0x10] = 'i'; /* dotless i */ + TeXtoASCII[0x11] = 'j'; /* dotless j */ + TeXtoASCII[0x12] = '`'; /* grave accent */ + TeXtoASCII[0x13] = '\''; /* acute accent */ + for (i = 0x14; i <= 0x17; i++) /* high accents */ + TeXtoASCII[i] = '~'; + TeXtoASCII[0x18] = ','; /* cedilla */ + for (i = 0x19; i <= 0x20; i++) /* foreigns */ + TeXtoASCII[i] = '?'; + for (i = 0x21; i <= 0x5b; i++) /* same */ + TeXtoASCII[i] = i; + TeXtoASCII[0x5c] = '"'; /* open dble quote */ + TeXtoASCII[0x5d] = ']'; /* same */ + for (i = 0x5e; i <= 0x5f; i++) /* more accents */ + TeXtoASCII[i] = '^'; + for (i = 0x60; i <= 0x7a; i++) /* same */ + TeXtoASCII[i] = i; + for (i = 0x7b; i <= 0x7c; i++) /* en & em dash */ + TeXtoASCII[i] = '-'; + for (i = 0x7d; i <= 0x7f; i++) /* more accents */ + TeXtoASCII[i] = '~'; + for (i = 0x80; i <= 0xff; i++) /* non-ASCII, but 8-bit: 128 to 255 */ + TeXtoASCII[i] = '?'; +} +/* InitTeXtoASCII */ + +/*--------------------------------------------------------------------*/ + +void +InitScreenIO () +{ + InitTeXtoASCII (); + /* We first save the current terminal characteristics. + save_init_tty also calls save_temp_tty, which + sets up ^C/^Z interrupt handlers; see unixio.c. + */ + save_init_tty (); + atexit (RestoreTerminal); + + singlecharon (); /* cbreak mode for ReadChar and BusyRead */ + echooff (); /* no echo for BusyRead */ + rawouton (); + /* was _IOFBF */ +#ifdef SETVBUF_REVERSED + if (setvbuf (stdout, _IONBF, NULL, BUFSIZ / 4) != 0) + { +#else + if (setvbuf (stdout, NULL, _IONBF, BUFSIZ / 4) != 0) + { +#endif + MesgString ("screenio.c: InitScreenIO: setvbuf failed!"); + MesgLine (); + } +} +/* InitScreenIO */ + +/*--------------------------------------------------------------------*/ + +/* end screenio.c */ diff --git a/dviware/dvgtk/screenio.h b/dviware/dvgtk/screenio.h new file mode 100644 index 0000000000..4a4b643e77 --- /dev/null +++ b/dviware/dvgtk/screenio.h @@ -0,0 +1,73 @@ +/* screenio.h - display functions + $Id: screenio.h,v 0.2 1997/03/28 03:17:29 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef __SCREENIO_H__ +#define __SCREENIO_H__ + +#include "dvgt.h" + +/* 0 = success, 1 = error */ +/* These terminal i/o routines are highly system-dependent and have been + designed for DVItoVDU and its auxiliary modules. + + Notes: + - InitScreenIO saves the current tty characteristics, + then sets the mode to cbreak with no echo. + Clients should therefore call RestoreTerminal before terminating. + - WriteFlush or WriteLine must be called to explicitly update the terminal + (e.g., just before a read) or to synchronize output with writes + from other modules that don't use ScreenIO. + - WriteString assumes the end of a string is the first blank (if not full), + so clients need to replace calls like WriteString('xxx = ') with + WriteString('xxx ='); WriteChar(' '). + */ + +#define CR '\n' /* SYSDEP: char read upon hitting Return key */ +#define CTRLC '\0' /* SYSDEP: interrupt, see unixio */ +#define CTRLZ '\001' /* SYSDEP: suspend, see unixio */ +/* SYSDEP: unixio puts CTRLC and CTRLZ into input buffer (along with CR) + upon getting a ^C or ^Z interrupt. + (It can't put chr(3) and chr(26) into buffer + because tty will detect another interrupt and we'll loop forever!) + */ +#define NUL '\0' +#define FF '\f' +#define CAN '\030' +#define ESC '\033' +#define FS '\034' +#define GS '\035' +#define US '\037' +#define XXX 256 + + +extern int textlinewidth; /* text characters (columns) per line */ +extern int textcolumn; /* column in current text line */ + +extern char TeXtoASCII[XXX]; /* TeX char to ASCII char */ + + +extern void InitScreenIO (); +extern void ReadChar PARAMS ((char *ch)); +extern void ReadString PARAMS ((char *s)); +extern boolean BusyRead PARAMS ((char *ch)); +extern void WriteInt PARAMS ((int i)); +extern void WriteLine (); + +#define WriteChar(X) putchar(X) +#define WriteString(X) fputs(X, stdout) +#define WriteFlush() fflush(stdout) + +extern int MesgInt PARAMS ((int i)); +extern void MesgLine (); + +extern int MesgChar PARAMS ((int ch)); +extern int MesgString PARAMS ((const char *s)); +extern int MesgFlush (); + +extern void RestoreTerminal (); + +#endif /* __SCREENIO_H__ */ + +/* end screenio.h */ diff --git a/dviware/dvgtk/stamp-auto b/dviware/dvgtk/stamp-auto new file mode 100644 index 0000000000..21ec1ed1b4 --- /dev/null +++ b/dviware/dvgtk/stamp-auto @@ -0,0 +1 @@ +Thu Mar 27 22:21:43 EST 1997 diff --git a/dviware/dvgtk/stamp-auto.in b/dviware/dvgtk/stamp-auto.in new file mode 100644 index 0000000000..15e135c4d9 --- /dev/null +++ b/dviware/dvgtk/stamp-auto.in @@ -0,0 +1 @@ +Thu Mar 27 22:21:42 EST 1997 diff --git a/dviware/dvgtk/unixio.c b/dviware/dvgtk/unixio.c new file mode 100644 index 0000000000..3c54a8a8f9 --- /dev/null +++ b/dviware/dvgtk/unixio.c @@ -0,0 +1,357 @@ +/* unixio.c - Unix terminal and signal handling + $Id: unixio.c,v 0.2 1997/03/28 03:17:33 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "unixio.h" +#include "screenio.h" /* for MesgString, MesgLine */ + +/* Set DV_FD (ioctl file descriptor) to 0 or 1 ? */ +#define DV_FD STDIN_FILENO + +sig_flags_t sig_flags; +cmode_flags_t cmode_flags; + +/* Alex Dickinson + Procedures for setting and resetting UNIX tty characteristics. + Interesting functions are: + save_init_tty; + restore_init_tty; + save_temp_tty; + restore_temp_tty; + echoon; + echooff; + singlecharon; + singlecharoff; + buffercount; + suspend; + A side effect of calling save_temp_tty is to set up signal handling + to reset the terminal characteristics appropriately for the various + interrupt signals. + */ + +/***************************************************************** +* terminal handling +*/ + +#if defined(HAVE_TERMIO_H) +#include +#include +#define TERMIO +#ifdef NCC +#define MAXCC NCC +#else +#define MAXCC 256 +#endif +#define DV_GTTY TCGETA +#define DV_STTY TCSETAW +typedef struct termio dv_tty; +unsigned char saved_cc[NCC]; +#else +#include +#define DV_GTTY TIOCGETP +#define DV_STTY TIOCSETN +typedef struct sgttyb dv_tty; +#endif /* TERMIOS || TERMIO */ + +#include +#include + +static dv_tty init_tty_state; /* store initial terminal characteristics */ +static dv_tty temp_tty_state; /* current terminal characteristics */ + +/* locally defined and used functions and data */ + +static void setsignals (); +static void reportio PARAMS ((int iostat)); +static int iostatus; /* return status of ioctl system function */ + +static void +reportio (int iostat) +{ + if (iostat < 0) + { /* an ioctl error */ + char *str = ""; + String cstr; + switch (errno) + { + /* generic errors */ +#ifdef EBADF + case EBADF: + str = "Not a valid, open, file descriptor!"; + break; +#endif +#ifdef EINTR + case EINTR: + str = "Signal caught."; + break; +#endif +#ifdef ENOTTY + case ENOTTY: + str = "No device driver, or doesn't accept control functions!"; + break; +#endif + /* specialised errors */ +#ifdef EFAULT + case EFAULT: + str = "Illegal data transfer address!"; + break; +#endif +#ifdef EINVAL + case EINVAL: + str = "Driver ignorant of this request or arg!"; + break; +#endif +#ifdef EIO + case EIO: + str = "Physical I/O error!"; + break; +#endif +#ifdef ENOLINK + case ENOLINK: + str = "Remote machine link no longer active!"; + break; +#endif +#ifdef ENXIO + case ENXIO: + str = "Subdevice cannot perform requested service!"; + break; +#endif + /* gt - should be ample space in cstr. */ + default: + sprintf (cstr, "Unknown error %d !", errno); + str = cstr; + break; + } + MesgString ("ioctl: "); + MesgString (str); + MesgLine (); + } +} /* reportio */ + +void +save_init_tty () +{ + /* Save the original tty characteristics and set up the signalling. */ + save_temp_tty (); + init_tty_state = temp_tty_state; +} /* save_init_tty */ + +void +restore_init_tty () +{ + /* Restore the original tty characteristics. */ + temp_tty_state = init_tty_state; + restore_temp_tty (); +} /* restore_init_tty */ + +void +save_temp_tty () +{ + /* Save the current tty characteristics and set up the signalling. */ + iostatus = ioctl (DV_FD, DV_GTTY, &temp_tty_state); + reportio (iostatus); + setsignals (); +} /* save_temp_tty */ + +void +restore_temp_tty () +{ + /* Restore the recent tty characteristics. */ + iostatus = ioctl (DV_FD, DV_STTY, &temp_tty_state); + reportio (iostatus); +} /* restore_temp_tty */ + +void +singlecharon () +{ + /* Set driver to read characters as they are typed without waiting for a + terminator. Echo remains unchanged. */ + dv_tty s; + + if (cmode_flags.cbreak != 1) + { + reportio (ioctl (DV_FD, DV_GTTY, &s)); +#ifndef TERMIO + s.sg_flags |= CBREAK; +#else /* TERMIO */ + saved_cc[VEOL] = s.c_cc[VEOL]; + saved_cc[VEOF] = s.c_cc[VEOF]; + s.c_lflag &= ~ICANON; /* Disable erase/kill processing */ + s.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */ + s.c_cc[VTIME] = 0; /* no matter how long that takes. */ +#endif /* TERMIO */ + reportio (ioctl (DV_FD, DV_STTY, &s)); +#ifdef FLUSH_STDIN + fflush (stdin); +#endif /* FLUSH_STDIN */ + + cmode_flags.cbreak = 1; + } +} /* singlecharon */ + +void +singlecharoff () +{ + /* Turn off single character read mode. */ + dv_tty s; + + if (cmode_flags.cbreak != 0) + { + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifndef TERMIO + s.sg_flags &= ~CBREAK; +#else /* TERMIO */ + s.c_lflag |= ICANON; /* Enable erase/kill processing */ + s.c_cc[VEOL] = saved_cc[VEOL]; + s.c_cc[VEOF] = saved_cc[VEOF]; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.cbreak = 0; + } +} /* singlecharoff */ + +void +echoon () +{ + /* Turn character echoing on. */ + dv_tty s; + + reportio (ioctl (DV_FD, DV_GTTY, &s)); +#ifndef TERMIO + s.sg_flags |= ECHO; +#else /* TERMIO */ + s.c_lflag |= ECHO; +#endif /* TERMIO */ + reportio (ioctl (DV_FD, DV_STTY, &s)); + cmode_flags.echo = 1; +} /* echoon */ + +void +echooff () +{ + /* Turn character echoing off. */ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifndef TERMIO + s.sg_flags &= ~ECHO; +#else /* TERMIO */ + s.c_lflag &= ~ECHO; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + cmode_flags.echo = 0; +} /* echooff */ + +void +rawouton () +{ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifdef TERMIO + s.c_oflag &= ~OPOST; /* Disables tab interpretation etc. */ +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.raw = 1; +} /* rawouton */ + +void +rawoutoff () +{ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifdef TERMIO /* TERMIO */ + s.c_oflag |= OPOST; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.raw = 0; +} /* rawoutoff */ + +int +buffercount () +{ + /* Return true if there are any characters currently in the input buffer. */ +#ifndef TERMIO + long count; + iostatus = ioctl (DV_FD, FIONREAD, &count); + reportio (iostatus); + return (count > 0); +#else /* TERMIO */ + int c, flags, ret; + + /* Save the current fcntl flags and make reads return without waiting */ + flags = fcntl (0, F_GETFL, 0); + fcntl (0, F_SETFL, flags | O_NDELAY); /* This might be SysV specific */ + if ((c = getchar ()) != EOF) + { + ungetc (c, stdin); + ret = 1; + } + else + { + ret = 0; + } + fcntl (0, F_SETFL, flags); /* This might be SysV specific */ + return ret; +#endif /* TERMIO */ +} /* buffercount */ + +RETSIGTYPE +handleint (int sig) +{ + /* Catch signals from tty. + If sig is an interrupt, set the intr flag, + Otherwise it was a suspend, so set the tstop flag. */ + fflush (stdin); + if (sig == SIGINT) + { + sig_flags.intr = 1; + } + else + { + sig_flags.tstop = 1; + } +#ifdef TERMIO /* TERMIO */ + setsignals (); /* Because SysV forgets its handlers */ +#endif /* TERMIO */ +} /* handleint */ + +static void +setsignals () +{ + /* Signal initialization. */ + signal (SIGINT, handleint); +#ifndef TERMIO + signal (SIGTSTP, handleint); +#endif /* TERMIO */ +} /* setsignals */ + +void +suspend () +{ + /* Suspend the process */ +#ifndef TERMIO + signal (SIGTSTP, SIG_DFL); + kill (0, SIGTSTP); + /* resumed again, goody! */ + setsignals (); +#else + /* don't know what to do */ +#endif /* TERMIO */ +} /* suspend */ + +#undef IN_UNIXIO_C diff --git a/dviware/dvgtk/unixio.h b/dviware/dvgtk/unixio.h new file mode 100644 index 0000000000..8d379765f6 --- /dev/null +++ b/dviware/dvgtk/unixio.h @@ -0,0 +1,44 @@ +/* unixio.h - Unix terminal and signal handling + $Id: unixio.h,v 0.2 1997/03/28 03:17:40 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef UNIXIO_H +#define UNIXIO_H + +#include "dvgt.h" + +typedef struct + { + unsigned int intr, tstop:1; + } +sig_flags_t; +typedef struct + { + unsigned int cbreak, raw, echo:1; + } +cmode_flags_t; + +extern sig_flags_t sig_flags; +extern cmode_flags_t cmode_flags; + +/* Alex Dickinson */ +/* Definitions for some unix ioctl calls. These external procedures */ +/* refer to the C functions contained in unixio.c. */ + +extern void save_init_tty (); +extern void restore_init_tty (); +extern void save_temp_tty (); +extern void restore_temp_tty (); +extern void singlecharon (); +extern void singlecharoff (); +extern void echoon (); +extern void echooff (); +extern void rawouton (); +extern void rawoutoff (); +extern int buffercount (); +extern void suspend (); + +#endif /* UNIXIO_H */ + +/* end unixio.h */ diff --git a/dviware/dvgtk/vdu.c b/dviware/dvgtk/vdu.c new file mode 100644 index 0000000000..c338ca7249 --- /dev/null +++ b/dviware/dvgtk/vdu.c @@ -0,0 +1,547 @@ +/* vdu.c - VDU driver interface + $Id: vdu.c,v 0.2 1997/03/28 03:17:44 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "vdu.h" +#include "options.h" +#include "screenio.h" + +/* Exported via "vdu.h" */ + +boolean vdu_clears_lines; /* Can current VDU clear a single line? */ + +int maxy, lineht, dragdown; +boolean havesentxy; + +static int oldhiy; /* for remembering old address in SendXY */ +static int oldhix, oldloy, charwidth; + /* set by LoadFont and used in ShowChar */ + +static int loadedsize; +/* remember alpha size set by last TEK4010LoadFont; + VT640, VIS500/550 VDUs don't actually need to worry about this, + since they use non-TEK4010 fonts to draw in dialogue region. + VIS240, however, uses alpha mode font. */ + +static int charsize; /* used to select alpha character size */ + + +/*--------------------------------------------------------------------*/ + +static void +Graphic () +{ + WriteChar (GS); /* switch to graphics mode */ +} + +/* Graphic */ + +/*--------------------------------------------------------------------*/ + +static void +Alpha () +{ + WriteChar (US); /* switch to alphanumeric mode */ +} + +/* Alpha */ + +/*--------------------------------------------------------------------*/ + +void +SendXY (int x, int y) +{ + /* Translates the given screen address into 4 bytes. + havesentxy is used to minimize the number of bytes sent: after the first + 4 bytes have been sent, subsequent bytes that don't change need not be sent + (except for the low x byte which is always sent). + If the high x byte changes then the low y byte must also be sent. + */ + + int hiy, loy, hix, lox; + boolean sendhix; + + /* we assume y is in [0..maxy] and x is in [0..1023] */ + hiy = y / 32 + ' '; + hix = x / 32 + ' '; + loy = (y & 31) + '`'; + lox = (x & 31) + '@'; + if (havesentxy) + { + if (hiy != oldhiy) + { + WriteChar (hiy); + oldhiy = hiy; + } + sendhix = (hix != oldhix); + if (loy != oldloy || sendhix) + { + WriteChar (loy); + oldloy = loy; + } + if (sendhix) + { + WriteChar (hix); + oldhix = hix; + } + WriteChar (lox); + } + else + { + /* + SYSDEP: We _assume_ XON/XOFF flow control is _enabled_, + to avoid data loss. + */ + WriteChar (hiy); + oldhiy = hiy; + WriteChar (loy); + oldloy = loy; + WriteChar (hix); + oldhix = hix; + WriteChar (lox); + havesentxy = true; + /* send first 4 bytes */ + } +} +/* SendXY */ + +/*--------------------------------------------------------------------*/ +void +ClearTextLine (int line) +{ + /* Do nothing as NCSA Telnet (version 2.3.0.3) can only clear + the entire screen in tek4010 and NOT just a line. + Live with the overwriting. In any case, + the next DisplayPage will clear and rewrite the status lines. + */ +} +/* ClearTextLine */ + +/*--------------------------------------------------------------------*/ + +void +ResetVDU () +{ + WriteChar (CAN); + WriteChar (CAN); +} +/* ResetVDU */ +/*--------------------------------------------------------------------*/ + +void +StartText () +{ + Alpha (); +} +/* StartText */ + +/*--------------------------------------------------------------------*/ + +void +MoveToTextLine (int line) +{ + /* Move cursor to start of given line using lineht. + At the end of this routine we must be in alpha mode, + and ready to display characters in the default charsize. + */ + + Graphic (); + + SendXY (0, maxy - line * lineht + 1); + textcolumn = 0; + + WriteChar (ESC); /* reset alpha character size */ + WriteChar ('0'); + charsize = 0; + charwidth = 13; + + Alpha (); /* back to alpha mode */ +} + +/* MoveToTextLine */ + +/*--------------------------------------------------------------------*/ + +void +ClearScreen () +{ +#ifdef NCSA_TELNET + WriteChar (ESC); + WriteChar (FF); /* erase graphics and put in alpha mode */ +#endif + + Graphic (); + + WriteChar (ESC); /* erase graphics and put in alpha mode */ + WriteChar (FF); + + havesentxy = false; /* ESC FF will home cursor */ + charsize = 0; /* ESC FF resets character size */ + charwidth = 13; +} + +/* ClearScreen */ + +/*--------------------------------------------------------------------*/ + +void +StartGraphics () +{ + if (charsize != loadedsize) + { /* graphics mode was interrupted */ + charsize = loadedsize; + dragdown = (charsize + 1) * 5; /* used by VIS500/550 ShowChar */ + + Graphic (); + + WriteChar (ESC); + WriteChar (charsize + '0'); /* recall last LoadFont character size */ + } + Graphic (); + + havesentxy = false; /* safer to send all bytes anew */ +} +/* StartGraphics */ + + +/*--------------------------------------------------------------------*/ + +void +LoadFont (char *fontname, int fontsize, double mag, + double hscale, double vscale) +{ + /* Use the given fontsize to select an appropriate character size + (based on horizontal scaling only!) for future TEK4010ShowChar calls. + */ + + int newsize; + + /* convert fontsize into scaled screen pixels using mag and hscale */ + fontsize = (int) (fontsize * mag * hscale + 0.5); + /* Choose one of the 4 alpha mode character sizes based on fontsize: + charsize max chars/line relative size fontsize range + 0 80 x1 0..40 + 1 40 x2 41..80 + 2 26 x3 81..120 + 3 20 x4 121... + The fontsize ranges were chosen by trial and error. + */ + if (fontsize < 41) + { + newsize = 0; + charwidth = 13; /* 1024/80 = 12.8 */ + } + else if (fontsize < 81) + { + newsize = 1; + charwidth = 26; /* 1024/40 = 25.6 */ + } + else if (fontsize < 121) + { + newsize = 2; + charwidth = 40; /* 1024/26 = 39.4 */ + } + else + { + newsize = 3; + charwidth = 52; /* 1024/20 = 51.2 */ + } + loadedsize = newsize; /* remember in case graphics mode is interrupted */ + if (charsize != newsize) + { /* change character size */ + charsize = newsize; + WriteChar (ESC); + WriteChar (charsize + '0'); + } + /* Alpha character reference pts on some emulating VDUs (VIS500/550) + are below baselines to allow for descenders. + Such VDUs can use dragdown to drag baselines down to TeX reference pts + when calling TEK4010ShowChar. + */ + dragdown = (charsize + 1) * 5; /* used by VIS500/550 TEK4010ShowChar */ + + Graphic (); /* must return from LoadFont in graphics mode */ +} +/* LoadFont */ + +/*--------------------------------------------------------------------*/ + +void +ShowChar (int screenh, int screenv, char ch) +{ + /* Show the given Terse character (mapped to ASCII) at the given ref pt. + We use the charwidth set by last TEK4010LoadFont call. + */ + + char newch; /* = TeXtoASCII[ch] */ + + /* shift character left if it will overlap right edge of screen */ + + if (screenh + charwidth > 1023) + screenh = 1023 - charwidth; + + /* We no longer _assume_ TEK4010StartGraphics, TEK4010LoadFont, + or last TEK4010ShowChar has just sent GS */ + + Graphic (); + SendXY (screenh, maxy - screenv); /* move cursor to ref pt */ + Alpha (); /* enter alpha mode */ + + /* We use TeXtoASCII to map ch into a comparable ASCII character, apart + from most of the ? characters which we attempt to simulate. + */ + + newch = TeXtoASCII[ch - NUL]; + if (newch != '?') + { + /* newch is similar to TeX ch */ + WriteChar (newch); + } + else + { + /* attempt to display something other than ? */ + switch (ch) + { + case 0xb: /* ff, fi, fl, ffi, ffl */ + case 0xc: + case 0xd: + case 0xe: + case 0xf: + WriteChar ('f'); + /* only simulate rest of ligature if room at right edge */ + if (screenh + charwidth * 2 <= 1023) + { + Graphic (); + SendXY (screenh + charwidth, maxy - screenv); + Alpha (); + + switch (ch) + { + case 0xb: /* ff */ + WriteChar ('f'); + break; + + case 0xc: /* fi */ + WriteChar ('i'); + break; + + case 0xd: /* fl */ + WriteChar ('l'); + break; + + case 0xe: + case 0xf: + WriteChar ('f'); + /* only simulate rest of ligature if room at right edge */ + if (screenh + charwidth * 3 <= 1023) + { + Graphic (); + SendXY (screenh + charwidth * 2, maxy - screenv); + Alpha (); + + if (ch == 0xe) /* ffi */ + WriteChar ('i'); + else /* if (ch == 0xf) */ + /* ffl */ + WriteChar ('l'); + } /* fi */ + break; + } /* switch */ + } /* fi */ + break; + case 0x19: /* German sharp S */ + WriteChar ('B'); + break; + case 0x1a: /* diphthongs: ae, oe, AE, OE */ + case 0x1b: + case 0x1d: + case 0x1e: + switch (ch) + { + case 0x1a: /* ae */ + WriteChar ('a'); + break; + case 0x1b: /* oe */ + WriteChar ('o'); + break; + case 0x1d: /* AE */ + WriteChar ('A'); + break; + case 0x1e: /* OE */ + WriteChar ('O'); + break; + } + if (screenh + charwidth * 2 <= 1023) + { + Graphic (); + SendXY (screenh + charwidth, maxy - screenv); + Alpha (); + + switch (ch) + { + case 0x1a: /* ae */ + case 0x1b: /* oe */ + WriteChar ('e'); + break; + + case 0x1d: /* AE */ + case 0x1e: /* OE */ + WriteChar ('E'); + break; + } + } + break; + case 0x1c: /* Scandinavian slashed o and O */ + case 0x1f: + switch (ch) + { + case 0x1c: /* o/ */ + WriteChar ('o'); + break; + + case 0x1f: /* O/ */ + WriteChar ('O'); + break; + } + + Graphic (); + SendXY (screenh, maxy - screenv); /* overwrite */ + Alpha (); + + WriteChar ('/'); + break; + case 0x20: /* Polish suppressed l and L */ + WriteChar ('\''); + break; + case '?': /* question mark */ + WriteChar ('?'); + + default: + /* WriteChar ('?'); */ + /* show hexadecimal character code, instead of question mark: */ + WriteChar ('\\'); + /* only simulate rest of ligature if room at right edge */ + if (screenh + charwidth * 3 <= 1023) + { + String outstr; /* ample size */ + + Graphic (); + SendXY (screenh + charwidth * 2, maxy - screenv); + Alpha (); + + sprintf (outstr, "%.2x", ch); + WriteChar (outstr[0]); + WriteChar (outstr[1]); + } + break; + } /* switch */ + } /* fi */ + + Graphic (); /* must return from ShowChar in graphics mode */ +} +/* ShowChar */ + +/*--------------------------------------------------------------------*/ + +void +ShowRectangle (int screenh, int screenv, int width, int height, + char ch) +{ + /* Display the given rectangle + (_without_ using the given black pixel character). + DVItoVDU ensures that the top left position is visible, + and that the given dimensions do not go beyond the window edges. + */ + + int i, endpt; + + /* DVItoVDU ensures width and height > 0 */ + if (height < width) + { + /* show row vectors */ + endpt = screenh + width - 1; + for (i = 0; i < height; i++) + { + Graphic (); + + SendXY (screenh, maxy - screenv - i); /* move cursor to start of row */ + SendXY (endpt, maxy - screenv - i); /* draw vector to end of row */ + } + } + else + { + /* show column vectors */ + endpt = maxy - screenv - height + 1; + for (i = 0; i < width; i++) + { + Graphic (); + + SendXY (screenh + i, maxy - screenv); + /* move cursor to start of column */ + SendXY (screenh + i, endpt); /* draw vector to end of column */ + } + } +} +/* ShowRectangle */ + +/*--------------------------------------------------------------------*/ + +void +InitVDU () +{ + vdu_clears_lines = false; + havesentxy = false; /* for first SendXY call */ + charsize = 0; /* the default character size */ + loadedsize = charsize; /* for first TEK4010StartGraphics call */ + charwidth = 13; /* 1024 / 80 = 12.8 */ + maxy = 779; /* some VDUs may want to change this */ + lineht = 26; /* 30 text lines; 26 * 30 = 780 */ + textlinewidth = 80; /* text characters per line */ + /* The dialog region will be the top 4 text lines in Tek mode: + Line 1 = DVI status line, + Line 2 = window status line, + Line 3 = message line, + Line 4 = command line. + The window region will be text lines 5 to 33 in TEK mode. + gt - in NCSA Telnet in TEK mode on my monitor (Viewsonic 5E VGA), + only 30 lines fit. If we use line 33, it wraps around! + */ + + /* The following line numbers assume NCSA Telnet is in VT100 mode. */ + DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */ + windowstatusl = 2; + messagel = 3; + commandl = 4; +#ifdef VIJAY_BOTTOML + bottoml = 33; /* also number of text lines on screen */ +#else /* according to gt's experience */ + bottoml = 30; /* also number of text lines on screen */ +#endif + + /* The following values assume NCSA Telnet is emulating + a Tektronix 4010. + Note that windowv must be given a value using DVItoVDU's + coordinate scheme, where top left pixel is (0,0). + */ + + /* + Approx. height, in TEK4010 pixels, of 4 text lines, viz. 92 + (i.e. ~ 4 * 780/34), does not work in the case of NCSA Telnet's + Tek mode. Value 115 arrived at by pure trial and error. + */ + windowv = 115; + windowh = 0; + windowht = 780 - windowv; + windowwd = 1024; + + textlinewidth = 72; /* text characters per line - a guess */ + + WriteChar (GS); +} +/* InitTEK4010emu */ + +/*--------------------------------------------------------------------*/ + +/* end vdu.c */ diff --git a/dviware/dvgtk/vdu.h b/dviware/dvgtk/vdu.h new file mode 100644 index 0000000000..431f7c8da0 --- /dev/null +++ b/dviware/dvgtk/vdu.h @@ -0,0 +1,87 @@ +/* vdu.h - VDU driver interface + $Id: vdu.h,v 0.2 1997/03/28 03:14:10 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#ifndef VDU_H +#define VDU_H + +#include "dvgt.h" + +/* VDU implements the screen-driving routines used by DVItoVDU. + InitVDU initializes the parameters for the VDU screen. + After starting up, DVItoVDU breaks the screen into 2 parts: + + 1. The DIALOGUE REGION will consist of the top 4 text lines on the screen. + This region is used to display DVI and window status information, + various kinds of messages and the command prompt. DVItoVDU assumes + text lines on the screen start at 1 and increase downwards. The bottom + text line on the screen is given by the parameter bottoml (also the total + number of text lines). + + 2. The WINDOW REGION is typically the remaining area of the screen and + is used to display some sort of representation of the current DVI page. + The user can move the window over any part of the current page, + or even completely outside the page edges (but only just). + The user can scale the page display by changing the width and height of + the window region; windowwd and windowht are the initial, unscaled + dimensions where one paper pixel equals one screen pixel. + When addressing screen pixels, DVItoVDU assumes the top left pixel + in the screen is at (0,0); horizontal coordinates increase to the right + and vertical coordinates increase down the screen. The top left pixel + in the window region is at (windowh,windowv) in this coordinate scheme. + + The following diagram illustrates the screen coordinate system used by + DVItoVDU and shows what the VDU parameters refer to. + + --> h increases to the right + h,v=(0,0) *------------------------------------------------ + | DVIstatusl | top text line = 1 + | | DIALOGUE REGION windowstatusl | (lines increase + V | messagel | downwards) + | commandl | + v * (windowh,windowv) ----------------------------| --- + increases | | | + down | | | + | | | + | | | + | WINDOW REGION | windowht + | contains windowwd * windowht pixels | | + | | | + | | | + | bottoml | | + ------------------------------------------------- --- + + |------------------ windowwd -------------------| + +*/ + +extern int DVIstatusl; /* DVI status line */ +extern int windowstatusl; /* window status line */ +extern int messagel; /* message line */ +extern int commandl; /* command line */ +extern int bottoml; /* bottom line; also num. of text lines in screen */ + +extern int windowh; /* horizontal coord for window's top left screen pixel */ +extern int windowv; /* vertical coord for window's top left screen pixel */ +extern int windowwd; /* width of window in screen pixels */ +extern int windowht; /* height of window in screen pixels */ + +extern boolean vdu_clears_lines; /* Can current VDU clear a single line? */ + +extern void InitVDU (); +extern void ClearScreen (); + +extern void StartText (); +extern void MoveToTextLine PARAMS ((int line)); +extern void ClearTextLine PARAMS ((int line)); +extern void ClearScreen (); +extern void StartGraphics (); +extern void LoadFont PARAMS ((char *fontname, int fontsize, double mag, double hscale, double vscale)); +extern void ShowChar PARAMS ((int screenh, int screenv, char ch)); +extern void ShowRectangle PARAMS ((int screenh, int screenv, int width, int height, char ch)); +extern void ResetVDU (); + +#endif /* VDU_H */ + +/* end vdu.h */ diff --git a/dviware/dvgtk/web2c-dvgtk.patch b/dviware/dvgtk/web2c-dvgtk.patch new file mode 100644 index 0000000000..a30ba0eeaa --- /dev/null +++ b/dviware/dvgtk/web2c-dvgtk.patch @@ -0,0 +1,55 @@ +*** ../texk-7.0-orig/configure Mon Feb 3 14:22:07 1997 +--- configure Fri Mar 21 19:29:56 1997 +*************** +*** 2111,2117 **** + + + +! subdirs="kpathsea dviljk dvipsk web2c xdvik" + + + trap '' 1 2 15 +--- 2111,2117 ---- + + + +! subdirs="kpathsea dviljk dvipsk web2c xdvik dvgtk" + + + trap '' 1 2 15 +*************** +*** 2434,2440 **** + esac + done + +! for ac_config_dir in kpathsea dviljk dvipsk web2c xdvik; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. +--- 2434,2440 ---- + esac + done + +! for ac_config_dir in kpathsea dviljk dvipsk web2c xdvik dvgtk; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. +*** ../texk-7.0-orig/Makefile.in Fri Feb 7 13:39:38 1997 +--- Makefile.in Fri Mar 21 19:54:31 1997 +*************** +*** 1,7 **** + # Top-level Makefile for kpathsea-using programs. + + # Package subdirectories, the library, and all subdirectories. +! programs = dviljk dvipsk web2c xdvik + kpathsea_dir = kpathsea + all_dirs = $(programs) $(kpathsea_dir) + +--- 1,7 ---- + # Top-level Makefile for kpathsea-using programs. + + # Package subdirectories, the library, and all subdirectories. +! programs = dviljk dvipsk web2c xdvik dvgtk + kpathsea_dir = kpathsea + all_dirs = $(programs) $(kpathsea_dir) + -- cgit v1.2.3