summaryrefslogtreecommitdiff
path: root/dviware/dvgt
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvgt
Initial commit
Diffstat (limited to 'dviware/dvgt')
-rw-r--r--dviware/dvgt/DVGT351.README97
-rw-r--r--dviware/dvgt/Makedist.dvgt85
-rw-r--r--dviware/dvgt/dvgt/CHANGES448
-rw-r--r--dviware/dvgt/dvgt/README426
-rw-r--r--dviware/dvgt/dvgt/TODO36
-rw-r--r--dviware/dvgt/dvgt/doc/Makefile24
-rw-r--r--dviware/dvgt/dvgt/doc/example.tex232
-rw-r--r--dviware/dvgt/dvgt/doc/guidemacs.tex105
-rw-r--r--dviware/dvgt/dvgt/doc/sysguide.tex914
-rw-r--r--dviware/dvgt/dvgt/doc/tripvdu.tex279
-rw-r--r--dviware/dvgt/dvgt/doc/userguide.tex1286
-rw-r--r--dviware/dvgt/dvgt/help/cmd.hlp22
-rw-r--r--dviware/dvgt/dvgt/help/immed.hlp23
-rw-r--r--dviware/dvgt/dvgt/help/options.hlp148
-rw-r--r--dviware/dvgt/dvgt/misc/stdlib.h78
-rw-r--r--dviware/dvgt/dvgt/sane9
-rw-r--r--dviware/dvgt/dvgt/src/Makefile.aix206
-rw-r--r--dviware/dvgt/dvgt/src/Makefile.gcc202
-rw-r--r--dviware/dvgt/dvgt/src/Makefile.sun204
-rw-r--r--dviware/dvgt/dvgt/src/TAGS158
-rw-r--r--dviware/dvgt/dvgt/src/aed512vdu.c527
-rw-r--r--dviware/dvgt/dvgt/src/config.h161
-rw-r--r--dviware/dvgt/dvgt/src/defaults.h27
-rw-r--r--dviware/dvgt/dvgt/src/dv-env25
-rw-r--r--dviware/dvgt/dvgt/src/dvireader.c2247
-rw-r--r--dviware/dvgt/dvgt/src/dvireader.h166
-rw-r--r--dviware/dvgt/dvgt/src/dvitovdu.c4056
-rw-r--r--dviware/dvgt/dvgt/src/files.h20
-rw-r--r--dviware/dvgt/dvgt/src/fontreader.c2002
-rw-r--r--dviware/dvgt/dvgt/src/fontreader.h20
-rw-r--r--dviware/dvgt/dvgt/src/globals.h99
-rw-r--r--dviware/dvgt/dvgt/src/help.h69
-rw-r--r--dviware/dvgt/dvgt/src/lstring.c80
-rw-r--r--dviware/dvgt/dvgt/src/lstring.h48
-rw-r--r--dviware/dvgt/dvgt/src/ncsatelvdu.c126
-rw-r--r--dviware/dvgt/dvgt/src/new.h15
-rw-r--r--dviware/dvgt/dvgt/src/options.c1103
-rw-r--r--dviware/dvgt/dvgt/src/options.h51
-rw-r--r--dviware/dvgt/dvgt/src/regisvdu.c408
-rw-r--r--dviware/dvgt/dvgt/src/regisvdu.h9
-rw-r--r--dviware/dvgt/dvgt/src/screenio.c544
-rw-r--r--dviware/dvgt/dvgt/src/screenio.h71
-rw-r--r--dviware/dvgt/dvgt/src/tek4010emu.c507
-rw-r--r--dviware/dvgt/dvgt/src/tek4010emu.h44
-rw-r--r--dviware/dvgt/dvgt/src/unixio.c364
-rw-r--r--dviware/dvgt/dvgt/src/unixio.h46
-rw-r--r--dviware/dvgt/dvgt/src/vdu.c166
-rw-r--r--dviware/dvgt/dvgt/src/vdu.h85
-rw-r--r--dviware/dvgt/dvgt/src/version.h11
-rw-r--r--dviware/dvgt/dvgt/src/vis240vdu.c29
-rw-r--r--dviware/dvgt/dvgt/src/vis500vdu.c250
-rw-r--r--dviware/dvgt/dvgt/src/vis500vdu.h23
-rw-r--r--dviware/dvgt/dvgt/src/vis550vdu.c128
-rw-r--r--dviware/dvgt/dvgt/src/vis603vdu.c50
-rw-r--r--dviware/dvgt/dvgt/src/vis630vdu.c322
-rw-r--r--dviware/dvgt/dvgt/src/vt100132vdu.c56
-rw-r--r--dviware/dvgt/dvgt/src/vt100vdu.c276
-rw-r--r--dviware/dvgt/dvgt/src/vt100vdu.h33
-rw-r--r--dviware/dvgt/dvgt/src/vt220vdu.c361
-rw-r--r--dviware/dvgt/dvgt/src/vt640vdu.c128
60 files changed, 19735 insertions, 0 deletions
diff --git a/dviware/dvgt/DVGT351.README b/dviware/dvgt/DVGT351.README
new file mode 100644
index 0000000000..b7cac37ce6
--- /dev/null
+++ b/dviware/dvgt/DVGT351.README
@@ -0,0 +1,97 @@
+DVGT351.README (BETA) - 18:18 GMT +10:00 Wed 25 August 1993.
+------------------------------------------------------------
+
+This is a brief overview of dvgt 3.51 beta.
+
+WHAT IS dvgt 3.5?
+-----------------
+
+dvgt 3.5 (version 3 mod 5) is an enhancement (with permission) of
+Andrew Trevorrow's `dvitovdu', a public domain TeX dvi file previewer
+familiar to some Vax/VMS users. Specifically, dvgt is based on
+Andrew's unix version 3.0 of dvitovdu.
+
+dvitovdu was written in Modula-2. dvgt, however, is in ANSI C
+(but old-style C is used if the compiler does not define __STDC__);
+it has been massaged for Sun/OS on a Sun 4, Solaris 2.1 on a Sparc 10,
+and for AIX on an IBM Risc/6000.
+
+Like dvitovdu, dvgt has Terse, Box and Full preview modes. Terse mode
+uses the text mode of the VDU, and is insensitive to zoom. Box mode
+shows the bounding boxes of characters. Full mode gives a graphically
+rendered preview. On non-graphic terminals at low screen
+magnifications, Terse mode is the most useful, but as one zooms in,
+Box and Full modes become more and more accurate.
+
+dvgt issues a help page to new users, and 3.5 gives more information
+when it exits.
+
+dvgt 3.5 tries to open a log file, `dvgt.vlg', to catch messages that
+occur before option parsing is complete. If a DVI file named
+`document.dvi' is to be viewed, dvgt will soon try to open a second
+log file named `document.vlg'; if that fails, `dvgt.vlg' continues to
+be used. If `dvgt.vlg' cannot be opened, then no logfile is written.
+
+Version 3.5 allows the search of multiple directories when seeking
+TFM or PK fonts. Since both AIX and Sun/OS are forms of unix,
+alternative directories are separated by a colon `:' character.
+
+Much larger PK bitmaps can now be handled, as the former fixed-size
+bitmap data structure has been replaced by a call to malloc.
+A side-effect is that small bitmaps are automatically stored
+efficiently.
+
+dvgt now has an enlarged set of environment variables, all prefixed
+with "DV_". For example, DV_TERM can be set independently of the
+normal TERM variable. (A user of 3.4 requested that.)
+
+In version 3.5, many of the commands were altered. See the "help"
+file in the "help" directory for the specifics. A new command,
+control-L, refreshes the screen, though only after the whole command
+line has been parsed. This behavior is typical of dvgt commands, and
+was present in dvitovdu, perhaps for the benefit of slow connections.
+
+dvgt's font search strategy is now to seek a PK font first; in Full
+mode this gives a passably accurate representation of the text. If
+that fails, and the font has a `PostScript prefix' (as per the "-p"
+option), then the TFM is tried and outlines displayed (like Box mode);
+next try is the dummy PK font, then the correct TFM, then the dummy
+TFM. If all else fails, dvgt writes ascii text (as in Terse mode);
+this uses cmr encoding, so it's likely to misidentify characters from
+other fonts.
+
+Earlier versions of dvgt have been used in the USA for English text,
+and in Japan to display text using Japanese fonts. Osaka University
+was recently (April 93) porting it to a DECStation under Ultrix.
+
+The author uses dvgt to preview dvi files remotely, using NCSA Telnet
+or MS-Kermit. Communication protocols are complex - and in Telnet's
+case, incomplete - systems, and use of dvgt may require some
+experimentation to give good results for graphic preview. For NCSA
+Telnet, the "ncsatel" vdu driver appears to give satisfactory results,
+thanks to input from Vijay (vijay@ncst.ernet.in).
+
+WHAT IS dvgt 3.51?
+------------------
+
+Version 3.51 is revision 1 of 3.5, containing bug fixes for non-ANSI
+compilers, and for mixed systems containing an ANSI compiler and a
+non-ANSI library.
+
+There are now separate Makefiles for gcc and Sun's cc.
+
+The PK font environment variable TEXPKS, used by dvips, is now used;
+it takes precedence over the more common PKFONTS.
+
+A Bourne shell script, "sane", is provided, in case dvgt leaves the
+screen messed up. This may be modified, if and as required for the
+local installation.
+
+NOTE: strings are limited to eighty (80) characters; if paths, for
+example, are longer than this, then you may increase the value of
+the constant "maxstring" #defined in the file "src/globals.h".
+
+As the TODO now records, I wish to use dynamic strings for paths in
+a future release.
+
+Geoffrey Tobin
diff --git a/dviware/dvgt/Makedist.dvgt b/dviware/dvgt/Makedist.dvgt
new file mode 100644
index 0000000000..b5bc5a3a95
--- /dev/null
+++ b/dviware/dvgt/Makedist.dvgt
@@ -0,0 +1,85 @@
+# "Makedist.dvgt" - 22:14 GMT +10:00 Fri 20 August 1993 - Geoffrey Tobin.
+# - Makefile for dvgt 3.5 distribution - doc, help, misc and src.
+# - targets: shar, tar, zip.
+# Internet address: ecsgrt@luxor.latrobe.edu.au
+
+# SHELL = /bin/sh
+# SHELL = /bin/csh
+# SHELL = /bin/bash
+
+DOC= \
+dvgt/CHANGES \
+dvgt/README \
+dvgt/TODO \
+dvgt/doc/Makefile \
+dvgt/doc/example.tex \
+dvgt/doc/guidemacs.tex \
+dvgt/doc/sysguide.tex \
+dvgt/doc/tripvdu.tex \
+dvgt/doc/userguide.tex \
+dvgt/help/cmd.hlp \
+dvgt/help/immed.hlp \
+dvgt/help/options.hlp
+
+MISC= \
+dvgt/misc/stdlib.h
+
+SRC= \
+dvgt/src/dv-env \
+dvgt/src/Makefile.aix \
+dvgt/src/Makefile.gcc \
+dvgt/src/Makefile.sun \
+dvgt/src/TAGS \
+dvgt/src/aed512vdu.c \
+dvgt/src/config.h \
+dvgt/src/defaults.h \
+dvgt/src/dvireader.c \
+dvgt/src/dvireader.h \
+dvgt/src/dvitovdu.c \
+dvgt/src/files.h \
+dvgt/src/fontreader.c \
+dvgt/src/fontreader.h \
+dvgt/src/globals.h \
+dvgt/src/help.h \
+dvgt/src/lstring.c \
+dvgt/src/lstring.h \
+dvgt/src/ncsatelvdu.c \
+dvgt/src/new.h \
+dvgt/src/options.c \
+dvgt/src/options.h \
+dvgt/src/regisvdu.c \
+dvgt/src/regisvdu.h \
+dvgt/src/screenio.c \
+dvgt/src/screenio.h \
+dvgt/src/tek4010emu.c \
+dvgt/src/tek4010emu.h \
+dvgt/src/unixio.c \
+dvgt/src/unixio.h \
+dvgt/src/vdu.c \
+dvgt/src/vdu.h \
+dvgt/src/version.h \
+dvgt/src/vis240vdu.c \
+dvgt/src/vis500vdu.c \
+dvgt/src/vis500vdu.h \
+dvgt/src/vis550vdu.c \
+dvgt/src/vis603vdu.c \
+dvgt/src/vis630vdu.c \
+dvgt/src/vt100132vdu.c \
+dvgt/src/vt100vdu.c \
+dvgt/src/vt100vdu.h \
+dvgt/src/vt220vdu.c \
+dvgt/src/vt640vdu.c
+
+SANE = \
+dvgt/sane
+
+DIST= Makedist.dvgt $(DOC) $(MISC) $(SRC) $(SANE)
+
+shar: $(DIST)
+ shar $(DIST) > dvgt.shar
+
+tar: $(DIST)
+ tar -cvf dvgt.tar $(DIST)
+
+zip: $(DIST)
+ zip dvgt $(DIST)
diff --git a/dviware/dvgt/dvgt/CHANGES b/dviware/dvgt/dvgt/CHANGES
new file mode 100644
index 0000000000..3f5acd5c0b
--- /dev/null
+++ b/dviware/dvgt/dvgt/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 `<dvistem>.vlg',
+ where the DVI file is named `<dvistem>.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 <math.h>.
+
+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 <sys/file.h> and #include <sys/types.h> for when
+BSD is true.
+ Also for when BSD is true, added twelve further (non-ANSI style)
+function declarations.
+ Added <sys/types.h> 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 <stddef.h> 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 <sys/file.h> and <sys/types.h> .
+
+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 <string.h>" 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 <stddef.h>, <stdlib.h> and <unistd.h>.
+
+73. - Fri 20 Aug 1993 -
+options.c :
+ PK search now = TEXPKS || PKFONTS || TEXFONTS || DEF_PK_DIR.
+
+74. - Fri 20 Aug 1993 -
+new.h :
+ Deleted <malloc.h> 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/dvgt/dvgt/README b/dviware/dvgt/dvgt/README
new file mode 100644
index 0000000000..3d7c29fbf5
--- /dev/null
+++ b/dviware/dvgt/dvgt/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/dvgt/dvgt/TODO b/dviware/dvgt/dvgt/TODO
new file mode 100644
index 0000000000..5b15511436
--- /dev/null
+++ b/dviware/dvgt/dvgt/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/dvgt/dvgt/doc/Makefile b/dviware/dvgt/dvgt/doc/Makefile
new file mode 100644
index 0000000000..58e0c10bbe
--- /dev/null
+++ b/dviware/dvgt/dvgt/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/dvgt/dvgt/doc/example.tex b/dviware/dvgt/dvgt/doc/example.tex
new file mode 100644
index 0000000000..858ad3b9bb
--- /dev/null
+++ b/dviware/dvgt/dvgt/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/dvgt/dvgt/doc/guidemacs.tex b/dviware/dvgt/dvgt/doc/guidemacs.tex
new file mode 100644
index 0000000000..11f556ae9f
--- /dev/null
+++ b/dviware/dvgt/dvgt/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. |<verbatim horizontal mode text in \tt>|
+%
+% 2. \begintt <optional stuff here>
+% <boxed lines of verbatim text in \tt; | is temporary escape character>
+% \endtt
+%
+% 3. \begindisplay
+% <off-centred display of aligned columns; typical row follows:>
+% |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/dvgt/dvgt/doc/sysguide.tex b/dviware/dvgt/dvgt/doc/sysguide.tex
new file mode 100644
index 0000000000..438f14cefa
--- /dev/null
+++ b/dviware/dvgt/dvgt/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 |<stdlib.h>|\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 <MACRO>|, perhaps at the top
+of the source file, so you can find them easily, write |#define <MACRO>|.
+Here |<MACRO>| 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/dvgt/dvgt/doc/tripvdu.tex b/dviware/dvgt/dvgt/doc/tripvdu.tex
new file mode 100644
index 0000000000..e8b92541e8
--- /dev/null
+++ b/dviware/dvgt/dvgt/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 49
+\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 49 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/dvgt/dvgt/doc/userguide.tex b/dviware/dvgt/dvgt/doc/userguide.tex
new file mode 100644
index 0000000000..f70df582d9
--- /dev/null
+++ b/dviware/dvgt/dvgt/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 |DRZI<z>UL| and
+|DRZO<z>UL|, respectively,
+where |<z>| 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/dvgt/dvgt/help/cmd.hlp b/dviware/dvgt/dvgt/help/cmd.hlp
new file mode 100644
index 0000000000..81883ca596
--- /dev/null
+++ b/dviware/dvgt/dvgt/help/cmd.hlp
@@ -0,0 +1,22 @@
+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
+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 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 current 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 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 centre or by current width if no h
diff --git a/dviware/dvgt/dvgt/help/immed.hlp b/dviware/dvgt/dvgt/help/immed.hlp
new file mode 100644
index 0000000000..acceb2c352
--- /dev/null
+++ b/dviware/dvgt/dvgt/help/immed.hlp
@@ -0,0 +1,23 @@
+dvgt is an interactive TeX page previewer. The program allows you to
+look at TeX-generated DVI files on a variety of commonly available VDUs.
+This is the short help file, "immed.hlp", called if no arguments are given.
+The options help file, "options.hlp", gives more information.
+
+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 ps_prefix] [-r resolution]
+ [-t tfm_directory] [-v vdu] [-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)
+-v vdu (default value = value of TERM) where 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 parameters' default values are system dependent.
+Try "dvgt -f", for example, to find the current default font directory.
diff --git a/dviware/dvgt/dvgt/help/options.hlp b/dviware/dvgt/dvgt/help/options.hlp
new file mode 100644
index 0000000000..e7cfda768e
--- /dev/null
+++ b/dviware/dvgt/dvgt/help/options.hlp
@@ -0,0 +1,148 @@
+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.
+
+-p postscript_font_prefix (default is system dependent;
+ environment: DV_PSPREFIX)
+
+ dvgt will search the TFM search paths for TFM metric files with this
+ prefix. dvgt cannot interpret PostScript, but TFM files for PS fonts
+ will allow dvgt to leave sufficient space for PS font characters,
+ which will then be displayed as filled (Full mode) or outline (Box
+ mode) blocks of that size.
+
+-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/dvgt/dvgt/misc/stdlib.h b/dviware/dvgt/dvgt/misc/stdlib.h
new file mode 100644
index 0000000000..4e204b73a7
--- /dev/null
+++ b/dviware/dvgt/dvgt/misc/stdlib.h
@@ -0,0 +1,78 @@
+/* stdlib.h - 22:18 GMT +10:00 Fri 20 August 1993 - modifier Geoffrey Tobin */
+/* - for Ian Dall's "dv"; adapted for dvgt */
+/* Here is an attempt at defining templates for all the libc.a functions.
+ * It is undoubtedly wrong for most machines!
+ */
+#ifdef __STDC__
+#ifdef stdin
+ extern int ungetc (int, FILE *);
+ extern int fseek (FILE *, long, int);
+ extern void rewind (FILE *);
+ extern long ftell (FILE *);
+ extern int fclose (FILE *);
+ extern int fflush (FILE *);
+ extern int fprintf(FILE *, char *,...);
+#endif /* stdin */
+ extern int abs(int);
+ extern char * memccpy (char *, char *, int, int);
+ extern char * memchr (char *, int, int);
+ extern int memcmp (char *, char *, int);
+ extern char * memcpy (char *, char *, int);
+ extern char * memset (char *, int, int);
+ extern char * memmove (char *, char *, int);
+ extern int rand();
+ extern void srand(unsigned);
+ extern long strtol (char *, char **, int);
+ extern long atol (char *);
+ extern int atoi (char *);
+ extern double strtod (char *, char **);
+ extern double atof (char *);
+ extern double atod (char *);
+ extern void perror (char *);
+ extern int toupper (int);
+ extern int tolower (int);
+ extern int toascii (int);
+ extern int sprintf (char *, char *,...);
+ extern int printf(char *,...);
+ extern void * malloc(unsigned);
+ extern void * realloc(void *, unsigned);
+ extern void * calloc(unsigned, unsigned);
+ extern void free (void *);
+ extern void exit (int);
+#else /* not __STDC__ */
+#ifdef stdin
+ extern int ungetc ();
+ extern int fseek ();
+ extern void rewind ();
+ extern long ftell ();
+ extern int fclose ();
+ extern int fflush ();
+ extern int fprintf();
+#endif /* stdin */
+ extern int abs();
+ extern char * memccpy ();
+ extern char * memchr ();
+ extern int memcmp ();
+ extern char * memcpy ();
+ extern char * memset ();
+ extern char * memmove ();
+ extern int rand();
+ extern void srand();
+ extern long strtol ();
+ extern long atol ();
+ extern int atoi ();
+ extern double strtod ();
+ extern double atof ();
+ extern double atod ();
+ extern void perror ();
+ extern int toupper ();
+ extern int tolower ();
+ extern int toascii ();
+ extern int sprintf ();
+ extern int printf();
+ extern char * malloc();
+ extern char * realloc();
+ extern char * calloc();
+ extern void free ();
+ extern void exit ();
+#endif /* __STDC__ */
diff --git a/dviware/dvgt/dvgt/sane b/dviware/dvgt/dvgt/sane
new file mode 100644
index 0000000000..fd766d1796
--- /dev/null
+++ b/dviware/dvgt/dvgt/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/dvgt/dvgt/src/Makefile.aix b/dviware/dvgt/dvgt/src/Makefile.aix
new file mode 100644
index 0000000000..c36e83d0a4
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/Makefile.aix
@@ -0,0 +1,206 @@
+# Makefile.aix - 19:22 GMT +10:00 Mon 2 Aug 1993 - Geoffrey Tobin.
+# - make dvgt for AIX.
+# - for dvgt 3.5 (DVItoVDU version 3.0, gt modification 5).
+# Compile (without optimization) and link dvgt.
+
+# Targets are all, depend, dvgt, tag and clean.
+
+SHELL = /bin/sh
+.SUFFIXES: .h
+
+# The "xlc" compiler works on the Risc/6000 under AIX that I'm using.
+#
+# CC = gcc # FSF's Gnu C compiler.
+# CC = cc # Default C compiler.
+# CFLAGS = -ansi -Wall -Wformat # for gcc.
+# INC = -I/usr/local/include # Where stdlib.h lives?
+# INC = -I/usr/local/lib/gcc-include # Where gcc's stdlib.h lives?
+# OPT = -O # Optimise - many compilers get this horribly wrong.
+
+CC = xlc # IBM AIX C compiler; very like their "c89".
+CFLAGS =
+DEBUG = -g
+DEFN = -DAIX -D_ALL_SOURCE
+INC =
+LDFLAGS =
+LIB = -lm
+OPT =
+
+USUALS = config.h globals.h
+
+# Other dependencies:
+# <ctype.h>
+# <fcntl.h>
+# <math.h>
+# <stddef.h>
+# <stdio.h>
+# <stdlib.h>
+# <strings.h>
+# <time.h>
+# <unistd.h>
+
+objs = dvireader.o dvitovdu.o fontreader.o lstring.o options.o \
+ screenio.o unixio.o vdu.o
+
+termobjs = \
+ aed512vdu.o \
+ ncsatelvdu.o \
+ regisvdu.o \
+ tek4010emu.o \
+ vis240vdu.o \
+ vis500vdu.o \
+ vis550vdu.o \
+ vis603vdu.o \
+ vis630vdu.o \
+ vt100vdu.o \
+ vt100132vdu.o \
+ vt220vdu.o \
+ vt640vdu.o
+
+objects = $(objs) $(termobjs)
+
+
+srcs = dvireader.c dvitovdu.c fontreader.c lstring.c options.c \
+ screenio.c unixio.c vdu.c
+
+termsrcs = \
+ aed512vdu.c \
+ ncsatelvdu.c \
+ regisvdu.c \
+ tek4010emu.c \
+ vis240vdu.c \
+ vis500vdu.c \
+ vis550vdu.c \
+ vis603vdu.c \
+ vis630vdu.c \
+ vt100vdu.c \
+ vt100132vdu.c \
+ vt220vdu.c \
+ vt640vdu.c
+
+CSRCS = $(srcs) $(termsrcs)
+
+all: dvgt
+
+
+.c.o:
+ $(CC) $(CFLAGS) $(DEBUG) -c $(INC) $(OPT) $(DEFN) $<
+
+
+depend: $(CSRCS)
+ $(CC) -M $(CSRCS) > makedep
+ @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
+ @echo '$$r makedep' >>eddep
+ @echo 'w' >>eddep
+ @cp Makefile Makefile.bak
+ ed - Makefile < eddep
+ @rm -f eddep makedep
+ @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
+ @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
+ @echo '# see make depend above' >> Makefile
+ - diff Makefile Makefile.bak
+ @rm -f Makefile.bak
+
+
+dvgt: $(objects)
+ $(CC) $(LDFLAGS) $(DEBUG) $(objects) $(LIB) -o dvgt
+# Only strip when not DEBUG-ging.
+# strip dvgt
+
+tag:
+ ctags -t -w -f TAGS *.h *.c
+
+clean:
+ rm dvgt core *.o *~ *.vlg
+
+
+# DO NOT DELETE THIS LINE
+
+dvireader.o : dvireader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h options.h screenio.h
+
+dvitovdu.o : dvitovdu.c \
+ $(USUALS) \
+ defaults.h dvireader.h fontreader.h help.h new.h options.h \
+ screenio.h vdu.h version.h
+
+fontreader.o : fontreader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h lstring.h new.h options.h \
+ screenio.h vdu.h
+
+lstring.o : lstring.c \
+ lstring.h new.h
+
+options.o : options.c \
+ $(USUALS) \
+ options.h screenio.h defaults.h
+
+screenio.o : screenio.c \
+ $(USUALS) \
+ screenio.h unixio.h vdu.h
+
+unixio.o : unixio.c \
+ $(USUALS) \
+ screenio.h unixio.h
+
+vdu.o : vdu.c \
+ $(USUALS) \
+ options.h screenio.h vdu.h
+
+aed512vdu.o : aed512vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+ncsatelvdu.o : ncsatelvdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+regisvdu.o : regisvdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+tek4010emu.o : tek4010emu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h
+
+vis240vdu.o : vis240vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vis500vdu.o : vis500vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis550vdu.o : vis550vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+vis603vdu.o : vis603vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis630vdu.o : vis630vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+vt100vdu.o : vt100vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt100132vdu.o : vt100132vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt220vdu.o : vt220vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+vt640vdu.o : vt640vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+# DEPENDENCIES MUST END AT END OF FILE
+# IF YOU PUT STUFF HERE IT WILL GO AWAY
+# see make depend above
diff --git a/dviware/dvgt/dvgt/src/Makefile.gcc b/dviware/dvgt/dvgt/src/Makefile.gcc
new file mode 100644
index 0000000000..97a72e4728
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/Makefile.gcc
@@ -0,0 +1,202 @@
+# Makefile.gcc - 20:56 GMT +10:00 Wed 18 Aug 93 - Geoffrey Tobin.
+# - make dvgt for gcc.
+# Tested on Suns and Sparcs running Sun/OS 4.0.3c and Solaris.
+# - for dvgt 3.51 (DVItoVDU version 3.0, gt modification 5, revision 1).
+# Compile (without optimization) and link dvgt.
+
+# Targets are all, depend, dvgt, tag and clean.
+
+SHELL = /bin/sh
+.SUFFIXES: .h
+
+# INC = -I/usr/local/include # Where stdlib.h lives?
+# INC = -I/usr/local/lib/gcc-include # Where gcc's stdlib.h lives?
+# OPT = -O # Optimise - many compilers get this horribly wrong.
+
+CC = gcc
+CFLAGS = -ansi -Wall -Wformat
+DEBUG = -g
+DEFN =
+INC =
+LDFLAGS =
+LIB = -lm
+OPT =
+
+USUALS = config.h globals.h
+
+# Standard Header dependencies:
+# <ctype.h>
+# <fcntl.h>
+# <math.h>
+# <stddef.h>
+# <stdio.h>
+# <stdlib.h>
+# <strings.h>
+# <time.h>
+# <unistd.h>
+
+objs = dvireader.o dvitovdu.o fontreader.o lstring.o options.o \
+ screenio.o unixio.o vdu.o
+
+termobjs = \
+ aed512vdu.o \
+ ncsatelvdu.o \
+ regisvdu.o \
+ tek4010emu.o \
+ vis240vdu.o \
+ vis500vdu.o \
+ vis550vdu.o \
+ vis603vdu.o \
+ vis630vdu.o \
+ vt100vdu.o \
+ vt100132vdu.o \
+ vt220vdu.o \
+ vt640vdu.o
+
+objects = $(objs) $(termobjs)
+
+
+srcs = dvireader.c dvitovdu.c fontreader.c lstring.c options.c \
+ screenio.c unixio.c vdu.c
+
+termsrcs = \
+ aed512vdu.c \
+ ncsatelvdu.c \
+ regisvdu.c \
+ tek4010emu.c \
+ vis240vdu.c \
+ vis500vdu.c \
+ vis550vdu.c \
+ vis603vdu.c \
+ vis630vdu.c \
+ vt100vdu.c \
+ vt100132vdu.c \
+ vt220vdu.c \
+ vt640vdu.c
+
+CSRCS = $(srcs) $(termsrcs)
+
+all: dvgt
+
+
+.c.o:
+ $(CC) $(CFLAGS) $(DEBUG) -c $(INC) $(OPT) $(DEFN) $<
+
+
+depend: $(CSRCS)
+ $(CC) -M $(CSRCS) > makedep
+ @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
+ @echo '$$r makedep' >>eddep
+ @echo 'w' >>eddep
+ @cp Makefile Makefile.bak
+ ed - Makefile < eddep
+ @rm -f eddep makedep
+ @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
+ @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
+ @echo '# see make depend above' >> Makefile
+ - diff Makefile Makefile.bak
+ @rm -f Makefile.bak
+
+
+dvgt: $(objects)
+ $(CC) $(LDFLAGS) $(DEBUG) $(objects) $(LIB) -o dvgt
+# Only strip when not DEBUG-ging.
+# strip dvgt
+
+tag:
+ ctags -t -w -f TAGS *.h *.c
+
+clean:
+ rm dvgt core *.o *~ *.vlg
+
+
+# DO NOT DELETE THIS LINE
+
+dvireader.o : dvireader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h options.h screenio.h
+
+dvitovdu.o : dvitovdu.c \
+ $(USUALS) \
+ defaults.h dvireader.h fontreader.h help.h new.h options.h \
+ screenio.h vdu.h version.h
+
+fontreader.o : fontreader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h lstring.h new.h options.h \
+ screenio.h vdu.h
+
+lstring.o : lstring.c \
+ lstring.h new.h
+
+options.o : options.c \
+ $(USUALS) \
+ options.h screenio.h defaults.h
+
+screenio.o : screenio.c \
+ $(USUALS) \
+ screenio.h unixio.h vdu.h
+
+unixio.o : unixio.c \
+ $(USUALS) \
+ screenio.h unixio.h
+
+vdu.o : vdu.c \
+ $(USUALS) \
+ options.h screenio.h vdu.h
+
+aed512vdu.o : aed512vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+ncsatelvdu.o : ncsatelvdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+regisvdu.o : regisvdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+tek4010emu.o : tek4010emu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h
+
+vis240vdu.o : vis240vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vis500vdu.o : vis500vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis550vdu.o : vis550vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+vis603vdu.o : vis603vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis630vdu.o : vis630vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+vt100vdu.o : vt100vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt100132vdu.o : vt100132vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt220vdu.o : vt220vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+vt640vdu.o : vt640vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+# DEPENDENCIES MUST END AT END OF FILE
+# IF YOU PUT STUFF HERE IT WILL GO AWAY
+# see make depend above
diff --git a/dviware/dvgt/dvgt/src/Makefile.sun b/dviware/dvgt/dvgt/src/Makefile.sun
new file mode 100644
index 0000000000..d4f56a7507
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/Makefile.sun
@@ -0,0 +1,204 @@
+# Makefile.sun - 20:56 GMT +10:00 Wed 18 Aug 93 - Geoffrey Tobin.
+# - make dvgt for Sun/OS 4.0 's compiler, "cc".
+# Tested on a Sun 4 running Sun/OS 4.0.3c.
+# - for dvgt 3.51 (DVItoVDU version 3.0, gt modification 5, revision 1).
+# Compile (without optimization) and link dvgt.
+
+# Targets are all, depend, dvgt, tag and clean.
+
+SHELL = /bin/sh
+.SUFFIXES: .h
+
+CC = cc # Default C compiler.
+
+# INC = -I/usr/local/include # Where stdlib.h lives?
+# OPT = -O # Optimise - many compilers get this horribly wrong.
+
+# CFLAGS =
+
+DEBUG = -g
+DEFN =
+INC =
+LDFLAGS =
+LIB = -lm
+OPT =
+
+USUALS = config.h globals.h
+
+# Header dependencies:
+# Standard and BSD:
+# <ctype.h>
+# <fcntl.h>
+# <math.h>
+# <stdio.h>
+# <strings.h>
+# <time.h>
+# System:
+# <sys/file.h>
+# <sys/types.h>
+
+objs = dvireader.o dvitovdu.o fontreader.o lstring.o options.o \
+ screenio.o unixio.o vdu.o
+
+termobjs = \
+ aed512vdu.o \
+ ncsatelvdu.o \
+ regisvdu.o \
+ tek4010emu.o \
+ vis240vdu.o \
+ vis500vdu.o \
+ vis550vdu.o \
+ vis603vdu.o \
+ vis630vdu.o \
+ vt100vdu.o \
+ vt100132vdu.o \
+ vt220vdu.o \
+ vt640vdu.o
+
+objects = $(objs) $(termobjs)
+
+
+srcs = dvireader.c dvitovdu.c fontreader.c lstring.c options.c \
+ screenio.c unixio.c vdu.c
+
+termsrcs = \
+ aed512vdu.c \
+ ncsatelvdu.c \
+ regisvdu.c \
+ tek4010emu.c \
+ vis240vdu.c \
+ vis500vdu.c \
+ vis550vdu.c \
+ vis603vdu.c \
+ vis630vdu.c \
+ vt100vdu.c \
+ vt100132vdu.c \
+ vt220vdu.c \
+ vt640vdu.c
+
+CSRCS = $(srcs) $(termsrcs)
+
+all: dvgt
+
+
+.c.o:
+ $(CC) $(CFLAGS) $(DEBUG) -c $(INC) $(OPT) $(DEFN) $<
+
+
+depend: $(CSRCS)
+ $(CC) -M $(CSRCS) > makedep
+ @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
+ @echo '$$r makedep' >>eddep
+ @echo 'w' >>eddep
+ @cp Makefile Makefile.bak
+ ed - Makefile < eddep
+ @rm -f eddep makedep
+ @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
+ @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
+ @echo '# see make depend above' >> Makefile
+ - diff Makefile Makefile.bak
+ @rm -f Makefile.bak
+
+
+dvgt: $(objects)
+ $(CC) $(LDFLAGS) $(DEBUG) $(objects) $(LIB) -o dvgt
+# Only strip when not DEBUG-ging.
+# strip dvgt
+
+tag:
+ ctags -t -w -f TAGS *.h *.c
+
+clean:
+ rm dvgt core *.o *~ *.vlg
+
+
+# DO NOT DELETE THIS LINE
+
+dvireader.o : dvireader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h options.h screenio.h
+
+dvitovdu.o : dvitovdu.c \
+ $(USUALS) \
+ defaults.h dvireader.h fontreader.h help.h new.h options.h \
+ screenio.h vdu.h version.h
+
+fontreader.o : fontreader.c \
+ $(USUALS) \
+ dvireader.h files.h fontreader.h lstring.h new.h options.h \
+ screenio.h vdu.h
+
+lstring.o : lstring.c \
+ lstring.h new.h
+
+options.o : options.c \
+ $(USUALS) \
+ options.h screenio.h defaults.h
+
+screenio.o : screenio.c \
+ $(USUALS) \
+ screenio.h unixio.h vdu.h
+
+unixio.o : unixio.c \
+ $(USUALS) \
+ screenio.h unixio.h
+
+vdu.o : vdu.c \
+ $(USUALS) \
+ options.h screenio.h vdu.h
+
+aed512vdu.o : aed512vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+ncsatelvdu.o : ncsatelvdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+regisvdu.o : regisvdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+tek4010emu.o : tek4010emu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h
+
+vis240vdu.o : vis240vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vis500vdu.o : vis500vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis550vdu.o : vis550vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vis500vdu.h vt100vdu.h
+
+vis603vdu.o : vis603vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h
+
+vis630vdu.o : vis630vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+vt100vdu.o : vt100vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt100132vdu.o : vt100132vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h
+
+vt220vdu.o : vt220vdu.c \
+ $(USUALS) \
+ screenio.h vdu.h vt100vdu.h
+
+vt640vdu.o : vt640vdu.c \
+ $(USUALS) \
+ screenio.h tek4010emu.h vdu.h vt100vdu.h
+
+# DEPENDENCIES MUST END AT END OF FILE
+# IF YOU PUT STUFF HERE IT WILL GO AWAY
+# see make depend above
diff --git a/dviware/dvgt/dvgt/src/TAGS b/dviware/dvgt/dvgt/src/TAGS
new file mode 100644
index 0000000000..2b73dae205
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/TAGS
@@ -0,0 +1,158 @@
+AED512ClearTextLine aed512vdu.c /^Void AED512ClearTextLine(int line)$/
+AED512LoadFont aed512vdu.c /^Void AED512LoadFont(Char *fontname, int fontsize, /
+AED512MoveToTextLine aed512vdu.c /^Void AED512MoveToTextLine(int line)$/
+AED512ShowChar aed512vdu.c /^Void AED512ShowChar(int screenh, int screenv, Char/
+AED512ShowRectangle aed512vdu.c /^Void AED512ShowRectangle(int screenh, int screenv,/
+Aconv dvireader.c /^double Aconv (Axis dir)$/
+Anyptr config.h 78
+Ares dvitovdu.c /^double Ares (Axis dir)$/
+Axis dvireader.h 18
+BuildFontSpec fontreader.c /^Void BuildFontSpec(fontinfo *fontptr)$/
+BuildTFMSpec fontreader.c /^Static Void BuildTFMSpec (fontinfo *fontptr)$/
+BusyRead screenio.c /^boolean BusyRead (Char *ch)$/
+Cap options.c /^Char Cap (Char ch)$/
+CopyArgv options.c /^Static CopyArgv(int n, char *buf)$/
+CurrMatchesNew dvireader.c /^Static boolean CurrMatchesNew (TeXpageinfo *newTeX/
+DVIPageFound dvitovdu.c /^Static boolean DVIPageFound (int n)$/
+Dan options.c 28
+DimenPixels options.c /^Static int DimenPixels (double r, units u, double /
+DoDown dvireader.c /^Static Void DoDown (int amount)$/
+DoFont dvireader.c /^Static Void DoFont (int externf)$/
+DoPutChar dvireader.c /^Static Void DoPutChar (int ch)$/
+DoPutRule dvireader.c /^Static Void DoPutRule (int height, int width)$/
+DoRight dvireader.c /^Static Void DoRight (int amount)$/
+DoSetChar dvireader.c /^Static Void DoSetChar (int ch)$/
+DoSetRule dvireader.c /^Static Void DoSetRule (int height, int width)$/
+DoSpecial dvireader.c /^Static Void DoSpecial (int hpos, int vpos, int tot/
+ExplicitExt options.c /^Static boolean ExplicitExt (Char *fname, int len)$/
+FixToDVI fontreader.c /^Static int FixToDVI(int b0, int b1, int b2, int b3/
+FndFileInDir fontreader.c /^FndFileInDir(Char *area, Char *name, int mag, font/
+Free config.h /^#define Free(p, T) (free((Anyptr) (p)), (p) = /
+GetBitmap fontreader.c /^Void GetBitmap(int ht, int wd, int mapadr, int_or_/
+GetCardinal options.c /^Static Void GetCardinal (int *n)$/
+GetDimen options.c /^Static Void GetDimen (double *r, units *un)$/
+GetDimension dvitovdu.c /^Static boolean GetDimension (Axis dir, Char *str_,/
+GetInteger dvitovdu.c /^Static boolean GetInteger (Char *str_, int slen, i/
+GetPosDimen options.c /^Static Void GetPosDimen (double *r, units *un)$/
+GetPosReal options.c /^Static Void GetPosReal (double *r)$/
+GetReal dvitovdu.c /^Static boolean GetReal (Char *str_, int slen, int /
+Inint options.c /^Static int Inint (double f) $/
+InitVDU vduinterface.c /^void InitVDU()$/
+Malloc config.h /^# define Malloc(n) (malloc(n) ?: (Anyptr)OutMem()/
+Max dvitovdu.c /^Static int Max (int a, int b)$/
+Mdvitovdu dvitovdu.c /^main (int argc, Char *argv[])$/
+Min dvitovdu.c /^Static int Min (int a, int b)$/
+MoveAbs vis500vdu.c /^Static Void MoveAbs(int row, int col)$/
+MoveQuick vt220vdu.c /^Static Void MoveQuick(int screenh, int screenv)$/
+MoveToDVIPage dvireader.c /^Void MoveToDVIPage(int n)$/
+MoveToNextPage dvireader.c /^Void MoveToNextPage(boolean ascending)$/
+MoveToTeXPage dvireader.c /^boolean MoveToTeXPage(TeXpageinfo *newTeXpage)$/
+NameUnit options.c /^Void NameUnit (units un, string nun)$/
+NewLocation dvitovdu.c /^Static Void NewLocation (int newhp, int newvp)$/
+NewWindowHeight dvitovdu.c /^Static Void NewWindowHeight (int ht)$/
+NewWindowWidth dvitovdu.c /^Static Void NewWindowWidth (int wd)$/
+NotFound dvitovdu.c /^Static Void NotFound (Char *fspec)$/
+OpenDVIFile dvireader.c /^Void OpenDVIFile (Char *name)$/
+OpenFontFile fontreader.c /^boolean OpenFontFile(Char *name)$/
+OutputXY aed512vdu.c /^Static Void OutputXY(int x, int y)$/
+ParseTeXpage dvitovdu.c /^Static boolean ParseTeXpage (TeXpageinfo *newTeXpa/
+PixelRound dvireader.c /^int PixelRound (Axis dir, int DVIunits)$/
+PixelVisible dvitovdu.c /^Static boolean PixelVisible (int hpos, int vpos)$/
+PrintFile dvitovdu.c /^Static Void PrintFile (Char * filename)$/
+REGISLoadFont regisvdu.c /^Void REGISLoadFont(Char *fontname, int fontsize, d/
+REGISShowChar regisvdu.c /^Void REGISShowChar(int screenh, int screenv, Char /
+REGISShowRectangle regisvdu.c /^Void REGISShowRectangle(int screenh, int screenv, /
+ReadChar screenio.c /^Void ReadChar (Char *ch)$/
+ReadString screenio.c /^Void ReadString (Char *s)$/
+RectangleVisible dvitovdu.c /^Static boolean RectangleVisible (int intop, int in/
+RulePixels dvireader.c /^Static int RulePixels (Axis dir, int DVIunits)$/
+ScaleHpos dvitovdu.c /^Static int ScaleHpos (int h)$/
+ScaleVpos dvitovdu.c /^Static int ScaleVpos (int v)$/
+SendXY tek4010vdu.c /^Void SendXY(int x, int y)$/
+SetConversionFactors dvireader.c /^Void SetConversionFactors (double xres, double yre/
+ShowFile dvitovdu.c /^Static Void ShowFile (Char * filename)$/
+SkipFntdef dvireader.c /^Static Void SkipFntdef (int which)$/
+SortFonts dvireader.c /^Void SortFonts (fontinfo ** unusedlist)$/
+TEK4010LoadFont tek4010vdu.c /^Void TEK4010LoadFont(Char *fontname, int fontsize,/
+TEK4010MoveToTextLine tek4010vdu.c /^Void TEK4010MoveToTextLine(int line)$/
+TEK4010ShowChar tek4010vdu.c /^Void TEK4010ShowChar(int screenh, int screenv, Cha/
+TEK4010ShowRectangle tek4010vdu.c /^Void TEK4010ShowRectangle(int screenh, int screenv/
+TeXcounters dvireader.h 104
+TeXpageinfo dvireader.h 110
+UserHitsReturn dvitovdu.c /^Static boolean UserHitsReturn (int *linecount)$/
+VFP config.h 74
+VIS500ClearTextLine vis500vdu.c /^Void VIS500ClearTextLine(int line)$/
+VIS500MoveToTextLine vis500vdu.c /^Void VIS500MoveToTextLine(int line)$/
+VIS500ShowChar vis500vdu.c /^Void VIS500ShowChar(int screenh, int screenv, Char/
+VIS500ShowRectangle vis500vdu.c /^Void VIS500ShowRectangle(int screenh, int screenv,/
+VIS550ClearTextLine vis550vdu.c /^Void VIS550ClearTextLine(int line)$/
+VIS550MoveToTextLine vis550vdu.c /^Void VIS550MoveToTextLine(int line)$/
+VIS630ClearTextLine vis630vdu.c /^Void VIS630ClearTextLine(int line)$/
+VIS630LoadFont vis630vdu.c /^Void VIS630LoadFont(Char *fontname, int fontsize, /
+VIS630MoveToTextLine vis630vdu.c /^Void VIS630MoveToTextLine (int line)$/
+VIS630ShowChar vis630vdu.c /^Void VIS630ShowChar(int screenh, int screenv, Char/
+VIS630ShowRectangle vis630vdu.c /^Void VIS630ShowRectangle(int screenh, int screenv,/
+VT100ClearTextLine vt100vdu.c /^Void VT100ClearTextLine(int line)$/
+VT100LoadFont vt100vdu.c /^Void VT100LoadFont(Char *fontname, int fontsize, d/
+VT100MoveAbs vt100vdu.c /^Void VT100MoveAbs(int row, int col)$/
+VT100MoveToTextLine vt100vdu.c /^Void VT100MoveToTextLine(int line)$/
+VT100ShowChar vt100vdu.c /^Void VT100ShowChar(int screenh, int screenv, Char /
+VT100ShowRectangle vt100vdu.c /^Void VT100ShowRectangle(int screenh, int screenv, /
+VT220LoadFont vt220vdu.c /^Void VT220LoadFont(Char *fontname, int fontsize, d/
+VT220ShowChar vt220vdu.c /^Void VT220ShowChar(int screenh, int screenv, Char /
+VT220ShowRectangle vt220vdu.c /^Void VT220ShowRectangle(int screenh, int screenv, /
+VT640ClearTextLine vt640vdu.c /^Void VT640ClearTextLine(int line)$/
+VT640MoveToTextLine vt640vdu.c /^Void VT640MoveToTextLine(int line)$/
+WriteBuffer screenio.h /^#define WriteBuffer() fflush(stdout)$/
+WriteCard screenio.c /^Static Void WriteCard (int c)$/
+WriteCardinal options.c /^Void WriteCardinal (Char * name, int value)$/
+WriteChar screenio.h /^#define WriteChar(X) putchar(X)$/
+WriteDimen options.c /^Void WriteDimen (Char * varname, double r, units u/
+WriteDimension dvitovdu.c /^Static Void WriteDimension (Axis dir, int pixels)$/
+WriteInt screenio.c /^Void WriteInt (int i)$/
+WriteName options.c /^Void WriteName (Char * varname, Char * svalue)$/
+WritePtSize dvitovdu.c /^Static Void WritePtSize (int scaledsize)$/
+WriteReal options.c /^Void WriteReal (Char * name, double value)$/
+WriteString screenio.h /^#define WriteString(X) fputs(X, stdout)$/
+_REC_TFMinfo fontreader.c 17
+_REC_charmetrics fontreader.c 21
+_REC_chartable dvireader.h 28
+_REC_pixeltable dvireader.h 46
+_REC_ruletable dvireader.h 23
+__ config.h /^# define __(X) X$/
+bitmap_rec globals.h 93
+bitmap_size globals.h 86
+boolean config.h 79
+buffer files.h 19
+bufflenm files.h 19
+byte0 globals.h /^#define byte0(lvalue) ((byte_order *)(&lvalue))->_/
+byte1 globals.h /^#define byte1(lvalue) ((byte_order *)(&lvalue))->_/
+byte2 globals.h /^#define byte2(lvalue) ((byte_order *)(&lvalue))->_/
+byte3 globals.h /^#define byte3(lvalue) ((byte_order *)(&lvalue))->_/
+byte_order globals.h 68
+char config.h 79
+charinfo dvireader.h 74
+fontinfo dvireader.h 101
+glyphrow dvitovdu.c 2624
+handleint unixio.c /^Void handleint (int sig)$/
+int_or_bptr globals.h 81
+int_or_bytes fontreader.c 364
+int_or_mptr globals.h 101
+maxTeXchar dvireader.h 81
+maxbufsizem screenio.h 43
+maxstring globals.h 42
+maxviswordsm dvitovdu.c 2624
+memcmp config.h /^# define memcmp(a,b,n) bcmp(a,b,n)$/
+memcpy config.h /^# define memcpy(a,b,n) (bcopy(b,a,n),a)$/
+pixeltable dvireader.h 81
+ruleinfo dvireader.h 68
+screenbuf screenio.h 43
+sizeof options.c /^size_t ldans = sizeof (dans) \/ sizeof (Dan); \/* l/
+specialinfo dvireader.h 118
+strMcpy options.c /^Char * strMcpy (Char * s, const Char * ct, size_t /
+strchr config.h /^# define strchr(s,c) index(s,c)$/
+string globals.h 42
+stringcopy options.c /^Char * stringcopy (string s, const Char * ct)$/
+strrchr config.h /^# define strrchr(s,c) rindex(s,c)$/
+uchar config.h 103
+units options.c 19
diff --git a/dviware/dvgt/dvgt/src/aed512vdu.c b/dviware/dvgt/dvgt/src/aed512vdu.c
new file mode 100644
index 0000000000..117a4a100f
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/aed512vdu.c
@@ -0,0 +1,527 @@
+/* aed512vdu.c - 20:15 GMT +10:00 Thu 22 July 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "vdu.h"
+
+#define screenht 512 /* change to 483 for smaller AED screen */
+
+#define ALPHA '\001' /* SOH = enter Alpha mode */
+#define INTER '\033' /* ESC = enter Interpreter mode */
+
+#define SAP "^" /* select Alpha parameters for char size */
+#define MOV "Q"
+/* move CAP to absolute x,y position;
+ CAP = Current Access Position */
+#define DVA "A"
+ /* draw vector from CAP to absolute x,y position */
+#define DFR "o"
+/* draw filled rectangle with one corner at CAP and
+ opposite corner at absolute x,y position */
+#define SWC "C" /* set current writing colour */
+#define SBC "[" /* set background colour */
+
+#define green '\002'
+ /* my writing colour; better than default red */
+#define black '\0' /* my background colour; also the default */
+
+#define lineht 9 /* height in pixels of my default text line */
+#define charwidth1 6
+ /* 5*8 font for dialogue region; 85 chars per line */
+#define charwidth2 8 /* normal 7*12 font; 64 chars per line */
+#define charwidth3 12 /* double 5*8 font; 42 chars per line */
+#define charwidth4 16 /* double 7*12 font; 32 chars per line */
+
+
+Static int maxy; /* screenht - 1 */
+Static int loadedwidth; /* remember charwidth set by last AED512LoadFont */
+Static int charwidth; /* used to select Alpha font */
+
+
+/******************************************************************************/
+
+Void AED512StartText (VOID)
+{
+ /* We are about to draw text in dialogue region. */
+
+ WriteChar (ALPHA);
+}
+/* AED512StartText */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void OutputXY (int x, int y)
+#else
+Static Void OutputXY (x, y)
+ int x, y;
+#endif
+{
+ /* Assuming non-mnemonic 8-bit encoding (the default),
+ send the 3 bytes representing the given x,y address.
+ */
+
+ WriteChar (x / 256 * 16 + y / 256); /* x11,x10,x9,x8,y11,y10,y9,y8 */
+ WriteChar (x & 255); /* x7 ,x6 , ... ,x0 */
+ WriteChar (y & 255); /* y7 ,y6 , ... ,y0 */
+}
+/* OutputXY */
+
+/******************************************************************************/
+
+Static Void SelectAlphaFont (VOID)
+{
+ /* Select a new Alpha font depending on the current value of charwidth
+ and prepare to display Alpha text.
+ charwidth is charwidth1 initially; changed in AED512MoveToTextLine and AED512LoadFont.
+ */
+
+ textlinewidth = windowwd / charwidth; /* text characters per line */
+
+ WriteChar (INTER);
+ WriteChar ('^'); /* select Alpha parameters */
+ switch (charwidth)
+ {
+ case charwidth1:
+ WriteChar ('1'); /* normal sized */
+ WriteChar ('5'); /* 5*8 font */
+ WriteChar (charwidth1); /* default hspace */
+ WriteChar (lineht); /* default vspace */
+ break;
+
+ case charwidth2:
+ WriteChar ('1'); /* normal sized */
+ WriteChar ('7'); /* 7*12 font */
+ WriteChar (charwidth2);
+ WriteChar ('\015'); /* vspace = 13 */
+ break;
+
+ case charwidth3:
+ WriteChar ('2'); /* double sized */
+ WriteChar ('5'); /* 5*8 font */
+ WriteChar (charwidth3);
+ WriteChar ('\022'); /* vspace = 18 */
+ break;
+
+ case charwidth4:
+ WriteChar ('2'); /* double sized */
+ WriteChar ('7'); /* 7*12 font */
+ WriteChar (charwidth4);
+ WriteChar ('\032'); /* vspace = 26 */
+ break;
+
+ default:
+ WriteString ("Bug in AED512VDU! Illegal charwidth!");
+ break;
+ }
+ WriteChar ('L'); /* Alpha cursor position identical with CAP */
+ WriteChar (ALPHA);
+}
+/* SelectAlphaFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void AED512MoveToTextLine (int line)
+#else
+Void AED512MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* Move to start of given text line; at the end of this routine we must
+ be ready to display default Alpha characters.
+ */
+
+ WriteChar (INTER);
+ WriteChar ('Q');
+ OutputXY (0, maxy - line * lineht);
+ textcolumn = 0;
+ charwidth = charwidth1; /* use default Alpha font */
+ SelectAlphaFont();
+}
+/* AED512MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void AED512ClearTextLine (int line)
+#else
+Void AED512ClearTextLine (line)
+ int line;
+#endif
+{
+
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+ WriteChar (INTER);
+ WriteChar ('C');
+ WriteChar (black); /* set writing colour to background temporarily */
+ WriteChar ('Q'); /* set CAP to bottom left corner of text line */
+ OutputXY (0, maxy - line * lineht - 2);
+ /* ensure g,j,p... descenders are erased */
+ WriteChar ('o'); /* draw filled rectangle to top right corner */
+ OutputXY (511, maxy - line * lineht + lineht - 3);
+ WriteChar ('C');
+ WriteChar (green); /* back to green */
+ WriteChar (ALPHA); /* safer to leave in Alpha mode */
+}
+/* AED512ClearTextLine */
+
+/******************************************************************************/
+
+Void AED512ClearScreen (VOID)
+{
+ WriteChar (INTER);
+ WriteChar (FF);
+ /* erase screen and return cursor to home position;
+ also exits Interpreter */
+ /* preferable to ERS = '~' which has some problems setting x,y origin */
+}
+/* AED512ClearScreen */
+
+/******************************************************************************/
+
+Void AED512StartGraphics (VOID)
+{
+ /* We are about to draw in window region. */
+
+ if (charwidth != loadedwidth)
+ {
+ /* graphics mode was interrupted */
+ charwidth = loadedwidth;
+ SelectAlphaFont(); /* restore font selected in last AED512LoadFont */
+ }
+ WriteChar (INTER);
+}
+/* AED512StartGraphics */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void AED512LoadFont (Char * fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void AED512LoadFont (fontname, fontsize, mag, hscale, vscale)
+ Char * fontname;
+ int fontsize;
+ double mag;
+ double hscale, vscale;
+#endif
+{
+ /* AED512 uses the given information to select an appropriate character size
+ (based on horizontal scaling only!) for future calls of AED512ShowChar.
+ DVItoVDU only calls this routine in graphics mode.
+ */
+
+ int newwidth;
+
+ /* convert fontsize into scaled screen pixels using mag and hscale */
+ fontsize = (int)(fontsize * mag * hscale + 0.5);
+ /* Chooose one of the 4 Alpha mode character sizes based on fontsize:
+ charwidth max chars/line fontsize range
+ 1 85 0..20
+ 2 64 21..40
+ 3 42 41..60
+ 4 32 61...
+ The fontsize ranges were chosen by trial and error.
+ */
+ if (fontsize < 21)
+ newwidth = charwidth1;
+ else if (fontsize < 41)
+ newwidth = charwidth2;
+ else if (fontsize < 61)
+ newwidth = charwidth3;
+ else
+ newwidth = charwidth4;
+ loadedwidth = newwidth; /* remember for AED512ShowChar */
+ if (charwidth != newwidth)
+ {
+ /* change needed */
+ charwidth = newwidth;
+ SelectAlphaFont();
+ }
+ WriteChar (INTER); /* must exit in graphics mode */
+}
+/* AED512LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void AED512ShowChar (int screenh, int screenv, Char ch)
+#else
+Void AED512ShowChar (screenh, screenv, ch)
+ int screenh, screenv;
+ Char ch;
+#endif
+{
+ /* We show the given character (mapping TeX text character to ASCII)
+ using the given reference point and the charwidth selected by the
+ last AED512LoadFont.
+ DVItoVDU only uses this routine in a Terse display.
+ Note that Alpha characters g,j,p,q,y have descenders that fall
+ below their reference point; when baselines appear near the
+ bottom of the screen, the descenders will wrap to the top.
+ */
+
+ Char newch; /* = TeXtoASCII[ch] */
+
+ /* shift character left if it will overlap right edge of screen */
+ if (screenh + charwidth > 511)
+ screenh = 511 - charwidth;
+ /* DVItoVDU only calls AED512ShowChar in graphics mode */
+ WriteChar ('Q');
+ OutputXY (screenh, maxy - screenv); /* move cursor to reference point */
+
+ /* We use TeXtoASCII to map ch into a comparable ASCII character, apart
+ from most of the ? characters which we attempt to simulate.
+ */
+
+ WriteChar (ALPHA);
+ newch = TeXtoASCII[ch - NUL];
+ if (newch != '?')
+ {
+ /* newch is similar to TeX ch */
+ WriteChar (newch);
+ }
+ else
+ {
+ /* attempt to display something other than ? */
+ switch (ch)
+ {
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15: /* ff, fi, fl, ffi, ffl */
+ WriteChar ('f');
+ /* only simulate rest of ligature if room at right edge */
+ if (screenh + charwidth * 2 - charwidth / 2 <= 511) {
+ WriteChar (INTER);
+ WriteChar ('Q');
+ OutputXY (screenh + charwidth - charwidth / 2, maxy - screenv);
+ WriteChar (ALPHA);
+ switch (ch)
+ {
+ case 0xb:
+ WriteChar ('f');
+ break;
+
+ case 0xc:
+ WriteChar ('i');
+ break;
+
+ case 0xd:
+ WriteChar ('l');
+ break;
+
+ case 0xe:
+ case 0xf:
+ WriteChar ('f');
+ if (screenh + charwidth * 3 - charwidth / 2 * 2 <= 511)
+ {
+ WriteChar (INTER);
+ WriteChar ('Q');
+ OutputXY (screenh + charwidth * 2 - charwidth / 2 * 2,
+ maxy - screenv);
+ WriteChar (ALPHA);
+ if (ch == '\016')
+ WriteChar ('i');
+ else
+ WriteChar ('l');
+ }
+ break;
+ }
+ }
+ break;
+
+ case 0x19: /* German sharp S */
+ WriteChar ('B');
+ break;
+
+ case 0x1a:
+ case 0x1b:
+ case 0x1d:
+ case 0x1e: /* diphthongs: ae, oe, AE, OE */
+ switch (ch) {
+
+ case 0x1a:
+ WriteChar ('a');
+ break;
+
+ case 0x1b:
+ WriteChar ('o');
+ break;
+
+ case 0x1d:
+ WriteChar ('A');
+ break;
+
+ case 0x1e:
+ WriteChar ('O');
+ break;
+ }
+ if (screenh + charwidth * 2 - charwidth / 2 <= 511)
+ {
+ WriteChar (INTER);
+ WriteChar ('Q');
+ OutputXY (screenh + charwidth - charwidth / 2, maxy - screenv);
+ WriteChar (ALPHA);
+ switch (ch)
+ {
+ case 0x1a:
+ case 0x1b:
+ WriteChar ('e');
+ break;
+
+ case 0x1d:
+ case 0x1e:
+ WriteChar ('E');
+ break;
+ }
+ }
+ break;
+
+ case 0x20: /* Polish suppressed l and L */
+ WriteChar ('\'');
+ break;
+
+ default:
+ WriteChar ('?');
+ break;
+ }
+ }
+ WriteChar (INTER); /* must exit in graphics mode */
+}
+/* AED512ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void AED512ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void AED512ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh, screenv; /* top left pixel */
+ int width, height; /* size of rectangle */
+ Char ch; /* black pixel */
+#endif
+{
+ /* Display the given rectangle _without_ using the given
+ black pixel character.
+ We assume that the top left position is correct,
+ and that the given dimensions do not go beyond the screen edges.
+ We assume DVItoVDU is in graphics mode.
+ */
+
+ int pos;
+
+ if (height == 1)
+ {
+ /* show row vector */
+ pos = maxy - screenv;
+ WriteChar ('Q');
+ OutputXY (screenh, pos); /* move cursor to start of row */
+ WriteChar ('A');
+ OutputXY (screenh + width - 1, pos); /* draw vector to end of row */
+ return;
+ }
+ if (width == 1)
+ {
+ /* show column vector */
+ WriteChar ('Q');
+ OutputXY (screenh, maxy - screenv); /* move cursor to start of column */
+ WriteChar ('A');
+ OutputXY (screenh, maxy - screenv - height + 1);
+ /* draw vector to end of column */
+ return;
+ }
+ else
+ {
+ /* draw filled rectangle */
+ /* assume height and width > 1 */
+ WriteChar ('Q');
+ OutputXY (screenh, maxy - screenv); /* CAP to top left corner */
+ WriteChar ('o');
+ OutputXY (screenh + width - 1, maxy - screenv - height + 1);
+ /* fill to bottom right corner */
+ }
+}
+/* AED512ShowRectangle */
+
+/******************************************************************************/
+
+Void AED512ResetVDU (VOID)
+{
+ /* We DON'T reset AED512 to power-up state;
+ we leave AED using green as the writing colour,
+ and set font back to power-up values.
+ Such decisions may not please other AED sites,
+ but I was talked into them by our AED users (all 2 of them!).
+ */
+
+ WriteChar (INTER);
+ WriteChar ('^'); /* select Alpha parameters */
+ WriteChar ('1'); /* normal sized */
+ WriteChar ('7'); /* 7*12 font */
+ WriteChar ('\b'); /* hspace = 8 */
+ WriteChar ('\f'); /* vspace = 12 */
+ WriteChar ('L'); /* Alpha cursor position identical with CAP */
+ WriteChar (ALPHA); /* exit in Alpha mode */
+}
+/* AED512ResetVDU */
+
+/******************************************************************************/
+
+Void InitAED512 (VOID)
+{
+ /* The dialogue region will be the top 4 text lines in Alpha mode.
+ The window region will be the remaining screen area.
+ */
+
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ maxy = screenht - 1;
+ bottoml = screenht / lineht; /* number of text lines on AED512 screen */
+
+ windowv = lineht * 4 + 5; /* height in pixels of dialogue region */
+ windowh = 0;
+ windowht = screenht - windowv;
+ windowwd = 512;
+
+ MoveToTextLine = AED512MoveToTextLine;
+ ClearTextLine = AED512ClearTextLine;
+ ClearScreen = AED512ClearScreen;
+ StartText = AED512StartText;
+ StartGraphics = AED512StartGraphics;
+ LoadFont = AED512LoadFont;
+ ShowChar = AED512ShowChar;
+ ShowRectangle = AED512ShowRectangle;
+ ResetVDU = AED512ResetVDU;
+
+ WriteChar (INTER);
+ WriteChar ('['); /* make sure black is the background colour */
+ WriteChar (black);
+ WriteChar ('C');
+ /* change writing colour to green; easier to read than red */
+ WriteChar (green);
+ WriteChar ('('); /* programmable option */
+ WriteChar ('\006');
+ WriteChar ('\001');
+ /* override any overlapping TEK4010 commands,
+ regardless of option switch 4! */
+ charwidth = charwidth1; /* font for dialogue region */
+ loadedwidth = charwidth; /* for first AED512StartGraphics call */
+
+ SelectAlphaFont();
+}
+/*InitAED512 */
+
+/******************************************************************************/
+
+/* end aed512vdu.c */
diff --git a/dviware/dvgt/dvgt/src/config.h b/dviware/dvgt/dvgt/src/config.h
new file mode 100644
index 0000000000..20c6e4a744
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/config.h
@@ -0,0 +1,161 @@
+/* config.h - 20:42 GMT +10:00 Wed 18 August 1993 - modifier Geoffrey Tobin */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+
+/* 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. */
+
+/* Intel microprocessors (eg in PCs) are little-endian.
+
+ Motorola's cpu-s (eg in Suns and Macs), and the Risc chip in the
+ IBM Risc/6000 (a common platform for Aix) are big-endian.
+
+ Other microprocessors have to be identified and classified by
+ whomever compiles DVItoVDU for them.
+
+ LITTLE_ENDIAN and BIG_ENDIAN are used in "globals.h". One of
+ these must be defined. In the event that both are defined,
+ LITTLE_ENDIAN prevails.
+*/
+
+/* #define LITTLE_ENDIAN */ /* As God intended */
+#define BIG_ENDIAN /* Otherwise*/
+
+/* unix directory separator(s) */
+#define DIRSEP ":"
+
+/* FILE is a #define in BSD, a typedef in SYSV (hp-ux, at least),
+ * and a typedef in ANSI C.
+ * A convenient, but horrible, kludge to detect BSD by its <stdio.h>
+ * header file! We want to know about the C headers and libraries.
+ */
+#ifdef FILE
+# define BSD 1
+#endif /* FILE */
+
+/* Test for ANSI C. Only conforming compilers may define __STDC__,
+ and they must also set __STDC__ to 1. */
+
+/* Note: The purpose of the definition of the "__(X)" macro is to
+ make it easier to write prototypes acceptable to both K&R first
+ edition and ANSI C compilers. Thus, "X" must always be
+ "(something)". For example, "__(void)" doesn't work: it has to be
+ "__((void))". When there are two or more arguments, this error is
+ caught quite promptly as a syntax error - well, it has been so far!
+*/
+
+#ifdef __STDC__
+# define __(X) X
+#else /* not __STDC__ */
+# define __(X) ()
+#endif /* __STDC__ */
+
+#ifdef __STDC__
+# define Void void /* Void f() = procedure */
+# define VOID void /* f (VOID) */
+#else /* not __STDC__ */
+# define void int
+# define Void int
+# define VOID
+#endif /* __STDC__ */
+
+/* GT - Complication: Our system, eg, has an ANSI compiler, gcc.
+ However, it has a BSD library!
+ And which headers does it use? - BSD's or gcc's or what?
+ (I find this whole `arrangement' very annoying.)
+ So I need to separate tests for compiler and library, somehow.
+ Take this "config.h" as only a crude attempt.
+*/
+
+#ifdef BSD
+# include <strings.h>
+# include <sys/file.h>
+# include <sys/types.h>
+ extern char * getenv();
+ extern char * strtok();
+ extern int open();
+ extern int close();
+ extern int read();
+ extern long lseek();
+ extern char * malloc();
+ extern int free();
+ extern char * calloc();
+ extern int bcopy();
+ extern int strcspn();
+ extern int access();
+ extern int ioctl();
+ extern int kill();
+# define memcpy(a,b,n) (bcopy(b,a,n),a)
+# define memcmp(a,b,n) bcmp(a,b,n)
+# define strchr(s,c) index(s,c)
+# define strrchr(s,c) rindex(s,c)
+#else /* Not BSD - maybe System V, ANSI C library, POSIX, or other ? */
+# include <memory.h>
+# include <string.h>
+# ifdef __STDC__
+# define HAS_STDLIB
+# include <stddef.h>
+# include <stdlib.h>
+# include <unistd.h> /* dvgt is for unix systems */
+# else /* not __STDC__, not BSD */
+# include <sys/types.h>
+# endif /* __STDC__ */
+#endif /* BSD */
+
+
+/* GT - Do Char and Static have any advantage over char and static ? */
+#define Char char /* Characters (not bytes) */
+#define Static static /* Private global funcs and vars */
+
+typedef Void (*VFP) (VOID);
+typedef Void *Anyptr;
+typedef unsigned char boolean;
+
+#ifndef true
+# define true 1
+# define false 0
+#endif /* not defined true */
+
+/* GT - Has Extern any advantage over extern ? */
+#ifndef Extern
+# define Extern extern
+#endif /* not defined Extern */
+
+Extern int P_argc;
+Extern char **P_argv;
+
+/* Memory allocation */
+extern int OutMem(VOID);
+
+/* GT - Nasty, nasty, nasty! */
+#ifdef __GNUC__
+# ifndef BSD /* gcc and not an inappropriate, BSD library */
+# define GNUC_LIB 1
+# endif
+#endif
+
+#ifdef GNUC_LIB
+# define Malloc(n) (malloc(n) ?: (Anyptr)OutMem())
+#else /* not GNUC_LIB */
+ Extern Anyptr __MallocTemp__;
+# ifdef ORIGINAL
+# define Malloc(n) \
+ ((__MallocTemp__ = malloc(n)) ? __MallocTemp__ : (Anyptr)OutMem())
+# else /* not ORIGINAL */
+# define Malloc(n) \
+ ((__MallocTemp__ = (Anyptr)malloc(n)) ? __MallocTemp__ : (Anyptr)OutMem())
+# endif /* ORIGINAL */
+#endif /* GNUC_LIB */
+
+#define Free(p, T) (free((Anyptr) (p)), (p) = (T *) NULL)
+
+#endif /* CONFIG_H */
+
+/* end config.h */
diff --git a/dviware/dvgt/dvgt/src/defaults.h b/dviware/dvgt/dvgt/src/defaults.h
new file mode 100644
index 0000000000..dcc9623e9b
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/defaults.h
@@ -0,0 +1,27 @@
+/* defaults.h - 22:18 GMT +10:00 Fri 25 Jun 1993 - modifier Geoffrey Tobin */
+
+#ifndef DEFAULTS_H
+#define DEFAULTS_H
+
+/* Initial default values for various DVItoVDU quantities */
+
+#define DEF_XRES 300.0 /* Horizontal resolution in dpi */
+#define DEF_YRES 300.0 /* Vertical resolution in dpi */
+
+#define DEF_PAPERWD "210mm" /* A4 paper width */
+#define DEF_PAPERHT "297mm" /* A4 paper height */
+
+#define DEF_PK_DIR ".:/usr/local/lib/tex/fonts/tmp"
+#define DEF_TFM_DIR ".:/usr/local/lib/tex/fonts"
+ /* PK and TFM of last resort; assumed in resp. usual font directory: */
+#define DEF_DUMMY_PK "cmr10.300pk"
+#define DEF_DUMMY_TFM "cmr10.tfm"
+ /* PS font prefix, by Karl Berry's convention. */
+#define DEF_PS_PREFIX "p"
+
+#define DEF_CMD_HELP "/usr/local/lib/tex/dvgt/cmd.hlp"
+#define DEF_IMMED_HELP "/usr/local/lib/tex/dvgt/immed.hlp"
+
+#endif /* DEFAULTS_H */
+
+/* end defaults.h */
diff --git a/dviware/dvgt/dvgt/src/dv-env b/dviware/dvgt/dvgt/src/dv-env
new file mode 100644
index 0000000000..2daced5ddb
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/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/dvgt/dvgt/src/dvireader.c b/dviware/dvgt/dvgt/src/dvireader.c
new file mode 100644
index 0000000000..50d59a5098
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/dvireader.c
@@ -0,0 +1,2247 @@
+/* dvireader.c - 18:19 GMT +10:00 Wed 18 Aug 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+
+#include "config.h"
+#include "globals.h"
+
+#include "files.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;
+
+
+/*******************************************************************************
+ 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 (VOID)
+{
+ /* Returns the value (unsigned) of the byte at DVIoffset and
+ advances DVIoffset for the next GetDVIByte.
+ */
+
+ extern int currDVIbuff, DVIfile, DVIoffset;
+
+ int Result, buffstart, result;
+
+ /* bufflen is a #define-d constant in "files.h" */
+
+ buffstart = DVIoffset / bufflen * bufflen; /* 0, bufflen, 2*bufflen... */
+ if (buffstart != currDVIbuff)
+ {
+ currDVIbuff = buffstart;
+ result = lseek (DVIfile, buffstart, 0);
+
+ /* DEBUG
+ IF result <> buffstart THEN BEGIN
+ writeln ('Lseek failed in GetDVIByte!'); RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+
+ if (result != buffstart)
+ {
+ MesgString ("lseek failed in GetDVIByte!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ result = read (DVIfile, DVIbuffer, bufflen);
+
+ /* DEBUG
+ IF result = -1 THEN BEGIN
+ writeln ('Read failed in GetDVIByte!'); RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+
+ if (result == -1)
+ {
+ MesgString ("read failed in GetDVIByte!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ Result = DVIbuffer[DVIoffset - buffstart];
+ DVIoffset++;
+ return Result;
+}
+/* GetDVIByte */
+
+/******************************************************************************/
+
+Static int SignedDVIByte (VOID)
+{
+ /* the next byte, signed */
+ int b;
+
+ b = GetDVIByte();
+ if (b < 128)
+ return b;
+ else
+ return (b - 256);
+}
+/* SignedDVIByte */
+
+/******************************************************************************/
+
+Static int GetTwoDVIBytes (VOID)
+{
+ /* the next 2 bytes, unsigned */
+ int a, b;
+
+ a = GetDVIByte();
+ b = GetDVIByte();
+ return (a * 256 + b);
+}
+/* GetTwoDVIBytes */
+
+/******************************************************************************/
+
+Static int SignedDVIPair (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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.
+ */
+
+ extern int DVIoffset, postpostid;
+ extern int lastbop, num, den, DVImag, maxstack, totalpages;
+
+ 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;
+
+ MesgString ("Stack capacity exceeded!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ /* now we don't need to test for stack overflow in DoPush */
+}
+/* ProcessPostamble */
+
+/******************************************************************************/
+
+Static Void ProcessFontDefs (VOID)
+{
+ /* 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.
+ */
+
+ extern int totalfonts;
+ extern fontinfo * fontlist;
+
+ int f, 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)
+ {
+ /* gt - hope outstring has room enough - it should have. */
+ string outstring;
+ sprintf (outstring,
+ "Unexpected DVI command in postamble = %d", DVIcommand);
+ MesgString (outstring);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ /* we have reached end of postamble */
+ }
+ } while (DVIcommand != postpost);
+
+ /* nop commands can occur between DVI commands */
+}
+/* ProcessFontDefs */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void OpenDVIFile (Char * name)
+#else
+Void OpenDVIFile (name)
+ Char * name;
+#endif
+{
+ /* 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)
+ */
+
+ extern int currDVIpage;
+ extern TeXcounters currTeXpage;
+ extern int currDVIbuff;
+ extern int DVIfile;
+ extern int DVIoffset, postpostid;
+
+
+ currDVIbuff = -1; /* impossible value for first GetDVIByte */
+
+ DVIfile = open (name, O_RDONLY, 0);
+
+ if (DVIfile >= 0)
+ {
+ int i;
+
+ if (logfile != NULL)
+ fprintf (logfile, "Opened DVI file `%s'\n", DVIname);
+
+ /* get offset of last DVI byte */
+ DVIoffset = lseek (DVIfile, 0, 2);
+ if (DVIoffset == -1)
+ {
+ MesgString ("Failed to find end of file!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ if (DVIoffset == 0)
+ {
+ MesgString ("DVI file is empty!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* DEBUG
+ writeln ('total bytes = ', DVIoffset:1);
+ GUBED */
+
+ fprintf (logfile, "Total DVI bytes = %d\n", DVIoffset);
+ fflush (logfile);
+
+ 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)
+ {
+ MesgString ("Not a valid DVI file!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+
+ /*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
+ {
+ /* gt - I suppose this is correct for length */
+ int length = strlen (name);
+ /* gt - hope outstr has sufficient room */
+ string outstr;
+ sprintf (outstr, "Couldn't open DVI file: `%.*s'\n", length, name);
+ MesgString (outstr);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+}
+/* OpenDVIFile */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void SkipFntdef (int which)
+#else
+Static Void SkipFntdef (which)
+ int which;
+#endif
+{
+ /* 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 (VOID)
+{
+
+ /* 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
+ {
+ MesgLine();
+ MesgString ("Unexpected DVI command before first bop=");
+ MesgInt (DVIcommand);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ /* do nothing */
+ } while (DVIcommand != bop);
+ currbop = DVIoffset - 1; /* position in DVI file of first bop */
+ currDVIpage = 1;
+}
+/* ReadFirstBop */
+
+/******************************************************************************/
+
+Static Void ReadNextBop (VOID)
+{
+ /* 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
+ {
+ MesgLine();
+ MesgString ("Unexpected DVI command between eop and bop=");
+ MesgInt (DVIcommand);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ /* do nothing */
+ } while (DVIcommand != bop);
+ currbop = DVIoffset - 1; /* position in DVI file of this bop */
+ currDVIpage++;
+}
+/* ReadNextBop */
+
+/******************************************************************************/
+
+Static Void ReadBopParameters (VOID)
+{
+
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void MoveToNextPage (boolean ascending)
+#else
+Void MoveToNextPage (ascending)
+ boolean ascending;
+#endif
+{
+ /* 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.
+ */
+
+ extern int currDVIpage;
+ extern int DVIoffset;
+ extern int totalpages;
+ extern int currbop, lastbop, prevbop;
+
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void MoveToDVIPage (int n)
+#else
+Void MoveToDVIPage (n)
+ int n;
+#endif
+{
+ /* Move to nth DVI page; n should be in 1..totalpages. */
+
+ extern int totalpages;
+ extern int currDVIpage;
+ extern int currbop, lastbop, prevbop;
+
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean CurrMatchesNew (TeXpageinfo * newTeXpage)
+#else
+Static boolean CurrMatchesNew (newTeXpage)
+ TeXpageinfo * newTeXpage;
+#endif
+{
+ /* Return TRUE iff currTeXpage matches newTeXpage. */
+
+ extern TeXcounters currTeXpage;
+
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean MoveToTeXPage (TeXpageinfo * newTeXpage)
+#else
+boolean MoveToTeXPage (newTeXpage)
+ TeXpageinfo * newTeXpage;
+#endif
+{
+ /* 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.
+ */
+
+ extern int totalpages;
+ extern int currDVIpage;
+ extern int DVIoffset;
+ extern int currbop, lastbop, prevbop;
+
+ boolean Result;
+
+ int savecurrbop, 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void SetConversionFactors (double xres, double yres, double magnification)
+#else
+Void SetConversionFactors (xres, yres, magnification)
+ double xres; double yres; double magnification;
+#endif
+/* 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.
+ */
+
+ /* num, den are written in ProcessPostAmble */
+ extern int num, den;
+
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int Sign (double d)
+#else
+Static int Sign (d)
+ double d;
+#endif
+{
+ return (d < 0.0 ? -1 : 1);
+}
+/* Sign */
+
+/******************************************************************************/
+
+Static Void InitStateValues (VOID)
+{
+ /* 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". */
+
+ extern int hoffset, voffset; /* page offsets in X & Y pixels */
+ extern int hh, vv; /* current position in X & Y pixels */
+ extern double xconv, yconv; /* numbers of X & Y pixels in one DVI unit */
+ extern int h, v; /* current position in DVI units */
+ extern int w, x, y, z; /* movement in DVI units */
+ extern int stackpos;
+ extern int fontspace;
+
+ 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 (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int XPixelRound (int DVIunits)
+#else
+int XPixelRound (DVIunits)
+ int DVIunits;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int YPixelRound (int DVIunits)
+#else
+int YPixelRound (DVIunits)
+ int DVIunits;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoSetChar (int ch)
+#else
+Static Void DoSetChar (ch)
+ int ch;
+#endif
+{
+ /* Add char info to current chartable, update our horizontal
+ position on the page and check the 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;
+
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoPutChar (int ch)
+#else
+Static Void DoPutChar (ch)
+ int ch;
+#endif
+{
+ /* Exactly the same as DoSetChar, 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;
+
+ currfont->totalchars++;
+ char_info->charcount++;
+ pageempty = false;
+ }
+}
+/* DoPutChar */
+
+/******************************************************************************/
+
+Static Void DoPush (VOID)
+{
+ /* Push state values onto stack.
+ No need to test for stack overflow since we compare maxstack and
+ maxstacksize in ProcessPostamble.
+ */
+
+ extern int stackpos;
+
+ 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 (VOID)
+{
+ /* Pop state values from top of stack. */
+
+ extern int stackpos;
+
+ /* DEBUG
+ IF stackpos = 0 THEN BEGIN
+ WriteLine; WriteString ('Stack empty!'); WriteLine;
+ RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+
+ if (stackpos == 0)
+ {
+ MesgLine();
+ MesgString ("Stack empty!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoRight (int amount)
+#else
+Static Void DoRight (amount)
+ int amount;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoDown (int amount)
+#else
+Static Void DoDown (amount)
+ int amount;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int RulePixels (double conv, int DVIunits)
+#else
+Static int RulePixels (conv, DVIunits)
+ double conv; int DVIunits;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoSetRule (int height, int width)
+#else
+Static Void DoSetRule (height, width)
+ int height; int width;
+#endif
+{
+ /* Add rule information to current ruletable, update page edges, h and hh
+ (but only if width and height are > 0).
+ */
+
+ _REC_ruletable * ruletab = (_REC_ruletable *) NULL;
+
+ if (height <= 0 || width <= 0)
+ return;
+
+ /* 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 || vv > maxvp)
+ maxvp = vv;
+ if (pageempty || hh < minhp)
+ minhp = hh;
+
+ if (pageempty || vv - ruletab->ht + 1 < minvp)
+ minvp = vv - ruletab->ht + 1;
+ if (pageempty || hh + ruletab->wd - 1 > maxhp)
+ maxhp = hh + ruletab->wd - 1;
+
+ hh += ruletab->wd;
+ 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);
+ }
+
+ totalrules++;
+ ruletail->rulecount++;
+ pageempty = false;
+}
+/* DoSetRule */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoPutRule (int height, int width)
+#else
+Static Void DoPutRule (height, width)
+ int height; int width;
+#endif
+{
+
+ /* 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)
+ return;
+
+ /* 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;
+}
+/* DoPutRule */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoFont (int externf)
+#else
+Static Void DoFont (externf)
+ int externf;
+#endif
+{
+ /* 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.
+ */
+
+ extern fontinfo * currfont, * fontlist;
+
+ charinfo * char_info = (charinfo *) NULL;
+
+ currfont = fontlist;
+ while (currfont != (fontinfo *) NULL && currfont->fontnum != externf)
+ {
+ currfont = currfont->nextfont;
+ }
+
+ /* DEBUG
+ IF currfont = NIL THEN BEGIN
+ WriteLine; WriteString ('Failed to find font #'); WriteInt (externf);
+ WriteLine; RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+
+ if (currfont == NULL)
+ {
+ MesgLine();
+ MesgString ("Failed to find font #");
+ MesgInt (externf);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void DoSpecial (int hpos, int vpos, int totalbytes)
+#else
+Static Void DoSpecial (hpos, vpos, totalbytes)
+ int hpos; int vpos; int totalbytes;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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, 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:
+ <set1, w0, right3, push/pop, x0, w3, y0, fntnum25, right2, fntnum31,
+ down3, x2, right4, w2, x3, down4, z0, fntnum8, setrule, y3, etc.
+ */
+ if (DVIcommand < set1) /* 0..127 */
+ DoSetChar (DVIcommand);
+ else if (DVIcommand == w0)
+ DoRight (w);
+ else if (DVIcommand == right3)
+ DoRight (SignedDVITrio());
+ else if (DVIcommand == push)
+ DoPush();
+ else if (DVIcommand == pop)
+ DoPop();
+ else if (DVIcommand == x0)
+ DoRight (x);
+ else if (DVIcommand == w3)
+ {
+ w = SignedDVITrio();
+ DoRight (w);
+ }
+ else if (DVIcommand == y0_)
+ DoDown (y);
+ else if (DVIcommand > 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
+ {
+ MesgLine();
+ MesgString ("Bug in InterpretPage!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ else if (DVIcommand == setrule)
+ {
+ ht = SignedDVIQuad();
+ wd = SignedDVIQuad();
+ DoSetRule (ht, wd);
+ }
+ else if (DVIcommand == putrule)
+ {
+ ht = SignedDVIQuad();
+ wd = SignedDVIQuad();
+ DoPutRule (ht, wd);
+ }
+ else if (DVIcommand >= put1 && DVIcommand <= put1 + 3)
+ {
+ switch (DVIcommand - put1)
+ {
+ case 0:
+ DoPutChar (GetDVIByte());
+ break;
+
+ case 1:
+ DoPutChar (GetTwoDVIBytes());
+ break;
+
+ case 2:
+ DoPutChar (GetThreeDVIBytes());
+ break;
+
+ case 3:
+ DoPutChar (SignedDVIQuad());
+ break;
+ }
+
+ }
+ else if (DVIcommand >= set1 && DVIcommand <= set1 + 3)
+ {
+ switch (DVIcommand - set1)
+ {
+ case 0:
+ DoSetChar (GetDVIByte());
+ break;
+
+ case 1:
+ DoSetChar (GetTwoDVIBytes());
+ break;
+
+ case 2:
+ DoSetChar (GetThreeDVIBytes());
+ break;
+
+ case 3:
+ DoSetChar (SignedDVIQuad());
+ 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 */
+ MesgLine();
+ MesgString ("Unexpected DVI command while interpreting page=");
+ MesgInt (DVIcommand);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ } while (DVIcommand != eop);
+
+ /* save position of eop byte for use in MoveToTeXPage */
+ curreop = DVIoffset - 1;
+
+ if (stackpos != 0)
+ {
+ MesgLine();
+ MesgString ("Stack not empty at eop!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* InitPage values */
+
+
+ /* fntnum0..fntnum63 */
+
+
+ /* skip fntdef command since we've got this info from postamble */
+
+ /* do nothing */
+}
+/* InterpretPage */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void SortFonts (fontinfo ** unusedlist)
+#else
+Void SortFonts (unusedlist)
+ fontinfo ** unusedlist;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ 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/dvgt/dvgt/src/dvireader.h b/dviware/dvgt/dvgt/src/dvireader.h
new file mode 100644
index 0000000000..7b49e2459e
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/dvireader.h
@@ -0,0 +1,166 @@
+/* dvireader.h - 21:21 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin. */
+
+#ifndef DVIREADER_H
+#define DVIREADER_H
+
+/* Include file ../include/dvireader.h from dvitovdu.c */
+
+/* DVIReader */
+
+#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 psfont; /* is this a PS or pure TFM 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: */
+#ifndef Extern
+#define Extern extern
+#endif
+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 (VOID);
+extern Void OpenDVIFile __((Char *name));
+extern Void SetConversionFactors __((double xres, double yres, double magnification));
+extern Void MoveToDVIPage __((int n));
+extern Void MoveToNextPage __((boolean ascending));
+extern boolean MoveToTeXPage __((TeXpageinfo *newTeXpage));
+extern int XPixelRound __((int DVIunits));
+extern int YPixelRound __((int DVIunits));
+extern Void InterpretPage (VOID);
+extern Void SortFonts __((fontinfo **unusedlist));
+extern Void CloseDVIFile (VOID);
+
+#endif /* DVIREADER_H */
+
+/* end dvireader.h */
diff --git a/dviware/dvgt/dvgt/src/dvitovdu.c b/dviware/dvgt/dvgt/src/dvitovdu.c
new file mode 100644
index 0000000000..27327ff1ed
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/dvitovdu.c
@@ -0,0 +1,4056 @@
+/* dvitovdu.c - 18:20 GMT +10:00 Wed 18 Aug 1993 - modifier Geoffrey Tobin */
+
+/* From input file "dvitovdu.p" */
+
+#include <signal.h>
+
+#ifdef __STDC__
+# include <time.h>
+#endif
+
+#include "version.h"
+
+/* Unix file access routines are needed in ShowFile. */
+
+#include "config.h"
+
+#include "defaults.h"
+#include "globals.h"
+#include "help.h"
+
+#include "screenio.h"
+#include "options.h"
+#include "unixio.h"
+#include "vdu.h"
+#include "dvireader.h"
+#include "fontreader.h"
+
+#include "lstring.h"
+#include "new.h"
+
+
+/* Variables Exported, via config.h */
+
+int P_argc = 0;
+char ** P_argv = (char **) NULL;
+Anyptr __MallocTemp__ = (Anyptr) NULL;
+
+
+/* Variables Exported, via globals.h */
+
+FILE * logfile = (FILE *) NULL;
+
+
+/* Variables Exported, via vdu.h */
+
+int DVIstatusl, windowstatusl, messagel, commandl, bottoml;
+int windowh, windowv, windowwd, windowht;
+
+
+Static Void DisplayPage (VOID);
+Static Void NextCommandLine (VOID);
+Static boolean PrintFile __((Char * filename));
+Static boolean PrintText __((Char * * text));
+Static boolean ShowFile __((Char * filename));
+Static boolean ShowCmdHelp (VOID);
+
+/* list of signal conditions */
+
+static int common_signals[]
+ = {SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM};
+
+/* default log file */
+static FILE * def_log = (FILE *) NULL;
+
+/*******************************************************************************
+ 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? */
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Char Cap (Char ch)
+#else
+Static Char Cap (ch)
+ Char ch;
+#endif
+{
+ /* If ch is a lowercase letter, then return capital, else return ch. */
+
+ if (islower(ch))
+ return (Char) toupper (ch);
+ else
+ return ch;
+}
+/* Cap */
+
+/******************************************************************************/
+
+Static char * TimeString (VOID)
+{
+#ifdef HAS_STDLIB
+ time_t tt;
+ (Void) time (&tt); /* obtain the time */
+ return (ctime (&tt)); /* local time */
+#else /* not HAS_STDLIB */
+ return ("Time is currently available only for ANSI C library.");
+#endif /* HAS_STDLIB */
+}
+/* TimeString */
+
+/******************************************************************************/
+
+Void PadMesg (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 ClearMessageLine (VOID)
+{
+ /* 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.
+ */
+
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ ClearTextLine (messagel);
+ MoveToTextLine (messagel);
+}
+/* ClearMessageLine */
+
+/******************************************************************************/
+
+Static Void WaitForReturn (VOID)
+{
+ /* DVItoVDU has just displayed an important message.
+ To ensure message is seen we wait for user to hit Return.
+ */
+
+ Char ch;
+
+#ifdef WAIT_FOR_RETURN
+ MesgString (" RETURN:");
+#endif /* WAIT_FOR_RETURN */
+
+ MesgFlush();
+ do {
+ ReadChar(&ch);
+ } while (ch != CR);
+}
+/* WaitForReturn */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void UpdateDVIStatusLine (VOID)
+#else
+Static Void UpdateDVIStatusLine ()
+#endif
+{
+ /* Show totalpages, currDVIpage, currTeXpage, direction and displaymode. */
+
+ int i, lastnonzero;
+
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ 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 */
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void WriteDimension (double precision, double res, int pixels)
+#else
+Static Void WriteDimension (precision, res, pixels)
+ double precision; double res; int pixels;
+#endif
+{
+ /* Show the given pixel dimension in terms of currentunits. */
+
+ double realdim;
+ int fracpart;
+
+ 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:
+ MesgInt (pixels);
+ break;
+ } /* currentunits */
+
+ if (currentunits != px)
+ {
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void WriteXDim (double precision, int pixels)
+#else
+Static Void WriteXDim (precision, pixels)
+ double precision; int pixels;
+#endif
+{
+ WriteDimension (precision, xres, pixels);
+}
+/* Write XDim */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void WriteYDim (double precision, int pixels)
+#else
+Static Void WriteYDim (precision, pixels)
+ double precision; int pixels;
+#endif
+{
+ WriteDimension (precision, yres, pixels);
+}
+/* Write YDim */
+
+/******************************************************************************/
+
+Static Void UpdateWindowStatusLine (VOID)
+{
+ /* 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 */
+
+
+#ifdef __STDC__
+Static boolean GetInteger (Char * str_in, int slen, int * pos, int * n)
+#else
+Static boolean GetInteger (str_in, slen, pos, n)
+ Char * str_in; /* str_in : in */
+ int slen; /* slen : in */
+ int * pos; /* pos : in/out */
+ int * n; /* n : out */
+#endif
+{
+ /* 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;
+
+ (void) 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
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean GetReal (Char * str_in, int slen, int * pos, double * r)
+#else
+Static boolean GetReal (str_in, slen, pos, r)
+ Char * str_in; /* *str_in: in */
+ int slen; /* slen: in */
+ int * pos; /* *pos: in/out */
+ double * r; /* *r: out */
+#endif
+{
+ /* 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.
+ */
+
+ boolean Result;
+ string str;
+
+ int sign, intpart, fracpart, divisor;
+ double absreal;
+
+ (void) 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 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;
+ Result = false;
+ goto _L999;
+
+ }
+ }
+
+ /* 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;
+
+ Result = true;
+
+_L999: ;
+ return Result;
+} /* GetReal */
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean GetDimension (double res, Char * str_in, int slen,
+ int * pos, int * n)
+#else
+Static boolean GetDimension (res, str_in, slen, pos, n)
+ double res; /* res: in */
+ Char * str_in; /* str_in: in */
+ int slen; /* slen: in */
+ int * pos; /* pos: in/out */
+ int * n; /* n: out */
+#endif
+{
+ /* 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.
+ */
+
+ boolean Result;
+ string str;
+
+ int sign, intdim, fracpart, divisor;
+ double absrealdim;
+ boolean intpresent, dimtoobig;
+
+ (void) 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;
+ Result = false;
+ goto _L999;
+
+ }
+ } /* 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;
+
+ Result = true;
+
+_L999: ;
+ return Result;
+}
+/* GetDimension */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean GetXDim (Char * str_in, int slen, int * pos, int * n)
+#else
+Static boolean GetXDim (str_in, slen, pos, n)
+ Char * str_in; int slen; int * pos; int * n;
+#endif
+{
+ return GetDimension (xres, str_in, slen, pos, n);
+}
+/* GetXDim */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean GetYDim (Char * str_in, int slen, int * pos, int * n)
+#else
+Static boolean GetYDim (str_in, slen, pos, n)
+ Char * str_in; int slen; int * pos; int * n;
+#endif
+{
+ return GetDimension (yres, str_in, slen, pos, n);
+}
+/* GetYDim */
+
+/******************************************************************************/
+
+Static Void BadCommandMessage (VOID)
+{
+ /* 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;
+
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ 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]);
+ }
+#ifdef OLDWAIT
+ WaitForReturn();
+ ClearMessageLine();
+ ClearTextLine (commandl);
+#else
+ NextCommandLine();
+#endif
+}
+/* BadCommandMessage */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void NewLocation (int newhp, int newvp)
+#else
+Static Void NewLocation (newhp, newvp)
+ int newhp; int newvp;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ 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 (VOID)
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void NewWindowWidth (int wd)
+#else
+Static Void NewWindowWidth (wd)
+ int wd;
+#endif
+{
+ /* Set window width to given value (> 0 and <= max dimension). */
+
+ scaledwd = wd;
+ hscalefactor = (double) windowwd / scaledwd;
+}
+/* NewWindowWidth */
+
+/******************************************************************************/
+
+Static Void SetWindowWidth (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void NewWindowHeight (int ht)
+#else
+Static Void NewWindowHeight (ht)
+ int ht;
+#endif
+{
+ /* Set window height to given value (> 0 and <= max dimension). */
+
+ scaledht = ht;
+ vscalefactor = (double)windowht / scaledht;
+}
+/* NewWindowHeight */
+
+/******************************************************************************/
+
+Static Void SetWindowHeight (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int ScaleHpos (int h)
+#else
+Static int ScaleHpos (h)
+ int h;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int ScaleVpos (int v)
+#else
+Static int ScaleVpos (v)
+ int v;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* Toggle AutoView. */
+
+ autoviewing = (autoviewing == false ? true : false);
+}
+/* SetAutoView */
+
+/******************************************************************************/
+
+Static Void ZITL (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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, zch3; /* 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 = Cap (commstring[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 = Cap (commstring[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;
+ }
+#ifdef DEBUG
+ else /* no number; use the previous Zoom Factor */
+ {
+ string msgstring;
+
+ /* !! GT - dangerous, as msgstring may overflow - unlikely, though */
+ sprintf (msgstring,
+ "no zoom argument, so retaining old factor of %.2f", zoomfactor);
+
+ ClearMessageLine();
+ MesgString (msgstring);
+ }
+#endif /* DEBUG */
+
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean NextPageFound (boolean ascending)
+#else
+Static boolean NextPageFound (ascending)
+ boolean ascending;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean DVIPageFound (int n)
+#else
+Static boolean DVIPageFound (n)
+ int n;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean ParseTeXpage (TeXpageinfo * newTeXpage)
+#else
+Static boolean ParseTeXpage (newTeXpage)
+ TeXpageinfo *newTeXpage;
+#endif
+{
+ /* 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 [.
+ */
+
+ boolean Result;
+
+ 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 */
+ Result = false;
+ goto _L999;
+
+ }
+ 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();
+ Result = false;
+ goto _L999;
+
+ }
+ newTeXpage->lastvalue++;
+ if (commstring[commpos] == '.')
+ continue;
+ ClearMessageLine();
+ MesgString ("Period, integer or ] expected!");
+ commpos++;
+ BadCommandMessage();
+ Result = false;
+ goto _L999;
+
+ } /* while */
+
+ while ( newTeXpage->lastvalue > 0
+ && ! newTeXpage->present[(int)newTeXpage->lastvalue] )
+ {
+ newTeXpage->lastvalue--;
+ }
+ Result = true;
+_L999: ;
+ return Result;
+}
+/* ParseTeXpage */
+
+/******************************************************************************/
+
+Static boolean TeXPageFound (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int Min (int a, int b)
+#else
+Static int Min (a, b)
+ int a, b;
+#endif
+{
+ /* Return the minimum value of a and b. */
+
+ if (a < b)
+ return a;
+ else
+ return b;
+}
+/* Min */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int Max (int a, int b)
+#else
+Static int Max (a, b)
+ int a, b;
+#endif
+{
+ /* Return the maximum value of a and b. */
+
+ if (a > b)
+ return a;
+ else
+ return b;
+}
+/* Max */
+
+/******************************************************************************/
+
+Static Void ProcessPage (VOID)
+{
+ /* 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!");
+ /* the previous page */
+ WaitForReturn();
+ }
+ LogClearScreen();
+ 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 (VOID)
+{
+ /* 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 = Cap (commstring[commpos++]);
+ else
+ nextch1 = ' ';
+
+ if (commpos < commlen)
+ nextch2 = Cap (commstring[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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean UserHitsReturn (int *linecount)
+#else
+Static boolean UserHitsReturn (linecount)
+int *linecount;
+#endif
+{
+ /* 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.
+ */
+
+ boolean Result = 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)
+ {
+ Result = true;
+ goto _L999;
+
+ }
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine(1);
+ *linecount = 1;
+ }
+ else
+ {
+ (*linecount)++;
+ }
+ Result = false;
+_L999:
+ return Result;
+}
+/* UserHitsReturn */
+
+/******************************************************************************/
+
+Static Void WriteUnits (VOID)
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int WritePtSize (int scaledsize)
+#else
+Static int WritePtSize (scaledsize)
+int scaledsize;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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 */
+
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ linecount = 1;
+
+ MesgString ("DVI file = ");
+ MesgString (LeftStr);
+ MesgString (DVIname);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("VDU = ");
+ MesgString (LeftStr);
+ MesgString (vdu);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ { /* beginblock */
+ string realstring;
+
+ MesgString ("X Resolution (dpi) = ");
+ /* xres is unlikely to overflow realstring */
+ sprintf (realstring, "%f", xres);
+ MesgString (realstring);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Y Resolution (dpi) = ");
+ /* yres is unlikely to overflow realstring */
+ sprintf (realstring, "%f", yres);
+ MesgString (realstring);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ } /* endblock */
+
+ MesgString ("Magnification = ");
+ MesgInt (mag);
+ if (mag == DVImag)
+ {
+ MesgString (" (DVI mag)");
+ }
+ else
+ {
+ MesgString (" (DVI mag of ");
+ MesgInt (DVImag);
+ MesgString (" was overridden)");
+ }
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("PK Font directory = ");
+ MesgString (LeftStr);
+ MesgString (pkdir);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("TFM directory = ");
+ MesgString (LeftStr);
+ MesgString (tfmdir);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Dummy PK font = ");
+ MesgString (LeftStr);
+ MesgString (dummy_pk);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Dummy TFM metric = ");
+ MesgString (LeftStr);
+ MesgString (dummy_tfm);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("PS font prefix = ");
+ MesgString (LeftStr);
+ MesgString (psprefix);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Command Help file = ");
+ MesgString (LeftStr);
+ MesgString (cmd_help);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Horizontal offset = ");
+ WriteXDim (precision, hoffset);
+ WriteUnits();
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Vertical offset = ");
+ WriteYDim (precision, voffset);
+ WriteUnits();
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString ("Paper wd by ht = ");
+ WriteXDim (precision, paperwd);
+ WriteUnits();
+ MesgString (" by ");
+ WriteYDim (precision, paperht);
+ WriteUnits();
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#ifdef TWICE
+ /* gt - why twice? */
+
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#endif /* TWICE */
+
+ MesgString ("Total fonts on ALL pages = ");
+ MesgInt (totalfonts);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#ifdef TWICE
+ /* gt - why twice? */
+
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#endif /* TWICE */
+
+ MesgString ("Fonts, at pt size: (if on current page, give (total chars))");
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ MesgString
+ ("H: Honest, S: Substitute; P: PostScript, K: PK, T: non-PS TFM, D: DVI.");
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ 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->psfont)
+ MesgChar ('P');
+ else if (thisfontinfo->pkfont)
+ MesgChar ('K');
+ else /* non-PostScript TFM */
+ MesgChar ('T');
+
+ MesgString (" ");
+ MesgString (thisfontinfo->fontspec);
+ }
+ else
+ {
+ MesgChar ('S');
+ MesgChar ('D');
+
+ MesgString (" ");
+ MesgString ("Terse display");
+ }
+
+ if (thisfontinfo->fontused)
+ {
+ fontcount++;
+ MesgString (" (");
+ MesgInt (thisfontinfo->totalchars);
+ MesgString (")");
+ }
+
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+ }
+ /* 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))
+ goto _L999;
+
+#ifdef TWICE
+ /* gt - why twice? */
+
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#endif /* TWICE */
+
+ MesgString ("Total rules on current page = ");
+ MesgInt (totalrules);
+
+ if (speciallist != (specialinfo *) NULL)
+ {
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#ifdef TWICE
+ /* gt - why twice? */
+
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+#endif /* TWICE */
+
+ MesgString ("\\special commands on current page: ");
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ temp = speciallist;
+ while (temp != (specialinfo *) NULL)
+ {
+ MesgString ("At (");
+ WriteXDim (precision, temp->hp);
+ MesgChar (',');
+ WriteYDim (precision, temp->vp);
+ MesgString ("): ");
+ MesgString (temp->special);
+ if (UserHitsReturn (&linecount))
+ goto _L999;
+
+ temp = temp->nextspecial;
+ } /* while */
+ } /* if */
+
+ MesgLine();
+ MesgLine();
+ MoveToTextLine (bottoml);
+ MesgString ("Hit RETURN key to resume page display: ");
+ MesgFlush();
+
+ do
+ {
+ ReadChar (&ch);
+ } while (ch != CR);
+
+_L999: ;
+}
+/* ShowStatistics */
+
+/******************************************************************************/
+/******************************************************************************/
+
+#define maxline 80
+ /* SYSDEP: cmd_help should have <= maxline chars/line */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean PrintText (Char * * text)
+#else
+Static boolean PrintText (text)
+ Char * * text;
+#endif
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean PrintFile (Char * filename)
+#else
+Static boolean PrintFile (filename)
+ Char * filename;
+#endif
+{
+ int retval = false;
+ FILE * filep = (FILE *) NULL; /* file pointer for "filename" */
+
+ filep = fopen (filename, "r"); /* read only */
+ if (filep == (FILE *) NULL)
+ {
+ /* File was not opened. */
+ retval = false;
+ }
+ else
+ {
+ Char outline[maxline + 1]; /* Allow space for terminating null */
+
+ while (fgets (outline, maxline+1, filep) != (char *) NULL)
+ {
+ printf ("%s", outline);
+ /* If there's no newline in cp, print one. */
+ if (strchr (outline, '\n') == (char *) NULL)
+ printf ("\n");
+ }
+ retval = true;
+ }
+ return retval;
+}
+/* PrintFile */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean ShowFile (Char * filename)
+#else
+Static boolean ShowFile (filename)
+ Char * filename;
+#endif
+{
+ /* Show file with name "filename" in a way something like unix more. */
+
+ FILE * filep = (FILE *) NULL; /* file pointer for "filename" */
+ int lines;
+
+ filep = fopen (filename, "r"); /* read only */
+ if (filep == (FILE *) NULL)
+ {
+#ifdef BORING_MESSAGES
+ ClearMessageLine();
+ MesgString ("Couldn't open file");
+ MesgString (" `");
+ MesgString (filename);
+ MesgString ("'!");
+ WaitForReturn();
+ ClearMessageLine();
+#endif /* BORING_MESSAGES */
+
+ return false;
+ }
+
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine(1);
+ rawoutoff();
+
+ for (lines = 0; true; lines++)
+ {
+ int ch;
+ Char answer;
+ Char outline[maxline + 1]; /* Allow space for terminating null */
+ int i;
+
+ if ((ch = getc (filep)) == EOF) /* SYSDEP: end of file */
+ {
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ ClearTextLine (bottoml);
+ MoveToTextLine (bottoml);
+
+ 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 */
+
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ ClearTextLine (bottoml);
+ MoveToTextLine (bottoml);
+
+ /* prompt */
+ MesgString ("Hit RETURN key to resume page display,");
+ MesgString (" or any other key for more of file `");
+ MesgString (filename);
+ MesgString ("': ");
+ MesgFlush();
+
+ ReadChar (&answer);
+ if (answer == CR)
+ break; /* EXIT point 2 of 2 from enclosing (for) loop */
+
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ lines = 0; /* reset line count */
+ }
+ for (i = 0; ch != CR; i++)
+ {
+ if (i < maxline)
+ outline[i] = ch;
+ /* SYSDEP: check if eof occurs before eoln */
+ if ((ch = getc (filep)) == EOF)
+ ch = CR;
+ }
+ outline[i] = '\0';
+ MesgString (outline);
+ MesgLine();
+ } /* (for) loop */
+
+ (Void) fclose (filep);
+
+ rawouton();
+ LogClearScreen();
+ screenjustcleared = true;
+ paintDVIStatus = true;
+ paintWindowStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+
+ return true;
+}
+/* ShowFile */
+
+/******************************************************************************/
+
+#undef maxline
+
+/******************************************************************************/
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean ShowText (Char * * text)
+#else
+Static boolean ShowText (text)
+ Char * * text;
+#endif
+{
+ /* Show text of consecutive lines, in a way something like unix more. */
+
+ int lines;
+ Char answer;
+
+ if (text == (Char * *) NULL)
+ {
+ ClearMessageLine();
+ MesgString ("NULL text!");
+ WaitForReturn();
+ ClearMessageLine();
+ return false;
+ }
+
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine(1);
+ rawoutoff();
+
+ for (lines = 0; true; lines++)
+ {
+ if (text[lines] == (Char *) NULL) /* end of text */
+ {
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ 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 */
+
+ fprintf (logfile, "\n");
+ fflush (logfile);
+
+ 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 */
+
+ LogClearScreen();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ lines = 0; /* reset line count */
+ }
+ MesgString (text[lines]);
+ MesgLine();
+ }
+
+ rawouton();
+ LogClearScreen();
+ screenjustcleared = true;
+ paintDVIStatus = true;
+ paintWindowStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+
+ return true;
+}
+/* ShowText */
+
+/******************************************************************************/
+
+Static boolean ShowCmdHelp (VOID)
+{
+ /* 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 (ShowFile (cmd_help) || ShowText (cmd_help_strings));
+}
+/* ShowCmdHelp */
+
+/******************************************************************************/
+
+#define edgepixel '.'
+ /* black pixel for outlines on non-graphic VDUs;
+ note that VDU TeXtoASCII['.'] = '.' */
+
+Static Void DisplayPaperEdges (VOID)
+{
+ /* 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)
+ goto _L999;
+
+ if (paperbottom < windowtop)
+ goto _L999;
+
+ if (paperleft > windowright)
+ goto _L999;
+
+ if (paperright < windowleft)
+ goto _L999;
+
+ /* 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);
+
+_L999: ;
+}
+/* DisplayPaperEdges */
+
+#undef edgepixel
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean RectangleVisible (int intop, int inbot, int inleft, int inright,
+ int *outtop, int *outbot, int *outleft, int *outright)
+#else
+Static boolean RectangleVisible (intop, inbot, inleft, inright,
+ outtop, outbot, outleft, outright)
+int intop; int inbot; int inleft; int inright;
+ int *outtop; int *outbot; int *outleft; int *outright;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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 = Cap (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 */
+ goto _L999;
+
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ /* visible rectangle */
+ thisrule++;
+ } /* while */
+ thisruleinfo = thisruleinfo->nextrule;
+ } /* while */
+_L999: ;
+}
+/* DisplayRules */
+
+#undef rulepixel
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean PixelVisible (int hpos, int vpos)
+#else
+Static boolean PixelVisible (hpos, vpos)
+int hpos; int vpos;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef FULL_CHAR_PS
+Static boolean FullCharPS (VOID)
+{
+ /* Display filled rectangle approximating the extent of PostScript glyph. */
+
+ 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;
+
+ _REC_chartable * chartab = (_REC_chartable *) NULL;
+ _REC_pixeltable * pixtab = (_REC_pixeltable *) NULL;
+
+ chartab = &thischarinfo->chartable[thischar];
+ 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;
+
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, scaledheight,
+ chartab->code);
+ }
+ /* visible part */
+ }
+
+ return true;
+}
+/* FullCharPS */
+#endif /* FULL_CHAR_PS */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void NotFound (Char *fspec)
+#else
+Static Void NotFound (fspec)
+Char *fspec;
+#endif
+{
+ StartText();
+ ResetVDU(); /* do before message since it might erase screen! */
+
+ MesgString ("Couldn't open font ");
+ MesgString (fspec);
+ MesgChar ('!');
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+}
+/* 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 (VOID)
+{
+ /* 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; /* 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
+ {
+ string dummyspec;
+ BuildFileSpec (pkdir, dummy_pk, dummyspec);
+ if (!OpenFontFile (dummyspec))
+ NotFound (dummyspec);
+ }
+ 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 (VOID)
+{
+ /* 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
+#ifdef FULL_CHAR_PS
+ FullCharPS();
+#else
+ BoxChar();
+#endif
+ }
+ 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 = Cap (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 */
+ goto _L999;
+
+ } /* if */
+ } /* if */
+ } /* inner (for) loop */
+ } /* middle (for) loop */
+ if (fontopen)
+ CloseFontFile();
+ } /* outer (for) loop */
+_L999: ;
+}
+/* DisplayChars */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void PaperMessage (double precision)
+#else
+Static Void PaperMessage (precision)
+ double precision;
+#endif
+{
+ /* Called by CheckPageEdges to remind user of the paper size. */
+
+ WriteUnits();
+
+ MesgString ("! (Paper ");
+ WriteXDim (precision, paperwd);
+ MesgString (" x ");
+ WriteYDim (precision, paperht);
+ MesgChar (')');
+
+ WaitForReturn();
+ ClearMessageLine();
+}
+/* PaperMessage */
+
+/******************************************************************************/
+
+Static Void CheckPageEdges (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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
+ {
+ LogClearScreen();
+ 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)
+ DisplayChars();
+
+ StartText();
+
+ if (pageoffpaper)
+ CheckPageEdges(); /* May write messages */
+
+ if (allpagevisible)
+ {
+ ClearMessageLine();
+ MesgString ("Entire page is visible. ");
+ PadMesg();
+ }
+ }
+
+ fprintf (logfile, "\n");
+ fprintf (logfile, "Displayed Page.\n");
+ MesgFlush();
+}
+/* DisplayPage */
+
+/******************************************************************************/
+/******************************************************************************/
+
+#ifdef __STDC__
+Void ProcessCommandLine (string commstring)
+#else
+Void ProcessCommandLine (commstring)
+ string commstring;
+#endif
+{
+ /* 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 = Cap (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();
+ LogClearScreen();
+ 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 */
+ goto _L999;
+
+ 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();
+ }
+_L999: ;
+}
+/* ProcessCommandLine */
+
+/******************************************************************************/
+
+Static Void NextCommandLine (VOID)
+{
+ /* 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 (VOID)
+{
+ /* close DVI file, reset VDU and restore terminal */
+
+ CloseDVIFile();
+
+ LogClearScreen();
+ screenjustcleared = true;
+
+ MoveToTextLine (1);
+ MesgLine();
+
+ ResetVDU();
+ RestoreTerminal();
+
+ fprintf (logfile, "Closed DVI file, reset VDU, and restored terminal.\n");
+ fflush (logfile);
+}
+/* Finish */
+
+/***************************************************************************/
+
+int OutMem (VOID)
+{
+ /* used in "config.h" to define Malloc() */
+
+ StartText();
+ ResetVDU(); /* do before message since it might erase screen! */
+
+ MesgString ("Out of memory.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+
+ return 0; /* Not Reached */
+}
+/* OutMem */
+
+/***************************************************************************/
+
+Void DefaultLog (VOID)
+{
+ extern FILE * logfile;
+ char * dlf = "dvgt.vlg";
+ logfile = fopen (dlf, "w");
+ if (logfile == (FILE *) NULL)
+ {
+ fprintf (stderr, "Cannot write default log file, `%s'\n", dlf);
+ fprintf (stderr, "logfile will remain NULL: no output will be logged.\n");
+ fprintf (stderr, "\n");
+ }
+ else
+ {
+ extern FILE * def_log;
+ def_log = logfile;
+ fprintf (stderr, "Writing default log file, `%s'.\n", dlf);
+ fprintf (stderr, "\n");
+ fprintf (logfile, "%s\n", dvgt_version);
+ fprintf (logfile, "%s\n", TimeString());
+ fflush (logfile);
+ }
+}
+/* DefaultLog */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void Handler (int sig)
+#else
+Void Handler (sig)
+ int sig;
+#endif
+{
+ /* Handle each of the six kinds of signals listed in the ANSI C K&R book. */
+
+ typedef Void (* PH) __((int));
+ PH prev_handler;
+
+ prev_handler = (PH) signal (sig, Handler);
+ if (prev_handler == SIG_ERR)
+ {
+ MesgString ("signal handling failed in Handler");
+ MesgLine();
+ }
+
+ StartText();
+ ResetVDU(); /* do before message since it might erase screen! */
+ RestoreTerminal();
+
+ MesgString
+ ((sig == SIGABRT ? "SIGABRT = abort signal" :
+ sig == SIGFPE ? "SIGFPE = floating point error" :
+ sig == SIGILL ? "SIGILL = illegal function image, eg, illegal instruction" :
+ sig == SIGINT ? "SIGINT = interactive attention, eg interrupt" :
+ sig == SIGSEGV ? "SIGSEGV = illegal storage access, eg outside memory limits" :
+ sig == SIGTERM ? "SIGTERM = termination request" :
+ "unknown signal"));
+ MesgLine();
+
+ RestoreTerminal(); /* just to be sure */
+ exit (1);
+}
+/* Handler */
+
+/******************************************************************************/
+
+Void TrapInterrupts (VOID)
+{
+ /* trap interrupts, to allow screen reset before exit */
+ typedef Void (* PH) __((int));
+ PH prev_handler;
+ int i;
+ for (i=0; i < sizeof (common_signals) / sizeof (int); i++)
+ {
+ prev_handler = (PH) signal (common_signals[i], Handler);
+ if (prev_handler == SIG_ERR)
+ {
+ MesgString ("dvgt: signal handling failed at outset!");
+ MesgLine();
+ }
+ }
+}
+/* TrapInterrupts */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int main (int argc, Char *argv[])
+#else
+int main (argc, argv)
+ int argc; Char * argv[];
+#endif
+{
+ P_argv = argv;
+ P_argc = argc;
+
+ save_init_tty(); /* save initial terminal settings, early */
+
+ textlinewidth = 80; /* for the initial screen type */
+
+ fprintf (stderr, "%s\n", dvgt_version);
+
+ if (argc <= 1) /* No commandline arguments: assume user is new */
+ {
+ char * env;
+ stringcopy (immed_help, (!(env = getenv ("DV_IMMED_HELP")) ?
+ DEF_IMMED_HELP : env));
+ /* If this file cannot be printed, print the precompiled information */
+ if (!PrintFile (immed_help))
+ PrintText (immed_help_strings);
+ }
+ else
+ {
+ DefaultLog(); /* until a DVI-file-specific log's established */
+ InitOptions(); /* initialise DVIname and command options */
+ if (DVIname == (char *) NULL || strlen (DVIname) == 0
+ || DVIname[0] == ' ')
+ {
+ /* gt - Eventually, I want to load DVI files interactively. */
+ DefaultLog(); /* NOT REACHED; JUST EXITED ! */
+ MesgString ("This line is not reached !!");
+ MesgLine();
+ }
+ else
+ {
+ Char STR1[2];
+ /* stem length of DVI file's name */
+ size_t dvilen = strcspn (DVIname, ".");
+ /* Allocate dvilen+4+1 chars, fill them with NUL characters. */
+ /* This is enough space for DVI file name's stem, plus ".vlg", */
+ /* plus a terminating NUL character. */
+ char * logfilename = cnew (dvilen+4+1, char);
+ if (logfilename == (char *) NULL)
+ {
+ fprintf (stderr, "Cannot allocate memory for log file's name!\n");
+ fprintf (stderr, "Using default log file name.\n");
+ DefaultLog();
+ }
+ else
+ {
+ strncpy (logfilename, DVIname, dvilen);
+ /* ".vlg" stands for "viewer log" */
+ /* enough space has been allocated to logfilename for this */
+ strcat (logfilename, ".vlg");
+ logfile = fopen (logfilename, "w");
+ if (logfile == (FILE *) NULL)
+ {
+ fprintf (stderr, "Cannot write a log file named `%s'!\n",
+ logfilename);
+ fprintf (stderr, "Using default log file name.\n");
+ DefaultLog();
+ }
+ else
+ {
+ fprintf (stderr, "Now using log file named `%s'.\n", logfilename);
+ fprintf (stderr, "\n");
+ fprintf (def_log, "Now using log file named `%s'.\n", logfilename);
+ fprintf (def_log, "\n");
+ fflush (def_log);
+ fprintf (logfile, "%s\n", dvgt_version);
+ fprintf (logfile, "%s\n", TimeString());
+ fflush (logfile);
+ }
+ }
+
+ TrapInterrupts();
+ 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();
+ LogClearScreen();
+ 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();
+ } /* if */
+ } /* if */
+ return 0; /* OK */
+}
+/* main() program of DVItoVDU */
+
+/* end dvitovdu.c */
diff --git a/dviware/dvgt/dvgt/src/files.h b/dviware/dvgt/dvgt/src/files.h
new file mode 100644
index 0000000000..8ef0fd4ea7
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/files.h
@@ -0,0 +1,20 @@
+/* files.h - 20:00 GMT +10:00 Thu 22 July 1993 - modified by Geoffrey Tobin */
+
+#ifndef FILES_H
+#define FILES_H
+
+/* Include file ../include/files.h from fontreader.c */
+
+/* Random file access routines; used in DVIReader and FontReader */
+/* 0 = success, 1 = error */
+
+/* SYSDEP: read-only flag, O_RDONLY, for open: defined in <fcntl.h> */
+
+#include <fcntl.h>
+
+#define bufflen 1024 /* size of buffer for holding DVI/PK bytes */
+typedef unsigned char buffer[bufflen];
+
+#endif /* FILES_H */
+
+/* end files.h */
diff --git a/dviware/dvgt/dvgt/src/fontreader.c b/dviware/dvgt/dvgt/src/fontreader.c
new file mode 100644
index 0000000000..612f347656
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/fontreader.c
@@ -0,0 +1,2002 @@
+/* fontreader.c - 19:53 GMT +10:00 Thu 29 July 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "files.h"
+#include "screenio.h"
+#include "vdu.h"
+#include "options.h"
+#include "dvireader.h"
+#include "fontreader.h"
+
+#include "new.h"
+#include "lstring.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];
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean CheckFontPtr (fontinfo * fontptr)
+#else
+boolean CheckFontPtr (fontptr)
+ fontinfo * fontptr;
+#endif
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean BuildFileSpec (const char * areas, const char * name, string spec)
+#else
+boolean BuildFileSpec (areas, name, spec)
+ char * areas, * name;
+ string spec;
+#endif
+{
+ /* Build a complete file specification in spec.
+ Firstly, test for valid areas and name.
+ */
+
+ boolean found = false, more = false;
+ string paths;
+ char * s = (char *) NULL;
+ LString * Lspec = NewLString (maxfontspec);
+
+ if (areas == (char *) NULL)
+ {
+ MesgString ("NULL areas passed to BuildFileSpec!");
+ MesgLine();
+ return false;
+ }
+ else if (strlen (areas) == 0)
+ {
+ MesgString ("Zero length areas passed to BuildFileSpec!");
+ MesgLine();
+ return false;
+ }
+
+ if (name == (char *) NULL)
+ {
+ MesgString ("NULL file name passed to BuildFileSpec!");
+ MesgLine();
+ return false;
+ }
+ else if (strlen (name) == 0)
+ {
+ MesgString ("Zero length file name passed to BuildFileSpec!");
+ MesgLine();
+ return false;
+ }
+
+ /* copy areas to paths because strtok() overwrites */
+ strncpy (paths, areas, maxfontspec);
+ paths[maxfontspec] = '\0'; /* to be careful */
+
+ found = false;
+ more = true;
+
+ /* loop for each directory listed in paths */
+ for (s = paths; !found && more; s = (char *) NULL)
+ {
+ /* NOTE: strtok returns NULL if all characters of s occur in DIRSEP */
+ char * onepath = strtok (s, DIRSEP); /* Hope strtok is common in C's */
+ if (onepath == (char *) NULL)
+ {
+ more = false;
+ }
+ else
+ {
+ /* start file spec. with one directory */
+ Scopys (Lspec, onepath);
+ Scats (Lspec, "/");
+
+ /* append name */
+ Scats (Lspec, name);
+
+ strncpy (spec, Lspec->s, maxfontspec);
+ spec[maxfontspec] = '\0'; /* to be careful */
+
+ /* check whether file exists where spec indicates */
+ { /* start block */
+ FILE * fp = fopen (spec, "r");
+ if (fp != (FILE *) NULL)
+ {
+ fclose (fp);
+ found = true;
+ }
+ } /* end block */
+ } /* fi */
+ } /* loop for each directory listed in paths */
+
+ FreeLString (Lspec);
+
+ return found;
+}
+/* BuildFileSpec */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean BuildTFMSpec (fontinfo *tfmptr)
+#else
+Static boolean BuildTFMSpec (tfmptr)
+ fontinfo *tfmptr;
+#endif
+{
+ /* Build a complete TFM file specification in tfmptr->fontspec.
+ This will be done at most once per font.
+ Test for valid tfmptr->fontname.
+ ASSUMPTIONS:
+ tfmptr->fontname contains the basename of the font.
+ SIDE EFFECTS on success:
+ tfmptr->fontspec will be set.
+ tfmptr->fontspeclen will no longer be 0.
+ tfmptr->fontexists becomes TRUE if the TFM file can be opened,
+ FALSE, if it cannot.
+ tfmptr->pkfont becomes FALSE.
+ (tfmptr->psfont is unaffected.)
+ SIDE EFFECTS on failure:
+ EITHER:
+ tfmptr is NULL.
+ OR:
+ tfmptr->fontspec will be unset (holds empty string "").
+ tfmptr->fontspeclen will be 0.
+ tfmptr->fontexists becomes FALSE.
+ tfmptr->pkfont becomes FALSE.
+ tfmptr->psfont becomes FALSE.
+ */
+
+ boolean found = false, more = false;
+ string tfmdirs;
+ char * s = (char *) NULL;
+ LString * Ltfmspec = NewLString (maxfontspec);
+
+ if (!CheckFontPtr (tfmptr))
+ return false;
+
+ /* Initialise correctly */
+ strncpy (tfmptr->fontspec, "", maxfontspec);
+ tfmptr->fontspeclen = 0;
+ tfmptr->fontexists = false;
+ tfmptr->pkfont = false;
+
+ /* tfmptr->fontarea has been read from DVI file. */
+ /* See "dvireadr.c". */
+ /* We normally expect fontarea to be empty, for portability. */
+
+ if (tfmptr->fontarealen > 0)
+ {
+ /* start TFM spec. with fontarea as read from DVI file */
+ strncpy (tfmdirs, tfmptr->fontarea, maxfontspec);
+ tfmdirs[maxfontspec] = '\0'; /* to be careful */
+ }
+ else
+ {
+ /* start TFM spec. with each directory from tfmdir, */
+ /* as set in "options.c" */
+ strncpy (tfmdirs, tfmdir, maxfontspec);
+ tfmdirs[maxfontspec] = '\0'; /* to be careful */
+ }
+
+ found = false;
+ more = true;
+
+ /* loop for each TFM directory listed in tfmdirs */
+ for (s = tfmdirs; !found && more; s = (char *) NULL)
+ {
+ /* NOTE: strtok returns NULL if all characters of s occur in DIRSEP */
+ char * onetfmdir = strtok (s, DIRSEP);
+ if (onetfmdir == (char *) NULL)
+ {
+ more = false;
+ }
+ else
+ {
+ /* start TFM spec. with one TFM directory */
+ Scopys (Ltfmspec, onetfmdir);
+ Scats (Ltfmspec, "/");
+
+ /* append <fontname>.tfm */
+ Scats (Ltfmspec, tfmptr->fontname);
+ Scats (Ltfmspec, ".tfm");
+
+ strncpy (tfmptr->fontspec, Ltfmspec->s, maxfontspec);
+ tfmptr->fontspec[maxfontspec] = '\0'; /* to be careful */
+ tfmptr->fontspeclen = strlen (tfmptr->fontspec); /* quite important */
+
+ /* check whether TFM file exists where tfmptr->fontspec indicates */
+ { /* start block */
+ FILE * fp = fopen (tfmptr->fontspec, "r");
+ if (fp != (FILE *) NULL)
+ {
+ fclose (fp);
+ tfmptr->fontexists = true;
+ tfmptr->pkfont = false;
+ found = true;
+ }
+ } /* end block */
+ } /* fi */
+ } /* loop for each TFM directory listed in tfmdirs */
+
+ FreeLString (Ltfmspec);
+
+ /* Finalise correctly */
+ if (!found)
+ {
+ strncpy (tfmptr->fontspec, "", maxfontspec);
+ tfmptr->fontspeclen = 0;
+ tfmptr->fontexists = false;
+ tfmptr->pkfont = false;
+ tfmptr->psfont = false;
+ }
+
+ return found;
+}
+/* BuildTFMSpec */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean
+FndFileInDir (Char *area, Char *name, int mag, fontinfo *pkfp)
+#else
+Static boolean
+FndFileInDir (area, name, mag, pkfp)
+ Char *area; Char *name; int mag; fontinfo *pkfp;
+#endif
+{
+ /* Seek file <name>.<mag>pk in directory <area>/<name> or <area> .
+ If it's found, then store that file spec. in pkfp->fontspec,
+ set pkfp->fontspeclen to the length of that file spec,
+ and return true.
+ If the file spec. is truncated, or the file is not found,
+ then return false.
+ */
+
+ boolean status = false;
+ char s[BUFSIZ];
+ int len;
+
+ /* Does file exist? (BSD, POSIX have "#define F_OK 0".) */
+ (Void) sprintf (s, "%s/%s/%s.%dpk", area, name, name, mag);
+ if (access (s, 0))
+ (Void) sprintf (s, "%s/%s.%dpk", area, name, mag);
+
+ (Void) strncpy (pkfp->fontspec, s, maxfontspec);
+ pkfp->fontspec[maxfontspec] = '\0'; /* to be careful */
+ pkfp->fontspeclen = strlen (pkfp->fontspec);
+
+ len = strlen (s);
+ if (len > maxfontspec)
+ {
+ fprintf (logfile, "PK font's spec. length = %d\n", pkfp->fontspeclen);
+ fprintf (logfile, "PK font's spec. = %s\n", pkfp->fontspec);
+ fprintf (logfile, "That PK font's spec. was truncated!\n");
+ fflush (logfile);
+
+ status = false;
+ }
+ else
+ {
+ /* Can file be read? (BSD, POSIX have "#define R_OK 4".) */
+ if (!access (pkfp->fontspec, 4))
+ status = true;
+ else
+ status = false;
+ }
+ return status;
+}
+/* FndFileInDir */
+
+/******************************************************************************/
+
+#define PK_MAGIC 4
+
+#ifdef __STDC__
+Static boolean BuildPKSpec (fontinfo * pkptr)
+#else
+Static boolean BuildPKSpec (pkptr)
+fontinfo * pkptr;
+#endif
+{
+ /* Build a complete PK file specification in pkptr->fontspec.
+ This will be done at most once per font.
+ Test for valid pkptr->fontname.
+ Rounding error in resolution requires an off-by-one check.
+ ASSUMPTIONS:
+ The global variables mag and xres must be defined.
+ pkptr->scaledsize and pkptr->designsize must be defined.
+ pkptr->fontname contains the basename of the font.
+ SIDE EFFECTS on success:
+ pkptr->fontspec will be set.
+ pkptr->fontspeclen will no longer be 0.
+ pkptr->fontexists becomes TRUE if the PK file can be opened,
+ FALSE, if it cannot.
+ pkptr->pkfont becomes TRUE if the PK file can be opened,
+ FALSE, if it cannot.
+ pkptr->psfont becomes FALSE;
+ SIDE EFFECTS on failure:
+ EITHER:
+ pkptr is NULL.
+ OR:
+ pkptr->fontspec will be unset (holds empty string "").
+ pkptr->fontspeclen will be 0.
+ pkptr->fontexists becomes FALSE.
+ pkptr->pkfont becomes FALSE.
+ pkptr->psfont becomes FALSE;
+ */
+
+ extern string pkdir;
+
+ boolean found = false, more = true;
+ string pkdir2;
+ char * s = (char *) NULL;
+
+ if (!CheckFontPtr (pkptr))
+ return false;
+
+ /* Initialise correctly */
+ strncpy (pkptr->fontspec, "", maxfontspec);
+ pkptr->fontspeclen = 0;
+ pkptr->fontexists = false;
+ pkptr->pkfont = false;
+ pkptr->psfont = false;
+
+ stringcopy (pkdir2, pkdir);
+
+ found = false;
+ more = true;
+
+ /* loop for each directory in pkdir2 */
+ for (s = pkdir2; !found && more; s = (char *) NULL)
+ {
+ char * onepkdir = (char *) NULL;
+ int fontsize;
+ int tempsize, tempsizelen;
+ int i;
+
+ /* NOTE: strtok returns NULL if all characters of s occur in DIRSEP */
+ onepkdir = strtok (s, DIRSEP);
+ if (onepkdir == (char *) NULL)
+ {
+ more = false;
+ }
+ else
+ {
+ string fontname;
+ int onepkdirlen = strlen (onepkdir);
+
+ /* To be careful: */
+ if (onepkdirlen >= maxfontspec)
+ {
+ onepkdirlen = maxfontspec - 1;
+
+ fprintf (logfile, "The PK directory `%s' was just truncated!\n",
+ onepkdir);
+ fflush (logfile);
+ }
+
+ strncpy (fontname, pkptr->fontname, maxfontspec);
+ fontname[maxfontspec] = '\0'; /* to be careful */
+
+ /* start PK spec. with one PK dir */
+ strncpy (pkptr->fontspec, onepkdir, maxfontspec-1);
+ pkptr->fontspec[maxfontspec] = '\0'; /* to be careful */
+ pkptr->fontspeclen = strlen (pkptr->fontspec);
+
+ pkptr->fontspec[onepkdirlen] = '/';
+ pkptr->fontspec[onepkdirlen + 1] = '\0';
+
+ /* gt - I hope "xres" is the right thing to use for the font size */
+ fontsize = (int) (mag / 1000.0
+ * (double) pkptr->scaledsize / pkptr->designsize
+ * xres
+ + 0.5);
+
+ if (fontsize == 0) /* allow for subtracting 1 */
+ ++ fontsize;
+
+ tempsize = fontsize;
+
+ for (i=0; true; i++) /* loop for adjacent font sizes */
+ {
+ /* Complete rest of fontspec,
+ and return the position of first digit for fontsize.
+ We have to try fontsize +/- 1 before giving up because
+ rounding problems can occur in the above fontsize calculation.
+ */
+
+ { /* start block for tempsizelen */
+ /* count decimal digits in tempsize */
+ int j = tempsize;
+ tempsizelen = 0;
+ while (j > 0)
+ {
+ ++ tempsizelen;
+ j /= 10;
+ }
+ } /* end block for tempsizelen */
+
+ /* gt - WHAT and WHY is this MAGIC NUMBER (4) here? */
+ if ((pkptr->fontnamelen + tempsizelen + PK_MAGIC)
+ > sizeof (fontname))
+ {
+ break;
+ }
+
+ if (FndFileInDir (onepkdir, fontname, tempsize, pkptr))
+ {
+ pkptr->fontexists = true; /* specified PK file exists */
+ pkptr->pkfont = true;
+ pkptr->psfont = false;
+ found = true;
+ break;
+ }
+ else if (i > 2) /* original fontsize has been restored */
+ {
+ break;
+ }
+ else
+ {
+ if (i == 0)
+ tempsize = fontsize - 1; /* try fontsize-1 */
+ else if (i == 1)
+ tempsize = fontsize + 1; /* try fontsize+1 */
+ else /* i == 2 */
+ tempsize = fontsize; /* restore original fontsize */
+ } /* inner if */
+ } /* inner loop for adjacent font sizes */
+ } /* outer if */
+ } /* end loop for each directory in pkdir2 */
+
+ /* Finalise correctly */
+ if (!found)
+ {
+ strncpy (pkptr->fontspec, "", maxfontspec);
+ pkptr->fontspeclen = 0;
+ pkptr->fontexists = false;
+ pkptr->pkfont = false;
+ pkptr->psfont = false;
+ }
+
+ return found;
+}
+/* BuildPKSpec */
+
+#undef PK_MAGIC
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean BuildFontSpec (fontinfo * fontptr)
+#else
+boolean BuildFontSpec (fontptr)
+ fontinfo * fontptr;
+#endif
+{
+ /* 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->psfont becomes TRUE if the font's a PS or pure TFM font
+ file that 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->psfont becomes FALSE;
+ fontptr->honest becomes FALSE.
+ */
+
+ boolean status = false; /* success? */
+
+ if (!CheckFontPtr (fontptr))
+ return false;
+
+ /**** Correct PK ? ****/
+
+ if (fontptr->fontspeclen == 0)
+ {
+ /* Try PK bitmap font. */
+ status = BuildPKSpec (fontptr);
+ }
+
+ if (fontptr->fontexists)
+ {
+ fontptr->pkfont = true;
+ fontptr->psfont = false;
+ fontptr->honest = true;
+
+ fprintf (logfile, "Loading PK font file `%s'.\n", fontptr->fontspec);
+ fflush (logfile);
+ }
+ else
+ {
+ /* PK font file doesn't exist. */
+
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+#ifdef DEBUG
+ fprintf (logfile, "Couldn't fopen PK font file `%s'!\n",
+ (fontptr->fontspeclen == 0 ?
+ fontptr->fontname : fontptr->fontspec));
+ fflush (logfile);
+#endif /* DEBUG */
+
+ } /* fi */
+
+ /* POSTSCRIPT OR PURE TFM ? */
+
+ /* Check for a PostScript font; if font is PS, then psfont becomes TRUE.
+ NOTE that strtok skips sequences of separators, and does not make
+ empty tokens. Therefore, we cannot set an empty PS prefix in order
+ to treat all missing PK fonts as PS fonts.
+ */
+
+ if (!fontptr->fontexists)
+ {
+ string prefixes;
+ char * seps = DIRSEP; /* use same separators as (PK and TFM) dir's! */
+ char * ptr = (char *) NULL;
+ boolean more;
+
+ strncpy (prefixes, psprefix, maxstring); /* !May TRUNCATE! */
+ ptr = prefixes;
+
+ do
+ {
+ char * prefix = strtok (ptr, seps); /* Hope strtok is common in C's */
+ more = (prefix != (char *) NULL);
+ if (more)
+ {
+ ptr = (char *) NULL; /* ready for next iteration */
+ if (strncmp (fontptr->fontname, prefix, strlen (prefix)) == 0
+ && (status = BuildTFMSpec (fontptr)) == true
+ && fontptr->fontexists)
+ {
+ fontptr->psfont = true;
+ fontptr->honest = true;
+ fontptr->pkfont = false;
+ }
+ else
+ {
+ fontptr->psfont = false;
+ fontptr->pkfont = false;
+ fontptr->honest = false;
+ } /* if */
+ } /* if */
+ }while (more && !fontptr->psfont);
+ if (fontptr->psfont)
+ {
+ fprintf (logfile, "Loading PostScript font TFM `%s'.\n",
+ fontptr->fontspec);
+ fflush (logfile);
+ }
+ else
+ {
+
+#ifdef DEBUG
+ fprintf (logfile, "`%s' is not a PostScript font.\n",
+ fontptr->fontname);
+ fflush (logfile);
+#endif /* DEBUG */
+
+ }
+ } /* if */
+
+ /**** Dummy PK? ****/
+
+ if (!fontptr->fontexists)
+ {
+ /* Try dummy PK font. */
+
+ string dummyspec;
+
+ if (BuildFileSpec (pkdir, dummy_pk, dummyspec))
+ {
+ /* Fill pixeltable with dummy_pk values. */
+
+ fontptr->fontexists = true;
+ fontptr->pkfont = true;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+ strncpy (fontptr->fontspec, dummyspec, maxfontspec);
+ fontptr->fontspeclen = strlen (fontptr->fontspec);
+ status = true;
+
+ fprintf (logfile, "Using dummy PK font `%s'\n", dummyspec);
+ fflush (logfile);
+ }
+ else
+ {
+ /* dummy PK font file doesn't exist. */
+
+ fontptr->fontexists = false;
+
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+#ifdef DEBUG
+ fprintf (logfile, "Couldn't fopen dummy PK font file `%s'!\n",
+ (fontptr->fontspeclen == 0 ?
+ fontptr->fontname : fontptr->fontspec));
+ fflush (logfile);
+#endif /* DEBUG */
+
+ }
+ } /* fi */
+
+ /**** Correct TFM? ****/
+
+ if (!fontptr->fontexists)
+ {
+ /* Try the correct font's TFM metric. */
+
+ status = BuildTFMSpec (fontptr);
+
+ if (fontptr->fontexists)
+ {
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = true;
+
+ fprintf (logfile, "Loading TFM metric file for `%s'.\n",
+ fontptr->fontname);
+ fflush (logfile);
+ }
+ else
+ {
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+#ifdef DEBUG
+ fprintf (logfile, "Couldn't fopen TFM metric file `%s'!\n",
+ (fontptr->fontspeclen == 0 ?
+ fontptr->fontname : fontptr->fontspec));
+ fflush (logfile);
+#endif /* DEBUG */
+
+ }
+ } /* fi */
+
+ /**** Dummy TFM? ****/
+
+ if (!fontptr->fontexists)
+ {
+ /* Try dummy TFM metric. */
+
+ string dummyspec;
+
+ if (BuildFileSpec (pkdir, dummy_tfm, dummyspec))
+ {
+ status = true;
+ fontptr->fontexists = true;
+
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+ strncpy (fontptr->fontspec, dummyspec, maxfontspec);
+ fontptr->fontspeclen = strlen (fontptr->fontspec);
+
+ fprintf (logfile, "Using dummy TFM `%s'.\n", dummyspec);
+ fflush (logfile);
+ }
+ else
+ {
+ status = false;
+ fontptr->fontexists = false;
+
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+#ifdef DEBUG
+ fprintf (logfile, "Couldn't fopen dummy TFM metric file `%s'!\n",
+ (fontptr->fontspeclen == 0 ?
+ fontptr->fontname : fontptr->fontspec));
+ fflush (logfile);
+#endif /* DEBUG */
+
+ }
+ } /* fi */
+
+ /**** Resort to Terse display of this font, using DVI info. ****/
+
+ if (!fontptr->fontexists)
+ {
+ /* Ran out of options. */
+
+ fontptr->pkfont = false;
+ fontptr->psfont = false;
+ fontptr->honest = false;
+
+ status = false;
+
+#ifdef DEBUG
+ fprintf (logfile, "No correct PK or TFM for `%s'\n", fontptr->fontname);
+ fprintf (logfile, " nor dummy PK `%s'\n", dummy_pk);
+ fprintf (logfile, " nor dummy TFM `%s'\n", dummy_tfm);
+ fflush (logfile);
+#endif /* DEBUG */
+
+ fprintf (logfile, "Using DVI Terse display for `%s'\n", fontptr->fontname);
+ fflush (logfile);
+
+ } /* fi */
+
+ return status;
+}
+/* BuildFontSpec */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean OpenFontFile (Char *name)
+#else
+boolean OpenFontFile (name)
+Char *name;
+#endif
+{
+ /* 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 (VOID)
+{
+ /* If there is a currently open font file, then close it. */
+
+ if (PTfile >= 0)
+ {
+ (Void) close (PTfile);
+ /* Be cautious: ensure PTfile is negative, after this function. */
+ if (PTfile >= 0)
+ PTfile = -1;
+ }
+}
+/* CloseFontFile */
+
+/******************************************************************************/
+
+Static int GetPTByte (VOID)
+{
+ /* 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 */
+
+ MesgString ("PTfile not open in GetPTByte!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ result = lseek (PTfile, buffstart, 0);
+ /* DEBUG
+ IF result <> buffstart THEN BEGIN
+ writeln ('Lseek failed in GetPTByte!'); RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+ if (result != buffstart)
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ MesgString ("lseek failed in GetPTByte!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ result = read (PTfile, PTbuffer, bufflen);
+ /* DEBUG
+ IF result = -1 THEN BEGIN
+ writeln ('Read failed in GetPTByte!'); RestoreTerminal; EXIT (1);
+ END;
+ GUBED */
+ if (result == -1)
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ MesgString ("Read failed in GetPTByte!");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ }
+ Result = PTbuffer[PToffset - buffstart];
+ PToffset++;
+ return Result;
+}
+/* GetPTByte */
+
+/******************************************************************************/
+
+Static int SignedPTByte (VOID)
+{
+ /* the next byte, signed */
+ int b;
+
+ b = GetPTByte();
+ if (b < 128)
+ return b;
+ else
+ return (b - 256);
+}
+/* SignedPTByte */
+
+/******************************************************************************/
+
+Static int GetTwoPTBytes (VOID)
+{
+ /* the next 2 bytes, unsigned */
+ int a, b;
+
+ a = GetPTByte();
+ b = GetPTByte();
+ return (a * 256 + b);
+}
+/* GetTwoPTBytes */
+
+/******************************************************************************/
+
+Static int SignedPTPair (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean GetBitmap (int ht, int wd, int mapadr, int_or_mptr *bitmap)
+#else
+boolean GetBitmap (ht, wd, mapadr, bitmap)
+ int ht; int wd; int mapadr; int_or_mptr * bitmap;
+#endif
+{
+ /* 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 = cnew (bitmapwords, Word);
+ if (bitmapptr == (Word *) NULL)
+ {
+ MesgString ("Character too big! size=");
+ MesgInt (bitmapwords);
+ MesgLine();
+
+ OutMem();
+
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int FixToDVI (int scale, int b0, int b1, int b2, int b3)
+#else
+Static int FixToDVI (scale, b0, b1, b2, b3)
+ /* scale = currfont->scaledsize; */
+ int scale;
+ /* fix width: 4 bytes */
+ int b0, b1, b2, b3;
+#endif
+{
+ /* 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;
+ }
+
+ if (beta == 0)
+ {
+ fprintf (logfile, "FixToDVI: beta = 0, so divide by zero imminent!\n");
+ fflush (logfile);
+ }
+
+ 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 */
+
+ MesgString ("Bad TFM width! 1st byte=");
+ MesgInt (b0);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ return dviwidth;
+}
+/* FixToDVI */
+
+/******************************************************************************/
+
+#define pkid 89
+#define pkpost 245
+#define pknoop 246
+#define pkpre 247
+
+#ifdef __STDC__
+Static Void PKFillPixelTable (fontinfo * currfont)
+#else
+Static Void PKFillPixelTable (currfont)
+ fontinfo * currfont;
+#endif
+{
+ /* 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 */
+
+ MesgString ("Bad PK pre command in `");
+ MesgString (currfont->fontspec);
+ MesgString ("'");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ if (GetPTByte() != pkid)
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ MesgString ("Bad PK id byte in `");
+ MesgString (currfont->fontspec);
+ MesgString ("'");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ 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 */
+
+ MesgString ("Bad PK flag byte in `");
+ MesgString (currfont->fontspec);
+ MesgString ("'");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+
+ break;
+ }
+ } /* of LOOP; flagbyte = pkpost */
+_L888: ;
+
+ /* extended short char preamble */
+ /* long char preamble */
+}
+/* PKFillPixelTable */
+
+#undef pkid
+#undef pkpost
+#undef pknoop
+#undef pkpre
+
+/******************************************************************************/
+
+Static Void ReadTFMIntegers (VOID)
+{
+ /* 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. */
+
+ string out; /* output string for messages */
+
+ 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 */
+
+ sprintf (out, "TFM file length given as: lf = %d words.", lf);
+ MesgString (out);
+ MesgLine();
+ sprintf (out, " Should have 0 <= lf < %d words.", 1<<15);
+ MesgString (out);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* sanity check of lh */
+ if (! (2 <= lh))
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ sprintf (out, "TFM's Header length given as: lh = %d words.", lh);
+ MesgString (out);
+ MesgLine();
+ MesgString (" Should have lh >= 2 (two) words.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* sanity check of bc and ec */
+ if ( ! (0 <= bc && bc-1 <= ec && ec <= maxTeXchar))
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ sprintf (out, "First & last char codes = (bc, ec) = (%d, %d).", bc, ec);
+ MesgString (out);
+ MesgLine();
+ MesgString (" Should have 0 <= bc <= ec <= maxTeXchar = 255.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* sanity check of nw */
+ if ( ! (0 <= nw && nw < 1<<15))
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ sprintf (out, "Number of Width Table words given as: nw = %d.", nw);
+ MesgString (out);
+ MesgLine();
+ sprintf (out, " Should have 0 <= nw < %d words.", 1<<15);
+ MesgString (out);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* sanity check of nh */
+ if ( ! (0 <= nh && nh < 1<<15))
+ {
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ sprintf (out, "Number of Height Table words given as: nh = %d", nh);
+ MesgString (out);
+ MesgLine();
+ sprintf (out, " Should have 0 <= nh < %d.", 1<<15);
+ MesgString (out);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+}
+/* ReadTFMIntegers */
+
+/******************************************************************************/
+
+Static Void ReadTFMCharInfo (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void TFMFillPixelTable (fontinfo * currfont)
+#else
+Static Void TFMFillPixelTable (currfont)
+ fontinfo * currfont;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+/* number of characters in CM fonts */
+#define CMSIZE 128
+
+#ifndef OLD_CHARDIM
+ /* Data taken from cmr10.pl = most common font (so usual dummy font) : */
+ /* (width, height, depth, italic correction) of each cmr10 character */
+ struct {double wd, ht, dp, ic;} cmr10[CMSIZE] =
+ {
+ {0.625002, 0.683332, 0, 0}, /* 00 */
+ {0.833336, 0.683332, 0, 0}, /* 01 */
+ {0.777781, 0.683332, 0, 0}, /* 02 */
+ {0.694446, 0.683332, 0, 0}, /* 03 */
+ {0.666669, 0.683332, 0, 0}, /* 04 */
+ {0.750002, 0.683332, 0, 0}, /* 05 */
+ {0.722224, 0.683332, 0, 0}, /* 06 */
+ {0.777781, 0.683332, 0, 0}, /* 07 */
+ {0.722224, 0.683332, 0, 0}, /* 08 */
+ {0.777781, 0.683332, 0, 0}, /* 09 */
+ {0.722224, 0.683332, 0, 0}, /* 0A */
+ {0.583336, 0.694445, 0, 0.077779}, /* 0B */
+ {0.555557, 0.694445, 0, 0}, /* 0C */
+ {0.555557, 0.694445, 0, 0}, /* 0D */
+ {0.833336, 0.694445, 0, 0}, /* 0E */
+ {0.833336, 0.694445, 0, 0}, /* 0F */
+ {0.277779, 0.430555, 0, 0}, /* 10 */
+ {0.305557, 0.430555, 0.194445, 0}, /* 11 */
+ {0.500002, 0.694445, 0, 0}, /* 12 */
+ {0.500002, 0.694445, 0, 0}, /* 13 */
+ {0.500002, 0.628473, 0, 0}, /* 14 */
+ {0.500002, 0.694445, 0, 0}, /* 15 */
+ {0.500002, 0.567777, 0, 0}, /* 16 */
+ {0.750002, 0.694445, 0, 0}, /* 17 */
+ {0.444446, 0, 0.170138, 0}, /* 18 */ /* sic : no height, only depth */
+ {0.500003, 0.694445, 0, 0}, /* 19 */
+ {0.722224, 0.430555, 0, 0}, /* 1A */
+ {0.777781, 0.430555, 0, 0}, /* 1B */
+ {0.500002, 0.527779, 0.097223, 0}, /* 1C */
+ {0.902781, 0.683332, 0, 0}, /* 1D */
+ {1.013891, 0.683332, 0, 0}, /* 1E */
+ {0.777781, 0.731944, 0.048612, 0}, /* 1F */
+ {0.277779, 0.430555, 0, 0}, /* 20 */
+ {0.277779, 0.694445, 0, 0}, /* 21 */
+ {0.500002, 0.694445, 0, 0}, /* 22 */
+ {0.833336, 0.694445, 0.194443, 0}, /* 23 */
+ {0.500002, 0.75, 0.055555, 0}, /* 24 */
+ {0.833336, 0.75, 0.055555, 0}, /* 25 */
+ {0.777781, 0.694445, 0, 0}, /* 26 */
+ {0.277779, 0.694445, 0, 0}, /* 27 */
+ {0.388889, 0.75, 0.25, 0}, /* 28 */
+ {0.388889, 0.75, 0.25, 0}, /* 29 */
+ {0.500002, 0.75, 0, 0}, /* 2A */
+ {0.777781, 0.583334, 0.194443, 0}, /* 2B */
+ {0.277779, 0.105556, 0.055555, 0}, /* 2C */
+ {0.333334, 0.430555, 0, 0}, /* 2D */
+ {0.277779, 0.105556, 0, 0}, /* 2E */
+ {0.500002, 0.75, 0.25, 0}, /* 2F */
+ {0.500002, 0.644444, 0, 0}, /* '0' */
+ {0.500002, 0.644444, 0, 0}, /* '1' */
+ {0.500002, 0.644444, 0, 0}, /* '2' */
+ {0.500002, 0.644444, 0, 0}, /* '3' */
+ {0.500002, 0.644444, 0, 0}, /* '4' */
+ {0.500002, 0.644444, 0, 0}, /* '5' */
+ {0.500002, 0.644444, 0, 0}, /* '6' */
+ {0.500002, 0.644444, 0, 0}, /* '7' */
+ {0.500002, 0.644444, 0, 0}, /* '8' */
+ {0.500002, 0.644444, 0, 0}, /* '9' */
+ {0.277779, 0.430555, 0, 0}, /* 3A */
+ {0.277779, 0.430555, 0.194445, 0}, /* 3B */
+ {0.277779, 0.5, 0.194445, 0}, /* 3C */
+ {0.777781, 0.366875, -0.133125, 0}, /* 3D */
+ {0.472224, 0.5, 0.194445, 0}, /* 3E */
+ {0.472224, 0.694445, 0, 0}, /* 3F */
+ {0.777781, 0.694445, 0, 0}, /* 40 */
+ {0.750002, 0.683332, 0, 0}, /* 'A' */
+ {0.708336, 0.683332, 0, 0}, /* 'B' */
+ {0.722224, 0.683332, 0, 0}, /* 'C' */
+ {0.763891, 0.683332, 0, 0}, /* 'D' */
+ {0.680557, 0.683332, 0, 0}, /* 'E' */
+ {0.652781, 0.683332, 0, 0}, /* 'F' */
+ {0.784724, 0.683332, 0, 0}, /* 'G' */
+ {0.750002, 0.683332, 0, 0}, /* 'H' */
+ {0.361112, 0.683332, 0, 0}, /* 'I' */
+ {0.51389, 0.683332, 0, 0}, /* 'J' */
+ {0.777781, 0.683332, 0, 0}, /* 'K' */
+ {0.625002, 0.683332, 0, 0}, /* 'L' */
+ {0.916669, 0.683332, 0, 0}, /* 'M' */
+ {0.750002, 0.683332, 0, 0}, /* 'N' */
+ {0.777781, 0.683332, 0, 0}, /* 'O' */
+ {0.680557, 0.683332, 0, 0}, /* 'P' */
+ {0.777781, 0.683332, 0.194445, 0}, /* 'Q' */
+ {0.736113, 0.683332, 0, 0}, /* 'R' */
+ {0.555557, 0.683332, 0, 0}, /* 'S' */
+ {0.722224, 0.683332, 0, 0}, /* 'T' */
+ {0.750002, 0.683332, 0, 0}, /* 'U' */
+ {0.750002, 0.683332, 0, 0.013888}, /* 'V' */
+ {1.027781, 0.683332, 0, 0.013888}, /* 'W' */
+ {0.750002, 0.683332, 0, 0}, /* 'X' */
+ {0.750002, 0.683332, 0, 0.025}, /* 'Y' */
+ {0.611113, 0.683332, 0, 0}, /* 'Z' */
+ {0.277779, 0.75, 0.25, 0}, /* 5B */
+ {0.500002, 0.694445, 0, 0}, /* 5C */
+ {0.277779, 0.75, 0.25, 0}, /* 5D */
+ {0.500002, 0.694445, 0, 0}, /* 5E */
+ {0.277779, 0.667859, 0, 0}, /* 5F */
+ {0.277779, 0.694445, 0, 0}, /* 60 */
+ {0.500002, 0.430555, 0, 0}, /* 'a' */
+ {0.555557, 0.694445, 0, 0}, /* 'b' */
+ {0.444446, 0.430555, 0, 0}, /* 'c' */
+ {0.555557, 0.694445, 0, 0}, /* 'd' */
+ {0.444446, 0.430555, 0, 0}, /* 'e' */
+ {0.305557, 0.694445, 0, 0.077779}, /* 'f' */
+ {0.500002, 0.430555, 0.194445, 0}, /* 'g' */
+ {0.555557, 0.694445, 0, 0}, /* 'h' */
+ {0.277779, 0.667859, 0, 0}, /* 'i' */
+ {0.305557, 0.667859, 0.194445, 0}, /* 'j' */
+ {0.527781, 0.694445, 0, 0}, /* 'k' */
+ {0.277779, 0.430555, 0, 0}, /* 'l' */
+ {0.833336, 0.430555, 0, 0}, /* 'm' */
+ {0.555557, 0.430555, 0, 0}, /* 'n' */
+ {0.500002, 0.430555, 0, 0}, /* 'o' */
+ {0.555557, 0.430555, 0.194445, 0}, /* 'p' */
+ {0.527779, 0.430555, 0.194445, 0}, /* 'q' */
+ {0.391668, 0.430555, 0, 0}, /* 'r' */
+ {0.394445, 0.430555, 0, 0}, /* 's' */
+ {0.38889, 0.61508, 0, 0}, /* 't' */
+ {0.555557, 0.430555, 0, 0}, /* 'u' */
+ {0.527781, 0.430555, 0, 0.013888}, /* 'v' */
+ {0.722224, 0.430555, 0, 0.013888}, /* 'w' */
+ {0.527781, 0.430555, 0, 0}, /* 'x' */
+ {0.527781, 0.430555, 0.194445, 0.013888}, /* 'y' */
+ {0.444446, 0.430555, 0, 0}, /* 'z' */
+ {0.500002, 0.430555, 0, 0.027779}, /* 7B */
+ {1.000003, 0.430555, 0, 0.027779}, /* 7C */
+ {0.500002, 0.694445, 0, 0}, /* 7D */
+ {0.500002, 0.667859, 0, 0}, /* 7E */
+ {0.500002, 0.667859, 0, 0}, /* 7F */
+ };
+#endif /* Not OLD_CHARDIM */
+
+
+#ifdef __STDC__
+Static Void AbsentFillPixelTable (fontinfo * currfont)
+#else
+Static Void AbsentFillPixelTable (currfont)
+ fontinfo * currfont;
+#endif
+{
+ /* 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 */
+
+#ifdef OLD_CHARDIM
+ /* 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;
+#else /* Not OLD_CHARDIM */
+ if (c < CMSIZE) /* 0 <= c < CMSIZE */
+ {
+ pix_tab->dwidth = scale * cmr10[c].wd;
+ dheight = scale * cmr10[c].ht;
+ ddepth = scale * cmr10[c].dp;
+ }
+ else /* CMSIZE <= c <= maxTeXchar */
+ {
+ pix_tab->dwidth = 0;
+ dheight = 0;
+ ddepth = 0;
+ }
+#endif /* OLD_CHARDIM */
+
+ /* 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 */
+
+#undef CMSIZE
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void PixelTableRoutine (fontinfo * currfont)
+#else
+Void PixelTableRoutine (currfont)
+ fontinfo * currfont;
+#endif
+{
+ /* 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.
+ */
+
+#ifdef CURRFONT_TRACE
+ fprintf (logfile, "PixelTableRoutine\n");
+ fprintf (logfile, "currfont = %p\n", currfont);
+ fprintf (logfile, "currfont->fontname = `%s'\n", currfont->fontname);
+ fprintf (logfile, "currfont->fontspec = `%s'\n", currfont->fontspec);
+ fprintf (logfile, "currfont->fontspeclen = %d\n", currfont->fontspeclen);
+ fflush (logfile);
+#endif /* CURRFONT_TRACE */
+
+ if (!CheckFontPtr (currfont))
+ return;
+
+ /* Try to find and fopen (& fclose) PK file; if that fails, try TFM file. */
+ if (currfont->fontspeclen == 0)
+ (Void) BuildFontSpec (currfont);
+
+ if (currfont->fontexists && !OpenFontFile (currfont->fontspec))
+ {
+ string mesg;
+
+ StartText();
+ ResetVDU(); /* let message stay */
+
+ sprintf (mesg, "fopen-ed but couldn't open file `%s' for font `%s'",
+ currfont->fontspec, currfont->fontname);
+ MesgString (mesg);
+ MesgLine();
+ fprintf (logfile, "That shouldn't happen.\n");
+ fflush (logfile);
+
+ RestoreTerminal();
+ exit (1);
+ }
+
+ /* 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 (VOID)
+{
+ /* 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/dvgt/dvgt/src/fontreader.h b/dviware/dvgt/dvgt/src/fontreader.h
new file mode 100644
index 0000000000..08bd0c7294
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/fontreader.h
@@ -0,0 +1,20 @@
+/* fontreader.h - 21:10 GMT +10:00 Mon 24 May 1993 - modifier Geoffrey Tobin */
+
+#ifndef FONTREADER_H
+#define FONTREADER_H
+
+/* Include file ../include/fontreader.h from dvitovdu.c */
+
+/* FontReader */
+
+extern Void InitFontReader (VOID);
+extern Void PixelTableRoutine __((fontinfo * currfont));
+extern boolean GetBitmap __((int ht, int wd, int mapadr, int_or_mptr *bitmap));
+extern boolean BuildFileSpec __((const char * areas, const char * name, string spec));
+extern boolean BuildFontSpec __((fontinfo *fontptr));
+extern boolean OpenFontFile __((Char *name));
+extern Void CloseFontFile (VOID);
+
+#endif /* FONTREADER_H */
+
+/* end fontreader.h */
diff --git a/dviware/dvgt/dvgt/src/globals.h b/dviware/dvgt/dvgt/src/globals.h
new file mode 100644
index 0000000000..bccae5ff8b
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/globals.h
@@ -0,0 +1,99 @@
+/* globals.h - 19:52 GMT +10:00 Wed 12 May 1993 - modified by Geoffrey Tobin */
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#ifndef CONFIG_H
+/* typedef for Word, in the appropriate architecture */
+#include "config.h"
+#endif /* CONFIG_H */
+
+/* Include file ../include/globals.h from dvitovdu.c */
+
+
+/* Author: Andrew Trevorrow
+ Implementation: Pyramid Pascal
+
+ Description:
+ This program allows pages from a DVI file produced by TeX to be previewed
+ on a VDU screen.
+
+ Notes:
+ - See AAAREAD.ME for revision history.
+ - Debugging code is bracketed by { DEBUG } ... { GUBED }.
+ This code will be commented out in the final working version.
+ - System-dependent code is indicated by the string "SYSDEP".
+ - Uncertain code is indicated by the string "???".
+ - Unfinished code is indicated by the string "!!!".
+ - Goto 999 is used to emulate a RETURN (from procedure) statement.
+ - Goto <= 888 is used to emulate an EXIT (from loop) statement.
+ - The above notes are also true for all separately compiled modules.
+*/
+
+
+/* Global declarations for DVItoVDU */
+
+/* logfile - defined in dvitovdu.c */
+
+extern FILE * logfile;
+
+#define maxstring 80
+
+
+typedef Char string[maxstring + 1]; /* Allow space for null terminator */
+
+/* pointer to 32-bit word */
+
+/* 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 LITTLE_ENDIAN
+ char _byte0, _byte1, _byte2, _byte3;
+#else /* not LITTLE_ENDIAN */
+#ifdef BIG_ENDIAN
+ char _byte3, _byte2, _byte1, _byte0;
+#else /* not BIG_ENDIAN */
+ /* Never heard of something that's neither little- nor big-endian! */
+ Configuration error.
+#endif /* BIG_ENDIAN */
+#endif /* LITTLE_ENDIAN */
+ }_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;
+
+#endif /* GLOBALS_H */
+
+/* end globals.h */
diff --git a/dviware/dvgt/dvgt/src/help.h b/dviware/dvgt/dvgt/src/help.h
new file mode 100644
index 0000000000..b4c5ae1537
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/help.h
@@ -0,0 +1,69 @@
+/* help.h - 20:32 GMT +10:00 Mon 2 Aug 1993 - Geoffrey Tobin */
+/* Precompiled help information. */
+
+#ifndef HELP_H
+#define HELP_H
+
+#include "version.h"
+
+#ifndef NULL
+#define NULL (char *) 0;
+#endif
+
+char * immed_help_strings[] =
+{
+dvgt_version,
+"dvgt interactively views TeX-generated DVI files on some common VDUs.",
+"This is the precompiled help, `help.h', shown if no arguments are given.",
+"The options help file, `options.hlp', gives more information.",
+"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 ps_prefix] [-r xres[,yres]]",
+" [-t tfm_directory] [-v vdu] [-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)",
+"-v vdu (default value = value of TERM) where 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 parameters' default values are system dependent.",
+"Try `dvgt -f', for example, to find the current default PK font directory.",
+NULL
+};
+
+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
+};
+
+#endif /* HELP_H */
+
+/* end help.h */
diff --git a/dviware/dvgt/dvgt/src/lstring.c b/dviware/dvgt/dvgt/src/lstring.c
new file mode 100644
index 0000000000..bdb207c47a
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/lstring.c
@@ -0,0 +1,80 @@
+/* lstring.c - 21:05 GMT +10:00 Tue 11 May 1993 - Geoffrey Tobin */
+/* Length (and capacity) specified strings. */
+
+#include "new.h"
+#include "lstring.h"
+
+#ifdef __STDC__
+LString * NewLString (int capacity)
+#else
+LString * NewLString (capacity)
+ int capacity;
+#endif
+{
+ LString * S = New (LString);
+ if (S != NULL)
+ {
+ S->cap = capacity;
+ S->len = 0;
+ S->s = (capacity < 0 ? NULL : cnew (capacity+1, char));
+ if (S->s != NULL)
+ S->s[0] = S->s[capacity] = '\0'; /* safeguard */
+ }
+ return S;
+}
+/* NewLString */
+
+#ifdef __STDC__
+LString * FreeLString (LString * S)
+#else
+LString * FreeLString (S)
+ LString * S;
+#endif
+{
+ Free (S, LString);
+ return S;
+}
+/* FreeLString */
+
+#ifdef __STDC__
+Void Scovers (LString * S, int l, const char * s)
+#else
+Void Scovers (S, l, s)
+ LString * S; int l; char * s;
+#endif
+{
+ if (S != NULL)
+ {
+ int c = S->cap;
+ char * t = S->s;
+ strncpy (t+l, s, c-l);
+ t[c] = '\0'; /* to be safe */
+ S->len = strlen (t);
+ }
+}
+/* Scovers */
+
+#ifdef __STDC__
+Void Scopys (LString * S, const char * s)
+#else
+Void Scopys (S, s)
+ LString * S; char * s;
+#endif
+{
+ Scovers (S, 0, s);
+}
+/* Scopys */
+
+#ifdef __STDC__
+Void Scats (LString * S, const char * s)
+#else
+Void Scats (S, s)
+ LString * S; char * s;
+#endif
+{
+ if (S != NULL)
+ Scovers (S, S->len, s);
+}
+/* Scats */
+
+/* end lstring.c */
diff --git a/dviware/dvgt/dvgt/src/lstring.h b/dviware/dvgt/dvgt/src/lstring.h
new file mode 100644
index 0000000000..05f2844a0b
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/lstring.h
@@ -0,0 +1,48 @@
+/* lstring.h - 21:05 GMT +10:00 Tue 11 May 1993 - Geoffrey Tobin */
+/* Length (and capacity) specified strings. */
+
+#ifndef LSTRING_H
+#define LSTRING_H
+
+#include "config.h"
+
+typedef struct LString
+{
+ int cap; /* capacity */
+ int len; /* length */
+ char * s; /* NULL-delimited character array, dynamically allocated */
+} LString;
+
+#ifdef __STDC__
+LString * NewLString (int capacity);
+#else
+LString * NewLString ();
+#endif
+
+#ifdef __STDC__
+LString * FreeLString (LString * S);
+#else
+LString * FreeLString ();
+#endif
+
+#ifdef __STDC__
+Void Scovers (LString * S, int l, const char * s);
+#else
+Void Scovers ();
+#endif
+
+#ifdef __STDC__
+Void Scopys (LString * S, const char * s);
+#else
+Void Scopys ();
+#endif
+
+#ifdef __STDC__
+Void Scats (LString * S, const char * s);
+#else
+Void Scats ();
+#endif
+
+#endif /* LSTRING_H */
+
+/* end lstring.h */
diff --git a/dviware/dvgt/dvgt/src/ncsatelvdu.c b/dviware/dvgt/dvgt/src/ncsatelvdu.c
new file mode 100644
index 0000000000..fe74f80378
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/ncsatelvdu.c
@@ -0,0 +1,126 @@
+/* ncsatelvdu.c - 18:31 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+/*********************************************************************
+ vdu driver for NCSA Telnet with Tektronix Graphics
+ created by vijay@ncst.ernet.in on 25th Dec 92.
+ "No reason why it should not work on a real tek 4010 too."
+*********************************************************************/
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "vdu.h"
+#include "tek4010emu.h"
+
+/******************************************************************************/
+
+Void NCSATELClearScreen (VOID)
+{
+ /* NCSA Telnet (2.3.0.3) tek emulator gets stuck on an extra GS which
+ TEK4010ClearScreen puts out.
+ Set in alpha mode and invoke TEK4010ClearScreen.
+ */
+
+ WriteChar (ESC);
+ WriteChar (FF); /* erase graphics and put in alpha mode */
+
+ TEK4010ClearScreen();
+}
+/* NCSATELClearScreen */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void NCSATELClearTextLine (int line)
+#else
+Void NCSATELClearTextLine (line)
+ int line;
+#endif
+{
+ /* 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.
+ */
+}
+/* NCSATELClearTextLine */
+
+/******************************************************************************/
+
+/* NCSATELShowChar: use TEK4010ShowChar */
+
+/******************************************************************************/
+
+/* NCSATELShowRectangle: use TEK4010ShowRectangle */
+
+/******************************************************************************/
+
+Void NCSATELResetVDU (VOID)
+{
+ WriteChar (CAN);
+ WriteChar (CAN);
+}
+/* NCSATELResetVDU */
+
+/******************************************************************************/
+
+Void InitNCSATEL (VOID)
+{
+ /* 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!
+ */
+
+ InitTEK4010emu(); /* We overwrite the values we don't want */
+
+ /* 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 */
+
+ MoveToTextLine = TEK4010MoveToTextLine;
+ ClearTextLine = NCSATELClearTextLine;
+ ClearScreen = NCSATELClearScreen;
+ StartText = TEK4010StartText;
+ StartGraphics = TEK4010StartGraphics;
+ LoadFont = TEK4010LoadFont;
+ ShowChar = TEK4010ShowChar;
+ ShowRectangle = TEK4010ShowRectangle;
+ ResetVDU = NCSATELResetVDU;
+
+ WriteChar (GS);
+}
+/*InitNCSATEL */
+
+/******************************************************************************/
+
+/* end ncsatelvdu.c */
diff --git a/dviware/dvgt/dvgt/src/new.h b/dviware/dvgt/dvgt/src/new.h
new file mode 100644
index 0000000000..24d30c0b94
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/new.h
@@ -0,0 +1,15 @@
+/* new.h - 19:41 GMT +10:00 Fri 20 August 1993 - Geoffrey Tobin */
+/* Slightly simpler memory allocation. */
+
+#ifndef NEW_H
+#define NEW_H
+
+#include "config.h"
+
+#define new(T) (T *) malloc (sizeof (T))
+#define New(T) (T *) Malloc (sizeof (T))
+#define cnew(n,T) (T *) calloc ((size_t) n, sizeof (T))
+
+#endif /* NEW_H */
+
+/* end new.h */
diff --git a/dviware/dvgt/dvgt/src/options.c b/dviware/dvgt/dvgt/src/options.c
new file mode 100644
index 0000000000..519bde6737
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/options.c
@@ -0,0 +1,1103 @@
+/* options.c - 19:28 GMT +10:00 Fri 20 Aug 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#define CHECK_ON_DVIname
+#define EXIT_IF_NO_DVI
+#define NEW_DIMEN_PIXELS
+
+#include "config.h"
+#include "globals.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 pkdir, tfmdir;
+string psprefix;
+string cmd_help, immed_help;
+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 __((double f));
+
+Static string clarg; /* current command line argument */
+Static int clen; /* command line argument's length */
+Static char option; /* current command option */
+Static string value; /* current option's value */
+Static int vlength; /* current value's length */
+Static int argnum; /* 0..argc-1; used in argv calls */
+
+
+/******************************************************************************/
+
+/* 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. */
+
+#ifdef __STDC__
+char * strMcpy (char * s, const char * ct, size_t n)
+#else
+char * strMcpy (s, ct, n)
+ char * s;
+ char * ct;
+ size_t n;
+#endif
+{
+ strncpy (s, ct, n);
+ s[n] = '\0';
+ return s;
+}
+/* strMcpy */
+
+/******************************************************************************/
+
+/* Copy at most maxstring characters from ct to s; */
+/* set s[maxstring] = NUL character. */
+
+#ifdef __STDC__
+char * stringcopy (string s, const char * ct)
+#else
+char * stringcopy (s, ct)
+ string s;
+ char * ct;
+#endif
+{
+ strncpy (s, ct, maxstring);
+ s[maxstring] = '\0';
+ return (char *) &s;
+}
+/* stringcopy */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static boolean HasExplicitExt (char * fname, int len)
+#else
+Static boolean HasExplicitExt (fname, len)
+ char * fname;
+ int len;
+#endif
+{
+ /* SYSDEP: Check for an extension of the form ".*" where * is any string
+ not containing "/". len is length of fname.
+ If "." found, then TRUE is returned, otherwise FALSE.
+ - gt - no side effects.
+ */
+
+ boolean Result = false;
+
+ while (len > 0) /* search backwards looking for . */
+ {
+ len--;
+ if (fname[len] == '/') /* handle file names like "../myfiles/foo" */
+ {
+ Result = false;
+ break;
+ }
+ if (fname[len] == '.')
+ {
+ Result = true;
+ break;
+ }
+ }
+ return Result;
+}
+/* HasExplicitExt */
+
+/******************************************************************************/
+
+Static Void GetValue (VOID)
+{
+/* gt observes - global variables:
+ * read (I): written (O):
+ *
+ . P_argc - .
+ . argnum argnum .
+ . option - .
+ . clarg - .
+ . clen - .
+ . - value .
+ . - vlength .
+ */
+
+ /* Get wanted parameter following current option and store in value. */
+
+ if (clen > 2) /* allow things like -m1000 */
+ {
+ /* This would be easier if value were a variable pointer. */
+ /* Then we could just say "value = clen + 2;" instead of the loop. */
+ int i;
+ for (i = 0; i < clen; i++) /* shift value left 2 places */
+ value[i] = clarg[i + 2];
+ vlength = clen - 2;
+ }
+ else /* clen <= 2, and current option should be followed by _one_ value */
+ {
+ if (argnum < P_argc) /* More command line arguments */
+ {
+ stringcopy (value, P_argv[argnum]);
+
+ /* gt - this needs to be here in the if statement. */
+ /* - otherwise, value = -option, which isn't right. */
+ /* - also, increasing argnum wd otherwise be wrong. */
+
+ vlength = strlen (value); /* 0 if no more args */
+ argnum++;
+ }
+ else /* gt - missing value */
+ {
+ stringcopy (value, "");
+ vlength = 0;
+ }
+
+ if (vlength < 0)
+ {
+ MesgString ("options.c GetValue(): ");
+ MesgString ("This can't happen! ");
+ MesgString ("After -");
+ MesgChar (option);
+ MesgString (", vlength < 0 !");
+ MesgLine ();
+
+ RestoreTerminal ();
+ exit (1);
+ }
+#ifdef OLD_FUSSY_CHECK
+ else if (vlength == 0)
+ {
+ MesgString ("Missing value after -");
+ MesgChar (option);
+ MesgLine ();
+/*
+ RestoreTerminal ();
+ exit (1);
+*/
+ }
+#endif /* OLD_FUSSY_CHECK */
+ }
+}
+/* GetValue */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int Inint (double f)
+#else
+Static int Inint (f)
+ double f;
+#endif
+{
+ return ((int) (f + 0.5));
+}
+/* Inint */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void ToCardinal (const char * option, const char * value, int *n)
+#else
+Static Void ToCardinal (option, value, n)
+ char * option; char * value; int * n;
+#endif
+{
+ /* If value represents a positive integer, then return via n. */
+
+ int check;
+ double r;
+
+ int vlen;
+ char * sval;
+
+ vlen = strlen (value);
+ sval = (char *) Malloc ((size_t) (vlen+1));
+ (void) strcpy (sval, value);
+
+ check = sscanf (sval, "%lf", &r);
+
+ Free (sval, char);
+
+ *n = Inint (r); /* round value to nearest integer */
+
+ /* check can be 1 or EOF if ok! */
+ if ((check == 1 || check == EOF) && *n > 0)
+ return;
+
+ MesgString ("Bad");
+ MesgString (option);
+ MesgString (" value: ");
+ MesgString (value);
+ MesgLine();
+
+ MesgString ("Specify a positive integer.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+}
+/* ToCardinal */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void ToRes (const char * option, const char * value, double * xr, double * yr)
+#else
+Static Void ToRes (option, value, xr, yr)
+ char * option; char * value; double * xr, * yr;
+#endif
+{
+ /* X and Y resolutions, specified in dots per inch. */
+
+ int check;
+
+ int vlen;
+ char * sval;
+
+ vlen = strlen (value);
+ sval = (char *) Malloc ((size_t) (vlen+1));
+ (void) strcpy (sval, value);
+
+ check = sscanf (sval, "%lf,%lf", xr, yr);
+
+ Free (sval, char);
+
+ if (check == 2 && *xr > 0 && *yr > 0)
+ {
+ return;
+ }
+ else
+ {
+ sval = (char *) Malloc ((size_t) (vlen+1));
+ (void) strcpy (sval, value);
+
+ check = sscanf (sval, "%lf", xr);
+
+ Free (sval, char);
+
+ if (check == 1 && *xr > 0)
+ {
+ *yr = *xr;
+ return;
+ }
+ }
+
+ MesgString ("Bad");
+ MesgString (option);
+ MesgString (" value(s): ");
+ MesgString (value);
+ MesgLine();
+
+ MesgString ("Resolutions must be positive reals,");
+ MesgLine();
+ MesgString ("specified as `-r xres' or `-r xres,yres'");
+ MesgLine();
+ MesgString ("in dots per inch.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+}
+/* ToRes */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static units Name2Unit (const char * uname)
+#else
+Static units Name2Unit (uname)
+ char * uname;
+#endif
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void ToDimen (const char * option, const char * value, double *r, units *un)
+#else
+Static Void ToDimen (option, value, r, un)
+ char * option; char * value; double * r; units * un;
+#endif
+{
+ /* 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 */
+
+ int vlen;
+ char * sval;
+
+ vlen = strlen (value);
+ sval = (char *) Malloc ((size_t) (vlen+1));
+ (void) strcpy (sval, value);
+
+ check = sscanf (sval, "%lf%2s", r, nun);
+
+ Free (sval, char);
+
+ 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 */
+ {
+ MesgString ("Bad");
+ MesgString (option);
+ MesgString (" value: ");
+ MesgString (value);
+ MesgLine();
+
+ MesgString ("Specify a dimensioned quantity.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+}
+/* ToDimen */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void ToPosDimen (const char * option, const char * value, double *r, units *un)
+#else
+Static Void ToPosDimen (option, value, r, un)
+ char * option; char * value; double * r; units * un;
+#endif
+{
+ /* 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)
+ {
+ MesgString ("Bad");
+ MesgString (option);
+ MesgString (" value: ");
+ MesgString (value);
+ MesgLine();
+
+ MesgString ("Specify a positive dimension.");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+}
+/* ToPosDimen */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int DimenPixels (double r, units u, double res)
+#else
+Static int DimenPixels (r, u, res)
+ double r; units u; double res;
+#endif
+{
+ /* Return given dimension as nearest whole number of pixels, */
+ /* given the appropriate (eg, X or Y direction's) resolution in dpi. */
+
+ int Result;
+
+#ifdef NEW_DIMEN_PIXELS
+
+ 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);
+ }
+ }
+
+#else
+
+ switch (u)
+ {
+ case px:
+ Result = Inint (r);
+ break;
+
+ case ic:
+ Result = Inint (r * res);
+ break;
+
+ case sp:
+ Result = Inint (r / 72.27 / 65536.0 * res);
+ break;
+
+ case cm:
+ Result = Inint (r / 2.54 * res);
+ break;
+
+ case mm:
+ Result = Inint (r / 25.4 * res);
+ break;
+
+ case bp:
+ Result = Inint (r / 72.0 * res);
+ break;
+
+ case pt:
+ Result = Inint (r / 72.27 * res);
+ break;
+
+ case pc:
+ Result = Inint (r / 72.27 * 12.0 * res);
+ break;
+
+ default:
+ MesgString ("Unimplemented unit, treating as inch.");
+ MesgLine();
+ Result = Inint (r * res);
+ break;
+ }
+#endif /* NEW_DIMEN_PIXELS */
+
+ return Result;
+}
+/* DimenPixels */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void WriteCardinal (char * name, int value)
+#else
+Void WriteCardinal (name, value)
+ char * name;
+ int value;
+#endif
+{
+ string outstring;
+
+ sprintf (outstring, "%s= %d", name, value);
+ MesgString (outstring);
+ MesgLine();
+}
+/* WriteCardinal */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void WriteReal (char * name, double value)
+#else
+Void WriteReal (name, value)
+ char * name;
+ double value;
+#endif
+{
+ 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. */
+
+#ifdef __STDC__
+Void NameUnit (units un, string nun)
+#else
+Void NameUnit (un, nun)
+ units un;
+ string nun;
+#endif
+/* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void WriteDimen (char * varname, double r, units un)
+#else
+Void WriteDimen (varname, r, un)
+ char * varname;
+ double r;
+ units un;
+#endif
+{
+ 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void WriteName (char * varname, char * svalue)
+#else
+Void WriteName (varname, svalue)
+ char * varname;
+ char * svalue;
+#endif
+{
+ string outstring;
+
+ sprintf (outstring, "%s= %s", varname, svalue);
+ MesgString (outstring);
+ MesgLine();
+}
+/* WriteName */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+double Unit2Value (units unit)
+#else
+double Unit2Value (unit)
+ units unit;
+#endif
+{
+ 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
+ {
+ string ustr;
+ sprintf (ustr, "%d", unit);
+ MesgString ("Bad unit, enumeration value = ");
+ MesgString (ustr);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+ }
+ return per_inch;
+}
+/* Unit2Value */
+
+/******************************************************************************/
+
+Void InitOptions (VOID)
+{
+ /* 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;
+
+ /*
+ (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)
+ {
+ if (sscanf (env, "%lf%lf", &xres, &yres) == 1)
+ yres = xres;
+ }
+
+ /* Display type: default is SYSDEP; see the dv script */
+ /* gt - no "dv" script provided with version 3.0, sadly for us! */
+
+ if (!(env = getenv ("DV_TERM")))
+ env = getenv ("TERM");
+
+ stringcopy (vdu,
+ !env ? "" : env);
+
+ /* Paper Width */
+ ToPosDimen ("", !(env = getenv ("DV_PAPERWD")) ? DEF_PAPERWD : env,
+ &xr, &xu);
+
+ /* Paper Height */
+ ToPosDimen ("", !(env = getenv ("DV_PAPERHT")) ? DEF_PAPERHT : env,
+ &yr, &yu);
+
+ /* location of PK files */
+
+ if (!(env = getenv ("TEXPKS")) && !(env = getenv ("PKFONTS")))
+ env = getenv ("TEXFONTS");
+
+ stringcopy (pkdir,
+ !env ? DEF_PK_DIR : env);
+
+ /* location of TFM files */
+
+ stringcopy (tfmdir,
+ ! (env = getenv ("TEXFONTS")) ? DEF_TFM_DIR : env);
+
+ /* 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);
+
+ /* prefix in PS font names */
+
+ stringcopy (psprefix,
+ ! (env = getenv("DV_PS_PREFIX")) ? DEF_PS_PREFIX : env);
+
+ /* command help file read by ? command */
+
+ stringcopy (cmd_help,
+ ! (env = getenv ("DV_CMD_HELP")) ? DEF_CMD_HELP : env);
+
+ /* immediate help file read when dvgt has no arguments */
+
+ stringcopy (immed_help,
+ ! (env = getenv ("DV_IMMED_HELP")) ? DEF_IMMED_HELP : env);
+
+ /* DVI file name */
+
+ stringcopy (DVIname, ""); /* no DVI file yet */
+
+ /* portrait or landscape page dimensions? */
+
+ landscape = false; /* portrait: don't swap -x and -y values */
+
+ /*
+ (2) COMMAND LINE OPTIONS.
+ */
+
+ argnum = 1;
+ while (argnum < P_argc)
+ {
+ stringcopy (clarg, P_argv[argnum]);
+ clen = strlen (clarg);
+ argnum++;
+
+ if (clarg[0] == '-')
+ {
+ if (clen < 2)
+ {
+ if (clen < 1)
+ {
+ MesgString ("This cannot happen! argument '-' with length < 1");
+ MesgLine();
+ }
+ else if (clen == 1)
+ {
+ MesgString ("Valid options are:");
+ MesgLine();
+ MesgString (" H V d e f h i l m p r t v x y");
+ MesgLine();
+ }
+ RestoreTerminal();
+ exit (1);
+ }
+ else
+ option = clarg[1];
+
+ /* bad string values will be detected in other modules */
+
+ switch (option)
+ {
+
+ case 'H':
+ GetValue();
+ if (vlength > 0)
+ ToDimen (" -H", value, &hoffr, &hoffu);
+ else
+ WriteDimen ("horizontal offset", hoffr, hoffu);
+ break;
+
+ case 'V':
+ GetValue();
+ if (vlength > 0)
+ ToDimen (" -V", value, &voffr, &voffu);
+ else
+ WriteDimen ("vertical offset", voffr, voffu);
+ break;
+
+ case 'd':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (dummy_pk, value);
+ else
+ {
+ WriteName ("dummy PK font", dummy_pk);
+ MesgString ("environment variable = DV_DUMMY_PK");
+ MesgLine();
+ }
+ break;
+
+ case 'e': /* gt - not very mnemonic, I know */
+ GetValue();
+ if (vlength > 0)
+ stringcopy (dummy_tfm, value);
+ else
+ {
+ WriteName ("dummy TFM metric", dummy_tfm);
+ MesgString ("environment variable = DV_DUMMY_TFM");
+ MesgLine();
+ }
+ break;
+
+ case 'f':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (pkdir, value);
+ else
+ {
+ WriteName ("pk font directory", pkdir);
+ MesgString ("environment variable = TEXPKS or PKFONTS or TEXFONTS");
+ MesgLine();
+ }
+ break;
+
+ case 'h':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (cmd_help, value);
+ else
+ {
+ WriteName ("command help file", cmd_help);
+ MesgString ("environment variable = DV_CMD_HELP");
+ MesgLine();
+ }
+ break;
+
+ case 'i':
+ WriteName ("immediate help file", immed_help);
+ MesgString ("environment variable = DV_IMMED_HELP");
+ MesgLine();
+ break;
+
+ case 'l':
+ landscape = true;
+ MesgString ("In landscape orientation now. (Default is portrait.)");
+ MesgLine();
+ break;
+
+ case 'm':
+ GetValue();
+ if (vlength > 0)
+ ToCardinal (" -m", value, &mag);
+ else
+ WriteCardinal ("magnification", mag);
+ break;
+
+ case 'p':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (psprefix, value);
+ else
+ {
+ WriteName ("postscript font prefix", psprefix);
+ MesgString ("environment variable = DV_PS_PREFIX");
+ MesgLine();
+ }
+ break;
+
+ case 'r':
+ GetValue();
+ /* gt - resolutions should allow non-integral dpi */
+ /* - this is because there are such output devices */
+ /* - for example, metric printers. */
+ if (vlength > 0)
+ {
+ /* Get resolutions, specified in dots per inch */
+ ToRes (" -r", value, &xres, &yres);
+ }
+ else
+ {
+ WriteReal ("horizontal resolution (in dpi) ", xres);
+ WriteReal ("vertical resolution (in dpi) ", yres);
+ MesgString ("environment variable = DV_RES");
+ MesgLine();
+ }
+ break;
+
+ case 't':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (tfmdir, value);
+ else
+ {
+ WriteName ("tfm directory", tfmdir);
+ MesgString ("environment variable = TEXFONTS");
+ MesgLine();
+ }
+ break;
+
+ case 'v':
+ GetValue();
+ if (vlength > 0)
+ stringcopy (vdu, value);
+ else
+ {
+ WriteName ("vdu", vdu);
+ MesgString ("environment variable = DV_TERM or TERM");
+ MesgLine();
+ }
+ break;
+
+ case 'x':
+ GetValue();
+ if (vlength > 0)
+ ToPosDimen (" -x", value, &xr, &xu);
+ else
+ {
+ WriteDimen ("page width", xr, xu);
+ MesgString ("environment variable = DV_PAPERWD");
+ MesgLine();
+ }
+ break;
+
+ case 'y':
+ GetValue();
+ if (vlength > 0)
+ ToPosDimen (" -y", value, &yr, &yu);
+ else
+ {
+ WriteDimen ("page height", yr, yu);
+ MesgString ("environment variable = DV_PAPERHT");
+ MesgLine();
+ }
+ break;
+
+ default:
+ MesgString ("Unknown option: `-");
+ MesgChar (option);
+ MesgString ("'");
+ MesgLine();
+
+ MesgString ("Valid options are:");
+ MesgLine();
+ MesgString (" H V d e f h i l m p r t v x y");
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1);
+
+ break;
+ } /* switch */
+ }
+ else
+ /* clarg doesn't start with '-', so assume it's a DVI file's name */
+ {
+ stringcopy (DVIname, clarg);
+
+ /* bad DVIname will be detected upon open in main module */
+
+ if (HasExplicitExt (DVIname, clen))
+ ; /* dvi file name has an extension */
+ else if (clen + 4 <= maxstring) /* room to append ".dvi" */
+ {
+ DVIname[clen] = '.';
+ DVIname[clen + 1] = 'd';
+ DVIname[clen + 2] = 'v';
+ DVIname[clen + 3] = 'i';
+ DVIname[clen + 4] = '\0';
+ }
+ else /* user has given a mighty long file name */
+ {
+ MesgString ("DVI file name too long: ");
+ MesgString (DVIname);
+ MesgLine();
+
+ RestoreTerminal();
+ exit (1); /* gt - pretty sad! */
+ } /* if */
+ } /* if */
+ } /* while */
+
+#ifdef CHECK_ON_DVIname
+ if (DVIname == (char *) NULL || strlen (DVIname) == 0 || DVIname[0] == ' ')
+ {
+ /* no file name on command line */
+
+ MesgString ("DVI file not given.");
+ MesgLine();
+#ifdef EXIT_IF_NO_DVI
+ RestoreTerminal();
+ exit (1);
+#endif /* EXIT_IF_NO_DVI */
+ }
+#endif /* CHECK_ON_DVIname */
+
+ /* 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;
+ }
+}
+/* InitOptions */
+
+/******************************************************************************/
+
+/* end options.c */
diff --git a/dviware/dvgt/dvgt/src/options.h b/dviware/dvgt/dvgt/src/options.h
new file mode 100644
index 0000000000..40b283f2a4
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/options.h
@@ -0,0 +1,51 @@
+/* options.h - 19:01 GMT +10:00 Fri 25 Jun 1993 - modifier Geoffrey Tobin */
+
+#ifndef OPTIONS_H
+#define OPTIONS_H
+
+/* Include file ../include/options.h from dvitovdu.c */
+
+/*
+ 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;
+
+#ifndef Extern
+#define Extern extern
+#endif
+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 tfmdir; /* location of TFM files */
+Extern string pkdir; /* location of PK files */
+Extern string dummy_tfm; /* dummy TFM file */
+Extern string dummy_pk; /* dummy PK file */
+Extern string psprefix; /* Prefix for PS & pure TFM fonts */
+Extern string immed_help; /* immediate help file name */
+Extern string cmd_help; /* command help file name */
+Extern string DVIname; /* DVI file name */
+
+
+extern Void InitOptions (VOID);
+
+extern int Len __((Char *str));
+
+extern Char * stringcopy __((string s, const Char * ct));
+extern Char * strMcpy __((Char * s, const Char * ct, size_t maxlen));
+
+extern Void WriteReal __((Char * name, double value));
+
+#endif /* OPTIONS_H */
+
+/* end options.h */
diff --git a/dviware/dvgt/dvgt/src/regisvdu.c b/dviware/dvgt/dvgt/src/regisvdu.c
new file mode 100644
index 0000000000..36e148cc52
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/regisvdu.c
@@ -0,0 +1,408 @@
+/* regisvdu.c - 19:29 GMT +10:00 Thu 22 July 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "vt100vdu.h"
+#include "regisvdu.h"
+
+Static int charht; /* set in REGISLoadFont and used in REGISShowChar */
+Static int lastv; /* REGISShowChar remembers last vertical coordinate */
+
+/******************************************************************************/
+
+Void REGISStartText (VOID)
+{
+ /* We are about to draw text in dialogue region. */
+
+ WriteChar (ESC);
+ WriteChar ('\\'); /* leave graphics mode */
+}
+/* REGISStartText */
+
+/******************************************************************************/
+
+/* REGISMoveToTextLine: use VT100MoveToTextLine */
+
+/******************************************************************************/
+
+/* REGISClearTextLine: use VT100ClearTextLine */
+
+/******************************************************************************/
+
+Void REGISStartGraphics (VOID)
+{
+ /* We are about to draw in window region. */
+
+ WriteChar (ESC);
+ WriteString ("Pp"); /* enter graphics mode */
+ lastv = 999999; /* undefined value for next REGISShowChar call */
+}
+/* REGISStartGraphics */
+
+/******************************************************************************/
+
+Void REGISClearScreen (VOID)
+{
+ VT100ClearScreen();
+ REGISStartGraphics(); /* switch to REGIS mode */
+ WriteString ("S(E)"); /* erase graphics plane */
+ REGISStartText(); /* exit in text mode */
+}
+/* REGISClearScreen */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void REGISLoadFont (Char * fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void REGISLoadFont (fontname, fontsize, mag, hscale, vscale)
+ Char * fontname;
+ int fontsize;
+ double mag;
+ double hscale, vscale;
+#endif
+{
+ /* Use the given information to select an appropriate character size
+ (based on horizontal AND vertical scaling)
+ for future calls of REGISShowChar.
+ */
+
+ int wd, ht; /* we will send T ( Swd Hht ) */
+
+ WriteChar ('T');
+ WriteChar ('(');
+
+ /* scale fontsize horizontally and choose an appropriate text width */
+ wd = (int)(fontsize * mag * hscale + 0.5) / 9;
+ if (wd > 16) /* wd now in 0,1,2,...,16 */
+ wd = 16;
+ /* larger widths tend to be too big so adjust accordingly (trial and error) */
+ if (wd > 1)
+ wd /= 2;
+ WriteChar ('S');
+ WriteInt (wd);
+
+ /* scale fontsize vertically and choose an appropriate text height */
+ ht = (int) (fontsize * mag * vscale + 0.5) / 10;
+ if (ht < 1) /* ht now in 1,2,...,16 */
+ ht = 1; /* ht must not be 0 */
+ else if (ht > 16)
+ ht = 16;
+ charht = ht * 10; /* charht now in 10,20,30,...,160 */
+ /* restrict charht to <= windowv,
+ so screenv-charht in REGISShowChar will be >= 0.
+ */
+ if (charht > windowv)
+ {
+ charht = windowv;
+ ht = windowv / 10;
+ }
+ /* now reduce charht by one fifth to allow for descenders in REGISShowChar */
+ charht = charht * 4 / 5 - 1; /* exact if charht is multiple of 10 */
+ WriteChar ('H');
+ WriteInt (ht);
+
+ /* Note that VT125 and GIGI VDUs sometimes vary the vertical thickness
+ of text (only for odd ht values? ? ?).
+ VT240 does not; instead, charht is sometimes 1 pixel too much
+ and baseline won't agree with Box/Full characters!
+ */
+
+ WriteChar (')');
+}
+/* REGISLoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void REGISShowChar (int screenh, int screenv, Char ch)
+#else
+Void REGISShowChar (screenh, screenv, ch)
+ int screenh; int screenv; Char ch;
+#endif
+{
+ /* Show the given Terse character (mapped to ASCII) using the given position.
+ We remember the vertical position in lastv so we can reduce the output
+ bytes needed to position the next Terse character on the same line.
+ REGISStartGraphics resets lastv to an undefined state (= 999999).
+ */
+
+ Char newch; /* = TeXtoASCII[ch] */
+
+ WriteChar ('P');
+ WriteChar ('[');
+ WriteInt (screenh);
+ /* charht allows for descenders and is used to shift ref pt of REGIS ch
+ (top left pixel) so that REGIS and TeX baselines will match.
+ REGISLoadFont guarantees that screenv - charht >= 0.
+ */
+ screenv -= charht;
+ if (lastv != screenv)
+ {
+ /* we need to send new vertical coordinate */
+ WriteChar (',');
+ WriteInt (screenv);
+ lastv = screenv; /* remember for next REGISShowChar call */
+ }
+ WriteChar (']');
+ WriteChar ('T');
+ newch = TeXtoASCII[ch - NUL]; /* convert TeX ch to ASCII */
+ if (newch != '\'')
+ {
+ WriteChar ('\''); /* open quoted string */
+ if (newch != '?')
+ {
+ /* newch is similar to TeX ch */
+ WriteChar (newch);
+ }
+ else
+ {
+ /* attempt to display something other than ? */
+ switch (ch)
+ {
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15: /* ff, fi, fl, ffi, ffl */
+ WriteChar ('f');
+ /* REGIS doesn't care if no room at right edge */
+ switch (ch)
+ {
+ case 0xb:
+ WriteChar ('f');
+ break;
+
+ case 0xc:
+ WriteChar ('i');
+ break;
+
+ case 0xd:
+ WriteChar ('l');
+ break;
+
+ case 0xe:
+ case 0xf:
+ WriteChar ('f');
+ if (ch == '\016')
+ WriteChar ('i');
+ else
+ WriteChar ('l');
+ break;
+ }
+ break;
+
+ case 0x19: /* German sharp S */
+ WriteChar ('B');
+ break;
+
+ case 0x1a:
+ case 0x1b:
+ case 0x1d:
+ case 0x1e: /* diphthongs: ae, oe, AE, OE */
+ switch (ch)
+ {
+ case 0x1a:
+ WriteChar ('a');
+ break;
+
+ case 0x1b:
+ WriteChar ('o');
+ break;
+
+ case 0x1d:
+ WriteChar ('A');
+ break;
+
+ case 0x1e:
+ WriteChar ('O');
+ break;
+ }
+ switch (ch)
+ {
+ case 0x1a:
+ case 0x1b:
+ WriteChar ('e');
+ break;
+
+ case 0x1d:
+ case 0x1e:
+ WriteChar ('E');
+ break;
+ }
+ break;
+
+ case 0x20: /* Polish suppressed l and L */
+ WriteChar ('/');
+ break;
+
+ default:
+ WriteChar ('?');
+ break;
+ }
+ }
+ WriteChar ('\''); /* close quoted string */
+ return;
+ }
+ WriteChar ('\"');
+ WriteChar ('\'');
+ WriteChar ('\"'); /* send "'" */
+}
+/* REGISShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void REGISShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void REGISShowRectangle (screenh, screenv, width, height, ch)
+ int screenh, screenv; /* top left pixel */
+ int width, height; /* size of rectangle */
+ Char ch; /* black pixel */
+#endif
+{
+ /* Display the given rectangle
+ (_without_ using the given black pixel character).
+ DVItoVDU ensures the top left position is visible
+ and the given dimensions do not go beyond the window edges.
+ */
+
+ if (height == 1)
+ {
+ /* show row vector */
+ WriteChar ('P');
+ WriteChar ('['); /* move cursor to start of row */
+ WriteInt (screenh);
+ WriteChar (',');
+ WriteInt (screenv);
+ /* call @R macrograph to draw starting pixel and begin row */
+ WriteChar ('@');
+ WriteChar ('R');
+ WriteInt (width - 1);
+ WriteChar (']');
+ return;
+ }
+ if (width == 1)
+ {
+ /* show column vector */
+ WriteChar ('P');
+ WriteChar ('['); /* move cursor to start of column */
+ WriteInt (screenh);
+ WriteChar (',');
+ WriteInt (screenv);
+ /* call @C macrograph to draw starting pixel and begin column */
+ WriteChar ('@');
+ WriteChar ('C');
+ WriteInt (height - 1);
+ WriteChar (']');
+ return;
+ }
+ else
+ {
+ /* assume height and width > 1 and use shading to fill rectangle */
+ WriteChar ('P');
+ WriteChar ('[');
+ WriteChar (','); /* position to last row */
+ WriteInt (screenv + height - 1);
+ /* call @E macrograph to define shading reference line and start
+ position command that moves to start of first row */
+ WriteChar ('@');
+ WriteChar ('E');
+ WriteInt (screenh);
+ WriteChar (',');
+ WriteInt (screenv);
+ /* call @R macrograph to draw starting pixel and begin rectangle */
+ WriteChar ('@');
+ WriteChar ('R');
+ WriteInt (width - 1);
+ /* call @D macrograph to disable shading */
+ WriteChar ('@');
+ WriteChar ('D');
+ }
+}
+/* REGISShowRectangle */
+
+/******************************************************************************/
+
+Void REGISResetVDU (VOID)
+{
+ /* We don't do a hardware reset, but leave VDU gracefully. */
+
+ REGISStartGraphics(); /* for following REGIS commands */
+ WriteString ("@."); /* clear macrograph storage */
+ WriteString ("T(E)"); /* restore Text attributes saved inInitREGIS */
+ REGISStartText(); /* safer to leave in text mode */
+}
+/* REGISResetVDU */
+
+/******************************************************************************/
+
+Void InitREGIS (VOID)
+{
+ /* The dialogue region is the top 4 lines.
+ The window region is the remaining area of the screen.
+ */
+
+ DVIstatusl = 1;
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = 24;
+ /* DVItoVDU's coordinate scheme is the same as the REGIS scheme. */
+
+ windowh = 0;
+ windowv = 80; /* = height of 4 dialogue lines
+ (better for REGISLoadFont if
+ windowv is a multiple of 10) */
+ windowwd = 768;
+ windowht = 480 - windowv;
+
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ MoveToTextLine = VT100MoveToTextLine;
+ ClearTextLine = VT100ClearTextLine;
+ ClearScreen = REGISClearScreen;
+ StartText = REGISStartText;
+ StartGraphics = REGISStartGraphics;
+ LoadFont = REGISLoadFont;
+ ShowChar = REGISShowChar;
+ ShowRectangle = REGISShowRectangle;
+ ResetVDU = REGISResetVDU;
+
+ REGISStartGraphics(); /* for following REGIS commands */
+
+ /* Set Text and Writing attributes to known initial states. */
+ /* save current Text attributes; will be restored by REGISResetVDU */
+ WriteString ("T(B)");
+ /* default character set, no italic slant, direction right, default text size */
+ WriteString ("T(A0,I0,D0,S1)");
+ /* solid fill, no alternate, normal, shading disabled, overlay */
+ WriteString ("W(P1,A0,N0,S0,V)");
+
+ /* Define some macrographs for frequently used strings in REGISShowRectangle. */
+ WriteString ("@.");
+ /* clear macrograph storage */
+ WriteString ("@:E]W(S1)P[@;");
+ /* @E = enable shading for filled rectangle */
+ WriteString ("@:D]W(S0)@;");
+ /* @D = disable shading */
+ WriteString ("@:R]V[]V[+@;");
+ /* @R = mid part of drawing a row vector */
+ WriteString ("@:C]V[]V[,+@;");
+ /* @C = mid part of drawing a column vector */
+
+ REGISStartText(); /* safer to leave in text mode */
+}
+/*InitREGIS */
+
+/******************************************************************************/
+
+/* end regisvdu.c */
diff --git a/dviware/dvgt/dvgt/src/regisvdu.h b/dviware/dvgt/dvgt/src/regisvdu.h
new file mode 100644
index 0000000000..a5c3f40344
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/regisvdu.h
@@ -0,0 +1,9 @@
+/* regisvdu.h - 21:11 GMT +10:00 Mon 24 May 1993 - Geoffrey Tobin */
+
+#ifndef CONFIG_H
+#include "config.h"
+#endif
+
+extern Void InitREGIS (VOID);
+
+/* end regisvdu.h */
diff --git a/dviware/dvgt/dvgt/src/screenio.c b/dviware/dvgt/dvgt/src/screenio.c
new file mode 100644
index 0000000000..42601706fc
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/screenio.c
@@ -0,0 +1,544 @@
+/* screenio.c - 16:00 GMT +10:00 Wed 4 Aug 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "unixio.h"
+#include "vdu.h"
+
+/* Variables Exported, via "screenio.h" */
+
+Char TeXtoASCII[XXX];
+
+
+/* IMPORT InitVDU, LogClearScreen, 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int MesgChar (int ch)
+#else
+int MesgChar (ch)
+ int ch;
+#endif
+{
+ 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);
+ if (logfile != NULL)
+ putc (ch, logfile);
+
+ ++ textcolumn;
+ }
+#ifdef COLUMN_LOG
+ fflush (logfile);
+ fprintf (logfile, "%% MesgChar: textcolumn = %d\n", textcolumn);
+ fflush (logfile);
+#endif
+ return status;
+}
+/* MesgChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int MesgString (const char * s)
+#else
+int MesgString (s)
+ char * s;
+#endif
+{
+ 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, "");
+ if (logfile != NULL)
+ {
+ fprintf (logfile,
+ "textcolumn = %d : must be 0 <= textcolumn < maxcol = %d\n",
+ textcolumn, maxcol);
+ }
+ }
+ else
+ {
+ strncpy (message, s, maxcol-textcolumn);
+ message[maxcol-textcolumn] = '\0';
+ }
+
+ status = fputs (message, stdout);
+ if (logfile != NULL)
+ fputs (message, logfile);
+
+ textcolumn += strlen (message);
+#ifdef COLUMN_LOG
+ fflush (logfile);
+ fprintf (logfile, "%% MesgString: textcolumn = %d\n", textcolumn);
+ fflush (logfile);
+#endif
+ return status;
+}
+/* MesgString */
+
+/******************************************************************************/
+
+int MesgFlush (VOID)
+{
+ int status = fflush (stdout);
+ textcolumn = 0;
+ if (logfile != NULL)
+ {
+ fflush (logfile);
+#ifdef COLUMN_LOG
+ fprintf (logfile, "%% MesgFlush: textcolumn = %d\n", textcolumn);
+ fflush (logfile);
+#endif
+ }
+ return status;
+}
+/* MesgFlush */
+
+/******************************************************************************/
+
+Void MesgLine (VOID)
+{
+ save_temp_tty();
+ rawoutoff(); /* Enable NL to CR+LF mapping */
+ putchar (CR); /* SYSDEP: Really an NL */
+ if (logfile != NULL)
+ fprintf (logfile, "\n");
+ MesgFlush(); /* MesgLine also updates terminal */
+ restore_temp_tty();
+}
+/* MesgLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static int MesgCard (int c)
+#else
+Static int MesgCard (c)
+ int c;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+int MesgInt (int i)
+#else
+int MesgInt (i)
+ int i;
+#endif
+{
+ int len = 0;
+ if (i < 0)
+ {
+ MesgChar ('-');
+ ++ len;
+ i = abs (i);
+ }
+ len += MesgCard (i);
+ return (len);
+}
+/* MesgInt */
+
+/******************************************************************************/
+
+Void WriteLine (VOID)
+{
+ WriteChar (CR);
+ WriteFlush(); /* WriteLine also updates terminal */
+}
+/* WriteLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void WriteCard (int c)
+#else
+Static Void WriteCard (c)
+ int c;
+#endif
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void WriteInt (int i)
+#else
+Void WriteInt (i)
+ int i;
+#endif
+{
+ if (i < 0)
+ {
+ WriteChar ('-');
+ i = abs (i);
+ }
+ WriteCard (i);
+}
+/* WriteInt */
+
+/******************************************************************************/
+
+static Void Restore_Temp_Terminal (VOID)
+{
+ /* 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 (VOID)
+{
+ /* 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 */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void ReadChar (Char *ch)
+#else
+Void ReadChar (ch)
+ Char * ch;
+#endif
+{
+ /* gt - if cbreak's off, turn it on */
+ if (cmode_flags.cbreak == 0)
+ singlecharon();
+
+ /* gt - if echo's on, turn it off */
+ if (cmode_flags.echo == 1)
+ 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();
+ LogClearScreen();
+ MesgLine();
+ ResetVDU();
+ Restore_Temp_Terminal();
+
+ suspend();
+ save_temp_tty();
+
+ singlecharon();
+ rawouton();
+ echooff();
+
+ InitVDU();
+ StartText();
+ LogClearScreen();
+
+ *ch = CR; /* return to Command: level */
+ }
+ else
+ {
+ (void) putchar (*ch = getchar());
+ if (logfile != NULL)
+ putc (*ch, logfile);
+ }
+}
+/* ReadChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void ReadString (Char *s)
+#else
+Void ReadString (s)
+ Char * s;
+#endif
+{
+ /* 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();
+ LogClearScreen();
+ MesgLine();
+ ResetVDU();
+ Restore_Temp_Terminal();
+
+ suspend();
+ save_temp_tty();
+ /* singlecharon and echooff are called below */
+
+ InitVDU();
+ StartText();
+ LogClearScreen();
+
+ s[0] = '\0';
+ break;
+ }
+ ch = getchar();
+ if (ch == CR)
+ {
+ s[i] = 0;
+ if (logfile != NULL)
+ fprintf (logfile, "\n");
+ break;
+ }
+ s[i] = ch;
+ if (logfile != NULL)
+ putc (ch, logfile);
+ if (i == maxstring)
+ {
+ s[i] = '\0';
+ break;
+ }
+ }
+ singlecharon(); /* return to cbreak mode */
+ rawouton();
+ echooff(); /* and no echo */
+}
+/* ReadString */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+boolean BusyRead (Char *ch)
+#else
+boolean BusyRead (ch)
+ Char * ch;
+#endif
+{
+ /* 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();
+ LogClearScreen();
+ MesgLine();
+ ResetVDU();
+ Restore_Temp_Terminal();
+
+ suspend();
+ save_temp_tty();
+ /* singlecharon and echooff are called below */
+
+ InitVDU();
+ StartText();
+ LogClearScreen();
+
+ *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();
+ if (logfile != NULL)
+ putc (*ch, logfile);
+ return true;
+ }
+}
+/* BusyRead */
+
+/******************************************************************************/
+
+Static Void InitTeXtoASCII (VOID)
+{
+ /* 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 (VOID)
+{
+ 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();
+ singlecharon(); /* cbreak mode for ReadChar and BusyRead */
+ echooff(); /* no echo for BusyRead */
+ rawouton();
+ if (setvbuf (stdout, NULL, _IOFBF, BUFSIZ/4) != 0)
+ {
+ MesgString ("screenio.c: InitScreenIO: setvbuf failed!");
+ MesgLine();
+ }
+}
+/* InitScreenIO */
+
+/******************************************************************************/
+
+/* end screenio.c */
diff --git a/dviware/dvgt/dvgt/src/screenio.h b/dviware/dvgt/dvgt/src/screenio.h
new file mode 100644
index 0000000000..5cc1291f08
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/screenio.h
@@ -0,0 +1,71 @@
+/* screenio.h - 22:01 GMT +10:00 Fri 23 July 1993 - modifier Geoffrey Tobin */
+
+#ifndef SCREENIO_H
+#define SCREENIO_H
+
+/* Include file ../include/screenio.h from vis630vdu.c */
+
+
+/* 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 (VOID);
+extern Void ReadChar __((Char *ch));
+extern Void ReadString __((Char *s));
+extern boolean BusyRead __((Char *ch));
+extern Void WriteInt __((int i));
+extern Void WriteLine (VOID);
+
+#define WriteChar(X) putchar(X)
+#define WriteString(X) fputs(X, stdout)
+#define WriteFlush() fflush(stdout)
+
+extern int MesgInt __((int i));
+extern Void MesgLine (VOID);
+
+extern int MesgChar __((int ch));
+extern int MesgString __((const char * s));
+extern int MesgFlush (VOID);
+
+extern Void RestoreTerminal (VOID);
+
+#endif /* SCREENIO_H */
+
+/* end screenio.h */
diff --git a/dviware/dvgt/dvgt/src/tek4010emu.c b/dviware/dvgt/dvgt/src/tek4010emu.c
new file mode 100644
index 0000000000..32ababedc4
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/tek4010emu.c
@@ -0,0 +1,507 @@
+/* tek4010emu.c - 19:21 GMT +10:00 Thu 29 July 1993 - modifier Geoffrey Tobin */
+
+/* Not a complete description.
+ * This file contains routines for use by TEK4010 emulating VDUs.
+ * A real TEK4010 is not supported.
+ */
+
+/* From input file "../include/globals.p" */
+
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+
+
+/* Variables Exported, via "tek4010emu.h" */
+
+int maxy, lineht, dragdown;
+boolean havesentxy;
+
+
+Static int oldhiy; /* for remembering old address in SendXY */
+Static int oldhix, oldloy, charwidth;
+ /* set by TEK4010LoadFont and used in TEK4010ShowChar */
+
+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 (VOID)
+{
+ WriteChar (GS); /* switch to graphics mode */
+}
+/* Graphic */
+
+/******************************************************************************/
+
+Static Void Alpha (VOID)
+{
+ WriteChar (US); /* switch to alphanumeric mode */
+}
+/* Alpha */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void SendXY (int x, int y)
+#else
+Void SendXY (x, y)
+int x; int y;
+#endif
+{
+ /* 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 TEK4010StartText (VOID)
+{
+ Alpha();
+}
+/* TEK4010StartText */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void TEK4010MoveToTextLine (int line)
+#else
+Void TEK4010MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* 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 */
+}
+/* TEK4010MoveToTextLine */
+
+/******************************************************************************/
+
+Void TEK4010ClearScreen (VOID)
+{
+ 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;
+}
+/* TEK4010ClearScreen */
+
+/******************************************************************************/
+
+Void TEK4010StartGraphics (VOID)
+{
+ if (charsize != loadedsize)
+ { /* graphics mode was interrupted */
+ charsize = loadedsize;
+ dragdown = (charsize + 1) * 5; /* used by VIS500/550 TEK4010ShowChar */
+
+ Graphic();
+
+ WriteChar (ESC);
+ WriteChar (charsize + '0'); /* recall last TEK4010LoadFont character size */
+ }
+ Graphic();
+
+ havesentxy = false; /* safer to send all bytes anew */
+}
+/* TEK4010StartGraphics */
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void TEK4010LoadFont (Char *fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void TEK4010LoadFont (fontname, fontsize, mag, hscale, vscale)
+Char *fontname; int fontsize; double mag; double hscale; double vscale;
+#endif
+{
+ /* 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);
+ /* Chooose 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 */
+}
+/* TEK4010LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void TEK4010ShowChar (int screenh, int screenv, Char ch)
+#else
+Void TEK4010ShowChar (screenh, screenv, ch)
+int screenh; int screenv; Char ch;
+#endif
+{
+ /* 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 */
+}
+/* TEK4010ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void TEK4010ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void TEK4010ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh, screenv; /* top left pixel */
+ int width, height; /* of rectangle */
+ Char ch; /* black pixel */
+#endif
+{
+ /* 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 */
+ }
+ }
+}
+/* TEK4010ShowRectangle */
+
+/******************************************************************************/
+
+Void InitTEK4010emu (VOID)
+{
+ 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 */
+}
+/* InitTEK4010emu */
+
+/******************************************************************************/
+
+/* end tek4010emu.c */
diff --git a/dviware/dvgt/dvgt/src/tek4010emu.h b/dviware/dvgt/dvgt/src/tek4010emu.h
new file mode 100644
index 0000000000..c75a9a7377
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/tek4010emu.h
@@ -0,0 +1,44 @@
+/* tek4010emu.h - 20:07 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+/* `Tektronix 4010' EMULATION. */
+
+/* Include file ../include/tek4010vdu.h from vis630vdu.c */
+
+#ifndef TEK4010EMU_H
+#define TEK4010EMU_H
+
+extern int maxy;
+/* TEK4010 vertical coordinates are in 0..maxy;
+ some VDUs may change default value of 779 */
+extern int lineht;
+/* height in TEK4010 pixels of a text line;
+ some VDUs may change default value of 26 */
+extern int dragdown;
+/* VIS500/550 VDUs can use this value to drag
+ Terse character baseline down to TeX ref pt */
+extern boolean havesentxy;
+ /* don't need to send all 4 bytes of address? */
+
+
+extern Void InitTEK4010emu (VOID);
+
+extern Void SendXY __((int x, int y));
+
+extern Void TEK4010StartText (VOID);
+
+extern Void TEK4010MoveToTextLine __((int line));
+
+extern Void TEK4010ClearScreen (VOID);
+
+extern Void TEK4010StartGraphics (VOID);
+
+extern Void TEK4010LoadFont __((Char *fontname, int fontsize, double mag,
+ double hscale, double vscale));
+
+extern Void TEK4010ShowChar __((int screenh, int screenv, Char ch));
+
+extern Void TEK4010ShowRectangle __((int screenh, int screenv,
+ int width, int height, Char ch));
+
+#endif /* TEK4010EMU_H */
+
+/* end tek4010emu.h */
diff --git a/dviware/dvgt/dvgt/src/unixio.c b/dviware/dvgt/dvgt/src/unixio.c
new file mode 100644
index 0000000000..5e611c394f
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/unixio.c
@@ -0,0 +1,364 @@
+/* unixio.c - 16:05 GMT + 10:00 Wed 4 Aug 1993 - modifier Geoffrey Tobin */
+
+/* Add a global structure so we don't need BSD specific stuff
+ * and remove that BSD specific stuff.
+ * -- Ian Dall
+ */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h" /* for MesgString, MesgLine */
+
+#define IN_UNIXIO_C
+#include "unixio.h"
+
+/* Set DV_FD (ioctl file descriptor) to 0 or 1 ? */
+#define DV_FD 0
+
+struct { unsigned int intr, tstop : 1;} sig_flags = {0, 0};
+
+struct { unsigned int cbreak, raw, echo : 1;} cmode_flags = {0, 0, 0};
+
+/* GT - For the purpose of this file, Aix is BSD - see the headers
+ taken from Berkeley in /usr/include and /usr/include/sys !
+*/
+
+#ifdef AIX
+# define BSD 1
+#endif /* AIX */
+
+/* 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.
+*/
+
+#ifdef BSD
+# include <sgtty.h>
+ typedef struct sgttyb dv_tty;
+# define DV_GTTY TIOCGETP
+# define DV_STTY TIOCSETN
+#else /* not BSD; System V ? */
+# include <fcntl.h>
+# include <termio.h>
+ typedef struct termio dv_tty;
+# define DV_GTTY TCGETA
+# define DV_STTY TCSETAW
+#endif /* BSD */
+
+#include <signal.h>
+#include <errno.h>
+
+static dv_tty init_tty_state; /* store initial terminal characteristics */
+static dv_tty temp_tty_state; /* current terminal characteristics */
+
+#ifndef BSD /* Not BSD */
+ unsigned char saved_cc[NCC];
+#endif /* Not BSD */
+
+/* locally defined and used functions and data */
+
+static Void setsignals (VOID);
+static Void reportio __((int iostat));
+
+static int iostatus; /* return status of ioctl system function */
+
+#ifdef __STDC__
+static Void reportio (int iostat)
+#else
+static Void reportio (iostat)
+ int iostat;
+#endif
+{
+ 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 (VOID)
+{
+ /* 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 (VOID)
+{
+ /* Restore the original tty characteristics. */
+ temp_tty_state = init_tty_state;
+ restore_temp_tty();
+} /* restore_init_tty */
+
+Void save_temp_tty (VOID)
+{
+ /* 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 (VOID)
+{
+ /* Restore the recent tty characteristics. */
+ iostatus = ioctl (DV_FD, DV_STTY, &temp_tty_state);
+ reportio (iostatus);
+} /* restore_temp_tty */
+
+Void singlecharon (VOID)
+{
+ /* 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)
+ {
+ /* First argument to ioctl is a file descriptor; */
+ /* our sysadm, Kevin Pye, says it should be standard input; */
+ /* so 0, not 1. */
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef BSD
+ s.sg_flags |= CBREAK;
+#else /* not BSD */
+ 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 /* BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+#ifdef FLUSH_STDIN
+ fflush (stdin);
+#endif /* FLUSH_STDIN */
+
+ cmode_flags.cbreak = 1;
+ }
+} /* singlecharon */
+
+Void singlecharoff (VOID)
+{
+ /* Turn off single character read mode. */
+ dv_tty s;
+
+ if (cmode_flags.cbreak != 0)
+ {
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef BSD
+ s.sg_flags &= ~CBREAK;
+#else /* not BSD */
+ s.c_lflag |= ICANON; /* Enable erase/kill processing */
+ s.c_cc[VEOL] = saved_cc[VEOL];
+ s.c_cc[VEOF] = saved_cc[VEOF];
+#endif /* BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.cbreak = 0;
+ }
+} /* singlecharoff */
+
+Void echoon (VOID)
+{
+ /* Turn character echoing on. */
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef BSD
+ s.sg_flags |= ECHO;
+#else /* not BSD */
+ s.c_lflag |= ECHO;
+#endif /* BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.echo = 1;
+} /* echoon */
+
+Void echooff (VOID)
+{
+ /* Turn character echoing off. */
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef BSD
+ s.sg_flags &= ~ECHO;
+#else /* not BSD */
+ s.c_lflag &= ~ECHO;
+#endif /* BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.echo = 0;
+ } /* echooff */
+
+Void rawouton (VOID)
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef BSD /* Not BSD */
+ s.c_oflag &= ~OPOST; /* Disables tab interpretation etc. */
+#endif /* Not BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 1;
+} /* rawouton */
+
+Void rawoutoff (VOID)
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef BSD /* Not BSD */
+ s.c_oflag |= OPOST;
+#endif /* Not BSD */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 0;
+} /* rawoutoff */
+
+int buffercount (VOID)
+{
+ /* Return true if there are any characters currently in the input buffer. */
+#ifdef BSD
+ long count;
+ iostatus = ioctl (DV_FD, FIONREAD, &count);
+ reportio (iostatus);
+ return (count > 0);
+#else /* not BSD */
+ 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 /* BSD */
+} /* buffercount */
+
+#ifdef __STDC__
+Void handleint (int sig)
+#else
+Void handleint (sig)
+ int sig;
+#endif
+{
+ /* 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;
+ }
+#ifndef BSD /* Not BSD */
+ setsignals(); /* Because SysV forgets its handlers */
+#endif /* Not BSD */
+} /* handleint */
+
+static Void setsignals (VOID)
+{
+ /* Signal initialization. */
+ signal (SIGINT, handleint);
+#ifdef BSD
+ signal (SIGTSTP, handleint);
+#endif /* BSD */
+} /* setsignals */
+
+Void suspend (VOID)
+{
+ /* Suspend the process */
+#ifdef BSD
+ signal (SIGTSTP, SIG_DFL);
+ kill (0, SIGTSTP);
+ /* resumed again, goody! */
+ setsignals();
+#else
+ /* don't know what to do */
+#endif /* BSD */
+} /* suspend */
+
+#undef IN_UNIXIO_C
diff --git a/dviware/dvgt/dvgt/src/unixio.h b/dviware/dvgt/dvgt/src/unixio.h
new file mode 100644
index 0000000000..891200ea66
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/unixio.h
@@ -0,0 +1,46 @@
+/* unixio.h - 14:52 GMT +10:00 Wed 4 Aug 1993 - modifier Geoffrey Tobin */
+
+#ifndef UNIXIO_H
+#define UNIXIO_H
+
+/* Include file "unixio.h" from screenio.c */
+
+/* The use of `Void' requires that "config.h" be included beforehand */
+
+#ifndef CONFIG_H
+#include "config.h"
+#endif /* CONFIG_H */
+
+/* Add a global structure so we don't need BSD specific stuff. */
+/* -- Ian Dall */
+
+/* gt - for some reason, the Aix "xlc" compiler claims that these
+ structure declarations of sig_flags and cmode_flags cause invalid
+ redeclarations of the same variables where they are defined in
+ "unixio.c".
+*/
+#ifndef IN_UNIXIO_C
+extern struct { unsigned int intr, tstop : 1;} sig_flags;
+extern struct { unsigned int cbreak, raw, echo : 1;} cmode_flags;
+#endif
+
+/* 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 (VOID);
+extern Void restore_init_tty (VOID);
+extern Void save_temp_tty (VOID);
+extern Void restore_temp_tty (VOID);
+extern Void singlecharon (VOID);
+extern Void singlecharoff (VOID);
+extern Void echoon (VOID);
+extern Void echooff (VOID);
+extern Void rawouton (VOID);
+extern Void rawoutoff (VOID);
+extern int buffercount (VOID);
+extern Void suspend (VOID);
+
+#endif /* UNIXIO_H */
+
+/* end unixio.h */
diff --git a/dviware/dvgt/dvgt/src/vdu.c b/dviware/dvgt/dvgt/src/vdu.c
new file mode 100644
index 0000000000..cd027a6301
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vdu.c
@@ -0,0 +1,166 @@
+/* vdu.c - 15:12 GMT +10:00 Wed 4 Aug 1993 - modifier Geoffrey Tobin */
+/* VDU driver interface */
+
+#include "config.h"
+#include "globals.h"
+#include "vdu.h"
+#include "options.h"
+#include "screenio.h"
+
+/* Additional imported functions : VDU initialisation routines */
+
+extern Void InitAED512(), InitNCSATEL(), InitVT100(), InitVT100132(),
+ InitVT640(), InitVIS500(), InitVIS550(), InitVIS630(), InitVIS603(),
+ InitREGIS(), InitVIS240(), InitVT220();
+
+
+/* Exported via "vdu.h" */
+
+boolean vdu_clears_lines; /* Can current VDU clear a single line? */
+
+/* pointers to VDU functions */
+
+Void (*StartText) (VOID);
+Void (*MoveToTextLine) __((int line));
+Void (*ClearTextLine) __((int line));
+Void (*ClearScreen) (VOID);
+Void (*StartGraphics) (VOID);
+Void (*LoadFont) __((Char *fontname, int fontsize, double mag,
+ double hscale, double vscale));
+Void (*ShowChar) __((int screenh, int screenv, Char ch));
+Void (*ShowRectangle) __((int screenh, int screenv, int width, int height,
+ Char ch));
+Void (*ResetVDU) (VOID);
+
+
+/* Local types and variables */
+
+struct vdu_block
+{
+ char * vdu_name;
+ Void (*vdu_init_func)(VOID);
+ boolean vdu_clears_lines;
+};
+
+struct vdu_block InitVDUlist[] =
+{
+ {"aed512", InitAED512, true},
+ {"gigi", InitREGIS, true},
+ {"kermit", InitNCSATEL, false}, /* temporarily for MS-Kermit Tek4010 emu. */
+ {"ncsatel", InitNCSATEL, false}, /* emulates tek4010 */
+ {"regis", InitREGIS, true},
+ {"tek4010", InitNCSATEL, false}, /* temporarily? */
+ {"vis240", InitVIS240, true}, /* I think vis240 can clear a line */
+ {"vis241", InitVIS240, true}, /* I think vis241 can, too */
+ {"vis500", InitVIS500, true},
+ {"vis550", InitVIS550, true},
+ {"vis603", InitVIS603, true}, /* BUT IF vis603 is like Tek4010, it cannot! */
+ {"vis630", InitVIS630, true},
+ {"vk100", InitREGIS, true}, /* I think vk100 can clear a line */
+ {"vt100", InitVT100, true},
+ {"vt100132", InitVT100132, true}, /* I think vt100132 can clear a line */
+ {"vt102", InitVT100, true}, /* I think vt102 can clear a line */
+ {"vt125", InitREGIS, true},
+ {"vt200", InitVT220, true},
+ {"vt220", InitVT220, true},
+ {"vt240", InitREGIS, true},
+ {"vt640", InitVT640, true}
+};
+
+/*******************************************************************/
+
+Void InitVDU (VOID)
+{
+ int i;
+ int n = sizeof (InitVDUlist) / sizeof (struct vdu_block);
+ struct vdu_block * vdu_block_p;
+
+ vdu_clears_lines = false;
+
+ for (i = n, vdu_block_p = InitVDUlist; i > 0; i--, vdu_block_p++)
+ {
+ if (!strcmp (vdu, vdu_block_p->vdu_name))
+ {
+ vdu_block_p->vdu_init_func();
+ vdu_clears_lines = vdu_block_p->vdu_clears_lines;
+ break;
+ }
+ }
+ /* If i == 0 then invalid VDU.
+ * If any of the function pointers are still NULL, then invalid driver.
+ */
+ if (i == 0)
+ {
+ string msgstr;
+ RestoreTerminal();
+ sprintf (msgstr, "Terminal type \"%s\" not supported.", vdu);
+ MesgString (msgstr); MesgLine();
+ sprintf (msgstr,
+ "Either use the \"-v\" option or the TERM environment variable");
+ MesgString (msgstr); MesgLine();
+ sprintf (msgstr, "to specify one of the following terminal types:");
+ MesgString (msgstr); MesgLine();
+#define TERMS_PER_LINE (5)
+ for (vdu_block_p = InitVDUlist, i = n ;i > 0;)
+ {
+ int j;
+ for (j = i < TERMS_PER_LINE? i: TERMS_PER_LINE;
+ j > 0; j--, vdu_block_p++)
+ {
+ sprintf (msgstr, "\t%s", vdu_block_p->vdu_name);
+ MesgString (msgstr);
+ } /* endfor */
+ i -= TERMS_PER_LINE;
+ MesgLine();
+ } /* endfor */
+#undef TERMS_PER_LINE
+ RestoreTerminal(); /* GT - to be safe */
+ exit (1);
+ }
+ else
+ {
+ string msgstr;
+ /* gt - specialised types for the following comparisons */
+
+ typedef Void (*TLFP) __((int line));
+ typedef Void (*SCFP) __((int screenh, int screenv, Char ch));
+ typedef Void (*SRFP) __((int screenh, int screenv,
+ int width, int height, Char ch));
+ typedef Void (*LFFP) __((Char * fontname, int fontsize, double mag,
+ double hscale, double vscale));
+
+ if (StartText == (VFP) NULL
+ || MoveToTextLine == (TLFP) NULL
+ || ClearTextLine == (TLFP) NULL
+ || ClearScreen == (VFP) NULL
+ || StartGraphics == (VFP) NULL
+ || LoadFont == (LFFP) NULL
+ || ShowChar == (SCFP) NULL
+ || ShowRectangle == (SRFP) NULL
+ || ResetVDU == (VFP) NULL)
+ {
+ RestoreTerminal();
+ sprintf (msgstr, "Error in configuration for \"%s\" vdu.", vdu);
+ MesgString (msgstr); MesgLine();
+ RestoreTerminal(); /* GT - to be safe */
+ exit (1);
+ } /* fi */
+ } /* fi */
+} /* End InitVDU () */
+
+/*******************************************************************/
+
+Void LogClearScreen (VOID)
+{
+ ClearScreen();
+ if (logfile != NULL)
+ {
+ fprintf (logfile, "\n");
+ fflush (logfile);
+ }
+}
+/* LogClearScreen */
+
+/*******************************************************************/
+
+/* end vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vdu.h b/dviware/dvgt/dvgt/src/vdu.h
new file mode 100644
index 0000000000..2aad6e672d
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vdu.h
@@ -0,0 +1,85 @@
+/* vdu.h - 20:46 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+#ifndef VDU_H
+#define VDU_H
+
+/* Include file ../include/vdu.h from vis630vdu.c */
+
+
+/* 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 (VOID);
+extern Void LogClearScreen (VOID);
+
+extern Void (*StartText) (VOID);
+extern Void (*MoveToTextLine) __((int line));
+extern Void (*ClearTextLine) __((int line));
+extern Void (*ClearScreen) (VOID);
+extern Void (*StartGraphics) (VOID);
+extern Void (*LoadFont) __((Char *fontname, int fontsize, double mag, double hscale, double vscale));
+extern Void (*ShowChar) __((int screenh, int screenv, Char ch));
+extern Void (*ShowRectangle) __((int screenh, int screenv, int width, int height, Char ch));
+extern Void (*ResetVDU) (VOID);
+
+#endif /* VDU_H */
+
+/* end vdu.h */
diff --git a/dviware/dvgt/dvgt/src/version.h b/dviware/dvgt/dvgt/src/version.h
new file mode 100644
index 0000000000..19004591dd
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/version.h
@@ -0,0 +1,11 @@
+/* version.h - 22:16 GMT +10:00 Fri 20 Aug 1993 - Geoffrey Tobin. */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#define dvgt_version \
+ "This is dvgt 3.51 (DVItoVDU, v. 3.0, gt mod 5 rev 1) - Fri 20 Aug 93"
+
+#endif /* VERSION_H */
+
+/* end version.h */
diff --git a/dviware/dvgt/dvgt/src/vis240vdu.c b/dviware/dvgt/dvgt/src/vis240vdu.c
new file mode 100644
index 0000000000..d825370f43
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis240vdu.c
@@ -0,0 +1,29 @@
+/* vis240vdu.c - 18:39 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "regisvdu.h"
+
+/*************************************************************************/
+
+Void InitVIS240 (VOID)
+{
+ InitREGIS();
+ /* the VIS240/241 has more text lines and a bigger window region: */
+ bottoml = 29;
+ windowwd = 800;
+ windowht = 580 - windowv;
+
+ textlinewidth = 72; /* text characters per line - a guess */
+}
+/*InitVIS240 */
+
+/*************************************************************************/
+
+/* end vis240vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vis500vdu.c b/dviware/dvgt/dvgt/src/vis500vdu.c
new file mode 100644
index 0000000000..0aa125ce79
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis500vdu.c
@@ -0,0 +1,250 @@
+/* vis500vdu.c - 19:22 GMT +10:00 Thu 29 July 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+#include "vis500vdu.h"
+
+/******************************************************************************/
+
+/* Void VIS500StartText: use TEK4010StartText */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void MoveAbs (int row, int col)
+#else
+Static Void MoveAbs (row, col)
+ int row, col;
+#endif
+{
+ /* _Assuming_ we are in VT52 mode (Alphanumeric mode),
+ move the cursor to the given row and column.
+ Since DVItoVDU assumes top left corner of screen is (row=1,col=1),
+ we need to subtract 1 from both coordinates to get the actual
+ VT52 position on the screen.
+ */
+
+ WriteChar (ESC);
+ WriteChar ('Y');
+ WriteChar (row + 31);
+ WriteChar (col + 31);
+ textcolumn = col - 1;
+}
+/* MoveAbs */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS500MoveToTextLine (int line)
+#else
+Void VIS500MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* Move current position to start of given line. */
+
+ WriteChar (CAN);
+
+ MoveAbs (line, 1);
+}
+/* VIS500MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS500ClearTextLine (int line)
+#else
+Void VIS500ClearTextLine (line)
+ int line;
+#endif
+{
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+
+ WriteChar (CAN); /* switch to Alphanumeric mode */
+
+ MoveAbs (line, 1); /* move to start of line */
+ WriteChar (ESC);
+ WriteChar ('K'); /* erase to end of line */
+}
+/* VIS500ClearTextLine */
+
+/******************************************************************************/
+
+Void VIS500ClearScreen (VOID)
+{
+ WriteChar (CAN); /* enable Alphanumeric display */
+
+ WriteChar (ESC);
+ WriteChar ('H'); /* move to top left of screen */
+ WriteChar (ESC);
+ WriteChar ('J'); /* erase to end of screen (Alphanumeric text) */
+ TEK4010ClearScreen(); /* erase graphics */
+}
+/* VIS500ClearScreen */
+
+/******************************************************************************/
+
+/* VIS500StartGraphics: use TEK4010StartGraphics */
+
+/******************************************************************************/
+
+/* VIS500LoadFont: use TEK4010LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS500ShowChar (int screenh, int screenv, Char ch)
+#else
+Void VIS500ShowChar (screenh, screenv, ch)
+ int screenh, screenv;
+ Char ch;
+#endif
+{
+ /* The TEK4010 Terse mode characters on the VIS500 need to be dragged down
+ so that any descenders will be below the baseline represented by screenv.
+ */
+
+ screenv += dragdown;
+ if (screenv > 779) /* drag down as far as possible */
+ TEK4010ShowChar (screenh, 779, ch);
+ else
+ TEK4010ShowChar (screenh, screenv, ch);
+}
+/* VIS500ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS500ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void VIS500ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh, screenv; /* (screenh, screenv) = top left pixel */
+ int width, height; /* (width, height) = size of rectangle */
+ Char ch; /* ch = black pixel */
+#endif
+{
+ /* Display the given rectangle. */
+
+ int pos;
+
+ if (height == 1)
+ {
+ /* show row vector */
+ pos = 779 - screenv;
+
+ WriteChar (GS);
+
+ SendXY (screenh, pos); /* move cursor to start of row */
+ SendXY (screenh + width - 1, pos); /* draw vector to end of row */
+ }
+ else if (width == 1)
+ {
+ /* show column vector */
+ pos = 779 - screenv;
+
+ WriteChar (GS);
+
+ SendXY (screenh, pos); /* move cursor to start of column */
+ SendXY (screenh, pos - height + 1); /* draw vector to end of column */
+ }
+ else
+ {
+ /* assume height and width > 1; draw and fill rectangle */
+ pos = 780 - height - screenv;
+
+ WriteChar (ESC);
+ WriteChar ('/');
+ WriteInt (screenh);
+ WriteChar (';'); /* left */
+ WriteInt (pos);
+ WriteChar (';'); /* bottom */
+ WriteInt (width - 1);
+ WriteChar (';');
+ WriteInt (height + 1);
+ WriteChar ('y');
+
+ /* Note that there are a few problems with this command:
+ - we need to subtract 1 from width. While this prevents exceeding the
+ right edge (reason unknown), it causes missing pixel columns.
+ - we need to ADD 1 to height to avoid missing pixel rows.
+ - the smallest rectangle drawn is 2 by 2.
+ - the new cursor position is undefined.
+ These funnies are outweighed by the improved efficiency in drawing large
+ rectangles.
+ */
+
+ havesentxy = false; /* need to re-synch cursor position */
+ }
+}
+/* VIS500ShowRectangle */
+
+/******************************************************************************/
+
+Void VIS500ResetVDU (VOID)
+{
+ WriteChar (CAN); /* make sure terminal is in Alphanumeric mode */
+}
+/* VIS500ResetVDU */
+
+/******************************************************************************/
+
+Void InitVIS500 (VOID)
+{
+ /* The main program only calls this routine after it has parsed the command
+ line and successfully opened the given DVI file.
+ */
+
+ InitTEK4010emu();
+
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = 33; /* also number of text lines on VIS500 screen */
+
+ /* The above values _assume_ the VIS500 is in Alphanumeric mode;
+ the following values _assume_ it 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).
+ */
+
+ windowv = 92; /* approx. height in TEK4010 pixels of 4 text lines;
+ i.e. 4 * 780/34 */
+ windowh = 0;
+ windowht = 780 - windowv;
+ windowwd = 1024;
+
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ MoveToTextLine = VIS500MoveToTextLine;
+ ClearTextLine = VIS500ClearTextLine;
+ ClearScreen = VIS500ClearScreen;
+ StartText = TEK4010StartText;
+ StartGraphics = TEK4010StartGraphics;
+ LoadFont = TEK4010LoadFont;
+ ShowChar = VIS500ShowChar;
+ ShowRectangle = VIS500ShowRectangle;
+ ResetVDU = VIS500ResetVDU;
+
+ WriteChar (GS);
+
+ WriteChar (ESC);
+ WriteChar ('@'); /* solid fill for rectangular draw and fill */
+
+ WriteChar (CAN);
+}
+/* InitVIS500 */
+
+/******************************************************************************/
+
+/* end vis500vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vis500vdu.h b/dviware/dvgt/dvgt/src/vis500vdu.h
new file mode 100644
index 0000000000..31ec7fce73
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis500vdu.h
@@ -0,0 +1,23 @@
+/* vis500vdu.h - 20:10 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+#ifndef VIS500VDU_H
+#define VIS500VDU_H
+
+/* Include file ../include/vis500vdu.h from vis630vdu.c */
+
+
+extern Void InitVIS500VDU (VOID);
+
+extern Void VIS500MoveToTextLine __((int line));
+
+extern Void VIS500ClearScreen (VOID);
+
+extern Void VIS500ShowChar __((int screenh, int screenv, Char ch));
+
+extern Void VIS500ShowRectangle __((int screenh, int screenv, int width,
+ int height, Char ch));
+extern Void VIS500ResetVDU (VOID);
+
+#endif /* VIS500VDU_H */
+
+/* end vis500vdu.h */
diff --git a/dviware/dvgt/dvgt/src/vis550vdu.c b/dviware/dvgt/dvgt/src/vis550vdu.c
new file mode 100644
index 0000000000..99541c8e97
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis550vdu.c
@@ -0,0 +1,128 @@
+/* vis550vdu.c - 18:41 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+#include "vt100vdu.h"
+#include "vis500vdu.h"
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS550MoveToTextLine (int line)
+#else
+Void VIS550MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* Move current position to start of given line. */
+
+ WriteChar (CAN);
+
+ VT100MoveToTextLine (line);
+}
+/* VIS550MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS550ClearTextLine (int line)
+#else
+Void VIS550ClearTextLine (line)
+ int line;
+#endif
+{
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+
+ WriteChar (CAN);
+
+ VT100ClearTextLine (line);
+}
+/* VIS550ClearTextLine */
+
+/******************************************************************************/
+
+Void VIS550ClearScreen (VOID)
+{
+ WriteChar (CAN);
+
+ VT100ClearScreen();
+ TEK4010ClearScreen();
+}
+/* VIS550ClearScreen */
+
+/******************************************************************************/
+
+/* VIS550ShowChar: use VIS500ShowChar */
+
+/******************************************************************************/
+
+/* VIS550ShowRectangle: use VIS500ShowRectangle */
+
+/******************************************************************************/
+
+/* VIS550ResetVDU: use VIS500ResetVDU */
+
+/******************************************************************************/
+
+Void InitVIS550 (VOID)
+{
+ /* The dialog region will be the top 4 text lines in VT100 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 VT100 mode.
+ */
+
+ InitTEK4010emu(); /* We overwrite the things we don't want */
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = 33; /* also = number of text lines on screen */
+
+ /* The above values assume the VIS550 is in VT100 mode;
+ the following values assume it 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).
+ */
+
+ windowv = 92; /* approx. height in TEK4010 pixels of 4 text lines
+ i.e. ~ 4 * 780/34 */
+ windowh = 0;
+ windowht = 780 - windowv;
+ windowwd = 1024;
+
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ MoveToTextLine = VIS550MoveToTextLine;
+ ClearTextLine = VIS550ClearTextLine;
+ ClearScreen = VIS550ClearScreen;
+ StartText = TEK4010StartText;
+ StartGraphics = TEK4010StartGraphics;
+ LoadFont = TEK4010LoadFont;
+ ShowChar = VIS500ShowChar;
+ ShowRectangle = VIS500ShowRectangle;
+ ResetVDU = VIS500ResetVDU;
+
+ WriteChar (GS);
+
+ WriteChar (ESC);
+ WriteChar ('@'); /* solid fill for rectangular draw and fill */
+
+ WriteChar (CAN);
+}
+/*InitVIS550 */
+
+/******************************************************************************/
+
+/* end vis550vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vis603vdu.c b/dviware/dvgt/dvgt/src/vis603vdu.c
new file mode 100644
index 0000000000..3776ce4184
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis603vdu.c
@@ -0,0 +1,50 @@
+/* vis603vdu.c - 18:46 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+
+extern Void InitVIS630 (VOID);
+
+/*****************************************************************************/
+
+Void InitVIS603 (VOID)
+{
+ /* The dialog region will be the top 4 text lines in VT200 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 24 in VT200 mode.
+ */
+
+ InitVIS630();
+
+ /* The following values assume the VIS603 is in VT200 mode. */
+
+ bottoml = 24; /* also number of text lines on screen */
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ /* The following values assume it 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).
+ */
+
+ windowv = 125;
+ /* approx. height in TEK4010 pixels of 4 text lines
+ i.e. ~ 4 * 780/25 */
+ windowh = 0;
+ windowht = 745 - windowv; /* avoid drawing in status line */
+ windowwd = 1024;
+}
+/*InitVIS603 */
+
+/*****************************************************************************/
+
+/* end vis603vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vis630vdu.c b/dviware/dvgt/dvgt/src/vis630vdu.c
new file mode 100644
index 0000000000..726c2868e5
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vis630vdu.c
@@ -0,0 +1,322 @@
+/* vis630vdu.c - 18:51 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+#include "vt100vdu.h"
+
+Static int cursrow, curscol; /* VIS630ShowChar remembers cursor location */
+Static boolean textmode; /* are we in VT200 mode? */
+
+/******************************************************************************/
+
+Void VIS630StartText (VOID)
+{
+ /* We are about to draw text in dialogue region. */
+
+ WriteChar (CAN);
+
+ textmode = true;
+}
+/* VIS630StartText */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS630MoveToTextLine (int line)
+#else
+Void VIS630MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* Move current position to start of given line. */
+
+ WriteChar (CAN);
+
+ textmode = true;
+ VT100MoveToTextLine (line);
+}
+/* VIS630MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS630ClearTextLine (int line)
+#else
+Void VIS630ClearTextLine (line)
+int line;
+#endif
+{
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+
+ WriteChar (CAN);
+
+ textmode = true;
+ VT100ClearTextLine (line);
+}
+/* VIS630ClearTextLine */
+
+/******************************************************************************/
+
+Void VIS630ClearScreen (VOID)
+{
+ WriteChar (CAN);
+
+ textmode = true;
+ VT100ClearScreen();
+ TEK4010ClearScreen();
+ textmode = false;
+}
+/* VIS630ClearScreen */
+
+/******************************************************************************/
+
+Void VIS630StartGraphics (VOID)
+{
+ /* We are about to draw in window region. */
+
+ TEK4010StartGraphics();
+ textmode = false;
+ cursrow = 0;
+}
+/* VIS630StartGraphics */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS630LoadFont (Char * fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void VIS630LoadFont (fontname, fontsize, mag, hscale, vscale)
+ Char * fontname; int fontsize; double mag;
+ double hscale, vscale;
+#endif
+{
+ TEK4010LoadFont (fontname, fontsize, mag, hscale, vscale);
+ textmode = false;
+}
+/* VIS630LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS630ShowChar (int screenh, int screenv, Char ch)
+#else
+Void VIS630ShowChar (screenh, screenv, ch)
+ int screenh; int screenv; Char ch;
+#endif
+{
+ /* We use VT200 text mode because it is much faster. */
+
+ int amount;
+
+ /* first translate DVItoVDU coordinates into actual screen location */
+ if (!textmode)
+ {
+ WriteChar (CAN);
+
+ textmode = true;
+ }
+ screenh = (int) (screenh * 132.0 / 1024);
+ screenv = (int) (screenv * bottoml / 753);
+
+ screenh++;
+ screenv++;
+ if (cursrow == screenv)
+ {
+ /* The cursor is on the same line as in previous VIS630ShowChar call,
+ so we only need to move left or right,
+ and probably just a small amount (if at all).
+ */
+ if (screenh == curscol) /* cursor in correct location */
+ curscol++; /* cursor will move right when ch written */
+ else if (screenh < curscol)
+ { /* move cursor left */
+ amount = curscol - screenh;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1) /* default is 1 col */
+ {
+ WriteInt (amount);
+ curscol += 1 - amount; /* no need if amount = 1 */
+ }
+ WriteChar ('D');
+ }
+ else
+ { /* move cursor right */
+ amount = screenh - curscol;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1) /* default is 1 col */
+ WriteInt (amount);
+ curscol += amount + 1;
+ WriteChar ('C');
+ }
+ }
+ else /* cursrow undefined or ch on a new line */
+ {
+ VT100MoveAbs (screenv, screenh);
+ cursrow = screenv;
+ curscol = screenh + 1; /* cursor will move right when ch written */
+ }
+ if (screenh == windowwd) /* ch will be written at right edge */
+ cursrow = 0;
+ /* so avoid auto wrap next time around */
+ WriteChar (TeXtoASCII[ch - NUL]);
+}
+/* VIS630ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VIS630ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void VIS630ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh, screenv; /* (screenh, screenv) = top left pixel */
+ int width, height; /* (width, height) = size of rectangle */
+ Char ch; /* ch = black pixel */
+#endif
+{
+ /* Display the given rectangle. */
+
+ int pos;
+
+ textmode = false;
+ if (height == 1)
+ {
+ /* show row vector */
+ pos = 779 - screenv;
+
+ WriteChar (GS);
+
+ SendXY (screenh, pos); /* move cursor to start of row */
+ SendXY (screenh + width - 1, pos); /* draw vector to end of row */
+ }
+ else if (width == 1)
+ {
+ /* show column vector */
+ pos = 779 - screenv;
+
+ WriteChar (GS);
+
+ SendXY (screenh, pos); /* move cursor to start of column */
+ SendXY (screenh, pos - height + 1); /* draw vector to end of column */
+ }
+ else
+ {
+ /* assume height and width > 1; draw and fill rectangle */
+ pos = 780 - height - screenv;
+
+ WriteChar (ESC);
+ WriteChar ('/');
+ WriteInt (screenh);
+ WriteChar (';'); /* left */
+ WriteInt (pos);
+ WriteChar (';'); /* bottom */
+ WriteInt (width - 1);
+ WriteChar (';');
+ WriteInt (height + 1);
+ WriteChar ('y');
+
+ /* Note that there are a few problems with this command:
+ - we need to subtract 1 from width. While this prevents exceeding the
+ right edge (reason unknown), it causes missing pixel columns.
+ - we need to ADD 1 to height to avoid missing pixel rows.
+ - the smallest rectangle drawn is 2 by 2.
+ - the new cursor position is undefined.
+ IS THIS TRUE FOR VIS 630???
+ These funnies are outweighed by the improved efficiency
+ in drawing large rectangles.
+ */
+
+ havesentxy = false; /* need to re-synch cursor position */
+ }
+}
+/* VIS630ShowRectangle */
+
+/******************************************************************************/
+
+Void VIS630ResetVDU (VOID)
+{
+ WriteChar (ESC);
+ WriteString ("[?50h");
+ /* 80 COL ITAG + graphics */
+
+ WriteChar (CAN);
+
+ textmode = true;
+}
+/* VIS630ResetVDU */
+
+/******************************************************************************/
+
+Void InitVIS630 (VOID)
+{
+ /* The dialog region will be the top 4 text lines in VT200 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 50 in VT200 mode.
+ */
+
+ InitTEK4010emu();
+
+ /* The following values assume the VIS630 is in VT200 mode. */
+
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = 50; /* also number of text lines on screen */
+
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ /* The following values assume it 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).
+ */
+
+ windowv = 55;
+ /* approx. height in TEK4010 pixels of 4 text lines
+ i.e. ~ 4 * 780/50 */
+ windowh = 0;
+ windowht = 753 - windowv; /* avoid drawing in status line */
+ windowwd = 1024;
+
+ MoveToTextLine = VIS630MoveToTextLine;
+ ClearTextLine = VIS630ClearTextLine;
+ ClearScreen = VIS630ClearScreen;
+ StartText = VIS630StartText;
+ StartGraphics = VIS630StartGraphics;
+ LoadFont = VIS630LoadFont;
+ ShowChar = VIS630ShowChar;
+ ShowRectangle = VIS630ShowRectangle;
+ ResetVDU = VIS630ResetVDU;
+
+ WriteChar (GS);
+
+ WriteChar (ESC);
+ WriteChar ('@'); /* solid fill for rectangular draw and fill */
+ WriteChar (ESC);
+ WriteString ("[?40h");
+ /* 132 COL ITAG + graphics */
+
+ WriteChar (CAN);
+
+ textmode = true;
+}
+/*InitVIS630 */
+
+/******************************************************************************/
+
+/* end vis630vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vt100132vdu.c b/dviware/dvgt/dvgt/src/vt100132vdu.c
new file mode 100644
index 0000000000..6c33ddba41
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vt100132vdu.c
@@ -0,0 +1,56 @@
+/* vt100132vdu.c - 19:03 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "vdu.h"
+
+/******************************************************************************/
+
+Void VT100132ResetVDU (VOID)
+{
+ /* We assume user wants to return to 80 column mode. */
+ WriteChar (ESC);
+ WriteString ("[?3l");
+
+ textlinewidth = 80; /* text characters per line */
+}
+/* VT100132ResetVDU */
+
+/******************************************************************************/
+
+/* On a VT100, a "pixel" is a character. */
+
+#define screenwd 132 /* width of wide VT100 screen in pixels */
+#define screenht 24 /* height of VT100 screen in pixels */
+#define lineht 1 /* height of one text line in pixels */
+
+extern Void InitVT100();
+
+Void InitVT100132 (VOID)
+{
+ /* The main program only calls this routine after it has parsed the command
+ line and successfully opened the given DVI file.
+ */
+ /* initialize the VDU parameters */
+ InitVT100();
+ ResetVDU = VT100132ResetVDU;
+ windowwd = screenwd;
+
+ /* 132 column mode */
+ WriteChar (ESC);
+ WriteString ("[?3h");
+
+ textlinewidth = screenwd; /* text characters per line */
+}
+/*InitVT100132 */
+
+#undef screenwd
+#undef screenht
+#undef lineht
+
+/******************************************************************************/
+
+/* end vt100132vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vt100vdu.c b/dviware/dvgt/dvgt/src/vt100vdu.c
new file mode 100644
index 0000000000..860c484565
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vt100vdu.c
@@ -0,0 +1,276 @@
+/* vt100vdu.c - 20:21 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "vdu.h"
+
+Static int cursrow, curscol; /* VT100ShowChar remembers cursor location */
+
+/******************************************************************************/
+
+Void VT100StartText (VOID)
+{
+ /* We are about to draw text in dialogue region. */
+ /* VT100 treats text and graphics the same, so do nothing */
+}
+/* VT100StartText */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100MoveAbs (int row, int col)
+#else
+Void VT100MoveAbs (row, col)
+ int row; int col;
+#endif
+{
+ /* Move cursor to given screen position. */
+
+ WriteChar (ESC);
+ WriteChar ('[');
+ WriteInt (row);
+ WriteChar (';');
+ WriteInt (col);
+ WriteChar ('H');
+ textcolumn = col - 1; /* textcolumn = 0 at start of line, where col = 1 */
+}
+/* VT100MoveAbs */
+
+/******************************************************************************/
+
+#define MoveAbs(X,Y) VT100MoveAbs(X,Y)
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100MoveToTextLine (int line)
+#else
+Void VT100MoveToTextLine (line)
+ int line;
+#endif
+{
+ /* Move current position to start of given line. */
+
+ MoveAbs (line, 1);
+}
+/* VT100MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100ClearTextLine (int line)
+#else
+Void VT100ClearTextLine (line)
+ int line;
+#endif
+{
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+
+ MoveAbs (line, 1);
+ /* erase to end of line */
+ WriteChar (ESC);
+ WriteString ("[K");
+}
+/* VT100ClearTextLine */
+
+/******************************************************************************/
+
+Void VT100ClearScreen (VOID)
+{
+ /* erase entire screen */
+
+ WriteChar (ESC);
+ WriteString ("[2J");
+}
+/* VT100ClearScreen */
+
+/******************************************************************************/
+
+Void VT100StartGraphics (VOID)
+{
+ /* We are about to draw in window region.
+ VT100 makes no distinction between text and graphics.
+ All we do is reset the current cursor position to some undefined state
+ for use in the next VT100ShowChar call.
+ */
+
+ cursrow = 0;
+}
+/* VT100StartGraphics */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100LoadFont (Char * fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void VT100LoadFont (fontname, fontsize, mag, hscale, vscale)
+ Char * fontname; int fontsize; double mag;
+ double hscale, vscale;
+#endif
+{
+ /* only one character size available on VT100s, so do nothing */
+}
+/* VT100LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100ShowChar (int screenh, int screenv, Char ch)
+#else
+Void VT100ShowChar (screenh, screenv, ch)
+ int screenh, screenv;
+ Char ch;
+#endif
+{
+ /* Show the given Terse character (mapped to ASCII) at the given position.
+ We remember the cursor position (cursrow,curscol) so we can reduce the
+ output bytes needed to position the next Terse character.
+ VT100StartGraphics resets the position to an undefined state (cursrow = 0).
+ We also reset when the cursor reaches the right edge (= windowwd) to
+ avoid possibility of any auto wrap.
+ */
+
+ int amount;
+
+ /* first translate DVItoVDU coordinates into actual screen location */
+ screenh++;
+ screenv++;
+ if (cursrow == screenv)
+ {
+ /* The cursor is on the same line as in previous VT100ShowChar call,
+ so we only need to move left or right,
+ and probably just a small amount (if at all).
+ */
+
+ if (screenh == curscol) /* cursor in correct location */
+ curscol++; /* cursor will move right when ch written */
+ else if (screenh < curscol)
+ {
+ amount = curscol - screenh;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1) /* default is 1 col */
+ {
+ WriteInt (amount);
+ curscol += 1 - amount; /* no need if amount = 1 */
+ }
+ WriteChar ('D');
+ }
+ else
+ {
+ amount = screenh - curscol;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1) /* default is 1 col */
+ WriteInt (amount);
+ curscol += amount + 1;
+ WriteChar ('C');
+ }
+ }
+ else /* cursrow undefined or ch on a new line */
+ {
+ MoveAbs (screenv, screenh);
+ cursrow = screenv;
+ curscol = screenh + 1; /* cursor will move right when ch written */
+ }
+ if (screenh == windowwd) /* ch will be written at right edge */
+ cursrow = 0;
+ /* so avoid auto wrap next time around */
+ WriteChar (TeXtoASCII[ch - NUL]);
+
+ /* move cursor left */
+ /* move cursor right */
+}
+/* VT100ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT100ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void VT100ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh; int screenv; /* top left pixel */
+ int width; int height; /* size of rectangle */
+ Char ch; /* black pixel */
+#endif
+{
+ /* Display the given rectangle using the given black pixel character.
+ DVItoVDU ensures the entire rectangle is visible.
+ */
+
+ int i, j;
+
+ ch = TeXtoASCII[ch - NUL]; /* first convert TeX ch to ASCII */
+ screenh++;
+ for (i = 1; i <= height; i++)
+ {
+ /* adding 1 to screenv here */
+ MoveAbs (screenv + i, screenh); /* move cursor to start of next row */
+ for (j = 1; j <= width; j++)
+ WriteChar (ch);
+ }
+}
+/* VT100ShowRectangle */
+
+/******************************************************************************/
+
+Void VT100ResetVDU (VOID)
+{
+ /* no need to do anything */
+}
+/* VT100ResetVDU */
+
+/******************************************************************************/
+
+/* On a VT100 a "pixel" is a character. */
+
+#define screenwd 80 /* width of VT100 screen in pixels */
+#define screenht 24 /* height of VT100 screen in pixels */
+#define lineht 1 /* height of one text line in pixels */
+
+Void InitVT100 (VOID)
+{
+ /* The main program only calls this routine after it has parsed the command
+ line and successfully opened the given DVI file.
+ */
+
+ /* initialize the VDU parameters */
+ DVIstatusl = 1;
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = screenht; /* = number of text lines */
+
+ textlinewidth = screenwd; /* text characters per line */
+
+ windowh = 0;
+ windowv = lineht * 4;
+ windowwd = screenwd;
+ windowht = screenht - lineht * 4;
+
+ MoveToTextLine = VT100MoveToTextLine;
+ ClearTextLine = VT100ClearTextLine;
+ ClearScreen = VT100ClearScreen;
+ StartText = VT100StartText;
+ StartGraphics = VT100StartGraphics;
+ LoadFont = VT100LoadFont;
+ ShowChar = VT100ShowChar;
+ ShowRectangle = VT100ShowRectangle;
+ ResetVDU = VT100ResetVDU;
+
+} /*InitVT100 */
+
+#undef screenwd
+#undef screenht
+#undef lineht
+
+/******************************************************************************/
+
+/* end vt100vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vt100vdu.h b/dviware/dvgt/dvgt/src/vt100vdu.h
new file mode 100644
index 0000000000..fc695b2b54
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vt100vdu.h
@@ -0,0 +1,33 @@
+/* vt100vdu.h - 20:10 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+#ifndef VT100VDU_H
+#define VT100VDU_H
+
+/* Include file ../include/vt100vdu.h from vis630vdu.c */
+
+
+extern Void InitVT100VDU (VOID);
+
+extern Void VT100StartText (VOID);
+
+extern Void VT100MoveAbs __((int row, int col));
+
+extern Void VT100MoveToTextLine __((int line));
+
+extern Void VT100ClearTextLine __((int line));
+
+extern Void VT100ClearScreen (VOID);
+
+extern Void VT100StartGraphics (VOID);
+
+extern Void VT100LoadFont __((Char *fontname, int fontsize, double mag,
+ double hscale, double vscale));
+
+extern Void VT100ShowChar __((int screenh, int screenv, Char ch));
+
+extern Void VT100ShowRectangle __((int screenh, int screenv, int width,
+ int height, Char ch));
+
+#endif /* VT100VDU_H */
+
+/* end vt100vdu.h */
diff --git a/dviware/dvgt/dvgt/src/vt220vdu.c b/dviware/dvgt/dvgt/src/vt220vdu.c
new file mode 100644
index 0000000000..b036a49071
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vt220vdu.c
@@ -0,0 +1,361 @@
+/* vt220vdu.c - 22:01 GMT +10:00 Fri 23 July 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+#include "screenio.h"
+#include "vdu.h"
+#include "vt100vdu.h"
+
+
+#define MoveAbs(x,y) VT100MoveAbs(x,y)
+
+#define SO '\016'
+#define SI '\017'
+
+#define hpixels 1 /* horizontal pixels per char position */
+#define vpixels 5 /* vertical pixels per char position */
+#define flag 7
+#define hscreenmax 131 /* max horizontal char coordinate */
+#define vscreenmax 23 /* max vertical char coordinate */
+
+
+Static int cursrow, curscol; /* VT220ShowChar remembers cursor location */
+Static int rectcount;
+/* keeps a count of VT220ShowRectangle calls;
+ reset in ShowBitmap */
+Static int Bitmap[hscreenmax + 1][vscreenmax + 1];
+
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Static Void MoveQuick (int screenh, int screenv)
+#else
+Static Void MoveQuick (screenh, screenv)
+ int screenh, screenv;
+#endif
+{
+ /* Move cursor to given screen position.
+ We remember the cursor position (cursrow, curscol),
+ so we can reduce the output bytes needed to do the next MoveQuick.
+ VT220StartGraphics resets the position to an undefined state (cursrow = 0).
+ We also reset when the cursor reaches the right edge (= windowwd),
+ to avoid possibility of any auto wrap.
+ */
+
+ int amount;
+
+ /* first translate DVItoVDU coordinates into actual screen location */
+ screenh++;
+ screenv++;
+ if (cursrow == screenv)
+ {
+ /* The cursor is on the same line as in previous MoveQuick call,
+ so we only need to move left or right,
+ and probably just a small amount (if at all).
+ */
+
+ if (screenh == curscol) /* cursor in correct location */
+ curscol++; /* cursor will move right when ch written */
+ else if (screenh < curscol)
+ {
+ /* move cursor left */
+ amount = curscol - screenh;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1)
+ {
+ /* default is 1 col */
+ WriteInt (amount);
+ curscol += 1 - amount;
+ }
+ WriteChar ('D');
+ }
+ else
+ {
+ amount = screenh - curscol;
+ WriteChar (ESC);
+ WriteChar ('[');
+ if (amount > 1) /* default is 1 col */
+ WriteInt (amount);
+ curscol += amount + 1;
+ WriteChar ('C');
+ }
+ }
+ else
+ {
+ /* cursrow undefined or ch on a new line */
+ MoveAbs (screenv, screenh);
+ cursrow = screenv;
+ curscol = screenh + 1; /* cursor will move right when ch written */
+ }
+ if (screenh == windowwd) /* ch will be written at right edge */
+ cursrow = 0;
+ /* so avoid auto wrap next time around */
+
+ /* move cursor right */
+
+ /* at start of a line, textcolumn = 0, curscol = 1 */
+ textcolumn = (curscol > 0 ? curscol - 1 : 0);
+}
+/* MoveQuick */
+
+/******************************************************************************/
+
+Static Void ClearBitmap (VOID)
+{
+ /* Clear the Bitmap. */
+
+ int h, v;
+
+ for (v = 4; v <= vscreenmax; v++) /* ignore dialogue lines 0..3 */
+ for (h = 0; h <= hscreenmax; h++)
+ Bitmap[h][v] = 0;
+}
+/* ClearBitmap */
+
+/******************************************************************************/
+
+Static Void ShowBitmap (VOID)
+{
+ /* Display only the flagged characters in the Bitmap. */
+
+ int h, v;
+
+ WriteChar (SO); /* assume only working over 7 bit comm lines */
+ for (v = 4; v <= vscreenmax; v++)
+ {
+ /* ignore dialogue lines */
+ for (h = 0; h <= hscreenmax; h++)
+ {
+ if ((unsigned)flag < 32 && ((1 << flag) & Bitmap[h][v]) != 0)
+ {
+ /* send flagged character */
+ Bitmap[h][v] &= ~(1 << flag); /* clear flag */
+ MoveQuick (h, v);
+ WriteChar (byte3(Bitmap[0][0]) + 32);
+ }
+ }
+ }
+ WriteChar (SI); /* assume only working over 7 bit comm lines */
+ WriteFlush();
+ rectcount = 0;
+}
+/* ShowBitmap */
+
+/******************************************************************************/
+
+Void VT220StartText (VOID)
+{
+ /* We are about to draw text in dialogue region. */
+
+ ShowBitmap();
+}
+/* VT220StartText */
+
+/******************************************************************************/
+
+Void VT220ClearScreen (VOID)
+{
+ VT100ClearScreen();
+ ClearBitmap(); /* reset Bitmap */
+}
+/* VT220ClearScreen */
+
+/******************************************************************************/
+
+Void VT220StartGraphics (VOID)
+{
+ /* We are about to draw in window region. */
+
+ rectcount = 0;
+ cursrow = 0; /* for MoveQuick */
+}
+/* VT220StartGraphics */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT220LoadFont (Char * fontname, int fontsize, double mag,
+ double hscale, double vscale)
+#else
+Void VT220LoadFont (fontname, fontsize, mag, hscale, vscale)
+ Char * fontname; int fontsize; double mag;
+ double hscale, vscale;
+#endif
+{
+ /* only one character size available on VT220s, so do nothing */
+}
+/* VT220LoadFont */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT220ShowChar (int screenh, int screenv, Char ch)
+#else
+Void VT220ShowChar (screenh, screenv, ch)
+ int screenh, screenv;
+ Char ch;
+#endif
+{
+ /* Show the given Terse character (mapped to ASCII) at the given position. */
+
+ if (rectcount > 0) /* flush Bitmap if VT220ShowRectangle/s are pending */
+ ShowBitmap();
+ MoveQuick (screenh, screenv / vpixels);
+ WriteChar (TeXtoASCII[ch - NUL]);
+}
+/* VT220ShowChar */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT220ShowRectangle (int screenh, int screenv, int width, int height,
+ Char ch)
+#else
+Void VT220ShowRectangle (screenh, screenv, width, height, ch)
+ int screenh; int screenv; /* top left pixel */
+ int width; int height; /* size of rectangle */
+ Char ch; /* black pixel */
+#endif
+{
+ /* Set the given rectangular Bitmap region.
+ DVItoVDU ensures the top left position is visible and the given
+ dimensions do not go beyond the window edges.
+ */
+
+ int h, v, vrow;
+
+ for (v = screenv; v < screenv + height; v++)
+ {
+ for (h = screenh; h < screenh + width; h++)
+ {
+ /* set bit h,v in Bitmap */
+ vrow = v / vpixels;
+ /* include flag so char will be sent */
+ Bitmap[h][vrow] |= (1 << (v % vpixels)) | (1 << flag);
+ }
+ }
+ rectcount++;
+ /* avoid too much of a pause before flushing Bitmap */
+ if (rectcount == 400)
+ ShowBitmap();
+}
+/* VT220ShowRectangle */
+
+/******************************************************************************/
+
+Static Void LoadPixels (VOID)
+{
+ /* Down-load the chunky graphics character set into the VT220. */
+
+ /* gt - WARNING: re ANSI standard C,
+ and Aix C (even Aix "cc") :
+ Watch out for trigraphs: "??nonletter", where nonletter is
+ one of the nine characters =, /, ', (, ), !, <, > or -.
+ See Kernighan & Ritchie (2nd edition, 1988), page 229.
+ "??" followed by "/" is a trigraph that occurs below.
+ */
+
+ WriteChar (ESC);
+ WriteChar ('P');
+ WriteString ("1;1;2;3;2;1{&%C");
+ WriteString ("BBBBBBBB/????????;");
+ WriteString ("KKKKKKKK/????????;");
+ WriteString ("NNNNNNNN/????????;");
+ WriteString ("oooooooo/????????;");
+ WriteString ("rrrrrrrr/????????;");
+ WriteString ("{{{{{{{{/????????;");
+ WriteString ("~~~~~~~~/????????;");
+ WriteString ("????????"); WriteString ("/BBBBBBBB;");
+ WriteString ("BBBBBBBB/BBBBBBBB;");
+ WriteString ("KKKKKKKK/BBBBBBBB;");
+ WriteString ("NNNNNNNN/BBBBBBBB;");
+ WriteString ("oooooooo/BBBBBBBB;");
+ WriteString ("rrrrrrrr/BBBBBBBB;");
+ WriteString ("{{{{{{{{/BBBBBBBB;");
+ WriteString ("~~~~~~~~/BBBBBBBB;");
+ WriteString ("????????"); WriteString ("/KKKKKKKK;");
+ WriteString ("BBBBBBBB/KKKKKKKK;");
+ WriteString ("KKKKKKKK/KKKKKKKK;");
+ WriteString ("NNNNNNNN/KKKKKKKK;");
+ WriteString ("oooooooo/KKKKKKKK;");
+ WriteString ("rrrrrrrr/KKKKKKKK;");
+ WriteString ("{{{{{{{{/KKKKKKKK;");
+ WriteString ("~~~~~~~~/KKKKKKKK;");
+ WriteString ("????????"); WriteString ("/NNNNNNNN;");
+ WriteString ("BBBBBBBB/NNNNNNNN;");
+ WriteString ("KKKKKKKK/NNNNNNNN;");
+ WriteString ("NNNNNNNN/NNNNNNNN;");
+ WriteString ("oooooooo/NNNNNNNN;");
+ WriteString ("rrrrrrrr/NNNNNNNN;");
+ WriteString ("{{{{{{{{/NNNNNNNN;");
+ WriteString ("~~~~~~~~/NNNNNNNN");
+ WriteChar (ESC);
+ WriteChar ('\\'); /* ESC \ */
+ WriteChar (ESC);
+ WriteString (")&%C");
+ /* set as G1 character set */
+}
+/* LoadPixels */
+
+/******************************************************************************/
+
+Void VT220ResetVDU (VOID)
+{
+ /* We don't do a hardware reset, but leave VDU in 80 column mode. */
+
+ /* 80 column mode */
+ WriteChar (ESC);
+ WriteString ("[?3l");
+
+ textlinewidth = 80; /* text characters per line */
+}
+/* VT220ResetVDU */
+
+/******************************************************************************/
+
+Void InitVT220 (VOID)
+{
+ /* The dialogue region is the top 4 lines.
+ The window region is the remaining area of the screen
+ (the bottom 20 rows in Bitmap).
+ */
+
+ DVIstatusl = 1;
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = vscreenmax + 1;
+
+ /* DVItoVDU's coordinate scheme is the same as the VT220 scheme. */
+
+ windowh = 0;
+ windowv = vpixels * 4; /* = height of 4 dialogue lines */
+ windowwd = hscreenmax + 1;
+ windowht = (vscreenmax + 1) * vpixels - windowv;
+
+ MoveToTextLine = VT100MoveToTextLine;
+ ClearTextLine = VT100ClearTextLine;
+ ClearScreen = VT220ClearScreen;
+ StartText = VT220StartText;
+ StartGraphics = VT220StartGraphics;
+ LoadFont = VT220LoadFont;
+ ShowChar = VT220ShowChar;
+ ShowRectangle = VT220ShowRectangle;
+ ResetVDU = VT220ResetVDU;
+ LoadPixels();
+
+ /* 132 column mode */
+ WriteChar (ESC);
+ WriteString ("[?3h");
+
+ textlinewidth = 132; /* text characters per line */
+}
+/*InitVT220 */
+
+/******************************************************************************/
+
+/* end vt220vdu.c */
diff --git a/dviware/dvgt/dvgt/src/vt640vdu.c b/dviware/dvgt/dvgt/src/vt640vdu.c
new file mode 100644
index 0000000000..d900941ac3
--- /dev/null
+++ b/dviware/dvgt/dvgt/src/vt640vdu.c
@@ -0,0 +1,128 @@
+/* vt640vdu.c - 19:05 GMT +10:00 Sat 12 Jun 1993 - modifier Geoffrey Tobin */
+
+/* From input file "../include/globals.p" */
+
+#include "config.h"
+#include "globals.h"
+
+#include "screenio.h"
+#include "vdu.h"
+
+#include "tek4010emu.h"
+#include "vt100vdu.h"
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT640MoveToTextLine (int line)
+#else
+Void VT640MoveToTextLine (line)
+int line;
+#endif
+{
+ /* Move current position to start of given line. */
+
+ WriteChar (GS); /* cannot send CAN if VT640 is already in VT100 mode */
+
+ WriteChar (CAN); /* switch to VT100 mode */
+
+ VT100MoveToTextLine (line);
+}
+/* VT640MoveToTextLine */
+
+/******************************************************************************/
+
+#ifdef __STDC__
+Void VT640ClearTextLine (int line)
+#else
+Void VT640ClearTextLine (line)
+int line;
+#endif
+{
+ /* Erase given line; note that DVItoVDU does not assume anything about the
+ current position at the end of this routine.
+ */
+
+ WriteChar (GS);
+
+ WriteChar (CAN);
+
+ VT100ClearTextLine (line);
+}
+/* VT640ClearTextLine */
+
+/******************************************************************************/
+
+Void VT640ClearScreen (VOID)
+{
+ WriteChar (GS);
+
+ WriteChar (CAN);
+
+ VT100ClearScreen(); /* erase all alphanumerics */
+ TEK4010ClearScreen();
+}
+/* VT640ClearScreen */
+
+/******************************************************************************/
+
+Void VT640ResetVDU (VOID)
+{
+ WriteChar (GS); /* cannot send CAN if VT640 is already in VT100 mode */
+
+ WriteChar (CAN); /* switch to VT100 mode */
+
+}
+/* VT640ResetVDU */
+
+/******************************************************************************/
+
+Void InitVT640 (VOID)
+{
+ /* The dialog region will be the top 4 text lines in VT100 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 24 in VT100 mode.
+ */
+
+ InitTEK4010emu();
+
+ /* The following values assume the VT640 is in VT100 mode. */
+
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+ bottoml = 24; /* also number of text lines on screen */
+
+ textlinewidth = 80; /* text characters per line */
+
+ /* The following values assume it 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).
+ */
+
+ windowv = 130;
+ /* approx. height in TEK4010 pixels of 4 text lines
+ i.e. 4 * 780/24 */
+ windowh = 0;
+ windowht = 780 - windowv;
+ windowwd = 1024;
+
+ MoveToTextLine = VT640MoveToTextLine;
+ ClearTextLine = VT640ClearTextLine;
+ ClearScreen = VT640ClearScreen;
+ StartText = TEK4010StartText;
+ StartGraphics = TEK4010StartGraphics;
+ LoadFont = TEK4010LoadFont;
+ ShowChar = TEK4010ShowChar;
+ ShowRectangle = TEK4010ShowRectangle;
+ ResetVDU = VT640ResetVDU;
+}
+/*InitVT640 */
+
+/******************************************************************************/
+
+/* end vt640vdu.c */