diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvgt |
Initial commit
Diffstat (limited to 'dviware/dvgt')
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 */ |