summaryrefslogtreecommitdiff
path: root/systems/msdos/dviware
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/msdos/dviware
Initial commit
Diffstat (limited to 'systems/msdos/dviware')
-rw-r--r--systems/msdos/dviware/dvilj4/commands.h65
-rw-r--r--systems/msdos/dviware/dvilj4/config.h131
-rw-r--r--systems/msdos/dviware/dvilj4/dvi2xx.c4427
-rw-r--r--systems/msdos/dviware/dvilj4/emu387bin0 -> 42766 bytes
-rw-r--r--systems/msdos/dviware/dvilj4/findfile.c121
-rw-r--r--systems/msdos/dviware/dvilj4/lj4.bat15
-rw-r--r--systems/msdos/dviware/dvilj4/makefile73
-rw-r--r--systems/msdos/dviware/dvips/maketexp.bat52
-rw-r--r--systems/msdos/dviware/dvips/readme.pc113
l---------systems/msdos/dviware/dviwin1
-rw-r--r--systems/msdos/dviware/pccrude.zoobin0 -> 91057 bytes
-rw-r--r--systems/msdos/dviware/xdvi-dos/copying249
-rw-r--r--systems/msdos/dviware/xdvi-dos/copying.dj63
-rw-r--r--systems/msdos/dviware/xdvi-dos/read_dvx.tex79
-rw-r--r--systems/msdos/dviware/xdvi-dos/read_dvx.txt76
-rw-r--r--systems/msdos/dviware/xdvi-dos/readme268
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi.h62
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi_draw.c1049
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi_init.c639
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/font_ope.c887
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/fontfmts.c21
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/fontsub.c62
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/gf.c294
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/makefile36
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/makefile.bak36
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/maketexp141
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/patchlev.h1
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/pk.c324
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/pxl.c166
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/tpic.c434
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/util.c216
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/vf.c123
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.c3175
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.h509
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.ico27
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h9
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h7
-rw-r--r--systems/msdos/dviware/xdvi-dos/texfonts.sub74
-rw-r--r--systems/msdos/dviware/xdvi-dos/xdvi.man396
39 files changed, 14421 insertions, 0 deletions
diff --git a/systems/msdos/dviware/dvilj4/commands.h b/systems/msdos/dviware/dvilj4/commands.h
new file mode 100644
index 0000000000..e926de318d
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/commands.h
@@ -0,0 +1,65 @@
+/* DVI COMMANDS */
+#define SETC_000 0 /* typeset character 0 and move right */
+#define SETC_127 127 /* typeset character 127 and move right */
+#define SET1 128 /* typeset a character and move right */
+#define SET2 129 /* ??? */
+#define SET3 130 /* ??? */
+#define SET4 131 /* ??? */
+#define SET_RULE 132 /* typeset a rule and move right */
+#define PUT1 133 /* typeset a character */
+#define PUT2 134 /* ??? */
+#define PUT3 135 /* ??? */
+#define PUT4 136 /* ??? */
+#define PUT_RULE 137 /* typeset a rule */
+#define NOP 138 /* no operation */
+#define BOP 139 /* beginning of page */
+#define EOP 140 /* ending of page */
+#define PUSH 141 /* save the current positions */
+#define POP 142 /* restore previous positions */
+#define RIGHT1 143 /* move right */
+#define RIGHT2 144 /* ??? */
+#define RIGHT3 145 /* ??? */
+#define RIGHT4 146 /* ??? */
+#define W0 147 /* move right by |w| */
+#define W1 148 /* move right and set |w| */
+#define W2 149 /* ??? */
+#define W3 150 /* ??? */
+#define W4 151 /* ??? */
+#define X0 152 /* move right by |x| */
+#define X1 153 /* move right and set |x| */
+#define X2 154 /* ??? */
+#define X3 155 /* ??? */
+#define X4 156 /* ??? */
+#define DOWN1 157 /* move down */
+#define DOWN2 158 /* ??? */
+#define DOWN3 159 /* ??? */
+#define DOWN4 160 /* ??? */
+#define Y0 161 /* move down by |y| */
+#define Y1 162 /* move down and set |y| */
+#define Y2 163 /* ??? */
+#define Y3 164 /* ??? */
+#define Y4 165 /* ??? */
+#define Z0 166 /* move down by |z| */
+#define Z1 167 /* move down and set |z| */
+#define Z2 168 /* ??? */
+#define Z3 169 /* ??? */
+#define Z4 170 /* ??? */
+#define FONT_00 171 /* set current font to 0 */
+#define FONT_63 234 /* set current font to 0 */
+#define FNT1 235 /* set current font */
+#define FNT2 236 /* Same as FNT1, except that arg is 2 bytes */
+#define FNT3 237 /* Same as FNT1, except that arg is 3 bytes */
+#define FNT4 238 /* Same as FNT1, except that arg is 4 bytes */
+#define XXX1 239 /* extension to \.DVI primitives */
+#define XXX2 240 /* Like XXX1, but 0<=k<65536 */
+#define XXX3 241 /* Like XXX1, but 0<=k<@t$2^{24}$@> */
+#define XXX4 242 /* potentially long extension to \.DVI
+ primitives */
+#define FNT_DEF1 243 /* define the meaning of a font number */
+#define FNT_DEF2 244 /* ??? */
+#define FNT_DEF3 245 /* ??? */
+#define FNT_DEF4 246 /* ??? */
+#define PRE 247 /* preamble */
+#define POST 248 /* postamble beginning */
+#define POST_POST 249 /* postamble ending */
+ /* undefined_commands 250,251,252,253,254,255 */
diff --git a/systems/msdos/dviware/dvilj4/config.h b/systems/msdos/dviware/dvilj4/config.h
new file mode 100644
index 0000000000..0a0d8798c3
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/config.h
@@ -0,0 +1,131 @@
+#define USEPXL
+
+/*
+ * default font path
+ * can be overridden by environment variable TEXPXL
+ * or -a option
+ * popular choice:
+ * #define FONTAREA "/usr/TeX/lib/tex/fonts" */
+#ifdef vms
+#define FONTAREA "tex$pkdir:"
+#else
+#define FONTAREA "/tex/fonts/canon"
+#endif
+
+/*
+ * if your LaserJet II P or LaserJet III or LaserJet 2000
+ * complains about not enough memory, you might try to reduce
+ * the value below or uncomment to use the default settings
+ */
+#ifdef LJ2P
+#define MAX_FONTS_PER_PAGE 255 /* maximum number of fonts per page */
+#endif
+
+/* Unix user: remove the following definition if you cannot access the
+ * appropriate C library functions
+ */
+#ifndef u3b2
+#define TIMING
+#endif
+
+#ifdef unix
+/* name of the program which is called to generate pk files which are missing
+ */
+#define MAKETEXPK "MakeTeXPK"
+#endif
+
+/*
+ * assure that LJ2 is defined when LJ2P is defined
+ */
+#ifdef LJ2P
+#ifndef LJ2
+#define LJ2
+#endif
+#endif
+
+/*
+ * assure that LJ is defined when LJ2 is defined
+ */
+#ifdef LJ2
+#ifndef LJ
+#define LJ
+#endif
+#endif
+
+/*
+ * assure that IBM3812 is not defined when LJ is defined
+ */
+#ifdef LJ
+#ifdef IBM3812
+#undef IBM3812
+#endif
+#endif
+
+
+#define TRUE (bool) 1
+#define FALSE (bool) 0
+#define UNKNOWN -1
+
+#define STRSIZE 255 /* stringsize for file specifications */
+
+typedef char bool;
+
+#ifdef hpux
+typedef char signed_char;
+#else
+#ifdef vms
+typedef char signed_char;
+#else
+#ifdef u3b2
+typedef short signed_char;
+#else
+/* this is the default !! */
+typedef signed char signed_char;
+#endif
+#endif
+#endif
+
+
+#ifndef u3b2
+#define ARITHMETIC_RIGHT_SHIFT
+#endif
+
+
+bool findfile();
+
+
+/*
+ * maximal number of characters in font file
+ * #define LASTFNTCHAR 127 7-bit classic version
+ * #define LASTFNTCHAR 255 8-bit fonts
+ */
+
+#ifdef SEVENBIT
+#define LASTFNTCHAR 127
+#else
+#define LASTFNTCHAR 255
+#endif
+
+
+
+/* this information is needed in findfile.c and dvi2xx.c, NO CUSTOMIZATION */
+#ifdef LJ
+#ifdef LJ4
+#define RESOLUTION 600
+#define MODE "hplf" /* mode definition for metafont */
+#else
+#define RESOLUTION 300
+#define MODE "localfont" /* mode definition for metafont */
+#endif
+#endif
+
+#ifdef IBM3812
+#define RESOLUTION 240
+#define MODE "IBMThreeEightOneTwo" /* mode definition for metafont */
+#endif
+
+
+
+
+
+
diff --git a/systems/msdos/dviware/dvilj4/dvi2xx.c b/systems/msdos/dviware/dvilj4/dvi2xx.c
new file mode 100644
index 0000000000..23516fb062
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/dvi2xx.c
@@ -0,0 +1,4427 @@
+#define VERSION "0.51alpha6"
+/**********************************************************************
+ **************************** Intro *********************************
+ **********************************************************************
+ * This program translates TeX's DVI-Code into device dependent
+ * code of either the
+ *
+ * - HP-LASERJET+ and compatibles (PCL), or the
+ * - IBM 3812 pageprinter
+ *
+ * depending on the preprocessor switches specified before compilation.
+ * The program is written to run on a PC XT/AT/PS2 under MS-DOS. It can
+ * be compiled nicely with MSC Rel. 3.0-5.1 with option -AL (large memory
+ * model). Take care that in the CONFIG.SYS file the FILES parameter
+ * is set to 20; otherwise reduce MAXOPEN. 640K are recommended.
+ * I use link option /stack:9000 to increase runtime stack.
+ * It also works without modifications under Unix System V.
+ **********************************************************************
+ * Adapted for the PC: Gustaf Neumann
+ * +1002 stuff University of Economics
+ * +3812 support Augasse 2-6
+ * +Output buffering A-1090 Vienna, AUSTRIA
+ * +lpt binary support Tel. *43-222-340525/533
+ * +pk-89 stuff 773
+ * +pixelpaths
+ * +alternative directory structure
+ * +code compiles also under Unix V (HP/UX)
+ * (thx Michael Haberler)
+ * +huge characters (a character bigger than 32K)
+ * formats PXL1001 and PXL 1002
+ * (use: raster graphics)
+ * +reduction of the produced code
+ * +new options -X -Y -c -g
+ * +changed options -r (LJ now default from first to last)
+ * -x,-y (accept floats)
+ * +new option -z for LJ: print testpage containing
+ * pagecounter after printjob
+ * +try to overcome font limit on LJ (max 16 fonts/page) and
+ * (max 32 fonts/document):
+ * additional fonts are drawn as bitmap-
+ * graphics.
+ * +allows to set character close to the paperedge on LJ
+ * +gf-supprt (by Joe Kelsey joe@Pacer.com)
+ * gf.c and gf.h from mitdevices/dvi2ps
+ * +clipping of rules
+ * +OS/2 defines from Rutger Berns, apprmb@hheouh50.bitnet
+ *
+ * BITNET/EARN: NEUMANN at AWIWUW11
+ **********************************************************************
+ * fixes in LJ-mode: rule-drawing,
+ * characters with 127<=height<=200
+ * reset printer at beginning and end of each job
+ * better positioning of rules
+ * 30.1.89 (0.48) bug fixed for files containing >32 fonts (thanks A. Brosig),
+ * different font assignment heuristic
+ * fixes in 3812-mode: 14.juli 87 positioning of rastered characters
+ * better positioning of rules
+ * general fixes
+ * 1.1.88 page origin set to 1in/1in (hopefully everywhere)
+ * 22.7.88 reset y-position for each page-eject
+ * 15.1.89 fixing bug is space allocation for EmitFileName
+ * (thanks to Bernhard Simon)
+ * 15.3.91 (0.49) landscape support for lj ii p, lj iii and lj 2000
+ * fixing rule drawing problems for IBM3812 in landcape mode,
+ * 256 character clean (lj family and IBM3812)
+ * 5.5.91 (0.50) -DSEVENBIT added for older LJ-emulations
+ * -D1, -D2, -D-, -D1-, -D2- options added due to suggestions
+ * from Tomasz Wolniewicz
+ **********************************************************************
+ * Preprocessor switches:
+ * #define DEBUG for massive printing of trace information
+ * when -d cmdline option specified
+ * #define IBM3812 produce output for the IBM3812 pageprinter
+ * #define LJ produce output for the HP Laserjet+ or LJ II
+ * #define LJ2P produce output for the HP Laserjet LJ IIP, LJ III
+ * or LaserJet 2000
+ * #define LJ_LARGE_FONT_MEMORY large FONT Memory for LJ printer family
+ * #define DRAWGLYPH draws PK-Glyphs on stderr
+ * #define USEPXL use PXL and PK fonts rather than gf fonts
+ */
+/**********************************************************************
+ ************************ Global Definitions ************************
+ **********************************************************************/
+/* #define IBM3812 */
+/* #define LJ */
+/* #define DRAWGLYPH */
+
+#include "config.h"
+
+#ifdef unix
+#define OS "Unix"
+#define READ_BINARY "r"
+#define WRITE_BINARY "w"
+#define labs(x) abs(x)
+#endif
+#ifdef MSDOS
+#define OS "MS-DOS"
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb"
+#define MSC5
+#endif
+#ifdef OS2
+#define OS "OS/2"
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb"
+#define MSC5
+#endif
+#ifdef vms
+#define OS "VMS"
+#include <ssdef.h>
+#include <stsdef.h>
+#define ftell vms_ftell /* use some external routines, because */
+#define fseek vms_fseek /* of some bugs in the VMS run time */
+#define getchar vms_getchar /* library */
+#define getenv vms_getenv
+#define ungetc vms_ungetc
+#define getname vms_getname
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb","rfm=fix","bls=512","mrs=512" /* fixed records */
+#define labs(x) abs(x)
+#endif
+
+#include "commands.h"
+#include <string.h>
+#include <signal.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifdef vms
+#include <file.h>
+#else
+#include <fcntl.h>
+#endif
+#ifdef MSDOS
+#include <dos.h> /* only for binaryopen on device */
+#endif
+#ifdef unix
+#include <limits.h>
+#endif
+
+#define DVIFORMAT 2
+#define UNKNOWN -1
+#define FIRSTFNTCHAR 0
+
+#ifdef MSDOS
+#define OPEN_MAX 30 /* better than 50 */
+#endif
+
+#ifdef OPEN_MAX /* ... in a friendly unix system */
+#ifndef vms
+#define MAXOPEN (OPEN_MAX - 8)
+#else
+#define MAXOPEN 12 /* OPEN_MAX seems to be 8 on VMS systems */
+#endif
+#else
+#define MAXOPEN 24 /* limit on number of open font files */
+#endif
+#define NFNTCHARS LASTFNTCHAR+1
+#define STACK_SIZE 100 /* DVI-stack size */
+#define NONEXISTANT -1 /* offset for PXL files not found */
+#define NO_FILE ((FILE *)-1)
+#define NEW(A) ((A *) malloc(sizeof(A)))
+#define EQ(a,b) (strcmp(a,b)==0)
+#define MM_TO_PXL(x) (int)(((x)*RESOLUTION*10)/254)
+#define PT_TO_PXL(x) (int)((long)((x)*RESOLUTION*100l)/7224)
+#define PT_TO_DVI(x) (long)((x)*65536l)
+#define BOPENCMD fopen
+#define BINOPEN(f) BOPENCMD(f,READ_BINARY)
+/* SMALL_SIZE characters are loaded into font storage of the printer */
+/* LARGE_SIZE characters are rastered */
+/* HUGE_SIZE characters are not loaded into the memory of the host */
+#define SMALL_SIZE (unsigned char) 0
+#define LARGE_SIZE (unsigned char) 1
+#define HUGE_SIZE (unsigned char) 2
+#define HUGE_CHAR_PATTERN 32767l
+#define BYTES_PER_PIXEL_LINE 500 /* max number of bytes per pixel line */
+
+
+#define PK_POST 245
+#define PK_PRE 247
+#define PK_ID 89
+
+/* to speedup the program a little: redefinition of PixRound and PutWord */
+/*#define PIXROUND(x,c) ((((double)x+(double)(c>>1))/(double)c)+0.5)*/
+#define PIXROUND(x,c) (((x)+c)/c)
+#define PUTWORD(w) EMITC((char)(w>>8)&0xff); EMITC((char)w&0xff)
+/*************************************************************************/
+#define EMIT fprintf /* output a formatted string */
+#ifndef vms
+#define EMITB(len,b) fwrite(b,1,len,outfp) /* output binary data of len */
+#else
+ /* VMS doesn't like to use fwrite on a file with fixed record sizes,
+ so use number of putc calls */
+#define EMITB(len,b) for (kk = 0;kk < len; kk++) putc(*(b+kk),outfp);
+#endif
+#define EMITWORD(w) PUTWORD((w)) /* output a 2 byte word of data */
+
+#define MoveOver(b) h += (long) b
+#define MoveDown(a) v += (long) a
+#define qfprintf if (!G_quiet) fprintf
+#define qprintf if (!G_quiet) printf
+#define LARGER(a,b) (((a)>(b)) ? (a) : (b))
+
+#ifdef IBM3812
+#define PRINTER "IBM 3812 pageprinter"
+#define EMITC(c) PMPoutC(c) /* output a single character */
+#define PMPcont(l) PMPout(-1,(long)l) /* next l bytes continuous */
+#define PMPflush PMPout(0l,"") /* flush PMP-buffer */
+#define EMITL(l,d) PMPout((int)l,d) /* EMIT-logical: via PMP-buffer */
+#define hconvRESOLUTION 240
+#define vconvRESOLUTION 240
+#define CHAR_WIDTH_LARGE 100 /* limit for loading into printer font */
+#define CHAR_HEIGTH_LARGE 127 /* limit for loading into printer font */
+#define OUTBUFSIZE 20000 /* size of output buffer for PMP cmds */
+ /* has to be less max(signed int) */
+#define MAXFONTSTORAGE 130000l /* font storage in the 3812 pageprinter */
+#define EMITFILE_EXTENSION ".pmp" /* default extension of emit file */
+#define XDEFAULTOFF RESOLUTION /* y default offset on page 1 inch */
+#define YDEFAULTOFF RESOLUTION /* y default offset on page 1 inch */
+#define CHARSTRINGMAX 80 /* bufferlength for SetString */
+#define MAX_PAGE_WIDTH 2040
+#define MAX_PAGE_HEIGHT 3360
+/**********************************************************************/
+/************** Positioning for the 3812 ****************************/
+/**********************************************************************/
+#define VERT_HALF(n) ((short)((n+1)>>1)-1)
+#define HOR_HALF(n) ((short)(n>>1))
+#define MoveHor(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\342"); EMITWORD((n)); }
+#define MoveVert(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\343"); EMITWORD((n)); }
+#endif
+
+#ifdef LJ
+#ifdef LJ2P
+#define PRINTER "HP LaserJet IIP"
+#else
+#ifdef LJ2
+#define PRINTER "HP LaserJet II"
+#else
+#define PRINTER "HP LaserJet"
+#endif
+#endif
+#ifdef LJ4
+#define RESOLUTION 600
+#define hconvRESOLUTION 600
+#define vconvRESOLUTION 600
+#else
+#define RESOLUTION 300
+#define hconvRESOLUTION 300
+#define vconvRESOLUTION 300
+#endif
+#ifdef LJ2
+/* the printer limit of the LJ2P is actually 16384x16384,
+ * but to exploit it, one would need lots of memory in the printer
+ */
+#define CHAR_WIDTH_LARGE 300 /* limit for loading into printer font */
+#define CHAR_HEIGTH_LARGE 300 /* y_offset reaches the same size! */
+#else /* such as LaserJet+, Laserjet II */
+#define CHAR_WIDTH_LARGE 100 /* limit for loading into printer font */
+#define CHAR_HEIGTH_LARGE 127 /* y_offset reaches the same size! */
+#endif
+#define EMITFILE_EXTENSION ".lj" /* default extension of emit file */
+#ifndef MAX_FONTS_PER_PAGE
+#define MAX_FONTS_PER_PAGE 16 /* maximum number of fonts per page */
+#endif
+#define HANDLE_MAX_FONTS 255 /* max nr of fonts handled (rasterfont) */
+#define FONTS_DOWNLOADABLE 32 /* max nr of fonts that can be downloaded */
+#define MAXFONTSTORAGE (395l*1024l) /* standard user memory */
+#define EMITC(c) putc(c,outfp) /* output a single character */
+#define EMITL(l,d) EMITB(l,d) /* EMIT-logical = EMITB */
+#define XDEFAULTOFF RESOLUTION-54 /*x default offset on page 1 inch (LJ2)*/
+#define YDEFAULTOFF RESOLUTION+9 /* y default offset on page 1 inch */
+#define max(x,y) if ((y)>(x)) x = y
+#ifndef vms
+#define INT_ASCII(b,i) if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%hd",i)
+#else
+#define INT_ASCII(b,i) if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%d",i)
+#endif
+#endif
+
+#ifdef SEVENBIT
+#define VIS 33
+#define VIS2 (VIS+32)
+unsigned char
+VisChar(c)
+unsigned char c;
+{
+ c &= 0xff;
+ if (c < VIS)
+ return ((unsigned char)(160 + c));
+ if (c < 128)
+ return (c);
+ if (c < (255 - VIS2))
+ return ((unsigned char)(VIS2 + c));
+ return (255);
+}
+#else
+#define VisChar(c) (unsigned char)(c)
+#endif
+
+
+/**********************************************************************/
+/*********************** external definitions ***********************/
+/**********************************************************************/
+/*typedef char bool;*/
+
+#ifndef unix
+long access();
+FILE *BOPENCMD();
+void exit();
+int fclose();
+int fprintf();
+int fseek();
+char *index();
+int printf();
+int sscanf();
+int strcmp();
+char *strcpy();
+#ifdef MSC5
+unsigned int strlen();
+#endif
+void free();
+void setbuf();
+#endif
+#ifndef MSDOS
+char *malloc();
+char *getenv();
+#endif
+
+#ifdef MSDOS
+int intdos();
+#endif
+
+#ifndef USEPXL
+/* interface to gf.c */
+extern FILE *gfin;
+extern int checksum;
+extern long tfm_wd[], char_pointer[];
+extern char char_exists[];
+extern int num_cols, num_rows, num_bytes, x_offset, y_offset;
+extern unsigned char bits[];
+extern int gf_font_max_m, gf_font_max_n, gf_font_min_n;
+extern int gettochar();
+extern void readbits();
+extern void readpost();
+extern void seekpost();
+extern int seekchar();
+#endif
+
+
+/**********************************************************************/
+/************************* Global Procedures ************************/
+/**********************************************************************/
+/* Note: Global procedures are declared here in alphabetical order, with
+ those which do not return values typed "void". Their bodies occur in
+ alphabetical order following the main() procedure. The names are
+ kept unique in the first 6 characters for portability. */
+double ActualFactor();
+void AllDone();
+#ifdef MSDOS
+void AssureBinary(); /* DOS and Microsoft C dependent !!! */
+#endif
+void CopyFile();
+void CopyHPFile();
+void DecodeArgs();
+void DoBop();
+long DoConv();
+void DoSpecial();
+void EmitChar();
+void Fatal();
+void FindPostAmblePtr();
+void FormFeed();
+void GetBytes();
+void GetFontDef();
+char *GetKeyStr();
+bool GetKeyVal();
+bool IsSame();
+void lcase();
+void LoadAChar();
+long NoSignExtend();
+/* see cautionary note in code, re arithmetic vs logical shifts */
+void OpenFontFile();
+long PixRound();
+void PkRaster();
+void PutWord();
+void RasterLine();
+void RasterChar();
+void ReadFontDef();
+void ReadPostAmble();
+void SetChar();
+void SetFntNum();
+void SetPosn();
+void SetRule();
+void SetString();
+long SignExtend();
+/* see cautionary note in code, re arithmetic vs logical shifts */
+void SkipFontDef();
+void Warning();
+unsigned char skip_specials() ;
+
+#ifdef IBM3812
+void PMPout();
+void PMPoutC();
+#endif
+
+/**********************************************************************/
+/*********************** Font Data Structures ***********************/
+/**********************************************************************/
+
+struct char_entry { /* character entry */
+#ifdef USEPXL
+ unsigned short width, height; /* width and height in pixels */
+ short xOffset, yOffset, yyOffset; /* x offset and y offset in pixels*/
+#endif
+ struct {
+ bool isloaded;
+ union {
+ long fileOffset;
+ long *pixptr;
+ } address;
+ } where;
+ long tfmw; /* TFM width */
+ long cw; /* character width in pixels */
+ unsigned char flag_byte; /* for PK-files */
+ unsigned char charsize;
+};
+struct font_entry { /* font entry */
+ long k, c, s, d;
+ int a, l;
+ char n[STRSIZE]; /* FNT_DEF command parameters */
+ long font_mag; /* computed from FNT_DEF s and d parameters */
+ /*char psname[STRSIZE];*/ /* PostScript name of the font */
+ char name[STRSIZE]; /* full name of PXL file */
+ FILE * font_file_id; /* file identifier (NO_FILE if none) */
+#ifdef USEPXL
+ long magnification; /* magnification read from PXL file */
+ long designsize; /* design size read from PXL file */
+#endif
+ struct char_entry ch[NFNTCHARS]; /* character information */
+ struct font_entry *next;
+ unsigned short ncdl; /* #of different chars actually downloaded */
+ unsigned short plusid; /* Font id in Printer */
+ bool used_on_this_page;
+ enum PxlId {
+ id1001, id1002, pk89 } id;
+#ifdef LJ
+ unsigned short max_width, max_height, max_yoff;
+#endif
+};
+
+
+struct pixel_list {
+ FILE *pixel_file_id; /* file identifier */
+ int use_count; /* count of "opens" */
+};
+/**********************************************************************/
+/************************* Global Variables *************************/
+/**********************************************************************/
+long FirstPage = -1000000; /* first page to print (uses count0) */
+long LastPage = 1000000; /* last page to print */
+long PrintPages = 1000000; /* nr of pages to print */
+bool FirstPageSpecified = FALSE;
+bool LastPageSpecified = FALSE;
+char G_progname[STRSIZE]; /* program name */
+char filename[STRSIZE]; /* DVI file name */
+char rootname[STRSIZE]; /* DVI filename without extension */
+char *PXLpath = FONTAREA; /* PXL path name for search */
+char *HeaderFileName = ""; /* file name & path of Headerfile */
+char *EmitFileName = ""; /* file name & path for output */
+#ifdef IBM3812
+bool FirstAlternate = FALSE; /* first page from alternate casette ? */
+#endif
+bool Reverse = FALSE; /* process DVI pages in reverse order? */
+bool Landscape = FALSE; /* print document in ladscape mode */
+bool ResetPrinter = TRUE; /* reset printer at the begin of the job*/
+bool DoublePage = FALSE; /* print on both sides of a paper */
+bool PrintSecondPart = TRUE; /* print First Part when DoublePage */
+bool PrintFirstPart = TRUE; /* print Second Part when DoublePage */
+bool PrintEmptyPages = TRUE; /* print Empty pages in DoublePage mode*/
+short PageParity = 1;
+#ifdef LJ
+#ifdef LJ2P
+int DuplexMode = 0;
+#endif
+bool PrintTestPage = FALSE; /* print testpage with pagecounter after job */
+unsigned short pagesize = 0; /* page size value */
+unsigned short pgsiz_dots = 0; /* page size in dots (for rule-clipping)*/
+#endif
+#ifndef vms
+short G_errenc = 0; /* has an error been encountered? */
+#else
+long G_errenc = SS$_NORMAL; /* has an error been encountered? */
+#endif
+bool G_header = FALSE; /* copy header file to output? */
+bool G_quiet = FALSE; /* for quiet operation */
+bool G_noverbatim = TRUE; /* inform user about pxl-files used */
+bool G_nowarn = FALSE; /* don't print out warnings */
+short x_origin = XDEFAULTOFF; /* x-origin in dots */
+short y_origin = YDEFAULTOFF; /* y-origin in dots */
+short x_goffset; /* global x-offset in dots */
+short y_goffset; /* global y-offset in dots */
+unsigned short ncopies = 1; /* number of copies to print */
+long hconv, vconv; /* converts DVI units to pixels */
+long den; /* denominator specified in preamble */
+long num; /* numerator specified in preamble */
+long h; /* current horizontal position */
+long hh = 0; /* current h on device */
+long v; /* current vertical position */
+long vv = 0; /* current v on device */
+long mag; /* magnification specified in preamble */
+long usermag = 0; /* user specified magnification */
+int ndone = 0; /* number of pages converted */
+int nopen = 0; /* number of open PXL files */
+#ifdef vms
+int kk; /* loop variable for EMITB */
+#endif
+FILE *outfp = NULL; /* output file */
+FILE *pxlfp; /* PXL file pointer */
+FILE *dvifp = NULL; /* DVI file pointer */
+struct font_entry *prevfont = NULL; /* font_entry pointer previous font*/
+struct font_entry *fontptr; /* font_entry pointer */
+struct font_entry *hfontptr = NULL; /* font_entry pointer */
+struct font_entry *pfontptr = NULL; /* previous font_entry pointer */
+struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL files */
+long postambleptr; /* Pointer to the postamble */
+long ppagep; /* previous page pointer */
+static int last_ry = UNKNOWN; /* last y-position on page */
+static int last_rx = UNKNOWN; /* last x-position on page */
+long StartPrintPages; /* notpad for double paged output */
+int WouldPrint = 0;
+bool ZeroPage = FALSE; /* Document starts with a Zero Page */
+bool EvenPage = FALSE; /* Document starts with an even Page */
+long LastPtobePrinted = 0;
+int G_ncdl = 0;
+
+long allocated_storage = 0; /* size of mallocated storage (statistics) */
+long power[32] ;
+long gpower[33] ;
+
+
+#ifdef DEBUG
+bool Debug = FALSE;
+#endif
+
+#ifdef LJ
+int fonts_used_on_this_page = MAX_FONTS_PER_PAGE+1;
+char rasterfont[HANDLE_MAX_FONTS];
+ /* raster if fonts/page>MAX_FONTS_PER_PAGE*/
+#endif
+
+long used_fontstorage = 0;
+
+#ifdef IBM3812
+char PMPformat[20];
+char CharString[CHARSTRINGMAX];
+unsigned int CharStringPos = 0;
+#define CharStringOut \
+ if (CharStringPos>0) { \
+ PMPcont(CharStringPos+1);\
+ PMPoutC((unsigned char)CharStringPos);\
+ PMPout(CharStringPos, CharString); \
+ CharStringPos=0; }
+#endif
+
+#ifdef TIMING
+/************************timing stuff*********************/
+#ifndef vms
+#include <sys/timeb.h>
+#else
+#include <timeb.h>
+#endif
+struct timeb timebuffer;
+double start_time;
+#endif
+
+
+
+
+/**********************************************************************/
+/******************************* main *******************************/
+/**********************************************************************/
+void
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ struct stack_entry { /* stack entry */
+ long h, v, w, x, y, z; /* what's on stack */
+ };
+ short command; /* current command */
+ long count[10]; /* the 10 counters at begining of each page*/
+ long cpagep; /* current page pointer */
+ bool Emitting = FALSE; /* outputting typsetting instructions? */
+ int i; /* command parameter; loop index */
+ int k; /* temporary parameter */
+ char n[STRSIZE]; /* command parameter */
+ int PassNo = 0; /* which pass over the DVI page are we on? */
+ bool SkipMode = FALSE; /* in skip mode flag */
+ int sp; /* stack pointer */
+ struct stack_entry stack[STACK_SIZE]; /* stack */
+ char SpecialStr[STRSIZE]; /* "\special" strings */
+ long val, val2; /* temporarys to hold command information */
+ long w; /* current horizontal spacing */
+ long x; /* current horizontal spacing */
+ long y; /* current vertical spacing */
+ long z; /* current vertical spacing */
+
+
+#ifdef vms
+ extern noshare int errno;
+ extern noshare char *sys_errlist[];
+#else
+ extern char *sys_errlist[];
+ extern int errno;
+#endif
+
+ setbuf(stderr, NULL);
+ (void) strcpy(G_progname, argv[0]);
+ DecodeArgs( argc, argv );
+
+ power [ 0 ] = 1 ;
+ for ( i = 1 ; i <= 31 ; i ++)
+ power [ i ] = power [ i - 1 ] << 1 ;
+ gpower[0] = 0l ;
+ for ( i = 1 ; i <= 32 ; i ++)
+ gpower[i] = gpower[i - 1] + power[i - 1] ;
+
+ if ((i = (int) NoSignExtend(dvifp, 1)) != PRE) {
+ Fatal(
+ "%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n",
+ G_progname);
+ }
+ i = (int) SignExtend(dvifp, 1);
+ if (i != DVIFORMAT) {
+ Fatal( "%s: DVI format = %d, can only process DVI format %d files\n\n",
+ G_progname, i, DVIFORMAT);
+ }
+
+ if (*EmitFileName == '-')
+ outfp = stdout;
+ else
+ if ((outfp = fopen(EmitFileName, WRITE_BINARY)) == NULL)
+ Fatal("opening output file: fopen(%s) : %s",
+ EmitFileName,sys_errlist[errno]);
+
+#ifdef MSDOS
+ AssureBinary(outfp);
+#endif
+
+#ifdef TIMING
+ ftime(&timebuffer);
+ start_time = (timebuffer.time) + (float)(timebuffer.millitm) / 1000.0;
+#endif
+
+ /* it is important that these be the very first things output !!! */
+ if ( G_header )
+ CopyFile( HeaderFileName );
+
+ /*****************************/
+ /*for( i0=0; i0<nif; i0++ ) */ /* copy all included files */
+ /* CopyFile( Ifile[i0] ); */
+ /*****************************/
+
+#ifdef IBM3812
+ PMPout(3, "\307\310\366"); /* unload all fonts and macros */
+ EMITWORD(MAX_PAGE_WIDTH);
+ EMITWORD(MAX_PAGE_HEIGHT);
+ if (Landscape)
+ PMPout(2, "\322\1");
+#endif
+#ifdef LJ
+ if (ResetPrinter)
+ EMIT(outfp, "\033E");
+#ifdef LJ4
+ EMIT(outfp, "\033%%-12345X@PJL SET RESOLUTION=600\012");
+ EMIT(outfp, "@PJL SET PAGEPROTECT=OFF\012");
+ EMIT(outfp, "@PJL SET ENTER LANGUAGE=PCL\012");
+ EMIT(outfp, "\033&u600D\033*t600R");
+#endif
+#ifdef LJ2P
+ if (DuplexMode)
+ EMIT(outfp, "\033&l%dH",DuplexMode);
+#endif
+ if (Landscape)
+ EMIT(outfp, "\033&l1O\033*rF");
+ if (pagesize>0)
+#ifndef vms
+ EMIT(outfp, "\033&l%hdaE\033&aL",pagesize);
+#else
+ EMIT(outfp, "\033&l%daE\033&aL",pagesize);
+#endif
+ else
+ EMIT(outfp, "\033&lE\033&aL");
+
+ if (ncopies>1)
+#ifndef vms
+ EMIT(outfp, "\033&l%hdX",ncopies);
+#else
+ EMIT(outfp, "\033&l%dX",ncopies);
+#endif
+#endif
+ if (DoublePage) {
+ StartPrintPages = PrintPages;
+#ifdef IBM3812
+ Reverse = (bool)!Reverse; /* perverse and strange */
+#endif
+
+ }
+ if (Reverse) {
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr, "reverse\n");
+#endif
+ ReadPostAmble(TRUE);
+ fseek(dvifp, ppagep, 0);
+ } else {
+ ReadPostAmble(TRUE);
+ fseek(dvifp, 14l, 0);
+ k = (int) NoSignExtend(dvifp, 1);
+ GetBytes(dvifp, n, k);
+ }
+ PassNo = 0;
+
+ while (TRUE) {
+ command = (short) NoSignExtend(dvifp, 1) ;
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"CMD:\t%d\n", command);
+#endif
+ switch (command) {
+ case SET1:
+ case SET2:
+ case SET3:
+ case SET4:
+ val = NoSignExtend(dvifp, (int) command - SET1 + 1);
+ if (!SkipMode)
+ SetChar(val, command, PassNo, TRUE,FALSE);
+ break;
+ case SET_RULE:
+ val = NoSignExtend(dvifp, 4);
+ val2 = NoSignExtend(dvifp, 4);
+ if (Emitting)
+ SetRule(val, val2, 1);
+ break;
+ case PUT1:
+ case PUT2:
+ case PUT3:
+ case PUT4:
+ val = NoSignExtend(dvifp, (int) command - PUT1 + 1);
+ if (!SkipMode)
+ SetChar(val, command, PassNo, TRUE,FALSE);
+ break;
+ case PUT_RULE:
+ val = NoSignExtend(dvifp, 4);
+ val2 = NoSignExtend(dvifp, 4);
+ if (Emitting)
+ SetRule(val, val2, 0);
+ break;
+ case NOP:
+ break;
+ case BOP:
+ cpagep = ftell(dvifp) - 1;
+ for (i = 0; i <= 9; i++)
+ count[i] = NoSignExtend(dvifp, 4);
+ ppagep = NoSignExtend(dvifp, 4);
+ h = v = w = x = y = z = 0;
+ hh = vv = 0;
+ sp = 0;
+ fontptr = NULL;
+ prevfont = NULL;
+ DoBop();
+/*
+fprintf(stderr,"skimode %d, count %d, F %d, L %d\n",
+ (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
+*/
+ SkipMode = (bool) ((FirstPageSpecified && count[0] < FirstPage) ||
+ (LastPageSpecified && count[0] > LastPage ));
+/*
+fprintf(stderr,"skimode %d, count %d, F %d, L %d\n",
+ (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
+*/
+
+ if (DoublePage && !SkipMode) {
+ if (PassNo == 0) {
+ LastPtobePrinted=count[0];
+ if (!Reverse && (WouldPrint == 0)) {
+ if (count[0] == 0l) {
+ ZeroPage = TRUE;
+ EvenPage = FALSE;
+ }
+ else {
+ EvenPage = (bool) ( (count[0]<0? labs(count[0])+1: count[0]) %2 == 0);
+
+ if (PrintEmptyPages && EvenPage && PageParity==1) {
+ WouldPrint ++;
+ if (PrintFirstPart) {
+ qfprintf(stderr,"[EvenPage] ");
+ FormFeed();
+ }
+ }
+ }
+ }
+ WouldPrint ++;
+/*
+ printf("doublepage %d, page parity = %d, 1=%d 2=%d, Reverse %d, WouldPrint %d, fpZ %d\n",
+ (int)DoublePage, (int)PageParity,(int)PrintFirstPart,(int)PrintSecondPart,
+ (int)Reverse, (int)WouldPrint, (int)ZeroPage);
+*/
+ }
+ if (!PrintFirstPart && PageParity==1) {
+ if (count[0]==0l) {
+ ZeroPage = TRUE;
+ EvenPage = FALSE;
+ }
+ SkipMode = TRUE;
+ }
+ else {
+/*
+fprintf(stderr,"FirstPart\n count %d, mod %d, pp %d\n",(int)count[0],(int)count[0]%2,PageParity);
+*/
+ SkipMode = (bool)(PageParity != (short)(
+ (count[0]<0? labs(count[0])+1: count[0])%2));
+ if (count[0]==0l) SkipMode=(bool)!SkipMode;
+ }
+
+ }
+ Emitting = (bool)((PassNo != 0) && !SkipMode);
+/*
+fprintf(stderr,"Emitting= %d, PassNo=%d, SkipMode = %d\n",(int)Emitting,(int)PassNo,(int)SkipMode);
+*/
+ if ( !SkipMode ) {
+ if ( PassNo == 0)
+ qfprintf(stderr, "[%ld", count[0]);
+ }
+ break;
+ case EOP:
+ if ( !SkipMode ) {
+ if ( PassNo == 0 ) {
+ /* start second pass on current page */
+ fseek(dvifp, cpagep, 0);
+ PassNo = 1;
+ } else {
+ /* end of second pass, and of page processing */
+
+ last_ry = UNKNOWN;
+ FormFeed();
+ ++ndone;
+
+ qfprintf(stderr, "] ");
+ if ( (ndone % 10) == 0 )
+ qfprintf(stderr, "\n");
+
+ if (DoublePage) --PrintPages;
+ if (--PrintPages < 1) AllDone(TRUE);
+ PassNo = 0;
+ }
+ } else
+ PassNo = 0;
+
+ if ( PassNo == 0 && Reverse ) {
+ if ( ppagep > 0 )
+ fseek(dvifp, ppagep, 0);
+ else {
+ if (DoublePage && !SkipMode)
+ ZeroPage = (bool)(count[0]==0l);
+
+ if (ZeroPage)
+ EvenPage = FALSE;
+ else
+ EvenPage = (bool) ((int)LastPtobePrinted%2 == 0);
+
+ AllDone(FALSE);
+ }
+ }
+ break;
+ case PUSH:
+ if (sp >= STACK_SIZE)
+ Fatal("stack overflow");
+ stack[sp].h = h;
+ stack[sp].v = v;
+ stack[sp].w = w;
+ stack[sp].x = x;
+ stack[sp].y = y;
+ stack[sp].z = z;
+ sp++;
+ break;
+ case POP:
+ --sp;
+ if (sp < 0)
+ Fatal("stack underflow");
+ h = stack[sp].h;
+ v = stack[sp].v;
+ w = stack[sp].w;
+ x = stack[sp].x;
+ y = stack[sp].y;
+ z = stack[sp].z;
+ break;
+ case RIGHT1:
+ case RIGHT2:
+ case RIGHT3:
+ case RIGHT4:
+ val = SignExtend(dvifp, (int) command - RIGHT1 + 1);
+ if (Emitting)
+ MoveOver(val);
+ break;
+ case W0:
+ if (Emitting)
+ MoveOver(w);
+ break;
+ case W1:
+ case W2:
+ case W3:
+ case W4:
+ w = SignExtend(dvifp, (int)command - W1 + 1);
+ if (Emitting)
+ MoveOver(w);
+ break;
+ case X0:
+ if (Emitting)
+ MoveOver(x);
+ break;
+ case X1:
+ case X2:
+ case X3:
+ case X4:
+ x = SignExtend(dvifp, (int)command - X1 + 1);
+ if (Emitting)
+ MoveOver(x);
+ break;
+ case DOWN1:
+ case DOWN2:
+ case DOWN3:
+ case DOWN4:
+ val = SignExtend(dvifp, (int)command - DOWN1 + 1);
+ if (Emitting)
+ MoveDown(val);
+ break;
+ case Y0:
+ if (Emitting)
+ MoveDown(y);
+ break;
+ case Y1:
+ case Y2:
+ case Y3:
+ case Y4:
+ y = SignExtend(dvifp, (int)command - Y1 + 1);
+ if (Emitting)
+ MoveDown(y);
+ break;
+ case Z0:
+ if (Emitting)
+ MoveDown(z);
+ break;
+ case Z1:
+ case Z2:
+ case Z3:
+ case Z4:
+ z = SignExtend(dvifp, (int)command - Z1 + 1);
+ if (Emitting)
+ MoveDown(z);
+ break;
+ case FNT1:
+ case FNT2:
+ case FNT3:
+ case FNT4:
+ if (!SkipMode) {
+ SetFntNum(NoSignExtend(dvifp, (int)command -FNT1 +1),Emitting);
+ }
+ break;
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ k = (int) NoSignExtend(dvifp, (int)command - XXX1 + 1);
+ GetBytes(dvifp, SpecialStr, k);
+ if (Emitting)
+ DoSpecial(SpecialStr, k);
+ break;
+ case FNT_DEF1:
+ case FNT_DEF2:
+ case FNT_DEF3:
+ case FNT_DEF4:
+ k = (int) NoSignExtend(dvifp, (int)command - FNT_DEF1 + 1);
+ SkipFontDef(); /* SkipFontDef(k); */
+ break;
+ case PRE:
+ Fatal("PRE occurs within file");
+ break;
+ case POST:
+ AllDone(FALSE);
+ PassNo = 0;
+ break;
+ case POST_POST:
+ Fatal("POST_POST with no preceding POST");
+ break;
+ default:
+ if (command >= FONT_00 && command <= FONT_63) {
+ if (!SkipMode)
+ SetFntNum((long) command - FONT_00, Emitting);
+ } else if (command >= SETC_000 && command <= SETC_127) {
+ if (!SkipMode) {
+ SetString(command, PassNo);
+ }
+ } else
+ Fatal("%d is an undefined command", command);
+ break;
+ }
+ } /* while TRUE */
+}
+
+
+/*-->ActualFactor*/
+/**********************************************************************/
+/************************** ActualFactor ****************************/
+/**********************************************************************/
+double /* compute the actual size factor given the approximation */
+ActualFactor(unmodsize)
+long unmodsize; /* actually factor * 1000 */
+{
+ double realsize; /* the actual magnification factor */
+ realsize = (double)unmodsize / 1000.0;
+ if (abs((int)(unmodsize - 1095l))<2)
+ realsize = 1.095445115; /*stephalf*/
+ else if (abs((int)(unmodsize - 1315l))<2)
+ realsize = 1.31453414; /*stepihalf*/
+ else if (abs((int)(unmodsize - 1577l))<2)
+ realsize = 1.57744097; /*stepiihalf*/
+ else if (abs((int)(unmodsize - 1893l))<2)
+ realsize = 1.89292916; /*stepiiihalf*/
+ else if (abs((int)(unmodsize - 2074l))<2)
+ realsize = 2.0736; /*stepiv*/
+ else if (abs((int)(unmodsize - 2488l))<2)
+ realsize = 2.48832; /*stepv*/
+ else if (abs((int)(unmodsize - 2986l))<2)
+ realsize = 2.985984; /*stepvi*/
+ /* the remaining magnification steps are represented with sufficient
+ accuracy already */
+ return(realsize);
+}
+
+
+/*-->AllDone*/
+/**********************************************************************/
+/****************************** AllDone ******************************/
+/**********************************************************************/
+void
+AllDone(PFlag)
+bool PFlag;
+{
+ double time;
+
+ if (DoublePage && (PageParity==1)) { /* Shall we go around again?*/
+ int k,rc;
+ char n[STRSIZE];
+
+ if (PrintEmptyPages && EvenPage && Reverse && PrintFirstPart) {
+ WouldPrint ++;
+ qfprintf(stderr,"[EvenPage] ");
+ FormFeed();
+ }
+#ifdef LJ
+ Reverse = (bool)!Reverse;
+#endif
+ if (Reverse) {
+ if (!PFlag) {
+ fseek (dvifp, postambleptr, 0);
+ (void) NoSignExtend(dvifp, 1);
+ ppagep = NoSignExtend(dvifp, 4);
+ }
+ fseek(dvifp, ppagep, 0);
+ } else {
+ fseek(dvifp, 14l, 0);
+ k = (int) NoSignExtend(dvifp, 1);
+ GetBytes(dvifp, n, k);
+ }
+
+ if (PrintSecondPart) {
+ if (PrintFirstPart) {
+ qfprintf(stderr,"\n----------------------starting second pass\n");
+#ifdef LJ
+ EMIT(outfp, "\033&l2H"); /* Manual Feed */
+#endif
+#ifdef IBM3812
+ PMPout(6,"\326\001\305\300\326\252");
+ /* set display; ring bell; stop; clear display */
+ PMPflush;
+#endif
+ }
+
+ if (PrintEmptyPages && Reverse) {
+ if (ZeroPage) WouldPrint++;
+ if ((WouldPrint%2) == 1) {
+ qfprintf(stderr,"[Padding] ");
+ FormFeed();
+ }
+ }
+ WouldPrint = 0;
+ if (PrintEmptyPages && !Reverse && ZeroPage) {
+ WouldPrint++;
+ qfprintf(stderr,"[ZeroPage] ");
+ FormFeed();
+ }
+ PageParity = 0;
+ PrintPages = StartPrintPages;
+ return;
+ }
+ }
+
+ if (EvenPage && DoublePage && !Reverse) WouldPrint++;
+
+ if (PrintEmptyPages && DoublePage && PrintSecondPart) {
+ if (Reverse) {
+ if (ZeroPage) {
+ WouldPrint ++;
+ qfprintf(stderr,"[ZeroPage] ");
+ FormFeed();
+ }
+ }
+ else if ((WouldPrint%2) != 0) {
+ qfprintf(stderr,"[Padding] ");
+ FormFeed();
+ }
+ }
+
+#ifdef IBM3812
+ PMPout(10, "\373\010PMP.init"); /* re-init printer */
+ PMPflush;
+
+ if (used_fontstorage > MAXFONTSTORAGE) {
+ Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7",
+ PRINTER, used_fontstorage, MAXFONTSTORAGE);
+ Warning("Try to format file in separate runs!");
+ } else
+ qfprintf(stderr,
+ "\nAll done, used font_storage of %s: %ld Bytes (of %ld)",
+ PRINTER, used_fontstorage, MAXFONTSTORAGE);
+#endif
+#ifdef LJ
+ qfprintf(stderr, "\nAll done, used font_storage of %s: %ld Bytes",
+ PRINTER, used_fontstorage);
+ EMIT(outfp, "\033E");
+ EMIT(outfp, "\033%%-12345X");
+ if (PrintTestPage) EMIT(outfp, "\033z");
+#ifdef vms
+ /* last record is not flushed to file, unless it is completely filled */
+ for (kk = (int)((*outfp)->_cnt); kk > 0; --kk) putc('\0',outfp);
+ fflush(outfp);
+#endif
+#endif
+
+ if (!G_quiet) {
+ fprintf(stderr,"\nDynamically allocated storage: %ld Bytes \n",
+ allocated_storage);
+ fprintf(stderr,"%d characters downloaded as soft fonts\n", G_ncdl);
+
+#ifdef TIMING
+ ftime(&timebuffer);
+ time = ((timebuffer.time) + (float)(timebuffer.millitm) / 1000.0) -start_time;
+
+ if (ndone > 0) {
+ fprintf(stderr,
+ "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page",
+ time, ndone, time / ndone);
+ fprintf(stderr," (%.2f ppm)\n",(ndone * 60) / time);
+ }
+ fprintf(stderr,"\n");
+#endif
+ }
+
+ exit(G_errenc);
+}
+
+
+/*-->CopyFile*/ /* copy a file straight through to output */
+/*********************************************************************/
+/***************************** CopyFile ******************************/
+/*********************************************************************/
+void
+CopyFile( str )
+char *str;
+{
+ FILE * spfp;
+ char t;
+ if ( (spfp = BINOPEN(str)) == NULL ) {
+ Warning("Unable to open file %s", str );
+ return;
+ }
+ qfprintf(stderr," [%s", str);
+ for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
+ putc(t, outfp);
+ fclose(spfp);
+ qfprintf(stderr,"]");
+}
+
+
+/*-->CopyHPFile*/ /* copy a HP file to output removing unwanted control codes*/
+/*********************************************************************/
+/***************************** CopyHPFile ******************************/
+/*********************************************************************/
+void
+CopyHPFile( str )
+char *str;
+{
+ FILE * spfp;
+ char t,numstr[20];
+ int count,rx,ry,miny,minx,num;
+
+ if ( (spfp = BINOPEN(str)) == NULL ) {
+ Warning("Unable to open file %s", str );
+ return;
+ }
+ minx=32767; /* Set to a high value initially */
+ miny=32767;
+
+/* Pass through the input PCL file twice. The first time find the smallest */
+/* x- and y-offsets so that they can be subtracted out when sending */
+/* positioning commands later. The second pass strips the unwanted commands */
+/* from the input file and outputs the rest */
+
+ qfprintf(stderr," [%s", str);
+ for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
+ {
+ if (t==0x1B) /* Find the escape character */
+ {
+ t=(char) getc(spfp);
+ if (t==0x2A) /* This indiactes the start of a graphics command */
+ {
+
+ t=(char) getc(spfp);
+ switch(t)
+ {
+ case(0x70):
+ /* These are the graphics positioning commands */
+ /* Find the smallest x and y offsets */
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ num= atoi (numstr);
+
+ /* Take into account the possible different ordering */
+ /* of the commands (x first, y first) */
+
+ if ((t==0x59)||(t==0x79))
+ {
+ if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
+ if (num<miny) miny=num;
+ if (t==0x79)
+ {
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ num=atoi (numstr);
+ if(numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
+ if (num<minx) minx=num;
+ }
+ }
+ if ((t==0x58)||(t==0x78))
+ {
+ if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
+ if (num<minx) minx=num;
+ if (t==0x78)
+ {
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ num= atoi (numstr);
+ if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
+ if (num<miny) miny=num;
+ }
+ }
+ break;
+ /* Ignore all other commands for the moment - just read them */
+ case(0x74):
+ for (t=(char) getc(spfp);t != 0x52; t=(char) getc(spfp));
+ break;
+
+ case(0x72):
+ for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp));
+ break;
+
+ case(0x62):
+ num=0;
+ count=0;
+ /* Read in the correct number of bytes of raster graphics */
+ /* so that we don't get commands and raster graphics confused */
+
+ for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ if (t==0x4D)
+ for(t=numstr[count=0];t!=0;t=numstr[++count]);
+ if (t==0x57)
+ {
+ for(t=numstr[count=0];t!=0;t=numstr[++count]);
+ for(count= atoi(numstr);count>0;count--)
+ t=(char) getc(spfp);
+ }
+ break;
+
+ case(0x63):
+ for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp));
+ break;
+
+ default:
+ break;
+
+
+ }
+ }
+ }
+ }
+ fclose(spfp);
+ qfprintf(stderr,"]");
+
+ if ( (spfp = BINOPEN(str)) == NULL ) {
+ Warning("Unable to open file %s", str );
+ return;
+ }
+ qfprintf(stderr," [%s", str);
+
+/* Pass through the input file again but this time output the */
+/* retained PCL commands */
+
+ for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
+ {
+ if (t==0x1B)
+ {
+ t=(char) getc(spfp);
+ if (t==0x2A)
+ {
+ t=(char) getc(spfp);
+ switch(t)
+ {
+ case(0x70):
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ num= atoi (numstr);
+ if ((t==0x59)||(t==0x79))
+ {
+ if (numstr[0]!='+'&&numstr[0]!='-')
+ {
+ /* Subtract the minimum offset found in first pass */
+ /* and add in the current vertical offset */
+ ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;
+ /* Output the new positioning command */
+ EMIT(outfp,"\033*p%dY",ry);
+ }
+
+ else if (num>=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num);
+ else EMIT(outfp,"\033*p%dY",num);
+
+ if (t==0x79)
+ {
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t; /* reconstructed code */
+ numstr[count]=0;
+ num=atoi (numstr);
+ if(numstr[0]!='+'&&numstr[0]!='-')
+ {
+ /*Add in correct horizontal offset */
+ rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
+ EMIT(outfp,"\033*p%dX",rx);
+ }
+ else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num);
+ else EMIT(outfp,"\033*p%dX",num);
+ }
+ }
+
+ if ((t==0x58)||(t==0x78))
+ {
+ if(numstr[0]!='+'&&numstr[0]!='-')
+ {
+ /*Add in the correct horizontal offset*/
+ rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
+ EMIT(outfp,"\033*p%dX",rx);
+ }
+ else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num);
+ else EMIT(outfp,"\033*p%dX",num);
+
+ if (t==0x78)
+ {
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ num= atoi (numstr);
+ if(numstr[0]!='+'&&numstr[0]!='-')
+ {
+ /*Add in correct vertical offset*/
+ ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;
+ EMIT(outfp,"\033*p%dY",ry);
+ }
+ else if (num >=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num);
+ else EMIT(outfp,"\033*p%dY",num);
+ }
+ }
+ break;
+
+ case(0x74):
+ /* Set the Raster resolution */
+ EMIT(outfp,"\033*t");
+ for (t=(char) getc(spfp);t != 0x52; t=(char) getc(spfp))
+ putc(t,outfp);
+ putc(t,outfp);
+ break;
+
+ case(0x72):
+ /* Raster Graphics commands such as start */
+ EMIT(outfp,"\033*r");
+ for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp))
+ putc(t,outfp);
+ putc(t,outfp);
+ break;
+
+ case(0x62):
+ /* Transfer the correct number of bytes of raster graphics */
+ EMIT(outfp,"\033*b");
+ num=0;
+ count=0;
+ for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp))
+ numstr[count++]=t;
+ numstr[count]=0;
+ if (t==0x4D)
+ {
+ for(t=numstr[count=0];t!=0;t=numstr[++count])
+ putc(t,outfp);
+ EMIT(outfp,"M");
+ }
+ if (t==0x57)
+ {
+ for(t=numstr[count=0];t!=0;t=numstr[++count])
+ putc(t,outfp);
+ EMIT(outfp,"W");
+ for(count= atoi(numstr);count>0;count--)
+ {
+ t=(char) getc(spfp);
+ putc(t,outfp);
+ }
+ }
+ break;
+
+ case(0x63):
+ /* Rectangular draw commands */
+ EMIT(outfp,"\033*c");
+ for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp))
+ putc(t,outfp);
+ putc(t,outfp);
+ break;
+
+ default:
+ break;
+
+
+ }
+ }
+ }
+ }
+ fclose(spfp);
+ qfprintf(stderr,"]");
+}
+
+
+
+/*-->DecodeArgs*/
+/*********************************************************************/
+/***************************** DecodeArgs ****************************/
+/*********************************************************************/
+void
+DecodeArgs( argc, argv )
+int argc;
+char *argv[];
+{
+ int argind; /* argument index for flags */
+ char curarea[STRSIZE]; /* current file area */
+ char curname[STRSIZE]; /* current file name */
+ char *tcp, *tcp1; /* temporary character pointers */
+ char *this_arg;
+ double x_offset=0.0, y_offset=0.0;
+
+ if ((tcp = getenv("TEXPXL")) != NULL) PXLpath = tcp;
+
+ argind = 1;
+ while (argind < argc) {
+ tcp = argv[argind];
+ if (*tcp == '-') {
+ ++tcp;
+ switch (*tcp) {
+ case 'a': /* a se default: J
+ PXLpath = ++tcp;
+ break;
+#ifdef IBM3812
+ case 'b': /* first page from alternate casette */
+ FirstAlternate = TRUE;
+ break;
+#endif
+ case 'c': /* number of copies to print */
+ if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 )
+ Fatal("Argument of -c is not a valid integer\n");
+ if (ncopies<1) {
+ Warning("argument of -c < 1; set to 1!");
+ ncopies=1;
+ }
+ break;
+#ifdef DEBUG
+ case '-': /* d selects Debug output */
+ Debug = TRUE;
+ break;
+#endif
+#ifdef LJ2P
+ case 'd': /* d selects DUPLEX mode */
+ tcp++;
+ if (*tcp == '1' ) DuplexMode = 1;
+ else if (*tcp == '2') DuplexMode = 2;
+ else {
+ Warning("Invalid DUPLEX mode, assuming DUPLEX=1, Long-Edge Binding");
+ DuplexMode = 1;
+ }
+ break;
+#endif
+ case 'D': /* D selects DoublePage */
+ DoublePage = TRUE;
+ tcp++;
+ if (*tcp == '1' || *tcp == '2') {
+ if (*tcp == '2') PrintFirstPart = FALSE;
+ else PrintSecondPart = FALSE;
+ tcp++;
+ }
+ if (*tcp == '-') PrintEmptyPages = FALSE;
+ break;
+
+ case 'e': /* emit file is specified */
+ EmitFileName = ++tcp;
+#ifdef MSDOS
+ /* delete trailing ':' (causing hangup) */
+ if (EmitFileName[strlen(EmitFileName)-1] == ':')
+ EmitFileName[strlen(EmitFileName)-1] = '\0';
+#endif
+#ifdef OS2 /* repeated to avoid problems with stupid c preprocessors */
+ /* delete trailing ':' (causing hangup) */
+ if (EmitFileName[strlen(EmitFileName)-1] == ':')
+ EmitFileName[strlen(EmitFileName)-1] = '\0';
+#endif
+ break;
+ case 'f': /* next arg is starting pagenumber */
+ if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 )
+ Fatal("Argument is not a valid integer\n");
+ FirstPageSpecified = TRUE;
+ break;
+#ifdef LJ
+ case 'g': /* do not reset printer (go) */
+ ResetPrinter = FALSE;
+ break;
+#endif
+ case 'h': /* copy header file through to output */
+ HeaderFileName = ++tcp;
+ G_header = TRUE;
+ break;
+#if defined(LJ2P) || defined(IBM3812)
+ case 'l': /* landscape */
+ Landscape = TRUE;
+ break;
+#endif
+ case 'x': /* specify x-offset */
+ this_arg = 0;
+ if (!(*++tcp)) {
+ this_arg = (++argind >= argc ? 0 : argv[argind]);
+ } else {
+ this_arg = tcp;
+ }
+ if (!this_arg
+ || sscanf(this_arg,"%lf", &x_offset) != 1)
+ Fatal("Argument of -x is not a valid floating point number\n");
+ break;
+ case 'y': /* specify y-offset */
+ this_arg = 0;
+ if (!(*++tcp)) {
+ this_arg = (++argind >= argc ? 0 : argv[argind]);
+ } else {
+ this_arg = tcp;
+ }
+ if (!this_arg || sscanf(this_arg, "%lf", &y_offset) != 1)
+ Fatal("Argument of -y is not a valid floating point number\n");
+ break;
+ case 'X': /* specify X-origin in dots */
+ this_arg = 0;
+ if (!(*++tcp)) {
+ this_arg = (++argind >= argc ? 0 : argv[argind]);
+ } else {
+ this_arg = tcp;
+ }
+ if (!this_arg || sscanf(this_arg,"%hd", &x_origin) != 1)
+ Fatal("Argument of -X is not a valid integer\n");
+ break;
+ case 'Y': /* specify Y-origin in dots */
+ this_arg = 0;
+ if (!(*++tcp)) {
+ this_arg = (++argind >= argc ? 0 : argv[argind]);
+ } else {
+ this_arg = tcp;
+ }
+ if (!this_arg ||
+ sscanf(this_arg, "%hd", &y_origin) != 1)
+ Fatal("Argument of -Y is not a valid integer\n");
+ break;
+ case 'm': /* specify magnification to use */
+ switch ( (*++tcp) ) {
+ case '#':
+ /* next arg is a magnification to use */
+ if ( sscanf(tcp + 1, "%ld", &usermag) != 1 )
+ Fatal("Argument of mag is not a valid integer\n");
+ break;
+ case '0':
+ usermag = 1000;
+ break;
+ case 'h':
+ case 'H':
+ usermag = 1095;
+ break;
+ case '1':
+ usermag = 1200;
+ break;
+ case 'q':
+ usermag = 1250;
+ break;
+ case '2':
+ usermag = 1440;
+ break;
+ case '3':
+ usermag = 1728;
+ break;
+ case '4':
+ usermag = 2074;
+ break;
+ case '5':
+ usermag = 2488;
+ break;
+ default:
+ Fatal("%c is a bad mag step\n", *tcp);
+ }
+ break;
+#ifdef SUPERCOMMENT
+ case 'o': /* PostScript command to send */
+ if ( ++argind >= argc )
+ Fatal("No argument following -o\n", 0);
+ PScmd[nps++] = argv[argind];
+ break;
+#endif
+ case 'p': /* print n pages */
+ if ( sscanf(tcp + 1, "%ld", &PrintPages) != 1 )
+ Fatal("Argument is not a valid integer\n");
+ if (PrintPages < 1)
+ Fatal("Argument of -p must be greater than 0\n");
+ break;
+ case 'q': /* quiet operation */
+ G_quiet = TRUE;
+ break;
+ case 'r': /* switch order to process pages */
+ Reverse = (bool)(!Reverse);
+ break;
+#ifdef LJ
+ case 's': /* specify X-origin in dots */
+ this_arg = 0;
+ if (!(*++tcp)) this_arg = (++argind >= argc ? 0 : argv[argind]);
+ else this_arg = tcp;
+ if (!this_arg || sscanf(this_arg,"%hd", &pagesize) != 1)
+ Fatal("Argument of -s is not a valid integer\n");
+ switch (pagesize) {
+ case 1: pgsiz_dots = 3150; break; /* executive */
+ case 2: pgsiz_dots = 3300; break; /* letter */
+ case 3: pgsiz_dots = 4200; break; /* legal */
+ case 26: pgsiz_dots = 3507; break; /* a4 */
+ case 80: pgsiz_dots = 2250; break; /* monarc */
+ case 81: pgsiz_dots = 2850; break; /* com10 */
+ case 90: pgsiz_dots = 2598; break; /* int dl */
+ case 91: pgsiz_dots = 2704; break; /* int c5 */
+ default: Fatal(
+#ifndef vms
+ "%hd is a bad value for pagesize (1,2,3,26,80,81,90,91)",
+#else
+ "%d is a bad value for pagesize (1,2,3,26,80,81,90,91)",
+#endif
+ pagesize);
+ }
+ break;
+#endif
+ case 't': /* ending pagenumber */
+ if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 )
+ Fatal("Argument is not a valid integer\n");
+ LastPageSpecified = TRUE;
+ break;
+ case 'v': /* verbatim mode (print pxl-file names) */
+ G_noverbatim = FALSE;
+ break;
+ case 'w': /* don't print out warnings */
+ G_nowarn = TRUE;
+ break;
+#ifdef LJ
+ case 'z':
+ PrintTestPage = (bool)(!PrintTestPage);
+ break;
+#endif
+ default:
+ fprintf(stderr, "%c is not a legal flag\n", *tcp);
+ }
+ } else {
+
+ (void) strcpy(filename, tcp);
+ tcp = strrchr(argv[argind], '/');
+ /* split into directory + file name */
+ if (tcp == NULL) {
+ curarea[0] = '\0';
+ tcp = argv[argind];
+ } else {
+ (void) strcpy(curarea, argv[argind]);
+ curarea[tcp-argv[argind]+1] = '\0';
+ tcp += 1;
+ }
+
+ (void) strcpy(curname, tcp);
+ /* split into file name + extension */
+ tcp1 = strchr(tcp, '.');
+ if (tcp1 == NULL) {
+ (void) strcpy(rootname, curname);
+ strcat(curname, ".dvi");
+ } else {
+ *tcp1 = '\0';
+ (void) strcpy(rootname, curname);
+ *tcp1 = '.';
+ }
+
+ (void) strcpy(filename, curarea);
+ (void) strcat(filename, curname);
+
+ if ((dvifp = BINOPEN(filename)) == NULL) {
+ Fatal("%s: can't find DVI file \"%s\"\n\n",
+ G_progname, filename);
+ }
+ }
+ argind++;
+ }
+
+ x_goffset = (short) MM_TO_PXL(x_offset) + x_origin;
+ y_goffset = (short) MM_TO_PXL(y_offset) + y_origin;
+
+ if (dvifp == NULL) {
+ fprintf(stderr,"\nThis is the DVI to %s converter version %s",
+ PRINTER, VERSION);
+#ifdef SEVENBIT
+ fprintf(stderr,", 7bit");
+#endif
+ fprintf(stderr," (%s)\n", OS);
+ fprintf(stderr,"usage: %s [OPTIONS] dvifile\n", G_progname);
+
+ fprintf(stderr,"OPTIONS are:\n");
+#ifdef DEBUG
+ fprintf(stderr,"\t-- ..... turns debug output on\n");
+#endif
+ fprintf(stderr,
+ "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n");
+#ifdef IBM3812
+ fprintf(stderr,
+ "\t-b ..... take paper for first page from alternate casette\n");
+#endif
+ fprintf(stderr,"\t-cX ..... X= number of copies\n");
+#ifdef LJ2P
+ fprintf(stderr,"\t-dX ..... duplex, X=1: long-edge, 2: short-edge binding\n");
+#endif
+ fprintf(stderr,"\t-D ..... turns doublepage output on; ");
+ fprintf(stderr,"-D1 odd pages only, -D2 even\n");
+ fprintf(stderr,"\t-eX ..... X= output file\n");
+ fprintf(stderr,"\t-fX ..... print from begin of page number X\n");
+#ifdef LJ
+ fprintf(stderr,
+ "\t-g ..... do not reset printer at begin of job (go)\n");
+#endif
+ fprintf(stderr,"\t-hX ..... X= name of headerfile\n");
+#ifdef LJ2P
+ fprintf(stderr,"\t-l ..... landscape mode\n");
+#endif
+ fprintf(stderr,"\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n");
+ fprintf(stderr,"\t-pX ..... print X pages\n");
+ fprintf(stderr,"\t-q ..... quiet operation\n");
+ fprintf(stderr,"\t-r ..... process pages in reverse order\n");
+#ifdef LJ
+ fprintf(stderr,"\t-sX ..... set paper size to X (see documentation)\n");
+#endif
+ fprintf(stderr,"\t-tX ..... print to end of page number X\n");
+ fprintf(stderr,"\t-w ..... don't print out warnings\n");
+ fprintf(stderr,"\t-v ..... tell user which pixel-files are used\n");
+ fprintf(stderr,"\t-xX ..... X= x-offset on printout in mm\n");
+ fprintf(stderr,"\t-yX ..... X= y-offset on printout in mm\n");
+ fprintf(stderr,"\t-XO ..... O= x page origin in dots (default=%d)\n",
+ XDEFAULTOFF );
+ fprintf(stderr,"\t-YO ..... O= y page origin in dots (default=%d)\n",
+ YDEFAULTOFF );
+#ifdef LJ
+ fprintf(stderr,
+ "\t-z ..... print test page with pagecounter after job\n");
+#endif
+ exit(1);
+ }
+ if (EQ(EmitFileName, "")) {
+ if ((EmitFileName = malloc( STRSIZE )) != NULL)
+ allocated_storage += STRSIZE;
+ else
+ Fatal("Can't allocate storage of %d bytes\n",STRSIZE);
+ (void) strcpy(EmitFileName, curname);
+ tcp1 = strchr(EmitFileName, '.');
+ *tcp1 = '\0';
+ strcat(EmitFileName, EMITFILE_EXTENSION);
+ }
+}
+
+
+/*-->DoConv*/
+/*********************************************************************/
+/******************************** DoConv ***************************/
+/*********************************************************************/
+long
+DoConv(num, den, convResolution)
+long num, den;
+int convResolution;
+{
+ /*register*/ double conv;
+ conv = ((double)num / (double)den) *
+ ((double)mag / 1000.0) *
+ ((double)convResolution/254000.0);
+
+ return((long) ((1.0/conv)+0.5));
+}
+
+
+/*-->DoSpecial*/
+/*********************************************************************/
+/***************************** DoSpecial ***************************/
+/*********************************************************************/
+typedef enum {
+ None, String, Integer, Number, Dimension}
+
+
+ValTyp;
+typedef struct {
+ char *Key; /* the keyword string */
+ char *Val; /* the value string */
+ ValTyp vt; /* the value type */
+ union { /* the decoded value */
+ int i;
+ float n;
+ } v;
+} KeyWord;
+typedef struct {
+ char *Entry;
+ ValTyp Typ;
+} KeyDesc;
+#define PSFILE 0
+#define ORIENTATION 1
+#define RESETPOINTS 2
+#define DEFPOINT 3
+#define FILL 4
+#define GRAY 5
+#define PATTERN 6
+#define HPFILE 7
+KeyDesc KeyTab[] = {
+ { "file", String },
+ { "orientation", Integer},
+ { "resetpoints", String},
+ { "defpoint", String},
+ { "fill", String},
+ { "gray", Integer},
+ { "pattern", Integer},
+ { "hpfile", String}
+ /*,
+ {"hsize", Dimension},
+ {"vsize", Dimension},
+ {"hoffset", Dimension},
+ {"voffset", Dimension},
+ {"hscale", Number},
+ {"vscale", Number}*/
+
+
+};
+
+
+#define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
+void
+DoSpecial( str, n )
+/* interpret a \special command, made up of keyword=value pairs */
+char *str;
+int n;
+{
+char spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE];
+char *sf = NULL;
+float x,y;
+long x_pos, y_pos;
+KeyWord k;
+int i, j, j1;
+static int GrayScale=10, Pattern=1;
+static bool GrayFill=TRUE;
+static long p_x[80], p_y[80];
+str[n] = '\0';
+spbuf[0] = '\0';
+
+SetPosn(h, v);
+while ( (str = GetKeyStr(str, &k)) != NULL ) {
+ /* get all keyword-value pairs */
+ /* for compatibility, single words are taken as file names */
+ if ( k.vt == None && access(k.Key, 0) == 0) {
+ if ( sf )
+ Warning("More than one \\special file name given. %s ignored", sf);
+ (void) strcpy(spbuf, k.Key);
+ sf = spbuf;
+/*
+ for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
+*/
+ } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
+ switch (i) {
+ case PSFILE:
+ case HPFILE:
+ if ( sf )
+ Warning("More than one \\special file name given. %s ignored",
+ sf);
+ (void) strcpy(spbuf, k.Val);
+ sf = spbuf;
+/*
+ for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++) ;
+*/
+ break;
+ case ORIENTATION:
+#ifdef IBM3812
+ if ((k.v.i >= 0) && (k.v.i < 4)) {
+ last_ry = UNKNOWN;
+ sprintf(PMPformat, "\322%c", (unsigned char)k.v.i);
+ PMPout(2, PMPformat);
+ if (k.v.i == 1) Landscape = TRUE;
+ else if (k.v.i == 0) Landscape = FALSE;
+#endif
+#ifdef LJ
+ if ((k.v.i >= 0) && (k.v.i < 2)) {
+ last_ry = UNKNOWN;
+ EMIT(outfp, "\033&l%dO\033*rF", (unsigned char)k.v.i);
+#endif
+ } else
+ Warning( "Invalid orientation (%d)given; ignored.", k.v.i);
+ break;
+ case RESETPOINTS:
+ (void) strcpy(spbuf, k.Val);
+
+ sf = NULL;
+ break;
+
+ case DEFPOINT:
+ (void) strcpy(spbuf, k.Val);
+ i=sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys);
+ if (i>0) {
+ x_pos=h; y_pos=v;
+ if (i>1) {
+ if (sscanf(xs,"%fpt",&x)>0) {
+ fprintf(stderr,"x = %f\n",x);
+ x_pos = PT_TO_DVI(x);
+ }
+ }
+ if (i>2) {
+ if (sscanf(ys,"%fpt",&y)>0) {
+ fprintf(stderr,"y = %f\n",y);
+ y_pos = PT_TO_DVI(y);
+ }
+ }
+ p_x[j]=x_pos;
+ p_y[j]=y_pos;
+ } else
+ Warning("invalid point definition\n");
+
+ sf = NULL;
+ break;
+
+ case FILL:
+ (void) strcpy(spbuf, k.Val);
+ i=sscanf(spbuf,"%d/%d %s",&j,&j1,xs);
+ if (i>1) {
+#ifdef LJ
+ SetPosn(p_x[j], p_y[j]);
+ x_pos = (long)PIXROUND(p_x[j1]-p_x[j], hconv);
+ y_pos = (long)PIXROUND(p_y[j1]-p_y[j], vconv);
+ if (labs(x_pos)<labs(y_pos)) x_pos=x_pos+3;
+ else y_pos=y_pos+3;
+ if (GrayFill) {
+ EMIT(outfp, "\033*c%lda%ldb%dg2P", x_pos, y_pos, GrayScale);
+ } else {
+ EMIT(outfp, "\033*c%lda%ldb%dg3P", x_pos, y_pos, Pattern);
+ }
+ last_ry = UNKNOWN;
+#endif
+ }
+ break;
+ case GRAY:
+ if ((k.v.i >= 0) && (k.v.i < 101)) {
+ GrayScale = k.v.i;
+ GrayFill = TRUE;
+ } else
+ Warning( "Invalid gray scale (%d) given; ignored.", k.v.i);
+ break;
+ case PATTERN:
+ if ((k.v.i >= 0) && (k.v.i < 7)) {
+ Pattern = k.v.i;
+ GrayFill = FALSE;
+ } else
+ Warning( "Invalid pattern (%d) given; ignored.", k.v.i);
+ break;
+
+ default:
+ Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val);
+ break;
+ }
+ else
+ Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key);
+}
+if ( sf ) {
+ last_ry = UNKNOWN;
+#ifdef IBM3812
+ PMPflush;
+#endif
+ if (i==HPFILE)
+ CopyHPFile( sf );
+ else
+ CopyFile( sf );
+ }
+}
+
+
+/*-->EmitChar*/
+/**********************************************************************/
+/**************************** EmitChar ******************************/
+/**********************************************************************/
+void /* output a character bitmap */
+EmitChar(c, ce)
+long c;
+struct char_entry *ce;
+{
+ register int i;
+ register unsigned char *sl;
+ unsigned short nbpl, nwpl;
+ long total;
+#ifdef LJ
+ unsigned char cnv_buffer[10];
+#endif
+
+
+#ifdef LJ
+/*
+printf("Emit character %c(%d) id=%d, yoff=%d[%d], w=%d[%d], h=%d[%d]\n",
+ (char)c,(int)c,
+ fontptr->plusid,
+ ce->yOffset, fontptr->max_yoff,
+ ce->width, fontptr->max_width,
+ ce->height, fontptr->max_height
+);
+*/
+#endif
+
+
+
+ if ( fontptr->ncdl == 0 ) {
+#ifdef IBM3812
+ used_fontstorage += 1028;
+#endif
+#ifdef LJ
+ if (fontptr->max_width == 0) { /* we have no realistic values */
+ fontptr->max_yoff = CHAR_HEIGTH_LARGE;
+ fontptr->max_width = CHAR_WIDTH_LARGE;
+ fontptr->max_height = CHAR_HEIGTH_LARGE*2;
+ }
+
+ /* open font dict before first char, set active font */
+ INT_ASCII(cnv_buffer,fontptr->plusid);
+#ifdef LJ4
+ EMIT(outfp, "\033*c%sD\033)s68W", cnv_buffer);
+ EMITB(6, "\0\104\024\2\0\0");
+#else
+ EMIT(outfp, "\033*c%sD\033)s26W", cnv_buffer);
+#ifdef SEVENBIT
+ EMITB(6, "\0\032\0\1\0\0");
+#else
+ EMITB(6, "\0\032\0\2\0\0");
+#endif
+#endif /* LJ 4 */
+ EMITWORD( fontptr->max_yoff);
+ EMITWORD( fontptr->max_width);
+ EMITWORD( fontptr->max_height);
+ EMITB(8, "\0\1\1\25\0\4\0\4");
+ EMITB(6, "\0\0\0\0\0\0");
+#ifdef LJ4
+ EMITB(22,"\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0");
+ EMITB(16," ");
+ EMITB(4 ,"\2\130\2\130");
+#endif
+ EMIT(outfp, "\033*c4F");
+#endif
+ }
+ if ( fontptr != prevfont ) { /* because this isn't done on pass 0 */
+#ifdef LJ
+ INT_ASCII(cnv_buffer,fontptr->plusid);
+ EMIT(outfp, "\033(%sX", cnv_buffer);
+#endif
+ prevfont = fontptr;
+ }
+
+#ifdef USEPXL
+ if (fontptr->id == pk89) {
+ nbpl = ((int)(ce->width) + 7) >> 3;
+ total = (long)ce->height * nbpl;
+ } else if (fontptr->id == id1002) {
+ nbpl = ((int)(ce->width) + 7) >> 3;
+ total = (long)ce->height * nbpl;
+ } else if (fontptr->id == id1001) {
+ nwpl = ((int)(ce->width) + 31) >> 5;
+ nbpl = ((int)(ce->width) + 7) >> 3;
+ total = (long)ce->height * nbpl;
+ }
+#else
+ nbpl = (num_cols + 7) >> 3;
+ total = num_rows * nbpl;
+#endif
+/***************************************************************
+ if ( ((char) c == 'i') && (fontptr->plusid == 0)) {
+ long j;
+ printf("cols=%ld, ncols=%ld\n",nwpl,nbpl);
+
+ printf("%ld Bytes:->",total);
+ for (j=0; j<total;j++) {
+ char *ch; char ic;
+ ch = (char *)(ce->where.address.pixptr);
+ ic = *(ch+j);
+ printf("%X.",ic);
+ }
+ printf("<- Now Emitting\n");
+ }
+***************************************************************/
+#ifdef USEPXL
+#ifdef IBM3812
+ if ((short)(ce->height) - ce->yOffset > 55) {
+ ce->yyOffset = (short) ce->height - ce->yOffset;
+ ce->yOffset = (short) ce->height;
+ } else {
+ ce->yyOffset = (short) 0;
+ }
+#endif
+#ifdef LJ
+ ce->yyOffset = (short) 0;
+#endif
+#endif
+
+ /* ce->cw = (long)(((double)ce->tfmw / (double)hconv) +0.5); */
+ /* set active font to nn, load font pattern xx ... */
+#ifdef IBM3812
+ PMPcont(total + 9);
+#ifdef USEPXL
+ sprintf(PMPformat, "\323%c\360%c%c%c",
+ (unsigned char)fontptr->plusid,
+ (unsigned char)VisChar((char)c),
+ (unsigned char)ce->height,
+ (unsigned char)ce->width);
+ PMPout(6, PMPformat);
+ PMPoutC((char)(-(ce->xOffset)));
+ PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width)));
+ PMPoutC((char)(ce->yOffset));
+#else
+ sprintf(PMPformat, "\323%c\360%c%c%c",
+ (unsigned char)fontptr->plusid,
+ (unsigned char)VisChar((char)c),
+ (unsigned char)num_rows,
+ (unsigned char)num_cols);
+ PMPout(6, PMPformat);
+ PMPoutC((char)(-x_offset));
+ PMPoutC((char)(ce->cw - (-x_offset + num_cols)));
+ PMPoutC((char)num_rows-y_offset);
+#endif
+#endif
+#ifdef LJ
+ INT_ASCII(cnv_buffer,fontptr->plusid);
+ EMIT(outfp, "\033*c%sd%dE\033(s%ldW", cnv_buffer,
+ (unsigned int)VisChar((char)c), (long)(total + 16));
+ EMITB(4, "\4\0\016\1");
+/* EMITC((char)(Landscape==TRUE)); */
+ EMITC((char)0);
+ EMITC((char)0);
+#ifdef USEPXL
+ EMITWORD(-ce->xOffset);
+ EMITWORD(ce->yOffset);
+ EMITWORD(ce->width);
+ EMITWORD(ce->height);
+#else
+ EMITWORD(-x_offset);
+ EMITWORD(num_rows-y_offset);
+ EMITWORD(num_cols);
+ EMITWORD(num_rows);
+#endif
+ EMITWORD((int)ce->cw * 4);
+#endif
+#ifdef USEPXL
+
+ if (fontptr->id == pk89)
+ PkRaster(ce, FALSE);
+ else if (fontptr->id == id1002)
+ for (i = 0; i < (int) ce->height; i++) {
+ sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl);
+ EMITL(nbpl, sl);
+ }
+ else if (fontptr->id == id1001)
+ for (i = 0; i < (int) ce->height; i++) {
+ sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
+ EMITL(nbpl, sl);
+ }
+#else
+ for (i = num_rows; i > 0; i--)
+ {
+ EMITL (nbpl, bits + (i-1) * nbpl);
+ }
+#endif
+#ifdef IBM3812
+#ifdef USEPXL
+ used_fontstorage += (long)ce->height * ((ce->width + 15) >> 4)
+ *2 + 14;
+#else
+ used_fontstorage += (long)num_rows * ((num_cols + 15) >> 4)
+ *2 + 14;
+#endif
+#endif
+#ifdef LJ
+#ifdef USEPXL
+ used_fontstorage += 64 * (((int)((ce->height * ce->width) - 1) / 64) + 1);
+#else
+ used_fontstorage += 64 * ((((num_rows * num_cols) - 1) / 64) + 1);
+#endif
+#endif
+ fontptr->ncdl += 1;
+ G_ncdl += 1;
+}
+
+
+/*-->RasterLine*/
+/**********************************************************************/
+/**************************** RasterLine ****************************/
+/**********************************************************************/
+void
+RasterLine(ce, nbpl, current_line, buffer)
+struct char_entry *ce;
+unsigned short nbpl, current_line;
+char *buffer;
+{
+#ifdef IBM3812
+ long total;
+ static unsigned short maxlines;
+
+ if (current_line == 0) {
+#ifdef USEPXL
+ maxlines = ce->height;
+
+ MoveVert(-ce->yOffset); /* move cursor up */
+ MoveHor(-ce->xOffset); /* move cursor right */
+#else
+ maxlines = num_rows;
+
+ MoveVert(-(num_rows-y_offset)); /* move cursor up */
+ MoveHor(-x_offset); /* move cursor right */
+#endif
+ last_ry = UNKNOWN; /* next time full positioning */
+ }
+
+ if (current_line % maxlines == 0) {
+ if (current_line > 0) { /* maxlines lines have been printed*/
+ MoveVert(maxlines); /* move cursor down */
+ last_ry = UNKNOWN; /* next time full positioning */
+ }
+#ifdef USEPXL
+ total = (long)(ce->height - current_line) * (long)nbpl;
+#else
+ total = (long)(num_rows - current_line) * (long)nbpl;
+#endif
+ if ((total + 9) > 65535) {
+ maxlines = (unsigned short)((65535 - 9) / nbpl);
+ total = (long)maxlines * (long)nbpl;
+ }
+
+ PMPcont(total + 9);
+ PMPout(2, "\365\0");
+ EMITWORD(maxlines);
+#ifdef USEPXL
+ EMITWORD(ce->width);
+#else
+ EMITWORD(num_cols);
+#endif
+ PMPoutC((unsigned char) (total >> 16) & 0xFF);
+ PMPoutC((unsigned char) (total >> 8 ) & 0xFF);
+ PMPoutC((unsigned char) total & 0xFF);
+ }
+ EMITL((int)nbpl, buffer);
+#endif
+#ifdef LJ
+ register int emitbytes;
+
+ for (emitbytes = (int)nbpl;
+ (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0);
+ emitbytes--) ;
+ EMIT(outfp, "\033*b%dW", emitbytes);
+ EMITL(emitbytes, buffer);
+#endif
+}
+
+
+/*-->RasterChar*/
+/**********************************************************************/
+/**************************** RasterChar ****************************/
+/**********************************************************************/
+void /* raster a character bitmap */
+RasterChar(ce)
+struct char_entry *ce;
+{
+ int i;
+ register unsigned char *sl;
+ unsigned short nbpl, nwpl;
+ unsigned char raster_line_buf[BYTES_PER_PIXEL_LINE];
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"Raster character ...size=%d \n", (int)ce->charsize );
+#endif
+
+#ifdef USEPXL
+ if (fontptr->id == pk89) {
+ nbpl = ((int)(ce->width) + 7) >> 3;
+ } else if (fontptr->id == id1002) {
+ nbpl = ((int) ce->width + 7) >> 3;
+ } else if (fontptr->id == id1001) {
+ nwpl = ((int) ce->width + 31) >> 5;
+ nbpl = ((int) ce->width + 7) >> 3;
+ }
+#else
+ nbpl = (num_cols + 7) >> 3;
+#endif
+
+#ifdef LJ
+#ifdef LJ4
+ EMIT(outfp, "\033*t600R\033*r1A");
+#else
+ EMIT(outfp, "\033*t300R\033*r1A");
+#endif
+#endif
+
+ { /* read pixel from file */
+ if ((ce->charsize == HUGE_SIZE) && (fontptr->id != pk89))
+ OpenFontFile();
+#ifdef USEPXL
+ fseek(pxlfp, ce->where.address.fileOffset, 0);
+#else
+ fseek(gfin, ce->where.address.fileOffset, 0);
+ gettochar();
+ readbits();
+#endif
+ }
+
+#ifdef USEPXL
+ if (fontptr->id == pk89)
+ PkRaster(ce, TRUE);
+ else if (fontptr->id == id1002) {
+ for (i = 0; i < (int) ce->height; i++) {
+ if (ce->charsize == HUGE_SIZE) {
+ fread(raster_line_buf, 1, (int) nbpl, pxlfp);
+ sl = raster_line_buf;
+ } else
+ sl = ((unsigned char *)(ce->where.address.pixptr)
+ + i * nbpl);
+
+ RasterLine(ce, (unsigned int)nbpl, i, sl);
+ }
+ } else if (fontptr->id == id1001) {
+ long filediff;
+ filediff = (long)nwpl * 4 - nbpl;
+ for (i = 0; i < (int) ce->height; i++) {
+ if (ce->charsize == HUGE_SIZE) {
+ fread(raster_line_buf, 1, (int) nbpl, pxlfp);
+ /* skip fill bytes */
+ fseek(pxlfp, filediff, 1);
+ sl = raster_line_buf;
+ } else
+ sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
+
+ RasterLine(ce, (unsigned int)nbpl, i, sl);
+ }
+ }
+#else
+ for (i = num_rows; i > 0; i--)
+ RasterLine(ce, (unsigned int)nbpl, i, bits + (i-1) * nbpl);
+#endif
+#ifdef LJ
+ EMIT(outfp, "\033*rB");
+#endif
+ last_ry = UNKNOWN;
+}
+
+
+/*-->Fatal*/
+/**********************************************************************/
+/****************************** Fatal *******************************/
+/**********************************************************************/
+void
+Fatal(fmt, a, b, c) /* issue a fatal error message */
+char *fmt; /* format */
+char *a, *b, *c; /* arguments */
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s: FATAL--", G_progname);
+ fprintf(stderr, fmt, a, b, c);
+ fprintf(stderr, "\n\n");
+#ifndef vms
+ exit(2);
+#else
+ exit(SS$_ABORT);
+#endif
+}
+
+
+/*-->FindPostAmblePtr*/
+/**********************************************************************/
+/************************ FindPostAmblePtr **************************/
+/**********************************************************************/
+void
+FindPostAmblePtr(postambleptr)
+long *postambleptr;
+/* this routine will move to the end of the file and find the start
+ of the postamble */
+{
+ long i;
+ fseek (dvifp, 0l, 2); /* goto end of file */
+ *postambleptr = ftell (dvifp) - 4;
+ fseek (dvifp, *postambleptr, 0);
+ while (TRUE) {
+ fseek (dvifp, --(*postambleptr), 0);
+ if (((i = NoSignExtend(dvifp, 1)) != 223) &&
+ (i != DVIFORMAT))
+ Fatal ("Bad end of DVI file");
+ if (i == DVIFORMAT)
+ break;
+ }
+ fseek (dvifp, (*postambleptr) - 4, 0);
+ (*postambleptr) = NoSignExtend(dvifp, 4);
+ fseek (dvifp, *postambleptr, 0);
+}
+
+
+/*-->GetBytes*/
+/**********************************************************************/
+/***************************** GetBytes *****************************/
+/**********************************************************************/
+void
+GetBytes(fp, cp, n) /* get n bytes from file fp */
+/*register*/ FILE *fp; /* file pointer */
+register char *cp; /* character pointer */
+int n; /* number of bytes */
+{
+ while (n--)
+ *cp++ = (char)getc(fp);
+}
+
+
+/*-->GetFontDef*/
+/**********************************************************************/
+/**************************** GetFontDef *****************************/
+/**********************************************************************/
+void
+GetFontDef()
+/***********************************************************************
+ Read the font definitions as they are in the postamble of the DVI
+ file.
+***********************************************************************/
+{
+ unsigned char byte;
+ while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) &&
+ (byte <= FNT_DEF4)) {
+ switch (byte) {
+ case FNT_DEF1:
+ ReadFontDef ( NoSignExtend(dvifp, 1));
+ break;
+ case FNT_DEF2:
+ ReadFontDef ( NoSignExtend(dvifp, 2));
+ break;
+ case FNT_DEF3:
+ ReadFontDef ( NoSignExtend(dvifp, 3));
+ break;
+ case FNT_DEF4:
+ ReadFontDef ( NoSignExtend(dvifp, 4));
+ break;
+ default:
+ Fatal ("Bad byte value in font defs");
+ break;
+ }
+ }
+ if (byte != POST_POST)
+ Fatal ("POST_POST missing after fontdefs");
+}
+
+
+/*-->GetKeyStr*/
+/**********************************************************************/
+/***************************** GetKeyStr ****************************/
+/**********************************************************************/
+/* extract first keyword-value pair from string (value part may be null)
+ * return pointer to remainder of string
+ * return NULL if none found
+ */
+char KeyStr[STRSIZE];
+char ValStr[STRSIZE];
+char
+*GetKeyStr( str, kw )
+char *str;
+KeyWord *kw;
+{
+ char *s, *k, *v, t;
+ if ( !str )
+ return( NULL );
+ for ( s = str; *s == ' '; s++)
+ ; /* skip over blanks */
+ if ( *s == '\0' )
+ return( NULL );
+ for ( k = KeyStr; /* extract keyword portion */
+ *s != ' ' && *s != '\0' && *s != '=';
+ *k++ = *s++)
+ ;
+ *k = '\0';
+ kw->Key = KeyStr;
+ kw->Val = v = NULL;
+ kw->vt = None;
+ for ( ; *s == ' '; s++)
+ ; /* skip over blanks */
+ if ( *s != '=' ) /* look for "=" */
+ return( s );
+ for ( s++; *s == ' '; s++); /* skip over blanks */
+ if ( *s == '\'' || *s == '\"' ) /* get string delimiter */
+ t = *s++;
+ else
+ t = ' ';
+ for ( v = ValStr; /* copy value portion up to delim */
+ *s != t && *s != '\0';
+ *v++ = *s++)
+ ;
+ if ( t != ' ' && *s == t )
+ s++;
+ *v = '\0';
+ kw->Val = ValStr;
+ kw->vt = String;
+ return( s );
+}
+
+
+/*-->GetKeyVal*/
+/**********************************************************************/
+/***************************** GetKeyVal ****************************/
+/**********************************************************************/
+/* get next keyword-value pair decode value according to table entry */
+bool
+GetKeyVal( kw, tab, nt, tno)
+KeyWord *kw;
+KeyDesc tab[];
+int nt;
+int *tno;
+{
+ int i;
+ char c = '\0';
+ *tno = -1;
+ for (i = 0; i < nt; i++)
+ if ( IsSame(kw->Key, tab[i].Entry) ) {
+ *tno = i;
+ switch ( tab[i].Typ ) {
+ case None:
+ if ( kw->vt != None )
+ return( FALSE );
+ break;
+ case String:
+ if ( kw->vt != String )
+ return( FALSE );
+ break;
+ case Integer:
+ if ( kw->vt != String )
+ return( FALSE );
+ if ( sscanf(kw->Val, "%d%c",
+ &(kw->v.i), &c) != 1
+ || c != '\0' )
+ return( FALSE );
+ break;
+/* case Number:
+ * case Dimension:
+ * if( kw->vt != String ) return( FALSE );
+ * if( sscanf(kw->Val,"%f%c",
+ * &(kw->v.n), &c) != 1
+ * || c != '\0' ) return( FALSE );
+ * break;
+ */
+ }
+ kw->vt = tab[i].Typ;
+ return( TRUE );
+ }
+ return( TRUE );
+}
+
+
+
+/*-->IsSame*/
+/**********************************************************************/
+/******************************* IsSame *****************************/
+/**********************************************************************/
+bool /* compare strings, ignore case */
+IsSame(a, b)
+char *a, *b;
+{
+ char *x, *y;
+ x = a;
+ y = b;
+ for ( ; *a != '\0'; )
+ if ( tolower(*a++) != tolower(*b++) )
+ return( FALSE );
+ return( *x == *y ? TRUE : FALSE );
+}
+
+
+/*-->NoSignExtend*/
+/**********************************************************************/
+/*************************** NoSignExtend ***************************/
+/**********************************************************************/
+long
+NoSignExtend(fp, n) /* return n byte quantity from file fd */
+register FILE *fp; /* file pointer */
+register int n; /* number of bytes */
+{
+ long x; /* number being constructed */
+ x = 0;
+ while (n--) {
+ x <<= 8;
+ x |= getc(fp);
+ }
+ return(x);
+}
+
+
+/*-->OpenFontFile*/
+/**********************************************************************/
+/************************** OpenFontFile *****************************/
+/**********************************************************************/
+void
+OpenFontFile()
+/***********************************************************************
+ The original version of this dvi driver reopened the font file each
+ time the font changed, resulting in an enormous number of relatively
+ expensive file openings. This version keeps a cache of up to
+ MAXOPEN open files, so that when a font change is made, the file
+ pointer, pxlfp, can usually be updated from the cache. When the
+ file is not found in the cache, it must be opened. In this case,
+ the next empty slot in the cache is assigned, or if the cache is
+ full, the least used font file is closed and its slot reassigned for
+ the new file. Identification of the least used file is based on the
+ counts of the number of times each file has been "opened" by this
+ routine. On return, the file pointer is always repositioned to the
+ beginning of the file.
+***********************************************************************/
+{
+ int i, least_used, current;
+ struct pixel_list tmp;
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"open font file %d\n", fontptr->font_file_id);
+#endif
+/*
+fprintf(stderr,"? %lx == %lx\n", pfontptr,fontptr);
+*/
+ if ((pfontptr == fontptr) && (pxlfp != NO_FILE))
+ return; /* we need not have been called */
+
+ if (fontptr->font_file_id == NO_FILE)
+ return; /* we need not have been called */
+
+ tmp = pixel_files[1];
+ for (current = 1;
+ (current <= nopen) && (tmp.pixel_file_id != fontptr->font_file_id); ) {
+ ++current;
+ tmp = pixel_files[current];
+ }
+ /* try to find file in open list */
+
+ if (current <= nopen) /* file already open */ {
+ if ( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE )
+ fseek(pxlfp, 0l, 0);
+ /* reposition to start of file */
+ } else {
+ /* file not in open list */
+ if (nopen < MAXOPEN) /* just add it to list */
+ current = ++nopen;
+ else {
+ /* list full -- find least used file, */
+ /* close it, and reuse slot for new file */
+ least_used = 1;
+ for (i = 2; i <= MAXOPEN; ++i)
+ if (pixel_files[least_used].use_count>pixel_files[i].use_count)
+ least_used = i;
+ if (pixel_files[least_used].pixel_file_id != NO_FILE) {
+ FILE * fid;
+ struct font_entry *fp;
+ fid = pixel_files[least_used].pixel_file_id;
+ /* mark file as being closed in the entry */
+ fp = hfontptr;
+ while (fp != NULL && fp->font_file_id != fid) fp = fp->next;
+ if (fp == NULL)
+ Fatal("Open file %x not found in font entry list.\n", fid);
+ else {
+ fp->font_file_id = NULL;
+ }
+ fclose( fid );
+ }
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"\n__reuse slot %d\n", least_used);
+#endif
+ current = least_used;
+ }
+ if ((pxlfp = BINOPEN(fontptr->name)) == NULL) {
+ Warning("PXL-file %s could not be opened", fontptr->name);
+ pxlfp = NO_FILE;
+ } else {
+#ifdef DEBUG
+ if (Debug) fprintf(stderr,
+ "Opening File <%s> /%x/, Size(font_entry)=%d\n",
+ fontptr->name, pxlfp, sizeof(struct font_entry ));
+#endif
+
+ }
+ pixel_files[current].pixel_file_id = pxlfp;
+ pixel_files[current].use_count = 0;
+ }
+ pfontptr = fontptr; /* make previous = current font */
+ fontptr->font_file_id = pxlfp; /* set file identifier */
+ pixel_files[current].use_count++; /* update reference count */
+#ifndef USEPXL
+ gfin = pxlfp;
+#endif
+}
+
+
+/*-->PixRound*/
+/**********************************************************************/
+/***************************** PixRound *****************************/
+/**********************************************************************/
+long
+PixRound(x, conv) /* return rounded number of pixels */
+long x; /* in DVI units */
+long conv; /* conversion factor */
+{
+ return((x + conv) / conv);
+}
+
+
+/*-->ReadFontDef*/
+/**********************************************************************/
+/**************************** ReadFontDef ***************************/
+/**********************************************************************/
+void
+ReadFontDef(k)
+long k;
+{
+ long t;
+ unsigned short i;
+ char nname[STRSIZE];
+ int nmag;
+ struct font_entry *tfontptr; /* temporary font_entry pointer */
+ struct char_entry *tcharptr; /* temporary char_entry pointer */
+ static int plusid = 0;
+ bool font_found = FALSE;
+#ifdef LJ
+ int depth, max_depth;
+#endif
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"Mallocating %d Bytes)...\n",
+ sizeof(struct font_entry ));
+#endif
+
+ if ((tfontptr = NEW(struct font_entry )) == NULL)
+ Fatal("can't malloc space for font_entry");
+
+ allocated_storage += sizeof(struct font_entry );
+
+ tfontptr->next = hfontptr;
+ tfontptr->font_file_id = NULL;
+ fontptr = hfontptr = tfontptr;
+ tfontptr->ncdl = 0;
+ tfontptr->k = k;
+ tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */
+ tfontptr->s = NoSignExtend(dvifp, 4); /* space size */
+ tfontptr->d = NoSignExtend(dvifp, 4); /* design size */
+ tfontptr->a = (int) NoSignExtend(dvifp, 1); /* length for font name */
+ tfontptr->l = (int) NoSignExtend(dvifp, 1); /* device length */
+
+#ifdef LJ
+ tfontptr->max_width = tfontptr->max_height = tfontptr->max_yoff =
+ max_depth = 0;
+#endif
+
+ GetBytes(dvifp, tfontptr->n, tfontptr->a + tfontptr->l);
+ tfontptr->n[tfontptr->a+tfontptr->l] = '\0';
+
+ tfontptr->font_mag = (long)((
+ ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5))
+ * ActualFactor(mag)
+#ifdef USEPXL
+ * RESOLUTION * 5.0
+#else
+ * RESOLUTION
+#endif
+ ) + 0.5);
+/*
+printf("[%ld]=%lf * %lf * %lf + 0.5 = %ld\n",
+ ((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
+ ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
+ ActualFactor(mag),
+ (double)RESOLUTION * 5,
+ tfontptr->font_mag );
+*/
+
+
+ if (!(font_found = (bool)
+ findfile(PXLpath, tfontptr->n, tfontptr->font_mag, tfontptr->name,FALSE))) {
+ Warning(tfontptr->name); /* contains error messsage */
+ tfontptr->font_file_id = NO_FILE;
+ }
+ else if (!( (G_noverbatim) || (G_quiet) ) )
+ fprintf(stderr,"%d: using font <%s>\n",
+ plusid,tfontptr->name);
+
+ tfontptr->plusid = plusid;
+ plusid++;
+
+ /* sprintf(tfontptr->psname,"%s.%ld.%d",
+ tfontptr->n,tfontptr->font_mag,tfontptr->plusid);*/
+
+#ifdef LJ
+ if (plusid >= HANDLE_MAX_FONTS)
+ Fatal("can handle only %d fonts! ask a wizzard..\n",
+ HANDLE_MAX_FONTS);
+#endif
+ if (tfontptr != pfontptr) {
+ if (font_found) OpenFontFile();
+ else
+ pxlfp = NO_FILE;
+ }
+#ifdef USEPXL
+ if ( pxlfp == NO_FILE ) { /* allow missing pxl files */
+ tfontptr->magnification = 0;
+ tfontptr->designsize = 0;
+#endif
+ for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) {
+ tcharptr = &(tfontptr->ch[i]);
+#ifdef USEPXL
+ tcharptr->width = 0;
+ tcharptr->height = 0;
+ tcharptr->xOffset = 0;
+ tcharptr->yOffset = 0;
+#endif
+ tcharptr->where.isloaded = FALSE;
+ tcharptr->where.address.fileOffset = NONEXISTANT;
+ tcharptr->tfmw = 0;
+ }
+#ifdef USEPXL
+ return;
+ }
+ t = (long) NoSignExtend(pxlfp, 1);
+ if (t == 0) {
+ t = (long) NoSignExtend(pxlfp, 1);
+ t = (long) NoSignExtend(pxlfp, 2);
+ if (t == 1002)
+ tfontptr->id = id1002;
+ else if (t == 1001)
+ tfontptr->id = id1001;
+ else
+ Fatal("Unknown Version of PXL-format\n");
+ } else {
+ if (t == PK_PRE) {
+ unsigned char temp_byte;
+ temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
+ if (temp_byte != PK_ID) Fatal(
+ "Wrong Version of pk file! (%d should be 89)\n",
+ (int)temp_byte);
+ else
+ tfontptr->id = pk89;
+ } else
+ Fatal("unknown font format in file <%s> !\n",fontptr->name);
+ }
+
+ if ((tfontptr->id == id1002) || (tfontptr->id == id1001)) {
+ fseek(pxlfp, -20l, 2);
+
+ t = NoSignExtend(pxlfp, 4);
+ if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
+ Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
+ tfontptr->name, tfontptr->c, t);
+ tfontptr->magnification = NoSignExtend(pxlfp, 4);
+ tfontptr->designsize = NoSignExtend(pxlfp, 4);
+
+ if (tfontptr->id == id1001)
+ fseek(pxlfp, (long) (NoSignExtend(pxlfp, 4) * 4), 0);
+ else
+ fseek(pxlfp, (long) NoSignExtend(pxlfp, 4) , 0);
+
+ for (i = FIRSTFNTCHAR; i <= 127; i++) { /* only defined for 7bit*/
+ tcharptr = &(tfontptr->ch[i]);
+ tcharptr->width = (unsigned short) NoSignExtend(pxlfp, 2);
+ tcharptr->height = (unsigned short) NoSignExtend(pxlfp, 2);
+ tcharptr->xOffset = (short) SignExtend(pxlfp, 2);
+ tcharptr->yOffset = (short) SignExtend(pxlfp, 2);
+ tcharptr->where.isloaded = FALSE;
+ if (tfontptr->id == id1001)
+ tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4) * 4;
+ else
+ tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4);
+ tcharptr->tfmw = (long)
+ ( (double)(NoSignExtend(pxlfp, 4))
+ * (double)tfontptr->s / (double) 0x100000 );
+ tcharptr->cw = (long)(((double)tcharptr->tfmw/(double)hconv) + 0.5);
+
+ if (tcharptr->width > CHAR_WIDTH_LARGE ||
+ tcharptr->height > CHAR_HEIGTH_LARGE )
+ tcharptr->charsize = LARGE_SIZE;
+ else
+ tcharptr->charsize = SMALL_SIZE;
+#ifdef LJ
+ max(tfontptr->max_width,tcharptr->width);
+ max(tfontptr->max_height,tcharptr->height);
+ if (tcharptr->yOffset > 0 && (int)tfontptr->max_yoff < (int)tcharptr->yOffset)
+ tfontptr->max_yoff = tcharptr->yOffset;
+ if ((depth = tcharptr->height - tcharptr->yOffset)>max_depth)
+ max_depth = depth;
+#endif
+
+ }
+#ifdef LJ
+ tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
+ tfontptr->max_yoff+1;
+#endif
+ } else { /* PK 89 format */
+ unsigned char temp_byte;
+ register unsigned char flag_byte;
+ long hppp, vppp, pkloc, packet_length, temp;
+ int car, ii;
+
+ /* read comment */
+ for ( ii = temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
+ ii>0; ii--) {
+ flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
+#ifdef DEBUG
+ if (Debug) fprintf(stderr, "%c", flag_byte ) ;
+#endif
+ }
+#ifdef DEBUG
+ if (Debug) fprintf(stderr, "\n");
+#endif
+ pkloc = 3 + (int)temp_byte;
+ tfontptr->designsize = NoSignExtend(pxlfp, 4);
+
+ t = NoSignExtend(pxlfp, 4);
+ if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
+ Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
+ tfontptr->name, tfontptr->c, t);
+
+ hppp = NoSignExtend(pxlfp, 4);
+ vppp = NoSignExtend(pxlfp, 4);
+ if (hppp != vppp)
+ Warning("aspect ratio is %ld:%ld (should be 1:1)!", hppp,vppp);
+ tfontptr->magnification = (long)(hppp * 72.27 * 5 / 65536l + 0.5);
+
+ pkloc += 16;
+ flag_byte = skip_specials(&pkloc);
+
+ while (flag_byte != PK_POST) {
+ if ((flag_byte & 7) == 7) {
+ /* fprintf(stderr,"\nRead long character preamble\n"); */
+
+ packet_length = (unsigned long)NoSignExtend(pxlfp,4);
+ if ((car = (int)NoSignExtend(pxlfp, 4)) > (LASTFNTCHAR))
+ Fatal("Bad character (%d) in PK-File\n",(int)car) ;
+
+ tcharptr = &(tfontptr->ch[car]);
+ tcharptr->where.address.fileOffset = pkloc;
+ /* set pkloc to end_of_packet */
+ pkloc += packet_length + 8;
+
+ tcharptr->tfmw = (long) NoSignExtend(pxlfp, 4);
+ (void) NoSignExtend(pxlfp, 4); /* horesc not used */
+ (void) NoSignExtend(pxlfp, 4); /* not used */
+
+ tcharptr ->width = (unsigned short) NoSignExtend(pxlfp, 4);
+ tcharptr ->height = (unsigned short) NoSignExtend(pxlfp, 4);
+ tcharptr ->xOffset = (short) SignExtend(pxlfp, 4);
+ tcharptr ->yOffset = (short) SignExtend(pxlfp, 4);
+ tcharptr ->where.isloaded = FALSE;
+ } else if (flag_byte & 4) {
+ /* fprintf(stderr,"Read extended short character preamble\n"); */
+
+ packet_length = ((long) flag_byte & 3) * 65536l +
+ (unsigned short) NoSignExtend(pxlfp, 2);
+ if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
+ Fatal("Bad character (%d) in PK-File\n",(int)car) ;
+
+ tcharptr = &(tfontptr->ch[car]);
+ tcharptr->where.address.fileOffset = pkloc;
+ /* set pkloc to end_of_packet */
+ pkloc += packet_length + 3;
+
+ tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3);
+/*
+ { register unsigned short t;
+ t = (unsigned short) NoSignExtend(pxlfp, 1);
+ tcharptr->tfmw = t * 65536l +
+ (unsigned short) NoSignExtend(pxlfp, 2);
+ }
+*/
+ /* horesc not used */
+ (void) NoSignExtend(pxlfp, 2) ;
+ tcharptr ->width = (unsigned short) NoSignExtend(pxlfp,2);
+ tcharptr ->height = (unsigned short) NoSignExtend(pxlfp,2);
+ tcharptr ->xOffset = (short) SignExtend(pxlfp, 2);
+ tcharptr ->yOffset = (short) SignExtend(pxlfp, 2);
+ tcharptr ->where.isloaded = FALSE;
+ } else {
+ /* fprintf(stderr,"<Read short character preamble@>\n"); */
+
+ packet_length = ((long)flag_byte & 3) * 256 +
+ NoSignExtend(pxlfp, 1) ;
+ if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
+ Fatal("Bad character (%d) in PK-File\n",(int)car) ;
+
+ tcharptr = &(tfontptr->ch[car]);
+ tcharptr->where.address.fileOffset = pkloc;
+ /* set pkloc to end_of_packet */
+ pkloc += packet_length + 2 ;
+
+ tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3);
+/*
+ { register unsigned short t;
+ t = (unsigned short) NoSignExtend(pxlfp, 1);
+ tcharptr->tfmw = t * 65536l +
+ (unsigned short) NoSignExtend(pxlfp, 2);
+ }
+*/
+ /* horesc not used */
+ (void) NoSignExtend(pxlfp, 1) ;
+ tcharptr ->width = (unsigned short) NoSignExtend(pxlfp,1);
+ tcharptr ->height = (unsigned short) NoSignExtend(pxlfp,1);
+ tcharptr ->xOffset = (short) SignExtend(pxlfp, 1);
+ tcharptr ->yOffset = (short) SignExtend(pxlfp, 1);
+ tcharptr ->where.isloaded = FALSE;
+ }
+
+ tcharptr->tfmw = (long)
+ ( tcharptr->tfmw * (double)tfontptr->s / (double) 0x100000 );
+
+ tcharptr->cw = (long)(((double)tcharptr->tfmw /
+ (double)hconv) + 0.5);
+
+ if (tcharptr->width > CHAR_WIDTH_LARGE ||
+ tcharptr->height > CHAR_HEIGTH_LARGE )
+ tcharptr->charsize = LARGE_SIZE;
+ else
+ tcharptr->charsize = SMALL_SIZE;
+
+#ifdef LJ
+/*
+printf("char=%d: this=%d, max_width=%d, this=%d,max_height=%d, this=%d,max_yoff=%d\n",
+ car, tcharptr->width, tfontptr->max_width,
+ tcharptr->height,tfontptr->max_height,
+ tcharptr->yOffset,tfontptr->max_yoff);
+*/
+ max(tfontptr->max_width, tcharptr->width);
+ max(tfontptr->max_height,tcharptr->height);
+ if (tcharptr->yOffset > 0 && (int)tfontptr->max_yoff < (int)tcharptr->yOffset)
+ tfontptr->max_yoff = tcharptr->yOffset;
+
+ if ((depth = tcharptr->height - tcharptr->yOffset) > max_depth)
+ max_depth = depth;
+#endif
+/*
+fprintf(stderr,"char=%d, yotcharptr=%lx, flag_byte=%d, font=%lx\n",car, tcharptr,flag_byte,tfontptr);
+*/
+ tcharptr->flag_byte = flag_byte;
+ fseek(pxlfp, (long) pkloc, 0);
+ flag_byte = skip_specials(&pkloc);
+
+ } /* end of while */
+#ifdef LJ
+tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
+ tfontptr->max_yoff+1;
+#endif
+
+/*
+printf("fontid=%d: max_width=%u, max_height=%d, max_yoff=%u\n",
+ tfontptr->plusid, tfontptr->max_width,
+ tfontptr->max_height, tfontptr->max_yoff);
+*/
+
+#else
+ if ( pxlfp == NO_FILE ) /* allow missing pxl files */
+ return;
+
+ gfin = pxlfp;
+ seekpost();
+ readpost();
+ if ((tfontptr->c != 0) && (checksum != 0) && (tfontptr->c != checksum))
+ Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d",
+ tfontptr->name, tfontptr->c, checksum);
+
+ for(i=FIRSTFNTCHAR; i<=LASTFNTCHAR; i++) {
+ if (char_exists[i]) {
+ tcharptr = &(tfontptr->ch[i]);
+ tcharptr->tfmw = (long)(((float)tfm_wd[i]*(float)tfontptr->s) /
+ (float)((long)1l<<20));
+ tcharptr->where.address.fileOffset = char_pointer[i];
+ }
+#ifdef LJ
+/* GF USER PLEASE CHECK IF THIS CODE WORKS
+ tfontptr->max_width = gf_font_max_m;
+ tfontptr->max_height = gf_font_max_n;
+ tfontptr->max_yoff = gf_font_min_n;
+*/
+#endif
+#endif
+/*****************************************************************************/
+/*if (tcharptr->charsize==LARGE_SIZE)
+ printf("%d:\t <%c> w=%d h=%d xO=%d yO=%d tfmw=%ld cw=%ld %d\n",
+ i,(char) i,
+ tcharptr->width,tcharptr->height,tcharptr->xOffset,tcharptr->yOffset,
+ tcharptr->tfmw, tcharptr->cw, (int)(tcharptr->charsize));
+ */
+/*****************************************************************************/
+ }
+ }
+
+
+unsigned char
+skip_specials( pkloc )
+long *pkloc;
+{
+ long i, j;
+ register unsigned char flag_byte;
+ do {
+ flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
+/*
+fprintf(stderr,"flagbyte = %d, pkloc=%ld\n",(int)flag_byte,*pkloc);
+*/
+
+ (*pkloc) ++;
+ if (flag_byte >= 240)
+ switch (flag_byte) {
+ case 240:
+ case 241:
+ case 242:
+ case 243 : {
+ i = 0 ;
+ for (j = 240; j <= (long)flag_byte; j++) {
+ i = 256 * i + NoSignExtend(pxlfp, 1) ;
+ (*pkloc) ++;
+ }
+ for (j = 1; j <= i; j++) {
+ (void) NoSignExtend(pxlfp, 1) ;
+ (*pkloc) ++;
+ }
+ break;
+ }
+ case 244 : {
+ i = NoSignExtend(pxlfp, 4);
+ (*pkloc) += 4;
+ break;
+ }
+ case 245 :
+ break;
+ case 246 :
+ break ;
+ case 247:
+ case 248:
+ case 249:
+ case 250:
+ case 251:
+ case 252:
+ case 253:
+ case 254:
+ case 255: {
+ Fatal("Unexpected flagbyte %d!\n",
+ (int)flag_byte) ;
+ }
+ }
+ } while (!((flag_byte < 240) || (flag_byte == PK_POST))) ;
+ return(flag_byte);
+}
+
+
+/*-->ReadPostAmble*/
+/**********************************************************************/
+/************************** ReadPostAmble ***************************/
+/**********************************************************************/
+/***********************************************************************
+ This routine is used to read in the postamble values. It
+ initializes the magnification and checks the stack height prior to
+ starting printing the document.
+***********************************************************************/
+void
+ReadPostAmble(load)
+bool load;
+{
+ FindPostAmblePtr (&postambleptr);
+ if (NoSignExtend(dvifp, 1) != POST)
+ Fatal ("POST missing at head of postamble");
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"got POST command\n");
+#endif
+ ppagep = NoSignExtend(dvifp, 4);
+ num = NoSignExtend(dvifp, 4);
+ den = NoSignExtend(dvifp, 4);
+ mag = NoSignExtend(dvifp, 4);
+ if ( usermag > 0 && usermag != mag )
+ Warning("DVI magnification of %ld over-ridden by user (%ld)",
+ mag, usermag );
+ if ( usermag > 0 )
+ mag = usermag;
+ hconv = DoConv(num, den, hconvRESOLUTION);
+ vconv = DoConv(num, den, vconvRESOLUTION);
+ (void) NoSignExtend(dvifp, 4); /* height-plus-depth of tallest page */
+ (void) NoSignExtend(dvifp, 4); /* width of widest page */
+ if (NoSignExtend(dvifp, 2) >= STACK_SIZE)
+ Fatal ("Stack size is too small");
+ (void) NoSignExtend(dvifp, 2); /* this reads the number of pages in */
+ /* the DVI file */
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"now reading font defs");
+#endif
+ if (load)
+ GetFontDef ();
+}
+
+
+/*-->LoadAChar*/
+/**********************************************************************/
+/***************************** LoadAChar ******************************/
+/**********************************************************************/
+void
+LoadAChar(c, ptr)
+long c;
+register struct char_entry *ptr;
+{
+ long *pr;
+ long bytes;
+
+ if (ptr->where.address.fileOffset == NONEXISTANT) {
+ ptr->where.isloaded = FALSE;
+ return;
+ }
+
+ OpenFontFile();
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr, "LoadAChar: <%c>(%ld) from file at pos %ld\n",
+ (char)c,c,ptr->where.address.fileOffset);
+#endif
+
+#ifdef USEPXL
+
+ fseek(pxlfp, ptr->where.address.fileOffset, 0);
+
+ if (fontptr->id == pk89) {
+#ifdef PARANOIA
+ unsigned char temp;
+ temp = (unsigned char) NoSignExtend(pxlfp, 1);
+
+ if ((int)(ptr->flag_byte) != (int)temp) {
+ fprintf(stderr,"font=%lx, ptr=%lx\n",fontptr,ptr);
+ Fatal("%d: oh boy! old flag %d, new flag %d, ptr=%lx\n",
+ (int)c,(int)(ptr->flag_byte),(int)temp,ptr);
+ }
+#endif
+
+ if ((ptr->flag_byte & 7) == 7) {
+ bytes = ((long) NoSignExtend(pxlfp, 4)) - 28;
+ fseek(pxlfp, ptr->where.address.fileOffset + 36, 0);
+/*
+fprintf(stderr,"bytes=%d, seeking at %ld\n",
+ bytes, ptr->where.address.fileOffset + 36);
+*/
+ } else if ((ptr->flag_byte & 4) == 4) {
+ bytes = ((long)ptr->flag_byte & 3)
+ * 65536l + NoSignExtend(pxlfp, 2) - 13;
+ fseek(pxlfp, ptr->where.address.fileOffset + 16, 0);
+ } else {
+ bytes = ((long)ptr->flag_byte & 3)
+ * 256 + NoSignExtend(pxlfp, 1) - 8;
+ fseek(pxlfp, ptr->where.address.fileOffset + 10, 0);
+ }
+ } else if (fontptr->id == id1002)
+ bytes = ((( (long)ptr->width + 7) >> 3) * (long) ptr->height);
+ else if (fontptr->id == id1001)
+ bytes = 4 * (((long)ptr->width + 31) >> 5) * (long)ptr->height;
+
+ if (bytes > 0) {
+ /* do NOT load Huge characters */
+ if ((bytes > HUGE_CHAR_PATTERN) && (fontptr->id != pk89)) {
+ qfprintf(stderr,"Huge Character <%c> (%ld Bytes)\n", (char)c, bytes);
+ ptr->charsize = HUGE_SIZE;
+ ptr->where.isloaded = FALSE;
+ } else {
+ if ( (pr = (long *)malloc( bytes )) == NULL )
+ Fatal("Unable to allocate %ld bytes for char <%c>\n",
+ bytes, (char)c);
+/*
+ * else fprintf(stderr,"allocating %ld bytes char <%c>(%d)\t at 0x%lx\n",
+ * bytes, (char)c,(int)c,pr);
+ */
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,
+ "Allocating Char <%c>, FileOffset=%lX, Bytes=%ld (%d) <%d>\n",
+ (char) c, ptr->where.address.fileOffset, bytes,
+ (int)bytes, (unsigned int)bytes);
+#endif
+ allocated_storage += bytes;
+ fread(pr, 1, (int) bytes , pxlfp);
+ ptr->where.address.pixptr = pr;
+ }
+ }
+#else
+ fseek(gfin, ptr->where.address.fileOffset, 0);
+ gettochar();
+ readbits();
+ if (num_bytes > HUGE_CHAR_PATTERN)
+ ptr->charsize = HUGE_SIZE;
+#endif
+ ptr->where.isloaded = TRUE;
+ if (ptr->charsize != SMALL_SIZE
+#ifdef LJ
+ /* we might have problems at the edge of the paper with diff. sized characters
+ * the correct treatment would be to check whether the bounding box of
+ * tfontptr is within the paper relative to the current position
+ */
+ || fontptr->max_height > CHAR_HEIGTH_LARGE
+ || (rasterfont[fontptr->plusid])
+#endif
+ )
+ return;
+
+ EmitChar(c, ptr);
+#ifdef USEPXL
+ /* we should really free the space used by the PXL data after this
+ point, but it is not large, and besides, we may want to be
+ more clever in the future, about sending bitmaps. So keep
+ the data around */
+#endif
+}
+/*-->SetChar*/
+/**********************************************************************/
+/***************************** SetChar ******************************/
+/**********************************************************************/
+void
+SetChar(c, command, PassNo, do_posn,in_string)
+long c;
+short command;
+int PassNo;
+bool do_posn,in_string;
+{
+ register struct char_entry *ptr; /* temporary char_entry pointer */
+ bool pos_after = FALSE;
+
+ ptr = &(fontptr->ch[c]);
+ if (!((ptr->where.isloaded) || (ptr->charsize == HUGE_SIZE)))
+ LoadAChar(c, ptr);
+ if (PassNo == 0)
+ return;
+
+ if (do_posn) {
+#ifdef IBM3812
+ if (CharStringPos>0) {
+ fprintf(stderr,"!!!! That should never happen!!!\n");
+ CharStringOut;
+ }
+#endif
+ SetPosn(h, v);
+ }
+
+/*
+printf("(%d) hh=%ld (+%ld/+%ld), h=%ld, xh=%ld,xhh=%ld, [%ld|%ld] ->%d\n",
+ (int)do_posn,hh,(long)ptr->cw,(long)ptr->cw*(long)hconv,h,
+ PIXROUND(h, hconv),
+ PIXROUND(hh, hconv),
+ labs((hh-h)),hconv,(labs((hh-h))>hconv)
+ );
+*/
+
+ if (in_string && (labs((hh-h))>hconv)) {
+#ifdef IBM3812
+ CharStringOut;
+#endif
+ SetPosn(h, v);
+ }
+
+/*
+fprintf(stderr,"raster?=%d - last_ry=%d, last_rx=%d,mmax-height=%d\n",
+ (int)last_ry < fontptr->max_height, (int)last_ry,(int)last_rx,
+ (int)fontptr->max_height);
+*/
+
+ if (fontptr->font_file_id != NO_FILE) { /* ignore missing fonts */
+ if (ptr->charsize != SMALL_SIZE
+#ifdef LJ
+ /* the LaserJet cannot printcahracters where the bounding box lies outside the
+ * paper edge. Missing: right paper edge
+ */
+ || last_ry < (int)fontptr->max_height
+ || fontptr->max_height > CHAR_HEIGTH_LARGE
+ || (rasterfont[fontptr->plusid])
+#endif
+ ) {
+ int tmp;
+ char sign;
+
+#ifdef LJ
+ if (!do_posn) {
+ SetPosn(h, v);
+ }
+#ifdef USEPXL
+ tmp = (int) -ptr->yOffset;
+#else
+ tmp = (int) num_rows-y_offset;
+#endif
+ if (tmp != 0) {
+ if (tmp < 0) {
+ sign = '-'; tmp = -tmp;
+ } else
+ sign = '+';
+ EMIT(outfp, "\033*p%c%dY", sign, tmp);
+ }
+#ifdef USEPXL
+ tmp = (int) -ptr->xOffset;
+#else
+ tmp = (int) -x_offset;
+#endif
+ if (tmp != 0) {
+ if (tmp < 0) {
+ sign = '-'; tmp = -tmp;
+ } else
+ sign = '+';
+ EMIT(outfp, "\033*p%c%dX", sign, tmp);
+ }
+#endif
+#ifdef IBM3812
+ CharStringOut;
+#endif
+#ifdef DEBUG
+ if (Debug)
+#ifndef vms
+ fprintf(stderr,"Raster character <%c> %hd\n", (char) c,(short)c);
+#else
+ fprintf(stderr,"Raster character <%c> %d\n", (char) c,(short)c);
+#endif
+#endif
+ RasterChar(ptr);
+ pos_after = TRUE;
+ } else {
+ unsigned char cc;
+ cc = VisChar((char)c);
+#ifdef IBM3812
+#ifdef USEPXL
+ if ( ptr->yyOffset || (!in_string) ) {
+ CharStringOut;
+ MoveVert(ptr->yyOffset);
+ sprintf(PMPformat, "\01%c", cc);
+ PMPout(2, PMPformat);
+ MoveVert((int)-(ptr->yyOffset));
+ } else {
+#endif
+ if (CharStringPos==CHARSTRINGMAX)
+ CharStringOut;
+
+ CharString[CharStringPos] = cc;
+ CharStringPos++;
+#ifdef USEPXL
+ }
+#endif
+#endif
+#ifdef LJ
+#define TRANSPARENTCHAR(ch) \
+ if ((ch == 0l) || (ch >= 7l && ch <= 15l) || (ch == 27l)) \
+ EMIT(outfp, "\033&p1X%c", (unsigned char)ch); \
+ else EMITC((unsigned char)ch)
+#ifdef USEPXL
+ if (ptr->yyOffset) {
+#ifndef vms
+ EMIT(outfp, "\033*p+%hdY", ptr->yyOffset);
+ TRANSPARENTCHAR(cc);
+ EMIT(outfp, "\033*p-%hdY", ptr->yyOffset); /* GUGUGU 255 */
+#else
+ EMIT(outfp, "\033*p+%dY", ptr->yyOffset);
+ TRANSPARENTCHAR(cc);
+ EMIT(outfp, "\033*p-%dY", ptr->yyOffset); /* GUGUGU 255 */
+#endif
+ } else
+#endif
+/* EMITC( (unsigned char)c);*/
+ { TRANSPARENTCHAR(cc);}
+#endif
+ }
+ hh += (long) ptr->cw*hconv;
+ }
+ if (command <= SET4)
+ h += ptr->tfmw;
+ if (pos_after) {
+ SetPosn(h, v);
+ }
+}
+
+
+void
+DoBop()
+{
+ struct font_entry *p;
+#ifdef LJ
+ register short i;
+ if (fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
+ for (i = 0; i < HANDLE_MAX_FONTS; i++)
+ rasterfont[i] = FALSE;
+ }
+ fonts_used_on_this_page = 0;
+#endif
+ for (p = hfontptr; p; p = p->next) {
+ p->used_on_this_page = FALSE;
+ }
+}
+
+
+/*-->SetFntNum*/
+/**********************************************************************/
+/**************************** SetFntNum *****************************/
+/**********************************************************************/
+void
+SetFntNum(k, Emitting)
+long k;
+bool Emitting;
+/* this routine is used to specify the font to be used in printing future
+ characters */
+{
+#ifdef LJ
+ static unsigned short plusid = 0;
+#endif
+ fontptr = hfontptr;
+ while ((fontptr != NULL) && (fontptr->k != k))
+ fontptr = fontptr->next;
+ if (fontptr == NULL)
+ Fatal("font %ld undefined", k);
+ if (Emitting && (fontptr->font_file_id != NO_FILE) ) {
+ if (!fontptr->used_on_this_page) {
+ fontptr->used_on_this_page = TRUE;
+#ifdef LJ
+ if (++fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
+ qfprintf(stderr,"this is the %d. font on this page!",
+ fonts_used_on_this_page);
+ qfprintf(stderr," (max = %d) rastering characters!\n",
+ MAX_FONTS_PER_PAGE);
+ rasterfont[fontptr->plusid] = TRUE;
+ }
+#endif
+ }
+
+ /* activate font */
+#ifdef IBM3812
+ sprintf(PMPformat, "\323%c", (unsigned char)fontptr->plusid);
+ PMPout(2, PMPformat);
+#endif
+#ifdef LJ
+ if (!rasterfont[fontptr->plusid]) {
+ if (fontptr->plusid>0) EMIT(outfp, "\033(%dX", fontptr->plusid);
+ else EMIT(outfp, "\033(X");
+ }
+/* else printf("I am doing rasterfont for plusid=%d instead\n",
+ fontptr->plusid);
+*/
+#endif
+ }
+#ifdef LJ /* reassignment of printer font id 0.48 */
+ else if (fontptr->font_file_id != NO_FILE) {
+ if (fontptr->ncdl == 0) {
+#ifdef DEBUG
+ if (Debug)
+ printf("Changing plusid from %d to %d\n", fontptr->plusid, (int)plusid);
+#endif
+ fontptr -> plusid = plusid;
+ plusid ++;
+ }
+ }
+#endif
+}
+
+
+/*-->SetPosn*/
+/**********************************************************************/
+/***************************** SetPosn ******************************/
+/**********************************************************************/
+void /* output a positioning command */
+SetPosn(x, y)
+long x, y;
+{
+ int rx, ry;
+ rx = (int)PIXROUND(x, hconv) + x_goffset;
+ ry = (int)PIXROUND(y, vconv) + y_goffset;
+
+/*
+* fprintf(stderr,"setposn to %ld/%ld, %d/%d\n",x,y,rx,ry);
+*/
+
+#ifdef IBM3812
+ PMPcont(3);
+ PMPoutC('\340');
+ EMITWORD(LARGER(rx,0));
+
+ if (last_ry != ry) { /* necessary to set new y-position */
+ PMPcont(3);
+ PMPoutC('\341');
+ EMITWORD(LARGER(ry,0));
+ }
+#endif
+#ifdef LJ
+ if (last_ry != ry) /* necessary to set new y-position */
+ EMIT(outfp, "\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0));
+ else
+ EMIT(outfp, "\033*p%dX", LARGER(rx,0));
+#endif
+
+ last_ry = ry; /* last y-position on output device */
+ last_rx = rx; /* last x-position on output device */
+/*
+ * must know where device "really" is horizontally, for rel. posning.
+ * (maybe in the future), but we always use direct positioning for
+ * vertical movement.
+ */
+ /* hh = rx * hconv; */
+ hh = x;
+ vv = y;
+/*
+ * fprintf(stderr,"DoPosn: x=%ld, y=%ld, rx=%d, ry=%d, hh=%ld, vv=%ld\n",
+ * x,y,rx,ry,hh,vv);
+ */
+}
+
+
+#ifdef IBM3812
+/*-->PMPLine*/
+/**********************************************************************/
+/***************************** PMPLine ******************************/
+/**********************************************************************/
+void /* drawing lines on the 3812 using PMP vector commands */
+PMPLine(w, y, x)
+int w, y, x;
+{
+
+ if ((w == 0) || ((x == 0) && (y == 0)))
+ return;
+
+/*
+fprintf(stderr,"w=%d / %d - %d, y=%d / %d - %d, x=%d / %d - %d\n",
+ w,(char)(w & 0xff),(int)((signed_char)(w & 0xff)),
+ y,(char)(y & 0xff),(int)((signed_char)(y & 0xff)),
+ x,(char)(x & 0xff),(int)((signed_char)(x & 0xff)));
+*/
+
+ if ( (((signed_char)(x & 0xff)) == x ) &&
+ ( ((signed_char)(y & 0xff)) == y ) ) {
+ PMPcont(6);
+ PMPout(1, "\370");
+ EMITWORD(3); /* length of vector */
+ PMPoutC((unsigned char)(0x80 | 0x00 | (unsigned char) w));
+ PMPoutC((signed_char)(y & 0xff));
+ PMPoutC((signed_char)(x & 0xff));
+/*
+ fprintf(stderr,"F8 00 03: w=%d, x=%d(%d-%.2X), y=%d(%d-%.2X),\n",
+ w,x,(char)(x & 0xff),(signed_char)(x & 0xff),
+ y,(char)(y & 0xff),(signed_char)(y & 0xff));
+*/
+
+ } else {
+ PMPcont(8);
+ PMPout(1, "\370");
+ EMITWORD(4 + 1); /* length of vector */
+ PMPoutC((unsigned char)(0xC0 | 0x00 | (unsigned char) w));
+ EMITWORD(y);
+ EMITWORD(x);
+/*
+ fprintf(stderr,"F8 00 05: w=%d, x=%d, y=%d,\n", w,x,y);
+*/
+ }
+}
+
+
+#endif
+/*-->SetRule*/
+/**********************************************************************/
+/***************************** SetRule ******************************/
+/**********************************************************************/
+void /* this routine will draw a rule */
+SetRule(a, b, Set)
+long a, b;
+int Set;
+{
+ long xx, yy;
+#ifdef IBM3812
+ short hor_offset, vert_offset, ll;
+#endif
+ if ( a > 0 && b > 0 ) {
+ SetPosn(h, v); /* lower left corner */
+ xx = (long)PIXROUND(b, hconv); /* width */
+ yy = (long)PIXROUND(a, vconv); /* height */
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"Rule xx=%ld, yy=%ld\n", xx, yy);
+#endif
+
+#ifdef IBM3812
+ hor_offset = (short)(last_ry - yy);
+ if (hor_offset < 0) yy += hor_offset;
+ if (last_rx < 0) xx += last_rx;
+
+ if (Landscape) {
+ if (last_ry > MAX_PAGE_WIDTH) yy += MAX_PAGE_WIDTH-last_ry;
+ hor_offset = (short)(MAX_PAGE_HEIGHT - (last_rx + xx));
+ } else {
+ if (last_ry > MAX_PAGE_HEIGHT) yy += MAX_PAGE_HEIGHT-last_ry;
+ hor_offset = (short)(MAX_PAGE_WIDTH - (last_rx + xx));
+ }
+ if (hor_offset < 0) xx += hor_offset;
+
+ if ((xx > 31) && (yy > 31)) {
+/*
+ * fill area by multiple lines (kind of a mess)
+ * process for simplicity always horizontally
+ */
+
+/* printf("large box: w=%d, x=%d, y=%d\n",(int)yy,(int)xx,0);*/
+
+ hor_offset = HOR_HALF(30);
+ MoveHor(hor_offset);
+ vert_offset = VERT_HALF(30);
+ MoveVert(-vert_offset);
+ ll = (short)xx - 30;
+
+ for (; yy > 30; yy -= 30) {
+ PMPLine(30, 0, ll);
+ MoveHor(-ll);
+ MoveVert(-30);
+ }
+
+ hor_offset = -hor_offset + HOR_HALF(yy);
+ MoveHor(hor_offset);
+ vert_offset = (vert_offset - 30) + VERT_HALF(yy);
+ MoveVert(-vert_offset);
+
+ PMPLine((int)yy, 0, (int)(xx - yy));
+
+ } else if ( (yy < xx) && (xx > 0) ) {
+
+/* printf("hori rule: w=%d, x=%d, y=%d\n",(int)yy,(int)(xx-yy),0);*/
+
+ hor_offset = HOR_HALF(yy);
+ vert_offset = VERT_HALF(yy);
+
+ MoveHor(hor_offset);
+ MoveVert(-vert_offset);
+
+ PMPLine((int)yy, 0, (int)(xx - yy));
+ } else if ( (xx < yy) && (yy > 0)) {
+
+ hor_offset = HOR_HALF(xx);
+ vert_offset = VERT_HALF(xx);
+/*
+ printf("move: x=%d, y=%d\n",hor_offset,-vert_offset);
+ printf("vert rule: w=%d, x=%d, y=%d\n",(int)xx,0,(int)-(yy-xx));
+*/
+ MoveHor(hor_offset);
+ MoveVert(-vert_offset);
+
+ PMPLine((int)xx, (int)-(yy - xx), 0);
+ } else if (xx == yy) {
+ short y0; /* small square box!! */
+
+ y0 = (short)yy / 2;
+ hor_offset = HOR_HALF(y0);
+ MoveHor(hor_offset);
+ vert_offset = VERT_HALF(y0);
+ MoveVert(-vert_offset);
+ ll = (short)xx - y0;
+
+ PMPLine((int)y0, 0, ll);
+
+ hor_offset = -(ll + hor_offset);
+ vert_offset = (y0 - vert_offset);
+
+ yy -= (long)y0;
+ hor_offset += HOR_HALF(yy);
+ MoveHor(hor_offset);
+ vert_offset += VERT_HALF(yy);
+ MoveVert(-vert_offset);
+
+ PMPLine((int)yy, 0, (int)xx - yy);
+ }
+#endif
+#ifdef LJ
+ if (last_ry + 1 < yy) yy = last_ry + 1;
+ if (last_rx < 0) xx += last_rx;
+
+ if (((int)pgsiz_dots >0) && ((int)last_ry > (int)pgsiz_dots))
+ yy += (long)pgsiz_dots - (long)last_ry;
+
+ if ((yy>0) && (xx>0))
+ EMIT(outfp, "\033*p-%ldY\033*c%lda%ldbP", yy - 1, xx, yy);
+#endif
+ last_ry = UNKNOWN; /* next time full positioning */
+ }
+ if (Set)
+ h += b;
+}
+
+
+/*-->SetString*/
+/**********************************************************************/
+/***************************** SetString ****************************/
+/**********************************************************************/
+void
+SetString(firstch, PassNo) /* read and set a consecutive string of chars */
+short firstch;
+int PassNo;
+{
+ short c;
+ register unsigned short i;
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr, "SetString ");
+#endif
+ for (i = 0, c = firstch; c >= SETC_000 && c <= SETC_127; i++) {
+#ifdef DEBUG
+ if (Debug)
+ fprintf (stderr, "%d ", c);
+#endif
+ SetChar((long)c, c, PassNo, (bool)(i==0),TRUE);
+ c = (short) NoSignExtend(dvifp, 1);
+ }
+ fseek(dvifp, -1l, 1); /* backup one character */
+#ifdef IBM3812
+ CharStringOut;
+#endif
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr, "...SetString\n");
+#endif
+}
+
+#ifndef ARITHMETIC_RIGHT_SHIFT
+long signTab[5] = {0,0x00000080,0x00008000,0x00800000,0x00000000};
+long extendTab[5] = {0,0xffffff00,0xffff0000,0xff000000,0x00000000};
+#endif
+
+/*-->SignExtend*/
+/**********************************************************************/
+/**************************** SignExtend ****************************/
+/**********************************************************************/
+long
+SignExtend(fp, n) /* return n byte quantity from file fd */
+register FILE *fp; /* file pointer */
+register int n; /* number of bytes */
+{
+ int n1; /* number of bytes */
+ long x,x0; /* number being constructed */
+ x = getc(fp); /* get first (high-order) byte */
+ n1 = n--;
+ while (n--) {
+ x <<= 8;
+ x |= getc(fp);
+ }
+/*
+ * NOTE: This code assumes that the right-shift is an arithmetic, rather
+ * than logical, shift which will propagate the sign bit right. According
+ * to Kernighan and Ritchie, this is compiler dependent!
+ */
+
+/*
+ x0 = x;
+ */
+
+#ifdef ARITHMETIC_RIGHT_SHIFT
+ x <<= 32 - 8 * n1;
+ x >>= 32 - 8 * n1; /* sign extend */
+#else
+ if (x & signTab[n1]) x |= extendTab[n1];
+#endif
+
+/*
+ fprintf(stderr,"\tSignExtend(fp,%d)=%X, was=%X,%d\n", n1, x,x0,x0&signTab[n1]);
+ */
+
+#ifdef DEBUG
+ if (Debug)
+ fprintf(stderr,"\tSignExtend(fp,%d)=%X\n", n1, x);
+#endif
+ return(x);
+}
+
+
+/*-->SkipFontDef*/
+/**********************************************************************/
+/**************************** SkipFontDef ***************************/
+/**********************************************************************/
+void
+SkipFontDef()
+{
+ int a, l;
+ char n[STRSIZE];
+
+ (void) NoSignExtend(dvifp, 4);
+ (void) NoSignExtend(dvifp, 4);
+ (void) NoSignExtend(dvifp, 4);
+ a = (int) NoSignExtend(dvifp, 1);
+ l = (int) NoSignExtend(dvifp, 1);
+ GetBytes(dvifp, n, a + l);
+}
+
+
+/*-->Warning*/
+/**********************************************************************/
+/***************************** Warning ******************************/
+/**********************************************************************/
+void /* issue a warning */
+Warning(fmt, a, b, c, d)
+char *fmt; /* format */
+char *a, *b, *c, *d; /* arguments */
+{
+#ifndef vms
+ G_errenc = 1;
+#else
+ G_errenc = (SS$_ABORT | STS$M_INHIB_MSG); /* no message on screen */
+#endif
+ if ( G_nowarn || G_quiet )
+ return;
+
+ fprintf(stderr, "warning : ");
+ fprintf(stderr, fmt, a, b, c, d);
+ fprintf(stderr, "\n");
+}
+
+void
+PutWord(w)
+int w;
+{
+ EMITC((char)(w >> 8) & 0xff);
+ EMITC((char)w & 0xff);
+}
+
+
+#ifdef IBM3812
+/*-->PMPout*/
+/*****************************************************************************/
+/* This routine produces the PMP-envelopes for the 3812. Its semantics are:
+
+ first arg == 0 ... flush buffer
+ first arg == -1 ... number of bytes specified in the second argument
+ have to be continuous, that is they must not
+ be disrupted by ENTER PMP etc.
+ first arg > 0 output first arg bytes
+
+ If arg2 > OUTBUFSIZE ... flush buffer,
+ switch to unbuffered mode
+ (dont't collect PMP commands)
+ If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
+ block will fit into buffer
+ otherwise ..... block will fit into buffer
+
+ Buffering is done to reduce the ENTER PMP-commands. Initially
+ the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
+ necessary to enter PMP mode. The ENTER-PMP-command contains the
+ number of bytes that will be interpreted as PMP-commands. In the
+ most naive approach for each primitive command (eg. set cursor) you
+ have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
+ favourable to collect as many PMP commands as possible in one envelope. */
+/*****************************************************************************/
+void
+PMPout(l, s)
+char *s;
+int l;
+{
+ static char buffer[OUTBUFSIZE];
+ static unsigned short bp = 0; /* range 0..OUTBUFSIZE */
+ static long continuous = 0l;
+ static bool buffered = TRUE;
+
+ if (l == 0) {
+ if (bp == 0)
+ return;
+ EMIT(outfp, "\033[C%c%c", (unsigned char)(bp & 0xFF),
+ (unsigned char)(bp >> 8));
+ EMITB((int)bp, buffer);
+ bp = 0;
+ return;
+ }
+ if (l == -1) {
+ continuous = (long)s;
+ if (continuous + (long)bp + 5l > (long) OUTBUFSIZE)
+ PMPflush;
+ buffered = (bool) ((continuous + 5l <= (long) OUTBUFSIZE));
+ if (!buffered) {
+ EMIT(outfp, "\033[C%c%c",
+ (unsigned char)(continuous & 0xFF),
+ (unsigned char)((continuous >> 8) & 0xFF));
+ }
+ return;
+ }
+ if (buffered) {
+ register int i;
+ if ( ((long)l + bp) > OUTBUFSIZE)
+ PMPflush;
+ for (i = 0; i < l; i++)
+ buffer[bp+i] = s[i];
+ bp += (unsigned short)l;
+ } else {
+ EMITB((int)l, s);
+ buffered = (bool) ((continuous -= (long)l) <= 0) ;
+ }
+}
+
+
+void
+PMPoutC(c)
+char (c);
+{
+ PMPout(1, &c);
+}
+
+
+#endif
+#ifdef MSDOS
+/*-->AssureBinary*/
+/**********************************************************************/
+/*************************** AssureBinary *****************************/
+/**********************************************************************/
+/* This procedure is both DOS AND MSC dependent. The MSC file open on */
+/* a device ignores the 'binary' of the "wb" parameter and opens the */
+/* file in ascii mode. This procedure sets the file f to binary mode */
+/* if it is connected to a device that is not console input or output */
+/* or the null device. For other operating systems this routine is */
+/* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
+/**********************************************************************/
+void
+AssureBinary(f)
+FILE *f;
+{
+ union REGS regs; /* registers for bios call */
+
+ regs.h.ah = (unsigned char) 0x44; /* IOCTL */
+ regs.h.al = (unsigned char) 0x00; /* get device information */
+ regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */
+ intdos(&regs, &regs); /* call DOS interrupt */
+ /* ---> result in DX */
+
+ if ( (regs.h.dl & 0x80) /* file handle points to a device */
+ && !(regs.h.dl & 0x07) ) /* neither console i/o or null */ {
+
+ regs.h.dl |= 0x20; /* set BINARY bit in device info */
+
+ regs.h.ah = (unsigned char) 0x44; /* IOCTL */
+ regs.h.al = (unsigned char) 0x01; /* set device information*/
+ regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */
+ regs.h.dh = (unsigned char) 0x00; /* clear DH */
+ intdos(&regs, &regs); /* call DOS interrupt */
+ }
+}
+
+
+#endif
+
+#ifdef USEPXL
+bool getbit ();
+unsigned char getnyb ();
+long pk_packed_num ();
+
+
+#define PKBYTE *pkloc; pkloc ++
+#define OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++
+
+unsigned char bitweight, inputbyte ;
+unsigned char dyn_f ;
+unsigned char *pkloc;
+int repeatcount;
+
+void /* <Read and translate raster description@>*/
+PkRaster(ce, raster)
+struct char_entry *ce;
+bool raster;
+{
+ int rp;
+ int current_line;
+ int wordwidth ;
+ bool turnon;
+ unsigned short nbpl;
+ long rowsleft, word, wordweight, hbit, count, i, j, tl;
+ long row[101] ;
+ unsigned char raster_line_buf[BYTES_PER_PIXEL_LINE];
+ unsigned short bp;
+
+
+ if (ce->charsize == HUGE_SIZE)
+ Fatal( "cannot process currently PK font patterns of that size!\n");
+
+
+ current_line = 0;
+ pkloc = (unsigned char *)ce->where.address.pixptr;
+ dyn_f = (unsigned char)(ce->flag_byte >> 4);
+ turnon = (bool)((ce->flag_byte & 8) == 8);
+ wordwidth = (int)(ce->width + 31) >> 5 ;
+ nbpl = ((int)(ce->width) + 7) >> 3;
+
+ bitweight = 0 ;
+ if (dyn_f == 14) {
+ /*printf("<Get raster by bits@>\n");*/
+ for (i = 1; i <= (long)ce->height; i++) {
+ word = 0 ;
+ wordweight = 31 ;
+ bp = 0; /* Sowa */
+
+#ifdef DRAWGLYPH
+ printf(" |");
+#endif
+ for (j = 1; j <= (long) ce->width; j++) {
+ bool getbit;
+ /* bp = 0; SOWA/
+/*******************************************begin Getbit *********/
+ bitweight /= 2 ;
+ if ( bitweight == 0 ) {
+ inputbyte = PKBYTE ;
+ bitweight = 128 ;
+ }
+ getbit = (bool)
+ ( inputbyte >= bitweight ) ;
+ if ( getbit )
+ inputbyte -= bitweight ;
+/*********************************************end Getbit *********/
+
+ if (getbit)
+ word += power[wordweight] ;
+
+ wordweight --;
+ if (wordweight == -1) {
+
+#ifdef DRAWGLYPH
+ { int k;
+ for (k=31; k>=0; k--) {
+ if ((power[k] & word)!=0) printf("M");
+ else printf(".");
+ }
+ }
+#endif
+
+ OUTCHAR((word >> 24 & 0xFF));
+ OUTCHAR((word >> 16 & 0xFF));
+ OUTCHAR((word >> 8 & 0xFF));
+ OUTCHAR((word & 0xFF));
+
+ word = 0 ;
+ wordweight = 31 ;
+ }
+ }
+ if (wordweight < 31) {
+#ifdef COMMENT
+#ifdef DRAWGLYPH
+ { int k;
+ for (k=15; k>=0; k--) {
+ if ((power[k] & word)!=0) printf("Z");
+ else printf(":");
+ }
+ }
+ printf("|\n ----|");
+#endif
+#endif
+
+ for (j = 3; j >= (wordwidth * 4 - (long)nbpl);
+ j--) {
+
+ OUTCHAR(((word >> (j << 3)) & 0xff));
+
+#ifdef DRAWGLYPH
+ { int k;
+ for (k=7; k>=0; k--) {
+ if ((power[k] & ((word >> (j << 3)) & 0xff))!=0) printf("M");
+ else printf(".");
+ }
+ }
+#endif
+
+ }
+ }
+
+ if (raster) {
+ RasterLine(ce, (unsigned int)nbpl,
+ current_line, raster_line_buf);
+ current_line++;
+ } else
+ EMITL(bp, raster_line_buf);
+
+#ifdef DRAWGLYPH
+ printf("|\n");
+#endif
+ }
+ } else {
+ /* printf("@<Create normally packed raster@>\n"); */
+ rowsleft = (long) ce->height ;
+ hbit = (long) ce->width ;
+ repeatcount = 0 ;
+ wordweight = 32 ;
+ word = 0 ;
+ rp = 1 ;
+ while ( rowsleft > 0 ) {
+ count = pk_packed_num() ;
+ bp = 0;
+
+ while (count > 0) {
+ if ((count < wordweight) && (count < hbit)) {
+ if (turnon)
+ word +=
+ gpower[wordweight] -
+ gpower[wordweight - count] ;
+
+ hbit -= count ;
+ wordweight -= count ;
+ count = 0 ;
+ } else if ((count >= hbit) && (hbit <=
+ wordweight)) {
+
+ if (turnon)
+ word +=
+ gpower[wordweight] -
+ gpower[wordweight - hbit] ;
+
+ row[rp] = word ;
+
+ /* printf(" @<Send row@> \n");*/
+ for (i = 0; i <= (long) repeatcount; i++) { int ii;
+
+#ifdef DRAWGLYPH
+ printf("*** |");
+#endif
+ for (ii = 1; ii < wordwidth; ii++) {
+ tl = row[ii];
+
+ OUTCHAR((tl >> 24 & 0xFF));
+ OUTCHAR((tl >> 16 & 0xFF));
+ OUTCHAR((tl >> 8 & 0xFF));
+ OUTCHAR((tl & 0xFF));
+
+#ifdef DRAWGLYPH
+ { int k;
+ for (k=31; k>=0; k--) {
+ if ((power[k] & row[ii])!=0) printf("M");
+ else printf(".");
+ }
+ }
+#endif
+ }
+ tl = row[wordwidth];
+ for (j = 3; j >= (wordwidth *4 - (long)nbpl);
+ j--) {
+
+ OUTCHAR(((tl >> (j << 3)) & 0xff));
+
+#ifdef DRAWGLYPH
+ { int k;
+ for (k=7; k>=0; k--) {
+ if ((power[k] & ((tl >> (j << 3)) & 0xff))!=0) printf("M");
+ else printf(".");
+ }
+ }
+#endif
+ }
+
+ if (raster) {
+ RasterLine(ce,
+ (unsigned int)nbpl,
+ current_line,
+ raster_line_buf);
+ current_line++;
+ } else
+ EMITL(bp, raster_line_buf);
+
+ bp = 0;
+
+#ifdef DRAWGLYPH
+ printf("| ");
+ for (j=1;j<=(long)wordwidth;j++) printf("%02lX/",row[j]);
+ printf(" raster=%d\n",raster);
+#endif
+ }
+
+ rowsleft -= (long)repeatcount + 1 ;
+ repeatcount = 0 ;
+ rp = 1 ;
+ word = 0 ;
+ wordweight = 32 ;
+ count -= hbit ;
+ hbit = (long)ce->width ;
+ } else {
+ if (turnon) word += gpower[wordweight] ;
+ row[rp] = word ;
+ rp = rp + 1 ;
+ word = 0 ;
+ count -= wordweight ;
+ hbit -= wordweight ;
+ wordweight = 32 ;
+ }
+ } /* .....while count > 0 */
+ if (turnon)
+ turnon = FALSE;
+ else
+ turnon = TRUE;
+ } /* ...... rowsleft > 0 */
+ if ((rowsleft != 0) || (hbit != (long)ce->width))
+ Fatal("Bad pk file----more bits than required!\n");
+ } /* .... create normally packed raster */
+}
+
+
+unsigned char getnyb ()
+{
+ register unsigned char temp ;
+ if ( bitweight == 0 ) {
+ inputbyte = PKBYTE ;
+ bitweight = 16 ;
+ }
+ temp = inputbyte / bitweight ;
+ inputbyte -= temp * bitweight ;
+ bitweight /= 16 ;
+ return ( temp ) ;
+}
+
+
+long
+pk_packed_num ()
+{ /*@<Packed number procedure@>= */
+ register int i;
+ long j;
+
+ i = (int)getnyb();
+ if (i == 0) {
+ do {
+ j = (long)getnyb();
+ i++;
+ } while (j == 0) ;
+ while (i > 0) {
+ j = j * 16 + (long)getnyb() ;
+ i--;
+ };
+ return (j - 15 + (13 - dyn_f) * 16 + dyn_f) ;
+ } else if (i <= (int)dyn_f) {
+ return ((long)i);
+ } else if (i < 14) {
+ return ((i-(long)dyn_f - 1) * 16 + (long)getnyb() + dyn_f + 1);
+ } else {
+ if (i == 14) {
+ repeatcount = (int) pk_packed_num() ;
+ } else {
+ repeatcount = 1 ;
+ }
+ /* printf("repeatcount = [%d]\n",repeatcount); */
+ return (pk_packed_num()) ; /* tail end recursion !! */
+ }
+}
+#endif
+
+#ifndef USEPXL
+void bad_gf(n)
+ int n;
+{
+ Fatal("Bad gf file, case %d\n",n); /* See gf.c */
+}
+#endif
+/*-->FormFeed*/
+/**********************************************************************/
+/***************************** FormFeed ******************************/
+/**********************************************************************/
+void
+FormFeed()
+{
+
+#ifdef IBM3812
+ unsigned short pages;
+ if ( (ndone == 0) && (FirstAlternate)){
+ for (pages = 1; pages < ncopies; pages++) {
+ PMPout(2, "\321\300"); /* PMP-command xD1C0 */
+ }
+ PMPout(2, "\321\100"); /* PMP-command xD140 */
+ } else {
+ for (pages = 1; pages < ncopies; pages++){
+ PMPout(2, "\321\200"); /* PMP-command xD180 */
+ }
+ PMPout(2, "\321\0"); /* PMP-command xD100 */
+ }
+#endif
+#ifdef LJ
+ EMITC('\f');
+#endif
+}
diff --git a/systems/msdos/dviware/dvilj4/emu387 b/systems/msdos/dviware/dvilj4/emu387
new file mode 100644
index 0000000000..fa2700b379
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/emu387
Binary files differ
diff --git a/systems/msdos/dviware/dvilj4/findfile.c b/systems/msdos/dviware/dvilj4/findfile.c
new file mode 100644
index 0000000000..e1126c9cc9
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/findfile.c
@@ -0,0 +1,121 @@
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+int stat();
+char *path_segment();
+
+bool
+findfile(path,n,fontmag,name)
+char path[STRSIZE]; /* PIXEL path */
+char n[STRSIZE]; /* name of font */
+long fontmag; /* magnification */
+char name[STRSIZE]; /* full name of PXL file (returned) */
+{
+ char local_path[STRSIZE];
+ char *pathpt;
+ struct stat s;
+ int rc = -1;
+ int resolution, i;
+
+ resolution = (int)(fontmag/5.0 +0.5) ;
+
+ for(i=0; (pathpt=path_segment((bool)(i==0),path,local_path))!=NULL;i++)
+ {
+#ifdef USEPXL
+ sprintf(name,"%s/%d/%s.pk",pathpt,resolution,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s/%d/%s.pxl",pathpt,resolution,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s.pk",n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s.pxl",n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s/%ld/%s.pk",pathpt,fontmag,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s/%ld/%s.pxl",pathpt,fontmag,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+#ifndef MSDOS
+ sprintf(name,"%s/%d/%s.pk",pathpt,resolution,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s/%d/%s.pxl",pathpt,resolution,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+#endif
+ sprintf(name,"%s/%d/%s.",pathpt,resolution,n);
+ rc = stat(name,&s);
+#ifndef MSDOS
+ }
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ sprintf(name,"%s/%d/%s.gf",pathpt,resolution,n);
+ if ((rc = stat(name,&s))!=0)
+ {
+ sprintf(name,"%s/%ld/%s.gf",pathpt,fontmag,n);
+ rc = stat(name,&s);
+ }
+#endif
+ if (rc==0) return(TRUE);
+ };
+
+#ifdef FUTURE
+ for(i=0; (pathpt=path_segment((bool)(i==0),VFPATH,local_path))!=NULL;i++) {
+ sprintf(name,"%s/%s.vfm",pathpt,n);
+ printf("searching virtual font <%s>\n",name);
+ if (stat(name,&s) == 0) return(TRUE);
+ }
+#endif
+
+#ifdef USEPXL
+ /* return error messaage */
+ sprintf(name,"font not found: <%s>/<%d;%ld>/%s.gf",
+ path,resolution,fontmag,n);
+#else
+ sprintf(name,"font not found: <%s>/<%d;%ld>/%s.<pk;pxl>",
+ path,resolution,fontmag,n);
+#endif
+
+return(FALSE);
+}
+
+char *
+path_segment(first,full_path,local_path)
+bool first;
+char *full_path, *local_path;
+{
+ static char *pppt;
+ char *pathpt;
+
+ if (first) pathpt = strcpy(local_path,full_path);
+ else pathpt = pppt;
+ if (pathpt != NULL) {
+#ifdef unix
+ pppt = strchr(pathpt , ':' );
+#else
+ pppt = strchr(pathpt , ';' );
+#endif
+#ifdef MSDOS
+ pppt = strchr(pathpt , ';' );
+#endif
+ if (pppt != NULL) {
+ *pppt = '\0';
+ pppt++;
+ }
+ }
+return pathpt;
+}
diff --git a/systems/msdos/dviware/dvilj4/lj4.bat b/systems/msdos/dviware/dvilj4/lj4.bat
new file mode 100644
index 0000000000..3edfb113a5
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/lj4.bat
@@ -0,0 +1,15 @@
+@echo off
+set TMPDIR=g:/
+rem ^^^ this is where gcc's temp files go
+set GO32TMP=g:/
+rem ^^^ this is where your paging file goes - if not set, the
+rem variables TMP and TEMP are checked in that order
+set 387=NO
+set go32=emu c:/tex/emu387
+c:\tex\dvilj4 -v %1 %2 %3 %4
+rem c:\tex\dvilj4 -eprn -v -ac:\tex\fonts\canon %1 %2 %3 %4
+rem ^^^ in case you have a printer :-)
+set TMPDIR=
+set GO32TMP=
+set 387=
+set go32= \ No newline at end of file
diff --git a/systems/msdos/dviware/dvilj4/makefile b/systems/msdos/dviware/dvilj4/makefile
new file mode 100644
index 0000000000..075d61db7e
--- /dev/null
+++ b/systems/msdos/dviware/dvilj4/makefile
@@ -0,0 +1,73 @@
+# makefile for the dvi-to-(3812 || lj + || lj II || lj IIp ) filter.
+#
+CFLAGS=-O -DMSDOS
+# BINDIR=/usr/TeX/bin
+# MANDIR=/usr/TeX/man
+# MANSEC=1
+CC=gcc
+
+OBJS=findlj.o find3812.o
+HFILES=commands.h config.h
+PROGRAMS=dvilj2p dvilj2 dvi3812 dvilj dviljp
+
+all: $(PROGRAMS) dvi2xx.txt
+
+dvi3812: dvi2xx.c find3812.o $(HFILES)
+ $(CC) ${CFLAGS} -DIBM3812 -o $@ dvi2xx.c find3812.o ${LFLAGS}
+
+dvilj2p: dvi2xx.c findlj.o commands.h config.h
+ $(CC) -O -DMSDOS -DLJ2P -DLJ -o dvilj2p dvi2xx.c findlj.o
+ strip dvilj2p
+ aout2exe dvilj2p
+ del dvilj2p
+
+dvilj4: dvi2xx.c findlj.o commands.h config.h
+ $(CC) -O -DMSDOS -DLJ4 -DLJ -o dvilj4 dvi2xx.c findlj.o
+ strip dvilj4
+ aout2exe dvilj4
+ del dvilj4
+
+dvilj2: dvi2xx.c findlj.o $(HFILES)
+ $(CC) ${CFLAGS} -DLJ2 -o $@ dvi2xx.c findlj.o ${LFLAGS}
+
+dvilj: dvi2xx.c findlj.o $(HFILES)
+ $(CC) ${CFLAGS} -DLJ -DSEVENBIT -o $@ dvi2xx.c findlj.o ${LFLAGS}
+
+dviljp: dvi2xx.c findlj.o $(HFILES)
+ $(CC) ${CFLAGS} -DLJ2P -DSEVENBIT -o $@ dvi2xx.c findlj.o ${LFLAGS}
+
+findlj.o: findfile.c config.h
+ $(CC) -O -DMSDOS -DLJ -c findfile.c
+ copy findfile.o findlj.o
+ del findfile.o
+
+find3812.o: findfile.c config.h
+ $(CC) ${CFLAGS} -DIBM3812 -c findfile.c
+ copy findfile.o findlj.o
+ del findfile.o
+
+clean:
+ rm -f core $(OBJS) $(PROGRAMS)
+
+DISTFILES = \
+ ./dvi2xx.c ./commands.h ./config.h ./findfile.c ./Makefile \
+ ./testpage.tex ./dvi2xx.history ./dvi2xx.man ./dvi2xx.txt ./graybox.sty \
+ ./dvi2xx.051 ./README ./sample2.tex ./2up.sty ./README.pcl
+
+
+install:
+ @for f in $(PROGRAMS); do \
+ echo installing $$f in $(BINDIR); \
+ install -c $$f $(BINDIR); \
+ done
+ cp dvi2xx.man dvi2xx.$(MANSEC)
+ install dvi2xx.$(MANSEC) $(MANDIR)/man$(MANSEC)
+
+dvi2xx.txt: dvi2xx.man
+ -nroff -man dvi2xx.man | col -b > dvi2xx.txt
+
+
+
+
+
+
diff --git a/systems/msdos/dviware/dvips/maketexp.bat b/systems/msdos/dviware/dvips/maketexp.bat
new file mode 100644
index 0000000000..61253ee70c
--- /dev/null
+++ b/systems/msdos/dviware/dvips/maketexp.bat
@@ -0,0 +1,52 @@
+@echo off
+REM
+REM This script file makes a new TeX PK font, because one wasn't
+REM found. Parameters are:
+REM
+REM name dpi bdpi magnification [mode]
+REM
+REM `name' is the name of the font, such as `cmr10'. `dpi' is
+REM the resolution the font is needed at. `bdpi' is the base
+REM resolution, useful for figuring out the mode to make the font
+REM in. `magnification' is a string to pass to MF as the
+REM magnification. `mode', if supplied, is the mode to use.
+REM
+REM Because of MSDOS memory constraints, this batch file just
+REM creates a mfjob file, so that the fonts can be created later.
+REM
+
+REM NAME=%1 DPI=%2 BDPI=%3 MAG=%4 MODE=%5
+
+if exist dvips.mfj goto :second
+echo %% dvips.mfj - created by dvips > dvips.mfj
+echo input [modes]; >> dvips.mfj
+echo Created dvips.mfj
+
+:second
+echo { >> dvips.mfj
+echo base=plain; >> dvips.mfj
+echo font=%1; >> dvips.mfj
+echo mag=%4; >> dvips.mfj
+
+if "%5" == "" goto :nomode
+if "%5" == "imagen" goto :hpmode
+if "%5" == "hplaser" goto :hpmode
+
+:goodmode
+echo mode=%5[%3]; >> dvips.mfj
+echo output=pk[c:\texfonts\%5\@Rrdpi\@f]; >> dvips.mfj
+goto :donemode
+
+:hpmode
+echo mode=hplaser[%3]; >> dvips.mfj
+echo output=pk[c:\texfonts\pixel.lj\@Rrdpi\@f]; >> dvips.mfj
+goto :donemode
+
+:nomode
+echo m; >> dvips.mfj
+
+:donemode
+echo } >> dvips.mfj
+
+echo Run "mfjob dvips"
+:exit
diff --git a/systems/msdos/dviware/dvips/readme.pc b/systems/msdos/dviware/dvips/readme.pc
new file mode 100644
index 0000000000..13e278ce14
--- /dev/null
+++ b/systems/msdos/dviware/dvips/readme.pc
@@ -0,0 +1,113 @@
+Some notes on installing dvips 5.5 on MS-DOS
+by Russell Lang <rjl@monu1.cc.monash.edu.au> 21st January 1993
+
+These notes are not by Tomas Rokicki.
+Tomas Rokicki does not use MS-DOS ( smart person :-) and so will be
+unable to answer questions about MS-DOS problems.
+
+This set of MSDOS files for dvips contains:
+README.pc This file.
+makefile.tc Makefile for Borland C++.
+makefile.emx Makefile for ndmake and emx/gcc.
+config.ps config.ps modified for MSDOS
+maketexp.bat Batch file to make tex pk files.
+maketexp.cmd OS/2 batch file to make tex pk files.
+winmain.c WinMain() routine for Windows dvips.
+dvipswin.rc Windows Resource file containing radical eye icon.
+dvipswin.def Windows defaults file.
+
+If you have the Unix tar file, the steps involved in making
+dvips on a PC are:
+- On Unix, in the dvips directory, give the following commands:
+ make texc.lpro
+ nroff -man dvips.1 > pc/dvips.doc
+ nroff -man afm2tfm.1 > pc/afm2tfm.doc
+- Copy dvips/* and dvips/pc/* directories to the PC.
+- copy PStfms/*.tfm to C:\EMTEX\TFM on the PC
+ (then optionally delete pst*.tfm, rpst*.tfm, pop*.tfm rpop*.tfm,
+ pad*.tfm rpad*.tfm)
+- copy PSvfs/*.vf to C:\TEXFONTS\VF on the PC
+ (then optionally delete pst*.vf, pop*.vf, pad*.vf)
+- edit dvipsmac.tex and replace the line
+ \generictrue
+ with
+ %\generictrue
+
+For Borland C++:
+- edit paths and directories in pc/makefile.tc and pc/config.ps.
+- 'make -fpc/makefile.tc'
+- if that works, try 'make -fpc/makefile.tc install'.
+- change to another directory (to avoid using the Unix config.ps)
+ and then try to run dvips!
+
+For emx/gcc:
+- edit paths and directories in pc/makefile.emx and pc/config.ps.
+- 'ndmake -f pc/makefile.emx'
+- if that works, try 'ndmake -f pc/makefile.emx install'.
+- change to another directory (to avoid using the Unix config.ps)
+ and then try to run dvips32!
+- This version of dvips has not been tested thoroughly.
+ See the EMX documentation for the EMX DOS extender.
+- It is hoped that this version will work under OS/2.
+
+If you have MS-DOS ZIP files, they will contain a compiled version of dvips.
+
+To install this in the emTeX directories on drive C:, use
+ pkunzip -d -o dvips* c:\
+
+The MSDOS version of dvips differs from the description in
+dvips.tex in the following ways:
+- path separators are ';' not ':'
+- directory separators are '\' not '/'
+- The user's initialization file is "dvips.ini" not ".dvipsrc".
+- pipes to printers not supported. Output must go to a file.
+- MakeTeXPk is a batch file. Since MSDOS has insufficient memory
+ to run both dvips and Metafont at the same time, this batch file
+ will typically write out a set of commands for running Metafont
+ later. The maketexp.bat supplied writes out an mfjob file for emTeX.
+ maketexp.bat will probably need customising for your site.
+- To automatically make fonts, use emTeX's dvidrv as follows:
+ dvidrv dvips file.dvi
+ dvidrv sets an option -pj=mfjobfile for dvips, where mfjobfile
+ is the name of a temporary mfjob file.
+ If there are missing fonts, dvips will write this mfjob file
+ and then ask:
+ Exit to make missing fonts now (y/n)?
+ If you answer yes, dvips exits with errorlevel 8 which tells
+ dvidrv to call mfjob to make the fonts, and then to call dvips again.
+ For this to work, dvidrv, dvips, mfjob and mf must be located in
+ the PATH, and the environment variables for mfjob and mf set
+ correctly. A font mode must be set with the 'M' option in config.ps.
+ If the -pj option is set, dvips will not call MakeTeXPk.bat
+- limited emTeX specials. The following ones are supported:
+ \special{em:message xxx}
+ \special{em:point n}
+ \special{em:line a[h|v|p],b[h|v|p] [,width]}
+ \special{em:linewidth width}
+ \special{em:moveto}
+ \special{em:lineto}
+ \special{em:graph xxx[,width[,height]]}
+ The line cut parameters [h|v|p] of the \special{em:line ...} command
+ are ignored. Lines are ended with a rounded cap.
+ A maximum of 1613 different point numbers are permitted on each page.
+ The \special{em:graph xxx} should work with PCX, MSP1, MSP2 and
+ BMP files. Compressed BMP files have not been tested.
+ The graph file may be scaled by giving an optional width and
+ height (expressed in the same way as TeX dimensions).
+ An example: \special{em:graph scrdump.pcx,100mm,75mm}
+
+See the config.ps file for other changes.
+
+If you want to use a different directory arrangement, modify the
+paths in config.ps. If you want to store config.ps or psfonts.map
+in a different place, either recompile dvips or use the environment
+variable TEXCONFIG.
+
+The program dvips can use emTeX font libraries created with the
+fontlib /2 option. PXL fonts within font libraries will be ignored.
+
+Borland C++ gives a large number of 'possible incorrect assignment'
+warnings.
+
+If you run out of memory running dvips, try using the `-Z0 -a' or
+just the `-a' command line options.
diff --git a/systems/msdos/dviware/dviwin b/systems/msdos/dviware/dviwin
new file mode 120000
index 0000000000..6a6d4658f8
--- /dev/null
+++ b/systems/msdos/dviware/dviwin
@@ -0,0 +1 @@
+../../../dviware/dviwin \ No newline at end of file
diff --git a/systems/msdos/dviware/pccrude.zoo b/systems/msdos/dviware/pccrude.zoo
new file mode 100644
index 0000000000..7e90251958
--- /dev/null
+++ b/systems/msdos/dviware/pccrude.zoo
Binary files differ
diff --git a/systems/msdos/dviware/xdvi-dos/copying b/systems/msdos/dviware/xdvi-dos/copying
new file mode 100644
index 0000000000..e038c461ac
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/copying
@@ -0,0 +1,249 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must tell them their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License. The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+ 7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+ 8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/systems/msdos/dviware/xdvi-dos/copying.dj b/systems/msdos/dviware/xdvi-dos/copying.dj
new file mode 100644
index 0000000000..3d87ae3ce2
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/copying.dj
@@ -0,0 +1,63 @@
+This is the file "copying.dj".
+
+ Copyright Information for sources and executables that are marked
+ Copyright (C) DJ Delorie
+ 24 Kirsten Ave
+ Rochester NH 03867-2954
+
+This document is Copyright (C) DJ Delorie and may be distributed
+verbatim, but changing it is not allowed.
+
+Source code copyright DJ Delorie is distributed under the terms of the
+GNU General Public Licence, with the following exceptions:
+
+
+* Source code copyright DJ Delorie is distributed under the terms of the
+ GNU General Public Licence, with the following exceptions:
+ ("go32.exe" refers to go32.exe and debug32.exe)
+
+ * There are no conditions on distributing copies of stub.exe as
+ it is originally distributed in this software package, prepended
+ onto a binary or otherwise. This is the recommended distribution
+ mechanism for applications.
+
+ * Binaries of emu387 may be distributed with no restrictions.
+
+ * If a user creates an application, prepends a copy of go32.exe onto
+ the beginning of it, and distributes it free of charge, then the
+ user is under no obligations to distribute source or pay royalties.
+ Note that the copyright terms of the FSF and/or UCB must be
+ obeyed regardless of this.
+
+ * If a user creates an application, prepends a copy of go32.exe onto
+ the beginning of it, and charges a fee for the software, then a
+ royalty of $5 or 5% of the selling price per copy sold must be paid
+ to DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954. Note that
+ shareware programs are not considered "sold" until payment is rendered
+ for them.
+
+ * For all other cases, source code for go32.exe must be distributed
+ with any distributed copies of go32.exe.
+
+ * Software that requires go32.exe to run, but is not distributed with
+ a copy of go32.exe, incurs no obligations with regards to the
+ above sections.
+
+ * Contact me for special terms if none of the above are suitable.
+
+ * Donations are always appreciated.
+
+ The intent of this copyright is this: If you make money by using the
+ programs I wrote, I get some of it. If you use your sources to
+ teach others how to write programs, I'll support you.
+
+Changes to source code copyright BSD or FSF are copyright DJ Delorie, but
+fall under the terms of the original copyright.
+
+A copy of the file "COPYING" is included with this document. If you did not
+receive a copy of "COPYING", you may obtain one from whence this document
+was obtained, or by writing:
+ Free Software Foundation
+ 675 Mass Ave
+ Cambridge, MA 02139
+ USA
diff --git a/systems/msdos/dviware/xdvi-dos/read_dvx.tex b/systems/msdos/dviware/xdvi-dos/read_dvx.tex
new file mode 100644
index 0000000000..18cd070d15
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/read_dvx.tex
@@ -0,0 +1,79 @@
+% This is a LaTeX file
+%
+% This file contains details of the XDVI port to DJGPP
+\documentstyle{article}
+\begin{document}
+
+
+\title{{\bf XDVI} for {\bf PC} under {\bf DV/X}}
+\author {Eric Ho \\ 9041477@SSCVAX.CIS.MCMASTER.CA}
+\maketitle
+
+This program is re-compiled using {\bf DJGPP}. As a result, the program
+expects 386 CPU and up with FPU as well as {\bf GO32}.
+Original {\bf XDVI} source is obtained from
+{\bf export.lcs.mit.edu:/contrib}.
+
+\section{Modifications}
+
+There are not many modifications done to the original xdvi except that
+fonts not available can now be substituted by specifying them in a file.
+The environmental variable {\bf TEXFONTSUB} points to this file. For example,
+{\bf TEXFONTSUB}=c:/xdvi/texfonts.sub". The filename texfonts.sub is arbitrary.
+One can rename it to some other name as long as the environmental variable
+TEXFONTSUB points to it. Format of the font substitute file (ASCII) is
+as follows:
+
+\vspace {10 pt}
+
+{\bf amr10} -$>$ {\bf cmr10}
+
+{\bf src2} -$>$ {\bf dest2}
+
+etc.
+\vspace {10 pt}
+
+where src2 is the unavailable font and dest2 is the font we intended to
+substitute. It is exactly as the font substitution machcanism found in
+{\bf DVIVGA}.
+
+For those interested in the image processing features provided by XDVI,
+please browse through the source and see if I did anything wrong
+in choosing suitable image quality since I do not know anything about
+image processing.
+
+Default \TeX font directory is "c:/tex/fonts." However, this can be overridden
+by specifying another directory through some environmental variable. Please
+look at the file {\it readme} for details.
+
+Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file. To
+use the other version one must re-compile the source. To obtain the other
+versions one must re-compile XDVI with appropiate switches set.
+
+\section{Optimizing XDVI}
+
+Opening and searching text file using DJGPP will add significant overhead
+to the execution due to mode switching. Also, I found most of substitutions
+are converting AM font to CM font (I only have cm font at home). Therefore,
+I also modified the program to convert amxxxx to cmxxxx internally to speed
+up execution. To choose this option one should recompile the source without
+defining {\bf FONTSUB} (i.e., take out -D{\bf FONTSUB} in the makefile). Finally,
+the makefile enclosed is compatible with both {\bf NDMAKE45}
+and Borlan?'s {\bf MAKE} utility.
+
+\section{Bugs}
+
+I have not yet found any bugs after I have performed some testings.
+However, I conducted the test without mouse attaching to my system (because I
+don't have one). Accordingly, I have no idea how XDVI will behave with mouse
+connected to the system. Finally, I tested only the {\bf pk} font version
+of XDVI, therefore the performance of using {\bf gf} and {\bf pxl} is unknown.
+
+\section{Acknowledgment}
+
+I wish to thank {\bf DJ, et. al.} for their excellent compiler. Also thank all
+authors of the original XDVI for their contribution.
+
+\end{document}
diff --git a/systems/msdos/dviware/xdvi-dos/read_dvx.txt b/systems/msdos/dviware/xdvi-dos/read_dvx.txt
new file mode 100644
index 0000000000..a0e076fd54
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/read_dvx.txt
@@ -0,0 +1,76 @@
+ XDVI for PC under DV/X
+ ----------------------
+
+
+This program is re-compiled using DJGPP. As a result, it expects 386 and
+up CPU with FPU as well as GO32. Original XDVI source is obtained from
+export.lcs.mit.edu:/contrib.
+==============================================================================
+
+Modifications
+-------------
+
+There are not many modifications done to the original xdvi except that
+fonts not available can now be substituted by specifying them in a file.
+The environmental variable "TEXFONTSUB" points to this file. For example,
+"TEXFONTSUB=c:\xdvi\texfonts.sub". The filename texfonts.sub is arbitrary.
+One can rename it to some other name as long as the environmental variable
+TEXFONTSUB points to it.
+
+
+Format of the font substitute (ASCII) file:
+
+amr10 -> cmr10
+src2 -> dest2
+ :
+ :
+
+where src2 is the unavailable font and dest2 is the font we intended to
+substitute. It is exactly as the font substitution machcanism found in
+DVIVGA.
+
+For those interested in the image processing features provided by XDVI,
+please browse through the source and see if I did anything wrong
+in choosing suitable image quality since I do not know anything about
+image processing.
+
+Default TeX font directory is "c:\tex\fonts." However, this can be overridden
+by specifying another directory through some environmental variable. Please
+look at the file "readme" for details.
+
+Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file.
+To obtain the other two versions one must re-compile XDVI with appropiate
+switches set.
+===============================================================================
+
+Optimizing the program
+----------------------
+
+Opening and searching text file using DJGPP will add significant overhead
+to the execution due to mode switching. Also, I found most of substitutions
+are converting AM font to CM font (I only have cm font at home). Therefore,
+I also modified the program to convert amxxxx to cmxxxx internally to speed
+up execution. To choose this option one should recompile the source without
+defining FONTSUB (i.e., take out -DFONTSUB in the makefile). Finally,
+the makefile enclosed is compatible with both NDMAKE45 and Borland's MAKE
+utility.
+===============================================================================
+
+Bugs
+----
+
+I have not yet found any bugs afte I have performed some testings. However,
+I conducted the test without mouse attaching to my system (because I do not
+ have one). Accordingly, I have no idea how XDVI will behave with mouse
+connected. Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file.
+===============================================================================
+
+Acknowledgment
+--------------
+
+I wish to thank DJ, et. al. for their excellent compiler. Also thank all
+authors of the original XDVI for their contribution.
diff --git a/systems/msdos/dviware/xdvi-dos/readme b/systems/msdos/dviware/xdvi-dos/readme
new file mode 100644
index 0000000000..8f07ff7d51
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/readme
@@ -0,0 +1,268 @@
+INSTALLATION INSTRUCTIONS
+
+To install, do the following:
+ 1. Read the ENVIRONMENT section of xdvi_man.sed to determine the correct
+ default values for the XDVIFONTS and XDVISIZES environment variables.
+ Edit the Imakefile or Makefile and change the values of the make
+ variables DEFAULT_FONT_PATH and DEFAULT_FONT_SIZES to these values.
+ If your site uses virtual fonts, do the same thing with the
+ DEFAULT_VF_PATH variable. Note that support of virtual fonts in xdvi
+ does not include support of built-in Postscript<tm> fonts.
+
+ (Note: for X10 compilation, use Makefile_10 instead of Makefile.)
+
+ You may also wish to change other compilation options; they are
+ described later in this file.
+
+ 2. make xdvi and try it out. If the settings in step one are incorrect,
+ you can use the corresponding environment variables to quickly try out
+ different values. If the values set in step 1 were incorrect,
+ rm font_open.o and go back to step 1.
+
+ If you get the error that the #include file <stdlib.h> does not exist,
+ then you should include -DX_NOT_STDC_ENV in the DEFS variable in the
+ Makefile or Imakefile. In X11R5 or later this problem should not
+ come up.
+
+ 3. make xdvi.man.
+
+ 4. Install xdvi and xdvi.man.
+
+
+ The X10 flag only affects xdvi.c (and the flags MSBITFIRST, BMSHORT,
+ and BMLONG, see below).
+
+ Note in particular the compilation flags USE_PK, USE_GF, and USE_PXL,
+ which can be set to reflect which font formats are actually used at
+ your site.
+
+Other compilation flags are:
+ SYSV (dvi_init.c font_open.c xdvi.c) Set for System V
+ compilation.
+ VMS Set for VMS compilation.
+ MSBITFIRST (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps internally with the most significant bit at
+ the left. For performance reasons, it would be best
+ to set this to coincide with what your server uses.
+ Use the keystroke '^P' to find information in this
+ regard. Generally, you should use MSBITFIRST if and
+ only if '^P' reports bitord = 1, and BMSHORT/BMLONG
+ (below) should be set to match whatever '^P' reports
+ under "Unit =". But, if bitord = byteord, then the
+ latter setting should not matter much.
+ BMSHORT (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps in short integers instead of bytes. See
+ MSBITFIRST for other relevant comments. To check
+ performance, you can use:
+ time xdvi -d 8 file.dvi
+ BMLONG (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps in long integers instead of bytes.
+ ALTFONT (xdvi.c) Default font to use if the font named in the
+ dvi file cannot be found. Can be set to NULL. By
+ default, it is "cmr10".
+ SEARCH_SUBDIRECTORIES (font_open.c) Enable recursive searching of
+ subdirectories for font files (* and ** specifiers).
+ This also enables the TEXFONTS_SUBDIR environment
+ variable and the DEFAULT_SUBDIR_PATH makefile variable.
+ XDVIFONTS_ONLY (font_open.c) Never check the TEXFONTS environment
+ variable. Normally xdvi checks TEXFONTS if the
+ XDVIFONTS variable is not set. This option is
+ recommended if the version of TeX in use requires
+ that the TEXFONTS variable be set. See the relevant
+ paragraph in xdvi_man.sed for more details. This
+ option turns off that paragraph.
+ NOTOOL (X11 only; xdvi.c) Compile using raw X calls.
+ BUTTONS (xdvi.c) Put radio buttons on the right side of the
+ window for commonly used commands.
+ A4 (xdvi.c) Use European size paper by default.
+ NOQUERY (xdvi.c) Set this if you have trouble compiling the
+ definition of drawingWidgetClass.
+ TEXXET (everything) Enables op-codes 250 and 251 (used for
+ right-to-left languages).
+ BDPI (xdvi.c) Default number of pixels per inch to use.
+ GREY (everything) Use greyscale anti-aliasing for
+ displaying shrunken bitmaps.
+ MAKEPK (font_open.c) If a font is not found, then try to
+ call Metafont to create the font. When using this
+ option, remember to set the paths in MakeTeXPK
+ correctly for your site, and be sure that the
+ destination directory for MakeTeXPK appears in your
+ DEFAULT_FONT_PATH variable.
+ MAKEPKCMD=\"/usr/local/tex/bin/MakeTeXPK\" (font_open.c) Same as the
+ above, but this variant explicitly declares which
+ command to use to create the font.
+
+All flags should be set in the appropriate Makefile via the variable ``DEFS''.
+
+================================================================
+
+ This program is the combined work of many people, including but not
+restricted to:
+ Eric Cooper, CMU
+ Bob Scheifler, MIT LCS
+ Paal Kvamme, Norwegian Institute of Technology
+ H\aa vard Eidnes, Norwegian Institute of Technology
+ Mark Eichin, MIT SIPB
+ Paul Vojta, UC Berkeley
+ Jeffrey Lee, U of Toronto
+ Donald Richardson, Clarkson Univ.
+At the present time, the person to send bug reports to is Paul Vojta,
+ vojta@math.berkeley.edu.
+
+In addition to the various comp.sources.x archives, current versions of this
+program can also be obtained via anonymous ftp from the following location:
+ export.lcs.mit.edu [18.24.0.12] file contrib/xdvi.tar.Z
+To ease the load on export, you may also check other X archives, for example:
+ gatekeeper.dec.com [16.1.0.2] file pub/X11/contrib/xdvi.tar.Z
+
+Paul Vojta, 17 March 1992
+
+================================================================
+
+Note for IBM RS6000 users: some of the libraries are in non-obvious places:
+
+ libXmu /usr/lpp/X11/Xamples/lib/Xmu/libXmu.a
+ libXaw /usr/lpp/X11/Xamples/lib/Xaw/libXaw.a
+
+These should be moved to /usr/lib or some more reasonable place (or use
+symlinks), and ditto for the include files, which are initially placed
+in /usr/lpp/X11/Xamples/include.
+
+================================================================
+
+Notes of historical nature follow. Most recent changes are listed at the end
+of the file.
+
+================================================================
+
+This directory contains a version of xdvi capable of reading GF, PXL
+and PK font files. This version of xdvi is based on the source that
+"came with" X v10r3. Xdvi was modified by Paal Kvamme at the Norwegian
+Institute of Technology, based on the modifications I had made to
+dviimp (a dvi to ImPress converter). This code was again more or less
+directly translated from the web source of PKtoPX.
+
+If you discover (and fix) any bugs in this code, please notify me, so
+I can make the corresponding changes myself.
+
+---------
+H}vard Eidnes (TeXish: H\aa vard Eidnes)
+Division of Computer Science
+Norwegian Institute of Technology
+
+E-Mail: h_eidnes%vax.runit.unit.uninett@nta-vax.arpa
+================================================================
+Also has path search added by Mark Eichin, looks in TEXFONTS
+================================================================
+
+================================================================
+Additional notes:
+ X11 version now works on the IBM PC/RT as well as VAX.
+ [eichin:19880313.1330EST]
+================================================================
+*MORE* fixes (for athena release locker) [eichin:19880722.2058EST]
+Fixes:
+ narrow vertical and horizontal lines no longer disappear.
+ bogus underlining (which usually occured on even sample sizes
+of odd sized characters) no longer occurs.
+ -S number (or typing number followed by S) will adjust the
+sampling fraction; 0 is special cased to mean if anything in the
+sampled zone is set, set the sample, else clear it. Interesting to
+experiment with, though not useful for reading (the default value of 3
+is just right.)
+ -display and -geometry arguments work (so do old style forms,
+though they were broken before)
+ fixed one of the PK debugging messages to print the correct
+font name instead of printing the pointer as text.
+ included Ken Raeburn <raeburn>'s changes to support multiple
+screens.
+================================================================
+More changes:
+
+ 1. Incorporated the bitmap under a viewport widget using the toolkit
+ (X11 only);
+ 2. Added an icon and icon geometry arguments (X11 only);
+ 3. Supported window resizing;
+ 4. Added a 'c' option to move whatever is currently under the cursor to
+ the center of the window;
+ 5. Added an 'R' option to reread the .dvi file, and added logic to make
+ 'R' happen automatically whenever any part of the window is exposed
+ and the dvi file changes (so that you can iconify xdvi, run tex,
+ deiconify xdvi, and voila!);
+ 6. Added a 'magnifying glass': when you push a button, a window pops
+ up, showing the region of the page, unshrunk;
+ 7. Added support for gf fonts;
+ 8. Upgraded font searching (at our site we use /usr/custom/tex82/gf
+ for gf fonts, /usr/custom/tex82/pk for pk fonts, etc.);
+ 9. Made numerous internal changes (removed all the lint I could,
+ made unshrunk bitmaps permanently resident, which speeds up size
+ changing, made table.h necessary only for pxl.h, split up the source
+ file into xdvi.c, dvi.c, gf.c, pxl.c, and pk.c, made shrinking occur
+ relative to the character's hot point, etc.)
+ 10. The program reads SIGIO signals and processes incoming events
+ immediately, so that it can stop displaying things that would be
+ erased anyway. If these interrupts are not coming through, then
+ it also checks for incoming events every several dozen characters
+ displayed.
+ 11. Further split up dvi.c into dvi_init.c and dvi_draw.c; added
+ compilation options for various internal bitmap representations.
+ Fixed it so gcc won't give warnings, and so it works with R3 toolkit.
+-- Patchlevel 2: --
+ 12. Added MAXCHARS compilation option. Eliminated the nonsense with
+ generating table.h.
+-- Patchlevel 3: --
+ 13. Added -altfont command line option and SYSV compilation option.
+================================================================================
+
+4/1989 Modified for System V boxes. -DSYSV compiler option.
+
+Donald Richardson, donr@crystal.mie.clarkson.edu
+
+================================================================================
+-- Patchlevel 4: --
+ 14. Removed MAXCHARS compilation option. It's automatic now. Made X10
+ scrolling smoother. Implemented the moving magnifying glass.
+-- Patchlevel 5: --
+ 15. Implemented compilation without the toolkit, as well as scrollbars
+ and tpic support in X10. Also this version should work with color
+ VAXstations, although overstrike characters will come out incorrectly.
+ 16. Fixed a bug in gf reading routines: specials at the beginning of
+ a character def. were not being processed. Thanks to
+ kevin@amath.washington.edu for a bug report and fix.
+ 17. Added 'k' keystroke.
+-- Patchlevel 6: --
+ 18. Added buttons on the right side of the window.
+ 19. Added -pagewidth and -pageheight command line options and A4
+ compilation option.
+ 20. Added a yet more robust font finding algorithm.
+-- Patchlevel 7: --
+ 21. Replaced -pagewidth and -pageheight options with -paper.
+-- Patchlevel 8: --
+ 22. Added compatibility for X11R4 and VMS. Fixed up alignment of rules.
+-- Patchlevel 9: --
+ 23. Removed obsolete '#' and '=' options from the X11 version: they
+ interfere with emacs.
+-- Patchlevel 10: --
+ 24. Implemented arrow keys, expert mode, searching for the font's actual
+ size first, the -[xy]offset and -sw options, and numerous bug fixes.
+-- Patchlevel 11: --
+ 25. Implemented recursive searching for font files in subdirectories.
+ 26. Changed +sw to -hushspecials and implemented -hush.
+ 27. Modified mksedscript so that the man page comes out neater.
+ 28. Added a -keep option and resource to match the `k' keystroke.
+-- Patchlevel 12: --
+ 29. Implemented virtual fonts (this does not include built-in
+ Postscript<tm> fonts!!!).
+ 30. X11R5 support, and numerous bug fixes.
+-- Patchlevel 13: --
+ 31. Added support for TeXXeT.
+-- Patchlevel 14: --
+ 32. Added support for greyscale anti-aliasing.
+-- Patchlevel 15: --
+ 33. Added support for MakeTeXPK, as in dvips.
+-- Patchlevel 16: --
+ 34. In the code for greyscale anti-aliasing, try to allocate a colormap
+ so that GXor operations can be used for drawing. Also interpolate
+ between foreground and background colors.
+
+Paul Vojta, vojta@math.berkeley.edu
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi.h b/systems/msdos/dviware/xdvi-dos/src/dvi.h
new file mode 100644
index 0000000000..ca2b7bc78b
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi.h
@@ -0,0 +1,62 @@
+/*
+ * Mnemonics for bytes in dvi file.
+ */
+
+#define SETCHAR0 0
+#define SET1 128
+#define SETRULE 132
+#define PUT1 133
+#define PUTRULE 137
+#define NOP 138
+#define BOP 139
+#define EOP 140
+#define PUSH 141
+#define POP 142
+#define RIGHT1 143
+#define RIGHT2 144
+#define RIGHT3 145
+#define RIGHT4 146
+#define W0 147
+#define W1 148
+#define W2 149
+#define W3 150
+#define W4 151
+#define X0 152
+#define X1 153
+#define X2 154
+#define X3 155
+#define X4 156
+#define DOWN1 157
+#define DOWN2 158
+#define DOWN3 159
+#define DOWN4 160
+#define Y0 161
+#define Y1 162
+#define Y2 163
+#define Y3 164
+#define Y4 165
+#define Z0 166
+#define Z1 167
+#define Z2 168
+#define Z3 169
+#define Z4 170
+#define FNTNUM0 171
+#define FNT1 235
+#define FNT2 236
+#define FNT3 237
+#define FNT4 238
+#define XXX1 239
+#define XXX2 240
+#define XXX3 241
+#define XXX4 242
+#define FNTDEF1 243
+#define FNTDEF2 244
+#define FNTDEF3 245
+#define FNTDEF4 246
+#define PRE 247
+#define POST 248
+#define POSTPOST 249
+#define SREFL 250
+#define EREFL 251
+
+#define TRAILER 223 /* Trailing bytes at end of file */
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c b/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c
new file mode 100644
index 0000000000..4c8b0989a7
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c
@@ -0,0 +1,1049 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+#include <ctype.h>
+#include "xdvi.h"
+#include "dvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+#if NeedVarargsPrototypes /* this is for tell_oops */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DOPRNT /* define this if vfprintf gives you trouble */
+#define vfprintf(stream, message, args) _doprnt(message, args, stream)
+#endif
+
+static struct frame frame0; /* dummy head of list */
+#ifdef TEXXET
+static struct frame *scan_frame; /* head frame for scanning */
+#endif
+
+#ifndef DVI_BUFFER_LEN
+#define DVI_BUFFER_LEN 512
+#endif
+
+static ubyte dvi_buffer[DVI_BUFFER_LEN];
+static struct frame *current_frame;
+
+#ifndef TEXXET
+#define DIR 1
+#else
+#define DIR currinf.dir
+#endif
+
+/*
+ * Explanation of the following constant:
+ * offset_[xy] << 16: margin (defaults to one inch)
+ * shrink_factor << 16: one pixel page border
+ * shrink_factor << 15: rounding for pixel_conv
+ */
+#define OFFSET_X (offset_x << 16) + (shrink_factor * 3 << 15)
+#define OFFSET_Y (offset_y << 16) + (shrink_factor * 3 << 15)
+
+#ifndef BMLONG
+#ifndef BMSHORT
+unsigned char bit_masks[9] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff
+};
+#else /* BMSHORT */
+unsigned short bit_masks[17] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff, 0x1ff, 0x3ff, 0x7ff,
+ 0xfff, 0x1fff, 0x3fff, 0x7fff,
+ 0xffff
+};
+#endif /* BMSHORT */
+#else /* BMLONG */
+unsigned long bit_masks[33] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff, 0x1ff, 0x3ff, 0x7ff,
+ 0xfff, 0x1fff, 0x3fff, 0x7fff,
+ 0xffff, 0x1ffff, 0x3ffff, 0x7ffff,
+ 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
+ 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff,
+ 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ 0xffffffff
+};
+#endif /* BMLONG */
+
+#ifdef VMS
+#define off_t int
+#endif
+extern off_t lseek();
+
+#ifndef SEEK_SET /* if <unistd.h> is not provided (or for <X11R5) */
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+static void draw_part();
+
+/*
+ * Byte reading routines for dvi file.
+ */
+
+#define xtell(pos) (lseek(fileno(dvi_file), 0L, SEEK_CUR) - \
+ (currinf.end - (pos)))
+
+static ubyte
+xxone()
+{
+ if (currinf.virtual) {
+ ++currinf.pos;
+ return EOP;
+ }
+ currinf.end = dvi_buffer +
+ read(fileno(dvi_file), (char *) (currinf.pos = dvi_buffer),
+ DVI_BUFFER_LEN);
+ return currinf.end > dvi_buffer ? *(currinf.pos)++ : EOF;
+}
+
+#define xone() (currinf.pos < currinf.end ? *(currinf.pos)++ : xxone())
+
+static unsigned long
+xnum(size)
+ register ubyte size;
+{
+ register long x = 0;
+
+ while (size--) x = (x << 8) | xone();
+ return x;
+}
+
+static long
+xsnum(size)
+ register ubyte size;
+{
+ register long x;
+
+#ifdef __STDC__
+ x = (signed char) xone();
+#else
+ x = xone();
+ if (x & 0x80) x -= 0x100;
+#endif
+ while (--size) x = (x << 8) | xone();
+ return x;
+}
+
+#define xsfour() xsnum(4)
+
+static void
+xskip(offset)
+ long offset;
+{
+ currinf.pos += offset;
+ if (!currinf.virtual && currinf.pos > currinf.end)
+ (void) lseek(fileno(dvi_file), (long) (currinf.pos - currinf.end),
+ SEEK_CUR);
+}
+
+#if NeedVarargsPrototypes
+static NORETURN void
+tell_oops(_Xconst char *message, ...)
+#else
+/* VARARGS */
+static NORETURN void
+tell_oops(va_alist)
+ va_dcl
+#endif
+{
+#if !NeedVarargsPrototypes
+ _Xconst char *message;
+#endif
+ va_list args;
+
+ Fprintf(stderr, "%s: ", prog);
+#if NeedVarargsPrototypes
+ va_start(args, message);
+#else
+ va_start(args);
+ message = va_arg(args, _Xconst char *);
+#endif
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ if (currinf.virtual)
+ Fprintf(stderr, " in virtual font %s\n", currinf.virtual->fontname);
+ else
+ Fprintf(stderr, ", offset %ld\n", xtell(currinf.pos - 1));
+ exit(1);
+}
+
+
+/*
+ * Code for debugging options.
+ */
+
+static void
+print_bitmap(bitmap)
+ register struct bitmap *bitmap;
+{
+ register BMUNIT *ptr = (BMUNIT *) bitmap->bits;
+ register int x, y, i;
+
+ if (ptr == NULL) oops("print_bitmap called with null pointer.");
+ Printf("w = %d, h = %d, bytes wide = %d\n",
+ bitmap->w, bitmap->h, bitmap->bytes_wide);
+ for (y = 0; y < bitmap->h; ++y) {
+ for (x = bitmap->bytes_wide; x > 0; x -= BYTES_PER_BMUNIT) {
+#ifndef MSBITFIRST
+ for (i = 0; i < BITS_PER_BMUNIT; ++i)
+#else
+ for (i = BITS_PER_BMUNIT - 1; i >= 0; --i)
+#endif
+ Putchar((*ptr & (1 << i)) ? '@' : ' ');
+ ++ptr;
+ }
+ Putchar('\n');
+ }
+}
+
+static void
+print_char(ch, g)
+ ubyte ch;
+ struct glyph *g;
+{
+ Printf("char %d", ch);
+ if (isprint(ch))
+ Printf(" (%c)", ch);
+ Putchar('\n');
+ Printf("x = %d, y = %d, dvi = %ld\n", g->x, g->y, g->dvi_adv);
+ print_bitmap(&g->bitmap);
+}
+
+static _Xconst char *dvi_table1[] = {
+ "SET1", NULL, NULL, NULL, "SETRULE", "PUT1", NULL, NULL,
+ NULL, "PUTRULE", "NOP", "BOP", "EOP", "PUSH", "POP", "RIGHT1",
+ "RIGHT2", "RIGHT3", "RIGHT4", "W0", "W1", "W2", "W3", "W4",
+ "X0", "X1", "X2", "X3", "X4", "DOWN1", "DOWN2", "DOWN3",
+ "DOWN4", "Y0", "Y1", "Y2", "Y3", "Y4", "Z0", "Z1",
+ "Z2", "Z3", "Z4"};
+
+static _Xconst char *dvi_table2[] = {
+ "FNT1", "FNT2", "FNT3", "FNT4", "XXX1", "XXX2", "XXX3", "XXX4",
+ "FNTDEF1", "FNTDEF2", "FNTDEF3", "FNTDEF4", "PRE", "POST", "POSTPOST",
+ "SREFL", "EREFL", NULL, NULL, NULL, NULL};
+
+static void
+print_dvi(ch)
+ ubyte ch;
+{
+ _Xconst char *s;
+
+ Printf("%4d %4d ", PXL_H, PXL_V);
+ if (ch <= SETCHAR0 + 127) {
+ Printf("SETCHAR%-3d", ch - SETCHAR0);
+ if (isprint(ch))
+ Printf(" (%c)", ch);
+ Putchar('\n');
+ return;
+ }
+ else if (ch < FNTNUM0) s = dvi_table1[ch - 128];
+ else if (ch <= FNTNUM0 + 63) {
+ Printf("FNTNUM%d\n", ch - FNTNUM0);
+ return;
+ }
+ else s = dvi_table2[ch - (FNTNUM0 + 64)];
+ if (s) Puts(s);
+ else
+ tell_oops("unknown op-code %d", ch);
+}
+
+
+/*
+ * Count the number of set bits in a given region of the bitmap
+ */
+
+char sample_count[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+static int
+sample(bits, bytes_wide, bit_skip, w, h)
+ BMUNIT *bits;
+ int bytes_wide, bit_skip, w, h;
+{
+ BMUNIT *ptr, *endp;
+ register BMUNIT *cp;
+ int bits_left;
+ register int n, bit_shift, wid;
+
+ ptr = bits + bit_skip / BITS_PER_BMUNIT;
+ endp = ADD(bits, h * bytes_wide);
+ bits_left = w;
+#ifndef MSBITFIRST
+ bit_shift = bit_skip % BITS_PER_BMUNIT;
+#else
+ bit_shift = BITS_PER_BMUNIT - bit_skip % BITS_PER_BMUNIT;
+#endif
+ n = 0;
+ while (bits_left) {
+#ifndef MSBITFIRST
+ wid = BITS_PER_BMUNIT - bit_shift;
+#else
+ wid = bit_shift;
+#endif
+ if (wid > bits_left) wid = bits_left;
+ if (wid > 4) wid = 4;
+#ifdef MSBITFIRST
+ bit_shift -= wid;
+#endif
+ for (cp = ptr; cp < endp; cp = ADD(cp, bytes_wide))
+ n += sample_count[(*cp >> bit_shift) & bit_masks[wid]];
+#ifndef MSBITFIRST
+ bit_shift += wid;
+ if (bit_shift == BITS_PER_BMUNIT) {
+ bit_shift = 0;
+ ++ptr;
+ }
+#else
+ if (bit_shift == 0) {
+ bit_shift = BITS_PER_BMUNIT;
+ ++ptr;
+ }
+#endif
+ bits_left -= wid;
+ }
+ return n;
+}
+
+#ifdef GREY
+static void
+shrink_glyph_grey(g)
+ register struct glyph *g;
+{
+ int rows_left, rows, init_cols, cols_left;
+ register int cols;
+ int x, y;
+ long thesample;
+ BMUNIT *old_ptr;
+
+ /* These machinations ensure that the character is shrunk according to
+ its hot point, rather than its upper left-hand corner. */
+ g->x2 = g->x / shrink_factor;
+ init_cols = g->x - g->x2 * shrink_factor;
+ if (init_cols <= 0) init_cols += shrink_factor;
+ else ++g->x2;
+ g->bitmap2.w = g->x2 + ROUNDUP(g->bitmap.w - g->x, shrink_factor);
+ /* include row zero with the positively numbered rows */
+ cols = g->y + 1; /* spare register variable */
+ g->y2 = cols / shrink_factor;
+ rows = cols - g->y2 * shrink_factor;
+ if (rows <= 0) {
+ rows += shrink_factor;
+ --g->y2;
+ }
+ g->bitmap2.h = g->y2 + ROUNDUP(g->bitmap.h - cols, shrink_factor) + 1;
+
+ g->image2 = XCreateImage(DISP, DefaultVisualOfScreen(SCRN),
+ DefaultDepthOfScreen(SCRN),
+ ZPixmap, 0, (char *) NULL,
+ g->bitmap2.w, g->bitmap2.h,
+ BITS_PER_BMUNIT, 0);
+ g->pixmap2 = g->image2->data = xmalloc((unsigned)
+ g->image2->bytes_per_line * g->bitmap2.h,
+ "character pixmap");
+
+ old_ptr = (BMUNIT *) g->bitmap.bits;
+ rows_left = g->bitmap.h;
+ y = 0;
+ while (rows_left) {
+ x = 0;
+ if (rows > rows_left) rows = rows_left;
+ cols_left = g->bitmap.w;
+ cols = init_cols;
+ while (cols_left) {
+ if (cols > cols_left) cols = cols_left;
+
+ thesample = sample(old_ptr, g->bitmap.bytes_wide,
+ g->bitmap.w - cols_left, cols, rows);
+ XPutPixel(g->image2, x, y, pixeltbl[thesample]);
+
+ cols_left -= cols;
+ cols = shrink_factor;
+ x++;
+ }
+ *((char **) &old_ptr) += rows * g->bitmap.bytes_wide;
+ rows_left -= rows;
+ rows = shrink_factor;
+ y++;
+ }
+
+ while (y < g->bitmap2.h) {
+ for (x = 0; x < g->bitmap2.w; x++)
+ XPutPixel(g->image2, x, y, *pixeltbl);
+ y++;
+ }
+
+ g->y2 = g->y / shrink_factor;
+}
+#endif /* GREY */
+
+static void
+shrink_glyph(g)
+ register struct glyph *g;
+{
+ int shrunk_bytes_wide, shrunk_height;
+ int rows_left, rows, init_cols, cols_left;
+ register int cols;
+ BMUNIT *old_ptr, *new_ptr;
+ register BMUNIT m, *cp;
+ int min_sample = shrink_factor * shrink_factor * density / 100;
+
+ /* These machinations ensure that the character is shrunk according to
+ its hot point, rather than its upper left-hand corner. */
+ g->x2 = g->x / shrink_factor;
+ init_cols = g->x - g->x2 * shrink_factor;
+ if (init_cols <= 0) init_cols += shrink_factor;
+ else ++g->x2;
+ g->bitmap2.w = g->x2 + ROUNDUP(g->bitmap.w - g->x, shrink_factor);
+ /* include row zero with the positively numbered rows */
+ cols = g->y + 1; /* spare register variable */
+ g->y2 = cols / shrink_factor;
+ rows = cols - g->y2 * shrink_factor;
+ if (rows <= 0) {
+ rows += shrink_factor;
+ --g->y2;
+ }
+ g->bitmap2.h = shrunk_height = g->y2 +
+ ROUNDUP(g->bitmap.h - cols, shrink_factor) + 1;
+ alloc_bitmap(&g->bitmap2);
+ old_ptr = (BMUNIT *) g->bitmap.bits;
+ new_ptr = (BMUNIT *) g->bitmap2.bits;
+ shrunk_bytes_wide = g->bitmap2.bytes_wide;
+ rows_left = g->bitmap.h;
+ bzero((char *) new_ptr, shrunk_bytes_wide * shrunk_height);
+ while (rows_left) {
+ if (rows > rows_left) rows = rows_left;
+ cols_left = g->bitmap.w;
+#ifndef MSBITFIRST
+ m = (1 << 0);
+#else
+ m = (1 << (BITS_PER_BMUNIT-1));
+#endif
+ cp = new_ptr;
+ cols = init_cols;
+ while (cols_left) {
+ if (cols > cols_left) cols = cols_left;
+ if (sample(old_ptr, g->bitmap.bytes_wide,
+ g->bitmap.w - cols_left, cols, rows) >= min_sample)
+ *cp |= m;
+#ifndef MSBITFIRST
+ if (m == (BMUNIT)(1 << (BITS_PER_BMUNIT-1))) {
+ m = (1 << 0);
+ ++cp;
+ }
+ else m <<= 1;
+#else
+ if (m == (1 << 0)) {
+ m = (1 << (BITS_PER_BMUNIT-1));
+ ++cp;
+ }
+ else m >>= 1;
+#endif
+ cols_left -= cols;
+ cols = shrink_factor;
+ }
+ *((char **) &new_ptr) += shrunk_bytes_wide;
+ *((char **) &old_ptr) += rows * g->bitmap.bytes_wide;
+ rows_left -= rows;
+ rows = shrink_factor;
+ }
+ g->y2 = g->y / shrink_factor;
+ if (debug & DBG_BITMAP)
+ print_bitmap(&g->bitmap2);
+}
+
+/*
+ * Find font #n.
+ */
+
+static void
+change_font(n)
+ unsigned long n;
+{
+ register struct tn *tnp;
+
+ currinf.fontp = NULL;
+ for (tnp = currinf.tn_head; tnp != NULL; tnp = tnp->next)
+ if (tnp->TeXnumber == n) {
+ currinf.fontp = tnp->fontp;
+ if (!(currinf.fontp->flags & FONT_LOADED))
+ load_font(currinf.fontp);
+ break;
+ }
+ if (currinf.fontp == NULL) tell_oops("non-existent font #%d", n);
+ maxchar = currinf.fontp->maxchar;
+ currinf.set_char_p = currinf.fontp->set_char_p;
+}
+
+
+/*
+ * Open a font file.
+ */
+
+static void
+open_font_file(fontp)
+ struct font *fontp;
+{
+ if (fontp->file == NULL) {
+ fontp->file = xfopen(fontp->filename);
+ if (fontp->file == NULL)
+ oops("Font file disappeared: %s", fontp->filename);
+ }
+}
+
+
+/*
+ * Routines to print characters.
+ */
+
+#ifndef TEXXET
+#define ERRVAL 0L
+#else
+#define ERRVAL
+#endif
+
+#ifndef TEXXET
+long
+set_char(ch)
+#else
+void
+set_char(cmd, ch)
+ WIDEARG(ubyte, int) cmd;
+#endif
+ WIDEARG(ubyte, int) ch;
+{
+ register struct glyph *g;
+#ifdef TEXXET
+ long dvi_h_sav;
+#endif
+
+ if (ch > maxchar) realloc_font(currinf.fontp, WIDEARG(,(int)) ch);
+ if ((g = &currinf.fontp->glyph[ch])->bitmap.bits == NULL) {
+ if (g->addr == 0) {
+ if (!hush_chars)
+ Fprintf(stderr, "Character %d not defined in font %s\n", ch,
+ currinf.fontp->fontname);
+ g->addr = -1;
+ return ERRVAL;
+ }
+ if (g->addr == -1)
+ return ERRVAL; /* previously flagged missing char */
+ open_font_file(currinf.fontp);
+ Fseek(currinf.fontp->file, g->addr, 0);
+ (*currinf.fontp->read_char)(currinf.fontp, ch);
+ if (debug & DBG_BITMAP) print_char((ubyte) ch, g);
+ currinf.fontp->timestamp = ++current_timestamp;
+ }
+
+#ifdef TEXXET
+ dvi_h_sav = DVI_H;
+ if (currinf.dir < 0) DVI_H -= g->dvi_adv;
+ if (scan_frame == NULL) {
+#endif
+ if (shrink_factor == 1)
+ put_bitmap(&g->bitmap, PXL_H - g->x, PXL_V - g->y);
+ else {
+#ifdef GREY
+ if (use_grey) {
+ if (g->pixmap2 == NULL) {
+ shrink_glyph_grey(g);
+ }
+ put_image(g->image2, PXL_H - g->x2, PXL_V - g->y2);
+ } else {
+ if (g->bitmap2.bits == NULL) {
+ shrink_glyph(g);
+ }
+ put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
+ }
+#else
+ if (g->bitmap2.bits == NULL) {
+ shrink_glyph(g);
+ }
+ put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
+#endif
+ }
+#ifndef TEXXET
+ return g->dvi_adv;
+#else
+ }
+ if (cmd == PUT1)
+ DVI_H = dvi_h_sav;
+ else
+ if (currinf.dir > 0) DVI_H += g->dvi_adv;
+#endif
+}
+
+
+#ifndef TEXXET
+long
+set_vf_char(ch)
+#else
+void
+set_vf_char(cmd, ch)
+ WIDEARG(ubyte, int) cmd;
+#endif
+ WIDEARG(ubyte, int) ch;
+{
+ register struct macro *m;
+ struct drawinf oldinfo;
+ ubyte oldmaxchar;
+ static ubyte c;
+#ifdef TEXXET
+ long dvi_h_sav;
+#endif
+
+ if (ch > maxchar) realloc_virtual_font(currinf.fontp, ch);
+ if ((m = &currinf.fontp->macro[ch])->pos == NULL) {
+ if (!hush_chars)
+ Fprintf(stderr, "Character %d not defined in font %s\n", ch,
+ currinf.fontp->fontname);
+ m->pos = m->end = &c;
+ return ERRVAL;
+ }
+#ifdef TEXXET
+ dvi_h_sav = DVI_H;
+ if (currinf.dir < 0) DVI_H -= m->dvi_adv;
+ if (scan_frame == NULL) {
+#endif
+ oldinfo = currinf;
+ oldmaxchar = maxchar;
+ WW = XX = YY = ZZ = 0;
+ currinf.tn_head = currinf.fontp->vf_chain;
+ currinf.pos = m->pos;
+ currinf.end = m->end;
+ currinf.virtual = currinf.fontp;
+ draw_part(current_frame, currinf.fontp->dimconv);
+ if (currinf.pos != currinf.end + 1)
+ tell_oops("virtual character macro does not end correctly");
+ currinf = oldinfo;
+ maxchar = oldmaxchar;
+#ifndef TEXXET
+ return m->dvi_adv;
+#else
+ }
+ if (cmd == PUT1)
+ DVI_H = dvi_h_sav;
+ else
+ if (currinf.dir > 0) DVI_H += m->dvi_adv;
+#endif
+}
+
+
+#ifndef TEXXET
+static long
+set_no_char(ch)
+#else
+static void
+set_no_char(cmd, ch)
+ ubyte cmd;
+#endif
+ ubyte ch;
+{
+ if (currinf.virtual) {
+ currinf.fontp = currinf.virtual->first_font;
+ if (currinf.fontp != NULL) {
+ if (!(currinf.fontp->flags & FONT_LOADED))
+ load_font(currinf.fontp);
+ maxchar = currinf.fontp->maxchar;
+ currinf.set_char_p = currinf.fontp->set_char_p;
+#ifndef TEXXET
+ return (*currinf.set_char_p)(ch);
+#else
+ (*currinf.set_char_p)(cmd, ch);
+ return;
+#endif
+ }
+ }
+ tell_oops("attempt to set character of unknown font");
+ /* NOTREACHED */
+}
+
+
+/*
+ * Set rule. Arguments are coordinates of lower left corner.
+ */
+
+static void
+set_rule(h, w)
+ int h, w;
+{
+#ifndef TEXXET
+ put_rectangle(PXL_H, PXL_V - h + 1, w, h, False);
+#else
+ put_rectangle(PXL_H - (currinf.dir < 0 ? w - 1 : 0), PXL_V - h + 1,
+ w, h, False);
+#endif
+}
+
+static void
+put_border(w, h)
+ int w, h;
+{
+ put_rectangle(0, 0, w, 1, True); /* top */
+ put_rectangle(w, 0, 1, h, True); /* right */
+ put_rectangle(1, h, w, 1, True); /* bottom */
+ put_rectangle(0, 1, 1, h, True); /* left */
+}
+
+static void
+special(nbytes)
+ long nbytes;
+{
+ static char *cmd = NULL;
+ static long cmdlen = -1;
+ char *p;
+
+ if (cmdlen < nbytes) {
+ if (cmd) free(cmd);
+ cmd = xmalloc((unsigned) nbytes + 1, "special");
+ cmdlen = nbytes;
+ }
+ p = cmd;
+ for (;;) {
+ int i = currinf.end - currinf.pos;
+
+ if (i > nbytes) i = nbytes;
+ bcopy((_Xconst char *) currinf.pos, p, i);
+ currinf.pos += i;
+ p += i;
+ nbytes -= i;
+ if (nbytes == 0) break;
+ (void) xxone();
+ --(currinf.pos);
+ }
+ *p = '\0';
+ applicationDoSpecial(cmd);
+}
+
+#define xspell_conv(n) spell_conv0(n, current_dimconv)
+
+static void
+draw_part(minframe, current_dimconv)
+ struct frame *minframe;
+ double current_dimconv;
+{
+ ubyte ch;
+#ifdef TEXXET
+ struct drawinf oldinfo;
+ ubyte oldmaxchar;
+ off_t file_pos;
+ int refl_count;
+#endif
+
+ currinf.fontp = NULL;
+ currinf.set_char_p = set_no_char;
+#ifdef TEXXET
+ currinf.dir = 1;
+ scan_frame = NULL; /* indicates we're not scanning */
+#endif
+ for (;;) {
+ ch = xone();
+ if (debug & DBG_DVI)
+ print_dvi(ch);
+ if (ch <= SETCHAR0 + 127)
+#ifndef TEXXET
+ DVI_H += (*currinf.set_char_p)(ch);
+#else
+ (*currinf.set_char_p)(ch, ch);
+#endif
+ else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63)
+ change_font((unsigned long) (ch - FNTNUM0));
+ else {
+ long a, b;
+
+ switch (ch) {
+ case SET1:
+ case PUT1:
+#ifndef TEXXET
+ a = (*currinf.set_char_p)(xone());
+ if (ch != PUT1) DVI_H += a;
+#else
+ (*currinf.set_char_p)(ch, xone());
+#endif
+ break;
+
+ case SETRULE:
+ /* Be careful, dvicopy outputs rules with
+ height = 0x80000000. We don't want any
+ SIGFPE here. */
+ a = xsfour();
+ b = xspell_conv(xsfour());
+#ifndef TEXXET
+ if (a > 0 && b > 0)
+#else
+ if (a > 0 && b > 0 && scan_frame == NULL)
+#endif
+ set_rule(pixel_round(xspell_conv(a)),
+ pixel_round(b));
+ DVI_H += DIR * b;
+ break;
+
+ case PUTRULE:
+ a = xspell_conv(xsfour());
+ b = xspell_conv(xsfour());
+#ifndef TEXXET
+ if (a > 0 && b > 0)
+#else
+ if (a > 0 && b > 0 && scan_frame == NULL)
+#endif
+ set_rule(pixel_round(a), pixel_round(b));
+ break;
+
+ case NOP:
+ break;
+
+ case BOP:
+ xskip((long) 11 * 4);
+ DVI_H = OFFSET_X;
+ DVI_V = OFFSET_Y;
+ PXL_V = pixel_conv(DVI_V);
+ WW = XX = YY = ZZ = 0;
+ break;
+
+ case EOP:
+ if (current_frame != minframe)
+ tell_oops("stack not empty at EOP");
+ return;
+
+ case PUSH:
+ if (current_frame->next == NULL) {
+ struct frame *newp = (struct frame *)
+ xmalloc(sizeof(struct frame), "stack frame");
+ current_frame->next = newp;
+ newp->prev = current_frame;
+ newp->next = NULL;
+ }
+ current_frame = current_frame->next;
+ current_frame->data = currinf.data;
+ break;
+
+ case POP:
+ if (current_frame == minframe)
+ tell_oops("more POPs than PUSHes");
+ currinf.data = current_frame->data;
+ current_frame = current_frame->prev;
+ break;
+
+#ifdef TEXXET
+ case SREFL:
+ if (scan_frame == NULL) {
+ /* we're not scanning: save some info. */
+ oldinfo = currinf;
+ oldmaxchar = maxchar;
+ if (!currinf.virtual)
+ file_pos = xtell(currinf.pos);
+ scan_frame = current_frame; /* now we're scanning */
+ refl_count = 0;
+ break;
+ }
+ /* we are scanning */
+ if (current_frame == scan_frame) ++refl_count;
+ break;
+
+ case EREFL:
+ if (scan_frame != NULL) { /* if we're scanning */
+ if (current_frame == scan_frame && --refl_count < 0)
+ {
+ /* we've hit the end of our scan */
+ scan_frame = NULL;
+ /* first: push */
+ if (current_frame->next == NULL) {
+ struct frame *newp = (struct frame *)
+ xmalloc(sizeof(struct frame),
+ "stack frame");
+ current_frame->next = newp;
+ newp->prev = current_frame;
+ newp->next = NULL;
+ }
+ current_frame = current_frame->next;
+ current_frame->data = currinf.data;
+ /* next: restore old file position, XX, etc. */
+ if (!currinf.virtual) {
+ off_t bgn_pos = xtell(dvi_buffer);
+
+ if (file_pos >= bgn_pos) {
+ oldinfo.pos = dvi_buffer
+ + (file_pos - bgn_pos);
+ oldinfo.end = currinf.end;
+ }
+ else {
+ (void) lseek(fileno(dvi_file), file_pos,
+ SEEK_SET);
+ oldinfo.pos = oldinfo.end;
+ }
+ }
+ currinf = oldinfo;
+ maxchar = oldmaxchar;
+ /* and then: recover position info. */
+ DVI_H = current_frame->data.dvi_h;
+ DVI_V = current_frame->data.dvi_v;
+ PXL_V = current_frame->data.pxl_v;
+ /* and finally, reverse direction */
+ currinf.dir = -currinf.dir;
+ }
+ break;
+ }
+ /* we're not scanning, */
+ /* so just reverse direction and then pop */
+ currinf.dir = -currinf.dir;
+ currinf.data = current_frame->data;
+ current_frame = current_frame->prev;
+ break;
+#endif /* TEXXET */
+
+ case RIGHT1:
+ case RIGHT2:
+ case RIGHT3:
+ case RIGHT4:
+ DVI_H += DIR * xspell_conv(xsnum(ch - RIGHT1 + 1));
+ break;
+
+ case W1:
+ case W2:
+ case W3:
+ case W4:
+ WW = xspell_conv(xsnum(ch - W0));
+ case W0:
+ DVI_H += DIR * WW;
+ break;
+
+ case X1:
+ case X2:
+ case X3:
+ case X4:
+ XX = xspell_conv(xsnum(ch - X0));
+ case X0:
+ DVI_H += DIR * XX;
+ break;
+
+ case DOWN1:
+ case DOWN2:
+ case DOWN3:
+ case DOWN4:
+ DVI_V += xspell_conv(xsnum(ch - DOWN1 + 1));
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case Y1:
+ case Y2:
+ case Y3:
+ case Y4:
+ YY = xspell_conv(xsnum(ch - Y0));
+ case Y0:
+ DVI_V += YY;
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case Z1:
+ case Z2:
+ case Z3:
+ case Z4:
+ ZZ = xspell_conv(xsnum(ch - Z0));
+ case Z0:
+ DVI_V += ZZ;
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case FNT1:
+ case FNT2:
+ case FNT3:
+ case FNT4:
+ change_font(xnum(ch - FNT1 + 1));
+ break;
+
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ a = xnum(ch - XXX1 + 1);
+ if (a > 0)
+ special(a);
+ break;
+
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ xskip((long) (12 + ch - FNTDEF1 + 1));
+ xskip((long) xone() + (long) xone());
+ break;
+
+#ifndef TEXXET
+ case SREFL:
+ case EREFL:
+#endif
+ case PRE:
+ case POST:
+ case POSTPOST:
+ tell_oops("shouldn't happen: %s encountered",
+ dvi_table2[ch - (FNTNUM0 + 64)]);
+ break;
+
+ default:
+ tell_oops("unknown op-code %d", ch);
+ } /* end switch*/
+ } /* end else (ch not a SETCHAR or FNTNUM) */
+ } /* end for */
+}
+
+#undef xspell_conv
+
+void
+draw_page()
+{
+ /* Check for changes in dvi file. */
+ if (!check_dvi_file()) return;
+
+ put_border(ROUNDUP(unshrunk_paper_w, shrink_factor) + 1,
+ ROUNDUP(unshrunk_paper_h, shrink_factor) + 1);
+
+ (void) lseek(fileno(dvi_file), page_offset[current_page], SEEK_SET);
+
+ bzero((char *) &currinf.data, sizeof(currinf.data));
+ currinf.tn_head = tn_head;
+ currinf.pos = currinf.end = dvi_buffer;
+ currinf.virtual = NULL;
+ draw_part(current_frame = &frame0, dimconv);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi_init.c b/systems/msdos/dviware/xdvi-dos/src/dvi_init.c
new file mode 100644
index 0000000000..f257cd579f
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi_init.c
@@ -0,0 +1,639 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+#include "xdvi.h"
+#include "dvi.h"
+#include <sys/stat.h>
+
+#ifdef sun
+extern char *sprintf();
+#endif
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+char *realloc();
+#endif
+#if defined(macII) && !defined(__STDC__) /* stdlib.h doesn't define these */
+char *realloc();
+#endif /* macII */
+
+#define PK_PRE 247
+#define PK_ID 89
+#define PK_MAGIC (PK_PRE << 8) + PK_ID
+#define GF_PRE 247
+#define GF_ID 131
+#define GF_MAGIC (GF_PRE << 8) + GF_ID
+#define VF_PRE 247
+#define VF_ID_BYTE 202
+#define VF_MAGIC (VF_PRE << 8) + VF_ID_BYTE
+#define PXL_MAGIC1 0
+#define PXL_MAGIC2 1001
+
+#define dvi_oops(str) longjmp(dvi_env, (int) str);
+
+static struct stat fstatbuf;
+
+static Boolean font_not_found;
+
+/*
+ * DVI preamble and postamble information.
+ */
+static char job_id[300];
+static long numerator, denominator, magnification;
+
+/*
+ * Offset in DVI file of last page, set in read_postamble().
+ */
+static long last_page_offset;
+
+
+/*
+ * free_vf_chain frees the vf_chain structure.
+ */
+
+static void
+free_vf_chain(tnp)
+ struct tn *tnp;
+{
+ while (tnp != NULL) {
+ register struct tn *tnp1 = tnp->next;
+ free((char *) tnp);
+ tnp = tnp1;
+ }
+}
+
+
+/*
+ * Release all shrunken bitmaps for all fonts.
+ */
+
+void
+reset_fonts()
+{
+ register struct font *f;
+ register struct glyph *g;
+
+ for (f = font_head; f != NULL; f = f->next)
+ if ((f->flags & FONT_LOADED) && !(f->flags & FONT_VIRTUAL))
+ for (g = f->glyph; g <= f->glyph + f->maxchar; ++g) {
+ if (g->bitmap2.bits) {
+ free(g->bitmap2.bits);
+ g->bitmap2.bits = NULL;
+ }
+#ifdef GREY
+ if (g->pixmap2) {
+ XDestroyImage(g->image2);
+ g->pixmap2 = NULL;
+ }
+#endif
+ }
+}
+
+/*
+ * realloc_font allocates the font structure to contain (newsize + 1)
+ * characters.
+ */
+
+void
+realloc_font(fontp, newsize)
+ struct font *fontp;
+ WIDEARG(ubyte, int) newsize;
+{
+ struct glyph *glyph;
+
+ glyph = fontp->glyph = (struct glyph *) realloc((char *) fontp->glyph,
+ ((unsigned int) newsize + 1) * sizeof(struct glyph));
+ if (glyph == NULL) oops("! Cannot reallocate space for glyph array.");
+ if (newsize > fontp->maxchar)
+ bzero((char *) (glyph + fontp->maxchar + 1),
+ (int) (newsize - fontp->maxchar) * sizeof(struct glyph));
+ maxchar = fontp->maxchar = newsize;
+}
+
+
+/*
+ * realloc_virtual_font does the same thing for virtual fonts.
+ */
+
+void
+realloc_virtual_font(fontp, newsize)
+ struct font *fontp;
+ WIDEARG(ubyte, int) newsize;
+{
+ struct macro *macro;
+
+ macro = fontp->macro = (struct macro *) realloc((char *) fontp->macro,
+ ((unsigned int) newsize + 1) * sizeof(struct macro));
+ if (macro == NULL) oops("! Cannot reallocate space for macro array.");
+ if (newsize > fontp->maxchar)
+ bzero((char *) (macro + fontp->maxchar + 1),
+ (int) (newsize - fontp->maxchar) * sizeof(struct macro));
+ maxchar = fontp->maxchar = newsize;
+}
+
+
+/*
+ * load_font locates the raster file and reads the index of characters,
+ * plus whatever other preprocessing is done (depending on the format).
+ */
+
+void
+load_font(fontp)
+ struct font *fontp;
+{
+ float fsize = fontp->fsize;
+ int dpi = fsize + 0.5;
+ char *font_found;
+ int size_found;
+ int magic;
+
+ fontp->flags |= FONT_LOADED;
+ fontp->file = font_open(fontp->fontname, &font_found,
+ (WIDEARG(float, double)) fsize, &size_found, fontp->magstepval,
+ &fontp->filename);
+ if (fontp->file == NULL) {
+ Fprintf(stderr, "Can't find font %s.\n", fontp->fontname);
+ font_not_found = True;
+ return;
+ }
+ --n_files_left;
+ if (font_found != NULL) {
+ Fprintf(stderr,
+ "Can't find font %s; using %s instead at %d dpi\n",
+ fontp->fontname, font_found, dpi);
+ free(fontp->fontname);
+ fontp->fontname = font_found;
+ }
+ else if (size_found > (int) (5 * 1.002 * fsize + 0.5) ||
+ size_found < (int) (5 * 0.998 * fsize + 0.5))
+ Fprintf(stderr,
+ "Can't find font %s at %d dpi; using %d dpi instead.\n",
+ fontp->fontname, dpi, (size_found + 2) / 5);
+ fontp->fsize = (float) size_found / 5;
+ fontp->timestamp = ++current_timestamp;
+ fontp->maxchar = maxchar = 255;
+ fontp->set_char_p = set_char;
+ magic = two(fontp->file);
+#ifdef USE_PK
+ if (magic == PK_MAGIC) read_PK_index(fontp);
+ else
+#endif
+#ifdef USE_GF
+ if (magic == GF_MAGIC) read_GF_index(fontp);
+ else
+#endif
+ if (magic == VF_MAGIC) read_VF_index(fontp);
+ else
+#ifdef USE_PXL
+ if (magic == PXL_MAGIC1 && two(fontp->file) == PXL_MAGIC2)
+ read_PXL_index(fontp);
+ else
+#endif
+ oops("Cannot recognize format for font file %s", fontp->filename);
+
+ if (fontp->flags & FONT_VIRTUAL) {
+ while (maxchar > 0 && fontp->macro[maxchar].pos == NULL) --maxchar;
+ if (maxchar < 255)
+ realloc_virtual_font(fontp, WIDEARG(,(int)) maxchar);
+ }
+ else {
+ while (maxchar > 0 && fontp->glyph[maxchar].addr == 0) --maxchar;
+ if (maxchar < 255)
+ realloc_font(fontp, WIDEARG(,(int)) maxchar);
+ }
+}
+
+
+/*
+ * MAGSTEPVALUE - If the given magnification is close to a \magstep
+ * or a \magstephalf, then return twice the number of \magsteps.
+ * Otherwise return NOMAGSTP.
+ */
+
+#define NOMAGSTP (-29999)
+#define NOBUILD 29999
+
+static int
+magstepvalue(mag)
+ float *mag;
+{
+ int m = 0;
+ double fmag = *mag;
+ double xmag = pixels_per_inch;
+ float margin = fmag * 0.002;
+
+ if (fmag < pixels_per_inch)
+ for (;;) {
+ if (xmag - fmag < margin && -(xmag - fmag) < margin) {
+ *mag = xmag;
+ return m;
+ }
+ if (xmag < fmag) break;
+ xmag *= 0.9128709292;
+ --m;
+ }
+ else
+ for (;;) {
+ if (xmag - fmag < margin && -(xmag - fmag) < margin) {
+ *mag = xmag;
+ return m;
+ }
+ if (xmag > fmag) break;
+ xmag *= 1.095445115;
+ ++m;
+ }
+ return NOMAGSTP;
+}
+
+
+/*
+ * reuse_font recursively sets the flags for font structures being reused.
+ */
+
+static void
+reuse_font(fontp)
+ struct font *fontp;
+{
+ struct tn *tnp;
+
+ if (fontp->flags & FONT_IN_USE) return;
+
+ fontp->flags |= FONT_IN_USE;
+ if (list_fonts)
+ Printf("(reusing) %s at %d dpi\n", fontp->fontname,
+ (int) (fontp->fsize + 0.5));
+ if (fontp->flags & FONT_VIRTUAL)
+ for (tnp = fontp->vf_chain; tnp != NULL; tnp = tnp->next)
+ reuse_font(tnp->fontp);
+}
+
+
+/*
+ * define_font reads the rest of the fntdef command and then reads in
+ * the specified pixel file, adding it to the global linked-list holding
+ * all of the fonts used in the job.
+ */
+void
+define_font(file, cmnd, vfparent, tn_headpp)
+ FILE *file;
+ WIDEARG(ubyte, unsigned int) cmnd;
+ struct font *vfparent; /* vf parent of this font, or NULL */
+ struct tn **tn_headpp; /* addr of head of list of TeXnumbers */
+{
+ register struct tn *tnp;
+ struct font *fontp;
+ float fsize;
+ double scale_dimconv;
+ int scale;
+ int design;
+ int magstepval;
+ int len;
+ char *fontname;
+ int size;
+
+ tnp = (struct tn *) xmalloc((unsigned) sizeof(struct tn),
+ "TeXnumber structure");
+ tnp->next = *tn_headpp;
+ *tn_headpp = tnp;
+ tnp->TeXnumber = num(file, (int) cmnd - FNTDEF1 + 1);
+ (void) four(file); /* checksum */
+ scale = four(file);
+ design = four(file);
+ len = one(file) + one(file);
+ fontname = xmalloc((unsigned) len + 1, "font name");
+ Fread(fontname, sizeof(char), len, file);
+ fontname[len] = '\0';
+ if(debug & DBG_PK)
+ Printf("Define font \"%s\" scale=%d design=%d\n",
+ fontname, scale, design);
+ if (vfparent == NULL) {
+ fsize = 0.001 * scale / design * magnification * pixels_per_inch;
+ scale_dimconv = dimconv;
+ }
+ else {
+ /*
+ * The scaled size is given in units of vfparent->scale * 2 ** -20
+ * SPELL units, so we convert it into SPELL units by multiplying by
+ * vfparent->dimconv.
+ * The design size is given in units of 2 ** -20 pt, so we convert
+ * into SPELL units by multiplying by
+ * (pixels_per_inch * 2**16) / (72.27 * 2**20).
+ */
+ fsize = (72.27 * (1<<4)) * vfparent->dimconv * scale / design;
+ scale_dimconv = vfparent->dimconv;
+ }
+ magstepval = magstepvalue(&fsize);
+ size = 5 * fsize + 0.5;
+ /*
+ * reuse font if possible
+ */
+ for (fontp = font_head;; fontp = fontp->next) {
+ if (fontp == NULL) { /* if font doesn't exist yet */
+ if (list_fonts)
+ Printf("%s at %d dpi\n", fontname, (int) (fsize + 0.5));
+ fontp = (struct font *) xmalloc((unsigned) sizeof(struct font),
+ "font structure");
+ fontp->dimconv = scale * scale_dimconv / (1<<20);
+ fontp->fontname = fontname;
+ fontp->fsize = fsize;
+ fontp->magstepval = magstepval;
+ fontp->flags = FONT_IN_USE;
+ if (vfparent == NULL) load_font(fontp);
+ fontp->next = font_head;
+ font_head = fontp;
+ break;
+ }
+ if (strcmp(fontname, fontp->fontname) == 0
+ && size == (int) (5 * fontp->fsize + 0.5)) {
+ /* if font already in use */
+ reuse_font(fontp);
+ free(fontname);
+ break;
+ }
+ }
+ tnp->fontp = fontp;
+}
+
+
+/*
+ * process_preamble reads the information in the preamble and stores
+ * it into global variables for later use.
+ */
+static void
+process_preamble()
+{
+ ubyte k;
+
+ if (one(dvi_file) != PRE)
+ dvi_oops("DVI file doesn't start with preamble");
+ if (one(dvi_file) != 2)
+ dvi_oops("Wrong version of DVI output for this program");
+ numerator = four(dvi_file);
+ denominator = four(dvi_file);
+ magnification = four(dvi_file);
+ dimconv = (((double) numerator * magnification)
+ / ((double) denominator * 1000.));
+ dimconv = dimconv * (((long) pixels_per_inch)<<16) / 254000;
+ specialConv = pixels_per_inch * magnification / 1000000.0;
+ k = one(dvi_file);
+ Fread(job_id, sizeof(char), (int) k, dvi_file);
+ job_id[k] = '\0';
+}
+
+/*
+ * find_postamble locates the beginning of the postamble
+ * and leaves the file ready to start reading at that location.
+ */
+#define TMPSIZ 516 /* 4 trailer bytes + 512 junk bytes allowed */
+static void
+find_postamble()
+{
+ long pos;
+ ubyte temp[TMPSIZ];
+ ubyte *p;
+ ubyte *p1;
+ ubyte byte;
+
+ Fseek(dvi_file, (long) 0, 2);
+ pos = ftell(dvi_file) - TMPSIZ;
+ if (pos < 0) pos = 0;
+ Fseek(dvi_file, pos, 0);
+ p = temp + fread((char *) temp, sizeof(char), TMPSIZ, dvi_file);
+ for (;;) {
+ p1 = p;
+ while (p1 > temp && *(--p1) != TRAILER) ;
+ p = p1;
+ while (p > temp && *(--p) == TRAILER) ;
+ if (p <= p1 - 4) break; /* found 4 TRAILER bytes */
+ if (p <= temp) dvi_oops("DVI file corrupted");
+ }
+ pos += p - temp;
+ byte = *p;
+ while (byte == TRAILER) {
+ Fseek(dvi_file, --pos, 0);
+ byte = one(dvi_file);
+ }
+ if (byte != 2)
+ dvi_oops("Wrong version of DVI output for this program");
+ Fseek(dvi_file, pos - 4, 0);
+ Fseek(dvi_file, sfour(dvi_file), 0);
+}
+
+
+/*
+ * read_postamble reads the information in the postamble,
+ * storing it into global variables.
+ * It also takes care of reading in all of the pixel files for the fonts
+ * used in the job.
+ */
+static void
+read_postamble()
+{
+ ubyte cmnd;
+ struct font *fontp;
+ struct font **fontpp;
+
+ if (one(dvi_file) != POST)
+ dvi_oops("Postamble doesn't begin with POST");
+ last_page_offset = four(dvi_file);
+ if (numerator != four(dvi_file)
+ || denominator != four(dvi_file)
+ || magnification != four(dvi_file))
+ dvi_oops("Postamble doesn't match preamble");
+ /* read largest box height and width */
+ unshrunk_page_h = (spell_conv(sfour(dvi_file)) >> 16) + offset_y;
+ if (unshrunk_page_h < unshrunk_paper_h)
+ unshrunk_page_h = unshrunk_paper_h;
+ unshrunk_page_w = (spell_conv(sfour(dvi_file)) >> 16) + offset_x;
+ if (unshrunk_page_w < unshrunk_paper_w)
+ unshrunk_page_w = unshrunk_paper_w;
+ (void) two(dvi_file); /* max stack size */
+ total_pages = two(dvi_file);
+ font_not_found = False;
+ while ((cmnd = one(dvi_file)) >= FNTDEF1 && cmnd <= FNTDEF4)
+ define_font(dvi_file, cmnd, (struct font *) NULL, &tn_head);
+ if (cmnd != POSTPOST)
+ dvi_oops("Non-fntdef command found in postamble");
+ if (font_not_found)
+ dvi_oops("Not all pixel files were found");
+ /*
+ * free up fonts no longer in use
+ */
+ fontpp = &font_head;
+ while ((fontp = *fontpp) != NULL)
+ if (fontp->flags & FONT_IN_USE)
+ fontpp = &fontp->next;
+ else {
+ if (debug & DBG_PK)
+ Printf("Discarding font \"%s\" at %d dpi\n",
+ fontp->fontname, (int) (fontp->fsize + 0.5));
+ *fontpp = fontp->next; /* remove from list */
+ free(fontp->fontname);
+ if (fontp->flags & FONT_LOADED) {
+ if (fontp->file != NULL) {
+ Fclose(fontp->file);
+ ++n_files_left;
+ }
+ free(fontp->filename);
+ if (fontp->flags & FONT_VIRTUAL) {
+ register struct macro *m;
+
+ for (m = fontp->macro;
+ m <= fontp->macro + fontp->maxchar; ++m)
+ if (m->free_me) free((char *) m->pos);
+ free((char *) fontp->macro);
+ free_vf_chain(fontp->vf_chain);
+ }
+ else {
+ register struct glyph *g;
+
+ for (g = fontp->glyph;
+ g <= fontp->glyph + fontp->maxchar; ++g) {
+ if (g->bitmap.bits != NULL) free(g->bitmap.bits);
+ if (g->bitmap2.bits != NULL) free(g->bitmap2.bits);
+#ifdef GREY
+ if (g->pixmap2 != NULL) XDestroyImage(g->image2);
+#endif
+ }
+ free((char *) fontp->glyph);
+ }
+ free((char *) fontp);
+ }
+ }
+}
+
+static void
+prepare_pages()
+{
+ int i;
+
+ page_offset = (long *) xmalloc((unsigned) total_pages * sizeof(long),
+ "page directory");
+ i = total_pages;
+ page_offset[--i] = last_page_offset;
+ Fseek(dvi_file, last_page_offset, 0);
+ /*
+ * Follow back pointers through pages in the DVI file,
+ * storing the offsets in the page_offset table.
+ */
+ while (i > 0) {
+ Fseek(dvi_file, (long) (1+4+(9*4)), 1);
+ Fseek(dvi_file, page_offset[--i] = four(dvi_file), 0);
+ }
+}
+
+void
+init_page()
+{
+ page_w = ROUNDUP(unshrunk_page_w, mane.shrinkfactor) + 2;
+ page_h = ROUNDUP(unshrunk_page_h, mane.shrinkfactor) + 2;
+}
+
+/*
+ * init_dvi_file is the main subroutine for reading the startup information
+ * from the dvi file.
+ */
+
+static void
+init_dvi_file()
+{
+ (void) fstat(fileno(dvi_file), &fstatbuf);
+ dvi_time = fstatbuf.st_mtime;
+ process_preamble();
+ find_postamble();
+ read_postamble();
+ prepare_pages();
+ init_page();
+ if (current_page >= total_pages) current_page = total_pages - 1;
+ hush_spec_now = hush_spec;
+}
+
+/**
+ ** open_dvi_file opens the dvi file and calls init_dvi_file() to
+ ** initialize it.
+ **/
+
+void
+open_dvi_file()
+{
+ char *errmsg;
+
+ if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
+ int n = strlen(dvi_name);
+ char *file = dvi_name;
+
+ if (strcmp(dvi_name + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+ perror(dvi_name);
+ exit(1);
+ }
+ dvi_name = xmalloc((unsigned) n + sizeof(".dvi"), "dvi file name");
+ Sprintf(dvi_name, "%s.dvi", file);
+ if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
+ perror(dvi_name);
+ exit(1);
+ }
+ }
+
+ if (errmsg = (char *) setjmp(dvi_env)) oops(errmsg);
+ init_dvi_file();
+}
+
+/**
+ ** Check for changes in dvi file.
+ **/
+
+Boolean
+check_dvi_file()
+{
+ struct font *fontp;
+
+ if (dvi_file == NULL || fstat(fileno(dvi_file), &fstatbuf) != 0
+ || fstatbuf.st_mtime != dvi_time) {
+ if (dvi_file) Fclose(dvi_file);
+ free((char *) page_offset);
+ dvi_file = fopen(dvi_name, OPEN_MODE);
+ if (dvi_file == NULL)
+ dvi_oops("Cannot reopen dvi file.");
+ if (list_fonts) Putchar('\n');
+ free_vf_chain(tn_head);
+ tn_head = NULL;
+ for (fontp = font_head; fontp != NULL; fontp = fontp->next)
+ fontp->flags &= ~FONT_IN_USE;
+ init_dvi_file();
+ redraw_page();
+ return False;
+ }
+ return True;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/font_ope.c b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
new file mode 100644
index 0000000000..78d9b412a9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
@@ -0,0 +1,887 @@
+/*
+ * font_open.c(font, font_ret, mag, mag_ret, magstepval, name)
+ * Find and open gf, pk, or pxl files in the given path, having the given
+ * name and magnification. It tries gf files first, followed by pk and pxl
+ * files. The path variable should be of the form path1:path2:...:pathn,
+ * and each of the paths will be tried successively. Strings in pathi of
+ * the form %f, %p, and %d will be replaced by the font name, "gf" or "pk"
+ * or "pxl", and the magnification, respectively. If no %f appears in a
+ * path specifier, then the string "/%f.%d%p" is added on the end. This
+ * procedure is repeated for each of the possible magnifications allowed,
+ * and if it fails then the procedure will try changing the point size
+ * as well. If all of the above fails, then alt_font will be tried.
+ *
+ * If the variable SEARCH_SUBDIRECTORIES is set, then the environment
+ * variable TEXFONTS_SUBDIR and the #define variable DEFAULT_SUBDIR_PATH
+ * will be enabled, as well as ``*'' and ``**'' specifiers. The
+ * SUBDIR_PATH things will be appended to the end of the usual path, with
+ * a `*' at the end of each component. The `*' means that subdirectories
+ * will be searched up to one level; `**' means that subdirectories
+ * will be recursively searched to any level. Neither specifier may be
+ * preceded by a `%' specifier (after the most recent colon).
+ *
+ * If the file is found, then a file pointer is returned, and the following
+ * values are set:
+ * *font_ret a pointer to a string containing the font name (if
+ * different from the font requested).
+ * *mag_ret the actual magnification found.
+ * *name a pointer to a string containing the file name
+ *
+ * If the file is not found, then the return value is NULL.
+ *
+ * Often there are so many fonts that we need to manage the number of
+ * simultaneously open files. For that reason, these routines call
+ * xfopen() instead of fopen(), which should manage the number of open
+ * font files.
+ *
+ */
+
+/*--------------------------- Msdos ---------------------------------------*/
+/* ericho */
+#ifdef __MSDOS__
+
+#define DEFAULT_FONT_PATH "/tex/fonts"
+#define DEFAULT_VF_PATH "/tex/fonts/vf"
+#define DEFAULT_FONT_SIZES "300:328.6:360:432:518.4:622:746.4"
+
+#ifdef FONTSUB
+#include <stdio.h>
+extern FILE *fontsubfile;
+extern char *subfont (FILE *,char *);
+#endif
+
+#endif
+/*--------------------------- Msdos ---------------------------------------*/
+
+#include "xdvi.h"
+#include <errno.h>
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h> /* has getenv() */
+#include <math.h> /* has atof() */
+#else
+extern char *getenv();
+#ifndef atof
+double atof();
+#endif
+#endif
+
+/*
+ * If you think you have to change DEFAULT_TAIL, then you haven't read the
+ * documentation closely enough.
+ */
+#ifndef VMS
+#define PATH_SEP ':'
+
+#ifndef __MSDOS__ /* eric ho */
+#define DEFAULT_TAIL "/%f.%d%p"
+#else
+#define DEFAULT_TAIL "/%d/%f.%p"
+#endif
+
+#define DEFAULT_VF_TAIL "/%f.vf"
+#else /* VMS */
+#define PATH_SEP '/'
+#define DEFAULT_TAIL ":%f.%d%p"
+#define DEFAULT_VF_TAIL ":%f.vf"
+#endif /* VMS */
+
+static _Xconst char *font_path;
+static _Xconst char *default_font_path = DEFAULT_FONT_PATH;
+static _Xconst char *vf_path;
+static _Xconst char *default_vf_path = DEFAULT_VF_PATH;
+#ifdef SEARCH_SUBDIRECTORIES
+static char default_subdir_path[] = DEFAULT_SUBDIR_PATH;
+#endif
+static int *sizes, *sizend;
+static char default_size_list[] = DEFAULT_FONT_SIZES;
+
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#ifdef PATH_MAX
+#define FILENAMESIZE PATH_MAX
+#endif
+#endif
+
+#ifndef FILENAMESIZE
+#define FILENAMESIZE 512
+#endif
+
+#ifdef sun
+char *sprintf();
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+/* We will need some system include files to deal with directories. */
+/* <sys/types.h> was included by xdvi.h. */
+
+#include <sys/stat.h>
+
+static int is_dir ();
+
+#if defined(SYSV) || defined(_POSIX_SOURCE)
+#include <dirent.h>
+typedef struct dirent *directory_entry_type;
+#else
+#include <sys/dir.h>
+typedef struct direct *directory_entry_type;
+#endif
+
+/* Declare the routine to get the current working directory. */
+
+#ifdef HAVE_GETWD
+extern char *getwd ();
+#define GETCWD(b, len) ((b) ? getwd (b) : getwd (xmalloc (len, "getwd")))
+#else
+/* POSIX says getcwd result is undefined if the pointer is NULL; at least
+ on a Convex, the result is a coredump. Hence the GETCWD macro
+ below is defined, as it works regardless of what getcwd() does
+ with a NULL pointer */
+#define GETCWD(b, len) ((b) ? getcwd (b,len) \
+ : getcwd (xmalloc (len, "getcwd"),len))
+#ifdef _POSIX_SOURCE
+#include <unistd.h> /* getcwd prototype */
+#else
+#if NeedFunctionPrototypes
+extern char *getcwd (char *, int);
+#else
+extern char *getcwd ();
+#endif /* not NeedFunctionPrototypes */
+#endif /* not _POSIX_SOURCE */
+#endif /* not HAVE_GETWD */
+
+static char *cwd;
+
+/* The following is a data structure containing the precomputed names of
+ subdirectories to be recursively searched. */
+
+static struct subdir_entry {
+ char *name; /* partial string */
+ _Xconst char *index; /* reference point in {,default_}font_path */
+ struct subdir_entry *next; /* link in list */
+}
+ *subdir_head = NULL,
+ *next_subdir;
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
+#endif
+
+
+
+/* Return true if FN is a directory or a symlink to a directory,
+ false if not. */
+
+static int
+is_dir (fn)
+ char *fn;
+{
+ struct stat stats;
+
+ return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
+}
+
+/*
+ * Compute extra length of subdirectory entries, including a star for each.
+ */
+
+static int
+extra_len(str1, str2)
+ char *str1, *str2;
+{
+ int bias = 0;
+ char *p = str1;
+ char *q;
+
+ do {
+ q = index(p, PATH_SEP);
+ if (q == NULL) q = p + strlen(p);
+ if (q == p) {
+ if (str2 != NULL) {
+ bias += extra_len(str2, (char *) NULL);
+ str2 = NULL;
+ }
+ }
+ else ++bias; /* don't forget the star */
+ p = q + 1;
+ }
+ while (p[-1] != '\0');
+ return bias + p - str1;
+}
+
+/*
+ * Add the specifiers (and double stars) for the given strings (user
+ * string, plus default string) to the destination string.
+ */
+
+static void
+add_subdir_paths(dst, dst_first, src, src_default)
+ char *dst, *dst_first, *src, *src_default;
+{
+ char *q;
+
+ do {
+ q = index(src, PATH_SEP);
+ if (q == NULL) q = src + strlen(src);
+ if (q == src) {
+ if (src_default != NULL) {
+ add_subdir_paths(dst, dst_first, src_default, (char *)NULL);
+ dst += strlen(dst);
+ src_default = NULL;
+ }
+ }
+ else {
+ if (dst != dst_first) *dst++ = PATH_SEP;
+ bcopy(src, dst, q - src);
+ dst += q - src;
+ *dst++ = '*';
+ }
+ src = q + 1;
+ }
+ while (src[-1] != '\0');
+ *dst = '\0';
+}
+
+/*
+ * Make a subdirectory entry.
+ */
+
+static struct subdir_entry *
+make_subdir_entry(index, name)
+ _Xconst char *index;
+ char *name;
+{
+ struct subdir_entry *new_entry;
+ static struct subdir_entry **subdir_tail = &subdir_head;
+
+ *subdir_tail = new_entry = (struct subdir_entry *)
+ xmalloc(sizeof(struct subdir_entry), "subdirectory list entry");
+ subdir_tail = &(new_entry->next);
+ new_entry->name = strcpy(xmalloc(strlen(name) + 1,
+ "subdirectory entry string"), name);
+ new_entry->index = index;
+ new_entry->next = NULL;
+ return new_entry;
+}
+
+/*
+ * Create the subdirectory linked list for the given initial string
+ */
+
+static void
+add_subdirs(str, len, recurs)
+ _Xconst char *str;
+ int len;
+ Boolean recurs;
+{
+ int len1 = len;
+ char temp[FILENAMESIZE];
+ struct subdir_entry *next_subdir;
+ DIR *dir;
+ directory_entry_type e;
+
+ bcopy(str, temp, len);
+ if (len > 0 && temp[len - 1] != '/') temp[len1++] = '/';
+ temp[len1] = '\0';
+ next_subdir = make_subdir_entry(str, temp + len);
+ do {
+ /* By changing directories, we save a bunch of string
+ concatenations (and make the pathnames the kernel looks up
+ shorter). */
+ Strcpy(temp + len, next_subdir->name);
+ if (chdir (temp) != 0) continue;
+
+ dir = opendir (".");
+ if (dir == NULL) continue;
+
+ len1 = strlen(temp);
+ if (len1 == 0 || temp[len1 - 1] != '/') temp[len1++] = '/';
+ while ((e = readdir (dir)) != NULL) {
+ if (is_dir (e->d_name) && strcmp (e->d_name, ".") != 0
+ && strcmp (e->d_name, "..") != 0) {
+ Strcpy(temp + len1, e->d_name);
+ (void) make_subdir_entry(str, temp + len);
+ }
+ }
+ (void) closedir (dir);
+
+
+ /* Change back to the current directory, in case the path
+ contains relative directory names. */
+ if (chdir (cwd) != 0) {
+ perror (cwd);
+ exit (errno);
+ }
+ }
+ while (recurs && (next_subdir = next_subdir->next) != NULL);
+}
+
+/*
+ * Recursively figure out the subdirectory tree and precompute the
+ * list of subdirectories to search.
+ */
+
+static void
+compute_subdir_paths(fp, fp_default)
+ _Xconst char *fp;
+ _Xconst char *fp_default;
+{
+ _Xconst char *star_loc = NULL;
+ _Xconst char *endp;
+
+ do {
+ if (star_loc == NULL) {
+ star_loc = index(fp, '*');
+ if (star_loc == NULL) star_loc = fp + strlen(fp);
+ }
+ endp = index(fp, PATH_SEP);
+ if (endp == NULL) endp = fp + strlen(fp);
+ if (endp == fp) {
+ if (fp_default != NULL) {
+ compute_subdir_paths(fp_default, (char *) NULL);
+ fp_default = NULL;
+ }
+ }
+ else if (star_loc < endp) {
+ add_subdirs(fp, star_loc - fp, star_loc[1] == '*');
+ star_loc = NULL;
+ }
+ fp = endp + 1;
+ }
+ while (fp[-1] != '\0');
+}
+#endif /* SEARCH_SUBDIRECTORIES */
+
+static void
+get_sizes(size_list, spp)
+ char *size_list;
+ int **spp;
+{
+ if (*size_list == PATH_SEP) ++size_list;
+ for (;;) {
+ *(*spp)++ = atof(size_list) * 5 + 0.5;
+ size_list = index(size_list, PATH_SEP);
+ if (size_list == NULL) return;
+ ++size_list;
+ }
+}
+
+void
+init_font_open()
+{
+ char *size_list;
+ int *sp, *sp1, *sp2;
+ unsigned int n;
+ char *p;
+#ifdef SEARCH_SUBDIRECTORIES
+ char *q;
+#endif
+
+ if ((font_path = getenv("XDVIFONTS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (font_path = getenv("PKFONTS")) == NULL
+ && (font_path = getenv("TEXFONTS")) == NULL
+#endif
+ ) {
+ font_path = default_font_path;
+ default_font_path = NULL;
+ }
+
+#ifdef SEARCH_SUBDIRECTORIES
+ p = getenv ("TEXFONTS_SUBDIR");
+ if (p == NULL) p = "";
+ q = xmalloc((unsigned) strlen(font_path)
+ + extra_len(p, default_subdir_path) + 1,
+ "initializing font searching");
+ Strcpy(q, font_path);
+ add_subdir_paths(q + strlen(q), q, p, default_subdir_path);
+ font_path = q;
+
+ /* Unfortunately, we can't look in the environment for the current
+ directory, because if we are running under a program (let's say
+ Emacs), the PWD variable might have been set by Emacs' parent
+ to the current directory at the time Emacs was invoked. This
+ is not necessarily the same directory the user expects to be
+ in. So, we must always call getcwd(3) or getwd(3), even though
+ they are slow and prone to hang in networked installations. */
+ cwd = GETCWD ((char *) NULL, FILENAMESIZE + 2);
+ if (cwd == NULL) {
+ perror ("getcwd");
+ exit (errno);
+ }
+ compute_subdir_paths(font_path, default_font_path);
+#endif
+
+ if ((vf_path = getenv("XDVIVFS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (vf_path = getenv("VFFONTS")) == NULL
+#endif
+ ) {
+ vf_path = default_vf_path;
+ default_vf_path = NULL;
+ }
+
+ size_list = getenv("XDVISIZES");
+ n = 1; /* count number of sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ for (p = default_size_list; (p = index(p, PATH_SEP)) != NULL; ++p)
+ ++n;
+ if (size_list != NULL)
+ for (p = size_list; (p = index(p, PATH_SEP)) != NULL; ++p) ++n;
+ sizes = (int *) xmalloc(n * sizeof(int), "size list");
+ sizend = sizes + n;
+ sp = sizes; /* get the actual sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ get_sizes(default_size_list, &sp);
+ if (size_list != NULL) get_sizes(size_list, &sp);
+
+ /* bubble sort the sizes */
+ sp1 = sizend - 1; /* extent of this pass */
+ do {
+ sp2 = NULL;
+ for (sp = sizes; sp < sp1; ++sp)
+ if (*sp > sp[1]) {
+ int i = *sp;
+ *sp = sp[1];
+ sp[1] = i;
+ sp2 = sp;
+ }
+ }
+ while ((sp1 = sp2) != NULL);
+}
+
+/* eric */
+static FILE *
+formatted_open(path, font, gforpk, mag, name, first_try, tail)
+ _Xconst char *path;
+ _Xconst char *font;
+ _Xconst char *gforpk;
+ int mag;
+ char **name;
+ Boolean first_try;
+ _Xconst char *tail;
+{
+ _Xconst char *p = path;
+ char nm[FILENAMESIZE];
+ char *n = nm;
+ char c;
+ Boolean f_used = False;
+ Boolean p_used = False;
+ FILE *f;
+
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ int len = index(p, '*') - p;
+
+ bcopy(p, n, len);
+ p += len;
+ n += len;
+ Strcpy(n, next_subdir->name);
+ n += strlen(n);
+ ++p;
+ if (*p == '*') ++p;
+ if (*p != '/') *n++ = '/';
+ }
+#endif
+ for (;;) {
+ c = *p++;
+ if (c==PATH_SEP || c=='\0') {
+ if (f_used) break;
+ p = tail;
+ continue;
+ }
+ if (c=='%') {
+ c = *p++;
+ switch (c) {
+ case 'f':
+ f_used = True;
+ Strcpy(n, font);
+ break;
+ case 'p':
+ p_used = True;
+ Strcpy(n, gforpk);
+ break;
+ case 'd':
+ Sprintf(n, "%d", mag);
+ break;
+ default:
+ *n++ = c;
+ *n = '\0';
+ }
+ n += strlen(n);
+ }
+ else *n++ = c;
+ }
+ if (!p_used && !first_try) return NULL;
+ *n = '\0';
+ if (debug & DBG_OPEN) Printf("Trying font file %s\n", nm);
+
+
+ f = xfopen(nm);
+ if (f != NULL) {
+ *name = xmalloc((unsigned) (n - nm + 1), "font file name");
+ Strcpy(*name, nm);
+ }
+ return f;
+}
+
+/*
+ * Try a given size
+ */
+
+static FILE *
+try_size(font, pxlmag, name, x_font_path, x_default_font_path)
+ _Xconst char *font;
+ int pxlmag;
+ char **name;
+ _Xconst char *x_font_path;
+ _Xconst char *x_default_font_path;
+{
+ _Xconst char *p = x_font_path;
+ FILE *f;
+ int pkmag = (pxlmag + 2) / 5;
+
+#ifdef __MSDOS__
+ char *sfont, *dotptr;
+#endif
+
+ /*
+ * loop over paths
+ */
+#ifdef SEARCH_SUBDIRECTORIES
+ next_subdir = subdir_head;
+#endif
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_font_path != NULL &&
+ (f = try_size(font, pxlmag, name, x_default_font_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+
+
+
+#define FIRST_TRY True
+#ifdef USE_PK
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && !defined(FONTSUB)
+
+ /* I prefer this method because it'll execute a lot */
+ /* faster than looking up the font substitute file */
+
+ /* simply convert all the amXXXX font to cmXXXX */
+ dotptr = strchr (font,'a');
+ if (dotptr != (char *)NULL) {
+ *dotptr = 'c';
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+ if ((f = formatted_open(p, font, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && defined(FONTSUB)
+ /* look for the substitute font from file */
+ if (fontsubfile != (FILE *) NULL) {
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,(char *)font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, (_Xconst char *)sfont, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+
+
+#ifdef USE_GF
+ if ((f = formatted_open(p, font, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+#ifdef USE_PXL
+ if ((f = formatted_open(p, font, "pxl", pxlmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "pxl", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ next_subdir = next_subdir->next;
+ if (next_subdir != NULL && next_subdir->index == p)
+ continue;
+ }
+#endif
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+/*
+ * Try a virtual font
+ */
+
+static FILE *
+try_vf(font, name, x_vf_path, x_default_vf_path)
+ _Xconst char *font;
+ char **name;
+ _Xconst char *x_vf_path;
+ _Xconst char *x_default_vf_path;
+{
+ _Xconst char *p = x_vf_path;
+ FILE *f;
+
+ /*
+ * loop over paths
+ */
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_vf_path != NULL &&
+ (f = try_vf(font, name, x_default_vf_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+ if ((f = formatted_open(p, font, "vf", 0, name, True,
+ DEFAULT_VF_TAIL)) != NULL)
+ return f;
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+#ifdef MAKEPKCMD
+#undef MAKEPK
+#define MAKEPK
+#endif
+
+#ifdef MAKEPK
+#ifndef MAKEPKCMD
+#define MAKEPKCMD "MakeTeXPK"
+#endif
+
+#define NOBUILD 29999
+#endif
+
+/*
+ * Try a given font name
+ */
+
+#ifndef MAKEPK
+#define PRE_FONT_OPEN(font, fmag, mag_ret, name, ignore) \
+ pre_font_open(font, fmag, mag_ret, name)
+#else
+#define PRE_FONT_OPEN pre_font_open
+#endif
+
+static FILE *
+PRE_FONT_OPEN(font, fmag, mag_ret, name, magstepval)
+ _Xconst char *font;
+ float fmag;
+ int *mag_ret;
+ char **name;
+#ifdef MAKEPK
+ int magstepval;
+#endif
+{
+ FILE *f;
+ int *p1, *p2;
+ int mag = 5 * fmag + 0.5;
+ int tmag;
+#ifndef VMS
+ _Xconst char *path_to_use;
+ _Xconst char *vf_path_to_use;
+#endif
+#ifdef MAKEPK
+ char mkpk[80];
+#endif
+
+ /*
+ * Loop over sizes. Try actual size first, then closest sizes.
+ If the pathname is absolutely or explicitly relative, don't
+ use the usual paths to search for it; just look for it in the
+ directory specified.
+ */
+
+#ifndef VMS
+ path_to_use = (_Xconst char *) NULL;
+ if (*font == '/') path_to_use = "/";
+ else if (*font == '.' && (*(font + 1) == '/'
+ || (*(font + 1) == '.' && *(font + 2) == '/')))
+ path_to_use = ".";
+ vf_path_to_use = path_to_use;
+ if (path_to_use == NULL) {
+ path_to_use = font_path;
+ vf_path_to_use = vf_path;
+ }
+#else /* VMS */
+#define path_to_use font_path
+#define vf_path_to_use vf_path
+#endif /* VMS */
+
+ if ((f = try_size(font, *mag_ret = mag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+
+ /* Try at one away from the size we just tried, to account
+ for rounding error. */
+ tmag = mag + (mag < 5 * fmag ? 1 : -1);
+ if ((f = try_size(font, tmag, name, path_to_use, default_font_path))
+ != NULL) {
+ *mag_ret = tmag;
+ return f;
+ }
+
+ /* Try a virtual font. */
+ if ((f = try_vf(font, name, vf_path_to_use, default_vf_path)) != NULL)
+ return f;
+
+#ifdef MAKEPK
+ /* Try to create the font. */
+ if (magstepval != NOBUILD) {
+ char str[24];
+ int dpi = (mag + 2) / 5;
+
+ if (magstepval == NOMAGSTP)
+ Sprintf(str, "%d+%d/%d", dpi / pixels_per_inch,
+ dpi % pixels_per_inch, pixels_per_inch);
+ else if (magstepval < 0)
+ Sprintf(str, "magstep\\(-%d%s\\)", (-magstepval) / 2,
+ magstepval % 2 ? ".5" :"");
+ else
+ Sprintf(str, "magstep\\(%d%s\\)", magstepval / 2,
+ magstepval % 2 ? ".5" :"");
+
+ Sprintf(mkpk, "%s %s %d %d %s", MAKEPKCMD, font, dpi,
+ pixels_per_inch, str);
+ Printf("- %s\n", mkpk);
+ if (system(mkpk) == 0
+ && (f = try_size(font, mag, name, path_to_use,
+ default_font_path))
+ != NULL)
+ return f;
+ }
+#endif
+
+ /* Now try at all the sizes. */
+ for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break;
+ p1 = p2;
+ for (;;) {
+ /* find another magnification */
+ if (p1 <= sizes)
+ if (p2 >= sizend) return NULL;
+ else tmag = *p2++;
+ else if (p2 >= sizend || (long) mag * mag <= (long) p1[-1] * *p2)
+ tmag = *--p1;
+ else tmag = *p2++;
+ if ((f = try_size(font, *mag_ret = tmag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+ }
+}
+
+/* ARGSUSED */
+FILE *
+font_open(font, font_ret, mag, mag_ret, magstepval, name)
+ _Xconst char *font;
+ char **font_ret;
+ WIDEARG(float, double) mag;
+ int *mag_ret;
+ int magstepval;
+ char **name;
+{
+ FILE *f;
+ int actual_pt, low_pt, high_pt, trial_pt;
+ char fn[50], *fnend;
+
+ f = PRE_FONT_OPEN(font, mag, mag_ret, name, magstepval);
+ if (f != NULL) {
+ *font_ret = NULL;
+ return f;
+ }
+ Strcpy(fn, font);
+ fnend = fn + strlen(fn);
+ while (fnend > fn && fnend[-1] >= '0' && fnend[-1] <= '9') --fnend;
+ actual_pt = low_pt = high_pt = atoi(fnend);
+ if (actual_pt) {
+ low_pt = actual_pt - 1;
+ high_pt = actual_pt + 1;
+ for (;;) {
+ if (2 * low_pt >= actual_pt &&
+ (low_pt * high_pt > actual_pt * actual_pt ||
+ high_pt > actual_pt + 5))
+ trial_pt = low_pt--;
+ else if (high_pt > actual_pt + 5) break;
+ else trial_pt = high_pt++;
+ Sprintf(fnend, "%d", trial_pt);
+ f = PRE_FONT_OPEN(fn, mag * actual_pt / trial_pt, mag_ret,
+ name, NOBUILD);
+ if (f != NULL) {
+ *font_ret = strcpy(xmalloc((unsigned) strlen(fn) + 1,
+ "name of font used"), fn);
+ return f;
+ }
+ }
+ }
+ if (alt_font != NULL) {
+ f = PRE_FONT_OPEN(alt_font, mag, mag_ret, name, NOBUILD);
+ if (f != NULL)
+ *font_ret = strcpy(xmalloc((unsigned) strlen(alt_font) + 1,
+ "name of font used"), alt_font);
+ }
+ return f;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/fontfmts.c b/systems/msdos/dviware/xdvi-dos/src/fontfmts.c
new file mode 100644
index 0000000000..69a0963d09
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/fontfmts.c
@@ -0,0 +1,21 @@
+#include "xdvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+/***
+ *** Font reading routines are read into this file.
+ ***/
+
+#ifdef USE_PK
+#include "pk.c"
+#endif
+
+#ifdef USE_GF
+#include "gf.c"
+#endif
+
+#ifdef USE_PXL
+#include "pxl.c"
+#endif
diff --git a/systems/msdos/dviware/xdvi-dos/src/fontsub.c b/systems/msdos/dviware/xdvi-dos/src/fontsub.c
new file mode 100644
index 0000000000..0ad76638d6
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/fontsub.c
@@ -0,0 +1,62 @@
+/* ------------------------------ For MsDos -------------------------------*/
+
+/*
+
+ These routines are written for opening and searching the font
+ substitute file pointed to by the environmental variable "TEXFONTSUB"
+
+ 10/OCT/1992 Eric Ho 9041477@SSCVAX.MCMASTER.CA
+
+*/
+
+#ifdef FONTSUB
+
+#include <stdio.h>
+#include <stdlib.h>
+
+FILE *openfontsubfile (void);
+char *subfont (FILE *,char *);
+
+
+char *subfont (fptr,font)
+FILE *fptr;
+char *font;
+{
+ char ofont[30], /* original font */
+ sfont[30]; /* font to be substitute */
+
+ rewind (fptr);
+ while (!feof (fptr)) {
+ fscanf (fptr,"%s -> %s",ofont,sfont);
+ if (strcmp (ofont,font) == 0) {
+/* fprintf (stderr,"Replacing %s with %s\n",font,sfont); */
+ return (sfont);
+ }
+ }
+ return (NULL);
+}
+
+
+
+FILE *openfontsubfile (void)
+{
+ FILE *fptr;
+ char fontsfname[64],
+ *sptr; /* font substitue file name */
+
+ if ((sptr = (char *) getenv ("TEXFONTSUB")) != (char *) NULL) {
+ (void) strcpy (fontsfname,sptr);
+ if ((fptr = fopen (fontsfname,"r")) != (FILE *) NULL) {
+ return ((FILE *) fptr);
+ } else {
+ fprintf (stderr,"\n\nFont substitute file not found!\n");
+ fprintf (stderr,"Check environmental variable TEXFONTSUB!\n\n");
+ return ((FILE *) NULL);
+ }
+ } else {
+ fprintf (stderr,"\n\nCheck environmental variable TEXFONTSUB!\n\n");
+ return ((FILE *) NULL);
+ }
+}
+
+#endif
diff --git a/systems/msdos/dviware/xdvi-dos/src/gf.c b/systems/msdos/dviware/xdvi-dos/src/gf.c
new file mode 100644
index 0000000000..cc6b9423fe
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/gf.c
@@ -0,0 +1,294 @@
+/***
+ *** GF font reading routines.
+ *** Public routines are read_GF_index and read_GF_char.
+ ***/
+
+#define PAINT_0 0
+#define PAINT1 64
+#define PAINT2 65
+#define PAINT3 66
+#define BOC 67
+#define BOC1 68
+#define EOC 69
+#define SKIP0 70
+#define SKIP1 71
+#define SKIP2 72
+#define SKIP3 73
+#define NEW_ROW_0 74
+#define NEW_ROW_MAX 238
+#define XXX1 239
+#define XXX2 240
+#define XXX3 241
+#define XXX4 242
+#define YYY 243
+#define NO_OP 244
+#define CHAR_LOC 245
+#define CHAR_LOC0 246
+#define PRE 247
+#define POST 248
+#define POST_POST 249
+
+#define GF_ID_BYTE 131
+#define TRAILER 223 /* Trailing bytes at end of file */
+
+static FILE *GF_file;
+
+static void
+expect(ch)
+ ubyte ch;
+{
+ ubyte ch1 = one(GF_file);
+
+ if (ch1 != ch)
+ oops("Bad GF file: %d expected, %d received.", ch, ch1);
+}
+
+static void
+too_many_bits(ch)
+ ubyte ch;
+{
+ oops("Too many bits found when loading character %d", ch);
+}
+
+/*
+ * Public routines
+ */
+
+
+static void
+read_GF_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ register struct glyph *g;
+ ubyte cmnd;
+ int min_m, max_m, min_n, max_n;
+ BMUNIT *cp, *basep, *maxp;
+ int bytes_wide;
+ Boolean paint_switch;
+#define White False
+#define Black True
+ Boolean new_row;
+ int count;
+ int word_weight;
+
+ g = &fontp->glyph[ch];
+ GF_file = fontp->file;
+
+ if(debug & DBG_PK)
+ Printf("Loading gf char %d", ch);
+
+ for (;;) {
+ switch (cmnd = one(GF_file)) {
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ Fseek(GF_file, (long) num(GF_file,
+ WIDEARG(,(int)) cmnd - XXX1 + 1), 1);
+ continue;
+ case YYY:
+ (void) four(GF_file);
+ continue;
+ case BOC:
+ (void) four(GF_file); /* skip character code */
+ (void) four(GF_file); /* skip pointer to prev char */
+ min_m = sfour(GF_file);
+ max_m = sfour(GF_file);
+ g->x = -min_m;
+ min_n = sfour(GF_file);
+ g->y = max_n = sfour(GF_file);
+ g->bitmap.w = max_m - min_m + 1;
+ g->bitmap.h = max_n - min_n + 1;
+ break;
+ case BOC1:
+ (void) one(GF_file); /* skip character code */
+ g->bitmap.w = one(GF_file); /* max_m - min_m */
+ g->x = g->bitmap.w - one(GF_file); /* ditto - max_m */
+ ++g->bitmap.w;
+ g->bitmap.h = one(GF_file) + 1;
+ g->y = one(GF_file);
+ break;
+ default:
+ oops("Bad BOC code: %d", cmnd);
+ }
+ break;
+ }
+ paint_switch = White;
+
+ if (debug & DBG_PK)
+ Printf(", size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+
+ alloc_bitmap(&g->bitmap);
+ cp = basep = (BMUNIT *) g->bitmap.bits;
+/*
+ * Read character data into *basep
+ */
+ bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
+ maxp = ADD(basep, g->bitmap.h * bytes_wide);
+ bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
+ new_row = False;
+ word_weight = BITS_PER_BMUNIT;
+ for (;;) {
+ count = -1;
+ cmnd = one(GF_file);
+ if (cmnd < 64) count = cmnd;
+ else if (cmnd >= NEW_ROW_0 && cmnd <= NEW_ROW_MAX) {
+ count = cmnd - NEW_ROW_0;
+ paint_switch = White; /* it'll be complemented later */
+ new_row = True;
+ }
+ else switch (cmnd) {
+ case PAINT1:
+ case PAINT2:
+ case PAINT3:
+ count = num(GF_file, WIDEARG(,(int)) cmnd - PAINT1 + 1);
+ break;
+ case EOC:
+ if (cp >= ADD(basep, bytes_wide)) too_many_bits(ch);
+ return;
+ case SKIP1:
+ case SKIP2:
+ case SKIP3:
+ *((char **) &basep) +=
+ num(GF_file, WIDEARG(,(int)) cmnd - SKIP0) * bytes_wide;
+ case SKIP0:
+ new_row = True;
+ paint_switch = White;
+ break;
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ Fseek(GF_file, (long) num(GF_file,
+ WIDEARG(,(int)) cmnd - XXX1 + 1), 1);
+ break;
+ case YYY:
+ (void) four(GF_file);
+ break;
+ case NO_OP:
+ break;
+ default:
+ oops("Bad command in GF file: %d", cmnd);
+ } /* end switch */
+ if (new_row) {
+ *((char **) &basep) += bytes_wide;
+ if (basep >= maxp || cp >= basep) too_many_bits(ch);
+ cp = basep;
+ word_weight = BITS_PER_BMUNIT;
+ new_row = False;
+ }
+ if (count >= 0) {
+ while (count)
+ if (count <= word_weight) {
+#ifndef MSBITFIRST
+ if (paint_switch)
+ *cp |= bit_masks[count] <<
+ (BITS_PER_BMUNIT - word_weight);
+#endif
+ word_weight -= count;
+#ifdef MSBITFIRST
+ if (paint_switch)
+ *cp |= bit_masks[count] << word_weight;
+#endif
+ break;
+ }
+ else {
+ if (paint_switch)
+#ifndef MSBITFIRST
+ *cp |= bit_masks[word_weight] <<
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ *cp |= bit_masks[word_weight];
+#endif
+ cp++;
+ count -= word_weight;
+ word_weight = BITS_PER_BMUNIT;
+ }
+ paint_switch = 1 - paint_switch;
+ }
+ } /* end for */
+}
+
+
+void
+read_GF_index(fontp)
+ register struct font *fontp;
+{
+ int hppp, vppp;
+ ubyte ch, cmnd;
+ register struct glyph *g;
+
+ fontp->read_char = read_GF_char;
+ GF_file = fontp->file;
+ if (debug & DBG_PK)
+ Printf("Reading GF pixel file %s\n", fontp->filename);
+/*
+ * Find postamble.
+ */
+ Fseek(GF_file, (long) -4, 2);
+ while (four(GF_file) !=
+ ((long) TRAILER << 24 | TRAILER << 16 | TRAILER << 8 | TRAILER))
+ Fseek(GF_file, (long) -5, 1);
+ Fseek(GF_file, (long) -5, 1);
+ for (;;) {
+ ch = one(GF_file);
+ if (ch != TRAILER) break;
+ Fseek(GF_file, (long) -2, 1);
+ }
+ if (ch != GF_ID_BYTE) oops("Bad end of font file %s", fontp->fontname);
+ Fseek(GF_file, (long) -6, 1);
+ expect(POST_POST);
+ Fseek(GF_file, sfour(GF_file), 0); /* move to postamble */
+/*
+ * Read postamble.
+ */
+ expect(POST);
+ (void) four(GF_file); /* pointer to last eoc + 1 */
+ (void) four(GF_file); /* skip design size */
+ (void) four(GF_file); /* skip checksum */
+ hppp = sfour(GF_file);
+ vppp = sfour(GF_file);
+ if (hppp != vppp && (debug & DBG_PK))
+ Printf("Font has non-square aspect ratio %d:%d\n", vppp, hppp);
+ (void) four(GF_file); /* skip min_m */
+ (void) four(GF_file); /* skip max_m */
+ (void) four(GF_file); /* skip min_n */
+ (void) four(GF_file); /* skip max_n */
+/*
+ * Prepare glyph array.
+ */
+ fontp->glyph = (struct glyph *) xmalloc(256 * sizeof(struct glyph),
+ "glyph array");
+ bzero((char *) fontp->glyph, 256 * sizeof(struct glyph));
+/*
+ * Read glyph directory.
+ */
+ while ((cmnd = one(GF_file)) != POST_POST) {
+ int addr;
+
+ ch = one(GF_file); /* character code */
+ g = &fontp->glyph[ch];
+ switch (cmnd) {
+ case CHAR_LOC:
+ /* g->pxl_adv = sfour(GF_file); */
+ (void) four(GF_file);
+ (void) four(GF_file); /* skip dy */
+ break;
+ case CHAR_LOC0:
+ /* g->pxl_adv = one(GF_file) << 16; */
+ (void) one(GF_file);
+ break;
+ default:
+ oops("Non-char_loc command found in GF preamble: %d",
+ cmnd);
+ }
+ g->dvi_adv = fontp->dimconv * sfour(GF_file);
+ addr = four(GF_file);
+ if (addr != -1) g->addr = addr;
+ if (debug & DBG_PK)
+ Printf("Read GF glyph for character %d; dy = %d, addr = %d\n",
+ ch, g->dvi_adv, addr);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/makefile b/systems/msdos/dviware/xdvi-dos/src/makefile
new file mode 100644
index 0000000000..6c817e2869
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/makefile
@@ -0,0 +1,36 @@
+
+# Makefile for dvi previewer (MSDOS version under dv/x).
+# eric ho
+
+
+# -DFONTSUB for running using font substitute file
+#
+DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY -DFONTSUB
+
+#DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY
+
+
+CFLAGS=-O2 -finline-functions -m486 -fexpensive-optimizations -Wall $(DEFS)
+LIBS= -lxt -lxmu -lxext -lxaw -lx -lsys -lm
+SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c fontsub.c
+OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o fontsub.o
+CC=gcc
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+xdvi: $(OBJS)
+ $(CC) -o xdvi *.o $(LIBS)
+ strip +strip-all xdvi
+ aout2exe xdvi
+
+xdvi.o: xdvi.h patchlevel.h xdvi_curs.h xdvi_mask.h
+dvi_init.o: xdvi.h dvi.h
+dvi_draw.o: xdvi.h dvi.h
+tpic.o: xdvi.h
+fontfmts.o: xdvi.h pk.c gf.c pxl.c
+util.o: xdvi.h
+
+font_open.o: font_open.c xdvi.h
+ $(CC) -c $(CFLAGS) font_open.c
+
diff --git a/systems/msdos/dviware/xdvi-dos/src/makefile.bak b/systems/msdos/dviware/xdvi-dos/src/makefile.bak
new file mode 100644
index 0000000000..135ee67d22
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/makefile.bak
@@ -0,0 +1,36 @@
+
+# Makefile for dvi previewer (MSDOS version under dv/x).
+# eric ho
+
+
+# -DFONTSUB for running using font substitute file
+#
+#DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY -DFONTSUB
+
+DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY
+
+
+CFLAGS=-O2 -finline-functions -m486 -fexpensive-optimizations -Wall $(DEFS)
+LIBS= -lxt -lxmu -lxext -lxaw -lx -lsys -lm
+SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c fontsub.c
+OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o fontsub.o
+CC=gcc
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+xdvi: $(OBJS)
+ $(CC) -o xdvi *.o $(LIBS)
+ strip +strip-all xdvi
+ aout2exe xdvi
+
+xdvi.o: xdvi.h patchlevel.h xdvi_curs.h xdvi_mask.h
+dvi_init.o: xdvi.h dvi.h
+dvi_draw.o: xdvi.h dvi.h
+tpic.o: xdvi.h
+fontfmts.o: xdvi.h pk.c gf.c pxl.c
+util.o: xdvi.h
+
+font_open.o: font_open.c xdvi.h
+ $(CC) -c $(CFLAGS) font_open.c
+
diff --git a/systems/msdos/dviware/xdvi-dos/src/maketexp b/systems/msdos/dviware/xdvi-dos/src/maketexp
new file mode 100644
index 0000000000..5c63ed3fb9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/maketexp
@@ -0,0 +1,141 @@
+#!/bin/sh
+#
+# This script file makes a new TeX PK font, because one wasn't
+# found. Parameters are:
+#
+# name dpi bdpi magnification [mode [subdir]]
+#
+# `name' is the name of the font, such as `cmr10'. `dpi' is
+# the resolution the font is needed at. `bdpi' is the base
+# resolution, useful for figuring out the mode to make the font
+# in. `magnification' is a string to pass to MF as the
+# magnification. `mode', if supplied, is the mode to use.
+#
+# Note that this file must execute Metafont, and then gftopk,
+# and place the result in the correct location for the PostScript
+# driver to find it subsequently. If this doesn't work, it will
+# be evident because MF will be invoked over and over again.
+#
+# Of course, it needs to be set up for your site.
+#
+TEXDIR=/usr/lib/tex
+LOCALDIR=/LocalLibrary/Fonts/TeXFonts
+DESTDIR=$LOCALDIR/pk
+#
+# TEMPDIR needs to be unique for each process because of the possibility
+# of simultaneous processes running this script.
+#
+if test "$TMPDIR" = ""
+then
+ TEMPDIR=/tmp/mtpk.$$
+else
+ TEMPDIR=$TMPDIR/mtpk.$$
+fi
+NAME=$1
+DPI=$2
+BDPI=$3
+MAG=$4
+MODE=$5
+
+umask 0
+
+if test "$MODE" = ""
+then
+ if test $BDPI = 300
+ then
+ MODE=imagen
+ elif test $BDPI = 200
+ then
+ MODE=FAX
+ elif test $BDPI = 360
+ then
+ MODE=nextII
+ elif test $BDPI = 400
+ then
+ MODE=nexthi
+ elif test $BDPI = 100
+ then
+ MODE=nextscreen
+ elif test $BDPI = 635
+ then
+ MODE=linolo
+ elif test $BDPI = 1270
+ then
+ MODE=linohi
+ elif test $BDPI = 2540
+ then
+ MODE=linosuper
+ else
+ echo "I don't know the mode for $BDPI"
+ echo "Have your system admin update MakeTeXPK"
+ exit 1
+ fi
+fi
+
+# Something like the following is useful at some sites.
+# DESTDIR=/usr/local/lib/tex/fonts/pk.$MODE
+GFNAME=$NAME.$DPI'gf'
+PKNAME=$NAME.$DPI'pk'
+
+# Clean up on normal or abnormal exit
+trap "cd /; /bin/rm -rf $TEMPDIR $DESTDIR/pktmp.$$" 0 1 2 15
+
+
+if test ! -d $DESTDIR
+then
+ mkdir $DESTDIR
+fi
+
+if test "$6" != ""
+then
+ DESTDIR=$DESTDIR"$6"
+ if test ! -d $DESTDIR
+ then
+ mkdir $DESTDIR
+ fi
+fi
+
+mkdir $TEMPDIR
+cd $TEMPDIR
+
+if test -r $DESTDIR/$PKNAME
+then
+ echo "$DESTDIR/$PKNAME already exists!"
+ exit 0
+fi
+
+# check also in the standard place
+
+if test "$6" = ""
+then
+ if test -r $TEXDIR/fonts/pk/$PKNAME
+ then
+ echo $TEXDIR/fonts/pk/$PKNAME already exists!
+ exit 0
+ fi
+else
+ if test -r $TEXDIR/fonts/pk/$6"$PKNAME"
+ then
+ echo $TEXDIR/fonts/pk/$6"$PKNAME" already exists!
+ exit 0
+ fi
+fi
+
+echo "mf \"\\mode:=$MODE; mag:=$MAG; scrollmode; input $NAME\" < /dev/null"
+mf "\mode:=$MODE; mag:=$MAG; scrollmode; input $NAME" < /dev/null
+if test ! -r $GFNAME
+then
+ echo "Metafont failed for some reason on $GFNAME"
+ exit 1
+fi
+
+gftopk -v ./$GFNAME ./$PKNAME
+
+# Install the PK file carefully, since others may be doing the same
+# as us simultaneously.
+
+mv $PKNAME $DESTDIR/pktmp.$$
+cd $DESTDIR
+mv pktmp.$$ $PKNAME
+
+exit 0
diff --git a/systems/msdos/dviware/xdvi-dos/src/patchlev.h b/systems/msdos/dviware/xdvi-dos/src/patchlev.h
new file mode 100644
index 0000000000..0eee8898e5
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/patchlev.h
@@ -0,0 +1 @@
+#define PATCHLEVEL 16
diff --git a/systems/msdos/dviware/xdvi-dos/src/pk.c b/systems/msdos/dviware/xdvi-dos/src/pk.c
new file mode 100644
index 0000000000..969245fdd1
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/pk.c
@@ -0,0 +1,324 @@
+/***
+ *** PK font reading routines.
+ *** Public routines are read_PK_index and read_PK_char.
+ ***/
+
+#define PK_ID 89
+#define PK_CMD_START 240
+#define PK_X1 240
+#define PK_X2 241
+#define PK_X3 242
+#define PK_X4 243
+#define PK_Y 244
+#define PK_POST 245
+#define PK_NOOP 246
+#define PK_PRE 247
+
+static int PK_flag_byte;
+static unsigned PK_input_byte;
+static int PK_bitpos;
+static int PK_dyn_f;
+static int PK_repeat_count;
+
+static int
+PK_get_nyb(fp)
+ register FILE *fp;
+{
+ unsigned temp;
+ if (PK_bitpos < 0) {
+ PK_input_byte = one(fp);
+ PK_bitpos = 4;
+ }
+ temp = PK_input_byte >> PK_bitpos;
+ PK_bitpos -= 4;
+ return (temp & 0xf);
+}
+
+
+static int
+PK_packed_num(fp)
+ register FILE *fp;
+{
+ int i,j;
+
+ if ((i = PK_get_nyb(fp)) == 0) {
+ do {
+ j = PK_get_nyb(fp);
+ ++i;
+ }
+ while (j == 0);
+ while (i > 0) {
+ j = (j << 4) | PK_get_nyb(fp);
+ --i;
+ }
+ return (j - 15 + ((13 - PK_dyn_f) << 4) + PK_dyn_f);
+ }
+ else {
+ if (i <= PK_dyn_f) return i;
+ if (i < 14)
+ return (((i - PK_dyn_f - 1) << 4) + PK_get_nyb(fp)
+ + PK_dyn_f + 1);
+ if (i == 14) PK_repeat_count = PK_packed_num(fp);
+ else PK_repeat_count = 1;
+ return PK_packed_num(fp);
+ }
+}
+
+
+static void
+PK_skip_specials(fontp)
+ register struct font *fontp;
+{
+ int i,j;
+ register FILE *fp = fontp->file;
+
+ do {
+ PK_flag_byte = one(fp);
+ if (PK_flag_byte >= PK_CMD_START) {
+ switch (PK_flag_byte) {
+ case PK_X1 :
+ case PK_X2 :
+ case PK_X3 :
+ case PK_X4 :
+ i = 0;
+ for (j = PK_CMD_START; j <= PK_flag_byte; ++j)
+ i = (i << 8) | one(fp);
+ while (i--) (void) one(fp);
+ break;
+ case PK_Y :
+ (void) four(fp);
+ case PK_POST :
+ case PK_NOOP :
+ break;
+ default :
+ oops("Unexpected %d in PK file %s", PK_flag_byte,
+ fontp->filename);
+ break;
+ }
+ }
+ }
+ while (PK_flag_byte != PK_POST && PK_flag_byte >= PK_CMD_START);
+}
+
+/*
+ * Public routines
+ */
+
+static void
+read_PK_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ int i, j;
+ int n;
+ int row_bit_pos;
+ Boolean paint_switch;
+ BMUNIT *cp;
+ register struct glyph *g;
+ register FILE *fp = fontp->file;
+ long fpwidth;
+ BMUNIT word;
+ int word_weight, bytes_wide;
+ int rows_left, h_bit, count;
+
+ g = &fontp->glyph[ch];
+ PK_flag_byte = g->x2;
+ PK_dyn_f = PK_flag_byte >> 4;
+ paint_switch = ((PK_flag_byte & 8) != 0);
+ PK_flag_byte &= 0x7;
+ if (PK_flag_byte == 7) n = 4;
+ else if (PK_flag_byte > 3) n = 2;
+ else n = 1;
+
+ if (debug & DBG_PK) Printf("loading pk char %d, char type %d ", ch, n);
+
+ /*
+ * now read rest of character preamble
+ */
+ if (n != 4) fpwidth = num(fp, 3);
+ else {
+ fpwidth = sfour(fp);
+ (void) four(fp); /* horizontal escapement */
+ }
+ (void) num(fp, n); /* vertical escapement */
+ {
+ unsigned long w, h;
+
+ w = num(fp, n);
+ h = num(fp, n);
+ if (w > 0x7fff || h > 0x7fff)
+ oops("Character %d too large in file %s", ch, fontp->fontname);
+ g->bitmap.w = w;
+ g->bitmap.h = h;
+ }
+ g->x = snum(fp, n);
+ g->y = snum(fp, n);
+
+ g->dvi_adv = fontp->dimconv * fpwidth;
+
+ if (debug & DBG_PK) {
+ if (g->bitmap.w != 0)
+ Printf(", size=%dx%d, dvi_adv=%ld", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+ Putchar('\n');
+ }
+
+ alloc_bitmap(&g->bitmap);
+ cp = (BMUNIT *) g->bitmap.bits;
+
+ /*
+ * read character data into *cp
+ */
+ bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
+ PK_bitpos = -1;
+ if (PK_dyn_f == 14) { /* get raster by bits */
+ bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
+ for (i = 0; i < g->bitmap.h; i++) { /* get all rows */
+ cp = ADD(g->bitmap.bits, i * bytes_wide);
+#ifndef MSBITFIRST
+ row_bit_pos = -1;
+#else
+ row_bit_pos = BITS_PER_BMUNIT;
+#endif
+ for (j = 0; j < g->bitmap.w; j++) { /* get one row */
+ if (--PK_bitpos < 0) {
+ word = one(fp);
+ PK_bitpos = 7;
+ }
+#ifndef MSBITFIRST
+ if (++row_bit_pos >= BITS_PER_BMUNIT) {
+ cp++;
+ row_bit_pos = 0;
+ }
+#else
+ if (--row_bit_pos < 0) {
+ cp++;
+ row_bit_pos = BITS_PER_BMUNIT - 1;
+ }
+#endif
+ if (word & (1 << PK_bitpos)) *cp |= 1 << row_bit_pos;
+ }
+ }
+ }
+ else { /* get packed raster */
+ rows_left = g->bitmap.h;
+ h_bit = g->bitmap.w;
+ PK_repeat_count = 0;
+ word_weight = BITS_PER_BMUNIT;
+ word = 0;
+ while (rows_left > 0) {
+ count = PK_packed_num(fp);
+ while (count > 0) {
+ if (count < word_weight && count < h_bit) {
+#ifndef MSBITFIRST
+ if (paint_switch)
+ word |= bit_masks[count] <<
+ (BITS_PER_BMUNIT - word_weight);
+#endif
+ h_bit -= count;
+ word_weight -= count;
+#ifdef MSBITFIRST
+ if (paint_switch)
+ word |= bit_masks[count] << word_weight;
+#endif
+ count = 0;
+ }
+ else if (count >= h_bit && h_bit <= word_weight) {
+ if (paint_switch)
+ word |= bit_masks[h_bit] <<
+#ifndef MSBITFIRST
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ (word_weight - h_bit);
+#endif
+ *cp++ = word;
+ /* "output" row(s) */
+ for (i = PK_repeat_count * bytes_wide /
+ BYTES_PER_BMUNIT; i > 0; --i) {
+ *cp = *SUB(cp, bytes_wide);
+ ++cp;
+ }
+ rows_left -= PK_repeat_count + 1;
+ PK_repeat_count = 0;
+ word = 0;
+ word_weight = BITS_PER_BMUNIT;
+ count -= h_bit;
+ h_bit = g->bitmap.w;
+ }
+ else {
+ if (paint_switch)
+#ifndef MSBITFIRST
+ word |= bit_masks[word_weight] <<
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ word |= bit_masks[word_weight];
+#endif
+ *cp++ = word;
+ word = 0;
+ count -= word_weight;
+ h_bit -= word_weight;
+ word_weight = BITS_PER_BMUNIT;
+ }
+ }
+ paint_switch = 1 - paint_switch;
+ }
+ if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h)))
+ oops("Wrong number of bits stored: char. %d, font %s", ch,
+ fontp->fontname);
+ if (rows_left != 0 || h_bit != g->bitmap.w)
+ oops("Bad pk file (%s), too many bits", fontp->fontname);
+ }
+}
+
+void
+read_PK_index(fontp)
+ register struct font *fontp;
+{
+ int hppp, vppp;
+
+ fontp->read_char = read_PK_char;
+ if (debug & DBG_PK)
+ Printf("Reading PK pixel file %s\n", fontp->filename);
+
+ Fseek(fontp->file, (long) one(fontp->file), 1); /* skip comment */
+
+ (void) four(fontp->file); /* skip design size */
+ (void) four(fontp->file); /* skip checksum */
+ hppp = sfour(fontp->file);
+ vppp = sfour(fontp->file);
+ if (hppp != vppp && (debug & DBG_PK))
+ Printf("Font has non-square aspect ratio %d:%d\n", vppp, hppp);
+ /*
+ * Prepare glyph array.
+ */
+ fontp->glyph = (struct glyph *) xmalloc(256 * sizeof(struct glyph),
+ "glyph array");
+ bzero((char *) fontp->glyph, 256 * sizeof(struct glyph));
+ /*
+ * Read glyph directory (really a whole pass over the file).
+ */
+ for (;;) {
+ int bytes_left, flag_low_bits;
+ unsigned int ch;
+
+ PK_skip_specials(fontp);
+ if (PK_flag_byte == PK_POST) break;
+ flag_low_bits = PK_flag_byte & 0x7;
+ if (flag_low_bits == 7) {
+ bytes_left = four(fontp->file);
+ ch = four(fontp->file);
+ } else if (flag_low_bits > 3) {
+ bytes_left = ((flag_low_bits - 4) << 16) + two(fontp->file);
+ ch = one(fontp->file);
+ } else {
+ bytes_left = (flag_low_bits << 8) + one(fontp->file);
+ ch = one(fontp->file);
+ }
+ fontp->glyph[ch].addr = ftell(fontp->file);
+ fontp->glyph[ch].x2 = PK_flag_byte;
+ Fseek(fontp->file, (long) bytes_left, 1);
+ if (debug & DBG_PK)
+ Printf("Scanning pk char %u, at %ld.\n", ch,
+ fontp->glyph[ch].addr);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/pxl.c b/systems/msdos/dviware/xdvi-dos/src/pxl.c
new file mode 100644
index 0000000000..1841aa614a
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/pxl.c
@@ -0,0 +1,166 @@
+/***
+ *** PXL font reading routines.
+ *** Public routines are read_PXL_index and read_PXL_char.
+ ***/
+
+#ifndef MSBITFIRST
+static unsigned char _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+#endif /* MSBITFIRST */
+
+static void
+read_PXL_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ register struct bitmap *bitmap;
+ register BMUNIT *ptr;
+ register FILE *fp = fontp->file;
+ register int i, j;
+#ifndef BMLONG
+ register int padding_length;
+#endif
+
+ bitmap = &fontp->glyph[ch].bitmap;
+ /* in file, bitmap rows are multiples of 32 bits wide */
+ alloc_bitmap(bitmap);
+ ptr = (BMUNIT *) bitmap->bits;
+#ifndef BMLONG
+ padding_length = 3 - (bitmap->bytes_wide + 3) % 4;
+#endif
+ for (i = bitmap->h; i > 0; --i) {
+ for (j = bitmap->bytes_wide; j > 0; j -= BYTES_PER_BMUNIT) {
+#ifndef MSBITFIRST
+ *ptr = _reverse_byte[one(fp)];
+#if BYTES_PER_BMUNIT > 1
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 8;
+#endif
+#ifdef BMLONG
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 16;
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 24;
+#endif
+#else /* MSBITFIRST */
+ *ptr = 0;
+#ifdef BMLONG
+ *ptr |= (BMUNIT) one(fp) << 24;
+ *ptr |= (BMUNIT) one(fp) << 16;
+#endif
+#if BYTES_PER_BMUNIT > 1
+ *ptr |= (BMUNIT) one(fp) << 8;
+#endif
+ *ptr |= (BMUNIT) one(fp);
+#endif /* MSBITFIRST */
+ ++ptr;
+ }
+#ifndef BMLONG
+ for (j = padding_length; j > 0; --j) (void) one(fp);
+#endif
+ }
+}
+
+void
+read_PXL_index(fontp)
+ register struct font *fontp;
+{
+ register FILE *fp = fontp->file;
+ register struct glyph *g;
+ long font_dir_ptr;
+ long trailer_ptr;
+
+ if (debug & DBG_PK)
+ Printf("Reading PXL file %s\n", fontp->filename);
+ fontp->read_char = read_PXL_char;
+ /* seek to trailer info */
+ Fseek(fp, (long) -4, 2);
+ while (four(fp) != 1001)
+ Fseek(fp, (long) -5, 1);
+ Fseek(fp, (long) -5 * 4, 1);
+ trailer_ptr = ftell(fp);
+ (void) four(fp); /* checksum */
+ (void) four(fp); /* magnify */
+ (void) four(fp); /* design size */
+ font_dir_ptr = sfour(fp) * 4;
+ (void) four(fp); /* pxl id word */
+ /* seek to font directory */
+ Fseek(fp, font_dir_ptr, 0);
+ maxchar = (trailer_ptr - font_dir_ptr) / 16 - 1;
+ fontp->glyph = (struct glyph *)
+ xmalloc((maxchar + 1) * sizeof(struct glyph), "glyph array");
+ for (g = fontp->glyph; g <= fontp->glyph + maxchar; ++g) {
+ g->bitmap.bits = NULL;
+ g->bitmap2.bits = NULL;
+#ifdef GREY
+ g->pixmap2 = NULL;
+#endif
+ g->bitmap.w = two(fp);
+ g->bitmap.h = two(fp);
+ g->x = stwo(fp);
+ g->y = stwo(fp);
+ g->addr = four(fp) * 4;
+ /*
+ ** The TFM-width word is kind of funny in the units
+ ** it is expressed in. It works this way:
+ **
+ ** If a glyph has width 'w' in a font with design-size
+ ** 'd' (both in same units), the TFM-width word is
+ **
+ ** t = (w/d) * 2^20
+ **
+ ** Therefore, in order to find the glyph width in
+ ** DVI units (1 / 2^16 points), we take the design-size
+ ** 'd' (in DVI's), the magnification 'm' of the PXL file
+ ** and the TFM-width word 't' to the width (in DVI's)
+ ** as follows:
+ **
+ ** dmt
+ ** w = -----
+ ** 2^20
+ **
+ ** But the magnification of the PXL file is just the
+ ** scaled size 's' over the design size, so the final
+ ** expression for the width is
+ **
+ ** st
+ ** w = ----
+ ** 2^20
+ **
+ */
+
+ g->dvi_adv = fontp->dimconv * four(fp);
+ if (debug & DBG_PK)
+ Printf("size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/tpic.c b/systems/msdos/dviware/xdvi-dos/src/tpic.c
new file mode 100644
index 0000000000..f6eb82da8c
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/tpic.c
@@ -0,0 +1,434 @@
+/*
+ * Support drawing routines for TeXsun and TeX
+ *
+ * Copyright, (C) 1987, 1988 Tim Morgan, UC Irvine
+ *
+ * At the time these routines are called, the values of hh and vv should
+ * have been updated to the upper left corner of the graph (the position
+ * the \special appears at in the dvi file). Then the coordinates in the
+ * graphics commands are in terms of a virtual page with axes oriented the
+ * same as the Imagen and the SUN normally have:
+ *
+ * 0,0
+ * +-----------> +x
+ * |
+ * |
+ * |
+ * \ /
+ * +y
+ *
+ * Angles are measured in the conventional way, from +x towards +y.
+ * Unfortunately, that reverses the meaning of "counterclockwise"
+ * from what it's normally thought of.
+ *
+ * A lot of floating point arithmetic has been converted to integer
+ * arithmetic for speed. In some places, this is kind-of kludgy, but
+ * it's worth it.
+ */
+
+#include <math.h>
+#include <ctype.h>
+
+#include "xdvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+#define MAXPOINTS 300 /* Max points in a path */
+#define TWOPI (double) (3.14159265359*2.0)
+#define MAX_PEN_SIZE 7 /* Max pixels of pen width */
+
+
+static int xx[MAXPOINTS], yy[MAXPOINTS]; /* Path in milli-inches */
+static int path_len = 0; /* # points in current path */
+static int pen_size = 1; /* Pixel width of lines drawn */
+
+static Boolean whiten = False;
+static Boolean shade = False;
+static Boolean blacken = False;
+
+/* Unfortunately, these values also appear in dvisun.c */
+#define xRESOLUTION (pixels_per_inch/shrink_factor)
+#define yRESOLUTION (pixels_per_inch/shrink_factor)
+
+
+/*
+ * Issue warning messages
+ */
+static void
+Warning(fmt, msg)
+ char *fmt, *msg;
+{
+ Fprintf(stderr, fmt, msg);
+ (void) fputc('\n', stderr);
+}
+
+
+/*
+ * Set the size of the virtual pen used to draw in milli-inches
+ */
+/* ARGSUSED */
+static void
+set_pen_size(cp)
+ char *cp;
+{
+ int ps;
+
+ if (sscanf(cp, " %d ", &ps) != 1) {
+ Warning("illegal .ps command format: %s", cp);
+ return;
+ }
+ pen_size = (ps * (xRESOLUTION + yRESOLUTION) + 1000) / 2000;
+ if (pen_size < 1) pen_size = 1;
+ else if (pen_size > MAX_PEN_SIZE) pen_size = MAX_PEN_SIZE;
+}
+
+
+/*
+ * Print the line defined by previous path commands
+ */
+static void
+flush_path()
+{
+ register int i;
+ int last_min_x, last_max_x, last_min_y, last_max_y;
+
+ last_min_x = 30000;
+ last_min_y = 30000;
+ last_max_x = -30000;
+ last_max_y = -30000;
+ for (i = 1; i < path_len; i++) {
+ if (xx[i] > last_max_x) last_max_x = xx[i];
+ if (xx[i] < last_min_x) last_min_x = xx[i];
+ if (yy[i] > last_max_y) last_max_y = yy[i];
+ if (yy[i] < last_min_y) last_min_y = yy[i];
+ line_btw(xx[i], yy[i], xx[i+1], yy[i+1]);
+ }
+ if (xx[path_len] > last_max_x) last_max_x = xx[path_len];
+ if (xx[path_len] < last_min_x) last_min_x = xx[path_len];
+ if (yy[path_len] > last_max_y) last_max_y = yy[path_len];
+ if (yy[path_len] < last_min_y) last_min_y = yy[path_len];
+ path_len = 0;
+ do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y);
+}
+
+
+/*
+ * Print a dashed line along the previously defined path, with
+ * the dashes/inch defined.
+ */
+
+static void
+flush_dashed(cp, dotted)
+ char *cp;
+ int dotted;
+{
+ int i;
+ int numdots;
+ int lx0, ly0, lx1, ly1;
+ int cx0, cy0, cx1, cy1;
+ float inchesperdash;
+ double d, spacesize, a, b, dx, dy, milliperdash;
+
+ if (sscanf(cp, " %f ", &inchesperdash) != 1) {
+ Warning("illegal format for dotted/dashed line: %s", cp);
+ return;
+ }
+ if (path_len <= 1 || inchesperdash <= 0.0) {
+ Warning("illegal conditions for dotted/dashed line", "");
+ return;
+ }
+ milliperdash = inchesperdash * 1000.0;
+ lx0 = xx[1]; ly0 = yy[1];
+ lx1 = xx[2]; ly1 = yy[2];
+ dx = lx1 - lx0;
+ dy = ly1 - ly0;
+ if (dotted) {
+ numdots = sqrt(dx*dx + dy*dy) / milliperdash + 0.5;
+ if (numdots == 0) numdots = 1;
+ for (i = 0; i <= numdots; i++) {
+ a = (float) i / (float) numdots;
+ cx0 = lx0 + a * dx + 0.5;
+ cy0 = ly0 + a * dy + 0.5;
+ dot_at(cx0, cy0);
+ }
+ }
+ else {
+ d = sqrt(dx*dx + dy*dy);
+ numdots = d / (2.0 * milliperdash) + 1.0;
+ if (numdots <= 1)
+ line_btw(lx0, ly0, lx1, ly1);
+ else {
+ spacesize = (d - numdots * milliperdash) / (numdots - 1);
+ for (i = 0; i < numdots - 1; i++) {
+ a = i * (milliperdash + spacesize) / d;
+ b = a + milliperdash / d;
+ cx0 = lx0 + a * dx + 0.5;
+ cy0 = ly0 + a * dy + 0.5;
+ cx1 = lx0 + b * dx + 0.5;
+ cy1 = ly0 + b * dy + 0.5;
+ line_btw(cx0, cy0, cx1, cy1);
+ b += spacesize / d;
+ }
+ cx0 = lx0 + b * dx + 0.5;
+ cy0 = ly0 + b * dy + 0.5;
+ line_btw(cx0, cy0, lx1, ly1);
+ }
+ }
+ path_len = 0;
+}
+
+
+/*
+ * Add a point to the current path
+ */
+static void
+add_path(cp)
+ char *cp;
+{
+ int pathx, pathy;
+
+ if (++path_len >= MAXPOINTS) oops("Too many points");
+ if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2)
+ oops("Malformed path command");
+ xx[path_len] = pathx;
+ yy[path_len] = pathy;
+}
+
+
+/*
+ * Draw to a floating point position
+ */
+static void
+im_fdraw(x, y)
+ double x,y;
+{
+ if (++path_len >= MAXPOINTS) oops("Too many arc points");
+ xx[path_len] = x + 0.5;
+ yy[path_len] = y + 0.5;
+}
+
+
+/*
+ * Draw an ellipse with the indicated center and radices.
+ */
+static void
+draw_ellipse(xc, yc, xr, yr)
+ int xc, yc, xr, yr;
+{
+ double angle, theta;
+ int n;
+ int px0, py0, px1, py1;
+
+ angle = (xr + yr) / 2.0;
+ theta = sqrt(1.0 / angle);
+ n = TWOPI / theta + 0.5;
+ if (n < 12) n = 12;
+ else if (n > 80) n = 80;
+ n /= 2;
+ theta = TWOPI / n;
+
+ angle = 0.0;
+ px0 = xc + xr; /* cos(0) = 1 */
+ py0 = yc; /* sin(0) = 0 */
+ while ((angle += theta) <= TWOPI) {
+ px1 = xc + xr*cos(angle) + 0.5;
+ py1 = yc + yr*sin(angle) + 0.5;
+ line_btw(px0, py0, px1, py1);
+ px0 = px1;
+ py0 = py1;
+ }
+ line_btw(px0, py0, xc + xr, yc);
+}
+
+/*
+ * Draw an arc
+ */
+static void
+arc(cp, invis)
+ char *cp;
+ Boolean invis;
+{
+ int xc, yc, xrad, yrad, n;
+ float start_angle, end_angle, angle, theta, r;
+ double xradius, yradius, xcenter, ycenter;
+
+ if (sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad,
+ &start_angle, &end_angle) != 6) {
+ Warning("illegal arc specification: %s", cp);
+ return;
+ }
+
+ if (invis) return;
+
+ /* We have a specialized fast way to draw closed circles/ellipses */
+ if (start_angle <= 0.0 && end_angle >= 6.282) {
+ draw_ellipse(xc, yc, xrad, yrad);
+ return;
+ }
+ xcenter = xc;
+ ycenter = yc;
+ xradius = xrad;
+ yradius = yrad;
+ r = (xradius + yradius) / 2.0;
+ theta = sqrt(1.0 / r);
+ n = 0.3 * TWOPI / theta + 0.5;
+ if (n < 12) n = 12;
+ else if (n > 80) n = 80;
+ n /= 2;
+ theta = TWOPI / n;
+ flush_path();
+ im_fdraw(xcenter + xradius * cos(start_angle),
+ ycenter + yradius * sin(start_angle));
+ angle = start_angle + theta;
+ if (end_angle < angle) end_angle += TWOPI;
+ while (angle < end_angle) {
+ im_fdraw(xcenter + xradius * cos(angle),
+ ycenter + yradius * sin(angle));
+ angle += theta;
+ }
+ im_fdraw(xcenter + xradius * cos(end_angle),
+ ycenter + yradius * sin(end_angle));
+ flush_path();
+}
+
+
+/*
+ * APPROXIMATE integer distance between two points
+ */
+#define dist(x0, y0, x1, y1) (abs(x0-x1)+abs(y0-y1))
+
+
+/*
+ * Draw a spline along the previously defined path
+ */
+static void
+flush_spline()
+{
+ int xp, yp;
+ int N;
+ int lastx, lasty;
+ int t1, t2, t3;
+ int steps;
+ int j;
+ register int i, w;
+
+#ifdef lint
+ lastx = lasty = -1;
+#endif
+ N = path_len + 1;
+ xx[0] = xx[1];
+ yy[0] = yy[1];
+ xx[N] = xx[N-1];
+ yy[N] = yy[N-1];
+ for (i = 0; i < N - 1; i++) { /* interval */
+ steps = (dist(xx[i], yy[i], xx[i+1], yy[i+1]) +
+ dist(xx[i+1], yy[i+1], xx[i+2], yy[i+2])) / 80;
+ for (j = 0; j < steps; j++) { /* points within */
+ w = (j * 1000 + 500) / steps;
+ t1 = w * w / 20;
+ w -= 500;
+ t2 = (750000 - w * w) / 10;
+ w -= 500;
+ t3 = w * w / 20;
+ xp = (t1*xx[i+2] + t2*xx[i+1] + t3*xx[i] + 50000) / 100000;
+ yp = (t1*yy[i+2] + t2*yy[i+1] + t3*yy[i] + 50000) / 100000;
+ if (i != 0 || j != 0) line_btw(lastx, lasty, xp, yp);
+ lastx = xp;
+ lasty = yp;
+ }
+ }
+ path_len = 0;
+}
+
+
+/*
+ * Shade the last box, circle, or ellipse
+ */
+static void
+shade_last()
+{
+ blacken = whiten = False;
+ shade = True;
+}
+
+
+/*
+ * Make the last box, circle, or ellipse, white inside (shade with white)
+ */
+static void
+whiten_last()
+{
+ whiten = True;
+ blacken = shade = False;
+}
+
+
+/*
+ * Make last box, etc, black inside
+ */
+static void
+blacken_last()
+{
+ blacken = True;
+ whiten = shade = False;
+}
+
+
+/*
+ * The following copyright message applies to the rest of this file. --PV
+ */
+
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ *
+ * This program may be freely copied, as long as this copyright
+ * message remaines affixed. It may not be sold, although it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warranty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ *
+ * Hacked in ignorance and desperation by jonah@db.toronto.edu
+ */
+
+/*
+ * The code to handle the \specials generated by tpic was modified
+ * by Dirk Grunwald using the code Tim Morgan at Univ. of Calif, Irvine
+ * wrote for TeXsun.
+ */
+
+#define COMLEN 4
+
+void
+applicationDoSpecial(cp)
+ char *cp;
+{
+ char command[COMLEN], *orig_cp;
+ register int len;
+
+ orig_cp = cp;
+ while (isspace(*cp)) ++cp;
+ len = 0;
+ while (!isspace(*cp) && *cp && len < COMLEN-1) command[len++] = *cp++;
+ command[len] = '\0';
+ if (strcmp(command, "pn") == 0) set_pen_size(cp);
+ else if (strcmp(command, "fp") == 0) flush_path();
+ else if (strcmp(command, "da") == 0) flush_dashed(cp, 0);
+ else if (strcmp(command, "dt") == 0) flush_dashed(cp, 1);
+ else if (strcmp(command, "pa") == 0) add_path(cp);
+ else if (strcmp(command, "ar") == 0) arc(cp, False);
+ else if (strcmp(command, "ia") == 0) arc(cp, True);
+ else if (strcmp(command, "sp") == 0) flush_spline();
+ else if (strcmp(command, "sh") == 0) shade_last();
+ else if (strcmp(command, "wh") == 0) whiten_last();
+ else if (strcmp(command, "bk") == 0) blacken_last();
+ /* throw away the path -- jansteen */
+ else if (strcmp(command, "ip") == 0) path_len = 0;
+ else if (!hush_spec_now)
+ Fprintf(stderr, "%s: special \"%s\" not implemented\n", prog,
+ orig_cp);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/util.c b/systems/msdos/dviware/xdvi-dos/src/util.c
new file mode 100644
index 0000000000..f1013d4d97
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/util.c
@@ -0,0 +1,216 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ */
+
+#include "xdvi.h"
+#include <errno.h>
+int errno;
+
+#ifdef VMS
+#include <rmsdef.h>
+#endif /* VMS */
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+char *malloc();
+#endif
+#if defined(macII) && !defined(__STDC__) /* stdlib.h doesn't define these */
+char *malloc();
+#endif /* macII */
+
+#if NeedVarargsPrototypes /* this is for oops */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DOPRNT /* define this if vfprintf gives you trouble */
+#define vfprintf(stream, message, args) _doprnt(message, args, stream)
+#endif
+
+/*
+ * General utility routines.
+ */
+
+/*
+ * Print error message and quit.
+ */
+
+#if NeedVarargsPrototypes
+NORETURN void
+oops(_Xconst char *message, ...)
+#else
+/* VARARGS */
+NORETURN void
+oops(va_alist)
+ va_dcl
+#endif
+{
+#if !NeedVarargsPrototypes
+ _Xconst char *message;
+#endif
+ va_list args;
+
+ Fprintf(stderr, "%s: ", prog);
+#if NeedVarargsPrototypes
+ va_start(args, message);
+#else
+ va_start(args);
+ message = va_arg(args, _Xconst char *);
+#endif
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ Putc('\n', stderr);
+ exit(1);
+}
+
+/*
+ * Either allocate storage or fail with explanation.
+ */
+
+char *
+xmalloc(size, why)
+ unsigned size;
+ _Xconst char *why;
+{
+ char *mem = malloc(size);
+
+ if (mem == NULL)
+ oops("! Cannot allocate %u bytes for %s.\n", size, why);
+ return mem;
+}
+
+/*
+ * Allocate bitmap for given font and character
+ */
+
+void
+alloc_bitmap(bitmap)
+ register struct bitmap *bitmap;
+{
+ register unsigned int size;
+
+ /* width must be multiple of 16 bits for raster_op */
+ bitmap->bytes_wide = ROUNDUP(bitmap->w, BITS_PER_BMUNIT) *
+ BYTES_PER_BMUNIT;
+ size = bitmap->bytes_wide * bitmap->h;
+ bitmap->bits = xmalloc(size != 0 ? size : 1, "character bitmap");
+}
+
+
+/*
+ * Close the pixel file for the least recently used font.
+ */
+
+static void
+close_a_file()
+{
+ register struct font *fontp;
+ unsigned short oldest = ~0;
+ struct font *f = NULL;
+
+ for (fontp = font_head; fontp != NULL; fontp = fontp->next)
+ if (fontp->file != NULL && fontp->timestamp <= oldest) {
+ f = fontp;
+ oldest = fontp->timestamp;
+ }
+ if (f == NULL)
+ oops("Can't find an open pixel file to close");
+ Fclose(f->file);
+ f->file = NULL;
+ ++n_files_left;
+}
+
+/*
+ * Open a file in the given mode.
+ */
+
+FILE *
+xfopen(filename)
+ _Xconst char *filename;
+{
+ FILE *f;
+
+ if (n_files_left == 0) close_a_file();
+ f = fopen(filename, OPEN_MODE);
+
+#ifndef VMS
+/* ericho if (f == NULL && (errno == EMFILE || errno == ENFILE)) */
+ if (f == NULL && (errno == EMFILE))
+#else /* VMS */
+ if (f == NULL && errno == EVMSERR && vaxc$errno == RMS$_ACC)
+#endif /* VMS */
+
+ {
+ n_files_left = 0;
+ close_a_file();
+ f = fopen(filename, OPEN_MODE);
+ }
+ return f;
+}
+
+
+/*
+ *
+ * Read size bytes from the FILE fp, constructing them into a
+ * signed/unsigned integer.
+ *
+ */
+
+unsigned long
+num(fp, size)
+ register FILE *fp;
+ register int size;
+{
+ register long x = 0;
+
+ while (size--) x = (x << 8) | one(fp);
+ return x;
+}
+
+long
+snum(fp, size)
+ register FILE *fp;
+ register int size;
+{
+ register long x;
+
+#ifdef __STDC__
+ x = (signed char) getc(fp);
+#else
+ x = (unsigned char) getc(fp);
+ if (x & 0x80) x -= 0x100;
+#endif
+ while (--size) x = (x << 8) | one(fp);
+ return x;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/vf.c b/systems/msdos/dviware/xdvi-dos/src/vf.c
new file mode 100644
index 0000000000..4560a5f966
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/vf.c
@@ -0,0 +1,123 @@
+#include "xdvi.h"
+#include "dvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+/***
+ *** VF font reading routines.
+ *** Public routine is read_index---because virtual characters are presumed
+ *** to be short, we read the whole virtual font in at once, instead of
+ *** faulting in characters as needed.
+ ***/
+
+#define LONG_CHAR 242
+
+/*
+ * These are parameters which determine whether macros are combined for
+ * storage allocation purposes. Small macros ( <= VF_PARM_1 bytes) are
+ * combined into chunks of size VF_PARM_2.
+ */
+
+#ifndef VF_PARM_1
+#define VF_PARM_1 20
+#endif
+#ifndef VF_PARM_2
+#define VF_PARM_2 256
+#endif
+
+/*
+ * The main routine
+ */
+
+void
+read_VF_index(fontp)
+ register struct font *fontp;
+{
+ FILE *VF_file = fontp->file;
+ ubyte cmnd;
+ ubyte *avail, *availend; /* available space for macros */
+
+ fontp->read_char = NULL;
+ fontp->flags |= FONT_VIRTUAL;
+ fontp->set_char_p = set_vf_char;
+ if (debug & DBG_PK)
+ Printf("Reading VF pixel file %s\n", fontp->filename);
+/*
+ * Read preamble.
+ */
+ Fseek(VF_file, (long) one(VF_file), 1); /* skip comment */
+ (void) four(VF_file); /* skip checksum */
+ (void) four(VF_file); /* skip design size */
+/*
+ * Read the fonts.
+ */
+ fontp->vf_chain = NULL;
+ fontp->first_font = NULL;
+ while ((cmnd = one(VF_file)) >= FNTDEF1 && cmnd <= FNTDEF4) {
+ define_font(VF_file, cmnd, fontp, &fontp->vf_chain);
+ if (fontp->first_font == NULL)
+ fontp->first_font = fontp->vf_chain->fontp;
+ }
+/*
+ * Prepare macro array.
+ */
+ fontp->macro = (struct macro *) xmalloc(256 * sizeof(struct macro),
+ "macro array");
+ bzero((char *) fontp->macro, 256 * sizeof(struct macro));
+/*
+ * Read macros.
+ */
+ avail = availend = NULL;
+ for (; cmnd <= LONG_CHAR; cmnd = one(VF_file)) {
+ register struct macro *m;
+ int len;
+ unsigned long cc;
+ long width;
+
+ if (cmnd == LONG_CHAR) { /* long form packet */
+ len = four(VF_file);
+ cc = four(VF_file);
+ width = four(VF_file);
+ if (cc >= 256) {
+ Fprintf(stderr,
+ "Virtual character %lu in font %s ignored.\n",
+ cc, fontp->fontname);
+ Fseek(VF_file, (long) len, 1);
+ continue;
+ }
+ }
+ else { /* short form packet */
+ len = cmnd;
+ cc = one(VF_file);
+ width = num(VF_file, 3);
+ }
+ m = &fontp->macro[cc];
+ m->dvi_adv = width * fontp->dimconv;
+ if (len > 0) {
+ if (len <= availend - avail) {
+ m->pos = avail;
+ avail += len;
+ }
+ else {
+ m->free_me = True;
+ if (len <= VF_PARM_1) {
+ m->pos = avail = (ubyte *) xmalloc(VF_PARM_2,
+ "macro array");
+ availend = avail + VF_PARM_2;
+ avail += len;
+ }
+ else m->pos = (ubyte *) xmalloc((unsigned) len,
+ "macro array");
+ }
+ Fread((char *) m->pos, 1, len, VF_file);
+ m->end = m->pos + len;
+ }
+ if (debug & DBG_PK)
+ Printf("Read VF macro for character %lu; dy = %ld, length = %d\n",
+ cc, m->dvi_adv, len);
+ }
+ if (cmnd != POST)
+ oops("Wrong command byte found in VF macro list: %d", cmnd);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.c b/systems/msdos/dviware/xdvi-dos/src/xdvi.c
new file mode 100644
index 0000000000..1aaa216ace
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.c
@@ -0,0 +1,3175 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+
+
+#ifndef ALTFONT
+#define ALTFONT "cmr10"
+#endif
+
+#ifndef A4
+#define DEFAULT_PAPER "us"
+#else
+#define DEFAULT_PAPER "a4"
+#endif
+
+#if !defined(X10) && !defined(NOTOOL)
+#define TOOLKIT
+#else
+#undef TOOLKIT
+#undef BUTTONS
+#endif
+
+#include <ctype.h>
+
+#define EXTERN
+#define INIT(x) =x
+#ifndef TOOLKIT
+#define NTINIT(x) =x
+#else
+#define NTINIT(x)
+#endif
+#include "xdvi.h"
+
+#include "patchlevel.h"
+static struct {_Xconst char a[33], b, c, d;}
+#ifndef X10
+ version = {"This is xdvi for X11, patchlevel ", '0' + PATCHLEVEL / 10,
+ '0' + PATCHLEVEL % 10, 0};
+#else
+ version = {"This is xdvi for X10, patchlevel ", '0' + PATCHLEVEL / 10,
+ '0' + PATCHLEVEL % 10, 0};
+#endif
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+
+/*------------------------------- MSDOS (Eric Ho) --------------------------*/
+#if defined(__MSDOS__) && defined (FONTSUB)
+
+extern FILE *openfontsubfile (void);
+FILE *fontsubfile; /* make this global to minize interference to */
+ /* the orginial source */
+#endif
+/*------------------------------- MSDOS (Eric Ho) --------------------------*/
+
+
+#ifndef X10
+/* Xlib and Xutil are already included */
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include "xdvi.icon"
+#endif /* X10 */
+
+#ifdef TOOLKIT
+#undef Boolean
+#include <X11/Intrinsic.h>
+#ifdef OLD_X11_TOOLKIT
+#include <X11/Atoms.h>
+#else /* not OLD_X11_TOOLKIT */
+#include <X11/Xatom.h>
+#include <X11/StringDefs.h>
+#endif /* not OLD_X11_TOOLKIT */
+#include <X11/Shell.h> /* needed for def. of XtNiconX */
+#ifndef XtSpecificationRelease
+#define XtSpecificationRelease 0
+#endif
+#if XtSpecificationRelease >= 4
+#include <X11/Xaw/Viewport.h>
+#ifdef BUTTONS
+#include <X11/Xaw/Command.h>
+#endif
+#else /* XtSpecificationRelease < 4 */
+#define XtPointer caddr_t
+#include <X11/Viewport.h>
+#ifdef BUTTONS
+#include <X11/Command.h>
+#endif
+#endif /* XtSpecificationRelease */
+#else /* !TOOLKIT */
+#define XtNumber(arr) (sizeof(arr)/sizeof(arr[0]))
+typedef int Position;
+typedef unsigned int Dimension;
+#ifndef X10
+typedef unsigned long Pixel;
+#define XtPending() XPending(DISP)
+#else
+#define XtPending XPending
+#define XMoveResizeWindow XConfigureWindow
+#endif
+#endif /* TOOLKIT */
+
+#ifdef HAS_SIGIO
+#include <fcntl.h>
+#include <signal.h>
+#endif
+
+#ifndef X10
+#ifndef GREY
+static Display *DISP;
+static Screen *SCRN;
+#endif
+#define DPY DISP,
+static Cursor redraw_cursor, ready_cursor;
+
+#ifdef VMS
+/*
+ * Magnifying glass cursor
+ *
+ * Developed by Tom Sawyer, April 1990
+ * Contibuted by Hunter Goatley, January 1991
+ *
+ */
+
+#define mag_glass_width 16
+#define mag_glass_height 16
+#define mag_glass_x_hot 6
+#define mag_glass_y_hot 6
+static char mag_glass_bits[] = {
+ 0xf8, 0x03, 0x0c, 0x06, 0xe2, 0x09, 0x13, 0x1a, 0x01, 0x14, 0x01, 0x14,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x03, 0x10, 0x02, 0x18, 0x0c, 0x34,
+ 0xf8, 0x6f, 0x00, 0xd8, 0x00, 0xb0, 0x00, 0xe0
+};
+#include <decw$cursor.h> /* Include the DECWindows cursor symbols */
+static int DECWCursorFont; /* Space for the DECWindows cursor font */
+static Pixmap MagnifyPixmap; /* Pixmap to hold our special mag-glass */
+#endif /* VMS */
+
+#define SetCursor(x) XDefineCursor(DISP, WINDOW(mane), x)
+#define ClearPage(wr) XClearWindow(DISP, WINDOW(wr));
+#define ClearArea(win, x, y, w, h) XClearArea(DISP, win, x, y, w, h, False)
+#define DarkenArea(win, x, y, w, h) \
+ XFillRectangle(DISP, win, ruleGC, x, y, w, h)
+#define CopyArea(win, x, y, w, h, x2, y2) \
+ XCopyArea(DISP, win, win, DefaultGCOfScreen(SCRN), \
+ x, y, w, h, x2, y2)
+#define Flush() XFlush(DISP)
+#ifndef X11HEIGHT
+#define X11HEIGHT 8 /* Height of server default font */
+#endif
+#else /* X10 */
+#define DPY
+#define GC int
+#define SetCursor(x)
+#define ClearPage(wr) XClear(WINDOW(wr));
+#define ClearArea(win, x, y, w, h) XPixSet(win, x, y, w, h, backpix)
+#define DarkenArea(win, x, y, w, h) XPixSet(win, x, y, w, h, foreGC)
+#define CopyArea(win, x, y, w, h, x2, y2) \
+ XMoveArea(win, x, y, x2, y2, w, h, GXcopy);
+#define XBell(a,b) XFeep(b/10-1)
+#define Flush() XFlush()
+#define ConnectionNumber(DISP) (_XlibCurrentDisplay->fd)
+#ifndef X10FONT
+#define X10FONT "helv10b" /* Font for X10 error messages */
+#define X10HEIGHT 10
+#endif
+#endif /* X10 */
+
+#define MAGBORD 1 /* border size for magnifier */
+
+/*
+ * Command line flags.
+ */
+
+static Dimension bwidth = 2;
+
+#ifdef TOOLKIT
+
+#define RESOURCE(x) resource.x
+
+static struct _resource {
+ char *debug_arg;
+ int _shrink_factor;
+ int density;
+#ifdef GREY
+ float gamma;
+#endif
+ int pixels_per_inch;
+ char *sidemargin;
+ char *topmargin;
+ char *xoffset;
+ char *yoffset;
+ _Xconst char *paper;
+ char *alt_font;
+ Boolean list_fonts;
+ Boolean reverse;
+ Boolean hush_spec;
+ Boolean hush_chars;
+ Pixel fore_Pixel;
+ char *fore_color;
+ Pixel back_Pixel;
+ char *back_color;
+ Pixel brdr_Pixel;
+ char *brdr_color;
+ Pixel hl_Pixel;
+ char *high_color;
+ Pixel cr_Pixel;
+ char *curs_color;
+ char *icon_geometry;
+ Boolean keep_flag;
+ char *copy_arg;
+ Boolean copy;
+ Boolean thorough;
+ Boolean version_flag;
+#ifdef BUTTONS
+ Boolean expert;
+#endif
+ int mg_size[5];
+#ifdef GREY
+ Boolean use_grey;
+#endif
+} resource;
+
+#else /* !TOOLKIT */
+
+#define RESOURCE(x) x
+static char *debug_arg;
+#ifdef GREY
+static float gamma = 1.0;
+#endif
+static char *sidemargin, *topmargin;
+static char *xoffset, *yoffset;
+static _Xconst char *paper = DEFAULT_PAPER;
+static Boolean reverse;
+static Boolean keep_flag = False;
+#ifndef X10
+static Pixel fore_Pixel, back_Pixel, brdr_Pixel, hl_Pixel, cr_Pixel;
+static char *icon_geometry;
+static Boolean copy = 2;
+static Boolean thorough;
+#endif /* X10 */
+static Boolean version_flag = False;
+static int mg_size[5] = {200, 350, 600, 900, 1200};
+
+#endif /* TOOLKIT */
+
+static char *curr_page;
+
+#ifndef TOOLKIT
+static char *fore_color;
+static char *back_color;
+static char *brdr_color;
+static char *high_color;
+static char *curs_color;
+#endif
+static GC foreGC, highGC;
+#ifndef X10
+static GC ruleGC;
+static GC foreGC2;
+#else /* X10 */
+#define ruleGC foreGC
+#endif /* X10 */
+
+static int pageno_correct = 1;
+static int bak_shrink;
+
+#define clip_w mane.width
+#define clip_h mane.height
+static Dimension window_w, window_h;
+#ifndef X10
+static Position main_x, main_y;
+static XImage *image;
+#else /* X10 */
+#define main_x 0
+#define main_y 0
+static int GXfunc;
+static int backpix, backmap, bdrmap;
+/*
+ * Cursor and mask for valid cursor
+ */
+#include "xdvi_curs.h"
+#include "xdvi_mask.h"
+#endif /* X10 */
+
+static Position mag_x, mag_y, new_mag_x, new_mag_y;
+static Boolean mag_moved = False;
+static int home_x, home_y;
+static int min_x, max_x, min_y, max_y;
+
+struct WindowRec mane = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+struct WindowRec alt = {(Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+/* currwin is temporary storage except for within redraw() */
+struct WindowRec currwin = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+
+#ifdef TOOLKIT
+static Widget top_level, vport_widget, draw_widget, clip_widget;
+#ifdef BUTTONS
+static Widget form_widget, line_widget, right_widget;
+#endif
+static Widget x_bar, y_bar; /* horizontal and vertical scroll bars */
+
+static Arg vport_args[] = {
+#ifdef BUTTONS
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainLeft},
+ {XtNright, (XtArgVal) XtChainRight},
+#endif
+ {XtNallowHoriz, (XtArgVal) True},
+ {XtNallowVert, (XtArgVal) True},
+};
+
+/* Note: Argument order in the following is important! */
+
+static Arg draw_args[] = {
+ {XtNwidth, (XtArgVal) 0},
+ {XtNheight, (XtArgVal) 0},
+ {XtNx, (XtArgVal) 0},
+ {XtNy, (XtArgVal) 0},
+ {XtNlabel, (XtArgVal) ""},
+};
+
+#ifdef BUTTONS
+static Arg form_args[] = {
+ {XtNdefaultDistance, (XtArgVal) 0},
+};
+#define XTRA_WID 79
+
+static Arg line_args[] = {
+ {XtNbackground, (XtArgVal) 0},
+ {XtNwidth, (XtArgVal) 1},
+ {XtNheight, (XtArgVal) 0},
+ {XtNfromHoriz, (XtArgVal) NULL},
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainRight},
+ {XtNright, (XtArgVal) XtChainRight},
+};
+
+static Arg right_args[] = {
+ {XtNfromHoriz, (XtArgVal) NULL},
+ {XtNwidth, (XtArgVal) (XTRA_WID - 1)},
+ {XtNheight, (XtArgVal) 0},
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainRight},
+ {XtNright, (XtArgVal) XtChainRight},
+};
+
+static struct {
+ _Xconst char *label;
+ _Xconst char *name;
+ int closure;
+ int y_pos;
+ }
+ command_table[] = {
+ {"Quit", "quit", 'q', 50},
+ {"Shrink1", "sh1", 1 << 8 | 's', 150},
+ {"Shrink2", "sh2", 2 << 8 | 's', 200},
+ {"Shrink3", "sh3", 3 << 8 | 's', 250},
+ {"Shrink4", "sh4", 4 << 8 | 's', 300},
+ {"Page-10", "prev10", 10 << 8 | 'p', 400},
+ {"Page-5", "prev5", 5 << 8 | 'p', 450},
+ {"Prev", "prev", 'p', 500},
+ {"Next", "next", 'n', 600},
+ {"Page+5", "next5", 5 << 8 | 'n', 650},
+ {"Page+10", "next10", 10 << 8 | 'n', 700},
+};
+
+static void handle_command();
+
+static XtCallbackRec command_call[] = {
+ {handle_command, NULL},
+ {NULL, NULL},
+};
+
+static Arg command_args[] = {
+ {XtNlabel, (XtArgVal) NULL},
+ {XtNx, (XtArgVal) 6},
+ {XtNy, (XtArgVal) 0},
+ {XtNwidth, (XtArgVal) 64},
+ {XtNheight, (XtArgVal) 30},
+ {XtNcallback, (XtArgVal) command_call},
+};
+
+
+
+static void
+create_buttons(h)
+ XtArgVal h;
+{
+ int i;
+
+ line_args[2].value = h;
+ line_args[3].value = (XtArgVal) vport_widget;
+ line_widget = XtCreateManagedWidget("line", widgetClass, form_widget,
+ line_args, XtNumber(line_args));
+ right_args[0].value = (XtArgVal) line_widget;
+ right_args[2].value = h;
+ right_widget = XtCreateManagedWidget("right", compositeWidgetClass,
+ form_widget, right_args, XtNumber(right_args));
+
+ command_args[2].value = (XtArgVal) vport_widget;
+ for (i = 0; i < XtNumber(command_table); ++i) {
+ command_args[0].value = (XtArgVal) command_table[i].label;
+ command_args[2].value = (XtArgVal) command_table[i].y_pos;
+ command_call[0].closure = (caddr_t) command_table[i].closure;
+ (void) XtCreateManagedWidget(command_table[i].name,
+ commandWidgetClass, right_widget,
+ command_args, XtNumber(command_args));
+ }
+}
+#endif /* BUTTONS */
+
+#ifdef NOQUERY
+#define drawWidgetClass widgetClass
+#else
+
+/* ARGSUSED */
+static XtGeometryResult
+QueryGeometry(w, constraints, reply)
+ Widget w;
+ XtWidgetGeometry *constraints, *reply;
+{
+ reply->request_mode = CWWidth | CWHeight;
+ reply->width = page_w;
+ reply->height = page_h;
+ return XtGeometryAlmost;
+}
+
+#include <X11/IntrinsicP.h>
+#include <X11/CoreP.h>
+
+ /* if the following gives you trouble, just compile with -DNOQUERY */
+static WidgetClassRec drawingWidgetClass = {
+ {
+ /* superclass */ &widgetClassRec,
+ /* class_name */ "Draw",
+ /* widget_size */ sizeof(WidgetRec),
+ /* class_initialize */ NULL,
+ /* class_part_initialize*/ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ NULL,
+ /* num_resources */ 0,
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ XtInheritAcceptFocus,
+ /* version */ XtVersion,
+ /* callback_offsets */ NULL,
+ /* tm_table */ XtInheritTranslations,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ }
+};
+
+#define drawWidgetClass &drawingWidgetClass
+
+#endif /* NOQUERY */
+
+#else /* !TOOLKIT */
+#define BAR_WID 12 /* width of darkened area */
+#define BAR_THICK 15 /* gross amount removed */
+
+static Window top_level;
+static Window x_bar, y_bar;
+static int x_bgn, x_end, y_bgn, y_end; /* scrollbar positions */
+#endif /* TOOLKIT */
+
+/*
+ * Mechanism to keep track of the magnifier window. The problems are,
+ * (a) if the button is released while the window is being drawn, this
+ * could cause an X error if we continue drawing in it after it is
+ * destroyed, and
+ * (b) creating and destroying the window too quickly confuses the window
+ * manager, which is avoided by waiting for an expose event before
+ * destroying it.
+ */
+static short alt_stat; /* 1 = wait for expose, */
+ /* -1 = destroy upon expose */
+static Boolean alt_canit; /* stop drawing this window */
+
+/*
+ * Data for buffered events.
+ */
+
+static Boolean canit = False,
+ has_arg = False;
+static VOLATILE short event_counter = 0;
+static VOLATILE short event_freq = 70;
+static int number = 0,
+ sign = 1;
+static jmp_buf canit_env;
+
+static void can_exposures(), read_events(), keystroke();
+
+#ifdef lint
+#ifndef X10
+char xdvi_bits[288];
+#ifdef TOOLKIT
+WidgetClass viewportWidgetClass, widgetClass;
+WidgetClassRec widgetClassRec;
+#ifdef BUTTONS
+WidgetClass formWidgetClass, compositeWidgetClass, commandWidgetClass;
+#endif /* BUTTONS */
+#endif /* TOOLKIT */
+#else /* X10 */
+short xdvi_bits[15], xdvi_mask_bits[15];
+Display *_XlibCurrentDisplay;
+#endif /* X10 */
+#endif /* lint */
+
+#ifdef GREY
+static void
+init_pix(warn)
+ Boolean warn;
+{
+ static int shrink_allocated_for = 0;
+ static Boolean colors_allocated = False;
+ int i;
+
+ if (!colors_allocated)
+ {
+ Pixel plane_masks[4];
+ Pixel pixel;
+ XColor color, fc, bc;
+ XGCValues values;
+ int i;
+
+ if (RESOURCE(gamma) == 0.0) RESOURCE(gamma) = 1.0;
+
+ if (!RESOURCE(copy))
+ /* allocate 4 color planes for 16 colors (for GXor drawing) */
+ if (!XAllocColorCells(DISP, DefaultColormapOfScreen(SCRN),
+ False, plane_masks, 4, &pixel, 1))
+ RESOURCE(copy) = warn = True;
+
+ /* get foreground and background RGB values for interpolating */
+ fc.pixel = RESOURCE(fore_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &fc);
+ bc.pixel = RESOURCE(back_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bc);
+
+ for (i = 0; i < 16; ++i) {
+ double pow();
+ double frac = RESOURCE(gamma) > 0 ?
+ pow((double) i / 15, 1 / RESOURCE(gamma))
+ : 1 - pow((double) (15 - i) / 15, -RESOURCE(gamma));
+
+ color.red = frac * ((double) fc.red - bc.red) + bc.red;
+ color.green = frac * ((double) fc.green - bc.green) + bc.green;
+ color.blue = frac * ((double) fc.blue - bc.blue) + bc.blue;
+
+ color.pixel = pixel;
+ color.flags = DoRed | DoGreen | DoBlue;
+
+ if (!RESOURCE(copy)) {
+ if (i & 1) color.pixel |= plane_masks[0];
+ if (i & 2) color.pixel |= plane_masks[1];
+ if (i & 4) color.pixel |= plane_masks[2];
+ if (i & 8) color.pixel |= plane_masks[3];
+ XStoreColor(DISP, DefaultColormapOfScreen(SCRN), &color);
+ palette[i] = color.pixel;
+ }
+ else {
+ if (!XAllocColor(DISP, DefaultColormapOfScreen(SCRN),
+ &color))
+ palette[i] = (i * 100 >= density * 15)
+ ? RESOURCE(fore_Pixel) : RESOURCE(back_Pixel);
+ else
+ palette[i] = color.pixel;
+ }
+ }
+
+ /* Make sure fore_ and back_Pixel are a part of the palette */
+ RESOURCE(fore_Pixel) = palette[15];
+ RESOURCE(back_Pixel) = palette[0];
+
+#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\
+ values.background=bg,\
+ XCreateGC(DISP, RootWindowOfScreen(SCRN),\
+ GCFunction|GCForeground|GCBackground, &values))
+
+ foreGC = ruleGC = MakeGC(RESOURCE(copy) ? GXcopy : GXor,
+ RESOURCE(fore_Pixel), RESOURCE(back_Pixel));
+
+ colors_allocated = True;
+ if (RESOURCE(copy) && warn)
+ Puts("Note: overstrike characters may be incorrect.");
+ }
+#undef MakeGC
+
+ if (mane.shrinkfactor == 1) return;
+
+ if (shrink_allocated_for < mane.shrinkfactor) {
+ if (pixeltbl != NULL) free((char *) pixeltbl);
+ pixeltbl = (Pixel *) xmalloc((unsigned)
+ (mane.shrinkfactor * mane.shrinkfactor + 1) * sizeof(Pixel),
+ "pixel table");
+ shrink_allocated_for = mane.shrinkfactor;
+ }
+
+ for (i = 0; i <= mane.shrinkfactor * mane.shrinkfactor; ++i)
+ pixeltbl[i] =
+ palette[(i * 30 + mane.shrinkfactor * mane.shrinkfactor)
+ / (2 * mane.shrinkfactor * mane.shrinkfactor)];
+}
+#endif /* GREY */
+
+#ifdef sun
+extern char *sprintf();
+#endif
+
+#ifndef atof /* on the Next it's a macro */
+extern double atof();
+#endif
+
+/********************************
+ * tpic routines *
+ *******************************/
+
+/* Things we need from spec_draw, unfortunately */
+
+/* (ignored for now)
+extern int pen_size, blacken, whiten, shade;
+*/
+
+#define toint(x) ((int) ((x) + 0.5))
+#define xconv(x) (toint(specialConv*(x))/shrink_factor + PXL_H)
+#define yconv(y) (toint(specialConv*(y))/shrink_factor + PXL_V)
+
+/*
+ * Draw a line from (fx,fy) to (tx,ty).
+ * Right now, we ignore pen_size.
+ */
+void
+line_btw(fx, fy, tx, ty)
+int fx, fy, tx, ty;
+{
+ register int fcx = xconv(fx),
+ tcx = xconv(tx),
+ fcy = yconv(fy),
+ tcy = yconv(ty);
+
+ if ((fcx < max_x || tcx < max_x) && (fcx >= min_x || tcx >= min_x) &&
+ (fcy < max_y || tcy < max_y) && (fcy >= min_y || tcy >= min_y))
+#ifndef X10
+ XDrawLine(DISP, WINDOW(currwin), ruleGC,
+ fcx - currwin.base_x, fcy - currwin.base_y,
+ tcx - currwin.base_x, tcy - currwin.base_y);
+#else
+ XLine(WINDOW(currwin),
+ fcx - currwin.base_x, fcy - currwin.base_y,
+ tcx - currwin.base_x, tcy - currwin.base_y,
+ 1, 1, ruleGC, GXcopy, AllPlanes);
+#endif
+}
+
+/*
+ * Draw a dot at (x,y)
+ */
+void
+dot_at(x, y)
+ int x, y;
+{
+ register int cx = xconv(x),
+ cy = yconv(y);
+
+ if (cx < max_x && cx >= min_x && cy < max_y && cy >= min_y)
+#ifndef X10
+ XDrawPoint(DISP, WINDOW(currwin), ruleGC,
+ cx - currwin.base_x, cy - currwin.base_y);
+#else
+ XPixSet(WINDOW(currwin), cx - currwin.base_x, cy - currwin.base_y,
+ 1, 1, ruleGC);
+#endif
+}
+
+/*
+ * Apply the requested attributes to the last path (box) drawn.
+ * Attributes are reset.
+ * (Not currently implemented.)
+ */
+ /* ARGSUSED */
+void
+do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y)
+int last_min_x, last_max_x, last_min_y, last_max_y;
+{
+}
+
+/*
+ * Put a rectangle on the screen. hl determines the GC.
+ */
+
+void
+put_rectangle(x, y, w, h, hl)
+ int x, y, w, h;
+ WIDEARG(Boolean, int) hl;
+{
+ if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y) {
+ if (--event_counter == 0) read_events(False);
+#ifndef X10
+ XFillRectangle(DISP, WINDOW(currwin), hl ? highGC : ruleGC,
+ x - currwin.base_x, y - currwin.base_y,
+ w ? w : 1, h ? h : 1);
+#else
+ XPixSet(WINDOW(currwin), x - currwin.base_x, y - currwin.base_y,
+ w ? w : 1, h ? h : 1, hl ? highGC : ruleGC);
+#endif
+ }
+}
+
+void
+put_bitmap(bitmap, x, y)
+ register struct bitmap *bitmap;
+ register int x, y;
+{
+
+ if (debug & DBG_BITMAP)
+ Printf("X(%d,%d)\n", x - currwin.base_x, y - currwin.base_y);
+ if (x < max_x && x + bitmap->w >= min_x &&
+ y < max_y && y + bitmap->h >= min_y) {
+ if (--event_counter == 0) read_events(False);
+#ifndef X10
+ image->width = bitmap->w;
+ image->height = bitmap->h;
+ image->data = bitmap->bits;
+ image->bytes_per_line = bitmap->bytes_wide;
+ XPutImage(DISP, WINDOW(currwin), foreGC, image,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h);
+ if (foreGC2)
+ XPutImage(DISP, WINDOW(currwin), foreGC2, image,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h);
+#else
+ XBitmapBitsPut(WINDOW(currwin),
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h, bitmap->bits,
+ foreGC, backpix, NULL, GXfunc, AllPlanes);
+#endif
+ }
+}
+
+#ifdef GREY
+void
+put_image(img, x, y)
+ register XImage *img;
+ register int x, y;
+{
+ if (x < max_x && x + img->width >= min_x &&
+ y < max_y && y + img->height >= min_y) {
+
+ if (--event_counter == 0) read_events (False);
+
+ XPutImage(DISP, WINDOW(currwin), foreGC, img,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ img->width, img->height);
+
+ if (foreGC2)
+ XPutImage(DISP, WINDOW(currwin), foreGC2, img,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ img->width, img->height);
+ }
+}
+#endif /* GREY */
+
+/*
+ * Event-handling routines
+ */
+
+static void
+expose(windowrec, x, y, w, h)
+ register struct WindowRec *windowrec;
+ int x, y, w, h;
+{
+ if (windowrec->min_x > x) windowrec->min_x = x;
+ if (windowrec->max_x < x + w)
+ windowrec->max_x = x + w;
+ if (windowrec->min_y > y) windowrec->min_y = y;
+ if (windowrec->max_y < y + h)
+ windowrec->max_y = y + h;
+}
+
+static void
+clearexpose(windowrec, x, y, w, h)
+ struct WindowRec *windowrec;
+ int x, y, w, h;
+{
+ ClearArea(WINDOW(*windowrec), x, y, w, h);
+ expose(windowrec, x, y, w, h);
+}
+
+static void
+scrollwindow(windowrec, x0, y0)
+ register struct WindowRec *windowrec;
+ int x0, y0;
+{
+ int x, y;
+ int x2 = 0, y2 = 0;
+ int ww, hh;
+
+ x = x0 - windowrec->base_x;
+ y = y0 - windowrec->base_y;
+ ww = windowrec->width - x;
+ hh = windowrec->height - y;
+ windowrec->base_x = x0;
+ windowrec->base_y = y0;
+ if (currwin.win == windowrec->win) {
+ currwin.base_x = x0;
+ currwin.base_y = y0;
+ }
+ windowrec->min_x -= x;
+ if (windowrec->min_x < 0) windowrec->min_x = 0;
+ windowrec->max_x -= x;
+ if (windowrec->max_x > windowrec->width)
+ windowrec->max_x = windowrec->width;
+ windowrec->min_y -= y;
+ if (windowrec->min_y < 0) windowrec->min_y = 0;
+ windowrec->max_y -= y;
+ if (windowrec->max_y > windowrec->height)
+ windowrec->max_y = windowrec->height;
+ if (x < 0) {
+ x2 = -x;
+ x = 0;
+ ww = windowrec->width - x2;
+ }
+ if (y < 0) {
+ y2 = -y;
+ y = 0;
+ hh = windowrec->height - y2;
+ }
+ if (ww <= 0 || hh <= 0) {
+ ClearPage(*windowrec);
+ windowrec->min_x = windowrec->min_y = 0;
+ windowrec->max_x = windowrec->width;
+ windowrec->max_y = windowrec->height;
+ }
+ else {
+ CopyArea(WINDOW(*windowrec), x, y, ww, hh, x2, y2);
+ if (x > 0) clearexpose(windowrec, ww, 0, x, windowrec->height);
+ if (x2 > 0) clearexpose(windowrec, 0, 0, x2, windowrec->height);
+ if (y > 0) clearexpose(windowrec, 0, hh, windowrec->width, y);
+ if (y2 > 0) clearexpose(windowrec, 0, 0, windowrec->width, y2);
+ }
+}
+
+#ifdef TOOLKIT
+/*
+ * routines for X11 toolkit
+ */
+
+static Arg arg_wh[] = {
+ {XtNwidth, (XtArgVal) &window_w},
+ {XtNheight, (XtArgVal) &window_h},
+};
+
+static Position window_x, window_y;
+static Arg arg_xy[] = {
+ {XtNx, (XtArgVal) &window_x},
+ {XtNy, (XtArgVal) &window_y},
+};
+
+#define get_xy() XtGetValues(draw_widget, arg_xy, XtNumber(arg_xy))
+
+#define mane_base_x 0
+#define mane_base_y 0
+
+static void
+home(scrl)
+ Boolean scrl;
+{
+ if (!scrl) XUnmapWindow(DISP, WINDOW(mane));
+ get_xy();
+ if (x_bar != NULL) {
+ register int coord = (page_w - clip_w) / 2;
+ if (coord > home_x / mane.shrinkfactor)
+ coord = home_x / mane.shrinkfactor;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (window_x + coord));
+ }
+ if (y_bar != NULL) {
+ register int coord = (page_h - clip_h) / 2;
+ if (coord > home_y / mane.shrinkfactor)
+ coord = home_y / mane.shrinkfactor;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (window_y + coord));
+ }
+ if (!scrl) {
+ XMapWindow(DISP, WINDOW(mane));
+ /* Wait for the server to catch up---this eliminates flicker. */
+ XSync(DISP, False);
+ }
+}
+
+static Boolean resized = False;
+
+static void
+get_geom()
+{
+ static Dimension new_clip_w, new_clip_h;
+ static Arg arg_wh_clip[] = {
+ {XtNwidth, (XtArgVal) &new_clip_w},
+ {XtNheight, (XtArgVal) &new_clip_h},
+ };
+ register int old_clip_w;
+
+ XtGetValues(vport_widget, arg_wh, XtNumber(arg_wh));
+ XtGetValues(clip_widget, arg_wh_clip, XtNumber(arg_wh_clip));
+ /* Note: widgets may be destroyed but not forgotten */
+ x_bar = page_w <= new_clip_w ? NULL
+ : XtNameToWidget(vport_widget, "horizontal");
+ y_bar = page_h <= new_clip_h ? NULL
+ : XtNameToWidget(vport_widget, "vertical");
+ old_clip_w = clip_w;
+ /* we need to do this because */
+ /* sizeof(Dimension) != sizeof(int) */
+ clip_w = new_clip_w;
+ clip_h = new_clip_h;
+ if (old_clip_w == 0) home(False);
+ resized = False;
+}
+
+static void
+center(x, y)
+ int x, y;
+{
+/* We use the clip widget here because it gives a more exact value. */
+ x -= clip_w/2;
+ y -= clip_h/2;
+ if (x_bar) XtCallCallbacks(x_bar, XtNscrollProc, (XtPointer) x);
+ if (y_bar) XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) y);
+ XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y);
+}
+
+/*
+ * callback routines
+ */
+
+/* The following callback routine should never be called. */
+ /*ARGSUSED*/
+static void
+handle_key(widget, junk, event, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *event;
+ Boolean *cont; /* unused */
+{
+ XBell(DISP, 20);
+}
+
+ /*ARGSUSED*/
+static void
+handle_resize(widget, junk, event, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *event;
+ Boolean *cont; /* unused */
+{
+ resized = True;
+}
+
+#ifdef BUTTONS
+ /*ARGSUSED*/
+static void
+handle_command(widget, client_data, call_data)
+ Widget widget;
+ XtPointer client_data;
+ XtPointer call_data;
+{
+ int int_client_data = (int) client_data; /* Apollo cc bug */
+
+ keystroke((int_client_data) & 0xff, (int_client_data) >> 8,
+ ((int_client_data) >> 8) != 0, (XEvent *) NULL);
+}
+#endif /* BUTTONS */
+
+#else /* !TOOLKIT */
+
+/*
+ * brute force scrollbar routines
+ */
+
+static void
+paint_x_bar()
+{
+ register int new_x_bgn = mane.base_x * clip_w / page_w;
+ register int new_x_end = (mane.base_x + clip_w) * clip_w / page_w;
+
+ if (new_x_bgn >= x_end || x_bgn >= new_x_end) { /* no overlap */
+ ClearArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID);
+ DarkenArea(x_bar, new_x_bgn, 1, new_x_end - new_x_bgn, BAR_WID);
+ }
+ else { /* this stuff avoids flicker */
+ if (x_bgn < new_x_bgn)
+ ClearArea(x_bar, x_bgn, 1, new_x_bgn - x_bgn, BAR_WID);
+ else
+ DarkenArea(x_bar, new_x_bgn, 1, x_bgn - new_x_bgn, BAR_WID);
+ if (new_x_end < x_end)
+ ClearArea(x_bar, new_x_end, 1, x_end - new_x_end, BAR_WID);
+ else
+ DarkenArea(x_bar, x_end, 1, new_x_end - x_end, BAR_WID);
+ }
+ x_bgn = new_x_bgn;
+ x_end = new_x_end;
+}
+
+static void
+paint_y_bar()
+{
+ register int new_y_bgn = mane.base_y * clip_h / page_h;
+ register int new_y_end = (mane.base_y + clip_h) * clip_h / page_h;
+
+ if (new_y_bgn >= y_end || y_bgn >= new_y_end) { /* no overlap */
+ ClearArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn);
+ DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, new_y_end - new_y_bgn);
+ }
+ else { /* this stuff avoids flicker */
+ if (y_bgn < new_y_bgn)
+ ClearArea(y_bar, 1, y_bgn, BAR_WID, new_y_bgn - y_bgn);
+ else
+ DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, y_bgn - new_y_bgn);
+ if (new_y_end < y_end)
+ ClearArea(y_bar, 1, new_y_end, BAR_WID, y_end - new_y_end);
+ else
+ DarkenArea(y_bar, 1, y_end, BAR_WID, new_y_end - y_end);
+ }
+ y_bgn = new_y_bgn;
+ y_end = new_y_end;
+}
+
+static void
+scrollmane(x, y)
+ int x, y;
+{
+ register int old_base_x = mane.base_x;
+ register int old_base_y = mane.base_y;
+ if (x > page_w - clip_w) x = page_w - clip_w;
+ if (x < 0) x = 0;
+ if (y > page_h - clip_h) y = page_h - clip_h;
+ if (y < 0) y = 0;
+ scrollwindow(&mane, x, y);
+ if (old_base_x != mane.base_x && x_bar) paint_x_bar();
+ if (old_base_y != mane.base_y && y_bar) paint_y_bar();
+}
+
+static void
+reconfig()
+{
+ int x_thick = 0;
+ int y_thick = 0;
+#ifdef X10
+ int old_clip_w = clip_w;
+ int old_clip_h = clip_h;
+ int old_x_thick = x_thick;
+ int old_y_thick = y_thick;
+#endif
+
+ /* determine existence of scrollbars */
+ if (window_w < page_w) x_thick = BAR_THICK;
+ if (window_h - x_thick < page_h) y_thick = BAR_THICK;
+ clip_w = window_w - y_thick;
+ if (clip_w < page_w) x_thick = BAR_THICK;
+ clip_h = window_h - x_thick;
+
+ /* process drawing (clip) window */
+ if (mane.win == NULL) { /* initial creation */
+#ifndef X10
+ mane.win = XCreateSimpleWindow(DISP, top_level, y_thick, x_thick,
+ (unsigned int) clip_w, (unsigned int) clip_h, 0,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DPY WINDOW(mane), ExposureMask |
+ ButtonPressMask | ButtonMotionMask | ButtonReleaseMask);
+#else
+ mane.win = XCreateWindow(top_level, y_thick, x_thick,
+ clip_w, clip_h, 0, bdrmap, backmap);
+ XSelectInput(WINDOW(mane), ExposeRegion | ExposeCopy |
+ ButtonPressed | ButtonReleased |
+ LeftDownMotion | MiddleDownMotion | RightDownMotion);
+#endif
+ XMapWindow(DPY WINDOW(mane));
+ }
+ else
+#ifdef X10
+ if (clip_w != old_clip_w || clip_h != old_clip_h ||
+ x_thick != old_x_thick || y_thick != old_y_thick) {
+#endif
+ XMoveResizeWindow(DPY WINDOW(mane),
+ y_thick, x_thick, clip_w, clip_h);
+#ifdef X10
+ XSync(False);
+ }
+#endif
+
+ /* process scroll bars */
+ if (x_thick) {
+ if (x_bar) {
+ XMoveResizeWindow(DPY x_bar,
+ y_thick - 1, -1, clip_w, BAR_THICK - 1);
+ paint_x_bar();
+ }
+ else {
+#ifndef X10
+ x_bar = XCreateSimpleWindow(DISP, top_level, y_thick - 1, -1,
+ (unsigned int) clip_w, BAR_THICK - 1, 1,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DISP, x_bar,
+ ExposureMask | ButtonPressMask | Button2MotionMask);
+#else
+ x_bar = XCreateWindow(top_level,
+ y_thick - 1, -1, clip_w, BAR_THICK - 1, 1,
+ bdrmap, backmap);
+ XSelectInput(x_bar,
+ ExposeRegion | ButtonPressed | MiddleDownMotion);
+#endif
+ XMapWindow(DPY x_bar);
+ }
+ x_bgn = mane.base_x * clip_w / page_w;
+ x_end = (mane.base_x + clip_w) * clip_w / page_w;
+ }
+ else
+ if (x_bar) {
+ XDestroyWindow(DPY x_bar);
+ x_bar = NULL;
+ }
+
+ if (y_thick) {
+ if (y_bar) {
+ XMoveResizeWindow(DPY y_bar,
+ -1, x_thick - 1, BAR_THICK - 1, clip_h);
+ paint_y_bar();
+ }
+ else {
+#ifndef X10
+ y_bar = XCreateSimpleWindow(DISP, top_level, -1, x_thick - 1,
+ BAR_THICK - 1, (unsigned int) clip_h, 1,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DISP, y_bar,
+ ExposureMask | ButtonPressMask | Button2MotionMask);
+#else
+ y_bar = XCreateWindow(top_level,
+ -1, x_thick - 1, BAR_THICK - 1, clip_h, 1,
+ bdrmap, backmap);
+ XSelectInput(y_bar,
+ ExposeRegion | ButtonPressed | MiddleDownMotion);
+#endif
+ XMapWindow(DPY y_bar);
+ }
+ y_bgn = mane.base_y * clip_h / page_h;
+ y_end = (mane.base_y + clip_h) * clip_h / page_h;
+ }
+ else
+ if (y_bar) {
+ XDestroyWindow(DPY y_bar);
+ y_bar = NULL;
+ }
+}
+
+static void
+home(scrl)
+ Boolean scrl;
+{
+ int x = 0, y = 0;
+
+ if (page_w > clip_w) {
+ x = (page_w - clip_w) / 2;
+ if (x > home_x / mane.shrinkfactor)
+ x = home_x / mane.shrinkfactor;
+ }
+ if (page_h > clip_h) {
+ y = (page_h - clip_h) / 2;
+ if (y > home_y / mane.shrinkfactor)
+ y = home_y / mane.shrinkfactor;
+ }
+ if (scrl)
+ scrollmane(x, y);
+ else {
+ mane.base_x = x;
+ mane.base_y = y;
+ if (currwin.win == mane.win) {
+ currwin.base_x = x;
+ currwin.base_y = y;
+ }
+ if (x_bar) paint_x_bar();
+ if (y_bar) paint_y_bar();
+ }
+}
+
+#define get_xy()
+#define window_x 0
+#define window_y 0
+#define mane_base_x mane.base_x
+#define mane_base_y mane.base_y
+#endif /* TOOLKIT */
+
+static void
+compute_mag_pos(xp, yp)
+ int *xp, *yp;
+{
+ register int t;
+
+ t = mag_x + main_x - alt.width/2;
+#ifndef X10
+ if (t > WidthOfScreen(SCRN) - alt.width - 2*MAGBORD)
+ t = WidthOfScreen(SCRN) - alt.width - 2*MAGBORD;
+#else
+ if (t > (int) window_w - alt.width - 2*MAGBORD)
+ t = window_w - alt.width - 2*MAGBORD;
+#endif
+ if (t < 0) t = 0;
+ *xp = t;
+ t = mag_y + main_y - alt.height/2;
+#ifndef X10
+ if (t > HeightOfScreen(SCRN) - alt.height - 2*MAGBORD)
+ t = HeightOfScreen(SCRN) - alt.height - 2*MAGBORD;
+#else
+ if (t > (int) window_h - alt.height - 2*MAGBORD)
+ t = window_h - alt.height - 2*MAGBORD;
+#endif
+ if (t < 0) t = 0;
+ *yp = t;
+}
+
+#ifdef TOOLKIT
+ /*ARGSUSED*/
+static void
+handle_button(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xbutton))
+ Boolean *cont; /* unused */
+#else /* !TOOLKIT */
+static void
+handle_button(event)
+ XButtonEvent *event;
+#endif /* TOOLKIT */
+{
+ int x, y;
+#ifndef X10
+ int w = RESOURCE(mg_size[event->button - 1]);
+ XSetWindowAttributes attr;
+#else
+ int w = RESOURCE(mg_size[2 - (event->detail & ValueMask)]);
+#endif
+
+ if (alt.win != (Window) 0 || mane.shrinkfactor == 1 || w <= 0)
+ XBell(DISP, 20);
+ else {
+ mag_x = event->x;
+ mag_y = event->y;
+ alt.width = alt.height = w;
+#ifndef X10
+ main_x = event->x_root - mag_x;
+ main_y = event->y_root - mag_y;
+#endif
+ compute_mag_pos(&x, &y);
+ alt.base_x = (event->x + mane_base_x) * mane.shrinkfactor -
+ alt.width/2;
+ alt.base_y = (event->y + mane_base_y) * mane.shrinkfactor -
+ alt.height/2;
+#ifndef X10
+ attr.save_under = True;
+ attr.border_pixel = RESOURCE(brdr_Pixel);
+ attr.background_pixel = RESOURCE(back_Pixel);
+ attr.override_redirect = True;
+ alt.win = XCreateWindow(DISP, RootWindowOfScreen(SCRN),
+ x, y, alt.width, alt.height, MAGBORD,
+ 0, /* depth from parent */
+ InputOutput, CopyFromParent,
+ CWSaveUnder | CWBorderPixel | CWBackPixel |
+ CWOverrideRedirect, &attr);
+ XSelectInput(DISP, WINDOW(alt), ExposureMask);
+#else
+ alt.win = XCreateWindow(WINDOW(mane),
+ x, y, alt.width, alt.height, MAGBORD,
+ bdrmap, backmap);
+ XSelectInput(WINDOW(alt), ExposeRegion);
+#endif
+ XMapWindow(DPY WINDOW(alt));
+ alt_stat = 1; /* waiting for exposure */
+ }
+}
+
+#ifdef TOOLKIT
+#undef event
+
+ /*ARGSUSED*/
+static void
+handle_motion(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xmotion))
+ Boolean *cont; /* unused */
+{
+ new_mag_x = event->x;
+ main_x = event->x_root - new_mag_x;
+ new_mag_y = event->y;
+ main_y = event->y_root - new_mag_y;
+ mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y);
+}
+
+#undef event
+#endif /* TOOLKIT */
+
+static void
+movemag(x, y)
+ int x, y;
+{
+ int xx, yy;
+
+ mag_x = x;
+ mag_y = y;
+ if (mag_x == new_mag_x && mag_y == new_mag_y) mag_moved = False;
+ compute_mag_pos(&xx, &yy);
+ XMoveWindow(DPY WINDOW(alt), xx, yy);
+ scrollwindow(&alt, (x + mane_base_x) * mane.shrinkfactor - alt.width/2,
+ (y + mane_base_y) * mane.shrinkfactor - alt.height/2);
+}
+
+#ifdef TOOLKIT
+ /*ARGSUSED*/
+static void
+handle_release(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xbutton))
+ Boolean *cont; /* unused */
+#else /* !TOOLKIT */
+static void
+handle_release()
+#endif /* TOOLKIT */
+{
+ if (alt.win)
+ if (alt_stat) alt_stat = -1; /* destroy upon expose */
+ else {
+ XDestroyWindow(DPY WINDOW(alt));
+ if (currwin.win == alt.win) alt_canit = True;
+ alt.win = (Window) 0;
+ mag_moved = False;
+ can_exposures(&alt);
+ }
+}
+
+#ifdef TOOLKIT
+#undef event
+
+ /*ARGSUSED*/
+static void
+handle_exp(widget, closure, ev, cont)
+ Widget widget;
+ XtPointer closure;
+ register XEvent *ev;
+#define event (&(ev->xexpose))
+ Boolean *cont; /* unused */
+{
+ struct WindowRec *windowrec = (struct WindowRec *) closure;
+
+ if (windowrec == &alt)
+ if (alt_stat < 0) { /* destroy upon exposure */
+ alt_stat = 0;
+ handle_release(widget, (caddr_t) NULL, ev, (Boolean *) NULL);
+ return;
+ }
+ else
+ alt_stat = 0;
+ expose(windowrec, event->x, event->y, event->width, event->height);
+}
+
+#undef event
+#endif /* TOOLKIT */
+
+/* |||
+ * Currently the event handler does not coordinate XCopyArea requests
+ * with GraphicsExpose events. This can lead to problems if the window
+ * is partially obscured and one, for example, drags a scrollbar.
+ */
+
+#ifndef X10
+#define XKEY(ev) (ev).xkey
+#ifndef TOOLKIT
+#define XANY(ev) (ev).xany
+#define XCONFIG(ev) (ev).xconfigure
+#define XEXPOSE(ev) (ev).xexpose
+#define XMOTION(ev) (ev).xmotion
+#define XBUTTON(ev) (ev).xbutton
+#define ISEXPOSE(ev) ((ev).type == Expose)
+#endif /* TOOLKIT */
+#else /* X10 */
+#define XANY(ev) (ev)
+#define XCONFIG(ev) (*((XExposeEvent *) &(ev)))
+#define XEXPOSE(ev) (*((XExposeEvent *) &(ev)))
+#define XMOTION(ev) (*((XMouseMovedEvent *) &(ev)))
+#define XBUTTON(ev) (*((XButtonEvent *) &(ev)))
+#define XKEY(ev) (*((XKeyEvent *) &(ev)))
+#define ConfigureNotify ExposeWindow
+#define Expose ExposeRegion
+#define ISEXPOSE(ev) ((ev).type == ExposeWindow || (ev).type == ExposeRegion)
+#define MotionNotify MouseMoved
+#define ButtonPress ButtonPressed
+#define ButtonRelease ButtonReleased
+#define KeyPress KeyPressed
+#endif /* X10 */
+
+static void
+keystroke(ch, number0, arg0, eventp)
+ char ch;
+ int number0;
+ Boolean arg0;
+ XEvent *eventp;
+{
+ int next_page;
+#ifdef TOOLKIT
+ Window ww;
+#endif
+
+ next_page = current_page;
+ switch (ch) {
+ case 'q':
+ case '\003': /* control-C */
+ case '\004': /* control-D */
+#ifdef VMS
+ case '\032': /* control-Z */
+#endif
+ exit(0);
+ case 'n':
+ case 'f':
+ case ' ':
+ case '\r':
+ case '\n':
+ /* scroll forward; i.e. go to relative page */
+ next_page = current_page + (arg0 ? number0 : 1);
+ break;
+ case 'p':
+ case 'b':
+ case '\b':
+ case '\177': /* Del */
+ /* scroll backward */
+ next_page = current_page - (arg0 ? number0 : 1);
+ break;
+ case 'g':
+ /* go to absolute page */
+ next_page = (arg0 ? number0 - pageno_correct :
+ total_pages - 1);
+ break;
+ case 'P': /* declare current page */
+ pageno_correct = arg0 * number0 - current_page;
+ return;
+ case 'k': /* toggle keep-position flag */
+ RESOURCE(keep_flag) = (arg0 ? number0 : !RESOURCE(keep_flag));
+ return;
+ case '\f':
+ /* redisplay current page */
+ break;
+ case '^':
+ home(True);
+ return;
+#ifdef TOOLKIT
+ case 'l':
+ if (!x_bar) goto bad;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (-2 * (int) clip_w / 3));
+ return;
+ case 'r':
+ if (!x_bar) goto bad;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (2 * (int) clip_w / 3));
+ return;
+ case 'u':
+ if (!y_bar) goto bad;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (-2 * (int) clip_h / 3));
+ return;
+ case 'd':
+ if (!y_bar) goto bad;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (2 * (int) clip_h / 3));
+ return;
+ case 'c':
+ center(eventp->xkey.x, eventp->xkey.y);
+ return;
+ case 'M':
+ XTranslateCoordinates(DISP, eventp->xkey.window,
+ WINDOW(mane), eventp->xkey.x, eventp->xkey.y,
+ &home_x, &home_y, &ww); /* throw away last argument */
+ home_x *= mane.shrinkfactor;
+ home_y *= mane.shrinkfactor;
+ return;
+#ifdef BUTTONS
+ case 'x':
+ if (arg0 && resource.expert == (number0 != 0)) return;
+ if (resource.expert) { /* create buttons */
+ XtResizeWidget(vport_widget, window_w -= XTRA_WID, window_h,
+ 0);
+ create_buttons((XtArgVal) window_h);
+ resource.expert = False;
+ }
+ else { /* destroy buttons */
+ XtResizeWidget(vport_widget, window_w += XTRA_WID, window_h,
+ 0);
+ XtDestroyWidget(right_widget);
+ XtDestroyWidget(line_widget);
+ resource.expert = True;
+ }
+ return;
+#endif /* BUTTONS */
+#else /* !TOOLKIT */
+ case 'l':
+ if (mane.base_x <= 0) goto bad;
+ scrollmane(mane.base_x - 2 * clip_w / 3, mane.base_y);
+ return;
+ case 'r':
+ if (mane.base_x >= page_w - clip_w) goto bad;
+ scrollmane(mane.base_x + 2 * clip_w / 3, mane.base_y);
+ return;
+ case 'u':
+ if (mane.base_y <= 0) goto bad;
+ scrollmane(mane.base_x, mane.base_y - 2 * clip_h / 3);
+ return;
+ case 'd':
+ if (mane.base_y >= page_h - clip_h) goto bad;
+ scrollmane(mane.base_x, mane.base_y + 2 * clip_h / 3);
+ return;
+ case 'c': /* unchecked scrollmane() */
+ scrollwindow(&mane, mane.base_x + XKEY(*eventp).x - clip_w/2,
+ mane.base_y + XKEY(*eventp).y - clip_h/2);
+ if (x_bar) paint_x_bar();
+ if (y_bar) paint_y_bar();
+#ifndef X10
+ XWarpPointer(DISP, None, None, 0, 0, 0, 0,
+ clip_w/2 - XKEY(*eventp).x, clip_h/2 - XKEY(*eventp).y);
+#else
+ XWarpMouse(WINDOW(mane), clip_w/2, clip_h/2, GXcopy);
+#endif
+ return;
+ case 'M':
+ home_x = (XKEY(*eventp).x - (y_bar ? BAR_THICK : 0)
+ + mane.base_x) * mane.shrinkfactor;
+ home_y = (XKEY(*eventp).y - (x_bar ? BAR_THICK : 0)
+ + mane.base_y) * mane.shrinkfactor;
+ return;
+#endif /* TOOLKIT */
+
+#ifndef X10
+ case '\020': /* Control P */
+ Printf("Unit = %d, bitord = %d, byteord = %d\n",
+ BitmapUnit(DISP), BitmapBitOrder(DISP),
+ ImageByteOrder(DISP));
+ return;
+#endif
+ case 's':
+ if (!arg0) {
+ int temp;
+ number0 = ROUNDUP(unshrunk_page_w, window_w - 2);
+ temp = ROUNDUP(unshrunk_page_h, window_h - 2);
+ if (number0 < temp) number0 = temp;
+ }
+ if (number0 <= 0) goto bad;
+ if (number0 == mane.shrinkfactor) return;
+ mane.shrinkfactor = number0;
+ init_page();
+ if (number0 != 1 && number0 != bak_shrink) {
+ bak_shrink = number0;
+#ifdef GREY
+ if (use_grey) init_pix(False);
+#endif
+ reset_fonts();
+ }
+#ifdef TOOLKIT
+ draw_args[0].value = (XtArgVal) page_w;
+ draw_args[1].value = (XtArgVal) page_h;
+ XtSetValues(draw_widget, draw_args, (Cardinal) 2);
+ get_geom();
+ home(False);
+#else /* TOOLKIT */
+ reconfig();
+ home(False);
+#endif /* TOOLKIT */
+ break;
+ case 'S':
+ if (!arg0) goto bad;
+ if (number0 < 0) goto bad;
+ if (number0 == density) return;
+ density = number0;
+ reset_fonts();
+ if (mane.shrinkfactor == 1) return;
+ break;
+#ifdef GREY
+ case 'G':
+ use_grey = (arg0 ? number0 : !use_grey);
+ if (use_grey) init_pix(False);
+ reset_fonts();
+ break;
+#endif
+ case 'R':
+ /* reread DVI file */
+ --dvi_time; /* then it will notice a change */
+ break;
+ default:
+ goto bad;
+ }
+ if (0 <= next_page && next_page < total_pages) {
+ if (current_page != next_page) {
+ current_page = next_page;
+ hush_spec_now = hush_spec;
+ if (!RESOURCE(keep_flag)) home(False);
+ }
+ canit = True;
+ Flush();
+ return; /* don't use longjmp here: it might be called from
+ * within the toolkit, and we don't want to longjmp out
+ * of Xt routines. */
+ }
+ bad: XBell(DISP, 10);
+}
+
+
+#ifndef X10
+#define TRSIZE 100
+#endif /* X10 */
+
+static void
+read_events(wait)
+ Boolean wait;
+{
+ char ch;
+ Boolean arg0;
+ int number0;
+ XEvent event;
+#ifndef X10
+ char trbuf[TRSIZE];
+#endif
+ char *string;
+ int nbytes;
+
+ alt_canit = False;
+ for (;;) {
+ ch = '\0';
+ event_counter = event_freq;
+ /*
+ * The above line clears the flag indicating that an event is
+ * pending. So if an event comes in right now, the flag will be
+ * set again needlessly, but we just end up making an extra call.
+ * Also, watch out, if we destroy the magnifying glass while
+ * writing it.
+ */
+ if (!XtPending() && (!wait || canit || mane.min_x < MAXDIM ||
+ alt.min_x < MAXDIM || mag_moved))
+ if (!wait && (canit || alt_canit)) longjmp(canit_env, 1);
+ else return;
+#ifdef TOOLKIT
+ XtNextEvent(&event);
+ if (resized) get_geom();
+ if (event.xany.window == WINDOW(alt) &&
+ event.type == Expose) {
+ handle_exp((Widget) NULL, (XtPointer) &alt, &event,
+ (Boolean *) NULL);
+ continue;
+ }
+ if (event.type != KeyPress) {
+ XtDispatchEvent(&event);
+ continue;
+ }
+ string = trbuf;
+ nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL, NULL);
+ if (nbytes > 1) ch = '?';
+ if (nbytes != 0) ch = *string;
+#else /* !TOOLKIT */
+
+ XNextEvent(DPY &event);
+ if (XANY(event).window == WINDOW(mane) ||
+ XANY(event).window == WINDOW(alt)) {
+
+ struct WindowRec *wr = &mane;
+
+ if (XANY(event).window == WINDOW(alt)) {
+ wr = &alt;
+ /* check in case we already destroyed the window */
+ if (alt_stat < 0) { /* destroy upon exposure */
+ alt_stat = 0;
+ handle_release();
+ continue;
+ }
+ else
+ alt_stat = 0;
+ }
+ switch (event.type) {
+#ifndef X10
+ case GraphicsExpose:
+#else
+ case ExposeWindow:
+#endif
+ case Expose:
+#ifdef X10
+ if (XEXPOSE(event).detail & ExposeCopy)
+ ClearArea(event.window,
+ XEXPOSE(event).x, XEXPOSE(event).y,
+ XEXPOSE(event).width, XEXPOSE(event).height);
+#endif
+ expose(wr, XEXPOSE(event).x, XEXPOSE(event).y,
+ XEXPOSE(event).width, XEXPOSE(event).height);
+#ifdef X10
+ case ExposeCopy: /* throw away junk event */
+#endif
+ break;
+
+ case MotionNotify:
+#ifdef X10
+ case LeftDownMotion:
+ case MiddleDownMotion:
+ case RightDownMotion:
+#endif
+ new_mag_x = XMOTION(event).x;
+ new_mag_y = XMOTION(event).y;
+ mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y);
+ break;
+
+ case ButtonPress:
+ handle_button(&XBUTTON(event));
+ break;
+
+ case ButtonRelease:
+ handle_release();
+ break;
+ } /* end switch */
+ } /* end if window == {mane,alt}.win */
+
+ else if (XANY(event).window == x_bar) {
+ if (ISEXPOSE(event))
+ DarkenArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID);
+ else if (event.type == MotionNotify)
+ scrollmane(XMOTION(event).x * page_w / clip_w,
+ mane.base_y);
+#ifndef X10
+ else switch (XBUTTON(event).button)
+#else
+ else if (event.type == ButtonPress)
+ switch (3 - (XBUTTON(event).detail & ValueMask))
+#endif
+ {
+ case 1:
+ scrollmane(mane.base_x + XBUTTON(event).x, mane.base_y);
+ break;
+ case 2:
+ scrollmane(XBUTTON(event).x * page_w / clip_w,
+ mane.base_y);
+ break;
+ case 3:
+ scrollmane(mane.base_x - XBUTTON(event).x, mane.base_y);
+ }
+ }
+
+ else if (XANY(event).window == y_bar) {
+ if (ISEXPOSE(event))
+ DarkenArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn);
+ else if (event.type == MotionNotify)
+ scrollmane(mane.base_x,
+ XMOTION(event).y * page_h / clip_h);
+#ifndef X10
+ else switch (XBUTTON(event).button)
+#else
+ else if (event.type == ButtonPress)
+ switch (3 - (XBUTTON(event).detail & ValueMask))
+#endif
+ {
+ case 1:
+ scrollmane(mane.base_x, mane.base_y + XBUTTON(event).y);
+ break;
+ case 2:
+ scrollmane(mane.base_x,
+ XBUTTON(event).y * page_h / clip_h);
+ break;
+ case 3:
+ scrollmane(mane.base_x, mane.base_y - XBUTTON(event).y);
+ }
+ }
+
+ else if (XANY(event).window == top_level)
+ switch (event.type) {
+ case ConfigureNotify:
+ if (XANY(event).window == top_level &&
+ (XCONFIG(event).width != window_w ||
+ XCONFIG(event).height != window_h)) {
+ register Window old_mane_win = mane.win;
+
+ window_w = XCONFIG(event).width;
+ window_h = XCONFIG(event).height;
+ reconfig();
+ if (old_mane_win == NULL) home(False);
+ }
+ break;
+
+#ifndef X10
+ case MapNotify: /* if running w/o WM */
+ if (mane.win == NULL) {
+ reconfig();
+ home(False);
+ }
+ break;
+#endif
+
+ case KeyPress:
+#ifndef X10
+ string = trbuf;
+ nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL,
+ NULL);
+#else
+ string = XLookupMapping(&event, &nbytes);
+#endif
+ if (nbytes > 1) ch = '?';
+ if (nbytes != 0) ch = *string;
+ break;
+ }
+#endif /* TOOLKIT */
+ if (ch == '\0') continue;
+ if (ch >= '0' && ch <= '9') {
+ has_arg = True;
+ number = number * 10 + sign * (ch - '0');
+ continue;
+ }
+ else if (ch == '-') {
+ has_arg = True;
+ sign = -1;
+ number = 0;
+ continue;
+ }
+ number0 = number;
+ number = 0;
+ sign = 1;
+ arg0 = has_arg;
+ has_arg = False;
+ keystroke(ch, number0, arg0, &event);
+ }
+}
+
+static void
+redraw(windowrec)
+ struct WindowRec *windowrec;
+{
+ char *errtext;
+#ifdef X10
+ static FontInfo *font = 0;
+#endif
+
+ currwin = *windowrec;
+ min_x = currwin.min_x + currwin.base_x;
+ min_y = currwin.min_y + currwin.base_y;
+ max_x = currwin.max_x + currwin.base_x;
+ max_y = currwin.max_y + currwin.base_y;
+ can_exposures(windowrec);
+
+ if (debug & DBG_EVENT)
+ Printf("Redraw %d x %d at (%d, %d) (base=%d,%d)\n", max_x - min_x,
+ max_y - min_y, min_x, min_y, currwin.base_x, currwin.base_y);
+ SetCursor(redraw_cursor);
+ Flush();
+ if (errtext = (char *) setjmp(dvi_env)) {
+ ClearPage(mane);
+#ifndef X10
+ get_xy();
+ XDrawString(DISP, WINDOW(mane), foreGC,
+ 5 - window_x, 5 + X11HEIGHT - window_y,
+ errtext, strlen(errtext));
+#else
+ if (!font) font = XOpenFont(X10FONT);
+ XTextMask(WINDOW(mane), 5, 5 + X10HEIGHT, errtext, strlen(errtext),
+ font->id, foreGC);
+#endif
+ if (dvi_file) {
+ Fclose(dvi_file);
+ dvi_file = NULL;
+ }
+ }
+ else {
+ draw_page();
+ hush_spec_now = True;
+ }
+}
+
+void
+redraw_page()
+{
+ if (debug & DBG_EVENT) Fputs("Redraw page: ", stdout);
+ get_xy();
+ ClearPage(mane);
+ mane.min_x = -window_x;
+ mane.max_x = -window_x + clip_w;
+ mane.min_y = -window_y;
+ mane.max_y = -window_y + clip_h;
+ redraw(&mane);
+}
+
+/*
+ * Interrupt system for receiving events. The program sets a flag
+ * whenever an event comes in, so that at the proper time (i.e., when
+ * reading a new dvi item), we can check incoming events to see if we
+ * still want to go on printing this page. This way, one can stop
+ * displaying a page if it is about to be erased anyway. We try to read
+ * as many events as possible before doing anything and base the next
+ * action on all events read.
+ * Note that the Xlib and Xt routines are not reentrant, so the most we
+ * can do is set a flag in the interrupt routine and check it later.
+ * Also, sometimes the interrupts are not generated (some systems only
+ * guarantee that SIGIO is generated for terminal files, and on the system
+ * I use, the interrupts are not generated if I use "(xdvi foo &)" instead
+ * of "xdvi foo"). Therefore, there is also a mechanism to check the
+ * event queue every 70 drawing operations or so. This mechanism is
+ * disabled if it turns out that the interrupts do work.
+ * For a fuller discussion of some of the above, see xlife in
+ * comp.sources.x.
+ */
+
+static void
+can_exposures(windowrec)
+ struct WindowRec *windowrec;
+{
+ windowrec->min_x = windowrec->min_y = MAXDIM;
+ windowrec->max_x = windowrec->max_y = 0;
+}
+
+static void
+handle_intr() {
+ event_counter = 1;
+ event_freq = -1; /* forget Plan B */
+}
+
+#ifdef HAS_SIGIO
+static void
+enable_intr() {
+ int socket = ConnectionNumber(DISP);
+ if (!isatty(0)) {
+ Puts("trying...");
+ if (dup2(socket, 0) == -1) perror(prog);
+ socket = 0;
+ }
+ (void) signal(SIGIO, handle_intr);
+ (void) fcntl(socket, F_SETOWN, getpid());
+ (void) fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | FASYNC);
+}
+#endif /* HAS_SIGIO */
+
+static void
+do_pages()
+{
+ if (debug & DBG_BATCH) {
+#ifdef TOOLKIT
+ while (mane.min_x == MAXDIM) read_events(True);
+#else /* !TOOLKIT */
+ while (mane.min_x == MAXDIM)
+ if (setjmp(canit_env)) break;
+ else read_events(True);
+#endif /* TOOLKIT */
+ for (current_page = 0; current_page < total_pages; ++current_page)
+ redraw_page();
+ }
+ else { /* normal operation */
+#ifdef HAS_SIGIO
+ enable_intr();
+#endif
+#ifdef __convex__
+ /* convex C turns off optimization for the entire function
+ if setjmp return value is discarded.*/
+ if (setjmp(canit_env)) /*optimize me*/;
+#else
+ (void) setjmp(canit_env);
+#endif
+ for (;;) {
+ if (mane.win) SetCursor(ready_cursor);
+ read_events(True);
+ if (canit) {
+ canit = False;
+ can_exposures(&mane);
+ can_exposures(&alt);
+ redraw_page();
+ }
+ else if (mag_moved) {
+ if (alt.win == (Window) 0) mag_moved = False;
+ else if (abs(new_mag_x - mag_x) >
+ 2 * abs(new_mag_y - mag_y))
+ movemag(new_mag_x, mag_y);
+ else if (abs(new_mag_y - mag_y) >
+ 2 * abs(new_mag_x - mag_x))
+ movemag(mag_x, new_mag_y);
+ else movemag(new_mag_x, new_mag_y);
+ }
+ else if (alt.min_x < MAXDIM) redraw(&alt);
+ else if (mane.min_x < MAXDIM) redraw(&mane);
+ Flush();
+ }
+ }
+}
+
+static NORETURN void
+usage() {
+#ifndef X10
+#ifndef VMS
+#ifdef BUTTONS
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
+ [-expert] [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] \
+[-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host:display>] [-copy] [-thorough] dvi_file\n\n\n\
+ Adapted to DV/X using DJGPP by Eric Ho\n\
+ 9041477@SSCVAX.MCMASTER.CA\n\n",
+ stderr);
+#else /* !BUTTONS */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] [-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] [-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host:display>] [-copy] [-thorough] dvi_file\n\n\n\
+ Adapted to DV/X using DJGPP by Eric Ho\n\
+ 9041477@SSCVAX.MCMASTER.CA\n\n",
+ stderr);
+#endif /* BUTTONS */
+#else /* VMS */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-density <%>] [-p <pixels>] [-l] [-rv]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\
+\n", stderr);
+ Fputs("\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] \
+[-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host::display>] [-copy] [-thorough] dvi_file\n",
+ stderr);
+#endif /* VMS */
+#else /* X10 */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry> | =<geometry>]\n\
+ [-display <host:display> | <host:display>] dvi_file\n", stderr);
+#endif /* X10 */
+ exit(1);
+}
+
+static int
+atopix(arg)
+ _Xconst char *arg;
+{
+ int len = strlen(arg);
+
+ return (len > 2 && arg[len - 2] == 'c' && arg[len - 1] == 'm' ?
+ 1.0 / 2.54 : 1.0) * atof(arg) * pixels_per_inch + 0.5;
+}
+
+/**
+ ** Main programs start here.
+ **/
+
+#ifdef TOOLKIT
+
+static XrmOptionDescRec options[] = {
+{"-d", ".debugLevel", XrmoptionSepArg, (caddr_t) NULL},
+{"-s", ".shrinkFactor", XrmoptionSepArg, (caddr_t) NULL},
+#ifndef VMS
+{"-S", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL},
+#endif
+{"-density", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL},
+#ifdef GREY
+{"-gamma", ".gamma", XrmoptionSepArg, (caddr_t) NULL},
+#endif
+{"-p", ".pixelsPerInch", XrmoptionSepArg, (caddr_t) NULL},
+{"-margins", ".Margin", XrmoptionSepArg, (caddr_t) NULL},
+{"-sidemargin", ".sideMargin", XrmoptionSepArg, (caddr_t) NULL},
+{"-topmargin", ".topMargin", XrmoptionSepArg, (caddr_t) NULL},
+{"-offsets", ".Offset", XrmoptionSepArg, (caddr_t) NULL},
+{"-xoffset", ".xOffset", XrmoptionSepArg, (caddr_t) NULL},
+{"-yoffset", ".yOffset", XrmoptionSepArg, (caddr_t) NULL},
+{"-paper", ".paper", XrmoptionSepArg, (caddr_t) NULL},
+{"-altfont", ".altFont", XrmoptionSepArg, (caddr_t) NULL},
+{"-l", ".listFonts", XrmoptionNoArg, (caddr_t) "on"},
+{"+l", ".listFonts", XrmoptionNoArg, (caddr_t) "off"},
+{"-hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "on"},
+{"+hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "off"},
+{"-hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "on"},
+{"+hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "off"},
+{"-hush", ".Hush", XrmoptionNoArg, (caddr_t) "on"},
+{"+hush", ".Hush", XrmoptionNoArg, (caddr_t) "off"},
+{"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
+{"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
+{"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL},
+{"-background", ".background", XrmoptionSepArg, (caddr_t) NULL},
+{"-hl", ".highlight", XrmoptionSepArg, (caddr_t) NULL},
+{"-cr", ".cursorColor", XrmoptionSepArg, (caddr_t) NULL},
+{"-icongeometry",".iconGeometry",XrmoptionSepArg, (caddr_t) NULL},
+{"-keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "on"},
+{"+keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "off"},
+{"-copy", ".copy", XrmoptionNoArg, (caddr_t) "on"},
+{"+copy", ".copy", XrmoptionNoArg, (caddr_t) "off"},
+{"-thorough", ".thorough", XrmoptionNoArg, (caddr_t) "on"},
+{"+thorough", ".thorough", XrmoptionNoArg, (caddr_t) "off"},
+{"-version", ".version", XrmoptionNoArg, (caddr_t) "on"},
+{"+version", ".version", XrmoptionNoArg, (caddr_t) "off"},
+#ifdef BUTTONS
+{"-expert", ".expert", XrmoptionNoArg, (caddr_t) "on"},
+{"+expert", ".expert", XrmoptionNoArg, (caddr_t) "off"},
+#endif
+{"-mgs", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs1", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs2", ".magnifierSize2",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs3", ".magnifierSize3",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs4", ".magnifierSize4",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs5", ".magnifierSize5",XrmoptionSepArg, (caddr_t) NULL},
+#ifdef GREY
+{"-nogrey", ".grey", XrmoptionNoArg, (caddr_t) "off"},
+{"+nogrey", ".grey", XrmoptionNoArg, (caddr_t) "on"},
+#endif
+};
+
+#define offset(field) XtOffsetOf(struct _resource, field)
+
+static int basedpi = BDPI; /* default value for -p option */
+
+static XtResource application_resources[] = {
+{"debugLevel", "DebugLevel", XtRString, sizeof(char *),
+ offset(debug_arg), XtRString, (caddr_t) NULL},
+{"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int),
+ offset(_shrink_factor), XtRString, "3"},
+{"densityPercent", "DensityPercent", XtRInt, sizeof(int),
+ offset(density), XtRString, "40"},
+#ifdef GREY
+{"gamma", "Gamma", XtRFloat, sizeof(float),
+ offset(gamma), XtRString, "1"},
+#endif
+{"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int),
+ offset(pixels_per_inch), XtRInt, (caddr_t) &basedpi},
+{"sideMargin", "Margin", XtRString, sizeof(char *),
+ offset(sidemargin), XtRString, (caddr_t) NULL},
+{"topMargin", "Margin", XtRString, sizeof(char *),
+ offset(topmargin), XtRString, (caddr_t) NULL},
+{"xOffset", "Offset", XtRString, sizeof(char *),
+ offset(xoffset), XtRString, (caddr_t) NULL},
+{"yOffset", "Offset", XtRString, sizeof(char *),
+ offset(yoffset), XtRString, (caddr_t) NULL},
+{"paper", "Paper", XtRString, sizeof(char *),
+ offset(paper), XtRString, (caddr_t) DEFAULT_PAPER},
+{"altFont", "AltFont", XtRString, sizeof(char *),
+ offset(alt_font), XtRString, (caddr_t) ALTFONT},
+{"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean),
+ offset(list_fonts), XtRString, "false"},
+{"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
+ offset(reverse), XtRString, "false"},
+{"hushSpecials", "Hush", XtRBoolean, sizeof(Boolean),
+ offset(hush_spec), XtRString, "false"},
+{"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean),
+ offset(hush_chars), XtRString, "false"},
+{"foreground", "Foreground", XtRPixel, sizeof(Pixel),
+ offset(fore_Pixel), XtRPixel, (caddr_t) &resource.fore_Pixel},
+{"foreground", "Foreground", XtRString, sizeof(char *),
+ offset(fore_color), XtRString, (caddr_t) NULL},
+{"background", "Background", XtRPixel, sizeof(Pixel),
+ offset(back_Pixel), XtRPixel, (caddr_t) &resource.back_Pixel},
+{"background", "Background", XtRString, sizeof(char *),
+ offset(back_color), XtRString, (caddr_t) NULL},
+{"borderColor", "BorderColor", XtRPixel, sizeof(Pixel),
+ offset(brdr_Pixel), XtRPixel, (caddr_t) &resource.brdr_Pixel},
+{"borderColor", "BorderColor", XtRString, sizeof(char *),
+ offset(brdr_color), XtRString, (caddr_t) NULL},
+{"highlight", "Highlight", XtRPixel, sizeof(Pixel),
+ offset(hl_Pixel), XtRPixel, (caddr_t) &resource.hl_Pixel},
+{"highlight", "Highlight", XtRString, sizeof(char *),
+ offset(high_color), XtRString, (caddr_t) NULL},
+{"cursorColor", "CursorColor", XtRPixel, sizeof(Pixel),
+ offset(cr_Pixel), XtRPixel, (caddr_t) &resource.cr_Pixel},
+{"cursorColor", "CursorColor", XtRString, sizeof(char *),
+ offset(curs_color), XtRString, (caddr_t) NULL},
+{"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
+ offset(icon_geometry), XtRString, (caddr_t) NULL},
+{"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean),
+ offset(keep_flag), XtRString, "false"},
+{"copy", "Copy", XtRString, sizeof(char *),
+ offset(copy_arg), XtRString, (caddr_t) NULL},
+{"copy", "Copy", XtRBoolean, sizeof(Boolean),
+ offset(copy), XtRString, "false"},
+{"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
+ offset(thorough), XtRString, "false"},
+{"version", "Version", XtRBoolean, sizeof(Boolean),
+ offset(version_flag), XtRString, "false"},
+#ifdef BUTTONS
+{"expert", "Expert", XtRBoolean, sizeof(Boolean),
+ offset(expert), XtRString, "false"},
+#endif
+{"magnifierSize1", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[0]), XtRString, "200"},
+{"magnifierSize2", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[1]), XtRString, "350"},
+{"magnifierSize3", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[2]), XtRString, "600"},
+{"magnifierSize4", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[3]), XtRString, "900"},
+{"magnifierSize5", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[4]), XtRString, "1200"},
+#ifdef GREY
+{"grey", "Grey", XtRBoolean, sizeof (Boolean),
+ offset(use_grey), XtRString, "true"},
+#endif
+};
+#undef offset
+
+static Arg temp_args1[] = {
+ {XtNiconX, (XtArgVal) 0},
+ {XtNiconY, (XtArgVal) 0},
+};
+
+static Arg temp_args2 = {XtNborderWidth, (XtArgVal) &bwidth};
+
+static Pixmap icon_pm;
+
+static Arg temp_args3[] = {
+ {XtNiconPixmap, (XtArgVal) &icon_pm},
+};
+
+static Arg temp_args4[] = {
+ {XtNtitle, (XtArgVal) 0},
+ {XtNinput, (XtArgVal) True},
+};
+
+static Arg set_wh_args[] = {
+ {XtNwidth, (XtArgVal) 0},
+ {XtNheight, (XtArgVal) 0},
+};
+#else /* !TOOLKIT */
+
+static char *display;
+static char *geometry;
+static char *margins;
+static char *offsets;
+static Boolean hush;
+
+#ifndef X10
+static Boolean iconic = False;
+
+static Pixel
+string_to_pixel(strp) /* adapted from the toolkit */
+ char **strp;
+{
+ char *str = *strp;
+ Status status;
+ XColor color, junk;
+
+ if (*str == '#') { /* an rgb definition */
+ status = XParseColor(DISP, DefaultColormapOfScreen(SCRN),
+ str, &color);
+ if (status != 0)
+ status = XAllocColor(DISP, DefaultColormapOfScreen(SCRN),
+ &color);
+ }
+ else /* a name */
+ status = XAllocNamedColor(DISP, DefaultColormapOfScreen(SCRN),
+ str, &color, &junk);
+ if (status == 0) {
+ Fprintf(stderr, "Cannot allocate colormap entry for \"%s\"\n", str);
+ *strp = NULL;
+ return (Pixel) 0;
+ }
+ return color.pixel;
+}
+#endif /* X10 */
+
+static struct option {
+ _Xconst char *name;
+ _Xconst char *resource;
+ enum {FalseArg, TrueArg, StickyArg, SepArg} argclass;
+ enum {BooleanArg, StringArg, NumberArg, FloatArg} argtype;
+ int classcount;
+ caddr_t address;
+} options[] = {
+ /* the display option MUST be first */
+{"-display", NULL, SepArg, StringArg, 1, (caddr_t) &display},
+{"-d", "debugLevel", SepArg, StringArg, 1, (caddr_t) &debug_arg},
+{"+", NULL, StickyArg, StringArg, 1,(caddr_t) &curr_page},
+{"-s", "shrinkFactor", SepArg, NumberArg, 1, (caddr_t) &shrink_factor},
+{"-S", NULL, SepArg, NumberArg, 2, (caddr_t) &density},
+{"-density", "densityPercent", SepArg, NumberArg, 1, (caddr_t) &density},
+#ifdef GREY
+{"-gamma", "gamma", SepArg, FloatArg, 1, (caddr_t) &gamma},
+#endif
+{"-p", "pixelsPerInch", SepArg, NumberArg, 1, (caddr_t) &pixels_per_inch},
+{"-margins", "Margin", SepArg, StringArg, 3, (caddr_t) &margins},
+{"-sidemargin", "sideMargin", SepArg, StringArg, 1, (caddr_t) &sidemargin},
+{"-topmargin", "topMargin", SepArg, StringArg, 1, (caddr_t) &topmargin},
+{"-offsets", "Offset", SepArg, StringArg, 3, (caddr_t) &offsets},
+{"-xoffset", "xOffset", SepArg, StringArg, 1, (caddr_t) &xoffset},
+{"-yoffset", "yOffset", SepArg, StringArg, 1, (caddr_t) &yoffset},
+{"-paper", "paper", SepArg, StringArg, 1, (caddr_t) &paper},
+{"-altfont", "altFont", SepArg, StringArg, 1, (caddr_t) &alt_font},
+{"-l", NULL, TrueArg, BooleanArg, 2, (caddr_t) &list_fonts},
+{"+l", "listFonts", FalseArg, BooleanArg, 1,(caddr_t) &list_fonts},
+{"-rv", NULL, TrueArg, BooleanArg, 2, (caddr_t) &reverse},
+{"+rv", "reverseVideo", FalseArg, BooleanArg, 1,(caddr_t) &reverse},
+{"-hush", NULL, TrueArg, BooleanArg, 6, (caddr_t) &hush},
+{"+hush", "Hush", FalseArg, BooleanArg, 5,(caddr_t) &hush},
+{"-hushspecials", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_spec},
+{"+hushspecials", "hushSpecials", FalseArg, BooleanArg, 1,(caddr_t) &hush_spec},
+{"-hushchars", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_chars},
+{"+hushchars", "hushLostChars", FalseArg, BooleanArg, 1,(caddr_t) &hush_chars},
+{"-bw", NULL, SepArg, NumberArg, 2, (caddr_t) &bwidth},
+{"-borderwidth", "borderWidth", SepArg, NumberArg, 1, (caddr_t) &bwidth},
+{"-fg", NULL, SepArg, StringArg, 2, (caddr_t) &fore_color},
+{"-foreground", "foreground", SepArg, StringArg, 1, (caddr_t) &fore_color},
+{"-bg", NULL, SepArg, StringArg, 2, (caddr_t) &back_color},
+{"-background", "background", SepArg, StringArg, 1, (caddr_t) &back_color},
+{"-bd", NULL, SepArg, StringArg, 2, (caddr_t) &brdr_color},
+{"-bordercolor","borderColor", SepArg, StringArg, 1, (caddr_t) &brdr_color},
+{"-hl", "highlight", SepArg, StringArg, 1, (caddr_t) &high_color},
+{"-cr", "cursorColor", SepArg, StringArg, 1, (caddr_t) &curs_color},
+#ifdef X10
+{"=", NULL, StickyArg, StringArg, 2,(caddr_t) &geometry},
+#endif
+{"-geometry", "geometry", SepArg, StringArg, 1, (caddr_t) &geometry},
+#ifndef X10
+{"-icongeometry","iconGeometry",StickyArg, StringArg, 1,(caddr_t) &icon_geometry},
+{"-iconic", NULL, TrueArg, BooleanArg, 2, (caddr_t) &iconic},
+{"+iconic", "iconic", FalseArg, BooleanArg, 1,(caddr_t) &iconic},
+{"-keep", NULL, TrueArg, BooleanArg, 2, (caddr_t) &keep_flag},
+{"+keep", "keepPosition", FalseArg, BooleanArg, 1,(caddr_t) &keep_flag},
+{"-copy", NULL, TrueArg, BooleanArg, 2, (caddr_t) &copy},
+{"+copy", "copy", FalseArg, BooleanArg, 1,(caddr_t) &copy},
+{"-thorough", NULL, TrueArg, BooleanArg, 2, (caddr_t) &thorough},
+{"+thorough", "thorough", FalseArg, BooleanArg, 1,(caddr_t) &thorough},
+{"-version", NULL, TrueArg, BooleanArg, 2, (caddr_t)&version_flag},
+{"+version", "version", FalseArg, BooleanArg, 1,(caddr_t)&version_flag},
+#endif /* X10 */
+{"-mgs", NULL, SepArg, NumberArg, 2, (caddr_t) &mg_size[0]},
+{"-mgs1", "magnifierSize1",SepArg, NumberArg, 1, (caddr_t) &mg_size[0]},
+{"-mgs2", "magnifierSize2",SepArg, NumberArg, 1, (caddr_t) &mg_size[1]},
+{"-mgs3", "magnifierSize3",SepArg, NumberArg, 1, (caddr_t) &mg_size[2]},
+#ifndef X10
+{"-mgs4", "magnifierSize4",SepArg, NumberArg, 1, (caddr_t) &mg_size[3]},
+{"-mgs5", "magnifierSize5",SepArg, NumberArg, 1, (caddr_t) &mg_size[4]},
+#endif
+#ifdef GREY
+{"-nogrey", NULL, FalseArg, BooleanArg, 2,(caddr_t) &use_grey},
+{"+nogrey", "grey", TrueArg, BooleanArg, 1, (caddr_t) &use_grey},
+#endif
+};
+
+/*
+ * Process the option table. This is not guaranteed for all possible
+ * option tables, but at least it works for this one.
+ */
+
+static void
+parse_options(argc, argv)
+ int argc;
+ char **argv;
+{
+ char **arg;
+ char **argvend = argv + argc;
+ char *optstring;
+ caddr_t addr;
+ struct option *opt, *lastopt, *candidate;
+ int len1, len2, matchlen;
+
+ /*
+ * Step 1. Process command line options.
+ */
+ for (arg = argv + 1; arg < argvend; ++arg) {
+ len1 = strlen(*arg);
+ candidate = NULL;
+ matchlen = 0;
+ for (opt = options; opt < options + XtNumber(options); ++opt) {
+ len2 = strlen(opt->name);
+ if (opt->argclass == StickyArg) {
+ if (matchlen <= len2 && !strncmp(*arg, opt->name, len2)) {
+ candidate = opt;
+ matchlen = len2;
+ }
+ }
+ else if (len1 <= len2 && matchlen <= len1 &&
+ !strncmp(*arg, opt->name, len1)) {
+ if (len1 == len2) {
+ candidate = opt;
+ break;
+ }
+ if (matchlen < len1) candidate = opt;
+ else if (candidate && candidate->argclass != StickyArg)
+ candidate = NULL;
+ matchlen = len1;
+ }
+ }
+ if (candidate == NULL) {
+#ifdef X10
+ if (**arg == '-') usage();
+ if (index(*arg, ':') != NULL) { /* display */
+ --arg;
+ candidate = options;
+ }
+ else if (dvi_name) usage();
+#else
+ if (**arg == '-' || dvi_name) usage();
+#endif
+ else {
+ dvi_name = *arg;
+ continue;
+ }
+ }
+ /* flag it for subsequent processing */
+ candidate->resource = (char *) candidate;
+ /* store the value */
+ addr = candidate->address;
+ switch (candidate->argclass) {
+ case FalseArg: *((Boolean *) addr) = False; continue;
+ case TrueArg: *((Boolean *) addr) = True; continue;
+ case StickyArg: optstring = *arg + strlen(candidate->name);
+ break;
+ case SepArg:
+ ++arg;
+ if (arg >= argvend) usage();
+ optstring = *arg;
+ break;
+ }
+ switch (candidate->argtype) {
+ case StringArg: *((char **) addr) = optstring; break;
+ case NumberArg: *((int *) addr) = atoi(optstring); break;
+ case FloatArg: *((float *) addr) = atof(optstring); break;
+ default: ;
+ }
+ }
+ /*
+ * Step 2. Propagate classes for command line arguments. Backwards.
+ */
+ for (opt = options + XtNumber(options) - 1; opt >= options; --opt)
+ if (opt->resource == (char *) opt) {
+ addr = opt->address;
+ lastopt = opt + opt->classcount;
+ for (candidate = opt; candidate < lastopt; ++candidate) {
+ if (candidate->resource != NULL) {
+ switch (opt->argtype) {
+ case BooleanArg:
+ *((Boolean *) candidate->address) =
+ *((Boolean *) addr);
+ break;
+ case StringArg:
+ *((char **) candidate->address) =
+ *((char **) addr);
+ break;
+ case NumberArg:
+ *((int *) candidate->address) = *((int *) addr);
+ break;
+ case FloatArg:
+ *((float *) candidate->address) =
+ *((float *) addr);
+ break;
+ }
+ candidate->resource = NULL;
+ }
+ }
+ }
+
+#ifndef X10
+ if ((DISP = XOpenDisplay(display)) == NULL)
+ oops("Can't open display");
+ SCRN = DefaultScreenOfDisplay(DISP);
+#else
+ if (XOpenDisplay(display) == NULL)
+ oops("Can't open display");
+#endif
+ /*
+ * Step 3. Handle resources (including classes).
+ */
+ for (opt = options; opt < options + XtNumber(options); ++opt)
+ if (opt->resource &&
+#ifndef X10
+ ((optstring = XGetDefault(DISP, prog, opt->resource)) ||
+ (optstring = XGetDefault(DISP, "XDvi", opt->resource))))
+#else
+ (optstring = XGetDefault(DPY prog, opt->resource)))
+#endif
+ {
+ lastopt = opt + opt->classcount;
+ for (candidate = opt; candidate < lastopt; ++candidate)
+ if (candidate->resource != NULL) switch (opt->argtype) {
+ case BooleanArg:
+ *((Boolean *) candidate->address) =
+ (strcmp(optstring, "on") == 0);
+ break;
+ case StringArg:
+ *((char **) candidate->address) = optstring;
+ break;
+ case NumberArg:
+ *((int *) candidate->address) = atoi(optstring);
+ break;
+ case FloatArg:
+ *((float *) candidate->address) =
+ atof(optstring);
+ }
+ }
+}
+
+#endif /* TOOLKIT */
+
+static _Xconst char *paper_types[] = {
+ "us", "8.5x11",
+ "usr", "11x8.5",
+ "legal", "8.5x14",
+ "foolscap", "13.5x17.0", /* ??? */
+
+ /* ISO `A' formats, Portrait */
+ "a1", "59.4x84.0cm",
+ "a2", "42.0x59.4cm",
+ "a3", "29.7x42.0cm",
+ "a4", "21.0x29.7cm",
+ "a5", "14.85x21.0cm",
+ "a6", "10.5x14.85cm",
+ "a7", "7.42x10.5cm",
+
+ /* ISO `A' formats, Landscape */
+ "a1r", "84.0x59.4cm",
+ "a2r", "59.4x42.0cm",
+ "a3r", "42.0x29.7cm",
+ "a4r", "29.7x21.0cm",
+ "a5r", "21.0x14.85cm",
+ "a6r", "14.85x10.5cm",
+ "a7r", "10.5x7.42cm",
+
+ /* ISO `B' formats, Portrait */
+ "b1", "70.6x100.0cm",
+ "b2", "50.0x70.6cm",
+ "b3", "35.3x50.0cm",
+ "b4", "25.0x35.3cm",
+ "b5", "17.6x25.0cm",
+ "b6", "13.5x17.6cm",
+ "b7", "8.8x13.5cm",
+
+ /* ISO `B' formats, Landscape */
+ "b1r", "100.0x70.6cm",
+ "b2r", "70.6x50.0cm",
+ "b3r", "50.0x35.3cm",
+ "b4r", "35.3x25.0cm",
+ "b5r", "25.0x17.6cm",
+ "b6r", "17.6x13.5cm",
+ "b7r", "13.5x8.8cm",
+
+ /* ISO `C' formats, Portrait */
+ "c1", "64.8x91.6cm",
+ "c2", "45.8x64.8cm",
+ "c3", "32.4x45.8cm",
+ "c4", "22.9x32.4cm",
+ "c5", "16.2x22.9cm",
+ "c6", "11.46x16.2cm",
+ "c7", "8.1x11.46cm",
+
+ /* ISO `C' formats, Landscape */
+ "c1r", "91.6x64.8cm",
+ "c2r", "64.8x45.8cm",
+ "c3r", "45.8x32.4cm",
+ "c4r", "32.4x22.9cm",
+ "c5r", "22.9x16.2cm",
+ "c6r", "16.2x11.46cm",
+ "c7r", "11.46x8.1cm",
+};
+
+static Boolean
+set_paper_type() {
+ _Xconst char *arg, *arg1;
+ char temp[21];
+ _Xconst char **p;
+ char *q;
+
+ if (strlen(RESOURCE(paper)) > sizeof(temp) - 1) return False;
+ arg = RESOURCE(paper);
+ q = temp;
+ for (;;) { /* convert to lower case */
+ char c = *arg++;
+ if (c >= 'A' && c <= 'Z') c ^= ('a' ^ 'A');
+ *q++ = c;
+ if (c == '\0') break;
+ }
+ arg = temp;
+ /* perform substitutions */
+ for (p = paper_types; p < paper_types + XtNumber(paper_types); p += 2)
+ if (strcmp(temp, *p) == 0) {
+ arg = p[1];
+ break;
+ }
+ arg1 = index(arg, 'x');
+ if (arg1 == NULL) return False;
+ unshrunk_paper_w = atopix(arg);
+ unshrunk_paper_h = atopix(arg1 + 1);
+ return (unshrunk_paper_w != 0 && unshrunk_paper_h != 0);
+}
+
+/*
+ * main program
+ */
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+
+
+#ifndef TOOLKIT
+#ifndef X10
+ XSizeHints size_hints;
+ XWMHints wmhints;
+#else
+ OpaqueFrame frame;
+ char def[32];
+ int mouspix;
+ Color cdef;
+ int x_thick, y_thick;
+#endif
+#endif /* TOOLKIT */
+ int screen_w, screen_h;
+
+#ifndef VMS
+ prog = rindex(*argv, '/');
+#else
+ prog = rindex(*argv, ']');
+#endif
+ if (prog != NULL) ++prog; else prog = *argv;
+
+#ifdef VMS
+ if (index(prog, '.') != NULL) *index(prog, '.') = '\0';
+#endif
+
+#ifdef TOOLKIT
+ top_level = XtInitialize(prog, "XDvi", options, XtNumber(options),
+ &argc, argv);
+ while (--argc > 0) {
+ if (*(*++argv) == '+')
+ if (curr_page != NULL) usage();
+ else curr_page = *argv + 1;
+ else if (dvi_name != NULL) usage();
+ else dvi_name = *argv;
+ }
+
+ XtGetApplicationResources(top_level, (XtPointer) &resource,
+ application_resources, XtNumber(application_resources), NULL, 0);
+ DISP = XtDisplay(top_level);
+ SCRN = XtScreen(top_level);
+ shrink_factor = resource._shrink_factor;
+ density = resource.density;
+ pixels_per_inch = resource.pixels_per_inch;
+ alt_font = resource.alt_font;
+ list_fonts = resource.list_fonts;
+ hush_spec = resource.hush_spec;
+ hush_chars = resource.hush_chars;
+#ifdef GREY
+ use_grey = resource.use_grey;
+#endif
+
+#else /* !TOOLKIT */
+
+ parse_options(argc, argv);
+#ifndef X10
+ if (fore_color) fore_Pixel = string_to_pixel(&fore_color);
+ if (back_color) back_Pixel = string_to_pixel(&back_color);
+ if (brdr_color) brdr_Pixel = string_to_pixel(&brdr_color);
+ if (high_color) hl_Pixel = string_to_pixel(&high_color);
+ if (curs_color) cr_Pixel = string_to_pixel(&curs_color);
+#endif
+
+#endif /* TOOLKIT */
+
+
+ if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 ||
+ dvi_name == NULL) usage();
+
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+#if defined(__MSDOS__) && defined(FONTSUB)
+
+ /* Open the font substitute file */
+ fontsubfile = openfontsubfile ();
+
+#endif
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+ if (shrink_factor != 1) bak_shrink = shrink_factor;
+ mane.shrinkfactor = shrink_factor;
+ if (RESOURCE(debug_arg) != NULL)
+ debug = isdigit(*RESOURCE(debug_arg)) ? atoi(RESOURCE(debug_arg))
+ : DBG_ALL;
+ if (RESOURCE(sidemargin)) home_x = atopix(RESOURCE(sidemargin));
+ if (RESOURCE(topmargin)) home_y = atopix(RESOURCE(topmargin));
+ offset_x = RESOURCE(xoffset) ? atopix(RESOURCE(xoffset))
+ : pixels_per_inch;
+ offset_y = RESOURCE(yoffset) ? atopix(RESOURCE(yoffset))
+ : pixels_per_inch;
+ if (!set_paper_type()) oops("Don't recognize paper type %s",
+ RESOURCE(paper));
+
+ init_font_open();
+ open_dvi_file();
+
+
+
+ if (curr_page) {
+ current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
+ if (current_page < 0 || current_page >= total_pages) usage();
+ }
+ if (RESOURCE(version_flag)) Puts((_Xconst char *) &version);
+
+#ifndef X10
+
+ /*
+ * X11 colors
+ */
+
+ if (RESOURCE(reverse)) {
+ if (!RESOURCE(fore_color))
+ RESOURCE(fore_Pixel) = WhitePixelOfScreen(SCRN);
+ if (!RESOURCE(back_color))
+ RESOURCE(back_Pixel) = BlackPixelOfScreen(SCRN);
+ /* Set them nonzero */
+ RESOURCE(fore_color) = RESOURCE(back_color) = (char *) &version;
+ } else {
+ if (!RESOURCE(fore_color))
+ RESOURCE(fore_Pixel) = BlackPixelOfScreen(SCRN);
+ if (!RESOURCE(back_color))
+ RESOURCE(back_Pixel) = WhitePixelOfScreen(SCRN);
+ }
+
+#ifdef GREY
+ if (DefaultDepthOfScreen(SCRN) == 1)
+ use_grey = False;
+#endif
+
+#ifdef TOOLKIT
+ if (resource.copy_arg)
+#else
+ if (copy == 2)
+#endif
+#ifdef GREY
+ RESOURCE(copy) = (!RESOURCE(thorough) && !use_grey
+ && DefaultDepthOfScreen(SCRN) > 1);
+#else
+ RESOURCE(copy) = (!RESOURCE(thorough)
+ && DefaultDepthOfScreen(SCRN) > 1);
+#endif
+
+#ifdef GREY
+ if (use_grey)
+ init_pix(True);
+ else
+#endif
+ {
+ XGCValues values;
+ Pixel set_bits = (Pixel)
+ (RESOURCE(fore_Pixel) & ~RESOURCE(back_Pixel));
+ Pixel clr_bits = (Pixel)
+ (RESOURCE(back_Pixel) & ~RESOURCE(fore_Pixel));
+
+#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\
+ values.background=bg,\
+ XCreateGC(DISP, RootWindowOfScreen(SCRN),\
+ GCFunction|GCForeground|GCBackground, &values))
+
+ if (RESOURCE(copy) || (set_bits && clr_bits))
+ ruleGC = MakeGC(GXcopy,
+ RESOURCE(fore_Pixel), RESOURCE(back_Pixel));
+ if (RESOURCE(copy)) foreGC = ruleGC;
+ else if (!RESOURCE(thorough) && ruleGC) {
+ foreGC = ruleGC;
+ Puts("Note: overstrike characters may be incorrect.");
+ }
+ else {
+ if (set_bits) foreGC = MakeGC(GXor, set_bits, 0);
+ if (clr_bits)
+ *(foreGC ? &foreGC2 : &foreGC) =
+ MakeGC(GXandInverted, clr_bits, 0);
+ if (!ruleGC) ruleGC = foreGC;
+ }
+ }
+
+ {
+ XGCValues values;
+
+ highGC = ruleGC;
+ if (RESOURCE(high_color))
+ highGC = MakeGC(GXcopy,
+ RESOURCE(hl_Pixel), RESOURCE(back_Pixel));
+ }
+
+ if (!RESOURCE(brdr_color)) RESOURCE(brdr_Pixel) = RESOURCE(fore_Pixel);
+
+#ifndef VMS
+ ready_cursor = XCreateFontCursor(DISP, XC_cross);
+ redraw_cursor = XCreateFontCursor(DISP, XC_watch);
+#else
+ DECWCursorFont = XLoadFont(DISP, "DECW$CURSOR");
+ XSetFont(DISP, foreGC, DECWCursorFont);
+ redraw_cursor = XCreateGlyphCursor(DISP, DECWCursorFont, DECWCursorFont,
+ decw$c_wait_cursor, decw$c_wait_cursor + 1,
+ &RESOURCE(fore_color), &RESOURCE(back_color));
+ MagnifyPixmap = XCreateBitmapFromData (DISP, RootWindowOfScreen(SCRN),
+ mag_glass_bits, mag_glass_width, mag_glass_height);
+ ready_cursor = XCreatePixmapCursor(DISP, MagnifyPixmap, MagnifyPixmap,
+ &RESOURCE(back_color), &RESOURCE(fore_color),
+ mag_glass_x_hot, mag_glass_y_hot);
+#endif /* VMS */
+
+ if (!RESOURCE(curs_color))
+ RESOURCE(cr_Pixel) = RESOURCE(high_color) ? RESOURCE(hl_Pixel)
+ : RESOURCE(fore_Pixel);
+ {
+ XColor bg_Color, cr_Color;
+
+ bg_Color.pixel = RESOURCE(back_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bg_Color);
+ cr_Color.pixel = RESOURCE(cr_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &cr_Color);
+ XRecolorCursor(DISP, ready_cursor, &cr_Color, &bg_Color);
+ XRecolorCursor(DISP, redraw_cursor, &cr_Color, &bg_Color);
+ }
+
+#ifdef TOOLKIT
+
+ /*
+ * X11 windows (toolkit)
+ */
+
+ /* The following code is lifted from Xterm */
+ if (resource.icon_geometry != NULL) {
+ int scr, junk;
+
+ for(scr = 0; /* yyuucchh */
+ SCRN != ScreenOfDisplay(DISP, scr);
+ scr++);
+
+ XGeometry(DISP, scr, resource.icon_geometry, "", 0, 0, 0, 0, 0,
+ (int *) &temp_args1[0].value,
+ (int *) &temp_args1[1].value, &junk, &junk);
+ XtSetValues(top_level, temp_args1, XtNumber(temp_args1));
+ }
+ /* Set icon pixmap */
+ XtGetValues(top_level, temp_args3, XtNumber(temp_args3));
+ if (icon_pm == (Pixmap) 0) {
+ temp_args3[0].value = (XtArgVal) (XCreateBitmapFromData(DISP,
+ RootWindowOfScreen(SCRN),
+ xdvi_bits, xdvi_width, xdvi_height));
+ XtSetValues(top_level, temp_args3, XtNumber(temp_args3));
+ }
+ temp_args4[0].value = (XtArgVal) dvi_name;
+ XtSetValues(top_level, temp_args4, XtNumber(temp_args4));
+
+#ifdef BUTTONS
+ form_widget = XtCreateManagedWidget("form", formWidgetClass,
+ top_level, form_args, XtNumber(form_args));
+
+ line_args[0].value = (XtArgVal) resource.high_color
+ ? resource.hl_Pixel : resource.fore_Pixel;
+#else /* !BUTTONS */
+#define form_widget top_level /* for calls to XtAddEventHandler */
+#endif /* BUTTONS */
+ vport_widget = XtCreateManagedWidget("vport", viewportWidgetClass,
+ form_widget, vport_args, XtNumber(vport_args));
+ clip_widget = XtNameToWidget(vport_widget, "clip");
+ draw_args[0].value = (XtArgVal) page_w;
+ draw_args[1].value = (XtArgVal) page_h;
+ draw_widget = XtCreateManagedWidget("drawing", drawWidgetClass,
+ vport_widget, draw_args, XtNumber(draw_args));
+ { /* set default window size */
+#ifdef BUTTONS
+ int xtra_wid = resource.expert ? 0 : XTRA_WID;
+#else
+#define xtra_wid 0
+#endif
+ XtWidgetGeometry constraints;
+ XtWidgetGeometry reply;
+
+ XtGetValues(top_level, &temp_args2, 1); /* get border width */
+ screen_w = WidthOfScreen(SCRN) - 2 * bwidth - xtra_wid;
+ screen_h = HeightOfScreen(SCRN) - 2 * bwidth;
+ constraints.request_mode = reply.request_mode = 0;
+ constraints.width = page_w;
+ if (page_w > screen_w) {
+ constraints.request_mode = CWWidth;
+ constraints.width = screen_w;
+ }
+ constraints.height = page_h;
+ if (page_h > screen_h) {
+ constraints.request_mode = CWHeight;
+ constraints.height = screen_h;
+ }
+ if (constraints.request_mode != 0
+ && constraints.request_mode != (CWWidth | CWHeight))
+ (void) XtQueryGeometry(vport_widget, &constraints, &reply);
+ if (!(reply.request_mode & CWWidth))
+ reply.width = constraints.width;
+ set_wh_args[0].value = (XtArgVal) ((reply.width < screen_w
+ ? reply.width : screen_w) + xtra_wid);
+ if (!(reply.request_mode & CWHeight))
+ reply.height = constraints.height;
+ set_wh_args[1].value = (XtArgVal) (reply.height < screen_h
+ ? reply.height : screen_h);
+ XtSetValues(top_level, set_wh_args, XtNumber(set_wh_args));
+#ifdef BUTTONS
+ set_wh_args[0].value -= xtra_wid;
+ XtSetValues(vport_widget, set_wh_args, XtNumber(set_wh_args));
+ if (!resource.expert) create_buttons(set_wh_args[1].value);
+#endif /* BUTTONS */
+ }
+ if (resource.fore_color) {
+ static Arg fore_args = {XtNforeground, (XtArgVal) 0};
+
+ fore_args.value = resource.fore_Pixel;
+ XtSetValues(draw_widget, &fore_args, 1);
+ }
+ if (resource.back_color) {
+ static Arg back_args = {XtNbackground, (XtArgVal) 0};
+
+ back_args.value = resource.back_Pixel;
+ XtSetValues(draw_widget, &back_args, 1);
+ XtSetValues(clip_widget, &back_args, 1);
+ }
+ XtAddEventHandler(form_widget, KeyPressMask, False, handle_key,
+ (caddr_t) NULL);
+ XtAddEventHandler(vport_widget, StructureNotifyMask, False,
+ handle_resize, (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ExposureMask, False, handle_exp,
+ (caddr_t) &mane);
+ XtAddEventHandler(draw_widget, ButtonPressMask, False, handle_button,
+ (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ButtonMotionMask, False, handle_motion,
+ (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ButtonReleaseMask, False, handle_release,
+ (caddr_t) NULL);
+ XtRealizeWidget(top_level);
+
+ currwin.win = mane.win = XtWindow(draw_widget);
+
+#else /* !TOOLKIT */
+
+ /*
+ * X11 windows (non toolkit)
+ */
+
+ screen_w = WidthOfScreen(SCRN) - 2*bwidth;
+ screen_h = HeightOfScreen(SCRN) - 2*bwidth;
+ size_hints.flags = PMinSize;
+ size_hints.min_width = size_hints.min_height = 50;
+ size_hints.x = size_hints.y = 0;
+ if (geometry != NULL) {
+ int flag = XParseGeometry(geometry, &size_hints.x, &size_hints.y,
+ &window_w, &window_h);
+
+ if (flag & (XValue | YValue))
+ size_hints.flags |= USPosition;
+ if (flag & (WidthValue | HeightValue))
+ size_hints.flags |= USSize;
+ if (flag & XNegative) size_hints.x += screen_w - window_w;
+ if (flag & YNegative) size_hints.y += screen_h - window_h;
+ }
+ if (!(size_hints.flags & USSize)) {
+ int x_thick = 0;
+ int y_thick = 0;
+ if (screen_w < page_w) x_thick = BAR_THICK;
+ if (screen_h < page_h + x_thick) y_thick = BAR_THICK;
+ window_w = page_w + y_thick;
+ if (window_w > screen_w) {
+ x_thick = BAR_THICK;
+ window_w = screen_w;
+ }
+ window_h = page_h + x_thick;
+ if (window_h > screen_h) window_h = screen_h;
+ size_hints.flags |= PSize;
+ }
+ size_hints.width = window_w;
+ size_hints.height = window_h;
+ top_level = XCreateSimpleWindow(DISP, RootWindowOfScreen(SCRN),
+ size_hints.x, size_hints.y, window_w, window_h, bwidth,
+ brdr_Pixel, back_Pixel);
+ XSetStandardProperties(DISP, top_level, dvi_name, prog, NULL,
+ argv, argc, &size_hints);
+
+ wmhints.flags = InputHint | StateHint | IconPixmapHint;
+ wmhints.input = True; /* window manager must direct input */
+ wmhints.initial_state = iconic ? IconicState : NormalState;
+ wmhints.icon_pixmap = XCreateBitmapFromData(DISP,
+ RootWindowOfScreen(SCRN),
+ xdvi_bits, xdvi_width, xdvi_height);
+ if (icon_geometry != NULL) {
+ int junk;
+
+ wmhints.flags |= IconPositionHint;
+ XGeometry(DISP, DefaultScreen(DISP), icon_geometry, "",
+ 0, 0, 0, 0, 0, &wmhints.icon_x, &wmhints.icon_y, &junk, &junk);
+ }
+ XSetWMHints(DISP, top_level, &wmhints);
+
+ XSelectInput(DISP, top_level, KeyPressMask | StructureNotifyMask);
+ XMapWindow(DISP, top_level);
+ Flush();
+
+#endif /* TOOLKIT */
+
+ XRebindKeysym(DISP, XK_Home, NULL, 0, (_Xconst ubyte *) "^", 1);
+ XRebindKeysym(DISP, XK_Left, NULL, 0, (_Xconst ubyte *) "l", 1);
+ XRebindKeysym(DISP, XK_Up, NULL, 0, (_Xconst ubyte *) "u", 1);
+ XRebindKeysym(DISP, XK_Right, NULL, 0, (_Xconst ubyte *) "r", 1);
+ XRebindKeysym(DISP, XK_Down, NULL, 0, (_Xconst ubyte *) "d", 1);
+ XRebindKeysym(DISP, XK_Prior, NULL, 0, (_Xconst ubyte *) "b", 1);
+ XRebindKeysym(DISP, XK_Next, NULL, 0, (_Xconst ubyte *) "f", 1);
+
+ image = XCreateImage(DISP, DefaultVisualOfScreen(SCRN), 1, XYBitmap, 0,
+ (char *)NULL, 0, 0, BITS_PER_BMUNIT, 0);
+ image->bitmap_unit = BITS_PER_BMUNIT;
+#ifndef MSBITFIRST
+ image->bitmap_bit_order = LSBFirst;
+#else
+ image->bitmap_bit_order = MSBFirst;
+#endif
+ {
+ short endian = MSBFirst << 8 | LSBFirst;
+ image->byte_order = *((char *) &endian);
+ }
+
+#else /* X10 */
+
+ /*
+ * X10 colors
+ */
+
+ if (reverse) {
+ foreGC = WhitePixel;
+ highGC = WhitePixel;
+ backpix = BlackPixel;
+ backmap = BlackPixmap;
+ bdrmap = WhitePixmap;
+ mouspix = WhitePixel;
+ GXfunc = GXor;
+ } else {
+ foreGC = BlackPixel;
+ highGC = BlackPixel;
+ backpix = WhitePixel;
+ backmap = WhitePixmap;
+ bdrmap = BlackPixmap;
+ mouspix = BlackPixel;
+ GXfunc = GXand;
+ }
+ if (DisplayCells() > 2) {
+ if (fore_color && XParseColor(fore_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ foreGC = cdef.pixel;
+ if (back_color && XParseColor(back_color, &cdef) &&
+ XGetHardwareColor(&cdef)) {
+ backpix = cdef.pixel;
+ backmap = XMakeTile(backpix);
+ }
+ if (brdr_color && XParseColor(brdr_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ bdrmap = XMakeTile(cdef.pixel);
+ if (high_color && XParseColor(high_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ highGC = cdef.pixel;
+ if (curs_color && XParseColor(curs_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ mouspix = cdef.pixel;
+ }
+
+ /*
+ * X10 windows
+ */
+
+ frame.bdrwidth = bwidth;
+ screen_w = DisplayWidth() - 2*bwidth;
+ screen_h = DisplayHeight() - 2*bwidth;
+ x_thick = y_thick = 0;
+ if (screen_w < page_w) x_thick = BAR_THICK;
+ if (screen_h < page_h + x_thick) y_thick = BAR_THICK;
+ frame.width = page_w + y_thick;
+ if (frame.width > screen_w) {
+ x_thick = BAR_THICK;
+ frame.width = screen_w;
+ }
+ frame.height = page_h + x_thick;
+ if (frame.height > screen_h) frame.height = screen_h;
+ frame.border = bdrmap;
+ frame.background = backmap;
+ frame.x = 0;
+ frame.y = 0;
+ Sprintf(def, "=%dx%d+0+0", frame.width, frame.height);
+ top_level = XCreate("DVI Previewer", prog, geometry, def,
+ &frame, 50, 50);
+ XSelectInput(top_level, ExposeWindow | KeyPressed);
+ XMapWindow(top_level);
+ XDefineCursor(top_level,
+ XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_mask_bits,
+ xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy));
+#endif /* X10 */
+
+ do_pages();
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+#if defined(__MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* close the font substitute file */
+ fclose (fontsubfile);
+ }
+
+#endif
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+ return 0; /* do_pages() returns if DBG_BATCH is specified */
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.h b/systems/msdos/dviware/xdvi-dos/src/xdvi.h
new file mode 100644
index 0000000000..2c0da4def9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.h
@@ -0,0 +1,509 @@
+/*
+ * Written by Eric C. Cooper, CMU
+ */
+
+/********************************
+ * The C environment *
+ *******************************/
+
+#ifndef X10
+#include <X11/Xlib.h> /* include Xfuncs.h, if available */
+#include <X11/Xutil.h> /* needed for XDestroyImage */
+#include <X11/Xos.h> /* same as below */
+#else /* X10 */
+#include <X/Xlib.h> /* get type of Window */
+#include <sys/types.h> /* for sites without X11 */
+#ifdef SYSV
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#include <fcntl.h>
+#else /* SYSV */
+#include <strings.h>
+#endif /* SYSV */
+#include <sys/file.h>
+#endif /* X10 */
+
+#ifndef XlibSpecificationRelease
+#define XlibSpecificationRelease 0
+#endif
+
+#if XlibSpecificationRelease >= 5
+#include <X11/Xfuncs.h>
+#endif
+
+#ifdef VMS
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#define bzero(a, b) (void) memset ((void *) (a), 0, (size_t) (b))
+#define bcopy(a, b, c) (void) memmove ((void *) (b), (void *) (a), (size_t) (c))
+#endif
+
+#include <stdio.h>
+#include <setjmp.h>
+
+#ifndef OPEN_MODE
+#ifndef VMS
+#define OPEN_MODE "rb"
+#else /* VMS */
+#define OPEN_MODE "r", "ctx=stm"
+#endif /* VMS */
+#endif /* OPEN_MODE */
+
+#ifndef SYSV
+#ifndef VMS
+#define HAS_SIGIO /* has SIGIO on _sockets_ */
+#endif
+#endif
+
+#ifndef NeedFunctionPrototypes
+#ifdef __STDC__
+#define NeedFunctionPrototypes 1
+#else /* STDC */
+#define NeedFunctionPrototypes 0
+#endif /* STDC */
+#endif /* NeedFunctionPrototypes */
+
+#ifndef NeedWidePrototypes
+#define NeedWidePrototypes NeedFunctionPrototypes
+#endif
+
+#if NeedWidePrototypes
+#define WIDEARG(a, b) b
+#else
+#define WIDEARG(a, b) a
+#endif
+
+#ifndef NeedVarargsPrototypes
+#define NeedVarargsPrototypes NeedFunctionPrototypes
+#endif
+
+#ifndef _XFUNCPROTOBEGIN
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#endif
+
+#ifndef _Xconst
+#ifdef __STDC__
+#define _Xconst const
+#else /* STDC */
+#define _Xconst
+#endif /* STDC */
+#endif /* _Xconst */
+
+#ifndef VOLATILE
+#if defined(__STDC__) || (defined(__stdc__) && defined(__convex__))
+#define VOLATILE volatile
+#else
+#define VOLATILE /* nothing */
+#endif
+#endif
+
+#ifndef NORETURN
+#ifdef __GNUC__
+#define NORETURN volatile
+#else
+#define NORETURN /* nothing */
+#endif
+#endif
+
+#define Printf (void) printf
+#define Puts (void) puts
+#define Fprintf (void) fprintf
+#define Sprintf (void) sprintf
+#define Fseek (void) fseek
+#define Fread (void) fread
+#define Fputs (void) fputs
+#define Putc (void) putc
+#define Putchar (void) putchar
+#define Fclose (void) fclose
+#define Strcpy (void) strcpy
+
+/********************************
+ * Types and data *
+ *******************************/
+
+#ifndef EXTERN
+#define EXTERN extern
+#define INIT(x)
+#define NTINIT(x)
+#endif
+
+typedef unsigned char ubyte;
+#define Boolean char
+#define True 1
+#define False 0
+
+#define MAXDIM 32767
+
+/*
+ * pixel_conv is currently used only for converting absolute positions
+ * to pixel values; although normally it should be
+ * ((int) ((x) / shrink_factor + (1 << 15) >> 16)),
+ * the rounding is achieved instead by moving the constant 1 << 15 to
+ * PAGE_OFFSET in dvi_draw.c.
+ */
+#define pixel_conv(x) ((int) ((x) / shrink_factor >> 16))
+#define pixel_round(x) ((int) ROUNDUP(x, shrink_factor << 16))
+#define spell_conv0(n, f) ((long) (n * f))
+#define spell_conv(n) spell_conv0(n, dimconv)
+
+#ifdef X10
+#undef MSBITFIRST
+#undef BMLONG
+#define BMSHORT
+#endif
+
+#ifdef BMLONG
+#define BMUNIT unsigned long
+#define BITS_PER_BMUNIT 32
+#define BYTES_PER_BMUNIT 4
+#else /* BMLONG */
+#ifdef BMSHORT
+#define BMUNIT unsigned short
+#define BITS_PER_BMUNIT 16
+#define BYTES_PER_BMUNIT 2
+#else /* BMSHORT */
+#define BMUNIT unsigned char
+#define BITS_PER_BMUNIT 8
+#define BYTES_PER_BMUNIT 1
+#endif /* BMSHORT */
+#endif /* BMLONG */
+
+#define ADD(a, b) ((BMUNIT *) (((char *) a) + b))
+#define SUB(a, b) ((BMUNIT *) (((char *) a) - b))
+
+extern BMUNIT bit_masks[BITS_PER_BMUNIT + 1];
+
+struct frame {
+ struct framedata {
+ long dvi_h, dvi_v, w, x, y, z;
+ int pxl_v;
+ } data;
+ struct frame *next, *prev;
+};
+
+#if NeedFunctionPrototypes
+#ifndef TEXXET
+typedef long (*set_char_proc)(WIDEARG(ubyte, int));
+#else /* TEXXET */
+typedef void (*set_char_proc)(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+#endif /* TEXXET */
+#else /* NeedFunctionPrototypes */
+#ifndef TEXXET
+typedef long (*set_char_proc)();
+#else /* TEXXET */
+typedef void (*set_char_proc)();
+#endif /* TEXXET */
+#endif /* NeedFunctionPrototypes */
+
+struct drawinf { /* this information is saved when using virtual fonts */
+ struct framedata data;
+ struct font *fontp;
+ set_char_proc set_char_p;
+ struct tn *tn_head;
+ ubyte *pos, *end;
+ struct font *virtual;
+#ifdef TEXXET
+ int dir;
+#endif
+};
+
+EXTERN struct drawinf currinf;
+
+/* entries below with the characters 'dvi' in them are actually stored in
+ scaled pixel units */
+
+#define DVI_H currinf.data.dvi_h
+#define PXL_H pixel_conv(currinf.data.dvi_h)
+#define DVI_V currinf.data.dvi_v
+#define PXL_V currinf.data.pxl_v
+#define WW currinf.data.w
+#define XX currinf.data.x
+#define YY currinf.data.y
+#define ZZ currinf.data.z
+#define ROUNDUP(x,y) (((x)+(y)-1)/(y))
+
+EXTERN int current_page;
+EXTERN int total_pages;
+EXTERN double dimconv;
+EXTERN int n_files_left INIT(32767); /* for LRU closing of fonts */
+EXTERN time_t dvi_time; /* last mod. time for dvi file */
+EXTERN int page_w, page_h;
+
+/*
+ * Table of page offsets in DVI file, indexed by page number - 1.
+ * Initialized in prepare_pages().
+ */
+EXTERN long *page_offset;
+
+/*
+ * Mechanism for reducing repeated warning about specials, lost characters, etc.
+ */
+EXTERN Boolean hush_spec NTINIT(False);
+EXTERN Boolean hush_spec_now;
+EXTERN Boolean hush_chars NTINIT(False);
+
+
+/*
+ * Bitmap structure for raster ops.
+ */
+struct bitmap {
+ short w, h; /* width and height in pixels */
+ short bytes_wide; /* scan-line width in bytes */
+ char *bits; /* pointer to the bits */
+};
+
+/*
+ * Per-character information.
+ * There is one of these for each character in a font (raster fonts only).
+ * All fields are filled in at font definition time,
+ * except for the bitmap, which is "faulted in"
+ * when the character is first referenced.
+ */
+struct glyph {
+ long addr; /* address of bitmap in font file */
+ long dvi_adv; /* DVI units to move reference point */
+ short x, y; /* x and y offset in pixels */
+ struct bitmap bitmap; /* bitmap for character */
+ short x2, y2; /* x and y offset in pixels (shrunken bitmap) */
+#ifdef GREY
+ XImage *image2;
+ char *pixmap2;
+#endif
+ struct bitmap bitmap2; /* shrunken bitmap for character */
+};
+
+/*
+ * Per character information for virtual fonts
+ */
+struct macro {
+ ubyte *pos; /* address of first byte of macro */
+ ubyte *end; /* address of last+1 byte */
+ long dvi_adv; /* DVI units to move reference point */
+ Boolean free_me; /* if free(pos) should be called when */
+ /* freeing space */
+};
+
+/*
+ * The layout of a font information block.
+ * There is one of these for every loaded font or magnification thereof.
+ * Duplicates are eliminated: this is necessary because of possible recursion
+ * in virtual fonts.
+ *
+ * Also note the strange units. The design size is in 1/2^20 point
+ * units (also called micro-points), and the individual character widths
+ * are in the TFM file in 1/2^20 ems units, i.e., relative to the design size.
+ *
+ * We then change the sizes to SPELL units (unshrunk pixel / 2^16).
+ */
+
+#define NOMAGSTP (-29999)
+
+#if NeedFunctionPrototypes
+typedef void (*read_char_proc)(struct font *, WIDEARG(ubyte, int));
+#else
+typedef void (*read_char_proc)();
+#endif
+
+struct font {
+ struct font *next; /* link to next font info block */
+ char *fontname; /* name of font */
+ float fsize; /* size information (dots per inch) */
+ int magstepval; /* magstep number * two, or NOMAGSTP */
+ FILE *file; /* open font file or NULL */
+ char *filename; /* name of font file */
+ unsigned short timestamp; /* for LRU management of fonts */
+ ubyte flags; /* flags byte (see values below) */
+ ubyte maxchar; /* largest character code */
+ double dimconv; /* size conversion factor */
+ set_char_proc set_char_p; /* proc used to set char */
+ /* these fields are used by (loaded) raster fonts */
+ read_char_proc read_char; /* function to read bitmap */
+ struct glyph *glyph;
+ /* these fields are used by (loaded) virtual fonts */
+ struct tn *vf_chain; /* list of fonts used by this vf */
+ struct font *first_font; /* first font defined */
+ struct macro *macro;
+ /* I suppose the above could be put into a union, but we */
+ /* wouldn't save all that much space. */
+};
+
+#define FONT_IN_USE 1 /* used for housekeeping */
+#define FONT_LOADED 2 /* if font file has been read */
+#define FONT_VIRTUAL 4 /* if font is virtual */
+
+struct tn {
+ struct tn *next; /* link to next TeXnumber info block */
+ int TeXnumber; /* font number (in DVI file) */
+ struct font *fontp; /* pointer to the rest of the info */
+};
+
+EXTERN struct font *font_head INIT(NULL);
+EXTERN struct tn *tn_head INIT(NULL);
+EXTERN ubyte maxchar;
+EXTERN unsigned short current_timestamp INIT(0);
+
+/*
+ * Command line flags.
+ */
+
+EXTERN int debug INIT(0);
+
+#define DBG_BITMAP 0x1
+#define DBG_DVI 0x2
+#define DBG_PK 0x4
+#define DBG_BATCH 0x8
+#define DBG_EVENT 0x10
+#define DBG_OPEN 0x20
+#define DBG_ALL (DBG_BITMAP|DBG_DVI|DBG_PK|DBG_EVENT|DBG_OPEN)
+
+EXTERN Boolean list_fonts NTINIT(False);
+
+#ifndef BDPI
+#define BDPI 300
+#endif
+
+EXTERN int pixels_per_inch NTINIT(BDPI);
+EXTERN int offset_x, offset_y;
+EXTERN int unshrunk_paper_w, unshrunk_paper_h;
+EXTERN int unshrunk_page_w, unshrunk_page_h;
+EXTERN int density NTINIT(40);
+EXTERN double specialConv;
+
+EXTERN char *dvi_name INIT(NULL);
+EXTERN FILE *dvi_file; /* user's file */
+EXTERN _Xconst char *alt_font NTINIT(ALTFONT);
+EXTERN char *prog;
+
+struct WindowRec {
+ Window win;
+ int shrinkfactor;
+ int base_x, base_y;
+ int width, height;
+ int min_x, max_x, min_y, max_y; /* for pending expose events */
+};
+
+extern struct WindowRec mane, alt, currwin;
+
+#define WINDOW(wr) ((Window) (wr).win)
+#define shrink_factor currwin.shrinkfactor
+
+EXTERN jmp_buf dvi_env; /* mechanism to communicate dvi file errors */
+
+#ifdef GREY
+#ifndef X10
+EXTERN Display *DISP;
+EXTERN Screen *SCRN;
+EXTERN unsigned long palette[17];
+EXTERN unsigned long *pixeltbl;
+EXTERN Boolean use_grey NTINIT(True);
+#else /* Sorry - GREY works only with X11 */
+#undef GREY
+#endif /* X10 */
+#endif /* GREY */
+
+/********************************
+ * Procedures *
+ *******************************/
+
+_XFUNCPROTOBEGIN
+#if NeedFunctionPrototypes
+
+extern void line_btw(int, int, int, int);
+extern void dot_at(int, int);
+extern void do_attribute_path(int, int, int, int);
+extern void put_bitmap(struct bitmap *, int, int);
+#ifdef GREY
+extern void put_image(XImage *, int, int);
+#endif
+extern void put_rectangle(int, int, int, int, WIDEARG(Boolean, int));
+extern void redraw_page(void);
+#if NeedVarargsPrototypes
+extern NORETURN void oops(_Xconst char *, ...);
+#else
+extern NORETURN void oops();
+#endif
+extern char *xmalloc(unsigned, _Xconst char *);
+extern void alloc_bitmap(struct bitmap *);
+extern FILE *xfopen(_Xconst char *);
+extern unsigned long num(FILE *, int);
+extern long snum(FILE *, int);
+extern void reset_fonts(void);
+extern void realloc_font(struct font *, WIDEARG(ubyte, int));
+extern void realloc_virtual_font(struct font *, WIDEARG(ubyte, int));
+extern void load_font(struct font *);
+extern void define_font(FILE *, WIDEARG(ubyte, unsigned int), struct font *,
+ struct tn **);
+extern void init_page(void);
+extern void open_dvi_file(void);
+extern Boolean check_dvi_file(void);
+#ifndef TEXXET
+extern long set_char(WIDEARG(ubyte, int));
+extern long set_vf_char(WIDEARG(ubyte, int));
+#else
+extern void set_char(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+extern void set_vf_char(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+#endif
+extern void draw_page(void);
+extern void init_font_open(void);
+extern FILE *font_open(_Xconst char *, char **,
+ WIDEARG(float, double), int *, int, char **);
+extern void applicationDoSpecial(char *);
+extern void read_PK_index(struct font *);
+extern void read_GF_index(struct font *);
+extern void read_PXL_index(struct font *);
+extern void read_VF_index(struct font *);
+
+#else /* ! NeedFunctionPrototypes */
+
+extern void line_btw();
+extern void dot_at();
+extern void do_attribute_path();
+extern void put_bitmap();
+#ifdef GREY
+extern void put_image();
+#endif
+extern void put_rectangle();
+extern void redraw_page();
+extern NORETURN void oops();
+extern char *xmalloc();
+extern void alloc_bitmap();
+extern FILE *xfopen();
+extern unsigned long num();
+extern long snum();
+extern void reset_fonts();
+extern void realloc_font();
+extern void realloc_virtual_font();
+extern void load_font();
+extern void define_font();
+extern void init_page();
+extern void open_dvi_file();
+extern Boolean check_dvi_file();
+#ifndef TEXXET
+extern long set_char();
+extern long set_vf_char();
+#else
+extern void set_char();
+extern void set_vf_char();
+#endif
+extern void draw_page();
+extern void init_font_open();
+extern FILE *font_open();
+extern void applicationDoSpecial();
+extern void read_PK_index();
+extern void read_GF_index();
+extern void read_PXL_index();
+extern void read_VF_index();
+
+#endif /* NeedFunctionPrototypes */
+
+#define one(fp) ((unsigned char) getc(fp))
+#define sone(fp) ((long) one(fp))
+#define two(fp) num (fp, 2)
+#define stwo(fp) snum(fp, 2)
+#define four(fp) num (fp, 4)
+#define sfour(fp) snum(fp, 4)
+
+_XFUNCPROTOEND
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.ico b/systems/msdos/dviware/xdvi-dos/src/xdvi.ico
new file mode 100644
index 0000000000..e98aeff206
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.ico
@@ -0,0 +1,27 @@
+#define xdvi_width 48
+#define xdvi_height 48
+static char xdvi_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa2, 0xe0, 0x44, 0x38, 0x95, 0x13,
+ 0x9e, 0x17, 0x45, 0x45, 0x55, 0xf4, 0x82, 0xf0, 0x28, 0x3d, 0xd5, 0x13,
+ 0x82, 0x10, 0x28, 0x05, 0x55, 0x10, 0x82, 0xe0, 0x10, 0x39, 0x8a, 0x13,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x1f, 0x00,
+ 0x79, 0x18, 0x18, 0x13, 0x16, 0x00, 0x69, 0x10, 0x18, 0x0e, 0x16, 0x00,
+ 0xcf, 0x20, 0x1c, 0x0e, 0xd6, 0x00, 0xe9, 0xc3, 0x7b, 0x84, 0x3f, 0x01,
+ 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x70, 0xcc,
+ 0x08, 0x00, 0x00, 0x00, 0x30, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x30, 0x52,
+ 0x0a, 0xc0, 0xff, 0x03, 0x30, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0xc0, 0xff, 0x03, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x17,
+ 0x0b, 0x0c, 0x3c, 0xc0, 0x93, 0x20, 0x0c, 0x0e, 0x43, 0x20, 0x96, 0x40,
+ 0x0c, 0x8e, 0x81, 0x10, 0x96, 0xbe, 0x0a, 0x8d, 0x81, 0x19, 0x90, 0x82,
+ 0x8a, 0x8c, 0x81, 0x0d, 0x90, 0x42, 0x48, 0x8c, 0x81, 0xed, 0x91, 0x3e,
+ 0x6a, 0x0c, 0xc3, 0x1d, 0x96, 0x12, 0x38, 0x0c, 0xbc, 0x0d, 0x1c, 0x02,
+ 0xf8, 0x3f, 0x80, 0x0d, 0x1c, 0x3e, 0x0b, 0x0c, 0x80, 0x0c, 0x1c, 0x00,
+ 0x0b, 0x0c, 0xc3, 0x18, 0x1c, 0x00, 0x0a, 0x0c, 0x63, 0x10, 0x16, 0x00,
+ 0x89, 0x3f, 0x1e, 0xe0, 0x11, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x1f, 0xae, 0x0f, 0x00, 0x80, 0x84, 0x0a, 0xae,
+ 0x87, 0x64, 0x86, 0x84, 0x08, 0x42, 0x42, 0x45, 0xe2, 0x1c, 0x07, 0x42};
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h b/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h
new file mode 100644
index 0000000000..a4083669b9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h
@@ -0,0 +1,9 @@
+#define xdvi_width 15
+#define xdvi_height 15
+#define xdvi_x_hot 7
+#define xdvi_y_hot 7
+static short xdvi_bits[] = {
+ 0x0080, 0x01c0, 0x03e0, 0x06b0,
+ 0x0c98, 0x188c, 0x3086, 0x7fff,
+ 0x3086, 0x188c, 0x0c98, 0x06b0,
+ 0x03e0, 0x01c0, 0x0080};
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h b/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h
new file mode 100644
index 0000000000..ab2f850b12
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h
@@ -0,0 +1,7 @@
+#define xdvi_mask_width 15
+#define xdvi_mask_height 15
+static short xdvi_mask_bits[] = {
+ 0x01c0, 0x03e0, 0x07f0, 0x0ff8,
+ 0x1ffc, 0x3ffe, 0x7fff, 0x7fff,
+ 0x7fff, 0x3ffe, 0x1ffc, 0x0ff8,
+ 0x07f0, 0x03e0, 0x01c0};
diff --git a/systems/msdos/dviware/xdvi-dos/texfonts.sub b/systems/msdos/dviware/xdvi-dos/texfonts.sub
new file mode 100644
index 0000000000..6d1a09caed
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/texfonts.sub
@@ -0,0 +1,74 @@
+amb10 -> cmb10
+ambsy10 -> cmbsy10
+ambx10 -> cmbx10
+ambx12 -> cmbx12
+ambx5 -> cmbx5
+ambx6 -> cmbx6
+ambx7 -> cmbx7
+ambx8 -> cmbx8
+ambx9 -> cmbx9
+ambxsl10 -> cmbxsl10
+ambxti10 -> cmbxti10
+amcsc10 -> cmcsc10
+amdunh10 -> cmdunh10
+amex10 -> cmex10
+amff10 -> cmff10
+amfib8 -> cmfib8
+aminch -> cminch
+amitt10 -> cmitt10
+ammi10 -> cmmi10
+ammi12 -> cmmi12
+ammi5 -> cmmi5
+ammi6 -> cmmi6
+ammi7 -> cmmi7
+ammi8 -> cmmi8
+ammi9 -> cmmi9
+ammib10 -> cmmib10
+amr10 -> cmr10
+amr12 -> cmr12
+amr17 -> cmr17
+amr5 -> cmr5
+amr6 -> cmr6
+amr7 -> cmr7
+amr8 -> cmr8
+amr9 -> cmr9
+amsl10 -> cmsl10
+amsl12 -> cmsl12
+amsl8 -> cmsl8
+amsl9 -> cmsl9
+amsltt10 -> cmsltt10
+amss10 -> cmss10
+amss12 -> cmss12
+amss17 -> cmss17
+amss8 -> cmss8
+amss9 -> cmss9
+amssbx10 -> cmssbx10
+amssdc10 -> cmssdc10
+amssi10 -> cmssi10
+amssi12 -> cmssi12
+amssi17 -> cmssi17
+amssi8 -> cmssi8
+amssi9 -> cmssi9
+amssq8 -> cmssq8
+amssqi8 -> cmssqi8
+amsy10 -> cmsy10
+amsy5 -> cmsy5
+amsy6 -> cmsy6
+amsy7 -> cmsy7
+amsy8 -> cmsy8
+amsy9 -> cmsy9
+amtcsc10 -> cmtcsc10
+amtex10 -> cmtex10
+amtex8 -> cmtex8
+amtex9 -> cmtex9
+amti10 -> cmti10
+amti12 -> cmti12
+amti7 -> cmti7
+amti8 -> cmti8
+amti9 -> cmti9
+amtt10 -> cmtt10
+amtt12 -> cmtt12
+amtt8 -> cmtt8
+amtt9 -> cmtt9
+amu10 -> cmu10
+amvtt10 -> cmvtt10
diff --git a/systems/msdos/dviware/xdvi-dos/xdvi.man b/systems/msdos/dviware/xdvi-dos/xdvi.man
new file mode 100644
index 0000000000..a60ddbdc09
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/xdvi.man
@@ -0,0 +1,396 @@
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+NAME
+ xdvi - DVI Previewer for the X Window System
+
+SYNOPSIS
+ xdvi [+[page]] [-s shrink] [-S density] [-p pixels]
+ [-altfont font] [-l] [-rv] [-fg color] [-bg color] [-hl
+ color] [-bd color] [-cr color] [-thorough] [-margins inches]
+ [-sidemargin inches] [-topmargin inches] [-mgs[n] size]
+ [-geometry geometry | =geometry] [%geometry] [-display
+ display] file
+
+DESCRIPTION
+ Xdvi is a program which runs under the X window system. It
+ is used to preview DVI files, such as are produced by TeX.
+
+ This program has the capability of showing the file shrunken
+ by various (integer) factors, and also has a ``magnifying
+ glass'' which allows one to see a small part of the unshrunk
+ image momentarily.
+
+ Also, before displaying any page or part thereof, it checks
+ to see if the dvi file has changed since the last time it
+ was displayed. If this is the case, then xdvi will reini-
+ tialize itself for the new dvi file. For this reason, ex-
+ posing parts of the xdvi window while TeX is running should
+ be avoided. This feature allows you to preview many ver-
+ sions of the same file while running xdvi only once.
+
+OPTIONS
+ In addition to specifying the .dvi file (with or without the
+ .dvi), Xdvi supports the following command line options. If
+ the option begins with a `+' instead of a `-', the option is
+ restored to its default value. By default, these options
+ can be set via the resource names given in parentheses in
+ the description of each option.
+
+ +page
+ Specifies the first page to show. If + is given
+ without a number, the last page is assumed; the first
+ page is the default.
+
+ -s shrink
+ (.shrinkFactor) Defines the initial shrink factor. The
+ default value is 3.
+
+ -S density
+ (.densityPercent) Determines the density used when
+ shrinking bitmaps for fonts. A higher value produces a
+ lighter font. The default value is 40.
+
+ -p pixels
+ (.pixelsPerInch) Defines the size of the fonts to use,
+
+
+
+X Version 11 Last change: 8 May 1989 1
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ in pixels per inch. The default value is 300.
+
+ -altfont font
+ (.altFont) Declares a default font to use when the font
+ in the dvi file cannot be found. This is useful, for
+ example, with PostScript <tm> fonts.
+
+ -l (.listFonts) Causes the names of the fonts used to be
+ listed.
+
+ -rv (.reverseVideo) Causes the page to be displayed with
+ white characters on a black background, instead of vice
+ versa.
+
+ -bw width
+ (.borderWidth) Specifies the width of the border of the
+ window.
+
+ -borderwidth width
+ Same as -bw, above.
+
+ -fg color
+ (.foreground) Determines the color of the text (fore-
+ ground).
+
+ -foreground color
+ Same as -fg, above.
+
+ -bg color
+ (.background) Determines the color of the background.
+
+ -background color
+ Same as -bg, above.
+
+ -hl color
+ (.highlight) Determines the color of the page border.
+
+ -bd color
+ (.borderColor) Determines the color of the window bord-
+ er.
+
+ -cr color
+ (.cursorColor) Determines the color of the cursor. The
+ default is the foreground color.
+
+ -thorough
+ (.thorough) Xdvi will usually try to ensure that over-
+ strike characters (e.g. \notin) are printed correctly.
+ On monochrome displays, this is always possible with
+ one logical operation, either and or or. On color
+ displays, however, this may take two operations, one to
+ set the appropriate bits and one to clear other bits.
+
+
+
+X Version 11 Last change: 8 May 1989 2
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ If this is the case, then by default xdvi will instead
+ use the copy operation, which does not handle over-
+ striking correctly. The ``thorough'' option chooses
+ the slower but more correct choice.
+
+ -margins inches
+ (.margins) Specifies the size of both the top margin
+ and side margin. This can be a decimal number, e.g.,
+ 1.5. It determines the ``home'' position of the page
+ within the window as follows. If the entire page fits
+ in the window, then the margin settings are ignored.
+ If, even after removing the margins from the left,
+ right, top, and bottom, the page still cannot fit in
+ the window, then the page is put in the window such
+ that the top and left margins are hidden, and presum-
+ ably the upper left-hand corner of the text on the page
+ will be in the upper left-hand corner of the window.
+ Otherwise, the text is centered in the window. See
+ also `H' under the KEYSTROKES section.
+
+ -sidemargin inches
+ (.sideMargin) Specifies the side margin (see above).
+
+ -topmargin inches
+ (.topMargin) Specifies the top and bottom margins (see
+ above).
+
+ -mgs[n] size
+ (.magnifierSize[n]) Specifies the size of the window to
+ be used for the ``magnifying glass'' for Button n. See
+ the MOUSE ACTIONS section. Defaults are 200, 350, 600,
+ 900, and 1200.
+
+ -mgs size
+ Same as -mgs1, above.
+
+ =geometry
+ (*geometry) Specifies the initial geometry of the win-
+ dow.
+
+ -geometry geometry
+ Same as above.
+
+ #geometry
+ (.iconGeometry) Specifies the initial position for the
+ icon.
+
+ -display host:display
+ Specifies the host and screen to be used for displaying
+ the dvi file. This is normally obtained from the en-
+ vironment variable ``DISPLAY.''
+
+
+
+
+X Version 11 Last change: 8 May 1989 3
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+KEYSTROKES
+ Xdvi recognizes the following keystrokes when typed in its
+ window. Each may optionally be preceded by a (positive or
+ negative) number, whose interpretation will depend on the
+ particular keystroke.
+
+ q Quits the program. Control-C and control-D will do
+ this, too.
+
+ n Moves to the next page (or to the nth next page if a
+ number is given). Synonyms are `f', Space, Return, and
+ Line Feed.
+
+ p Moves to the previous page (or back n pages). Synonyms
+ are `b', control-H, and Delete.
+
+ g Moves to the page with the given number. Initially,
+ the first page is assumed to be page number 1, but this
+ can be changed with the `P' keystroke, below. If no
+ page number is given, then it goes to the last page.
+
+ P ``This is page number n.'' This can be used to make
+ the `g' keystroke refer to actual page numbers instead
+ of absolute page numbers.
+
+ Control-L
+ Redisplays the current page.
+
+ ^ Move to the ``home'' position of the page. This is
+ normally the upper left-hand corner of the page,
+ depending on the margins as described in the -margins
+ option, above.
+
+ u Moves up a window-full.
+
+ d Moves down a window-full.
+
+ l Moves left a window-full.
+
+ r Moves right a window-full.
+
+ c Moves the page so that the point currently beneath the
+ cursor is moved to the middle of the window. It also
+ (gasp!) warps the cursor to the same place.
+
+ M Sets the margins so that the point currently under the
+ cursor is the upper left-hand corner of the text in the
+ page.
+
+ s Changes the shrink factor to the given number. If no
+ number is given, the smallest factor that makes the en-
+ tire page fit in the window will be used. (Margins are
+
+
+
+X Version 11 Last change: 8 May 1989 4
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ ignored in this computation.)
+
+ S Sets the density factor to be used when shrinking bit-
+ maps. This should be a number between 0 and 100;
+ higher numbers produce lighter characters.
+
+ R Forces the dvi file to be reread. This allows you to
+ preview many versions of the same file while running
+ xdvi only once.
+
+MOUSE ACTIONS
+ If the shrink factor is set to any number other than one,
+ then clicking any mouse button will pop up a ``magnifying
+ glass'' which shows the unshrunk image in the vicinity of
+ the mouse click. This subwindow disappears when the mouse
+ button is released. Different mouse buttons produce dif-
+ ferent sized windows, as indicated by the -mgs option,
+ above.
+
+ Also, the scrollbars (if present) behave in the standard
+ way: pushing Button 2 in a scrollbar moves the top or left
+ edge of the scrollbar to that point; pushing Button 1 moves
+ the image up or right by an amount equal to the distance
+ from the button press to the upper left-hand corner of the
+ window; pushing Button 3 moves the image down or left by the
+ same amount.
+
+ENVIRONMENT
+ Uses the environment variable ``DISPLAY'' to specify which
+ bit map display terminal to use.
+
+ The environment variable ``TEXPKS'' determines the path(s)
+ searched for fonts in the following manner. The string con-
+ sists of one or more strings separated by colons. In each
+ such string, the substring ``%f'' is changed to the font
+ name; ``%d'' is changed to the magnification; and ``%p'' is
+ changed to the font family (``gf'', ``pk'', or ``pxl''). If
+ no ``%f'' appears in the string, then the string
+ ``/%f.%d%p'' is added on the end. For example, if the
+ string is ``/usr/local/tex/fonts'' and the font is cmr10 at
+ 300dpi, then it searches for
+ /usr/local/tex/fonts/cmr10.300gf,
+ /usr/local/tex/fonts/cmr10.300pk, and
+ /usr/local/tex/fonts/cmr10.1500pxl, in that order. If the
+ first character of the ``TEXPKS'' variable is a colon, then
+ the system default paths are tried first.
+
+FILES
+ /usr/local/lib/tex/fonts/pk Font pixel files.
+
+SEE ALSO
+ X(1).
+
+
+
+X Version 11 Last change: 8 May 1989 5
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+AUTHORS
+ Eric Cooper, CMU, did a version for direct output to a QVSS.
+ Modified for X by Bob Scheifler, MIT Laboratory for Computer
+ Science. Modified for X11 by Mark Eichin, MIT SIPB. Addi-
+ tional enhancements by many others.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+X Version 11 Last change: 8 May 1989 6
+
+
+