summaryrefslogtreecommitdiff
path: root/dviware/umddvi/previewers
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/umddvi/previewers
Initial commit
Diffstat (limited to 'dviware/umddvi/previewers')
-rw-r--r--dviware/umddvi/previewers/dvistuff.c978
-rw-r--r--dviware/umddvi/previewers/dvistuff.h83
-rw-r--r--dviware/umddvi/previewers/makefile54
-rw-r--r--dviware/umddvi/previewers/texsun.136
-rw-r--r--dviware/umddvi/previewers/texsun.c1576
-rw-r--r--dviware/umddvi/previewers/texx.136
-rw-r--r--dviware/umddvi/previewers/texx.c1382
-rw-r--r--dviware/umddvi/previewers/texx2/00readme.tex62
-rw-r--r--dviware/umddvi/previewers/texx2/buildfonts17
-rw-r--r--dviware/umddvi/previewers/texx2/changelog123
-rw-r--r--dviware/umddvi/previewers/texx2/description64
-rw-r--r--dviware/umddvi/previewers/texx2/dvi-simple.c508
-rw-r--r--dviware/umddvi/previewers/texx2/dvi-simple.h75
-rw-r--r--dviware/umddvi/previewers/texx2/dvipage.c915
-rw-r--r--dviware/umddvi/previewers/texx2/dvipage.h64
-rw-r--r--dviware/umddvi/previewers/texx2/dvipage2.c522
-rw-r--r--dviware/umddvi/previewers/texx2/dvipagep.h106
-rw-r--r--dviware/umddvi/previewers/texx2/fonts9
-rw-r--r--dviware/umddvi/previewers/texx2/fonts.distrib9
-rw-r--r--dviware/umddvi/previewers/texx2/imakefile23
-rw-r--r--dviware/umddvi/previewers/texx2/makefile26
-rw-r--r--dviware/umddvi/previewers/texx2/manifest33
-rw-r--r--dviware/umddvi/previewers/texx2/mftobdf.c600
-rw-r--r--dviware/umddvi/previewers/texx2/mio.h64
-rw-r--r--dviware/umddvi/previewers/texx2/readme57
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-defs.h4
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-error.c224
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-file.c383
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-font.c127
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-font.h8
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-mark.c163
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-mark.h24
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-page.c833
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-page.h63
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-widgets.c174
-rw-r--r--dviware/umddvi/previewers/texx2/texx2-widgets.h40
-rw-r--r--dviware/umddvi/previewers/texx2/texx2.c104
-rw-r--r--dviware/umddvi/previewers/texx2/texx2.h58
38 files changed, 9627 insertions, 0 deletions
diff --git a/dviware/umddvi/previewers/dvistuff.c b/dviware/umddvi/previewers/dvistuff.c
new file mode 100644
index 0000000000..669ab55268
--- /dev/null
+++ b/dviware/umddvi/previewers/dvistuff.c
@@ -0,0 +1,978 @@
+/*
+ * 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, altough it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warrenty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ */
+#include <stdio.h>
+#include <ctype.h>
+
+#include "dvistuff.h" /* includes types & fonts */
+
+#include "conv.h"
+#include "dvi.h"
+#include "dviclass.h"
+#include "dvicodes.h"
+#include "postamble.h"
+#include "search.h"
+#include "fio.h"
+
+int dviHH = -1; /* current horizontal position, in DEVs */
+int dviVV = -1; /* current vertical position, in DEVs */
+int dviHHMargin = -1; /* horizontal margin (in DEVs) */
+int dviVVMargin = -1; /* vertical margin (in DEVs) */
+int dviTallestPage = -1;
+int dviWidestPage = -1 ;
+int dviCurrentPage = -1;
+int dviTotalPages = -1;
+int dviDPI = -1;
+int dviMaxDrift = -1;
+int dviUserMag = -1; /* user-specified magnification */
+int dviBlackness = -1;
+FILE *dviFile; /* users file */
+char *dviPrintEngine = "canon";
+
+char *ProgName;
+
+/*
+ * Similar to dvi_stack, but includes `dviHH and `dviVV, which are usually
+ * but not always the same as fromSP(h) and fromSP(v):
+ */
+struct localstack {
+ int stack_hh;
+ int stack_vv;
+ struct dvi_stack stack_dvi;
+};
+
+static struct localstack *dvi_stack; /* base of stack */
+static struct localstack *dvi_stackp; /* current place in stack */
+
+/*
+ * DVI preamble and postamble information.
+ */
+
+static long Magnification;
+static long Numerator; /* numerator from DVI file */
+static long Denominator; /* denominator from DVI file */
+
+/*
+ * Font related things.
+ * We keep track of the current font, use the fontfiner
+ * and record errors in the dvi postable in FontErros.
+ * the NoFont is a used when we cant find a font,
+ * to avoid errors.
+ */
+
+struct fontinfo *dviCurrentFont;
+
+static int NextFamilyNumber = 0;
+static int MaxFontFamily = MAX_FONTFAMILY;
+
+static struct search *FontFinder;
+int FontErrors;
+static struct fontinfo NoFont;
+
+/*
+ * We keep a list of pointers to the beginning of pages.
+ * Each page is headed by a DVI_BOP + 44 bytes of information.
+ */
+
+static long *pageOffset;
+
+/*
+ * Correct devpos (the actual device position) to be within dviMaxDrift pixels
+ * of dvipos (the virtual DVI position).
+ */
+#define FIXDRIFT(devpos, dvipos) \
+ if ((devpos) < (dvipos)) \
+ if ((dvipos) - (devpos) <= dviMaxDrift) \
+ /* void */; \
+ else \
+ (devpos) = (dvipos) - dviMaxDrift; \
+ else \
+ if ((devpos) - (dvipos) <= dviMaxDrift) \
+ /* void */; \
+ else \
+ (devpos) = (dvipos) + dviMaxDrift
+
+#define ABS(X) ( (X) < 0 ? -(X) : (X) )
+
+/*
+ * Store the relevant information from the DVI postamble, and set up
+ * various internal things.
+ */
+static void
+PostAmbleHeader(p)
+ register struct PostAmbleInfo *p;
+{
+ int i;
+ int pageSize;
+ int stackSize;
+ long prevPagePointer;
+ long wuzAt;
+
+ Numerator = p->pai_Numerator;
+ Denominator = p->pai_Denominator;
+ Magnification = p->pai_DVIMag;
+
+/*
+ * Set the conversion factor. This must be done before using
+ * any fonts or the fromSP routine.
+ */
+
+ SetConversion(dviDPI, dviUserMag, Numerator, Denominator, Magnification);
+
+ dviTotalPages = p -> pai_NumberOfPages;
+ dviWidestPage = fromSP(p -> pai_WidestPageWidth);
+ dviTallestPage = fromSP(p -> pai_TallestPageHeight);
+
+/*
+ * Set up the DVI stack
+ */
+ stackSize = p -> pai_DVIStackSize * sizeof(*dvi_stack);
+ dvi_stack = (struct localstack *) malloc((unsigned) stackSize);
+
+/*
+ * Set of the table of pointers to pages
+ */
+
+ pageSize = dviTotalPages * sizeof(long);
+ pageOffset = (long *) malloc(pageSize);
+
+ if (pageOffset == NULL) {
+ fprintf(stderr,"xdvi: Can not allocate page directory (%d pages)",
+ dviTotalPages);
+ exit(1);
+ }
+
+/*
+ * Follow back pointers through pages in the DVI file,
+ * storing the offsets in the pageOffset table.
+ */
+
+ prevPagePointer = p->pai_PrevPagePointer;
+ wuzAt = (long) ftell(dviFile);
+
+ if( fseek(dviFile, prevPagePointer, 0) < 0) {
+ perror("fseek");
+ fprintf(stderr,"[postamble] improper seek looking up pages\n");
+ fprintf(stderr,"prevPagePointer = %lx\n",
+ prevPagePointer);
+ }
+
+ for (i = dviTotalPages - 1; i > 0 ; i--) {
+
+ pageOffset[i] = prevPagePointer;
+
+ if (fseek(dviFile, (long) prevPagePointer, 0) < 0) {
+ perror("fseek");
+ fprintf(stderr,"[postamble] improper seek looking up pages\n");
+ fprintf(stderr,"prevPagePointer = %lx\n",
+ prevPagePointer);
+ exit(1);
+ }
+/*
+ * Skip past the other counters at the beginning of the page
+ */
+ if (fseek(dviFile, (long) (1 + 10 * 4), 1) < 0) {
+ perror("fseek");
+ fprintf(stderr,"[postamble] attemping to align to prevPointer\n");
+ exit(1);
+ }
+
+ fGetLong(dviFile, prevPagePointer);
+ }
+
+ pageOffset[0] = prevPagePointer;
+ fseek(dviFile, wuzAt, 0);
+}
+
+static void
+PostAmbleFontDef(p)
+register struct PostAmbleFont *p;
+{
+ register struct fontinfo *fi;
+ register struct font *f;
+
+ char *fname;
+ int def = S_CREATE | S_EXCL;
+
+ fi = (struct fontinfo *) SSearch(FontFinder, p->paf_DVIFontIndex,
+ &def);
+ if (fi == NULL) {
+ if (def & S_COLL)
+ GripeFontAlreadyDefined(p->paf_DVIFontIndex);
+ else {
+ fprintf(stderr, "Can not stash font %ld (out of memory?)\n",
+ p -> paf_DVIFontIndex);
+ exit(1);
+ }
+ }
+
+ if (NextFamilyNumber == MaxFontFamily) {
+ fprintf(stderr,"Out of font family!\n");
+ exit(1);
+ }
+
+ fi->family = NextFamilyNumber;
+ NextFamilyNumber++;
+
+ f = GetFont(p->paf_name, p->paf_DVIMag, p->paf_DVIDesignSize,
+ dviPrintEngine, &fname);
+
+/*
+ * Give the application a chance to bang on this if they want to.
+ */
+
+ f = applicationNewFont(f, fi -> family);
+
+ if ((fi->f = f) == NULL) {
+ GripeCannotGetFont(p->paf_name, p->paf_DVIMag,
+ p->paf_DVIDesignSize, dviPrintEngine, fname);
+ FontErrors++;
+ return;
+ }
+
+ /* match checksums, if not zero */
+ if (p->paf_DVIChecksum && f->f_checksum &&
+ p->paf_DVIChecksum != f->f_checksum)
+ GripeDifferentChecksums(fname, p->paf_DVIChecksum,
+ f->f_checksum);
+
+ fi->pspace = p->paf_DVIMag / 6; /* a three-unit "thin space" */
+ fi->nspace = -4 * fi->pspace;
+ fi->vspace = 5 * fi->pspace;
+}
+
+static void
+ReadPostAmble()
+{
+
+ if ((FontFinder = SCreate(sizeof(struct fontinfo))) == 0) {
+ fprintf(stderr, "can not create FontFinder (out of memory?)");
+ exit(1);
+ }
+
+ ScanPostAmble(dviFile, PostAmbleHeader, PostAmbleFontDef);
+
+ if (FontErrors)
+ GripeMissingFontsPreventOutput(FontErrors);
+}
+
+/*
+ * Read the preamble and do a few sanity checks
+ */
+
+static void
+ReadPreAmble()
+{
+ register int n;
+
+ rewind(dviFile);
+ if (GetByte(dviFile) != Sign8(DVI_PRE))
+ GripeMissingOp("PRE");
+
+ if (GetByte(dviFile) != Sign8(DVI_VERSION))
+ GripeMismatchedValue("version numbers");
+
+ if (GetLong(dviFile) != Numerator)
+ GripeMismatchedValue("numerator");
+
+ if (GetLong(dviFile) != Denominator)
+ GripeMismatchedValue("denominator");
+
+ if (GetLong(dviFile) != Magnification)
+ GripeMismatchedValue("\\magfactor");
+
+ n = UnSign8(GetByte(dviFile));
+ while (--n >= 0)
+ (void) GetByte(dviFile);
+}
+
+void
+dviInit()
+{
+ extern char *ProgName;
+
+ if (dviUserMag == -1) {
+ dviUserMag = 1000;
+ }
+
+ if (dviMaxDrift == -1) {
+ dviMaxDrift = 3;
+ }
+
+ if (dviDPI == -1) {
+ dviDPI = DEFAULT_DPI;
+ }
+
+ if (dviBlackness == -1) {
+ dviBlackness = DEFAULT_BLACKNESS;
+ }
+
+ ReadPostAmble();
+ ReadPreAmble();
+
+ /* Margins -- needs work! */
+
+ if (dviHHMargin == -1) {
+ dviHHMargin = DEFAULT_HHMARGIN;
+ }
+
+ if (dviVVMargin == -1) {
+ dviVVMargin = DEFAULT_VVMARGIN;
+ }
+
+ dviCurrentFont = &NoFont; /* fake font, all zeros */
+
+}
+
+static void
+SelectFont(n)
+i32 n;
+{
+ int x = S_LOOKUP;
+
+ if ((dviCurrentFont = (struct fontinfo *)SSearch(FontFinder, n, &x)) == 0)
+ GripeNoSuchFont(n);
+}
+
+/* Read the postamble. */
+
+/*
+ * Skip a font definition (since we are using those from the postamble)
+ */
+
+/*ARGSUSED*/
+void
+SkipFontDef(font)
+i32 font;
+{
+ register int i;
+
+ (void) GetLong(dviFile);
+ (void) GetLong(dviFile);
+ (void) GetLong(dviFile);
+ i = UnSign8(GetByte(dviFile)) + UnSign8(GetByte(dviFile));
+ while (--i >= 0)
+ (void) GetByte(dviFile);
+}
+
+
+static void
+doDviChar(c, advance)
+int c;
+int advance;
+{
+ register struct glyph *g;
+ register struct font *f;
+ int p;
+
+ f = dviCurrentFont->f;
+
+ if (c < f -> f_lowch || c > f -> f_highch) {
+ fprintf(stderr,"Character out of range: %d\n",
+ c);
+ return;
+ }
+
+ g = GLYPH(f, c);
+ if (!GVALID(g)) {
+ fprintf(stderr, "there is no character %d in %s",
+ c, f->f_path);
+ exit(1);
+ } else {
+
+ if (HASRASTER(g)) { /* workaround for Imagen bug */
+ applicationPutChar(dviHH,dviVV,c);
+ }
+
+ if (advance) {
+ dviHH += g->g_pixwidth;
+ dvi_h += g->g_tfmwidth;
+ p = fromSP(dvi_h);
+ FIXDRIFT(dviHH, p);
+ }
+ }
+}
+
+/*
+ * The next two routines are used to reset all the glyphs.
+ * the dviResetFont routine is called for each font in the font table.
+ * It de-allocates the rasters & glyphs for the shrunken fonts, leaving
+ * the original glyph data untouched.
+ */
+
+
+static void
+dviResetFont(fi, key)
+struct fontinfo *fi;
+int key;
+{
+ if (fi != 0) {
+ applicationResetFont(fi, fi -> family);
+ }
+}
+
+void
+dviResetAll()
+{
+ SEnumerate(FontFinder, dviResetFont);
+}
+
+/*
+ * Process the DVI commands for page #page. If the page number is
+ * out of range, it is cropped to the end.
+ *
+ * Updates dviCurrentPage
+ */
+void
+dviPreparePage(page)
+int page;
+{
+ register int c;
+ register i32 p;
+ int advance;
+
+ if (page < 0) {
+ page = 0;
+ }
+
+ if (page >= dviTotalPages) {
+ page = dviTotalPages - 1;
+ }
+
+ dviCurrentPage = page;
+
+ fseek(dviFile, (long) pageOffset[page], 0);
+
+ dviHH = dviHHMargin;
+ dviVV = dviVVMargin;
+
+ dvi_h = toSP(dviHH);
+ dvi_v = toSP(dviVV);
+
+ dvi_w = 0;
+ dvi_x = 0;
+ dvi_y = 0;
+ dvi_z = 0;
+
+ dvi_stackp = dvi_stack;
+
+ for(;;) {
+/*
+ * Get the DVI byte, and switch on its parameter length and type.
+ * Note that getchar() returns unsigned values.
+ */
+
+ if (feof(dviFile)) {
+ fprintf(stderr,"Unexpected end-of-file\n");
+ exit(1);
+ }
+
+ c = getc(dviFile);
+
+ if (DVI_IsChar(c)) {
+ advance = 1;
+ doDviChar(c, advance);
+ } else {
+
+ switch (DVI_OpLen(c)) {
+
+ case DPL_NONE:
+ break;
+
+ case DPL_SGN1:
+ p = getc(dviFile);
+ p = Sign8(p);
+ break;
+
+ case DPL_SGN2:
+ fGetWord(dviFile, p);
+ p = Sign16(p);
+ break;
+
+ case DPL_SGN3:
+ fGet3Byte(dviFile, p);
+ p = Sign24(p);
+ break;
+
+ case DPL_SGN4:
+ fGetLong(dviFile, p);
+ break;
+
+ case DPL_UNS1:
+ p = UnSign8(getc(dviFile));
+ break;
+
+ case DPL_UNS2:
+ fGetWord(dviFile, p);
+ p = UnSign16(p);
+ break;
+
+ case DPL_UNS3:
+ fGet3Byte(dviFile, p);
+ p = UnSign24(p);
+ break;
+
+ default:
+ panic("DVI_OpLen(%d) = %d", c, DVI_OpLen(c));
+ /* NOTREACHED */
+ }
+
+ switch (DVI_DT(c)) {
+
+ case DT_SET:
+ c = p;
+ doDviChar(c, 1);
+ break;
+
+ case DT_PUT:
+ c = p;
+ doDviChar(c, 0);
+ break;
+
+ case DT_SETRULE:
+ case DT_PUTRULE:
+
+ {
+ i32 h, w, rw;
+
+ fGetLong(dviFile, h);
+ fGetLong(dviFile, rw);
+
+ h = ConvRule(h);
+ w = ConvRule(rw);
+
+ applicationSetRule(dviHH, dviVV, h,w);
+
+ if (DVI_DT(c) == DT_SETRULE) {
+ dviHH += w;
+ dvi_h += rw;
+ w = fromSP(dvi_h);
+ FIXDRIFT(dviHH, w);
+ }
+ }
+ break;
+
+ case DT_NOP:
+ break;
+
+ case DT_BOP:
+/*
+ * Each beginning of page has 11 4-byte words telling us things
+ * about the page. We ignore them.
+ */
+ {
+ fseek(dviFile, (long) (11 * 4), 1);
+ }
+
+ break;
+
+ case DT_EOP:
+ return;
+
+ case DT_PUSH:
+ dvi_stackp->stack_hh = dviHH;
+ dvi_stackp->stack_vv = dviVV;
+ dvi_stackp->stack_dvi = dvi_current;
+ dvi_stackp++;
+ break;
+
+ case DT_POP:
+ dvi_stackp--;
+ dviHH = dvi_stackp->stack_hh;
+ dviVV = dvi_stackp->stack_vv;
+ dvi_current = dvi_stackp->stack_dvi;
+ break;
+
+ case DT_W0: /* there should be a way to make these pretty */
+ p = dvi_w;
+ goto move_right;
+
+ case DT_W:
+ dvi_w = p;
+ goto move_right;
+
+ case DT_X0:
+ p = dvi_x;
+ goto move_right;
+
+ case DT_X:
+ dvi_x = p;
+ goto move_right;
+
+ case DT_RIGHT:
+ move_right:
+ dvi_h += p;
+/*
+ * DVItype tells us that we must round motions in this way:
+ * `When the horizontal motion is small, like a kern, hh
+ * changes by rounding the kern; but when the motion is
+ * large, hh changes by rounding the true position so that
+ * accumulated rounding errors disappear.
+ */
+ if (p >= dviCurrentFont->pspace || p <= dviCurrentFont->nspace)
+ dviHH = fromSP(dvi_h);
+ else {
+ dviHH += fromSP(p);
+ p = fromSP(dvi_h);
+ FIXDRIFT(dviHH, p);
+ }
+ break;
+
+ case DT_Y0:
+ p = dvi_y;
+ goto move_down;
+
+ case DT_Y:
+ dvi_y = p;
+ goto move_down;
+
+ case DT_Z0:
+ p = dvi_z;
+ goto move_down;
+
+ case DT_Z:
+ dvi_z = p;
+ goto move_down;
+
+ case DT_DOWN:
+ move_down:
+ dvi_v += p;
+/*
+ * `Vertical motion is done similarly, but with the threshold
+ * between ``small and ``large increased by a factor of
+ * 5. The idea is to make fractions like $1\over2$ round
+ * consistently, but to absorb accumulated rounding errors in
+ * the baseline-skip moves.
+ */
+ if (ABS(p) >= dviCurrentFont->vspace)
+ dviVV = fromSP(dvi_v);
+ else {
+ dviVV += fromSP(p);
+ p = fromSP(dvi_v);
+ FIXDRIFT(dviVV, p);
+ }
+ break;
+
+ case DT_FNTNUM:
+ SelectFont((i32) (c - DVI_FNTNUM0));
+ break;
+
+ case DT_FNT:
+ SelectFont(p);
+ break;
+
+ case DT_XXX:
+ {
+ char specialBuffer [2048];
+ register char *cp;
+ int sweetp = 0;
+
+ if (p > 2047) {
+ sweetp = p - 2047;
+ p = 2047;
+ }
+
+ for (cp = specialBuffer ; p > 0; p--) {
+ *cp = getc(dviFile);
+ cp++;
+ }
+ *(cp) = 0;
+
+ while(sweetp > 0) {
+ getc(dviFile);
+ }
+
+ applicationDoSpecial(specialBuffer);
+ }
+ break;
+
+ case DT_FNTDEF:
+ SkipFontDef(p);
+ break;
+
+ case DT_PRE:
+ GripeUnexpectedOp("PRE");
+ /* NOTREACHED */
+
+ case DT_POST:
+ GripeUnexpectedOp("POST");
+ /* NOTREACHED */
+
+ case DT_POSTPOST:
+ GripeUnexpectedOp("POSTPOST");
+ /* NOTREACHED */
+
+ case DT_UNDEF:
+ GripeUndefinedOp(c);
+ /* NOTREACHED */
+
+ default:
+ panic("DVI_DT(%d) = %d", c, DVI_DT(c));
+ /* NOTREACHED */
+ }
+ }
+ }
+}
+
+/*
+ * The following routine is used to shrink a glyph by some
+ * shrink factor (in the width & height dimension).
+ *
+ * These shrunken glyphs are more appropriate for previewers.
+ *
+ * To do this, we simple scan the original raster, counting the
+ * number of pixels within a given area. If the number of on pixels is
+ * at least twice the total number of pixels, we turn the pixel in
+ * the shrunken glyph ON, else OFF.
+ *
+ * We use a lookup table to hasten the process of counting pixels.
+ *
+ * The method used should be independent of byte-order (I think).
+ *
+ * You need to define two types. One should be 32-bits long, and
+ * the other 16 bits long.
+ */
+
+typedef unsigned short B16;
+typedef unsigned long B32;
+
+#define LOOKUP_BYTES 256
+#define LOOKUP_BITS 8
+#define LOOKUP_MASK 0xff
+
+static char dviLookUpTable[LOOKUP_BYTES];
+static char tableNotInitialized = 1;
+
+struct glyph *
+dviShrinkGlyph(gly, shrinkH, shrinkW)
+DviGlyph *gly;
+int shrinkH;
+int shrinkW;
+{
+ int shrunkHeight;
+ int shrunkWidth;
+ int glyphWide;
+ int glyphHigh;
+
+ int bytesWide;
+ int shrunkBytesWide;
+
+ struct glyph *ngly;
+
+ B16 *shrunkRaster;
+ int rasterSize;
+
+ int x,y;
+ char *cp;
+ B16 *ptr;
+
+ B32 shrinkMask;
+
+ int sampleSize;
+
+ if (gly == 0 || !HASRASTER(gly)) {
+ return(0);
+ }
+
+ if (gly -> g_raster == 0) {
+ gly-> g_raster = RASTER(gly, dviCurrentFont -> f, ROT_NORM);
+ }
+
+/*
+ * Initialize the lookup table of the number of bits in a given byte
+ */
+
+ if (tableNotInitialized) {
+ register int i;
+ register int j;
+ register int k;
+ register int acc;
+ for (i = 0; i < LOOKUP_BYTES; i++) {
+ j = i;
+ acc = 0;
+ for (k = 0; j != 0 && k < LOOKUP_BITS ; k++) {
+ acc += (j & 1);
+ j >>= 1;
+ }
+ dviLookUpTable[i] = acc;
+ }
+ tableNotInitialized = 0;
+ }
+
+/*
+ * When shrinking the fonts, we convert them from byte alligned
+ * to 16 bit-aligned fonts. I think that this is needed by X,
+ * and also SunWindows. This is done rather than changing the
+ * library routines because some device drivers, i.e. imagen1,
+ * depend on the byte-alligned fonts.
+ */
+ glyphHigh = gly -> g_height;
+ glyphWide = gly -> g_width;
+
+ shrunkHeight = (glyphHigh + shrinkH - 1) / shrinkH;
+ shrunkWidth = (glyphWide + shrinkW - 1) / shrinkW;
+
+ bytesWide = (gly -> g_width + 7) >> 3;
+
+ shrunkBytesWide = ((shrunkWidth + 15) >> 4) * 2;
+
+ rasterSize = (shrunkHeight + 1) * shrunkBytesWide;
+ ptr = shrunkRaster = (B16 *) malloc(rasterSize);
+ bzero(ptr, rasterSize);
+
+ if (ptr == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+
+ for (y = 0; y < glyphHigh; y+= shrinkH) {
+ cp = (char *) ptr;
+ shrinkMask = 0x8000;
+ for (x = 0; x < glyphWide; x += shrinkW) {
+ int i;
+ int samples;
+ char *baseP;
+ int upper;
+ register int thisShrinkW;
+
+ baseP = gly -> g_raster + (y * bytesWide);
+
+/*
+ * Set the upper limit on the height iteration so we dont count
+ * off the end of the raster
+ */
+
+ upper = y + shrinkH;
+ if (upper > glyphHigh) {
+ upper = glyphHigh;
+ }
+
+ if (x + shrinkW > glyphWide) {
+ thisShrinkW = glyphWide - x;
+ } else {
+ thisShrinkW = shrinkW;
+ }
+
+ samples = 0;
+ sampleSize = thisShrinkW * shrinkH;
+
+ for (i = y; i < upper; i++) {
+ register int acc;
+ register char *p;
+ register char *ep;
+/*
+ * Determine how many bytes our shrink window crosses (we might
+ * overlap on byte-edges)
+ */
+
+ p = baseP + (x >> 3);
+ ep = baseP + ( (x + thisShrinkW - 1) >> 3);
+ baseP += bytesWide;
+
+/*
+ * stuff everything in the accumulator
+ */
+
+ acc = 0;
+ while (p <= ep) {
+ acc = ((acc << 8) & 0xff) | *p;
+ p++;
+ }
+
+/*
+ * clean off the right hand-side of extra bits, then clean off
+ * the left hand side of extra bits, and then count them.
+ */
+
+ acc = acc >> ( 7 - ((x + thisShrinkW - 1) & 0x7));
+ acc &= ~(-1 << thisShrinkW);
+ while (acc != 0) {
+ samples += dviLookUpTable[ acc & LOOKUP_MASK ];
+ acc >>= LOOKUP_BITS;
+ }
+ }
+/*
+ * If at least 1/blackness of the bits are on, treat this entire sample as
+ * being on.
+ */
+
+ if ((samples * dviBlackness) >= sampleSize) {
+ *ptr |= shrinkMask;
+ } else {
+ *ptr &= ~ shrinkMask;
+ }
+ shrinkMask >>= 1;
+ if (shrinkMask == 0) {
+ shrinkMask = 0x8000;
+ ptr ++;
+ }
+ }
+ ptr = (B16 *) (cp + shrunkBytesWide);
+ }
+
+/*
+ * Build a new glyph from the shrunken raster
+ */
+
+#ifdef UNDEF
+ printf("Old glyph:\n");
+ seeGlyph(gly -> g_raster, glyphHigh, bytesWide);
+ printf("New glyph:\n");
+ seeGlyph(shrunkRaster, shrunkHeight, shrunkBytesWide);
+#endif UNDEF
+
+ ngly = (struct glyph *) malloc(sizeof(struct glyph));
+ bzero(ngly, sizeof(struct glyph));
+
+ ngly -> g_raster = (char * ) shrunkRaster;
+ ngly -> g_width = shrunkWidth;
+ ngly -> g_height = shrunkHeight;
+
+ ngly -> g_xorigin = gly -> g_xorigin / shrinkH;
+ ngly -> g_yorigin = gly -> g_yorigin / shrinkW;
+
+ ngly -> g_flags |= GF_SHRUNK; /* yes, its been shrunk */
+
+ return(ngly);
+}
+
+#ifdef UNDEF
+
+seeGlyph(c, h, w)
+char *c;
+int h;
+int w;
+{
+ int i,j;
+
+ for (i = 0; i < h; i++ ) {
+ for (j = 0; j < w; j++) {
+ int k;
+ register int ch;
+ register int m;
+ char str[9];
+
+ ch = *(c++);
+ m = 0x80;
+ for (k = 0; k < 8; k++) {
+ str[k] = '0' + ( (ch & m) ? 1 : 0 );
+ m >>= 1;
+ }
+ str[8] = 0;
+ printf("%s", str);
+ }
+ printf("\n");
+ }
+}
+
+
+#endif UNDEF
diff --git a/dviware/umddvi/previewers/dvistuff.h b/dviware/umddvi/previewers/dvistuff.h
new file mode 100644
index 0000000000..b7da1bd3b7
--- /dev/null
+++ b/dviware/umddvi/previewers/dvistuff.h
@@ -0,0 +1,83 @@
+/*
+ * 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, altough it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warrenty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ */
+
+/*
+ * Include the following from the CTex distribution
+ */
+
+#include <stdio.h>
+
+#include "types.h"
+#include "font.h"
+
+/*
+ * We use the following flags to keep track of shrunk fonts
+ */
+
+#define GF_SHRUNK GF_USR0
+
+#define GLYPH_SHRUNK(g) ((g) -> g_flags & GF_SHRUNK)
+
+#define SHRUNK_GLYPH_BYTES_WIDE(g) ((((g) -> g_width + 15) >> 4) * 2)
+
+typedef struct font DviFont;
+typedef struct glyph DviGlyph;
+
+#define MAX_GLYPH 128
+#define MAX_FONTFAMILY 128
+
+#define DEFAULT_DPI 300
+#define DEFAULT_HHMARGIN DEFAULT_DPI
+#define DEFAULT_VVMARGIN DEFAULT_DPI
+
+#define DEFAULT_BLACKNESS 3
+
+
+struct fontinfo {
+ struct font *f; /* the font */
+ i32 pspace; /* boundary between `small & `large spaces
+ (for positive horizontal motion) */
+ i32 nspace; /* -4 * pspace, for negative motion */
+ i32 vspace; /* 5 * pspace, for vertical motion */
+ int family; /* Imagen family number (we pick one) */
+};
+
+typedef struct fontinfo DviFontInfo;
+
+extern int dviHH; /* current horizontal position, in DEVs */
+extern int dviVV; /* current vertical position, in DEVs */
+extern int dviHHMargin;
+extern int dviVVMargin;
+extern int dviDPI;
+extern int dviTallestPage;
+extern int dviWidestPage;
+extern int dviTotalPages;
+extern int dviCurrentPage;
+extern int dviMaxDrift;
+extern char *dviPrintEngine;
+extern int dviBlackness;
+
+extern DviFontInfo *dviCurrentFont;
+extern FILE *dviFile; /* user's file */
+extern char *ProgName;
+
+extern void dviInit();
+extern void dviPreparePage( /* int */ );
+extern struct glyph *dviShrinkGlyph();
+
+void applicationLoadGlyph( /* charCode, glyph */ );
+void applicationPutChar( /* hh, vv, charCode */ );
+DviFont *applicationNewFont( /* font structure */);
+void applicationResetFont(/* font info, key */);
+void applicationSetRule( /* hh, vv, height, width : long*/ );
+void applicationDoSpecial();
diff --git a/dviware/umddvi/previewers/makefile b/dviware/umddvi/previewers/makefile
new file mode 100644
index 0000000000..53b3fd7ba9
--- /dev/null
+++ b/dviware/umddvi/previewers/makefile
@@ -0,0 +1,54 @@
+#
+# Makefile for dvi previewer.
+#
+# $Header: Makefile,v 1.3 87/11/30 12:10:21 grunwald Locked $
+# $Source: /mntm/usr.src.local/Iptex/previewers/RCS/Makefile,v $
+#
+BINDIR=/usr/local/bin
+MANDIR=/usr/man
+INCLUDES= -I/usr/include/X -I../h
+CC= cc
+CFLAGS= -O ${INCLUDES}
+XLIBS= ../lib/lib.a -lX
+SUNLIBS= ../lib/lib.a -lsuntool -lsunwindow -lpixrect
+SRCS= texx.c dvistuff.c dvistuff.h
+MANSRC = texx.1 texsun.1
+
+XOBJS= texx.o dvistuff.o
+SUNOBJS = texsun.o dvistuff.o
+
+all: texx texsun
+
+texx: $(OBJS) Makefile
+ $(CC) $(CFLAGS) -o texx $(XOBJS) $(XLIBS)
+
+texsun: $(SUNOBJS) Makefile
+ $(CC) $(CFLAGS) -o texsun $(SUNOBJS) $(SUNLIBS)
+
+dvistuff.o: dvistuff.c dvistuff.h
+texsun.o: texsun.c dvistuff.h
+texx.o: texx.c dvistuff.h
+
+$(SRCS) $(MANSRC):
+ co -q $@
+
+inst-texx: texx texx.1
+ install -s -c -m 775 texx $(BINDIR)/texx
+ install -c -m 664 texx.1 $(MANDIR)/man1/texx.1
+
+inst-texsun: texsun texsun.1
+ install -s -c -m 775 texsun $(BINDIR)/texsun
+ install -c -m 664 texsun.1 $(MANDIR)/man1/texsun.1
+
+depend:
+ makedepend $(CFLAGS) $(SRCS)
+
+install: inst-texsun inst-texx
+
+clean:
+ -rm -f mktable table.c *.o *.BAK *.CKP texx a.out core errs *~
+
+lint:
+ lint $(INCLUDES) texx.c dvistuff.c $(XLIBS)
+ lint $(INCLUDES) texsun.c dvistuff.c $(SUNLIBS)
+
diff --git a/dviware/umddvi/previewers/texsun.1 b/dviware/umddvi/previewers/texsun.1
new file mode 100644
index 0000000000..e1a80e7154
--- /dev/null
+++ b/dviware/umddvi/previewers/texsun.1
@@ -0,0 +1,36 @@
+.TH TEXSUN 1
+.SH NAME
+texsun \- view DVI files on your SunView display
+.SH SYNOPSIS
+.B texsun
+.B [many options]
+.B filename
+.SH DESCRIPTION
+.I Texsun
+takes a DVI file produced by TeX and converts it to a format suitable
+for a SunView window.
+.I filename
+should be the name of a
+.B .dvi
+file.
+The environment and commands for
+.I texsun
+are too complicated to explain in man page.
+Users should consult the Dvi Output Guide.
+.SH DIAGNOSTICS
+Most of these should be self explanatory.
+.SH AUTHOR
+Dirk Grunwald, Univ. of Illinois
+.br
+.I Texsun
+uses a library of routines written by
+Chris Torek, University of Maryland
+.SH FILES
+/usr/local/texsun
+.br
+.SH "SEE ALSO"
+iptex(1), dviselect(1), tex(1)
+.SH BUGS
+.I Still
+needs to handle more ``\especial''s.
+
diff --git a/dviware/umddvi/previewers/texsun.c b/dviware/umddvi/previewers/texsun.c
new file mode 100644
index 0000000000..4eaa87e3e6
--- /dev/null
+++ b/dviware/umddvi/previewers/texsun.c
@@ -0,0 +1,1576 @@
+/*
+ * 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, altough it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warrenty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <suntool/sunview.h>
+#include <suntool/canvas.h>
+#include <sunwindow/defaults.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sun/fbio.h>
+#include "dvistuff.h"
+/*
+ * These constants may need to be changed on your implementation
+ */
+
+/*
+ * Note that ROUNDUP evaluates Y twice.
+ */
+#define ROUNDUP(x,y) (((x)+(y)-1) / (y))
+
+#define DEBUG printf
+
+#define INFORM (Debug > 2)
+#define TALK (Debug > 1)
+#define VERBOSE (Debug > 0)
+
+int Debug = 0;
+static int obscured = 1;
+
+
+/*
+ * SunTools related variables
+ */
+
+static Window tool = 0;
+static Canvas ptubeWindow = 0;
+static Pixwin *ptube = 0;
+
+static int canvasHeight;
+static int canvasWidth;
+static int canvasNormalWidthOffset;
+static int canvasNormalHeightOffset;
+
+typedef int (*intFuncp)();
+intFuncp memPixmapOps;
+
+static int foregroundMode = PIX_SRC | PIX_DST;
+static int clearMode = PIX_CLR;
+static int setMode = PIX_SET;
+static int copyMode = PIX_SRC;
+static int paintMode;
+static int cursorMode;
+
+static int globalArg = 0;
+static int globalNumber = 0;
+static int globalSign = 1;
+static int globalOtherLeaf = 0;
+static int globalLeafX;
+static int globalLeafY;
+static int globalDisplayState;
+static int globalDisplayLeaf;
+
+static int firstPage = 0;
+static char *dviFileName = 0;
+
+static Cursor workingCursor;
+static Cursor readyCursor;
+
+short workingCursorData[] = {
+#include <images/hglass.cursor>;
+};
+mpr_static(workingCursorPixrect, 16, 16, 1, workingCursorData);
+
+short readyCursorData[] = {
+#include <images/bullseye.cursor>;
+};
+mpr_static(readyCursorPixrect, 16, 16, 1, readyCursorData);
+
+/*
+ * TeX-Dvi related variables
+ */
+
+static int rawDviHeight;
+static int rawDviWidth; /* part of X interface, not dvistuff */
+static int maxHeight;
+static int maxWidth;
+static int maxDepth;
+
+static int screenWidth, screenHeight;
+
+#define MAX_LEAVES 2
+#define LEAF_LEFT 0
+#define LEAF_RIGHT 1
+
+#define DEFAULT_LEAVES 2
+
+static int Leaves;
+static int currentLeaf = 0;
+static int pageOnLeaf[MAX_LEAVES] = {-1,-1};
+static int haveLargePage[MAX_LEAVES] = {-1, -1};
+
+#define SHRINK_NORMAL 0
+#define SHRINK_LARGE 1
+#define MAX_SHRINKS 2
+
+static int page_w[MAX_SHRINKS], page_h[MAX_SHRINKS];
+static int leaf_w[MAX_SHRINKS];
+
+static int shrinkFactor[MAX_SHRINKS];
+static int currentShrink;
+static struct glyph **shrunkenGlyphs[MAX_SHRINKS][MAX_FONTFAMILY];
+
+typedef struct mpr_data MprData;
+static Pixrect **shrunkenPixrect[MAX_SHRINKS][MAX_FONTFAMILY];
+
+static int reverse = 0;
+
+static double specialConv;
+
+#define TEXSUN_STATE_NAME "TEXSUN_STATE"
+#define maxStateLines 100
+char *stateFileName;
+
+char **globalArgv;
+int globalArgc;
+
+char *malloc(), *calloc(), *index();
+
+#define MAXFUNC(a,b) ((a) < (b)) ? (b) : (a)
+#define MINFUNC(a,b) ((a) < (b)) ? (a) : (b)
+
+stop_output()
+{
+/*
+ * We must write the state before killing the window
+ */
+ writeState(stateFileName);
+
+ window_set(tool, FRAME_NO_CONFIRM, TRUE, 0);
+ window_destroy (tool);
+ exit (0);
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+
+ int xargc=argc;
+ char **xargv=argv;
+
+ char *display = NULL;
+ char option[120];
+ int optionEnd;
+ char *poption;
+
+ int bwidth = 2;
+ char *geometry = NULL, def[32];
+
+ int bdrpix, mouspix;
+ unsigned long xswattrs_mask;
+
+ struct rect tool_rect;
+ int ptubeSelected();
+ int repaintCanvas();
+ int resizeCanvas();
+
+ double atof();
+ char *getenv();
+
+/*
+ * Choose an explicit name so we always find the options.
+ */
+
+ ProgName = "texsun";
+ argv++;
+ argc--;
+ dviFileName = NULL;
+
+ strcpy(option, ProgName);
+ sprintf(option,"/%s/", ProgName);
+ optionEnd = strlen(option);
+ option[optionEnd] = 0;
+ reverse = (int) defaults_get_boolean(strcat(option,"ReverseVideo"), 0, 0);
+
+ option[optionEnd] = 0;
+ shrinkFactor[SHRINK_NORMAL] =
+ defaults_get_integer(strcat(option,"NormalShrink"), 0, 0);
+
+ option[optionEnd] = 0;
+ shrinkFactor[SHRINK_LARGE] =
+ defaults_get_integer(strcat(option,"LargeShrink"), 0, 0);
+
+ option[optionEnd] = 0;
+ dviDPI = defaults_get_integer(strcat(option,"Dpi"), DEFAULT_DPI, 0);
+
+ option[optionEnd] = 0;
+ Leaves = defaults_get_integer(strcat(option,"Leaves"), 0, 0);
+
+ option[optionEnd] = 0;
+ poption = defaults_get_string(strcat(option,"TopMargin"), 0, 0);
+ dviVVMargin = DEFAULT_VVMARGIN * ( (poption == 0) ? 1.0 : atof(poption));
+
+ option[optionEnd] = 0;
+ poption = defaults_get_string(strcat(option,"SideMargin"), 0, 0);
+ dviHHMargin = DEFAULT_HHMARGIN * ( (poption == 0) ? 1.0 : atof(poption));
+
+ option[optionEnd] = 0;
+ dviBlackness = defaults_get_integer(strcat(option,"Blackness"),
+ DEFAULT_BLACKNESS, 0);
+
+ option[optionEnd] = 0;
+ stateFileName = defaults_get_string(strcat(option,"StateFile"), 0, 0);
+
+ if (stateFileName == 0) {
+ stateFileName = getenv(TEXSUN_STATE_NAME);
+ }
+
+ if (argc > 0 && strcmp(argv[0], "-new") == 0) {
+ argv++;
+ argc--;
+ } else {
+ readState(&argc, &argv, stateFileName);
+ }
+
+ globalArgc = argc;
+ globalArgv = argv;
+
+ while (argc) {
+ if (strcmp(*argv, "-rv") == 0) {
+ reverse = !reverse;
+/*
+ * these two are for the state-saver
+ */
+
+ } else if (strcmp(*argv, "-rvOn") == 0 ) {
+ reverse = 1;
+ } else if (strcmp(*argv, "-rvOff") == 0) {
+ reverse = 0;
+ } else if (strcmp(*argv,"-l") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ Leaves = atoi(*argv);
+ if( Leaves < 1 || Leaves > MAX_LEAVES) {
+ fprintf(stderr,"[%s] Bad number of leaves(%d), using %d\n",
+ ProgName, Leaves, MAX_LEAVES);
+ Leaves = MAX_LEAVES;
+ }
+ } else if (strcmp(*argv,"-ns") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ shrinkFactor[SHRINK_NORMAL] = atoi(*argv);
+ } else if (strcmp(*argv,"-ls") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ shrinkFactor[SHRINK_LARGE] = atoi(*argv);
+ } else if (strcmp(*argv,"-dpi") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviDPI = atoi(*argv);
+ } else if (strcmp(*argv,"-tm") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviVVMargin = dviDPI * atof(*argv);
+ } else if (strcmp(*argv,"-sm") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviHHMargin = dviDPI * atof(*argv);
+ } else if (strcmp(*argv, "-bl") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviBlackness = atoi(*argv);
+ } else if (strcmp(*argv, "-pg") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ firstPage = atoi(*argv);
+ } else if (strcmp(*argv,"-debug") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ Debug = atoi(*argv);
+ } else if (**argv != '-') {
+ dviFileName = *argv;
+ } else {
+ usage:
+ fprintf(stderr, "Usage: %s [-ns <shrink>] [-ls <shrink>] [-dpi <dots>] \n",
+ ProgName);
+ fprintf(stderr, " [-l <leaves>] [-rv] [-tm <inches>] [-sm <inches>] dviFile\n");
+ exit(1);
+ }
+ argv++;
+ argc--;
+ }
+
+ if (dviFileName == NULL)
+ goto usage;
+
+ if ((dviFile = fopen(dviFileName, "r")) == NULL) {
+ int n = strlen(dviFileName);
+ char *dvi_name;
+
+ if (strcmp(dviFileName + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+ perror(dviFileName);
+ exit(1);
+ }
+ dvi_name = malloc((unsigned) n + sizeof(".dvi"));
+ sprintf(dvi_name, "%s.dvi", dviFileName);
+
+ if ((dviFile = fopen(dvi_name, "r")) == NULL) {
+ perror(dvi_name);
+ exit(1);
+ }
+
+ dviFileName = dvi_name;
+ }
+
+ if (INFORM) {
+ fprintf(stderr, "[texsun] call dviInit();\n");
+ }
+
+ dviInit();
+
+ if (TALK) {
+ fprintf(stderr,"page is %d wide, %d high\n",
+ dviTallestPage, dviWidestPage);
+ }
+
+ if (((double) dviTallestPage * (double) dviWidestPage) > 4.0e7) {
+ fprintf(stderr,"[%s] Warning: Your page size is %d wide and %d tall,\n",
+ ProgName, dviTallestPage, dviWidestPage);
+ fprintf(stderr,"which may be too big to be displayed\n");
+ }
+
+ specialConv = (float) dviDPI / 1000.0;
+
+/*
+ * If no shrink factor was chosen, pick one which will work out nicely
+ * on their display
+ */
+ if (INFORM) {
+ fprintf(stderr, "[texsun] set screenSpecific\n");
+ }
+
+ setScreenSpecifics();
+
+ rawDviHeight = dviTallestPage + 2 * dviVVMargin;
+ rawDviWidth = dviWidestPage + 2 * dviHHMargin;
+
+ if (Leaves == 0) {
+ if (dviTotalPages == 1) {
+ Leaves = 1;
+ } else {
+ Leaves = DEFAULT_LEAVES;
+ }
+ }
+
+ if (INFORM) {
+ fprintf(stderr, "[texsun] choose screenSpecific\n");
+ }
+
+ if (shrinkFactor[SHRINK_NORMAL] == 0) {
+ int sH;
+ int sW;
+ int sH2;
+ int sW2;
+ int shrink2;
+
+ sH = (rawDviHeight + maxHeight - 1) / maxHeight;
+ sW = (Leaves * rawDviWidth + maxWidth - 1) / maxWidth;
+
+ shrinkFactor[SHRINK_NORMAL] = MAXFUNC(sW, sH);
+ shrinkFactor[SHRINK_NORMAL] = MAXFUNC(shrinkFactor[SHRINK_NORMAL], 1);
+
+/*
+ * Check to see if we can get another shrink size bigger display
+ * if we cut the margins.
+ */
+
+ sH2 = (dviTallestPage + (dviHHMargin/32) + maxHeight - 1)
+ / maxHeight;
+ sW2 = ( Leaves * (dviWidestPage + (dviVVMargin/32))
+ + maxHeight - 1) / maxHeight;
+
+ shrink2 = MAXFUNC(sH2, sW2);
+ shrink2 = MAXFUNC(shrink2, 1);
+
+ if (shrink2 < shrinkFactor[SHRINK_NORMAL]) {
+ dviVVMargin /= 32;
+ dviHHMargin /= 32;
+ rawDviHeight = dviTallestPage + 2 * dviVVMargin;
+ rawDviWidth = dviWidestPage + 2 * dviHHMargin;
+ shrinkFactor[SHRINK_NORMAL] = shrink2;
+ }
+ }
+
+ page_h[SHRINK_NORMAL]=(rawDviHeight + shrinkFactor[SHRINK_NORMAL] - 1)
+ / shrinkFactor[SHRINK_NORMAL];
+ leaf_w[SHRINK_NORMAL]=(rawDviWidth + shrinkFactor[SHRINK_NORMAL] - 1)
+ / shrinkFactor[SHRINK_NORMAL];
+
+/*
+ * Based on the shrink factor, choose a shrink factor for the enlarged
+ * display
+ */
+
+ if (shrinkFactor[SHRINK_LARGE] == 0) {
+ shrinkFactor[SHRINK_LARGE] = shrinkFactor[SHRINK_NORMAL] / 2;
+ }
+
+ shrinkFactor[SHRINK_LARGE] = MINFUNC(shrinkFactor[SHRINK_LARGE],
+ shrinkFactor[SHRINK_NORMAL]-1);
+ shrinkFactor[SHRINK_LARGE] = MAXFUNC(shrinkFactor[SHRINK_LARGE], 1);
+
+ page_h[SHRINK_LARGE]=(rawDviHeight + shrinkFactor[SHRINK_LARGE] - 1)
+ / shrinkFactor[SHRINK_LARGE];
+ leaf_w[SHRINK_LARGE]=(rawDviWidth + shrinkFactor[SHRINK_LARGE] - 1)
+ / shrinkFactor[SHRINK_LARGE];
+
+/*
+ * Compute the page size given the number of leaves. We may have
+ * to scale back if everything cant fit.
+ */
+
+ if (leaf_w[SHRINK_NORMAL] * Leaves <= maxWidth) {
+ page_w[SHRINK_NORMAL] = leaf_w[SHRINK_NORMAL] * Leaves;
+ } else {
+ page_w[SHRINK_NORMAL] = leaf_w[SHRINK_NORMAL];
+ Leaves = 1;
+ }
+
+ screenWidth = (page_w[SHRINK_NORMAL] > maxWidth)
+ ? maxWidth : page_w[SHRINK_NORMAL];
+ screenHeight = (page_h[SHRINK_NORMAL] > maxHeight)
+ ? maxHeight : page_h[SHRINK_NORMAL];
+
+ tool_rect.r_left = 0;
+ tool_rect.r_top = 0;
+ tool_rect.r_width = 0;
+ tool_rect.r_height = 0;
+
+ cursorMode = PIX_SRC ^ PIX_DST;
+
+ if (reverse) {
+ paintMode = PIX_NOT(PIX_SRC);
+ } else {
+ paintMode = PIX_SRC;
+ }
+
+ if (INFORM) {
+ fprintf(stderr,"[texsun] create the tool windows\n");
+ }
+
+/* create the tool */
+ tool = window_create (0, FRAME,
+ FRAME_LABEL, "TeXsun",
+ FRAME_OPEN_RECT, &tool_rect,
+ 0);
+ if (tool == 0) {
+ fprintf(stderr,"Unable to create window\n");
+ exit(1);
+ }
+ ptubeWindow = window_create(tool, CANVAS,
+ CANVAS_AUTO_SHRINK, TRUE,
+ CANVAS_AUTO_EXPAND, TRUE,
+ CANVAS_WIDTH, screenWidth,
+ WIN_FIT_WIDTH, screenWidth,
+ CANVAS_HEIGHT, screenHeight,
+ WIN_FIT_HEIGHT, screenHeight,
+ CANVAS_RETAINED, FALSE,
+ CANVAS_REPAINT_PROC, repaintCanvas,
+ CANVAS_RESIZE_PROC, resizeCanvas,
+ WIN_EVENT_PROC, ptubeSelected,
+ WIN_BOTTOM_MARGIN, 0,
+ WIN_LEFT_MARGIN, 0,
+ WIN_TOP_MARGIN, 0,
+ WIN_RIGHT_MARGIN, 0,
+ WIN_X, 0,
+ WIN_Y, 0,
+ 0);
+ if (ptubeWindow == 0) {
+ fprintf(stderr,"Unable to create canvas\n");
+ exit(1);
+ }
+
+ readyCursor = cursor_create(CURSOR_IMAGE, &readyCursorPixrect,
+ CURSOR_OP, cursorMode, 0);
+ workingCursor = cursor_create(CURSOR_IMAGE, &workingCursorPixrect,
+ CURSOR_OP, cursorMode, 0);
+
+ ptubeInit();
+
+ window_set(ptubeWindow, WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS,0);
+
+ signal (SIGINT, stop_output);
+ signal (SIGQUIT, stop_output);
+ signal (SIGIOT, stop_output);
+
+ window_fit(ptubeWindow);
+ window_fit(tool);
+
+ if (INFORM) {
+ fprintf(stderr,"[texsun] enter window loop\n");
+ }
+
+ window_main_loop (tool);
+
+ /* terminate tool */
+ stop_output(0);
+}
+
+/*
+ * State-maintenance routines.
+ *
+ * The state is maintained in a file indicated by the environment
+ * variable TEXSUN_STATE.
+ *
+ * The state is written as a sequence of options, the same options
+ * which can be specified on the command line.
+ *
+ * When the state is used, the saved options are inserted in the
+ * command line before any new options. Thus, new options will
+ * over-ride the saved options, and both saved state and command
+ * line options will over-ride the default options.
+ */
+
+readState(inOutArgc, inOutArgv, stateFileName)
+char ***inOutArgv;
+int *inOutArgc;
+char *stateFileName;
+{
+ if (stateFileName != 0) {
+ FILE *f;
+ char **newArgv;
+ char *p;
+ int newArgc;
+ char buffer[512];
+ char *bufp;
+ int i;
+
+ int argc = *inOutArgc;
+ char **argv = *inOutArgv;
+
+ newArgv = (char **) malloc( sizeof(char *) * (argc + maxStateLines));
+ f = fopen(stateFileName,"r");
+
+/*
+ * The program name has already been removed.
+ */
+
+ newArgc = 0;
+
+ if (f != 0) {
+ while (!feof(f)) {
+ p = fgets(buffer, 512, f);
+ if (p != 0) {
+ int lth;
+ lth = strlen(buffer);
+ p = malloc(lth + 1);
+ strcpy(p, buffer);
+ p[lth-1] = 0; /* kill the newline character */
+ newArgv[newArgc++] = p;
+ }
+ }
+
+ for (i = 0 ; i < argc; i++ ) {
+ newArgv[newArgc++] = argv[i];
+ }
+
+ *inOutArgc = newArgc;
+ *inOutArgv = newArgv;
+ }
+ }
+}
+
+writeState(stateFileName)
+char *stateFileName;
+{
+ if (stateFileName != 0) {
+ FILE *f;
+ char *ptr;
+
+ f = fopen(stateFileName,"w");
+ if (f != 0) {
+ fprintf(f, "-rv%s\n", (reverse) ? "On" : "Off");
+ fprintf(f, "-l\n%d\n", Leaves);
+ fprintf(f, "-ns\n%d\n", shrinkFactor[SHRINK_NORMAL]);
+ fprintf(f, "-ls\n%d\n", shrinkFactor[SHRINK_LARGE]);
+ fprintf(f, "-dpi\n%d\n", dviDPI);
+ fprintf(f, "-tm\n%f\n", (double)
+ ((double) dviVVMargin / (double) dviDPI));
+ fprintf(f, "-sm\n%f\n", (double)
+ ((double) dviHHMargin / (double) dviDPI));
+ fprintf(f, "-bl\n%d\n", dviBlackness);
+ fprintf(f, "-debug\n%d\n", Debug);
+ fprintf(f, "-pg\n%d\n", pageOnLeaf[0]);
+ fprintf(f, "%s\n", dviFileName);
+
+ fclose(f);
+ }
+ }
+}
+
+
+/*
+ * Sun Screen-specific things
+ */
+setScreenSpecifics()
+{
+ struct fbtype FbType;
+ int Fb;
+
+ Fb = open("/dev/fb", O_RDONLY, 0);
+
+ if (Fb < 0) {
+ perror("open");
+ fprintf(stderr,"Unable to open /dev/fb\n");
+ exit(1);
+ }
+ if (ioctl(Fb, FBIOGTYPE, &FbType) == -1) {
+ perror("ioctl");
+ fprintf(stderr,"Unable to determine screen size\n");
+ exit(1);
+ }
+
+ maxWidth = FbType.fb_width;
+ maxHeight = FbType.fb_height;
+ maxDepth = FbType.fb_depth;
+
+ close(Fb);
+}
+
+resizeCanvas(canvas, width, height)
+{
+ canvasWidth = width;
+ canvasHeight = height;
+
+ if (canvasWidth > (Leaves * leaf_w[SHRINK_NORMAL])) {
+ canvasNormalWidthOffset =
+ (canvasWidth - Leaves * leaf_w[SHRINK_NORMAL]);
+ }
+ if (canvasHeight > (Leaves * page_h[SHRINK_NORMAL])) {
+ canvasNormalHeightOffset =
+ (canvasHeight - Leaves * page_h[SHRINK_NORMAL]);
+ }
+}
+
+repaintCanvas(canvas, pixwin, repaint_area)
+Canvas canvas;
+Pixwin *pixwin;
+Rectlist *repaint_area;
+{
+ displayLeaves();
+}
+
+/*
+ * Pixmap manipulation routines
+ */
+
+static Pixrect *pasteUpPixmap[MAX_SHRINKS][MAX_LEAVES];
+static int largePixmapsAllocated = 0;
+
+/*
+ * Ideally, we'd like to paint up a local pixmap & then transmit the
+ * entire pixmap. However, it looks like pixmaps require interaction
+ * with the server.
+ *
+ * So, if the entire page fits on the screen, we'll paint the screen
+ * and when we're done, we'll copy the screen to the pixmap. This
+ * gives the illusion of progress, but allows us to do fast re-paints.
+ *
+ * If we're *not* on the display, we'll just draw to the pixmap and
+ * update it at the end
+ */
+
+static int buildToPixmap = 0;
+
+static void
+clearPixmap(leaf, shrinkSize)
+int leaf;
+int shrinkSize;
+{
+ Pixrect *w;
+
+ if (leaf< 0 || leaf >= Leaves) {
+ fprintf(stderr,"[%s] Reference to bogus leaf in clearPixmap: %d\n",
+ ProgName, leaf);
+ exit(1);
+ }
+
+ if (shrinkSize < 0 || shrinkSize >= MAX_SHRINKS ) {
+ fprintf(stderr,"[%s] reference to bogus shrink %d\n",
+ ProgName, shrinkSize);
+ exit(1);
+ }
+
+ w = pasteUpPixmap[shrinkSize][leaf];
+ pr_rop(w, 0, 0,
+ leaf_w[shrinkSize], page_h[shrinkSize],
+ clearMode,
+ w, 0, 0);
+}
+
+/*
+ * Clear the window. Actually, for a black-on-white display (normal)
+ * this means we need to *set* the entire display using COLOR(1) color.
+ */
+static void
+clearWindow()
+{
+ int localClear = PIX_COLOR(1) | clearMode;
+ if (reverse) {
+ localClear = PIX_NOT(localClear);
+ }
+ pw_writebackground(ptube,
+ 0, 0,
+ canvasWidth, canvasHeight,
+ localClear);
+}
+
+allocatePixmaps()
+{
+ int i;
+
+ for (i = 0; i < Leaves; i++ ) {
+ pasteUpPixmap[SHRINK_NORMAL][i] = (Pixrect *)
+ mem_create(leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL], 1);
+
+ if (pasteUpPixmap[SHRINK_NORMAL][i] == 0) {
+ fprintf(stderr,"[%s] erp! out of PIXMAP memory!\n",
+ ProgName);
+ stop_output();
+ }
+ }
+
+ largePixmapsAllocated = 0;
+
+/*
+ * Clear the pixmap
+ */
+ for (i = 0; i < Leaves; i++) {
+ clearPixmap(i, SHRINK_NORMAL);
+ }
+}
+
+allocateLargePixmaps()
+{
+ int i;
+ for (i = 0; i < Leaves; i++) {
+ pasteUpPixmap[SHRINK_LARGE][i] = (Pixrect *)
+ mem_create(leaf_w[SHRINK_LARGE], page_h[SHRINK_LARGE], 1);
+ clearPixmap(i, SHRINK_LARGE);
+ }
+
+ largePixmapsAllocated = 1;
+}
+
+/*
+ * display the normal sized leaf
+ */
+static int
+displayLeaves()
+{
+ if (globalDisplayState == SHRINK_LARGE) {
+
+/*
+ * globalLeafX and globalLeafY point the part of the display
+ * they want to see, scaled to the large shrink.
+ *
+ */
+ int leafX;
+ int leafY;
+ int leafW;
+ int leafH;
+ int canvasX;
+ int canvasY;
+
+ leafW = MINFUNC(leaf_w[SHRINK_LARGE], canvasWidth);
+ leafH = MINFUNC(page_h[SHRINK_LARGE], canvasHeight);
+
+ leafX = globalLeafX - (leafW / 2); /* find left side */
+ if (leafX < 0) {
+ canvasX = -leafX;
+ leafX = 0;
+ } else {
+ canvasX = 0;
+ }
+
+ if ((leafX + leafW) > leaf_w[SHRINK_LARGE]) {
+ leafW = leaf_w[SHRINK_LARGE] - leafX;
+ }
+
+ leafY = globalLeafY - (leafH / 2); /* gind top side */
+ if (leafY < 0) {
+ canvasY = -leafY;
+ leafY = 0;
+ } else {
+ canvasY = 0;
+ }
+ if ((leafY + leafH) > page_h[SHRINK_LARGE]) {
+ leafH = page_h[SHRINK_LARGE] - leafY;
+ }
+
+#ifdef UNDEF
+ if (leafW < canvasWidth) {
+ leafX += (canvasWidth - leafW) / 2;
+ }
+ if (leafH < canvasHeight) {
+ leafY += (canvasHeight - leafH) / 2;
+ }
+#endif
+
+ clearWindow();
+ pw_write(ptube,
+ canvasX, canvasY,
+ leafW, leafH,
+ paintMode,
+ pasteUpPixmap[SHRINK_LARGE][globalDisplayLeaf],
+ leafX, leafY);
+ } else {
+ clearWindow();
+ pw_write(ptube,
+ 0, 0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ paintMode,
+ pasteUpPixmap[SHRINK_NORMAL][0],
+ 0,0);
+ pw_write(ptube,
+ leaf_w[SHRINK_NORMAL], 0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ paintMode,
+ pasteUpPixmap[SHRINK_NORMAL][1],
+ 0,0);
+ }
+}
+
+static void
+swapLeaf(from, to)
+int from;
+int to;
+{
+ Pixrect *tempPix;
+ int tempNum;
+
+ if (to < 0 || to >= Leaves) {
+ fprintf(stderr,"[%s] bogus to leaf %d in swapLeaf\n",
+ ProgName, to);
+ exit(1);
+ }
+ if (from < 0 || from >= Leaves) {
+ fprintf(stderr,"[%s] bogus from leaf %d in swapLeaf\n",
+ ProgName, from);
+ exit(1);
+ }
+
+ tempPix = pasteUpPixmap[SHRINK_NORMAL][to];
+ pasteUpPixmap[SHRINK_NORMAL][to] = pasteUpPixmap[SHRINK_NORMAL][from];
+ pasteUpPixmap[SHRINK_NORMAL][from] = tempPix;
+
+ tempPix = pasteUpPixmap[SHRINK_LARGE][to];
+ pasteUpPixmap[SHRINK_LARGE][to] = pasteUpPixmap[SHRINK_LARGE][from];
+ pasteUpPixmap[SHRINK_LARGE][from] = tempPix;
+
+ tempNum = pageOnLeaf[to];
+ pageOnLeaf[to] = pageOnLeaf[from];
+ pageOnLeaf[from] = tempNum;
+
+ tempNum = haveLargePage[to];
+ haveLargePage[to] = haveLargePage[from];
+ haveLargePage[from] = tempNum;
+}
+
+static void
+buildLeaf(leaf, page, shrinkSize)
+int leaf;
+int page;
+int shrinkSize;
+{
+
+ if (leaf < 0 || leaf >= Leaves) {
+ fprintf(stderr,"[%s] bogus leaf %d in buildLeaf\n",
+ ProgName, leaf);
+ exit(1);
+ }
+
+ if (shrinkSize < 0 || shrinkSize >= MAX_SHRINKS ) {
+ fprintf(stderr,"[%s] Bogus shrink size %d in buildLeaf\n",
+ ProgName, shrinkSize);
+ exit(1);
+ }
+
+ window_set(ptubeWindow, WIN_CURSOR, workingCursor, 0);
+
+ if (shrinkSize == SHRINK_LARGE && !largePixmapsAllocated) {
+ allocateLargePixmaps();
+ }
+
+/*
+ * If this is a normal size page, kill the information
+ * for the large version.
+ */
+ if (shrinkSize == SHRINK_NORMAL) {
+ haveLargePage[leaf] = -1;
+ }
+
+/*
+ * Determine if this is a valid page. If it's not, we'll just clear
+ * the particular leaf.
+ */
+
+ if (page < 0 || page >= dviTotalPages) {
+ clearPixmap(leaf, shrinkSize);
+
+ if (shrinkSize == SHRINK_NORMAL) {
+ clearWindow(leaf);
+ }
+ } else {
+
+ if (obscured || shrinkSize == SHRINK_LARGE) {
+ buildToPixmap = 1;
+ } else {
+ buildToPixmap = 1;
+ }
+
+ if (buildToPixmap) {
+ clearPixmap(leaf, shrinkSize);
+ } else {
+ clearPixmap(leaf, shrinkSize);
+ if (shrinkSize == SHRINK_NORMAL) {
+ clearWindow(leaf);
+ }
+ }
+
+/*
+ * Note that dviPreparePage may change dviCurrentPage
+ */
+
+ currentLeaf = leaf;
+ currentShrink = shrinkSize;
+
+ dviPreparePage(page);
+
+ page = dviCurrentPage;
+
+/*
+ * Save the constructed page if we were painting it to the screen
+ */
+ put_border(0, 0, leaf_w[currentShrink], page_h[currentShrink], 1);
+
+ if (! buildToPixmap && shrinkSize == SHRINK_NORMAL) {
+ clearPixmap(leaf, SHRINK_NORMAL);
+/*
+ * We save the pixmap from the *retained* image -- the tool may not
+ * actually be up. This isn't optimal, but it saves us a lot of
+ * hacking & having to determine when we're obscured.
+ */
+ pr_rop(pasteUpPixmap[SHRINK_NORMAL][leaf],
+ 0,0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ copyMode,
+ ptube -> pw_prretained,
+ leaf_w[SHRINK_NORMAL] * leaf, 0);
+ } else if (shrinkSize == SHRINK_NORMAL) {
+ /* null */
+ }
+ }
+
+ pageOnLeaf[leaf] = dviCurrentPage;
+ window_set(ptubeWindow, WIN_CURSOR, readyCursor, 0);
+}
+
+/*
+ * interfaces to dvistuff
+ */
+
+/*
+ * Whenever a new font is registers, we create a shrunken Glyph
+ * table for it. However, we don't shrink the glyphs -- that's
+ * done on the fly by the putChar routine.
+ */
+
+DviFont *
+applicationNewFont(f, key)
+struct font *f;
+int key;
+{
+ int shrink;
+
+ if (key < 0 || key > MAX_FONTFAMILY) {
+ fprintf(stderr,"[%s] bogus key in Newfont = %d\n",
+ ProgName, key);
+ exit(1);
+ }
+
+ for (shrink = SHRINK_NORMAL; shrink <= SHRINK_LARGE; shrink++) {
+
+ if (shrunkenGlyphs[shrink][key] == 0) {
+ int lth = sizeof(struct glyph *) * MAX_GLYPH;
+ struct glyph **g;
+
+ g = (struct glyph **) malloc( lth );
+ bzero(g, lth);
+ shrunkenGlyphs[shrink][key] = g;
+ }
+
+ if (shrunkenPixrect[shrink][key] == 0) {
+ int lth = sizeof(Pixrect *) * MAX_GLYPH;
+ Pixrect **g;
+
+ g = (Pixrect **) malloc( lth );
+ bzero(g, lth);
+ shrunkenPixrect[shrink][key] = g;
+ }
+
+ }
+ return(f);
+}
+
+/*
+ * When we reset a font, we only need to free the storage for the
+ * shrunken glyphs. We keep the glyph table available because we're
+ * very likely to fill it in again.
+ */
+
+void
+applicationResetFont(fi, key)
+struct fontinfo *fi;
+int key;
+{
+ int i;
+ struct glyph **theseGlyphs;
+ Pixrect **thesePixrect;
+ int shrink;
+
+
+ for (shrink = SHRINK_NORMAL; shrink <= SHRINK_LARGE; shrink++) {
+ theseGlyphs = shrunkenGlyphs[shrink][key];
+ if (theseGlyphs != 0) {
+ for (i = 0; i < MAX_GLYPH; i++) {
+ struct glyph *g;
+
+ g = theseGlyphs[i];
+
+ if (g != 0) {
+ if ( g -> g_raster != 0) {
+ free(g -> g_raster);
+ }
+ free(g);
+ theseGlyphs[i] = 0;
+ }
+ }
+ }
+
+ thesePixrect = shrunkenPixrect[shrink][key];
+ if (thesePixrect != 0) {
+ for (i = 0; i < MAX_GLYPH; i++) {
+ Pixrect *g;
+
+ g = thesePixrect[i];
+
+ if (g != 0) {
+ free(g -> pr_data);
+ free(g);
+ thesePixrect[i] = 0;
+ }
+ }
+ }
+ }
+}
+
+
+void
+applicationPutChar(hh, vv, charCode)
+int hh;
+int vv;
+int charCode;
+{
+ register struct glyph *g;
+ int x,y;
+ int key;
+ Pixrect *image;
+
+ key = dviCurrentFont -> family;
+
+ g = shrunkenGlyphs[currentShrink][key][charCode];
+
+ if (g == 0) {
+
+ MprData *newMpr = (MprData *) malloc(sizeof(MprData));
+ Pixrect *newPixrect = (Pixrect *) malloc(sizeof(Pixrect));
+ extern struct pixrectops mem_ops;
+
+ g = dviShrinkGlyph(dviCurrentFont -> f -> f_gly[charCode],
+ shrinkFactor[currentShrink],
+ shrinkFactor[currentShrink]);
+ shrunkenGlyphs[currentShrink][key][charCode] = g;
+
+ newMpr -> md_linebytes = SHRUNK_GLYPH_BYTES_WIDE(g);
+ newMpr -> md_image = (short *) g -> g_raster;
+ newMpr -> md_offset.x = 0;
+ newMpr -> md_offset.y = 0;
+ newMpr -> md_primary = 0;
+ newMpr -> md_flags = 0;
+
+ newPixrect -> pr_ops = &mem_ops;
+ newPixrect -> pr_size.x = g -> g_width;
+ newPixrect -> pr_size.y = g -> g_height;
+ newPixrect -> pr_depth =1;
+ newPixrect -> pr_data = (caddr_t) newMpr;
+ shrunkenPixrect[currentShrink][key][charCode] = newPixrect;
+ }
+
+ if (g == 0 || !HASRASTER(g)) return;
+
+ hh /= shrinkFactor[currentShrink];
+ vv /= shrinkFactor[currentShrink];
+
+ x = hh - g -> g_xorigin;
+ y = vv - g -> g_yorigin;
+
+ image = shrunkenPixrect[currentShrink][key][charCode];
+
+ if (buildToPixmap) {
+ pr_rop(pasteUpPixmap[currentShrink][currentLeaf],
+ x,y,
+ g->g_width, g->g_height,
+ foregroundMode,
+ image,
+ 0,0);
+ } else {
+ x += currentLeaf * leaf_w[currentShrink];
+ pw_write(ptube,
+ x, y,
+ g->g_width, g->g_height,
+ foregroundMode,
+ image,
+ 0,0);
+ }
+}
+
+void
+applicationSetRule(hh, vv, h, w)
+int hh, vv;
+int h, w;
+{
+/* (w,h) specifies lower left corner of rule box */
+ int nh, nw;
+
+ hh /= shrinkFactor[currentShrink];
+ vv /= shrinkFactor[currentShrink];
+
+ nh = h / shrinkFactor[currentShrink];
+ nw = w / shrinkFactor[currentShrink];
+
+ if (nh == 0 && h != 0) {
+ nh = 1;
+ }
+ if (nw == 0 && w != 0) {
+ nw = 1 ;
+ }
+
+ put_rectangle(hh, vv - nh, nw, nh, setMode);
+}
+
+/*
+ * This code attempts to support the same set of specials
+ * as imagen1
+ */
+static char *
+skipWhite(c)
+char *c;
+{
+ while (c != 0 && *c != 0 && isspace(*c)) c++;
+ return(c);
+}
+
+static char *
+skipNonWhite(c)
+char *c;
+{
+ while (c != 0 && *c != 0 && ! isspace(*c)) c++;
+ return(c);
+}
+
+#define MAX_POINTS 128
+static int pointListCount = 0;
+static struct pr_pos pointList[MAX_POINTS];
+
+static struct pr_brush specialBrush = {1};
+
+void
+applicationDoSpecial(command)
+char *command;
+{
+ char com[20];
+ int x,y;
+ char *c, *oc;
+
+ c = skipWhite(command);
+ if (*c == 0) return;
+
+ oc = c;
+ c = skipNonWhite(c);
+ x = *c;
+ *c = '\000';
+ strncpy(com, oc, 20);
+ *c = x;
+ c++;
+
+ if (strcmp(com, "pa") == 0) {
+ sscanf(c, " %d %d ", &x, &y);
+ pointList[pointListCount].x =
+ (specialConv * x + dviHH) / shrinkFactor[currentShrink];
+ pointList[pointListCount].y =
+ (specialConv * y + dviVV) / shrinkFactor[currentShrink];
+
+ if (! buildToPixmap) {
+ pointList[pointListCount].x += currentLeaf * leaf_w[currentShrink];
+ }
+
+ pointListCount++;
+
+/*
+ * Make all lines styles come out as a simple line.
+ * Crude, but effective.
+ */
+
+ } else if (strcmp(com, "fp") == 0
+ || strcmp(com,"da") == 0
+ || strcmp(com,"dt") == 0) {
+ if (pointListCount > 0) {
+
+ int fx,fy;
+ int tx,ty;
+ int i;
+
+ fx = pointList[0].x;
+ fy = pointList[0].y;
+
+ for (i = 0; i < pointListCount; i++) {
+ tx = pointList[i].x;
+ ty = pointList[i].y;
+ if (buildToPixmap) {
+ pr_vector(pasteUpPixmap[currentShrink][currentLeaf],
+ fx, fy, tx, ty, foregroundMode, -1);
+ } else {
+ pw_vector(ptube,
+ fx, fy, tx, ty, foregroundMode, -1);
+ }
+ fx = tx;
+ fy = ty;
+ }
+ }
+ pointListCount = 0;
+
+ } else if (strcmp(com, "pn") == 0) {
+ int penSize;
+ sscanf(c," %d ", &penSize);
+ penSize /= (shrinkFactor[currentShrink] * 2); /* looks good */
+ penSize = MAXFUNC(penSize,1);
+ penSize = MINFUNC(penSize,99);
+/*
+ * We dont do anything with this
+ */
+
+ } else {
+
+/*
+ * For now, lets just flush the special
+ */
+ pointListCount = 0;
+ fprintf(stderr, "[%s] special \"%s\" not implemented\n",
+ ProgName, command);
+ }
+}
+
+ptubeInit()
+{
+ struct inputmask mask;
+
+ ptube = canvas_pixwin(ptubeWindow);
+
+ if (ptube == (Pixwin *) NULL) {
+ fprintf(stderr,"Couldn't create ptube pixwin\n");
+ stop_output(0);
+ }
+
+ obscured = 1; /* SunTools does auto-save-unders */
+ globalDisplayState = SHRINK_NORMAL;
+
+ resizeCanvas(ptube,
+ (int) window_get(ptube, CANVAS_WIDTH),
+ (int) window_get(ptube, CANVAS_HEIGHT));
+
+ allocatePixmaps();
+ dviCurrentPage = firstPage;
+ buildLeaf(LEAF_LEFT, dviCurrentPage, SHRINK_NORMAL);
+
+ if (Leaves == 2) {
+ buildLeaf(LEAF_RIGHT, dviCurrentPage + 1, SHRINK_NORMAL);
+ }
+ globalArg = 0;
+ globalNumber = 0;
+}
+
+/* respond to damage to ptube subwindow */
+static int
+ptubeSighandler(sw)
+caddr_t sw;
+{
+ displayLeaves();
+}
+
+static int
+ptubeSelected(win, inputEvent, arg)
+ Window *win;
+ Event *inputEvent;
+ caddr_t arg;
+{
+ int ch;
+
+ int repaint;
+ int rebuild;
+
+#define BOGUSDIR -1
+#define FOREWARD 0
+#define BACKWARD 1
+#define ABSOLUTE 2
+
+ int direction;
+
+ Event *ie;
+
+ repaint = 1;
+ rebuild = 0;
+ direction = BOGUSDIR;
+
+ ie = inputEvent;
+
+ switch(event_id(ie)) {
+
+ case BUT(1) :
+ case BUT(2) :
+ case BUT(3):
+ if (event_is_down(ie)) { /* button going down? */
+ int leaf;
+ int normalLeafW = leaf_w[SHRINK_NORMAL];
+ int leafX;
+ int leafY;
+ int lastLeaf = -1;
+
+ int x = event_x(ie);
+ int y = event_y(ie);
+
+/*
+ * Determine which leaf was pointed to & where we will display it
+ */
+ leaf = x / normalLeafW;
+ if (leaf < 0 || leaf >= Leaves) {
+ leaf = Leaves - 1;
+ }
+
+ lastLeaf = leaf;
+
+ if (Leaves == 1) {
+ globalOtherLeaf = leaf;
+ } else {
+ globalOtherLeaf = 1 - leaf;
+ }
+
+/*
+ * Build the enlarged page if its not already there
+ */
+ if (haveLargePage[leaf] != pageOnLeaf[leaf]) {
+ buildLeaf(leaf, pageOnLeaf[leaf], SHRINK_LARGE);
+ haveLargePage[leaf] = pageOnLeaf[leaf];
+ }
+
+ leafX = (x - (leaf * normalLeafW));
+ leafX = (leafX * shrinkFactor[SHRINK_NORMAL])
+ / shrinkFactor[SHRINK_LARGE];
+
+ leafY = (y * shrinkFactor[SHRINK_NORMAL])
+ / shrinkFactor[SHRINK_LARGE];
+
+ globalLeafX = leafX;
+ globalLeafY = leafY;
+ globalDisplayLeaf = leaf;
+ globalDisplayState = SHRINK_LARGE;
+ displayLeaves();
+ } else {
+ globalDisplayState = SHRINK_NORMAL;
+ displayLeaves();
+ }
+ return;
+
+ case 'q':
+ case '\003': /* control-C */
+ case '\004': /* control-D */
+ stop_output(0);
+ break;
+
+ case 'n':
+ case 'f':
+ case ' ':
+ case '\n' :
+ case '\r' :
+ /* scroll forward */
+ direction = FOREWARD;
+ rebuild = 1;
+ break;
+
+ case 'p':
+ case 'b':
+ case '\b':
+ case 0177 : /* DEL */
+ /* scroll backward */
+ direction = BACKWARD;
+ rebuild = 1;
+ break;
+
+ case '\f':
+ case 'r' :
+ /* repaint current page */
+ repaint = 1;
+ break;
+
+ case 'g':
+ /* go to absolute page */
+ direction = ABSOLUTE; /* may not be, but tough */
+ rebuild = 1;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (! globalArg) {
+ globalArg = 1;
+ globalSign = 1;
+ globalNumber = 0;
+ }
+ globalNumber = 10*globalNumber + (event_id(ie) - '0');
+ return;
+
+ case '-':
+ if (! globalArg) {
+ globalArg = 1;
+ globalSign = -1;
+ globalNumber = 0;
+ repaint = 0;
+ return;
+ } else
+ goto bad;
+ default:
+ goto bad;
+ }
+
+ if (rebuild && direction != BOGUSDIR) {
+ int newLeft;
+ int newRight;
+/*
+ * canonicalize the request. globalArg is always > 0, were moving in
+ * some direction.
+ */
+
+ if (globalArg == 0 || globalNumber == 0) {
+ globalNumber = 1;
+ }
+
+ globalNumber = globalNumber * globalSign;
+
+ if (globalNumber < 0) {
+ if (direction == FOREWARD) {
+ direction = BACKWARD;
+ } else if (direction == BACKWARD){
+ direction = FOREWARD;
+ }
+ globalNumber = -globalNumber;
+ }
+
+/*
+ * Turn pages
+ */
+ if (direction == BACKWARD) {
+ newLeft = pageOnLeaf[LEAF_LEFT] - globalNumber;
+ } else if (direction == FOREWARD) {
+ newLeft = pageOnLeaf[LEAF_LEFT] + globalNumber;
+ } else {
+ newLeft = globalNumber - 1; /* pages globalNumbered at 0 */
+ }
+
+ newLeft = MINFUNC(newLeft, dviTotalPages-1);
+ newLeft = MAXFUNC(newLeft, 0);
+
+ if (Leaves == 1) {
+ if (newLeft != pageOnLeaf[LEAF_LEFT]) {
+ buildLeaf(LEAF_LEFT, newLeft, SHRINK_NORMAL);
+ }
+ } else {
+ newRight = newLeft + 1;
+
+ if (pageOnLeaf[LEAF_LEFT] != newLeft) {
+ if (newLeft == pageOnLeaf[LEAF_RIGHT]) {
+ swapLeaf(LEAF_RIGHT, LEAF_LEFT);
+ } else if (newRight == pageOnLeaf[LEAF_LEFT]) {
+ swapLeaf(LEAF_LEFT, LEAF_RIGHT);
+ }
+
+ if (pageOnLeaf[LEAF_LEFT] != newLeft) {
+ buildLeaf(LEAF_LEFT, newLeft, SHRINK_NORMAL);
+ }
+
+ if (pageOnLeaf[LEAF_RIGHT] != newRight) {
+ buildLeaf(LEAF_RIGHT, newRight, SHRINK_NORMAL);
+ }
+ }
+ }
+/*
+ * Only repaint it if we need to
+ */
+ }
+
+ displayLeaves();
+
+ globalArg = 0;
+ globalNumber = 0;
+
+ return;
+
+ bad:
+
+ globalArg = 0; /* throw away numeric globalArgument */
+ return;
+
+}
+
+put_border(x, y, w, h, t)
+int x, y, w, h, t;
+{
+ put_rectangle(x, y, w, t, setMode);
+ put_rectangle(x, y, t, h, setMode);
+ put_rectangle(x, y + h - t, w, t, setMode);
+ put_rectangle(x + w - t, y, t, h, setMode);
+}
+
+put_rectangle(x, y, w, h, pix)
+int x, y, w, h;
+int pix;
+{
+ if (buildToPixmap) {
+ pr_rop(pasteUpPixmap[currentShrink][currentLeaf],
+ x,y,
+ w,h,
+ pix,
+ pasteUpPixmap[currentShrink][currentLeaf],
+ 0, 0);
+ } else {
+ pw_write(ptube,
+ x + currentLeaf * leaf_w[currentShrink],y,
+ w,h,
+ pix,
+ ptube, 0, 0);
+ }
+}
+
+
diff --git a/dviware/umddvi/previewers/texx.1 b/dviware/umddvi/previewers/texx.1
new file mode 100644
index 0000000000..a23ef143a1
--- /dev/null
+++ b/dviware/umddvi/previewers/texx.1
@@ -0,0 +1,36 @@
+.TH TEXX 1
+.SH NAME
+texx \- view DVI files on your X-11 window
+.SH SYNOPSIS
+.B texx
+.B [many options]
+.B filename
+.SH DESCRIPTION
+.I Texx
+takes a DVI file produced by TeX and converts it to a format suitable
+an X-11 window.
+.I filename
+should be the name of a
+.B .dvi
+file.
+The environment and commands for
+.I texx
+are too complicated to explain in man page.
+Users should consult the Dvi Output Guide.
+.SH DIAGNOSTICS
+Most of these should be self explanatory.
+.SH AUTHOR
+Dirk Grunwald, Univ. of Illinois
+.br
+.I Texx
+uses a library of routines written by
+Chris Torek, University of Maryland
+.SH FILES
+/usr/local/texx
+.br
+.SH "SEE ALSO"
+iptex(1), dviselect(1), tex(1)
+.SH BUGS
+.I Still
+needs to handle more ``\especial''s.
+
diff --git a/dviware/umddvi/previewers/texx.c b/dviware/umddvi/previewers/texx.c
new file mode 100644
index 0000000000..feaf524b29
--- /dev/null
+++ b/dviware/umddvi/previewers/texx.c
@@ -0,0 +1,1382 @@
+/*
+ * 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, altough it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warrenty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ */
+#include <sys/types.h>
+#include <X/Xlib.h>
+#include <X/Xutil.h>
+#include <X/cursorfont.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "dvistuff.h"
+/*
+ * These constants may need to be changed on your implementation
+ */
+
+#define BitsPerByte 8
+#define BitsPerShort 16
+#define BytesPerShort (sizeof(short))
+
+#define BitsPerByteMask 0x7
+#define BitsPerByteShift 3
+
+#define BytesPerShot 2
+/*
+ * Note that ROUNDUP evaluates Y twice.
+ */
+#define ROUNDUP(x,y) (((x)+(y)-1) / (y))
+
+
+
+int debug = 0;
+static int obscured = 1;
+
+
+/*
+ * X-11 related variables
+ */
+
+Display *DISP;
+static Window win;
+static int backpix;
+static GC highpix, forepix;
+static GC specialGC;
+static int defaultScreen;
+
+static Cursor workingCursor;
+static Cursor readyCursor;
+
+/*
+ * TeX-Dvi related variables
+ */
+
+static int rawDviHeight;
+static int rawDviWidth; /* part of X interface, not dvistuff */
+static int maxHeight;
+static int maxWidth;
+
+static int screenWidth, screenHeight;
+
+#define MAX_LEAVES 2
+#define LEAF_LEFT 0
+#define LEAF_RIGHT 1
+
+static int Leaves;
+static int currentLeaf = 0;
+static int pageOnLeaf[MAX_LEAVES] = {-1,-1};
+static int haveLargePage[MAX_LEAVES] = {-1, -1};
+
+#define SHRINK_NORMAL 0
+#define SHRINK_LARGE 1
+#define MAX_SHRINKS 2
+
+static int page_w[MAX_SHRINKS], page_h[MAX_SHRINKS];
+static int leaf_w[MAX_SHRINKS];
+
+static int shrinkFactor[MAX_SHRINKS];
+static int currentShrink;
+static struct glyph **shrunkenGlyphs[MAX_SHRINKS][MAX_FONTFAMILY];
+static XImage **shrunkenImages[MAX_SHRINKS][MAX_FONTFAMILY];
+
+static int reverse = 0;
+
+static double specialConv;
+
+char *malloc(), *calloc(), *index();
+
+#define MAX(a,b) ((a) < (b)) ? (b) : (a)
+#define MIN(a,b) ((a) < (b)) ? (a) : (b)
+
+/*
+ * I don't know why this is needed, but our sun seems to thing
+ * and is or & vice versa
+ */
+
+#ifdef mc68000
+#define GXAND GXand
+#define GXOR GXor
+#else
+#define GXAND GXor
+#define GXOR GXand
+#endif
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+
+ int xargc=argc;
+ char **xargv=argv;
+
+ char *file;
+ char *display = NULL;
+ char *option;
+
+ int bwidth = 2;
+ char *fore_color;
+ char *back_color;
+ char *high_color;
+ char *brdr_color;
+ char *mous_color;
+ char *geometry = NULL, def[32];
+
+ int bdrpix, mouspix;
+ XColor cdef;
+ XSizeHints hints;
+ XSetWindowAttributes xswattrs;
+ unsigned long xswattrs_mask;
+
+ double atof();
+
+ char *getenv();
+
+ ProgName = *argv;
+ argv++;
+ argc--;
+
+ if ((DISP = XOpenDisplay(display)) == NULL) {
+
+ fprintf(stderr, "[%s] Can't open display '%s'\n",
+ ProgName, XDisplayName(display));
+ exit(1);
+ }
+
+ if ((option = XGetDefault(DISP, ProgName, "ReverseVideo")) &&
+ strcmp(option, "on") == 0)
+ reverse = 1;
+ if (option = XGetDefault(DISP, ProgName, "BorderWidth"))
+ bwidth = atoi(option);
+ fore_color = XGetDefault(DISP, ProgName, "ForeGround");
+ back_color = XGetDefault(DISP, ProgName, "BackGround");
+ high_color = XGetDefault(DISP, ProgName, "Highlight");
+ brdr_color = XGetDefault(DISP, ProgName, "Border");
+ mous_color = XGetDefault(DISP, ProgName, "Mouse");
+
+ option = XGetDefault(DISP, ProgName, "NormalShrink");
+ shrinkFactor[SHRINK_NORMAL] = (option == 0) ? 0 : atoi(option);
+
+ option = XGetDefault(DISP, ProgName, "LargeShrink");
+ shrinkFactor[SHRINK_LARGE] = (option == 0) ? 0 : atoi(option);
+
+ option = XGetDefault(DISP, ProgName, "Blackness");
+ dviBlackness = (option == 0) ? DEFAULT_BLACKNESS : atoi(option);
+
+ option = XGetDefault(DISP, ProgName, "Leaves");
+ Leaves = (option == 0) ? 0 : atoi(option);
+
+ option = XGetDefault(DISP, ProgName, "Dpi");
+ dviDPI = (option == 0) ? DEFAULT_DPI : atoi(option);
+
+ option = XGetDefault(DISP, ProgName, "TopMargin");
+ dviVVMargin = (option == 0) ? DEFAULT_VVMARGIN : atof(option) * dviDPI;
+
+ option = XGetDefault(DISP, ProgName, "SideMargin");
+ dviHHMargin = (option == 0) ? DEFAULT_HHMARGIN : atof(option) * dviDPI;
+
+ file = NULL;
+
+ while (argc) {
+ if (strcmp(*argv, "-p") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviDPI = atoi(*argv);
+ if (dviDPI <= 0) goto usage;
+ } else if (strcmp(*argv, "-rv") == 0) {
+ reverse = !reverse;
+ } else if (strcmp(*argv, "-bw") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ bwidth = atoi(*argv);
+ } else if (strcmp(*argv, "-fg") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ fore_color = *argv;
+ } else if (strcmp(*argv, "-bg") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ back_color = *argv;
+ } else if (strcmp(*argv, "-hl") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ high_color = *argv;
+ } else if (strcmp(*argv, "-bd") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ brdr_color = *argv;
+ } else if (strcmp(*argv, "-ms") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ mous_color = *argv;
+ } else if (strcmp(*argv,"-l") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ Leaves = atoi(*argv);
+ if( Leaves < 1 || Leaves > MAX_LEAVES) {
+ fprintf(stderr,"[%s] Bad number of leaves(%d), using %d\n",
+ ProgName, Leaves, MAX_LEAVES);
+ Leaves = MAX_LEAVES;
+ }
+ } else if (strcmp(*argv,"-ns") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ shrinkFactor[SHRINK_NORMAL] = atoi(*argv);
+ } else if (strcmp(*argv,"-ls") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ shrinkFactor[SHRINK_LARGE] = atoi(*argv);
+ } else if (strcmp(*argv,"-bl") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviBlackness = atoi(*argv);
+ } else if (strcmp(*argv,"-dpi") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviDPI = atoi(*argv);
+ } else if (strcmp(*argv,"-tm") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviVVMargin = dviDPI * atof(*argv);
+ } else if (strcmp(*argv,"-sm") == 0 && argc > 1) {
+ argv++;
+ argc--;
+ dviHHMargin = dviDPI * atof(*argv);
+ } else if (**argv == '=') {
+ geometry = *argv;
+ } else if (**argv != '-') {
+ if (index(*argv, ':') != NULL)
+ display = *argv;
+ else
+ file = *argv;
+ } else {
+ usage:
+ fprintf(stderr, "Usage: %s [-s <shrink>] [-l <leaves>] [-rv] [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] [-ms <color>] [=<geometry>] [host:display] dviFile\n",
+ ProgName);
+ exit(1);
+ }
+ argv++;
+ argc--;
+ }
+ if (file == NULL)
+ goto usage;
+ if ((dviFile = fopen(file, "r")) == NULL) {
+ int n = strlen(file);
+ char *dvi_name;
+
+ if (strcmp(file + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+ perror(file);
+ exit(1);
+ }
+ dvi_name = malloc((unsigned) n + sizeof(".dvi"));
+ sprintf(dvi_name, "%s.dvi", file);
+ if ((dviFile = fopen(dvi_name, "r")) == NULL) {
+ perror(dvi_name);
+ exit(1);
+ }
+ }
+
+ dviInit();
+
+ specialConv = (float) dviDPI / 1000.0;
+
+/*
+ * If no shrink factor was chosen, pick one which will work out nicely
+ * on their display
+ */
+
+ defaultScreen = XDefaultScreen(DISP);
+
+ maxHeight = XDisplayHeight(DISP, defaultScreen) - 2 * bwidth;
+ maxWidth = XDisplayWidth(DISP, defaultScreen) - 2 * bwidth;
+
+ rawDviHeight = dviTallestPage + 2 * dviVVMargin;
+ rawDviWidth = dviWidestPage + 2 * dviHHMargin;
+
+ if (Leaves == 0) {
+ if (dviTotalPages == 1) {
+ Leaves = 1;
+ } else {
+ Leaves = 2;
+ }
+ }
+
+ if (shrinkFactor[SHRINK_NORMAL] == 0) {
+ int sH;
+ int sW;
+ int sH2;
+ int sW2;
+ int shrink2;
+
+ sH = (rawDviHeight + maxHeight - 1) / maxHeight;
+ sW = (Leaves * rawDviWidth + maxWidth - 1) / maxWidth;
+
+ shrinkFactor[SHRINK_NORMAL] = MAX(sW, sH);
+ shrinkFactor[SHRINK_NORMAL] = MAX(shrinkFactor[SHRINK_NORMAL], 1);
+
+/*
+ * Check to see if we can get another shrink size bigger display
+ * if we cut the margins.
+ */
+
+ sH2 = (dviTallestPage + (dviHHMargin/32) + maxHeight - 1)
+ / maxHeight;
+ sW2 = ( Leaves * (dviWidestPage + (dviVVMargin/32))
+ + maxHeight - 1) / maxHeight;
+
+ shrink2 = MAX(sH2, sW2);
+ shrink2 = MAX(shrink2, 1);
+
+ if (shrink2 < shrinkFactor[SHRINK_NORMAL]) {
+ dviVVMargin /= 32;
+ dviHHMargin /= 32;
+ rawDviHeight = dviTallestPage + 2 * dviVVMargin;
+ rawDviWidth = dviWidestPage + 2 * dviHHMargin;
+ shrinkFactor[SHRINK_NORMAL] = shrink2;
+ }
+ }
+
+ page_h[SHRINK_NORMAL]=(rawDviHeight + shrinkFactor[SHRINK_NORMAL] - 1)
+ / shrinkFactor[SHRINK_NORMAL];
+ leaf_w[SHRINK_NORMAL]=(rawDviWidth + shrinkFactor[SHRINK_NORMAL] - 1)
+ / shrinkFactor[SHRINK_NORMAL];
+
+/*
+ * Based on the shrink factor, choose a shrink factor for the enlarged
+ * display
+ */
+
+ if (shrinkFactor[SHRINK_LARGE] == 0) {
+ shrinkFactor[SHRINK_LARGE] = shrinkFactor[SHRINK_NORMAL] / 2;
+ }
+
+ shrinkFactor[SHRINK_LARGE] = MIN(shrinkFactor[SHRINK_LARGE],
+ shrinkFactor[SHRINK_NORMAL]-1);
+ shrinkFactor[SHRINK_LARGE] = MAX(shrinkFactor[SHRINK_LARGE], 1);
+
+ page_h[SHRINK_LARGE]=(rawDviHeight + shrinkFactor[SHRINK_LARGE] - 1)
+ / shrinkFactor[SHRINK_LARGE];
+ leaf_w[SHRINK_LARGE]=(rawDviWidth + shrinkFactor[SHRINK_LARGE] - 1)
+ / shrinkFactor[SHRINK_LARGE];
+
+/*
+ * Compute the page size given the number of leaves. We may have
+ * to scale back if everything can't fit.
+ */
+
+ if (leaf_w[SHRINK_NORMAL] * Leaves <= maxWidth) {
+ page_w[SHRINK_NORMAL] = leaf_w[SHRINK_NORMAL] * Leaves;
+ } else {
+ page_w[SHRINK_NORMAL] = leaf_w[SHRINK_NORMAL];
+ Leaves = 1;
+ }
+
+ screenWidth = (page_w[SHRINK_NORMAL] > maxWidth)
+ ? maxWidth : page_w[SHRINK_NORMAL];
+ screenHeight = (page_h[SHRINK_NORMAL] > maxHeight)
+ ? maxHeight : page_h[SHRINK_NORMAL];
+
+ highpix = XCreateGC(DISP, RootWindow(DISP, defaultScreen), 0, NULL);
+ forepix = XCreateGC(DISP, RootWindow(DISP, defaultScreen), 0, NULL);
+
+ XCopyGC(DISP, DefaultGC(DISP, 0), (1L<<(GCLastBit+1))-1, highpix);
+ XCopyGC(DISP, highpix, (1L<<(GCLastBit+1))-1, forepix);
+
+ if (reverse) {
+
+ XSetForeground(DISP, forepix, WhitePixel(DISP, defaultScreen));
+ XSetForeground(DISP, highpix, WhitePixel(DISP, defaultScreen));
+ backpix = BlackPixel(DISP, defaultScreen);
+ bdrpix = WhitePixel(DISP, defaultScreen);
+ mouspix = WhitePixel(DISP, defaultScreen);
+ XSetFunction(DISP, forepix, GXAND); /* or */
+ XSetFunction(DISP, highpix, GXAND);
+
+ } else {
+
+ XSetForeground(DISP, forepix, BlackPixel(DISP, defaultScreen));
+ XSetForeground(DISP, highpix, BlackPixel(DISP, defaultScreen));
+ backpix = WhitePixel(DISP, defaultScreen);
+ bdrpix = BlackPixel(DISP, defaultScreen);
+ mouspix = BlackPixel(DISP, defaultScreen);
+ XSetFunction(DISP, forepix, GXOR); /* and */
+ XSetFunction(DISP, highpix, GXOR);
+ }
+
+ if (DisplayCells(DISP, 0) > 2) {
+ Colormap dcm = DefaultColormap(DISP, defaultScreen);
+ if (fore_color
+ && XParseColor(DISP, dcm, fore_color, &cdef)
+ && XAllocColor(DISP, dcm, &cdef)) {
+ XSetForeground(DISP, forepix, cdef.pixel);
+ }
+
+ if (back_color
+ && XParseColor(DISP, dcm, back_color, &cdef)
+ && XAllocColor(DISP, dcm, &cdef)) {
+ backpix = cdef.pixel;
+ }
+
+ if (high_color
+ && XParseColor(DISP, dcm, high_color, &cdef)
+ && XAllocColor(DISP, dcm, &cdef)) {
+ XSetForeground(DISP, highpix, cdef.pixel);
+ }
+
+ if (brdr_color
+ && XParseColor(DISP, dcm, brdr_color, &cdef)
+ && XAllocColor(DISP, dcm, &cdef))
+ {
+ /* null statement? */
+ }
+
+ if (mous_color
+ && XParseColor(DISP, dcm, mous_color, &cdef)
+ && XAllocColor(DISP, dcm, &cdef)) {
+ mouspix = cdef.pixel;
+ }
+ }
+
+ XSetBackground(DISP, forepix, backpix);
+ XSetBackground(DISP, highpix, backpix);
+
+ sprintf(def, "=%dx%d+0+0", screenWidth, screenHeight);
+
+ hints.width = page_w[SHRINK_NORMAL];
+ hints.height = page_h[SHRINK_NORMAL];
+ hints.x = 0; hints.y = 0;
+ hints.flags = (PSize | PPosition);
+
+ xswattrs.border_pixel = bdrpix;
+ xswattrs.background_pixel = backpix;
+ xswattrs_mask = (CWBackPixel|CWBorderPixel);
+
+ win = XCreateWindow(DISP, RootWindow(DISP, defaultScreen),
+ 0, 0,
+ screenWidth, screenHeight,
+ bdrpix,
+ 0, /* depth from parent */
+ InputOutput,
+ CopyFromParent,
+ xswattrs_mask,
+ &xswattrs);
+
+ XSetStandardProperties(DISP, win,
+ ProgName, "DVI Previewer",
+ None,
+ argv, argc, &hints);
+
+ XMapRaised(DISP, win);
+ XSelectInput(DISP, win,
+ KeyPressMask|ButtonPressMask | ButtonReleaseMask
+ |ExposureMask | VisibilityChangeMask);
+
+ workingCursor = XCreateFontCursor(DISP, XC_watch);
+ readyCursor = XCreateFontCursor(DISP, XC_spraycan);
+
+ XDefineCursor(DISP, win, workingCursor);
+ XFlush(DISP);
+
+ specialGC = XCreateGC(DISP, RootWindow(DISP, defaultScreen), 0, NULL);
+ XCopyGC(DISP, forepix, (1L<<(GCLastBit+1))-1, specialGC);
+
+ mainLoop();
+ stop_output(0);
+}
+
+/*
+ * Pixmap manipulation routines
+ */
+
+static Pixmap pasteUpPixmap[MAX_SHRINKS][MAX_LEAVES];
+static GC pasteFillGC;
+static GC pasteCopyGC;
+
+static int largePixmapsAllocated = 0;
+
+/*
+ * Ideally, we'd like to paint up a local pixmap & then transmit the
+ * entire pixmap. However, it looks like pixmaps require interaction
+ * with the server.
+ *
+ * So, if the entire page fits on the screen, we'll paint the screen
+ * and when we're done, we'll copy the screen to the pixmap. This
+ * gives the illusion of progress, but allows us to do fast re-paints.
+ *
+ * If we're *not* on the display, we'll just draw to the pixmap and
+ * update it at the end
+ */
+
+static int buildToPixmap = 1;
+
+static void
+clearPixmap(leaf, shrinkSize)
+int leaf;
+int shrinkSize;
+{
+ if (leaf< 0 || leaf >= Leaves) {
+ fprintf(stderr,"[%s] Reference to bogus leaf in clearPixmap: %d\n",
+ ProgName, leaf);
+ exit(1);
+ }
+
+ if (shrinkSize < 0 || shrinkSize >= MAX_SHRINKS ) {
+ fprintf(stderr,"[%s] reference to bogus shrink %d\n",
+ ProgName, shrinkSize);
+ exit(1);
+ }
+
+ XFillRectangle(DISP, pasteUpPixmap[shrinkSize][leaf], pasteFillGC, 0, 0,
+ leaf_w[shrinkSize], page_h[shrinkSize]);
+}
+
+static void
+clearWindow(leaf)
+int leaf;
+{
+ XFillRectangle(DISP, win, pasteFillGC,
+ leaf * leaf_w[SHRINK_NORMAL], 0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL]);
+}
+
+allocatePixmaps()
+{
+ int i;
+
+ for (i = 0; i < Leaves; i++ ) {
+ pasteUpPixmap[SHRINK_NORMAL][i] =
+ XCreatePixmap(DISP, win, leaf_w[SHRINK_NORMAL],
+ page_h[SHRINK_NORMAL], 1);
+
+ if (pasteUpPixmap[SHRINK_NORMAL][i] == 0) {
+ fprintf(stderr,"[%s] erp! out of PIXMAP memory!\n",
+ ProgName);
+ exit(1);
+ }
+ }
+
+ largePixmapsAllocated = 0;
+
+ if (pasteFillGC == 0) {
+ pasteFillGC = XCreateGC(DISP, RootWindow(DISP, defaultScreen),0,NULL);
+ pasteCopyGC = XCreateGC(DISP, RootWindow(DISP, defaultScreen),0,NULL);
+ XCopyGC(DISP, forepix, (1L<<(GCLastBit+1))-1, pasteFillGC);
+ XCopyGC(DISP, forepix, (1L<<(GCLastBit+1))-1, pasteCopyGC);
+ if (reverse) {
+ XSetForeground(DISP, pasteFillGC, BlackPixel(DISP, defaultScreen));
+ } else {
+ XSetForeground(DISP, pasteFillGC, WhitePixel(DISP, defaultScreen));
+ }
+ XSetFunction(DISP, pasteFillGC, GXcopy);
+ XSetFunction(DISP, pasteCopyGC, GXcopy);
+ }
+
+/*
+ * Clear the pixmap
+ */
+ for (i = 0; i < Leaves; i++) {
+ clearPixmap(i, SHRINK_NORMAL);
+ }
+}
+
+allocateLargePixmaps()
+{
+ int i;
+ for (i = 0; i < Leaves; i++) {
+ pasteUpPixmap[SHRINK_LARGE][i] =
+ XCreatePixmap(DISP, win, leaf_w[SHRINK_LARGE],
+ page_h[SHRINK_LARGE], 1);
+
+ clearPixmap(i, SHRINK_LARGE);
+ }
+
+ largePixmapsAllocated = 1;
+}
+
+/*
+ * display the normal sized leaf
+ */
+static void
+displayLeaves()
+{
+ int leaf;
+ XClearWindow(DISP,win);
+ for (leaf = 0; leaf < Leaves; leaf++) {
+ XCopyArea(DISP, pasteUpPixmap[SHRINK_NORMAL][leaf], win, forepix,
+ 0, 0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ leaf_w[SHRINK_NORMAL] * leaf, 0);
+ }
+}
+
+static void displayLeaf(leaf)
+int leaf;
+{
+ clearWindow(leaf);
+ XCopyArea(DISP, pasteUpPixmap[SHRINK_NORMAL][leaf], win, forepix,
+ 0, 0,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ leaf_w[SHRINK_NORMAL] * leaf, 0);
+}
+
+static void
+swapLeaf(from, to)
+int from;
+int to;
+{
+ Pixmap tempPix;
+ int tempNum;
+
+ if (to < 0 || to >= Leaves) {
+ fprintf(stderr,"[%s] bogus to leaf %d in swapLeaf\n",
+ ProgName, to);
+ exit(1);
+ }
+ if (from < 0 || from >= Leaves) {
+ fprintf(stderr,"[%s] bogus from leaf %d in swapLeaf\n",
+ ProgName, from);
+ exit(1);
+ }
+
+ tempPix = pasteUpPixmap[SHRINK_NORMAL][to];
+ pasteUpPixmap[SHRINK_NORMAL][to] = pasteUpPixmap[SHRINK_NORMAL][from];
+ pasteUpPixmap[SHRINK_NORMAL][from] = tempPix;
+
+ tempPix = pasteUpPixmap[SHRINK_LARGE][to];
+ pasteUpPixmap[SHRINK_LARGE][to] = pasteUpPixmap[SHRINK_LARGE][from];
+ pasteUpPixmap[SHRINK_LARGE][from] = tempPix;
+
+ tempNum = pageOnLeaf[to];
+ pageOnLeaf[to] = pageOnLeaf[from];
+ pageOnLeaf[from] = tempNum;
+
+ tempNum = haveLargePage[to];
+ haveLargePage[to] = haveLargePage[from];
+ haveLargePage[from] = tempNum;
+}
+
+static void
+buildLeaf(leaf, page, shrinkSize)
+int leaf;
+int page;
+int shrinkSize;
+{
+ XDefineCursor(DISP, win, workingCursor);
+
+ if (leaf < 0 || leaf >= Leaves) {
+ fprintf(stderr,"[%s] bogus leaf %d in buildLeaf\n",
+ ProgName, leaf);
+ exit(1);
+ }
+
+ if (shrinkSize < 0 || shrinkSize >= MAX_SHRINKS ) {
+ fprintf(stderr,"[%s] Bogus shrink size %d in buildLeaf\n",
+ ProgName, shrinkSize);
+ exit(1);
+ }
+
+ if (shrinkSize == SHRINK_LARGE && !largePixmapsAllocated) {
+ allocateLargePixmaps();
+ }
+
+/*
+ * If this is a normal size page, kill the information
+ * for the large version.
+ */
+ if (shrinkSize == SHRINK_NORMAL) {
+ haveLargePage[leaf] = -1;
+ }
+
+/*
+ * Determine if this is a valid page. If it's not, we'll just clear
+ * the particular leaf.
+ */
+
+ if (page < 0 || page >= dviTotalPages) {
+ clearPixmap(leaf, shrinkSize);
+
+ if (shrinkSize == SHRINK_NORMAL) {
+ clearWindow(leaf);
+ }
+ } else {
+
+ if (obscured || shrinkSize == SHRINK_LARGE) {
+ buildToPixmap = 1;
+ } else {
+ buildToPixmap = 0;
+ }
+
+ if (buildToPixmap) {
+ clearPixmap(leaf, shrinkSize);
+ } else {
+ clearPixmap(leaf, shrinkSize);
+ if (shrinkSize == SHRINK_NORMAL) {
+ clearWindow(leaf);
+ }
+ }
+
+/*
+ * Note that dviPreparePage may change dviCurrentPage
+ */
+
+ currentLeaf = leaf;
+ currentShrink = shrinkSize;
+
+ dviPreparePage(page);
+
+ page = dviCurrentPage;
+
+/*
+ * Save the constructed page if we were painting it to the screen
+ */
+ put_border(0, 0, leaf_w[currentShrink], page_h[currentShrink], 1);
+
+ if (! buildToPixmap && shrinkSize == SHRINK_NORMAL) {
+ XCopyArea(DISP, win, pasteUpPixmap[SHRINK_NORMAL][leaf], forepix,
+ leaf * leaf_w[currentShrink], 0,
+ screenWidth, screenHeight, 0,0);
+ } else if (shrinkSize == SHRINK_NORMAL) {
+ displayLeaf(leaf);
+ }
+ }
+
+ pageOnLeaf[leaf] = dviCurrentPage;
+ XDefineCursor(DISP, win, readyCursor);
+
+ XFlush(DISP);
+}
+
+/*
+ * interfaces to dvistuff
+ */
+
+/*
+ * Whenever a new font is registers, we create a shrunken Glyph
+ * table for it. However, we don't shrink the glyphs -- that's
+ * done on the fly by the putChar routine.
+ */
+
+DviFont *
+applicationNewFont(f, key)
+struct font *f;
+int key;
+{
+ int shrink;
+
+ if (key < 0 || key > MAX_FONTFAMILY) {
+ fprintf(stderr,"[%s] bogus key in Newfont = %d\n",
+ ProgName, key);
+ exit(1);
+ }
+
+ for (shrink = SHRINK_NORMAL; shrink <= SHRINK_LARGE; shrink++) {
+
+ if (shrunkenGlyphs[shrink][key] == 0) {
+ int lth = sizeof(struct glyph *) * MAX_GLYPH;
+ struct glyph **g;
+
+ g = (struct glyph **) malloc( lth );
+ bzero(g, lth);
+ shrunkenGlyphs[shrink][key] = g;
+ }
+
+ if (shrunkenImages[shrink][key] == 0) {
+ int lth = sizeof(XImage *) * MAX_GLYPH;
+ XImage **image;
+
+ image = (XImage **) malloc(lth);
+ bzero(image, lth);
+ shrunkenImages[shrink][key] = image;
+ }
+ }
+
+ return(f);
+}
+
+/*
+ * When we reset a font, we only need to free the storage for the
+ * shrunken glyphs. We keep the glyph table available because we're
+ * very likely to fill it in again.
+ */
+
+void
+applicationResetFont(fi, key)
+struct fontinfo *fi;
+int key;
+{
+ int i;
+ struct glyph **theseGlyphs;
+ XImage **theseImages;
+ int shrink;
+
+
+ for (shrink = SHRINK_NORMAL; shrink <= SHRINK_LARGE; shrink++) {
+ theseGlyphs = shrunkenGlyphs[shrink][key];
+ if (theseGlyphs != 0) {
+ for (i = 0; i < MAX_GLYPH; i++) {
+ struct glyph *g;
+
+ g = theseGlyphs[i];
+
+ if (g != 0) {
+ if ( g -> g_raster != 0) {
+ free(g -> g_raster);
+ }
+ free(g);
+ theseGlyphs[i] = 0;
+ }
+ }
+ }
+
+ theseImages = shrunkenImages[shrink][key];
+
+ if (theseImages != 0) {
+ for (i = 0; i < MAX_GLYPH; i++) {
+ if (theseImages[i] != 0) {
+ XDestroyImage(theseImages[i]);
+ }
+ theseImages[i] = 0;
+ }
+ }
+ }
+}
+
+
+void
+applicationPutChar(hh, vv, charCode)
+int hh;
+int vv;
+int charCode;
+{
+ register struct glyph *g;
+ int x,y;
+ XImage *image;
+ int key;
+
+ key = dviCurrentFont -> family;
+
+ g = shrunkenGlyphs[currentShrink][key][charCode];
+
+ if (g == 0) {
+ g = dviShrinkGlyph(dviCurrentFont -> f -> f_gly[charCode],
+ shrinkFactor[currentShrink],
+ shrinkFactor[currentShrink]);
+ shrunkenGlyphs[currentShrink][key][charCode] = g;
+ }
+
+ if (g == 0 || !HASRASTER(g)) return;
+
+ hh /= shrinkFactor[currentShrink];
+ vv /= shrinkFactor[currentShrink];
+
+ x = hh - g -> g_xorigin;
+ y = vv - g -> g_yorigin;
+
+ image = shrunkenImages[currentShrink][key][charCode];
+
+ if (image == 0 ) {
+ image = XCreateImage(DISP, DefaultVisual(DISP, defaultScreen),
+ 1, XYBitmap,
+ 0, g->g_raster,
+ g->g_width, g->g_height,
+ 16, 0);
+
+ shrunkenImages[currentShrink][key][charCode] = image;
+ }
+
+ if (buildToPixmap) {
+ XPutImage(DISP, pasteUpPixmap[currentShrink][currentLeaf],
+ forepix, image,
+ 0, 0,
+ x, y,
+ g->g_width, g->g_height);
+ } else {
+ XPutImage(DISP, win,
+ forepix, image,
+ 0, 0,
+ x + currentLeaf * leaf_w[currentShrink], y,
+ g->g_width, g->g_height);
+ }
+}
+
+void
+applicationSetRule(hh, vv, h, w)
+int hh, vv;
+int h, w;
+{
+/* (w,h) specifies lower left corner of rule box */
+ int nh, nw;
+
+ hh /= shrinkFactor[currentShrink];
+ vv /= shrinkFactor[currentShrink];
+
+ nh = h / shrinkFactor[currentShrink];
+ nw = w / shrinkFactor[currentShrink];
+
+ if (nh == 0 && h != 0) {
+ nh = 1;
+ }
+ if (nw == 0 && w != 0) {
+ nw = 1 ;
+ }
+
+ put_rectangle(hh, vv - nh, nw, nh, forepix);
+}
+
+/*
+ * This code attempts to support the same set of specials
+ * as imagen1
+ */
+static char *
+skipWhite(c)
+char *c;
+{
+ while (c != 0 && *c != 0 && isspace(*c)) c++;
+ return(c);
+}
+
+static char *
+skipNonWhite(c)
+char *c;
+{
+ while (c != 0 && *c != 0 && ! isspace(*c)) c++;
+ return(c);
+}
+
+#define MAX_POINTS 128
+static int pointListCount = 0;
+static XPoint pointList[MAX_POINTS];
+
+void
+applicationDoSpecial(command)
+char *command;
+{
+ char com[20];
+ int x,y;
+ char *c, *oc;
+
+ c = skipWhite(command);
+ if (*c == 0) return;
+
+ oc = c;
+ c = skipNonWhite(c);
+ x = *c;
+ *c = '\000';
+ strncpy(com, oc, 20);
+ *c = x;
+ c++;
+
+ if (strcmp(com, "pa") == 0) {
+ sscanf(c, " %d %d ", &x, &y);
+ pointList[pointListCount].x =
+ (specialConv * x + dviHH) / shrinkFactor[currentShrink];
+ pointList[pointListCount].y =
+ (specialConv * y + dviVV) / shrinkFactor[currentShrink];
+
+ if (! buildToPixmap) {
+ pointList[pointListCount].x += currentLeaf * leaf_w[currentShrink];
+ }
+
+ pointListCount++;
+
+/*
+ * Make all lines styles come out as a simple line.
+ * Crude, but effective.
+ */
+
+ } else if (strcmp(com, "fp") == 0
+ || strcmp(com,"da") == 0
+ || strcmp(com,"dt") == 0) {
+ if (pointListCount > 0) {
+
+ if (buildToPixmap) {
+ XDrawLines(DISP, pasteUpPixmap[currentShrink][currentLeaf],
+ specialGC, pointList, pointListCount,
+ CoordModeOrigin);
+ } else {
+ XDrawLines(DISP, win,
+ specialGC, pointList, pointListCount,
+ CoordModeOrigin);
+ }
+ }
+ pointListCount = 0;
+
+ } else if (strcmp(com, "pn") == 0) {
+ int penSize;
+ sscanf(c," %d ", &penSize);
+ penSize /= (shrinkFactor[currentShrink] * 2); /* looks good */
+ penSize = MAX(penSize,1);
+ penSize = MIN(penSize,99);
+ XSetLineAttributes(DISP, specialGC, penSize,
+ LineSolid, CapButt, JoinMiter);
+ } else {
+
+/*
+ * For now, lets just flush the special
+ */
+ fprintf(stderr, "[%s] special \"%s\" not implemented\n",
+ ProgName, command);
+ }
+}
+
+int
+mainLoop()
+{
+ int ch, arg, sign, number;
+ XEvent event;
+ XWindowAttributes query;
+
+ char trbuf[100];
+ char *string;
+ int nbytes=0;
+
+ int repaint;
+ int rebuild;
+
+#define BOGUSDIR -1
+#define FOREWARD 0
+#define BACKWARD 1
+#define ABSOLUTE 2
+
+ int direction;
+
+/*
+ *
+ * We need to initialized 'obscured'.
+ * Ideally, we would like to know if we are covered at all, but
+ * the best I can come up with is a way to determine if we're
+ * mapped. This works well for wm, uwm & no window manager at all.
+ */
+
+ XClearWindow(DISP,win);
+ XSync(DISP, 0);
+
+ XGetWindowAttributes(DISP, win, &query);
+ obscured = ! (query.map_state == IsViewable);
+
+ allocatePixmaps();
+ dviCurrentPage = 0;
+ buildLeaf(LEAF_LEFT, 0, SHRINK_NORMAL);
+
+ if (Leaves == 2) {
+ XGetWindowAttributes(DISP, win, &query); /* status changed? */
+ obscured = ! (query.map_state == IsViewable);
+ buildLeaf(LEAF_RIGHT, 1, SHRINK_NORMAL);
+ }
+
+ arg = 0;
+ number = 0;
+
+ for (;;) {
+
+ repaint = 1;
+ rebuild = 0;
+ direction = BOGUSDIR;
+
+ XDefineCursor(DISP, win, readyCursor);
+
+ bzero(&event, sizeof(event));
+ XNextEvent (DISP, &event);
+
+ string = "";
+
+ switch (event.type) {
+
+/*
+ * If were painting to the display, and were not completely
+ * visible, wed better really paint to the pixmap, otherwise,
+ * all the stuff painted in an obscured region wont be in the pixmap.
+ */
+
+ case VisibilityNotify:
+ obscured = (event.xvisibility.state != VisibilityUnobscured);
+ continue;
+
+ case Expose:
+ string = "\f";
+ nbytes = 1;
+ break;
+
+
+ case ButtonPress:
+ {
+ int leaf;
+ int otherLeaf;
+ int normalLeafW = leaf_w[SHRINK_NORMAL];
+ int leafX;
+ int leafY;
+ int lastLeaf = -1;
+
+ int x = event.xbutton.x;
+ int y = event.xbutton.y;
+ int lastButton = event.xbutton.button;
+
+/*
+ * Determine which leaf was pointed to & where we will display it
+ */
+ leaf = x / normalLeafW;
+ if (leaf < 0 || leaf >= Leaves) {
+ fprintf(stderr,"[%s] error in button press, leaf = %d\n",
+ ProgName, leaf);
+ exit(1);
+ }
+
+ if (leaf != lastLeaf && lastLeaf != -1) {
+ displayLeaf(lastLeaf);
+ }
+ lastLeaf = leaf;
+
+ if (Leaves == 1) {
+ otherLeaf = leaf;
+ } else {
+ otherLeaf = 1 - leaf;
+ }
+
+/*
+ * Build the enlarged page if its not already there
+*/
+ if (haveLargePage[leaf] != pageOnLeaf[leaf]) {
+ buildLeaf(leaf, pageOnLeaf[leaf], SHRINK_LARGE);
+ haveLargePage[leaf] = pageOnLeaf[leaf];
+ }
+
+/*
+ * Determine where he was looking, build a (x,y) such that
+ * the thing he was pointing at will be on the screen, as close to
+ * center as possible.
+ */
+
+ leafX = (x - (leaf * normalLeafW));
+ leafX = (leafX * shrinkFactor[SHRINK_NORMAL])
+ / shrinkFactor[SHRINK_LARGE];
+
+ leafX -= (leaf_w[SHRINK_NORMAL] / 2);
+ leafX = MAX(leafX, 0);
+ leafX = MIN(leafX, leaf_w[SHRINK_LARGE]);
+
+ leafY = (y * shrinkFactor[SHRINK_NORMAL])
+ / shrinkFactor[SHRINK_LARGE];
+
+ leafY -= (page_h[SHRINK_NORMAL] / 2);
+ leafY = MAX(leafY, 0);
+ leafY = MIN(leafY, page_h[SHRINK_LARGE]);
+
+/*
+ * Display the enlarged image on the leaf, wait for another
+ * button event (the release, we hope)& then restore the image as it was
+ */
+ clearWindow(otherLeaf);
+ XCopyArea(DISP, pasteUpPixmap[SHRINK_LARGE][leaf],
+ win, forepix,
+ leafX, leafY,
+ leaf_w[SHRINK_NORMAL], page_h[SHRINK_NORMAL],
+ leaf_w[SHRINK_NORMAL] * otherLeaf, 0);
+
+ bzero(&event, sizeof(event));
+ for(;;) {
+ XNextEvent(DISP, &event);
+ if (event.type == ButtonRelease
+ && event.xbutton.button == lastButton) {
+ break;
+ }
+ }
+ displayLeaf(otherLeaf);
+ break;
+ }
+
+ case ButtonRelease:
+ break;
+
+ case KeyPress:
+ string = trbuf;
+ nbytes = XLookupString(&event, string, 100, NULL, NULL);
+
+ break;
+ }
+
+ if (nbytes == 0) continue;
+
+ if (nbytes > 1) goto bad;
+
+ switch (ch = *string) {
+ case 'q':
+ case '\003': /* control-C */
+ case '\004': /* control-D */
+ stop_output(0);
+ break;
+
+ case 'n':
+ case 'f':
+ case ' ':
+ case '\n' :
+ case '\r' :
+ /* scroll forward */
+ direction = FOREWARD;
+ rebuild = 1;
+ break;
+
+ case 'p':
+ case 'b':
+ case '\b':
+ case 0177 : /* DEL */
+ /* scroll backward */
+ direction = BACKWARD;
+ rebuild = 1;
+ break;
+
+ case '\f':
+ case 'r' :
+ /* repaint current page */
+ repaint = 1;
+ break;
+
+ case 'g':
+ /* go to absolute page */
+ direction = ABSOLUTE; /* may not be, but tough */
+ rebuild = 1;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (! arg) {
+ arg = 1;
+ sign = 1;
+ number = 0;
+ }
+ number = 10*number + sign*(ch - '0');
+
+ repaint = 0;
+ continue;
+
+ case '-':
+ if (! arg) {
+ arg = 1;
+ sign = -1;
+ number = 0;
+ repaint = 0;
+ continue;
+ } else
+ goto bad;
+ default:
+ goto bad;
+ }
+
+ if (rebuild && direction != BOGUSDIR) {
+ int newLeft;
+ int newRight;
+/*
+ * canonicalize the request. arg is always > 0, were moving in
+ * some direction.
+ */
+
+ if (!arg || number == 0) {
+ number = 1;
+ }
+
+
+ if (number < 0) {
+ if (direction == FOREWARD) {
+ direction = BACKWARD;
+ } else if (direction == BACKWARD){
+ direction = FOREWARD;
+ }
+ number = -number;
+ }
+
+/*
+ * Turn pages back
+ */
+ if (direction == BACKWARD) {
+ newLeft = pageOnLeaf[LEAF_LEFT] - number;
+ } else if (direction == FOREWARD) {
+ newLeft = pageOnLeaf[LEAF_LEFT] + number;
+ } else {
+ newLeft = number - 1; /* pages numbered at 0 */
+ }
+
+ newLeft = MIN(newLeft, dviTotalPages-1);
+ newLeft = MAX(newLeft, 0);
+
+ if (Leaves == 1) {
+ if (newLeft != pageOnLeaf[LEAF_LEFT]) {
+ buildLeaf(LEAF_LEFT, newLeft, SHRINK_NORMAL);
+ }
+ } else {
+ newRight = newLeft + 1;
+
+ if (pageOnLeaf[LEAF_LEFT] != newLeft) {
+ if (newLeft == pageOnLeaf[LEAF_RIGHT]) {
+ swapLeaf(LEAF_RIGHT, LEAF_LEFT);
+ displayLeaf(LEAF_LEFT);
+ } else if (newRight == pageOnLeaf[LEAF_LEFT]) {
+ swapLeaf(LEAF_LEFT, LEAF_RIGHT);
+ displayLeaf(LEAF_RIGHT);
+ }
+
+ if (pageOnLeaf[LEAF_LEFT] != newLeft) {
+ buildLeaf(LEAF_LEFT, newLeft, SHRINK_NORMAL);
+ }
+
+ if (pageOnLeaf[LEAF_RIGHT] != newRight) {
+ buildLeaf(LEAF_RIGHT, newRight, SHRINK_NORMAL);
+ }
+ }
+ }
+ repaint = 0;
+ rebuild = 0;
+ arg = 0;
+/*
+ * Only repaint it if we need to
+ */
+ }
+
+ if (repaint){
+ displayLeaves();
+ repaint = 0;
+ }
+
+ continue;
+
+ bad:
+
+ arg = 0; /* throw away numeric argument */
+ continue;
+
+ }
+}
+
+stop_output(sig)
+{
+ exit(sig);
+}
+
+put_border(x, y, w, h, t)
+int x, y, w, h, t;
+{
+ put_rectangle(x, y, w, t, highpix);
+ put_rectangle(x, y, t, h, highpix);
+ put_rectangle(x, y + h - t, w, t, highpix);
+ put_rectangle(x + w - t, y, t, h, highpix);
+}
+
+put_rectangle(x, y, w, h, pix)
+int x, y, w, h;
+GC pix;
+{
+ if (buildToPixmap) {
+ XFillRectangle(DISP, pasteUpPixmap[currentShrink][currentLeaf],
+ pix, x, y, w, h);
+ } else {
+ XFillRectangle(DISP, win,
+ pix, x + currentLeaf * leaf_w[currentShrink], y, w, h);
+ }
+}
+
+
diff --git a/dviware/umddvi/previewers/texx2/00readme.tex b/dviware/umddvi/previewers/texx2/00readme.tex
new file mode 100644
index 0000000000..fed4bf42b0
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/00readme.tex
@@ -0,0 +1,62 @@
+% drivers/umddvi/texx2
+\index{previewers!X11}
+\par\begin{footnotesize}\begin{alltt}
+Contents of README files:\par
+Sorry, this file got let out of the original distribution.
+
+This directory contains several tools to manipulate the DVI files produced
+by TeX and LaTeX. Additionally, it includes a re-distribution of the
+DVI library routines written by Chris Torek at the University of Maryland.
+The utilities included are:
+
+dviselect select specific pages from a DVI file
+iptex print a dvi file on an Imagen
+texx a dvi previewer for X-11 windows
+texsun a dvi previewer for SunView windows
+
+texx2 a much improved dvi previewer for X-11 windows
+
+To install this package, read the documentation in the file
+doc/installation.tex. The short instructions follow.
+
+FOR TEXX2:
+
+ + Change the binary path names in the ./Makefile.
+
+ + Select a location for your ``font description'' file, and copy and
+ modify the file in fontdesc-example to suit your local installation.
+ Change the main makefile to use that path for variable FONTDESC
+
+ The default is /usr/local/lib/tex82/fontdesc
+
+ + cd to texx2; Edit the Imakefile. Note that DEFAULT_TFM_PATH
+ defines the default path for finding .tfm files, just like TeX.
+
+ + Build a Makefile from the Imakefile
+
+ + run ``make texx2'' at the main level
+
+ + texx2 should now be built. You'll need to install some fonts.
+
+ + in run texx2/mftobdf -mag 1000 -scaled 1000 cmr10. If mftobdf
+ can't find your font, you've got a bad fontdesc file or the
+ path to it is wrong.
+
+ + assuming that this works, edit texx2/buildfonts to suite your
+ local X configuration. I keep fonts in /usr/local/lib/X11/fonts/cmr,
+ and have added this to my font path using
+ % xset +fp /usr/local/lib/X11/fonts/cmr
+ % xset fp rehash
+
+ + in texx2, run "buildfonts -mag 500 `cat FONTS` " to build a
+ fair number of standard fonts. Note that the default is
+ 300 dpi. If you want a smaller set too, say ``-mag 333''.
+
+ + You can use other DPI's -- both texx2 & mftobdf have switches
+ for this.
+
+Dirk Grunwald
+Univ. of Illinois
+grunwald@m.cs.uiuc.edu
+
+\end{alltt}\end{footnotesize}\par
diff --git a/dviware/umddvi/previewers/texx2/buildfonts b/dviware/umddvi/previewers/texx2/buildfonts
new file mode 100644
index 0000000000..fa25079e55
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/buildfonts
@@ -0,0 +1,17 @@
+#!/bin/sh
+MFTOBDF=mftobdf
+FONTDIR=/u/tex/xfonts
+#
+${MFTOBDF} $*
+for file in *.bdf ;
+do
+ base=`echo $file | sed -e 's/.bdf//g'`
+ echo Process $base
+ bdftosnf $base.bdf > ${FONTDIR}/$base.snf
+ rm -f $base.bdf
+done
+#
+cd ${FONTDIR}
+mkfontdir
+xset +fp `pwd`
+xset fp rehash
diff --git a/dviware/umddvi/previewers/texx2/changelog b/dviware/umddvi/previewers/texx2/changelog
new file mode 100644
index 0000000000..a52c3ae90d
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/changelog
@@ -0,0 +1,123 @@
+Tue Feb 28 18:41:45 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * repackeged as 2.8.5
+
+ * (texx2-font.c) Calculation of mag ignored mag specified in
+ document. Fixed.
+
+ * (texx2-file.c) Made the file name be stuffed into the input box
+
+Sun Feb 26 16:44:46 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * Compensate for scroll-bars. Now, mag=333 on a sun3 gets rid
+ of horiz scroll.
+
+Sat Feb 25 13:19:50 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * texx2-page.c - added TeXPageSlamPages, in case we fail
+ to open a file and need to close exising windows. If we
+ don't, they can move around or redisplay, referencing dead
+ data structures.
+
+ * texx2-page.c - reopening a file now leaves pages at the same
+ page number in the new file. this means you don't have to
+ reposition yourself when you open a file.
+
+ * Released as 2.8
+
+ * texx2-page.c - split TeXPageNewFile into two parts, because
+ value of DviTotalPages changes after an open, causing
+ bogus free().
+
+ * texx2.c - stat the command line file name to make certain
+ it's a regular file before doing a setFile
+
+ * texx2-mark.c - plug last double free? Now explicitly zero variables
+ after *all* frees.
+
+Fri Feb 24 14:47:13 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * Released as 2.7
+
+ * texx2.c - allow single argument to set the file name
+
+ * DviPage.c - fix problem with inlines & optimization. Fontdefs
+ weren't being skipper properly, causing font names to be displayed.
+
+ * texx2-page.c - optimize tied pages for single-page-ahead
+ with foreward travel (avoid freeing next page until it gets it)
+
+ * texx2-page.c - fix double free in TeXPageNewFile (forgot to zero)
+
+ * dvi-simple.c - fix double free for DviCount (forgot to zero)
+
+ * dvi-simple.c - use strncpy
+
+ * texx2-page.c - found out about XtNallowShellResize.
+ remove include of ShellP.h
+
+ * texx2-font.c - reverse order of -mag and -scaled in error
+ message to make cut & paste buildfonts easier
+
+ * Imakefile - remove tabs
+
+ * texx2-error.c - Apply patch from Dana to fix over-write of
+ dialog box.
+
+ * DviPage.c, DviPage2.c - removed setGC, use single globalGC
+ which is rebuilt on each redisplay.
+
+ * DviPageP.h - removed `clearGC', renamed setGC to globalGC
+
+ * texx2-file.c - merged BuildPageLevel into BuildFileLevel.
+
+Fri Feb 24 14:50:36 1989 Dana A. Chee (dana at dino)
+
+ * texx2-error.c - removed unneeded resource XtNresize (not used in
+ text widgets).
+
+ * texx2-file.c - changed strcpy to proper strncpy; created widgets
+ in order used for chaining (Form widget goes through child list
+ once to place children, if the order of their chaining is
+ different from their creation order, the results will not be
+ satisfactory).
+
+ * texx2-widgets.c - let widgets dimension the form; build widgets
+ in correct order for chaining (Page within File now, see above
+ reasons).
+
+ * texx2.c - use proper program and class names for XtInitialize.
+
+Thur Feb 23 17:30:10 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * texx2-page.c - Added `large' and `small' buttons
+ * texx2.c - Added `largeMag' and `smallMag' resources
+
+Sun Feb 19 17:30:10 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * Released as 2.5
+
+ * Added `clear marks' button
+
+ * Fixed error in DviPageWidget - wasn't setting the setGC
+ properly, causing redraws to fail when not using backing store
+
+Fri Feb 17 17:30:10 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * Added ``tied'' pages, Imakefile, man page
+
+Tue Feb 14 11:49:11 1989 Dirk Grunwald (grunwald at flute.cs.uiuc.edu)
+
+ * Changed all args to widgets to be built use XtSetArg instead of
+ automatic aggregate initializations.
+
+ * Changed all callbacks to be built using XtAddCallback instead
+ of automatic aggregate initializations.
+
+ * Changes texx2-error.c to build a temporary _iobuf structure
+ for _doprnt to print erorr messages if vsprintf is unavailable.
+
+ * (texx2-page.c) made pushGotoButton goto the page with a count[0]
+ field matching the selected page number, as opposed to the ordinal
+ page number.
+
diff --git a/dviware/umddvi/previewers/texx2/description b/dviware/umddvi/previewers/texx2/description
new file mode 100644
index 0000000000..2c8009802a
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/description
@@ -0,0 +1,64 @@
+
+texx2.4 is available for anonymous FTP from
+ a.cs.uiuc.edu: pub/TeX/texx2.4.tar.Z
+or
+ expo.lcs.mit.edu: contrib/texx2.4.tar.Z
+
+texx2, currently at revision 4, is a second generation TeX previewer for
+X11 windowing systems. Unlike texx or xdvi, texx2 uses X11 fonts to display
+TeX output. A companion program, `mftobdf', is used to convert TeX fonts
+(i.e., PXL/GF/PK) fonts to the the formats required for X11.
+
+Consequentially, texx2 is significantly faster than the first release of
+texx or the venerable xdvi. Page display occurs at roughly the same speed
+of displays in `xman'. It's really even faster than texsun.
+
+Features include:
+ + Multiple pages displays at once, each in their own toplevel window.
+
+ + Pages can be `tied' together, such that hitting `foreward'
+ in one page causes the second page to go forward
+
+ + Ability to goto any page (using page numbers stored in \count0)
+
+ + Different mag levels can be set for different page displays
+
+ + Can use any existing fonts (for example, I use 300 dpi fonts,
+ and view the document at mags of 500 and 333 -- this gives
+ good detail & overall views)
+
+ + horiztoial and vertical scroll bars if needed
+
+ + can mark individual pages for printing
+
+ + can print entire document and/or marked pages
+
+ + the main window is designed to be leftup between viewing
+ sessions -- no need to restart the tool each time.
+
+ + handles tpic specials, out-lines bounding box of psfig
+ pictures.
+
+ + Known to work on X servers for Sun 3/60, IBM PC/RT, Vaxstation 3100.
+ Known to run as client on Sun 3/60, IBM PC/RT, Encore Multimax
+ (our vaxstation version of X11 doesn't have all patches applied,
+ so something causes it to die there)
+
+ + It's free.
+
+Downsides:
+ + You need to generate the X11 fonts. While this is simple, it's
+ takes me about 600K to store the fonts we use on a daily basis.
+ However, you *can* compress them, although that slows down
+ page display startup.
+
+ + Can easily expand your server memory size by 450K, because of all
+ the fonts.
+
+ + There is no warrenty, precious little documentation,
+ and I'm not going to be able to answer mail about it
+ because I'm interviewing and trying to finish my thesis.
+ However, if you've ever installed texsun or texx, texx2
+ should be a snap.
+Office: 72 DCL (217) 333-1925
+
diff --git a/dviware/umddvi/previewers/texx2/dvi-simple.c b/dviware/umddvi/previewers/texx2/dvi-simple.c
new file mode 100644
index 0000000000..eea2aca35b
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvi-simple.c
@@ -0,0 +1,508 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include <stdio.h>
+#include "dvi-simple.h"
+#include "conv.h"
+#include <assert.h>
+#include <sys/file.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 1
+#endif
+
+#ifdef __STDC__
+ extern void bzero(char *, int);
+ extern char* malloc(int);
+ extern void free(char *);
+ extern char *getenv(char *);
+ extern strcpy(char *, char *);
+ extern strncpy(char *, char *,int);
+ extern strcat(char *, char *);
+ extern FILE *fopen(char *, char *);
+#else
+ extern void bzero();
+ extern char* malloc();
+ extern void free();
+ extern char *getenv();
+ extern strcpy();
+ extern strcat();
+ extern FILE *fopen();
+#endif
+
+struct PostAmbleInfo ThePostAmbleInfo;
+
+int RegisteredFonts = 0;
+
+#define MAX_GLYPHS 256
+DviFontInfo TheFontInfo[ MAX_POSTAMBLE_FONTS ];
+
+long dviPageOffsets;
+
+static long Magnification;
+static long Numerator; /* numerator from DVI file */
+static long Denominator; /* denominator from DVI file */
+
+long *DviCount[DVI_COUNT];
+long *DviPageOffsets = 0;
+
+int DviHHMargin = -1; /* horizontal margin (in DEVs) */
+int DviVVMargin = -1; /* vertical margin (in DEVs) */
+int DviTallestPage = -1;
+int DviWidestPage = -1 ;
+int DviCurrentPage = -1;
+int DviTotalPages = -1;
+int DviDpi = -1;
+int DviMaxDrift = -1;
+int DviUserMag = -1; /* user-specified magnification */
+int DviBlackness = -1;
+FILE *DviFile;
+long DviFileSize;
+char *DviFileName;
+
+static Conv Conversion;
+
+extern int errno;
+
+static int anError;
+
+static void savePostAmblePointer(p)
+struct PostAmbleInfo *p;
+{
+ int i;
+ int page;
+ int pageSize;
+ int stackSize;
+ long prevPagePointer;
+ long wuzAt;
+
+ ThePostAmbleInfo = *p;
+
+ Numerator = p->pai_Numerator;
+ Denominator = p->pai_Denominator;
+ Magnification = p->pai_DVIMag;
+
+ /*
+ * Set the conversion factor. This must be done before using
+ * any fonts or the fromSP routine.
+ */
+
+ CSetConversion(&Conversion,
+ DviDpi, DviUserMag, Numerator, Denominator, Magnification);
+
+ DviTotalPages = p -> pai_NumberOfPages;
+ DviWidestPage = cfromSP(&Conversion, p -> pai_WidestPageWidth);
+ DviTallestPage = cfromSP(&Conversion, p -> pai_TallestPageHeight);
+
+ /*
+ * Set of the table of pointers to pages and room for the
+ * count variables.
+ */
+
+ pageSize = DviTotalPages * sizeof(long);
+ if (DviPageOffsets != 0) {
+ free( (char *) DviPageOffsets);
+ DviPageOffsets = 0;
+ }
+ DviPageOffsets = (long *) malloc(pageSize);
+
+ if (DviPageOffsets == NULL) {
+ error(1,0,"Can not allocate page directory (%d pages)", DviTotalPages);
+ exit(1);
+ }
+
+ for (i = 0; i < DVI_COUNT; i++) {
+ if (DviCount[i] != 0) {
+ free( (char *) DviCount[i]);
+ DviCount[i] = 0;
+ }
+ DviCount[i] = (long *) malloc(pageSize);
+ if (DviCount[i] == NULL) {
+ error(1,0,"Can not allocate count directory (%d pages)", DviTotalPages);
+ exit(1);
+ }
+ }
+
+ /*
+ * Follow back pointers through pages in the DVI file,
+ * storing the offsets in the DviPageOffsets table.
+ */
+
+ prevPagePointer = p->pai_PrevPagePointer;
+ wuzAt = (long) ftell(DviFile);
+
+ fseek(DviFile, 0L, 2);
+ DviFileSize = ftell(DviFile);
+
+ for (page = DviTotalPages - 1; page >= 0 ; page--) {
+
+ /*
+ * Skip to previous page, but skip over BOP marker.
+ */
+ DviPageOffsets[page] = prevPagePointer;
+
+ if( fseek(DviFile, prevPagePointer+1, 0) < 0) {
+ error(1, errno, "Improper seek looking up pages\n");
+ anError |= 1;
+ return;
+ }
+
+ /*
+ * Read the other counters at the beginning of the page
+ */
+
+ for (i = 0; i < DVI_COUNT; i++) {
+ long value;
+ fGetLong(DviFile, value);
+ DviCount[i][page] = value;
+ }
+ fGetLong(DviFile, prevPagePointer);
+ }
+ fseek(DviFile, wuzAt, 0);
+}
+
+#ifndef TEXFONTS
+#define TEXFONTS ".:/u/tex/mftfm:/u/tex/pstfm"
+#endif
+
+static char *EnvFontPath;
+
+static FILE *openTfmFile(name)
+char *name;
+{
+ char *usePath;
+ char path[1024];
+
+ if ( EnvFontPath == 0 ) {
+ extern char *getenv();
+ EnvFontPath = getenv("TEXFONTS");
+ }
+
+ usePath = (EnvFontPath == 0) ? TEXFONTS: EnvFontPath;
+
+ for (;;) {
+ char *p = path;
+
+ if ( usePath == 0 || *usePath == 0 ) {
+ return( 0 );
+ }
+
+ *p = 0;
+
+ while ( *usePath && *usePath != ':' ) {
+ *(p++) = *(usePath++);
+ }
+
+ /* append name */
+
+ *(p++) = '/';
+ strcpy(p, name);
+ strcat(p, ".tfm");
+ if ( access( path, R_OK ) == 0 ) {
+ return( fopen(path, "r") );
+ }
+
+ if ( *usePath == ':' ) {
+ usePath++;
+ }
+ }
+}
+
+static void
+registerFont(f)
+struct PostAmbleFont *f;
+{
+ int thisFont;
+ FILE *tfmFile;
+ char *fontName[1024];
+
+ assert( RegisteredFonts < MAX_POSTAMBLE_FONTS );
+
+ thisFont = RegisteredFonts++;
+/* Attempt to locate the TFM files */
+
+ tfmFile = openTfmFile( f -> paf_name );
+ if ( tfmFile == 0 ) {
+ error(0,0,"Can't find TFM file for %s", f -> paf_name);
+ anError = 1;
+ }
+ else {
+ struct tfmdata t;
+ i32 pspace;
+ int len;
+
+ TheFontInfo[ thisFont ].paf = *f;
+
+ /* make a copy of the name */
+
+ len = strlen( f -> paf_name );
+ TheFontInfo[ thisFont ].paf.paf_name
+ = malloc( sizeof(char) * (len + 1 ));
+ strncpy( TheFontInfo[ thisFont ].paf.paf_name, f -> paf_name, len+1);
+
+ pspace = f -> paf_DVIMag / 6; /* a three-unit "thin space" */
+
+ TheFontInfo[ thisFont ].pspace = pspace;
+ TheFontInfo[ thisFont ].nspace = -4 * pspace;
+ TheFontInfo[ thisFont ].vspace = 5 * pspace;
+
+ bzero((char *) &t, sizeof(t));
+
+ if ( readtfmfile( tfmFile, &t, TRUE ) != 0 ) {
+ error(0,0,"Bogus TFM file: %s", f -> paf_name);
+ }
+ else {
+ int i;
+ int nc = t.t_hdr.th_ec - t.t_hdr.th_bc + 1;
+ int nw;
+ int *p;
+ int s; /* see dvitype */
+ int d;
+
+ if ( TheFontInfo[ thisFont ].widths == 0 ) {
+ TheFontInfo[ thisFont ].widths =
+ (int *) malloc( sizeof(int) * MAX_GLYPHS );
+ }
+
+ /* convert widths */
+ assert( t.t_width[0] == 0 );
+ nw = t.t_hdr.th_nw;
+ s = TheFontInfo[ thisFont ].paf.paf_DVIMag;
+ d = TheFontInfo[ thisFont ].paf.paf_DVIDesignSize;
+
+ for (i = 0; i < nw; i++) {
+
+ int width = t.t_width[i];
+
+ if (width != 0) {
+ width = ScaleOneWidth(width, s);
+ }
+ t.t_width[i] = width;
+
+ }
+
+ p = TheFontInfo[ thisFont ].widths;
+ bzero( (char *) p , sizeof(int) * MAX_GLYPHS );
+
+ p += t.t_hdr.th_bc;
+
+ for (i = 0; i <= nc; i++) {
+ int wi = t.t_ci[i].ci_width;
+ *(p++) = t.t_width[wi];
+ }
+ }
+
+ fclose(tfmFile);
+ }
+}
+
+/*
+ * Returns TRUE if everything is fine
+ */
+
+int
+DviInit( dviFileName, copy )
+char *dviFileName;
+int copy;
+{
+ extern char *ProgName;
+ FILE *dviFile;
+ char *mktemp();
+
+ anError = 0;
+
+ DviFini(); /* clean up the old files */
+
+ DviFile = 0;
+
+ if (dviFileName == 0) {
+ dviFile = stdin;
+ dviFileName = "<stdin>";
+ copy = 1;
+ }
+ else if ((dviFile = fopen(dviFileName, "r")) == NULL) {
+
+ int n = strlen(dviFileName);
+ char *dviName;
+
+ if (strcmp(dviFileName + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+ DviFini();
+ error(0, errno, "[fopen] can't open %s", dviFileName);
+ return(1);
+ }
+
+ dviName = (char *) malloc((unsigned) n + sizeof(".dvi") + 1);
+ sprintf(dviName, "%s.dvi", dviFileName);
+
+ if ((dviFile = fopen(dviName, "r")) == NULL) {
+ DviFini();
+ error(0, errno, "[fopen] can't open %s", dviName);
+ return(1);
+ }
+ dviFileName = dviName;
+ }
+
+ DviFileName = dviFileName;
+
+ if ( copy ) {
+
+ /*
+ * Copy the file to a temporary location if requested.
+ * This lets the person peruse the file while theyre re-texing it.
+ */
+ FILE *tmpFile;
+ char dviTmpFileNameBuffer[256];
+ char *dviTmpFileName;
+
+ sprintf(dviTmpFileNameBuffer,"/tmp/Dvistuff.XXXXXX");
+
+ dviTmpFileName = mktemp(dviTmpFileNameBuffer);
+
+ if (!(tmpFile = fopen(dviTmpFileName,"w+"))) {
+ error(0, errno, "[fopen] Unable to create temporary file");
+ dviTmpFileName = 0;
+ }
+ else {
+ char buffer[BUFSIZ];
+ int b;
+
+ rewind(dviFile);
+ do {
+ b = fread(buffer, 1, BUFSIZ, dviFile);
+ fwrite(buffer, 1, b, tmpFile);
+ } while (! feof(dviFile));
+
+ fclose(dviFile);
+ dviFile = tmpFile;
+ rewind(dviFile);
+
+ /*
+ * Unlink the temporary file. This keeps tmp files from cluddering
+ * up /tmp and it does it in a very application-independent way.
+ * You can't reopen the tmp file, but we don't really allow that
+ * anyway (the tmp file is hidden from the user).
+ */
+
+ if (dviTmpFileName != 0 &&
+ strncmp(dviTmpFileName,"/tmp/",5) == 0) {
+ unlink(dviTmpFileName);
+ }
+ }
+ }
+
+ assert( dviFile != 0 );
+
+ DviFile = dviFile;
+
+ if (DviUserMag == -1) {
+ DviUserMag = 1000;
+ }
+
+ if (DviMaxDrift == -1) {
+ DviMaxDrift = DEFAULT_MAX_DRIFT;
+ }
+
+ if (DviDpi == -1) {
+ DviDpi = DEFAULT_DPI;
+ }
+
+ if (DviBlackness == -1) {
+ DviBlackness = DEFAULT_BLACKNESS;
+ }
+
+ /* Margins -- needs work! */
+
+ if (DviHHMargin == -1) {
+ DviHHMargin = DEFAULT_HHMARGIN;
+ }
+
+ if (DviVVMargin == -1) {
+ DviVVMargin = DEFAULT_VVMARGIN;
+ }
+
+ anError |= ScanPostAmble( DviFile, savePostAmblePointer, registerFont);
+
+ if (anError) {
+ DviFini();
+ }
+
+ return( anError );
+}
+
+void
+DviFini()
+{
+ int font;
+ int c;
+
+ if (DviFile != 0) {
+ fclose(DviFile);
+ }
+
+ DviFile = 0;
+
+ for (font = 0; font < RegisteredFonts; font++) {
+ if ( TheFontInfo[ font ].paf.paf_name ) {
+ free ( (char *) TheFontInfo[ font ].paf.paf_name );
+ TheFontInfo[ font] .paf.paf_name = 0;
+ }
+ if ( TheFontInfo[ font ].widths ) {
+ free ( (char *) TheFontInfo[ font ].widths );
+ TheFontInfo[ font].widths = 0;
+ }
+ }
+ RegisteredFonts = 0;
+
+ for (c = 0; c < DVI_COUNT; c++) {
+ if ( DviCount[ c ] ) {
+ free( (char *) DviCount[ c ] );
+ DviCount[ c ] = 0;
+ }
+ }
+}
+
+
+char *
+DviFetchPage(pageNumber)
+int pageNumber;
+{
+ if ( pageNumber < 0 || pageNumber > DviTotalPages ) {
+ return(0);
+ }
+ else {
+ long start = DviPageOffsets[ pageNumber ];
+ long end = ( pageNumber == (DviTotalPages-1))
+ ? DviFileSize : DviPageOffsets[ pageNumber + 1];
+ long toRead = end - start;
+
+ char *buffer = malloc( toRead );
+
+ if (buffer == 0 ) {
+ return( 0 );
+ }
+ else {
+
+ long loc;
+ long bytes;
+
+ loc = fseek(DviFile, (long) start, 0);
+ if (loc < 0) {
+ error(0,0,"Improper seek: %d", errno);
+ }
+
+ bytes = fread( buffer, 1, toRead, DviFile );
+
+ if (bytes != toRead) {
+ error(0,0,"Tried to read %d, only got %d", toRead, bytes);
+ }
+ return(buffer);
+ }
+ }
+}
+
diff --git a/dviware/umddvi/previewers/texx2/dvi-simple.h b/dviware/umddvi/previewers/texx2/dvi-simple.h
new file mode 100644
index 0000000000..b79e98fb96
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvi-simple.h
@@ -0,0 +1,75 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include "types.h"
+#include "dviclass.h"
+#include "dvicodes.h"
+#include "tfm.h"
+#include "fio.h"
+#include "postamble.h"
+
+/*****************************************************************************
+ * Things we read from the DVI file
+ */
+
+extern struct PostAmbleInfo ThePostAmbleInfo;
+
+typedef struct {
+ struct PostAmbleFont paf;
+ int *widths;
+ i32 pspace; /* boundary between `small & `large spaces
+ (for positive horizontal motion) */
+ i32 nspace; /* -4 * pspace, for negative motion */
+ i32 vspace; /* 5 * pspace, for vertical motion */
+} DviFontInfo;
+
+#define MAX_POSTAMBLE_FONTS 256
+extern int RegisteredFonts;
+extern DviFontInfo TheFontInfo[ MAX_POSTAMBLE_FONTS ];
+
+/*****************************************************************************
+/*
+ * Defaults and configuration for dvi-simple
+ */
+
+#define DEFAULT_DPI 300
+#define DEFAULT_HHMARGIN DEFAULT_DPI
+#define DEFAULT_VVMARGIN DEFAULT_DPI
+#define DEFAULT_MAX_DRIFT 3
+
+#define DEFAULT_BLACKNESS 3
+
+#define DVI_COUNT 10 /* count0 .. count9 */
+
+#define SP_PER_INCH(dpi) ( (dpi) * 65536 )
+#define POINTS_PER_INCH 72.27
+
+extern long *DviCount[DVI_COUNT];
+extern long *DviPageOffsets;
+
+extern int DviHHMargin;
+extern int DviVVMargin;
+extern int DviDpi;
+extern int DviTallestPage;
+extern int DviWidestPage;
+extern int DviTotalPages;
+extern int DviCurrentPage;
+extern int DviMaxDrift;
+extern char *DviPrintEngine;
+extern int DviBlackness;
+extern int DviUserMag;
+
+extern FILE *DviFile;
+extern char *DviFileName;
+
+#ifdef __STDC__
+ extern int DviInit( char *, int );
+ extern void DviFini();
+ extern char * DviFetchPage( int );
+#else
+ extern int DviInit();
+ extern void DviFini();
+ extern char * DviFetchPage();
+#endif
diff --git a/dviware/umddvi/previewers/texx2/dvipage.c b/dviware/umddvi/previewers/texx2/dvipage.c
new file mode 100644
index 0000000000..50f3c77a92
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvipage.c
@@ -0,0 +1,915 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <stdio.h>
+#include "dvi-simple.h"
+#include "mio.h"
+#include "conv.h"
+#include <assert.h>
+
+#include "DviPageP.h"
+
+ static XtResource resources[] = {
+
+#define offset(field) XtOffset(DviPageWidget, field)
+
+ /* {name, class, type, size, offset, default_type, default_addr}, */
+
+ {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
+ offset(dviPage.background), XtRString, "XtDefaultBackground"},
+
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(dviPage.foreground), XtRString, "XtDefaultForeground"},
+
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ offset(dviPage.font), XtRString, "XtDefaultFont"},
+
+ {XtNpage, XtCPage, XtRPointer, sizeof(char *),
+ offset(dviPage.page), XtRPointer, 0},
+
+ {XtNpai, XtCPai, XtRPointer, sizeof(struct PostAmbleInfo *),
+ offset(dviPage.pai), XtRPointer, 0 },
+
+ {XtNdviFonts, XtCDviFonts, XtRPointer, sizeof(DviFontInfo *),
+ offset(dviPage.dviFonts), XtRPointer, 0 },
+
+ {XtNxFonts, XtCXFonts, XtRPointer, sizeof(XFontStruct **),
+ offset(dviPage.xFonts), XtRPointer, 0 },
+
+ {XtNuserMag, XtCUserMag, XtRInt, sizeof(int),
+ offset(dviPage.userMag), XtRString, "500"},
+
+ {XtNdpi, XtCDpi, XtRInt, sizeof(int),
+ offset(dviPage.dpi), XtRString, "300"},
+
+ {XtNreverseVideo, XtCReverseVideo, XtRBool, sizeof(Bool),
+ offset(dviPage.reverseVideo), XtRString, "False"},
+
+ {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
+ offset (dviPage.useBackingStore), XtRString, "default"},
+
+ {XtNpaperWidth, XtCPaperWidth, XtRString, sizeof (char *),
+ offset (dviPage.paperWidthString), XtRString, "8.5"},
+
+ {XtNpaperHeight, XtCPaperHeight, XtRString, sizeof (char *),
+ offset (dviPage.paperHeightString), XtRString, "11"}
+
+#undef offset
+ };
+
+#ifdef __STDC__
+ static void ClassInitialize();
+ static void Initialize(), Destroy(), Redisplay();
+ static void Realize();
+ static Boolean SetValues( );
+ static void SetPageSize( DviPageWidget, Dimension *width, Dimension *heigth);
+ static XtGeometryResult QueryGeometry();
+
+ extern double atof(char *);
+#else
+ static void ClassInitialize();
+ static void Initialize(), Destroy(), Redisplay();
+ static void Realize();
+ static Boolean SetValues();
+ static XtGeometryResult QueryGeometry();
+ static XtGeometryResult QueryGeometry();
+
+ extern double atof();
+#endif
+
+static void DviPageAction(/* Widget, XEvent*, String*, Cardinal* */);
+
+static XtActionsRec actions[] =
+{
+ /* {name, procedure}, */
+ {"dviPage", DviPageAction},
+};
+
+static char translations[] =
+ "<Key>: dviPage() \n\
+";
+
+DviPageClassRec dviPageClassRec = {
+ { /* core fields */
+ /* superclass */
+ (WidgetClass) &widgetClassRec,
+ /* class_name */ "DviPage",
+ /* widget_size */ sizeof(DviPageRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ NULL,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ translations,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* dviPage fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass dviPageWidgetClass = (WidgetClass)&dviPageClassRec;
+
+/****************************************************************
+ *
+ * Class Procedures
+ *
+ ****************************************************************/
+
+/* Sun cc complains about the following line, but I'll be damned if
+ I know why. It's decld a static void above */
+
+static void ClassInitialize()
+{
+ XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
+ NULL, 0 );
+}
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void DviPageAction(/* Widget, XEvent*, String*, Cardinal* */)
+{
+ fprintf(stderr,"EVENT\n");
+}
+
+void
+SetPageSize(w, wd, ht)
+DviPageWidget w;
+Dimension *wd;
+Dimension *ht;
+{
+ DviPagePart *pi = & (w -> dviPage);
+ struct PostAmbleInfo *pai = pi -> pai;
+
+ long bdr;
+
+ if ( pai != 0 ) {
+ int bdr;
+
+ CSetConversion(&(pi -> Conversion),
+ pi -> dpi,
+ pi -> userMag,
+ pai -> pai_Numerator,
+ pai -> pai_Denominator,
+ pai -> pai_DVIMag);
+ }
+ else {
+ long Numerator = 25400000;
+ long Denominator = 473628272;
+
+ CSetConversion(&(pi -> Conversion),
+ pi -> dpi,
+ pi -> userMag,
+ Numerator,
+ Denominator,
+ 1000);
+ }
+
+ w -> dviPage.fastFromSpValue
+ = (long) ( w -> dviPage.Conversion.c_tosp );
+
+ w -> dviPage.pixelsPerInch
+ = cfromSP(&(pi -> Conversion), SP_PER_INCH( POINTS_PER_INCH ));
+
+ bdr = w -> dviPage.pixelsPerInch;
+
+ w -> dviPage.texPicScale = pi -> userMag * bdr;
+
+ w -> dviPage.pixelsWide = bdr * w -> dviPage.paperWidth;
+ w -> dviPage.pixelsHigh = bdr * w -> dviPage.paperHeight;
+
+ (*wd) = w -> dviPage.pixelsWide;
+ (*ht) = w -> dviPage.pixelsHigh;
+}
+
+static void Initialize (request, new)
+ Widget request, new;
+{
+ DviPageWidget want = (DviPageWidget) request;
+ DviPageWidget w = (DviPageWidget) new;
+
+ XFontStruct *f;
+ int dir, as, ds;
+ XCharStruct os;
+
+ Dimension wd, ht;
+
+ w -> dviPage.page = want -> dviPage.page;
+ w -> dviPage.pai = want -> dviPage.pai ;
+ w -> dviPage.xFonts = want -> dviPage.xFonts ;
+ w -> dviPage.dviFonts = want -> dviPage.dviFonts ;
+
+ w -> dviPage.paperWidth = atof(want -> dviPage.paperWidthString);
+ w -> dviPage.paperHeight = atof(want -> dviPage.paperHeightString);
+
+ w -> dviPage.globalGC = 0;
+
+ w -> dviPage.dviStack = 0;
+ w -> dviPage.dviStackSize = 0;
+ w -> dviPage.pathLen = 0;
+ w -> dviPage.penSize = 1;
+ w -> dviPage.whiten = False;
+ w -> dviPage.shade = False;
+ w -> dviPage.blacken = False;
+
+ SetPageSize(w, &wd, &ht);
+
+#define MaX(x,y) ((x) > (y) ) ? (x) : (y)
+
+ w -> core.width = MaX(wd, want->core.width);
+ w -> core.height = MaX(ht, want->core.height);
+
+#undef MaX
+
+}
+
+static void Realize (gw, valueMask, attrs)
+ Widget gw;
+ XtValueMask *valueMask;
+ XSetWindowAttributes *attrs;
+{
+
+ XWindowAttributes wAttributes;
+
+ DviPageWidget w = (DviPageWidget) gw;
+
+ switch (w->dviPage.useBackingStore) {
+ case Always:
+ case NotUseful:
+ case WhenMapped:
+ *valueMask |=CWBackingStore;
+ attrs->backing_store = w->dviPage.useBackingStore;
+ break;
+ }
+
+ XtCreateWindow( w, InputOutput, (Visual *)CopyFromParent,
+ *valueMask, attrs);
+
+ XGetWindowAttributes( XtDisplay(w), XtWindow(w), &wAttributes );
+
+
+ w -> dviPage.haveBackingStore
+ = ( wAttributes.save_under == Always)
+ || (wAttributes.save_under == WhenMapped);
+
+ w->dviPage.globalGC
+ = XCreateGC( XtDisplay(w), XtWindow(w), 0, NULL);
+}
+
+static void Destroy (gw)
+ Widget gw;
+{
+ DviPageWidget w = (DviPageWidget) gw;
+ XtFree( w -> dviPage.dviStack );
+ w -> dviPage.dviStack = 0;
+
+ if ( w -> dviPage.globalGC ) {
+ XFreeGC( XtDisplay(w), w -> dviPage.globalGC );
+ w -> dviPage.globalGC = 0;
+ }
+}
+
+static Boolean SetValues(current, request, new)
+ DviPageWidget current, request, new;
+{
+
+ DviPagePart *pi = & (request -> dviPage);
+ struct PostAmbleInfo *p = pi -> pai;
+
+ new -> dviPage.page =
+ (request -> dviPage.page)
+ ? (request -> dviPage.page) : current -> dviPage.page ;
+
+ new -> dviPage.xFonts =
+ (request -> dviPage.xFonts)
+ ? (request -> dviPage.xFonts) : current -> dviPage.xFonts;;
+
+ new -> dviPage.pai =
+ (request -> dviPage.pai)
+ ? (request -> dviPage.pai) : current -> dviPage.pai;
+
+ if ( new -> dviPage.pai ) {
+
+ int stackSize = new -> dviPage.pai -> pai_DVIStackSize;
+
+ if (stackSize > new -> dviPage.dviStackSize ) {
+
+ stackSize += 2;
+
+ XtFree( new -> dviPage.dviStack );
+
+ new -> dviPage.dviStack = 0;
+ new -> dviPage.dviStackSize = stackSize;
+
+ if (stackSize > 0 ) {
+ new -> dviPage.dviStack =
+ (LocalDviStack *) (malloc( stackSize * sizeof(LocalDviStack) ));
+ }
+ }
+ }
+
+ new -> dviPage.dviFonts =
+ (request -> dviPage.dviFonts)
+ ? (request -> dviPage.dviFonts) : current -> dviPage.dviFonts;
+
+ new -> dviPage.paperWidth =
+ (request -> dviPage.paperWidthString)
+ ? atof(request -> dviPage.paperWidthString)
+ : current -> dviPage.paperWidth;
+
+ new -> dviPage.paperHeight =
+ (request -> dviPage.paperHeightString)
+ ? atof(request -> dviPage.paperHeightString)
+ : current -> dviPage.paperHeight;
+
+ SetPageSize(new, &(new -> core.width), &(new -> core.height));
+
+ return( True ); /* resize */
+}
+
+static XtGeometryResult QueryGeometry(w, intended, preferred)
+ Widget w;
+ XtWidgetGeometry *intended, *preferred;
+{
+ register DviPageWidget lw = (DviPageWidget) w;
+ Dimension wd, ht;
+
+ SetPageSize((DviPageWidget) w, &wd, &ht);
+
+ preferred -> request_mode = CWWidth | CWHeight;
+
+ preferred -> width = wd ;
+ preferred -> height = ht ;
+
+ if ( ((intended->request_mode & (CWWidth | CWHeight))
+ == (CWWidth | CWHeight)) &&
+ intended->width == preferred->width &&
+ intended->height == preferred->height)
+ return XtGeometryYes;
+ else if (preferred->width == w->core.width &&
+ preferred->height == w->core.height)
+ return XtGeometryNo;
+ else
+ return XtGeometryAlmost;
+}
+
+/*
+ * Some very DVI related things
+ */
+
+#define ABS(X) ( (X) < 0 ? -(X) : (X) )
+
+int
+selectFont(w, ptr, index, font)
+DviPageWidget w;
+DviFontInfo **ptr;
+int *index;
+int font;
+{
+ if ( *ptr != 0 && (*ptr) -> paf.paf_DVIFontIndex == font ) {
+ return 0;
+ }
+ else {
+ int offset;
+ DviFontInfo *fonts = w -> dviPage.dviFonts;
+
+ *ptr = 0;
+ for ( offset = 0; offset < RegisteredFonts; offset++ ) {
+ if ( fonts[offset].paf.paf_DVIFontIndex == font ) {
+ *ptr = &(fonts[offset]);
+ *index = offset;
+ break;
+ }
+ }
+
+ if ( *ptr == 0 ) {
+ error(0,0,"Can't find font %d", font);
+ return 1;
+ }
+ else {
+ return(0);
+ }
+ }
+}
+
+void DviDisplay(widget)
+ DviPageWidget widget;
+{
+ int c;
+ i32 p;
+ int advance;
+ int wuz;
+ int spDrift;
+
+ DviPagePart *page = &( widget -> dviPage);
+
+ struct PostAmbleInfo *pai = page -> pai;
+
+ char *thisPage = page -> page;
+ Conv *conv = &(page -> Conversion);
+
+ DviFontInfo *dviCurrentFont = 0;
+ int dviCurrentFontIndex = 0;
+
+/* following are used to reduce the number of XDrawStrings we do */
+
+#define MAX_DVI_STRING 64
+ char dviString[ MAX_DVI_STRING ];
+ int dviStringLength;
+ int startHH, startVV;
+ int endHH, endVV;
+
+ LocalDviStack *dviStack = page -> dviStack;
+ LocalDviStack *dviStackP; /* current stack item */
+
+ if ( pai == 0 || thisPage == 0 || dviStack == 0) {
+ return;
+ }
+
+ assert( dviStack != 0 );
+
+ dviStackP = dviStack;
+
+ dviStringLength = 0;
+ startHH = startVV = -1;
+ endHH = endVV = -1;
+
+ /* insure that first byte is a BOP mark */
+
+ c = (*thisPage) & 0xff;
+ if ( DVI_DT(c) != DT_BOP ) {
+ error(0,0,"No BOP found");
+ goto cleanup;
+ }
+
+ /* initialize spDrift to be a single pixel width */
+ spDrift = ctoSP( conv, POINTS_PER_INCH / DviDpi );
+
+ for(;;) {
+
+ c = mGetByte(&thisPage);
+
+ if (DVI_IsChar(c)) {
+
+ advance = 1;
+
+ doDviChar:
+ if ( !advance
+ || ABS(endHH - (dviStackP -> h)) > spDrift
+ || ABS(endVV - (dviStackP -> v)) > spDrift
+ || dviStringLength >= MAX_DVI_STRING )
+ {
+
+ if ( dviStringLength > 0 ) {
+ i32 atHH = fastFromSP(widget, startHH);
+ i32 atVV = fastFromSP(widget, startVV);
+ Bool doit = True;
+
+ if ( widget -> dviPage.haveBackingStore ) {
+ i32 width = fastFromSP(widget, endHH);
+ i32 height = fastFromSP(widget, endVV);
+
+ doit =
+ XRectInRegion( widget -> dviPage.updateRegion, atHH, atVV,
+ width, height) != RectangleOut;
+ }
+
+ if (doit) {
+ XDrawString( XtDisplay( widget ), XtWindow( widget ),
+ page -> globalGC, atHH, atVV,
+ dviString, dviStringLength );
+ }
+ }
+ dviStringLength = 0;
+ startHH = dviStackP -> h;
+ startVV = dviStackP -> v ;
+ }
+
+ dviString[ dviStringLength++ ] = c;
+
+ if ( advance && dviCurrentFont && dviCurrentFont -> widths) {
+ dviStackP -> h += (dviCurrentFont -> widths[ c ]) ;
+ }
+
+ endHH = dviStackP -> h;
+ endVV = dviStackP -> v;
+
+ } else {
+
+ switch (DVI_OpLen(c)) {
+
+ case DPL_NONE:
+ break;
+
+ case DPL_SGN1:
+ p = mGetByte(&thisPage);
+ p = Sign8(p);
+ break;
+
+ case DPL_SGN2:
+ mGetWord(&thisPage, &p);
+ p = Sign16(p);
+ break;
+
+ case DPL_SGN3:
+ mGet3Byte(&thisPage, &p);
+ p = Sign24(p);
+ break;
+
+ case DPL_SGN4:
+ mGetLong(&thisPage, &p);
+ break;
+
+ case DPL_UNS1:
+ p = UnSign8(mGetByte(&thisPage));
+ break;
+
+ case DPL_UNS2:
+ mGetWord(&thisPage, &p);
+ p = UnSign16(p);
+ break;
+
+ case DPL_UNS3:
+ mGet3Byte(&thisPage, &p);
+ p = UnSign24(p);
+ break;
+
+ default:
+ panic("DVI_OpLen(%d) = %d", c, DVI_OpLen(c));
+ goto cleanup;
+ /* NOTREACHED */
+ }
+
+ switch (DVI_DT(c)) {
+
+ case DT_SET:
+ c = p;
+ advance = 1;
+ goto doDviChar;
+ break;
+
+ case DT_PUT:
+ c = p;
+ advance = 0;
+ goto doDviChar;
+ break;;
+
+ case DT_SETRULE:
+ case DT_PUTRULE:
+
+ {
+ i32 cHH, cVV;
+ i32 rhh, rvv;
+
+ cHH = fastFromSP(widget, dviStackP -> h);
+ cVV = fastFromSP(widget, dviStackP -> v);
+
+ mGetLong(&thisPage, &rvv);
+ mGetLong(&thisPage, &rhh);
+
+ if (DVI_DT(c) == DT_SETRULE) {
+ dviStackP -> h += rhh;
+ }
+
+ rhh = CConvRule(conv, rhh);
+ rvv = CConvRule(conv, rvv);
+
+ XFillRectangle(XtDisplay(widget), XtWindow(widget),
+ page -> globalGC, cHH, cVV - rvv, rhh, rvv);
+
+ }
+ break;
+
+ case DT_NOP:
+ break;
+
+ case DT_BOP:
+ /*
+ * Each beginning of page has 11 4-byte words telling us things
+ * about the page. We ignore them.
+ */
+ thisPage += (11 * 4);
+
+ dviStackP = dviStack;
+
+ dviStackP -> h = SP_PER_INCH( POINTS_PER_INCH );
+ dviStackP -> v = SP_PER_INCH( POINTS_PER_INCH );
+ startHH = dviStackP -> h;
+ startVV = dviStackP -> v ;
+ endHH = startHH;
+ endVV = startVV;
+ dviStackP -> w = 0;
+ dviStackP -> x = 0;
+ dviStackP -> y = 0;
+ dviStackP -> z = 0;
+
+ break;
+
+ case DT_EOP:
+ goto cleanup;
+ /* NOTREACHED */
+
+ case DT_PUSH:
+ {
+ /* copy the old stack to the new one */
+
+ LocalDviStack *old = dviStackP;
+ dviStackP++;
+ *dviStackP = *old;
+ }
+ break;
+
+ case DT_POP:
+ /* just use the old stack */
+ dviStackP--;
+ break;
+
+ case DT_W0: /* there should be a way to make these pretty */
+ p = dviStackP -> w;
+ goto move_right;
+
+ case DT_W:
+ dviStackP -> w = p;
+ goto move_right;
+
+ case DT_X0:
+ p = dviStackP -> x;
+ goto move_right;
+
+ case DT_X:
+ dviStackP -> x = p;
+ goto move_right;
+
+ case DT_RIGHT:
+ move_right:
+ dviStackP -> h += p;
+ break;
+
+ case DT_Y0:
+ p = dviStackP -> y;
+ goto move_down;
+
+ case DT_Y:
+ dviStackP -> y = p;
+ goto move_down;
+
+ case DT_Z0:
+ p = dviStackP -> z;
+ goto move_down;
+
+ case DT_Z:
+ dviStackP -> z = p;
+ goto move_down;
+
+ case DT_DOWN:
+ move_down:
+ dviStackP -> v += p;
+ break;
+
+ case DT_FNTNUM:
+ case DT_FNT:
+ {
+ int font;
+
+ /* flush existing text */
+
+ if ( dviStringLength > 0 ) {
+ i32 atHH = fastFromSP(widget, startHH);
+ i32 atVV = fastFromSP(widget, startVV);
+ Bool doit = True;
+
+ if ( widget -> dviPage.haveBackingStore ) {
+ i32 width = fastFromSP(widget, endHH);
+ i32 height = fastFromSP(widget, endVV);
+
+ doit =
+ XRectInRegion( widget -> dviPage.updateRegion, atHH, atVV,
+ width, height) != RectangleOut;
+ }
+
+ if (doit) {
+ XDrawString( XtDisplay( widget ), XtWindow( widget ),
+ page -> globalGC, atHH, atVV,
+ dviString, dviStringLength );
+ }
+ dviStringLength = 0;
+ startHH = dviStackP -> h;
+ startVV = dviStackP -> v ;
+ }
+
+ /* switch to new font */
+
+ font = ( DVI_DT(c) == DT_FNTNUM )
+ ? font = (c - DVI_FNTNUM0) : p;
+
+ if ( selectFont(widget,
+ &dviCurrentFont, &dviCurrentFontIndex, font) ) {
+ goto cleanup;
+ }
+ else {
+ /* load the font */
+ XSetFont( XtDisplay(widget), widget -> dviPage.globalGC,
+ (widget -> dviPage.xFonts && widget -> dviPage.xFonts[ dviCurrentFontIndex ])
+ ? (widget->dviPage.xFonts[ dviCurrentFontIndex ]) -> fid
+ : widget -> dviPage.font->fid ) ;
+ }
+ }
+ break;
+
+ case DT_XXX:
+ {
+ char specialBuffer [2048];
+ register char *cp;
+ int sweetp = 0;
+
+ if (p > 2047) {
+ sweetp = p - 2047;
+ p = 2047;
+ }
+
+ for (cp = specialBuffer ; p > 0; p--) {
+ *cp = mGetByte(&thisPage);
+ cp++;
+ }
+ *(cp) = 0;
+
+ while(sweetp > 0) {
+ mGetByte(&thisPage);
+ }
+
+ widget -> dviPage.dviStackPointer = dviStackP;
+ doSpecial(widget, specialBuffer);
+ }
+ break;
+
+ case DT_FNTDEF:
+ {
+ int i;
+ long j;
+ mGetLong(&thisPage, &j);
+ mGetLong(&thisPage, &j);
+ mGetLong(&thisPage, &j);
+ i = UnSign8(mGetByte(&thisPage));
+ i += UnSign8(mGetByte(&thisPage));
+ while (--i >= 0) {
+ (void) mGetByte(&thisPage);
+ }
+ }
+ break;
+
+ case DT_PRE:
+ GripeUnexpectedOp("PRE");
+ goto cleanup;
+ /* NOTREACHED */
+
+ case DT_POST:
+ GripeUnexpectedOp("POST");
+ goto cleanup;
+ /* NOTREACHED */
+
+ case DT_POSTPOST:
+ GripeUnexpectedOp("POSTPOST");
+ goto cleanup;
+ /* NOTREACHED */
+
+ case DT_UNDEF:
+ GripeUndefinedOp(c);
+ goto cleanup;
+ /* NOTREACHED */
+
+ default:
+ panic("DVI_DT(%d) = %d", c, DVI_DT(c));
+ goto cleanup;
+ /* NOTREACHED */
+ }
+ }
+ }
+
+ cleanup:
+ /* clean up laststring if there was one */
+
+ if ( dviStringLength > 0 ) {
+ i32 atHH = fastFromSP(widget, startHH);
+ i32 atVV = fastFromSP(widget, startVV);
+ Bool doit = True;
+
+ if ( widget -> dviPage.haveBackingStore ) {
+ i32 width = fastFromSP(widget, endHH);
+ i32 height = fastFromSP(widget, endVV);
+
+ doit =
+ XRectInRegion( widget -> dviPage.updateRegion, atHH, atVV,
+ width, height) != RectangleOut;
+ }
+
+ if (doit) {
+ XDrawString( XtDisplay( widget ), XtWindow( widget ),
+ page -> globalGC, atHH, atVV,
+ dviString, dviStringLength );
+ }
+ dviStringLength = 0;
+ }
+
+ return;
+
+}
+
+
+/* ARGSUSED */
+static void Redisplay (gw, event, region)
+ Widget gw;
+ XEvent *event; /* unused */
+ Region region; /* unused */
+{
+ DviPageWidget w = (DviPageWidget) gw;
+
+ if (XtIsRealized(w)) {
+
+ XGCValues values;
+ unsigned long fore = w->dviPage.foreground;
+ unsigned long aft = w->dviPage.background;
+
+ if ( w -> dviPage.reverseVideo ) {
+ unsigned long tmp = aft;
+ aft = fore;
+ fore = tmp;
+ }
+
+ /* Prepare to clear the main screen */
+
+ values.function = GXcopy;
+ values.foreground = aft;
+ values.background = fore;
+
+ XChangeGC( XtDisplay(gw), w -> dviPage.globalGC,
+ (unsigned) GCFunction | GCForeground | GCBackground,
+ &values);
+
+ XSetRegion( XtDisplay(w), w -> dviPage.globalGC, region );
+
+ XFillRectangle(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ 0, 0,
+ w -> core.width, w -> core.height);
+
+ /* Prepare to paint */
+
+ values.foreground = fore;
+ values.background = aft;
+ values.plane_mask = AllPlanes;
+ values.font = w->dviPage.font->fid;
+
+ if ( aft ) {
+ values.function = GXand;
+ }
+ else {
+ values.function = GXor;
+ }
+
+ XChangeGC( XtDisplay(gw), w -> dviPage.globalGC,
+ (unsigned) GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFont,
+ &values);
+
+ XSetRegion( XtDisplay(w), w -> dviPage.globalGC, region );
+
+ if (w -> dviPage.pai && w -> dviPage.page && w -> dviPage.dviFonts ) {
+
+ w -> dviPage.updateRegion = region;
+
+ DviDisplay(w);
+
+ }
+ }
+}
diff --git a/dviware/umddvi/previewers/texx2/dvipage.h b/dviware/umddvi/previewers/texx2/dvipage.h
new file mode 100644
index 0000000000..643ed0a2a3
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvipage.h
@@ -0,0 +1,64 @@
+#include <X11/copyright.h>
+
+#ifndef _DviPage_h
+#define _DviPage_h
+
+/****************************************************************
+*
+* DviPage widget
+*
+****************************************************************/
+
+/* Resources:
+
+Name Class RepType Default Value
+---- ----- ------- -------------
+background Background Pixel XtDefaultBackground
+border BorderColor Pixel XtDefaultForeground
+borderWidth BorderWidth Dimension 1
+destroyCallback Callback Pointer NULL
+height Height Dimension 0
+mappedWhenManaged MappedWhenManaged Boolean True
+sensitive Sensitive Boolean True
+width Width Dimension 0
+x Position Position 0
+y Position Position 0
+
+*/
+
+#include <X11/Xmu.h>
+
+/* define any special resource names here that are not in <X11/StringDefs.h> */
+
+#define XtNbackingStore "backingStore"
+ /* when server should use backing store */
+
+#define XtNpage "page"
+#define XtNpai "pai"
+#define XtNuserMag "userMag"
+#define XtNdpi "dpi"
+#define XtNdviFonts "dviFonts"
+#define XtNxFonts "xFonts"
+#define XtNpaperWidth "paperWidth"
+#define XtNpaperHeight "paperHeight"
+
+#define XtCBackingStore "BackingStore"
+#define XtCPage "Page"
+#define XtCPai "Pai"
+#define XtCUserMag "UserMag"
+#define XtCDpi "Dpi"
+#define XtCDviFonts "DviFonts"
+#define XtCXFonts "XFonts"
+#define XtCPaperWidth "PaperWidth"
+#define XtCPaperHeight "PaperHeight"
+
+/* declare specific DviPageWidget class and instance datatypes */
+
+typedef struct _DviPageClassRec* DviPageWidgetClass;
+typedef struct _DviPageRec* DviPageWidget;
+
+/* declare the class constant */
+
+extern WidgetClass dviPageWidgetClass;
+
+#endif _DviPage_h
diff --git a/dviware/umddvi/previewers/texx2/dvipage2.c b/dviware/umddvi/previewers/texx2/dvipage2.c
new file mode 100644
index 0000000000..0eedd7acca
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvipage2.c
@@ -0,0 +1,522 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/*
+ * 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 <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <stdio.h>
+#include "dvi-simple.h"
+#include "conv.h"
+#include <assert.h>
+
+#include "DviPageP.h"
+
+extern char *ProgName;
+
+#include <math.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define texPicConv(w,x) ( (x * w -> dviPage.pixelsPerInch) / 1000 )
+
+/*
+ * Draw a line from (fx,fy) to (tx,ty).
+ * Right now, we ignore pen_size.
+ */
+static void line_btw(w, fx, fy, tx, ty)
+ DviPageWidget w;
+ int fx, fy, tx, ty;
+{
+ int rx = fastFromSP(w, w -> dviPage.dviStackPointer -> h);
+ int ry = fastFromSP(w, w -> dviPage.dviStackPointer -> v);
+
+ fx = texPicConv(w, fx);
+ fy = texPicConv(w, fy);
+ tx = texPicConv(w, tx);
+ ty = texPicConv(w, ty);
+
+ if ( fx == tx && fy == ty ) {
+ fx += rx;
+ fy += ry;
+
+ if ( XPointInRegion(w -> dviPage.updateRegion, fx, ry) ) {
+ XDrawPoint(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC, fx, fy);
+ }
+ }
+ else {
+ XDrawLine(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ fx + rx, fy + ry, tx + rx, ty + ry);
+ }
+}
+
+/*
+ * Draw a dot at (x,y)
+ */
+static void dot_at(w, x, y)
+ DviPageWidget w;
+ int x;
+ int y;
+{
+ line_btw(w, x, y, x+1, y);
+}
+
+/*
+ * Apply the requested attributes to the last path (box) drawn.
+ * Attributes are reset.
+ */
+static void
+ do_attribute_path(w, last_min_x, last_max_x, last_min_y, last_max_y)
+DviPageWidget w;
+int last_min_x, last_max_x, last_min_y, last_max_y;
+{
+
+#ifdef UNDEF
+ /*
+ * This is the code as it appears in TeXsun. I dont have the time to
+ * make this do the shading in X-11. If someone does this, please post
+ * diffs to the net.
+ *
+ * Dirk Grunwald
+ */
+
+ static struct pixrect *shade_pr;
+
+ if (last_min_x < last_max_x && last_min_y < last_max_y) {
+ if (whiten) {
+ do_op(last_min_x, last_min_y,
+ xconv(last_max_x) - xconv(last_min_x),
+ yconv(last_max_y) - yconv(last_min_y),
+ PIX_SRC, (struct pixrect *) 0);
+ }
+ else if (blacken) {
+ do_op(last_min_x, last_min_y,
+ xconv(last_max_x) - xconv(last_min_x),
+ yconv(last_max_y) - yconv(last_min_y),
+ PIX_NOT(PIX_SRC), (struct pixrect *) 0);
+ }
+ else if (shade) {
+ if (!shade_pr) {
+ shade_pr = mem_create(3, 3, 1);
+ if (!shade_pr) Fatal("Out of memory -- cannot create pixrect");
+ pr_put(shade_pr, 0, 0, 1);
+ }
+ if (buildToPixmap) {
+ pr_replrop(pasteUpPixmap[currentShrink][currentLeaf],
+ xconv(last_min_x) + pen_size,
+ yconv(last_min_y) + pen_size,
+ xconv(last_max_x) - xconv(last_min_x) - pen_size,
+ yconv(last_max_y) - yconv(last_min_y) - pen_size,
+ PIX_SRC, shade_pr, 0, 0);
+ }
+ else {
+ int offset = currentLeaf*leaf_w[currentShrink]
+ pw_replrop(ptube,
+ xconv(last_min_x) + pen_size + offset,
+ yconv(last_min_y) + pen_size,
+ xconv(last_max_x) - xconv(last_min_x) - pen_size + offset,
+ yconv(last_max_y) - yconv(last_min_y) - pen_size,
+ PIX_SRC, shade_pr, 0, 0);
+ }
+ }
+ }
+ shade = blacken = whiten = FALSE;
+#endif
+}
+
+/*****************************************************************************/
+
+#define TWOPI (3.14159265359*2.0)
+#define MAX_PEN_SIZE 7 /* Max pixels of pen width */
+
+/* Unfortunately, these values also appear in dvisun.c */
+#define xRESOLUTION(w) ( w -> dviPage.pixelsPerInch )
+#define yRESOLUTION(w) ( w -> dviPage.pixelsPerInch )
+
+/*
+ * Set the size of the virtual pen used to draw in milli-inches
+ */
+
+/* ARGSUSED */
+static void set_pen_size(w, cp)
+ DviPageWidget w;
+ char *cp;
+{
+ int ps;
+
+ if (sscanf(cp, " %d ", &ps) != 1) {
+ error(0,0, "illegal .ps command format: %s", cp);
+ return;
+ }
+ w -> dviPage.penSize
+ = (ps*(xRESOLUTION(w)+yRESOLUTION(w)) + 1000) / 2000;
+ if (w -> dviPage.penSize < 1) {
+ w -> dviPage.penSize = 1;
+ }
+ else {
+ if (w -> dviPage.penSize > MAX_PEN_SIZE) {
+ w -> dviPage.penSize = MAX_PEN_SIZE;
+ }
+ }
+}
+
+
+/*
+ * Print the line defined by previous path commands
+ */
+static void flush_path(w)
+ DviPageWidget w;
+{
+ register int i;
+ int last_min_x, last_max_x, last_min_y, last_max_y;
+ int *xx = w -> dviPage.xx;
+ int *yy = w -> dviPage.yy;
+ int path_len = w -> dviPage.pathLen;
+
+ 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(w, 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];
+
+ w -> dviPage.pathLen = 0;
+
+ do_attribute_path(w, 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(w, cp, dotted)
+ DviPageWidget w;
+ char *cp;
+ int dotted;
+{
+ int i, numdots, x0, y0, x1, y1;
+ int cx0, cy0, cx1, cy1;
+ float inchesperdash;
+ double d, spacesize, a, b, dx, dy, milliperdash;
+
+ int *xx = w -> dviPage.xx;
+ int *yy = w -> dviPage.yy;
+ int path_len = w -> dviPage.pathLen;
+
+ if (sscanf(cp, " %f ", &inchesperdash) != 1) {
+ error(0,0,"illegal format for dotted/dashed line: %s", cp);
+ return;
+ }
+ if (path_len <= 1 || inchesperdash <= 0.0) {
+ error(0,0,"illegal conditions for dotted/dashed line");
+ return;
+ }
+ milliperdash = inchesperdash * 1000.0;
+ x0 = xx[1]; y0 = yy[1];
+ x1 = xx[2]; y1 = yy[2];
+ dx = x1 - x0;
+ dy = y1 - y0;
+ if (dotted) {
+ numdots = sqrt(dx*dx + dy*dy) / milliperdash + 0.5;
+ for (i=0; i <= numdots; i++) {
+ a = (float) i / (float) numdots;
+ cx0 = x0 + a*dx + 0.5;
+ cy0 = y0 + a*dy + 0.5;
+ dot_at(cx0, cy0);
+ }
+ }
+ else {
+ d = sqrt(dx*dx + dy*dy);
+ if (d <= 2.0*milliperdash)
+ line_btw(w, x0, y0, x1, y1);
+ else {
+ numdots = d / (2.0*milliperdash) + 1.0;
+ spacesize = (d - numdots * milliperdash) / (numdots - 1);
+ for (i=0; i<numdots-1; i++) {
+ a = i * (milliperdash + spacesize) / d;
+ b = a + milliperdash / d;
+ cx0 = x0 + a*dx + 0.5;
+ cy0 = y0 + a*dy + 0.5;
+ cx1 = x0 + b*dx + 0.5;
+ cy1 = y0 + b*dy + 0.5;
+ line_btw(w, cx0, cy0, cx1, cy1);
+ b += spacesize / d;
+ }
+ cx0 = x0 + b*dx + 0.5;
+ cy0 = y0 + b*dy + 0.5;
+ line_btw(w, cx0, cy0, x1, y1);
+ }
+ }
+
+ w -> dviPage.pathLen = 0;
+}
+
+
+/*
+ * Add a point to the current path
+ */
+static void add_path(w, cp)
+ DviPageWidget w;
+ char *cp;
+
+{
+ int pathx, pathy;
+
+ if (++( w -> dviPage.pathLen) >= MAXPOINTS) {
+ error(0,0, "Too many points");
+ return;
+ }
+ if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2) {
+ error(0,0,"Malformed path command");
+ return;
+ }
+ w-> dviPage.xx[w -> dviPage.pathLen] = pathx;
+ w-> dviPage.yy[w -> dviPage.pathLen] = pathy;
+}
+
+/*
+ * Draw an arc
+ */
+static void arc(w, cp)
+ DviPageWidget w;
+ char *cp;
+{
+ int xc, yc, xrad, yrad, n;
+ float start_angle, end_angle;
+ int angS, angE;
+ Bool doit = True;
+
+ int rx = fastFromSP(w, w -> dviPage.dviStackPointer -> h);
+ int ry = fastFromSP(w, w -> dviPage.dviStackPointer -> v);
+
+ if (sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad,
+ &start_angle, &end_angle) != 6) {
+ error(0,0,"illegal arc specification: %s", cp);
+ return;
+ }
+
+ xc = texPicConv(w, xc);
+ yc = texPicConv(w, yc);
+ xrad = texPicConv(w, xrad);
+ yrad = texPicConv(w, yrad);
+
+ angS = (int) ( (start_angle * 360 * 64) / TWOPI);
+ angE = (int) ( ((end_angle - start_angle) * 360 * 64) / TWOPI);
+
+ if ( w -> dviPage.haveBackingStore ) {
+ doit = XRectInRegion( w -> dviPage.updateRegion,
+ xc + rx - xrad, yc + ry - yrad,
+ 2 * xrad, 2 * yrad) != RectangleOut;
+ }
+
+ if (doit) {
+ XDrawArc(XtDisplay(w), XtWindow(w), w -> dviPage.globalGC,
+ xc + rx - xrad, yc + ry - yrad,
+ 2 * xrad, 2 * yrad, -angS, -angE);
+ }
+}
+
+
+/*
+ * 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(widget)
+ DviPageWidget widget;
+{
+ int xp, yp, N, lastx=(-1), lasty;
+ int t1, t2, t3, steps, j;
+ register int i, w;
+
+ int *xx = widget -> dviPage.xx;
+ int *yy = widget -> dviPage.yy;
+ int path_len = widget -> dviPage.pathLen;
+
+#ifdef lint
+ 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 (lastx > -1) line_btw(widget, lastx, lasty, xp, yp);
+ lastx = xp;
+ lasty = yp;
+ }
+ }
+
+ widget -> dviPage.pathLen = 0;
+}
+
+
+/*
+ * Shade the last box, circle, or ellipse
+ */
+static void shade_last(w)
+ DviPageWidget w;
+{
+ w -> dviPage.blacken = False;
+ w -> dviPage.whiten = False;
+ w -> dviPage.shade = True;
+}
+
+
+/*
+ * Make the last box, circle, or ellipse, white inside (shade with white)
+ */
+static void whiten_last(w)
+ DviPageWidget w;
+{
+ w -> dviPage.blacken = False;
+ w -> dviPage.whiten = True;
+ w -> dviPage.shade = False;
+}
+
+
+/*
+ * Make last box, etc, black inside
+ */
+static void blacken_last(w)
+ DviPageWidget w;
+{
+ w -> dviPage.blacken = True;
+ w -> dviPage.whiten = False;
+ w -> dviPage.shade = False;
+}
+
+/*
+ * Draw the bounding box for a \psfig special.
+ *
+ * expected format of the command string is
+ *
+ * width height bbllx bblly bburx bbury
+ *
+ * *ll* means lower-left, *ur* means upper-right.
+ *
+ * We just draw the bounding box.
+ */
+psfigBegin(w,cp)
+DviPageWidget w;
+char *cp;
+{
+ int bbllx, bblly;
+ int bburx, bbury;
+ int width, height;
+
+ int rx = fastFromSP(w, w -> dviPage.dviStackPointer -> h);
+ int ry = fastFromSP(w, w -> dviPage.dviStackPointer -> v);
+
+ sscanf(cp, " %d %d %d %d %d %d ",
+ &width, &height,
+ &bbllx, &bblly, &bburx, &bbury);
+
+ width = fastFromSP(w, width);
+ height = fastFromSP(w, height);
+
+ XDrawLine(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ rx, ry, rx + width, ry );
+ XDrawLine(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ rx + width, ry, rx + width, ry + height);
+ XDrawLine(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ rx + width, ry + height, rx, ry + height);
+ XDrawLine(XtDisplay(w), XtWindow(w),
+ w -> dviPage.globalGC,
+ rx, ry + height, rx, ry);
+}
+
+/*****************************************************************************/
+
+/*
+ * 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 64
+
+void doSpecial(w, cp)
+ DviPageWidget w;
+ 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(w,cp);
+ else if (strcmp(command, "fp") == 0) flush_path(w);
+ else if (strcmp(command, "da") == 0) flush_dashed(w, cp, 0);
+ else if (strcmp(command, "dt") == 0) flush_dashed(w, cp, 1);
+ else if (strcmp(command, "pa") == 0) add_path(w, cp);
+ else if (strcmp(command, "ar") == 0) arc(w, cp);
+ else if (strcmp(command, "sp") == 0) flush_spline(w);
+ else if (strcmp(command, "sh") == 0) shade_last(w);
+ else if (strcmp(command, "wh") == 0) whiten_last(w);
+ else if (strcmp(command, "bk") == 0) blacken_last(w);
+ else if (strcmp(command, "ps::[begin]") == 0) psfigBegin(w, cp);
+ else if (strncmp(command, "ps:",3) == 0) /* do nothing */;
+ else if (strncmp(command, "ln03", 4) == 0) /* do nothing */;
+ else {
+ error(0,0, "special \"%s\" not implemented", orig_cp);
+ }
+}
diff --git a/dviware/umddvi/previewers/texx2/dvipagep.h b/dviware/umddvi/previewers/texx2/dvipagep.h
new file mode 100644
index 0000000000..c81d078bf2
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/dvipagep.h
@@ -0,0 +1,106 @@
+#include <X11/copyright.h>
+
+/* $XConsortium: DviPageP.h,v 1.2 88/10/25 17:37:59 swick Exp $ */
+/* Copyright Massachusetts Institute of Technology 1987, 1988 */
+
+#ifndef _DviPageP_h
+#define _DviPageP_h
+
+#include "DviPage.h"
+/* include superclass private header file */
+
+#include <X11/CoreP.h>
+
+typedef struct {
+ int empty;
+} DviPageClassPart;
+
+typedef struct _DviPageClassRec {
+ CoreClassPart core_class;
+ DviPageClassPart dviPage_class;
+} DviPageClassRec;
+
+extern DviPageClassRec dviPageClassRec;
+
+typedef struct {
+ i32 stack_hh;
+ i32 stack_vv;
+ i32 h; /* the saved h */
+ i32 v; /* the saved v */
+ i32 w; /* etc */
+ i32 x;
+ i32 y;
+ i32 z;
+} LocalDviStack;
+
+typedef struct {
+ Pixel background;
+ Pixel foreground;
+
+ int useBackingStore; /* backing store type */
+ Bool haveBackingStore;
+
+ Bool reverseVideo;
+
+ XFontStruct *font;
+
+ /* private state */
+
+ GC globalGC;
+
+ char *page;
+ Dimension pixelsWide;
+ Dimension pixelsHigh;
+ Dimension pixelsPerInch;
+
+ char *paperWidthString;
+ char *paperHeightString;
+ float paperWidth;
+ float paperHeight;
+
+ XFontStruct **xFonts;
+
+ struct PostAmbleInfo *pai;
+ DviFontInfo *dviFonts;
+
+ int userMag;
+ int dpi;
+
+ Conv Conversion;
+ int fastFromSpValue;
+
+ Region updateRegion;
+
+ LocalDviStack *dviStack;
+ LocalDviStack *dviStackPointer;
+ int dviStackSize;
+
+ /* for tpic specials */
+#define MAXPOINTS 300 /* Max points in a path */
+ int texPicScale;
+ int xx[MAXPOINTS];
+ int yy[MAXPOINTS];
+ int pathLen;
+ int penSize;
+ Bool whiten;
+ Bool shade;
+ Bool blacken;
+} DviPagePart;
+
+typedef struct _DviPageRec {
+ CorePart core;
+ DviPagePart dviPage;
+} DviPageRec;
+
+#ifdef __STDC__
+static inline long fastFromSP(DviPageWidget w, long x)
+{
+ return( x / ( w -> dviPage.fastFromSpValue ) );
+}
+#else
+
+#define fastFromSP(w, x) ((x) / (w -> dviPage.fastFromSpValue))
+
+#endif
+
+#endif _DviPageP_h
diff --git a/dviware/umddvi/previewers/texx2/fonts b/dviware/umddvi/previewers/texx2/fonts
new file mode 100644
index 0000000000..d28d720595
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/fonts
@@ -0,0 +1,9 @@
+-scaled 1000
+cmr10 cmex10 cmr17 cmbx12 cmr12 cmtt10 cmbx10 cmti10 cmsy10 cmmi10
+cmbx9 cmsy9 cmmi9 cmr9 cmbx8 cmti8 cmti12 cmsy8 cmmi8 cmr8 cmsy7 cmmi7
+cmr7 cmsy6 cmmi6 cmr6 cmsy5 cmmi5 cmr5 cmsl10 lasy10 cmcsc12 cmbx14
+cmr14 cmr25
+-scaled 1200 cmbx17
+-scaled 1440 cmbx10 cmr10
+-scaled 1728 cmcsc10 cmti10
+-scaled 1200 cmcsc10
diff --git a/dviware/umddvi/previewers/texx2/fonts.distrib b/dviware/umddvi/previewers/texx2/fonts.distrib
new file mode 100644
index 0000000000..d28d720595
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/fonts.distrib
@@ -0,0 +1,9 @@
+-scaled 1000
+cmr10 cmex10 cmr17 cmbx12 cmr12 cmtt10 cmbx10 cmti10 cmsy10 cmmi10
+cmbx9 cmsy9 cmmi9 cmr9 cmbx8 cmti8 cmti12 cmsy8 cmmi8 cmr8 cmsy7 cmmi7
+cmr7 cmsy6 cmmi6 cmr6 cmsy5 cmmi5 cmr5 cmsl10 lasy10 cmcsc12 cmbx14
+cmr14 cmr25
+-scaled 1200 cmbx17
+-scaled 1440 cmbx10 cmr10
+-scaled 1728 cmcsc10 cmti10
+-scaled 1200 cmcsc10
diff --git a/dviware/umddvi/previewers/texx2/imakefile b/dviware/umddvi/previewers/texx2/imakefile
new file mode 100644
index 0000000000..465c122147
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/imakefile
@@ -0,0 +1,23 @@
+ DEFINES = -DDEFAULT_TFM_PATH=\".:/usr/local/lib/tex82/fonts\"
+
+ SRCS1 = texx2.c texx2-widgets.c \
+ texx2-file.c texx2-error.c dvi-simple.c \
+ texx2-page.c texx2-font.c texx2-mark.c \
+ DviPage.c DviPage2.c
+ OBJS1 = texx2.o texx2-widgets.o \
+ texx2-file.o texx2-error.o dvi-simple.o \
+ texx2-page.o texx2-font.o texx2-mark.o \
+ DviPage.o DviPage2.o
+ SRCS2 = mftobdf.c
+ OBJS2 = mftobdf.o
+ PROGRAMS = mftobdf texx2
+ INCLUDES = -I../h
+
+SYS_LIBRARIES = -lXaw -lXt -lXmu -lX11
+
+SingleProgramTarget(texx2,$(OBJS1),../lib/lib.a,-lm)
+InstallProgram(texx2, $(BINDIR))
+InstallManPage(texx2, $(MANDIR))
+
+SingleProgramTarget(mftobdf,$(OBJS2),../lib/lib.a,-lm)
+InstallProgram(mftobdf, $(BINDIR) )
diff --git a/dviware/umddvi/previewers/texx2/makefile b/dviware/umddvi/previewers/texx2/makefile
new file mode 100644
index 0000000000..55edaf18d0
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/makefile
@@ -0,0 +1,26 @@
+CC=gcc
+SRCS1 = texx2.c texx2-widgets.c \
+ texx2-file.c texx2-error.c dvi-simple.c \
+ texx2-page.c texx2-font.c texx2-mark.c \
+ DviPage.c DviPage2.c
+OBJS1 = texx2.o texx2-widgets.o \
+ texx2-file.o texx2-error.o dvi-simple.o \
+ texx2-page.o texx2-font.o texx2-mark.o \
+ DviPage.o DviPage2.o
+SRCS2 = mftobdf.c
+OBJS2 = mftobdf.o
+PROGRAMS = mftobdf texx2
+INCLUDES = -I../h -I~x/include
+SYS_LIBRARIES = -lXaw -lXt -lXmu -lX11
+FONTDESC =/u/tex/config/fontdesc
+
+.c.o:
+ $(CC) -c $< -DTEXFONTS=\".:/u/tex/mftfm:/u/tex/psftm\" $(INCLUDES)
+
+all: texx2 mftobdf
+
+texx2: $(OBJS1)
+ $(CC) -o texx2 $(OBJS1) $(SYS_LIBRARIES) ../lib/lib.a -lm
+
+mftobdf: $(OBJS2)
+ $(CC) -o mftobdf $(OBJS2) ../lib/lib.a -lm
diff --git a/dviware/umddvi/previewers/texx2/manifest b/dviware/umddvi/previewers/texx2/manifest
new file mode 100644
index 0000000000..b98eec15ab
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/manifest
@@ -0,0 +1,33 @@
+total 264
+-rw-r----- 1 tex 2112 Apr 3 17:49 00readme.tex
+-rw-r----- 1 tex 4097 Mar 17 22:58 ChangeLog
+-rw-r----- 1 tex 2309 Mar 28 11:01 Description
+-rw-r----- 1 tex 20508 Feb 26 02:11 DviPage.c
+-rw-r----- 1 tex 1671 Feb 17 18:03 DviPage.h
+-rw-r----- 1 tex 13451 Feb 25 21:11 DviPage2.c
+-rw-r----- 1 tex 1942 Feb 24 20:49 DviPageP.h
+-rw-r----- 1 tex 326 Mar 28 11:38 FONTS
+-rw-r----- 1 tex 326 Mar 28 12:41 FONTS.distrib
+-rw-r----- 1 tex 840 Mar 15 16:23 Imakefile
+-rw-r----- 1 tex 0 May 14 15:55 MANIFEST
+-rw-r----- 1 tex 790 Mar 30 12:35 Makefile
+-rw-r----- 1 tex 1964 Mar 2 02:07 README
+-rwxr-x--- 1 tex 276 Mar 28 13:02 buildfonts
+-rw-r----- 1 tex 10626 Mar 30 12:36 dvi-simple.c
+-rw-r----- 1 tex 1831 Feb 15 22:33 dvi-simple.h
+-rwxr-x--x 1 tex 114688 Mar 30 12:37 mftobdf
+-rw-r----- 1 tex 13450 Mar 28 13:37 mftobdf.c
+-rw-r----- 1 tex 1175 Feb 15 22:33 mio.h
+-rw-r----- 1 tex 117 Feb 15 22:33 texx2-defs.h
+-rw-r----- 1 tex 4485 Mar 17 22:58 texx2-error.c
+-rw-r----- 1 tex 8720 Mar 1 00:47 texx2-file.c
+-rw-r----- 1 tex 2750 Mar 1 01:04 texx2-font.c
+-rw-r----- 1 tex 172 Feb 17 18:02 texx2-font.h
+-rw-r----- 1 tex 2938 Mar 28 12:57 texx2-mark.c
+-rw-r----- 1 tex 559 Feb 15 22:33 texx2-mark.h
+-rw-r----- 1 tex 20912 Mar 1 00:19 texx2-page.c
+-rw-r----- 1 tex 1467 Feb 26 22:25 texx2-page.h
+-rw-r----- 1 tex 5718 Feb 24 20:15 texx2-widgets.c
+-rw-r----- 1 tex 742 Feb 19 20:47 texx2-widgets.h
+-rw-r----- 1 tex 2511 Mar 28 12:57 texx2.c
+-rw-r----- 1 tex 1040 Mar 1 00:18 texx2.h
diff --git a/dviware/umddvi/previewers/texx2/mftobdf.c b/dviware/umddvi/previewers/texx2/mftobdf.c
new file mode 100644
index 0000000000..ea179ee2f5
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/mftobdf.c
@@ -0,0 +1,600 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "../h/types.h"
+#include "../h/font.h"
+
+#include "../h/conv.h"
+#include "../h/dvi.h"
+#include "../h/dviclass.h"
+#include "../h/dvicodes.h"
+#include "../h/postamble.h"
+#include "../h/search.h"
+#include "../h/fio.h"
+
+/* X11 related files */
+
+int DviBlackness = -1;
+int DviDpi = 300;
+int DviMag = 1000;
+int DviDsz = 1000;
+char *ProgName;
+int ShowSnf = 0;
+int UserMag = 1000;
+
+long Numerator = 25400000;
+long Denomonator = 473628272;
+
+Conv Conversion;
+float DviFontTfmScale;
+
+#define GF_SHRUNK GF_USR0
+#define GLYPH_SHRUNK(g) ((g) -> g_flags & GF_SHRUNK)
+#define SHRUNK_GLYPH_BYTES_WIDE(g) ((((g) -> g_width + 15) >> 4) * 2)
+#define DEFAULT_BLACKNESS 3
+
+#define TWOTO16 0x10000
+#define TWOTO24 16777216
+#define PTPI 72.27
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ char *name = 0;
+ char *dev = "canon";
+ char *fname = 0;
+ int arg;
+ extern void processFont();
+
+ struct font *theFont;
+
+ ProgName = argv[0];
+
+ for (arg = 1; arg < argc; arg++) {
+ char *str = argv[arg];
+ if ( strcmp(str, "-scaled") == 0 ) {
+ arg++;
+ DviMag = atoi( argv[arg] );
+ }
+ else if ( strcmp(str, "-dpi") == 0 ) {
+ arg++;
+ DviDpi = atoi( argv[arg] );
+ }
+ else if ( strcmp(str, "-size") == 0 ) {
+ arg++;
+ DviDsz = atoi( argv[arg] );
+ }
+ else if ( strcmp(str, "-dev") == 0 ) {
+ arg++;
+ dev = argv[arg];
+ }
+ else if ( strcmp(str, "-show") == 0 ) {
+ ShowSnf = !ShowSnf;
+ }
+ else if ( strcmp(str, "-mag") == 0 ) {
+ arg++;
+ UserMag = atoi(argv[arg]);
+ }
+ else if ( strcmp(str, "-b") == 0 ) {
+ arg++;
+ DviBlackness = atoi(argv[arg]);
+ }
+ else if ( str[0] != '-' ) {
+ name = argv[arg];
+
+ if ( name == 0 ) {
+ fprintf(stderr,"%s: you must specify a font name\n", ProgName);
+ exit(1);
+ }
+
+/* We read the font in at mag and then step it down to user mag, so
+ assume here that usermag is 1000 */
+
+ SetConversion(DviDpi, 1000, Numerator, Denomonator, 1000);
+
+ theFont = GetFont(name, DviMag, DviDsz, dev, &fname);
+ if ( theFont == 0 ) {
+ fprintf(stderr,"Unable to locate ``%s''\n", name);
+ continue;
+ }
+
+ if ( fname != 0 ) {
+ fprintf(stderr,"%s: returned name is %s\n", ProgName, fname);
+ fprintf(stderr,"%s: which lives in %s\n",
+ ProgName, theFont -> f_path);
+ }
+
+/* DviFontTfmScale = fromSP( theFont -> f_design_size); */
+ DviFontTfmScale = ((double)theFont -> f_design_size);
+ DviFontTfmScale *= 1000;
+ DviFontTfmScale /= (double) TWOTO24;
+
+ processFont( theFont, name );
+
+ }
+ else {
+ fprintf(stderr,"%s: don't grok ``%s''\n", ProgName, argv[arg]);
+ exit(1);
+ }
+ }
+ exit(0);
+}
+
+/*
+ * The following routine is used to shrink a glyph by some
+ * shrink factor (in the width & height dimension).
+ *
+ * These shrunken glyphs are more appropriate for previewers.
+ *
+ * To do this, we simple scan the original raster, counting the
+ * number of pixels within a given area. If the number of on pixels is
+ * at least twice the total number of pixels, we turn the pixel in
+ * the shrunken glyph ON, else OFF.
+ *
+ * We use a lookup table to hasten the process of counting pixels.
+ *
+ * The method used should be independent of byte-order (I think).
+ *
+ * You need to define two types. One should be 32-bits long, and
+ * the other 16 bits long.
+ */
+
+typedef unsigned char BITS_8;
+typedef unsigned short BITS_16;
+typedef unsigned long BITS_32;
+
+#define LOOKUP_BYTES 256
+#define LOOKUP_BITS 8
+#define LOOKUP_MASK 0xff
+
+static char dviLookUpTable[LOOKUP_BYTES];
+static char tableNotInitialized = 1;
+
+struct glyph *
+dviShrinkGlyph(gly, font, rotation,shrinkH, shrinkW, blackness, killOld)
+struct glyph *gly;
+struct font *font;
+int rotation;
+int shrinkH;
+int shrinkW;
+int blackness;
+int killOld;
+{
+ int shrunkHeight;
+ int shrunkWidth;
+ int glyphWide;
+ int glyphHigh;
+ int glyphAdvance;
+ int shrunkAdvance;
+
+ int bytesWide;
+ int shrunkBytesWide;
+
+ struct glyph *ngly;
+
+ BITS_16 *shrunkRaster;
+ int rasterSize;
+
+ long width;
+ long dvimag;
+
+ int x,y;
+ BITS_8 *cp;
+ BITS_8 *ptr;
+
+ BITS_32 shrinkMask;
+
+ int sampleSize;
+
+ if (gly == 0 || !HASRASTER(gly) || (gly -> g_width < 0) ) {
+ return(0);
+ }
+
+ if (gly -> g_raster == 0) {
+ gly-> g_raster = RASTER(gly, font, rotation);
+ }
+
+#ifdef UNDEF
+ if ( shrinkH == 1 ) {
+ return( gly );
+ }
+#endif
+
+/*
+ * Initialize the lookup table of the number of bits in a given byte
+ */
+
+ if (tableNotInitialized) {
+ register int i;
+ register int j;
+ register int k;
+ register int acc;
+ for (i = 0; i < LOOKUP_BYTES; i++) {
+ j = i;
+ acc = 0;
+ for (k = 0; j != 0 && k < LOOKUP_BITS ; k++) {
+ acc += (j & 1);
+ j >>= 1;
+ }
+ dviLookUpTable[i] = acc;
+ }
+ tableNotInitialized = 0;
+ }
+
+ glyphHigh = gly -> g_height;
+ glyphWide = gly -> g_width;
+
+/*
+ * The following computes the ``escapement'' or the TFMwidth in
+ * pixels. This converted to the DWIDTH in the bdf files.
+ *
+ * This is a screwy point with Toreks library. He changes
+ * the values of the design_size
+ *
+ */
+ dvimag = font -> f_design_size / 16;
+ dvimag *= font -> f_scaled;
+ dvimag /= 1000;
+ width = ScaleOneWidth( gly -> g_rawtfmwidth, dvimag);
+ gly -> g_pixwidth = fromSP( width );
+ glyphAdvance = (gly -> g_pixwidth);
+
+ shrunkHeight = (glyphHigh + shrinkH - 1) / shrinkH;
+ shrunkWidth = (glyphWide + shrinkW - 1) / shrinkW;
+ shrunkAdvance = (glyphAdvance + shrinkW - 1) / shrinkW;
+
+ bytesWide = (gly -> g_width + 7) >> 3;
+
+ shrunkBytesWide = ((shrunkWidth + 7) >> 3);
+
+ rasterSize = (shrunkHeight + 1) * shrunkBytesWide;
+ shrunkRaster = (BITS_16 *) malloc(rasterSize);
+ bzero(shrunkRaster, rasterSize);
+ ptr = (BITS_8 *) shrunkRaster;
+
+ if (shrunkRaster == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+
+ for (y = 0; y < glyphHigh; y+= shrinkH) {
+ cp = (BITS_8 *) ptr;
+ shrinkMask = 0x80;
+ for (x = 0; x < glyphWide; x += shrinkW) {
+ int i;
+ int samples;
+ BITS_8 *baseP;
+ int upper;
+ register int thisShrinkW;
+
+ baseP = (BITS_8 *) gly -> g_raster + (y * bytesWide);
+
+/*
+ * Set the upper limit on the height iteration so we dont count
+ * off the end of the raster
+ */
+
+ upper = y + shrinkH;
+ if (upper > glyphHigh) {
+ upper = glyphHigh;
+ }
+
+ if (x + shrinkW > glyphWide) {
+ thisShrinkW = glyphWide - x;
+ } else {
+ thisShrinkW = shrinkW;
+ }
+
+ samples = 0;
+ sampleSize = thisShrinkW * shrinkH;
+
+ for (i = y; i < upper; i++) {
+ register int acc;
+ register BITS_8 *p;
+ register BITS_8 *ep;
+/*
+ * Determine how many bytes our shrink window crosses (we might
+ * overlap on byte-edges)
+ */
+
+ p = baseP + (x >> 3);
+ ep = baseP + ( (x + thisShrinkW - 1) >> 3);
+ baseP += bytesWide;
+
+/*
+ * stuff everything in the accumulator
+ */
+
+ acc = 0;
+ while (p <= ep) {
+ acc = ((acc << 8) & 0xff) | *p;
+ p++;
+ }
+
+/*
+ * clean off the right hand-side of extra bits, then clean off
+ * the left hand side of extra bits, and then count them.
+ */
+
+ acc = acc >> ( 7 - ((x + thisShrinkW - 1) & 0x7));
+ acc &= ~(-1 << thisShrinkW);
+ while (acc != 0) {
+ samples += dviLookUpTable[ acc & LOOKUP_MASK ];
+ acc >>= LOOKUP_BITS;
+ }
+ }
+/*
+ * If at least 1/blackness of the bits are on, treat this entire sample as
+ * being on.
+ */
+
+ if ((samples * blackness) >= sampleSize) {
+ *ptr |= shrinkMask;
+ } else {
+ *ptr &= ~ shrinkMask;
+ }
+ shrinkMask >>= 1;
+ if (shrinkMask == 0) {
+ shrinkMask = 0x80;
+ ptr ++;
+ }
+ }
+ ptr = (BITS_8 *) (cp + shrunkBytesWide);
+ }
+
+/*
+ * Build a new glyph from the shrunken raster
+ */
+
+ if (ShowSnf) {
+ printf("Old glyph:\n");
+ seeGlyph(gly -> g_raster, glyphHigh, bytesWide);
+ printf("New glyph:\n");
+ seeGlyph(shrunkRaster, shrunkHeight, shrunkBytesWide);
+ }
+
+ ngly = (struct glyph *) malloc(sizeof(struct glyph));
+ bzero(ngly, sizeof(struct glyph));
+
+ ngly -> g_raster = (char * ) shrunkRaster;
+ ngly -> g_un.g_integer = shrunkBytesWide;
+ ngly -> g_width = shrunkWidth;
+ ngly -> g_pixwidth = shrunkAdvance;
+ ngly -> g_height = shrunkHeight;
+
+ ngly -> g_xorigin = gly -> g_xorigin / shrinkH;
+ ngly -> g_yorigin = gly -> g_yorigin / shrinkW;
+
+ ngly -> g_flags |= GF_SHRUNK; /* yes, its been shrunk */
+
+ if ( killOld && gly -> g_raster ) {
+ free ( gly -> g_raster );
+ gly -> g_raster = 0;
+ }
+
+ return(ngly);
+}
+
+seeGlyph(c, h, w)
+char *c;
+int h;
+int w;
+{
+ int i,j;
+
+ for (i = 0; i < h; i++ ) {
+ for (j = 0; j < w; j++) {
+ int k;
+ register int ch;
+ register int m;
+ char str[9];
+
+ ch = *(c++);
+ m = 0x80;
+ for (k = 0; k < 8; k++) {
+ str[k] = ( (ch & m) ? '#' : '-' );
+ m >>= 1;
+ }
+ str[8] = 0;
+ printf("%s", str);
+ }
+ printf("\n");
+ }
+}
+
+printhex(f,n)
+FILE *f;
+int n;
+{
+ fputc("0123456789abcdef"[(n >> 4) & 0xf], f);
+ fputc("0123456789abcdef"[n & 0xf], f);
+}
+
+/* SNF related junk */
+
+void
+processFont(f, name)
+struct font *f;
+char *name;
+{
+ struct glyph *g;
+ int c;
+ int blackness;
+
+ int maxOverlap;
+ int nnonexistchars;
+
+#define MAX_CHARACTER 127
+
+ int glyphBytes[ MAX_CHARACTER + 1];
+ struct glyph *shrunkGlyphs[ MAX_CHARACTER + 1];
+
+ int totalGlyphs;
+ int pointSize;
+ int shrink;
+
+ int min_width = TWOTO16;
+ int max_width = -TWOTO16;
+
+ int min_height = TWOTO16;
+ int max_height = -TWOTO16;
+
+ int min_xorigin = TWOTO16;
+ int max_xorigin = -TWOTO16;
+
+ int min_yorigin = TWOTO16;
+ int max_yorigin = -TWOTO16;
+
+#define MIN(x,y) ((x < y) ? (x) : (y))
+#define MAX(x,y) ((x < y) ? (y) : (x))
+
+#ifdef __STDC__
+#define MINMAX(x,y) { min_##x = MIN(min_##x,y); max_##x = MAX(max_##x,y); }
+#else
+#define MINMAX(x,y) { min_/**/x = MIN(min_/**/x,y); max_/**/x = MAX(max_/**/x,y); }
+#endif
+
+ char newFileName[256];
+ char newName[256];
+ FILE *fontOut;
+ int i;
+
+ double suffMag = (double) DviMag / (double) DviDsz;
+ int scaled = (suffMag * 1000 + 0.5);
+ int suff = (DviDpi * UserMag * DviMag) / (1000 * 1000);
+
+ if ( f -> f_design_size == 0 ) {
+ return;
+ }
+
+ shrink = 1000 / UserMag ;
+ if (shrink < 1 ) {
+ shrink = 1;
+ }
+ else if ( shrink > 10 ) {
+ shrink = 10;
+ }
+
+ blackness = DviBlackness;
+ blackness = (blackness < 1) ? DEFAULT_BLACKNESS : blackness;
+
+ sprintf(newName, "%s.%d", name, suff);
+ sprintf(newFileName, "%s.bdf", newName);
+
+ fontOut = fopen(newFileName,"w");
+
+ if (! fontOut ) {
+ perror("fopen");
+ exit(1);
+ }
+
+ totalGlyphs = 0;
+
+ for( c = f -> f_lowch; c < f -> f_highch; c++ ) {
+ g = GLYPH(f,c);
+ shrunkGlyphs[c] = 0;
+
+ if (GVALID(g) && HASRASTER(g)) {
+ struct glyph *s;
+
+ s = dviShrinkGlyph( g, f, ROT_NORM, shrink, shrink, blackness, 1);
+ shrunkGlyphs[c] = s;
+
+ if (s == 0 )
+ continue;
+
+ totalGlyphs++;
+
+ MINMAX(width, s->g_width);
+ MINMAX(height, s->g_height);
+ MINMAX(xorigin, s->g_xorigin);
+ MINMAX(yorigin, s->g_yorigin);
+
+ }
+ }
+
+ fprintf(fontOut, "STARTFONT 2.1\n");
+ fprintf(fontOut,
+ "COMMENT This font image translated from Metafont\n");
+ fprintf(fontOut, "COMMENT Input file was ``%s''\n", name);
+ fprintf(fontOut, "COMMENT DPI was ``%d'', usermag ``%d'', blackness ``%d''\n",
+ DviDpi, UserMag, blackness);
+ fprintf(fontOut, "COMMENT shrink was %d\n", shrink);
+
+ fprintf(fontOut, "FONT %s\n", newName);
+
+ pointSize = (f -> f_design_size) / (TWOTO16 * 16);
+ fprintf(fontOut, "SIZE %d %d %d\n", pointSize, suff, suff);
+
+ fprintf(fontOut, "FONTBOUNDINGBOX %d %d %d %d\n",
+ max_width + 1, max_height,
+ -max_xorigin, max_yorigin - max_height + 1);
+
+ /* These follow the X conventions */
+
+ fprintf(fontOut,"STARTPROPERTIES 3\n");
+ fprintf(fontOut,"FONT_ASCENT %d\n",
+ max_height - min_yorigin);
+ fprintf(fontOut,"FONT_DESCENT %d\n",
+ min_yorigin);
+ fprintf(fontOut,"COPYRIGHT \"Public Domain\"\n");
+ fprintf(fontOut,"ENDPROPERTIES\n");
+ fprintf(fontOut,"CHARS %d\n", totalGlyphs);
+
+ for( c = f -> f_lowch; c < f -> f_highch; c++ ) {
+ if ( shrunkGlyphs[c] != 0 ) {
+ int column;
+ int width;
+ float swidth;
+ int bytes;
+ int byte;
+ char *p;
+ struct glyph *s = shrunkGlyphs[c];
+
+ if ( s -> g_raster == 0 ) {
+ continue; /* to next one */
+ }
+
+ fprintf(fontOut, "STARTCHAR C%03d\n",c);
+ fprintf(fontOut, "ENCODING %d\n",c);
+
+ /* I don't know why it's off by one, but it is.. */
+
+ width = s -> g_pixwidth;
+
+ swidth = (double) ( width * 72000 ) / (double) ( pointSize * DviDpi );
+ fprintf(fontOut, "SWIDTH %d %d\n", (int) swidth, 0);
+ fprintf(fontOut, "DWIDTH %d %d\n", width, 0);
+
+ fprintf(fontOut, "BBX %d %d %d %d\n",
+ s -> g_width, /* width, height of bounding box */
+ s -> g_height,
+ -s -> g_xorigin, /* offset of origin w.r.t. lower left corner*/
+ s -> g_yorigin - s -> g_height + 1);
+ fprintf(fontOut, "BITMAP\n");
+
+ column = 0;
+ width = s -> g_un.g_integer;
+ bytes = width * s -> g_height;
+ for( p = s -> g_raster, byte = 0; byte < bytes; byte++, p++, column++ ) {
+ if (column >= width) {
+ fprintf(fontOut,"\n");
+ column = 0;
+ }
+ printhex(fontOut,*p);
+ }
+ if (column == width) {
+ fprintf(fontOut,"\n");
+ }
+ fprintf(fontOut, "ENDCHAR\n");
+ }
+ }
+ fprintf(fontOut, "ENDFONT\n");
+}
diff --git a/dviware/umddvi/previewers/texx2/mio.h b/dviware/umddvi/previewers/texx2/mio.h
new file mode 100644
index 0000000000..cb2b84bfbf
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/mio.h
@@ -0,0 +1,64 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/*
+ * Memory I/O: numbers.
+ *
+ */
+
+#ifdef __STDC__
+
+static
+inline int mGetByte(char **m)
+{
+ unsigned char foo = **m;
+ unsigned int retval = foo & 0xff;
+ (*m)++;
+ return retval;
+}
+
+static
+inline void mGetWord( char **m, i32 *r)
+{
+ int x = mGetByte( m ) << 8;
+ x |= mGetByte(m);
+ *r = x;
+}
+
+static
+inline void mGet3Byte( char **m, i32 *r)
+{
+ long x = mGetByte( m ) << 16;
+ x |= ( mGetByte(m ) << 8 );
+ x |= mGetByte(m);
+ *r = x;
+}
+
+static
+inline void mGetLong( char **m, i32 *r)
+{
+ long x = mGetByte( m ) << 24;
+ x |= ( mGetByte(m) << 16 );
+ x |= ( mGetByte(m) << 8 );
+ x |= mGetByte(m);
+ *r = x;
+}
+
+#else
+
+#define mGetByte(m) ( *((*m)++) & 0xff )
+
+#define mGetWord(m, r) {*(r) = mGetByte(m) << 8; *(r) |= mGetByte(m);}
+
+#define mGet3Byte(m,r) {*(r) = mGetByte(m) << 16;\
+ *(r) |= mGetByte(m) << 8;\
+ *(r) |= mGetByte(m);}
+
+#define mGetLong(m, r) {*(r) = mGetByte(m) << 24;\
+ *(r) |= mGetByte(m) << 16;\
+ *(r) |= mGetByte(m) << 8;\
+ *(r) |= mGetByte(m);}
+
+#endif
diff --git a/dviware/umddvi/previewers/texx2/readme b/dviware/umddvi/previewers/texx2/readme
new file mode 100644
index 0000000000..af51b5391c
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/readme
@@ -0,0 +1,57 @@
+Sorry, this file got let out of the original distribution.
+
+This directory contains several tools to manipulate the DVI files produced
+by TeX and LaTeX. Additionally, it includes a re-distribution of the
+DVI library routines written by Chris Torek at the University of Maryland.
+The utilities included are:
+
+dviselect select specific pages from a DVI file
+iptex print a dvi file on an Imagen
+texx a dvi previewer for X-11 windows
+texsun a dvi previewer for SunView windows
+
+texx2 a much improved dvi previewer for X-11 windows
+
+To install this package, read the documentation in the file
+doc/installation.tex. The short instructions follow.
+
+FOR TEXX2:
+
+ + Change the binary path names in the ./Makefile.
+
+ + Select a location for your ``font description'' file, and copy and
+ modify the file in fontdesc-example to suit your local installation.
+ Change the main makefile to use that path for variable FONTDESC
+
+ The default is /usr/local/lib/tex82/fontdesc
+
+ + cd to texx2; Edit the Imakefile. Note that DEFAULT_TFM_PATH
+ defines the default path for finding .tfm files, just like TeX.
+
+ + Build a Makefile from the Imakefile
+
+ + run ``make texx2'' at the main level
+
+ + texx2 should now be built. You'll need to install some fonts.
+
+ + in run texx2/mftobdf -mag 1000 -scaled 1000 cmr10. If mftobdf
+ can't find your font, you've got a bad fontdesc file or the
+ path to it is wrong.
+
+ + assuming that this works, edit texx2/buildfonts to suite your
+ local X configuration. I keep fonts in /usr/local/lib/X11/fonts/cmr,
+ and have added this to my font path using
+ % xset +fp /usr/local/lib/X11/fonts/cmr
+ % xset fp rehash
+
+ + in texx2, run "buildfonts -mag 500 `cat FONTS` " to build a
+ fair number of standard fonts. Note that the default is
+ 300 dpi. If you want a smaller set too, say ``-mag 333''.
+
+ + You can use other DPI's -- both texx2 & mftobdf have switches
+ for this.
+
+Dirk Grunwald
+Univ. of Illinois
+grunwald@m.cs.uiuc.edu
+
diff --git a/dviware/umddvi/previewers/texx2/texx2-defs.h b/dviware/umddvi/previewers/texx2/texx2-defs.h
new file mode 100644
index 0000000000..5373a96b19
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-defs.h
@@ -0,0 +1,4 @@
+
+#define XtIsPoppedUp(widget) ( widget -> shell.popped_up )
+
+#define TOPBOXNAME "topBox" /* Name of the Top Box. */
diff --git a/dviware/umddvi/previewers/texx2/texx2-error.c b/dviware/umddvi/previewers/texx2/texx2-error.c
new file mode 100644
index 0000000000..fdb0854ce5
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-error.c
@@ -0,0 +1,224 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/*
+ * Print an error message with an optional system error number, and
+ * optionally quit.
+ *
+ */
+
+#include <stdio.h>
+#include <varargs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/ShellP.h>
+#include <X11/AsciiText.h>
+#include "texx2.h"
+#include "texx2-widgets.h"
+
+#ifdef _STDC_
+ extern char* malloc(int);
+ extern char* realloc(char *, int);
+#else
+ extern char* malloc();
+ extern char* realloc();
+#endif
+
+#define ERROR_BUFFER_SIZE 2048
+static char errorMessageBuffer[ ERROR_BUFFER_SIZE ]
+ = {"Welcome to TeXx-2.8.5\nThis is the dialog box\n"};
+static int errorMessageBufferLength=0;
+
+static message(str,quit)
+ char *str;
+ int quit;
+{
+
+ if ( errorText ) {
+ int len = strlen(str);
+ char *p;
+ XtTextPosition start;
+ XtTextPosition end;
+ XtTextBlock tblk;
+
+ tblk.firstPos = 0;
+ tblk.length = len;
+ tblk.ptr = str;
+ tblk.format = FMT8BIT;
+
+ if ( len > 0 && str[len-1] != '\n' ) {
+ str[len] = '\n';
+ str[len+1] = 0;
+ tblk.length = len+1;
+ }
+
+ start = strlen( errorMessageBuffer );
+
+ if ( start + len > ERROR_BUFFER_SIZE ) {
+ start = 0;
+ bzero( errorMessageBuffer, ERROR_BUFFER_SIZE );
+ }
+
+ end = start;
+
+ XtTextDisableRedisplay(errorText);
+
+ XtTextSetInsertionPoint(errorText, start);
+ XtTextSetLastPos( errorText, start );
+
+ XtTextReplace( errorText, start, end, &tblk );
+
+ XtTextEnableRedisplay(errorText);
+
+ }
+}
+
+static void
+pushClearButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ bzero( errorMessageBuffer , ERROR_BUFFER_SIZE );
+
+ XtTextDisableRedisplay(errorText);
+ XtTextSetInsertionPoint(errorText, 0);
+ XtTextSetLastPos( errorText, 0 );
+ XtTextEnableRedisplay(errorText);
+}
+
+/*
+ * If you had a real compiler, these would all be
+ * local the next function
+ */
+
+static XtCallbackRec clearButtonCallBacks [] = {
+ {pushClearButton,NULL},
+ {NULL, NULL}
+};
+
+static Arg clearButtonArgs[] = {
+ {XtNcallback, (XtArgVal) clearButtonCallBacks}
+};
+
+static Arg textArgs[] = {
+ {XtNeditType, (XtArgVal) XttextEdit},
+ {XtNstring, (XtArgVal) errorMessageBuffer},
+ {XtNlength, (XtArgVal) ERROR_BUFFER_SIZE},
+ {XtNtextOptions, (XtArgVal) (scrollVertical | scrollOnOverflow | wordBreak )}
+};
+
+void
+BuildErrorBox()
+{
+
+ clearButton =
+ XtCreateManagedWidget("Clear Dialog Box",
+ commandWidgetClass, topPane,
+ clearButtonArgs, XtNumber(clearButtonArgs));
+ errorText =
+ XtCreateManagedWidget("Error-Text",
+ asciiStringWidgetClass, topPane,
+ textArgs, XtNumber(textArgs));
+}
+
+
+#ifdef lint
+
+/* VARARGS3 ARGSUSED */
+error(quit, e, fmt) int quit, e; char *fmt; {;}
+
+/* VARARGS1 ARGSUSED */
+panic(fmt) char *fmt; { exit(1); /* NOTREACHED */ }
+
+#else lint
+
+extern char *ProgName;
+extern int errno;
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+#define ERROR_MSG_LEN 1024
+static char ErrorMsgBuffer[ ERROR_MSG_LEN ];
+
+error(va_alist)
+ va_dcl
+{
+ va_list l;
+ int quit, e;
+ char *fmt;
+ char *p;
+
+ p = ErrorMsgBuffer;
+
+ va_start(l);
+ /* pick up the constant arguments: quit, errno, printf format */
+ quit = va_arg(l, int);
+ e = va_arg(l, int);
+ if (e < 0)
+ e = errno;
+
+ fmt = va_arg(l, char *);
+
+#if defined(sun)
+ (void) vsprintf(p, fmt, l);
+#else
+ /* Does someone know how to do this properly? */
+
+ {
+ struct _iobuf ungodlyhack;
+ ungodlyhack._cnt = ERROR_MSG_LEN;
+ ungodlyhack._ptr = p;
+ ungodlyhack._base = p;
+ ungodlyhack._bufsiz = ERROR_MSG_LEN;
+ ungodlyhack._flag = _IOSTRG;
+ ungodlyhack._file = 255;
+ _doprnt(fmt, l, &ungodlyhack);
+ }
+#endif
+
+ va_end(l);
+
+ message( ErrorMsgBuffer, quit);
+}
+
+panic(va_alist)
+ va_dcl
+{
+ va_list l;
+ char *fmt;
+ char *p;
+
+ p = ErrorMsgBuffer;
+ sprintf(p, "panic: ");
+ p += strlen(p);
+
+ va_start(l);
+ /* pick up the constant arguments: quit, errno, printf format */
+ fmt = va_arg(l, char *);
+
+#if defined(sun)
+ (void) vsprintf(p, fmt, l);
+#else
+ /* Does someone know how to do this properly? */
+
+ {
+ struct _iobuf ungodlyhack;
+ ungodlyhack._cnt = ERROR_MSG_LEN;
+ ungodlyhack._ptr = p;
+ ungodlyhack._base = p;
+ ungodlyhack._bufsiz = ERROR_MSG_LEN;
+ ungodlyhack._flag = _IOSTRG;
+ ungodlyhack._file = 255;
+ _doprnt(fmt, l, &ungodlyhack);
+ }
+#endif
+
+ va_end(l);
+
+ message(ErrorMsgBuffer, 1);
+}
+
+#endif /* lint */
diff --git a/dviware/umddvi/previewers/texx2/texx2-file.c b/dviware/umddvi/previewers/texx2/texx2-file.c
new file mode 100644
index 0000000000..b4fa05310c
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-file.c
@@ -0,0 +1,383 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include "texx2.h"
+
+#include <errno.h>
+#include <sys/param.h>
+#include <assert.h>
+#include "dvi-simple.h"
+#include "texx2-page.h"
+#include "texx2-mark.h"
+#include "texx2-widgets.h"
+
+char TeXInputFileNameString[MAXPATHLEN+40];
+char *TeXInputFileName;
+
+char TeXInputDirNameString[MAXPATHLEN+40];
+char *TeXInputDirName;
+
+char fileNameInput[MAXPATHLEN];
+
+/*
+ * If it's a file name, set to the directory of that file,
+ * otherwise, set to the directory
+ */
+void
+setDirectory(dir)
+char *dir;
+{
+ Arg argList[20];
+ Cardinal args;
+
+ char pDir[MAXPATHLEN];
+ char *endPDir;
+ int len;
+
+ strncpy(pDir,dir,MAXPATHLEN);
+ len = strlen(pDir);
+ endPDir = &pDir[len];
+
+ while (chdir(pDir) < 0) {
+ /* skip back to last slash */
+ while (endPDir != pDir && *endPDir != '/') endPDir--;
+
+ if (endPDir == pDir) {
+ getwd(pDir);
+ }
+ else {
+ *endPDir = 0;
+ }
+
+ }
+
+ getwd(pDir);
+
+ strcpy(TeXInputDirNameString, "Directory: ");
+ TeXInputDirName = &TeXInputDirNameString[strlen(TeXInputDirNameString)];
+ strncpy(TeXInputDirName, pDir, MAXPATHLEN);
+
+ if ( directoryLabel != NULL ) {
+ args = 0;
+ XtSetArg(argList[args], XtNlabel, TeXInputDirNameString); args++;
+ XtSetArg(argList[args], XtNmaximumLength, MAXPATHLEN); args++;
+
+ XtSetValues( directoryLabel, argList, args);
+ }
+}
+
+void
+ setFileName(fileName)
+char *fileName;
+{
+ if ( fileNameText && XtIsRealized( fileNameText ) ) {
+ XtTextBlock tblk;
+ int len = (fileName == 0) ? 0 : strlen(fileName);
+
+ if ( len > 0 ) {
+ XtTextPosition start = 0;
+ XtTextPosition end = strlen(fileNameInput);;
+
+ tblk.firstPos = 0;
+ tblk.length = len;
+ tblk.ptr = fileName;
+ tblk.format = FMT8BIT;
+
+ XtTextDisableRedisplay(fileNameText);
+
+ XtTextReplace( fileNameText, start, end, &tblk );
+
+ XtTextEnableRedisplay(fileNameText);
+ }
+ }
+ else {
+ int len = (fileName == 0) ? 0 : strlen(fileName);
+ bzero(fileNameInput, MAXPATHLEN);
+ if ( len > 0 ) {
+ strncpy(fileNameInput, fileName, MAXPATHLEN);
+ }
+ }
+}
+
+void
+setFile(fileName, copy)
+char *fileName;
+int copy;
+{
+ DviDpi = TeXxResources.dpi;
+
+ TeXPageCloseFile(); /* close open pages stuff */
+
+ if( DviInit(fileName, copy )) {
+ disablePageLevel();
+ TeXPageSlamPages();
+ error(0, 0,"[fopen] Unable to open ``%s''", fileName);
+ }
+ else {
+ enablePageLevel();
+
+ error(0, 0, "Opened the %d page file ``%s''",
+ DviTotalPages, DviFileName);
+
+ strcpy(TeXInputFileNameString, "File: ");
+ TeXInputFileName = &TeXInputFileNameString[strlen(TeXInputFileNameString)];
+ strcpy(TeXInputFileName, DviFileName, MAXPATHLEN);
+
+ if ( fileLabel != NULL) {
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNlabel, TeXInputFileNameString); args++;
+ XtSetArg(argList[args], XtNmaximumLength, MAXPATHLEN); args++;
+
+ XtSetValues( fileLabel, argList, args );
+ }
+ }
+ TeXFontNewFile();
+ TeXMarkNewFile();
+ TeXPageOpenFile();
+}
+
+static lastOpenKind = 0;
+
+static void
+pushOpenFileButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ char *fileName = fileNameInput;
+
+ if ( fileName == NULL ) {
+ error(0, 0, "No file specified?");
+ }
+ else {
+ if ( w == cdButton ) {
+ setDirectory( fileName );
+ }
+ else if (w == openButton) {
+ lastOpenKind = 0;
+ setFile( fileName, 0);
+ }
+ else if (w == copyButton) {
+ lastOpenKind = 1;
+ setFile( fileName, 1);
+ }
+ }
+}
+
+void
+pushReopenButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ char *fileName = fileNameInput;
+
+ if ( fileName == NULL ) {
+ error(0, 0, "No file specified?");
+ }
+ else {
+ setFile( fileName, lastOpenKind); /* open it same way they did */
+ }
+}
+
+static void
+pushCloseFileButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ DviFini();
+ TeXFontNewFile();
+ TeXMarkNewFile();
+ TeXPageCloseFile();
+ TeXPageSlamPages();
+ disablePageLevel();
+}
+
+/*
+ * Page related callbacks & routines
+ */
+
+enablePageLevel()
+{
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNsensitive, True); args++;
+
+ XtSetValues(pageButton, argList, args);
+ XtSetValues(printAllButton, argList, args);
+ XtSetValues(printMarkedButton, argList, args);
+ XtSetValues(printUnmarkedButton, argList, args);
+ XtSetValues(clearMarksButton, argList, args);
+}
+
+disablePageLevel()
+{
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNsensitive, False); args++;
+
+ XtSetValues(pageButton, argList, args);
+ XtSetValues(printAllButton, argList, args);
+ XtSetValues(printMarkedButton, argList, args);
+ XtSetValues(printUnmarkedButton, argList, args);
+ XtSetValues(clearMarksButton, argList, args);
+}
+
+static void
+pushPageButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ if (DviFile != 0 ) {
+ TeXPageBuild();
+ }
+}
+
+static void
+pushPrintButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ PrintDirective what = (PrintDirective) clientData;
+ assert( what == printAll || what == printMarked || what == printUnmarked );
+
+ if (DviFile != 0) {
+ TeXMarkPrint( what );
+ }
+
+}
+
+static void
+pushClearMarksButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ if (DviFile != 0 ) {
+ TeXMarkNone();
+ }
+}
+
+static void
+pushQuitButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ exit(0);
+}
+
+void
+ BuildFileLevel()
+{
+ Arg argList[20];
+ Cardinal args;
+ int len = strlen(fileNameInput);
+
+ args = 0;
+ XtSetArg(argList[args], XtNeditType,XttextEdit); args++;
+ XtSetArg(argList[args], XtNstring, fileNameInput); args++;
+ XtSetArg(argList[args], XtNlength, MAXPATHLEN); args++;
+ XtSetArg(argList[args], XtNtextOptions, (resizeWidth | wordBreak)); args++;
+ fileNameText =
+ XtCreateManagedWidget("fileName",
+ asciiStringWidgetClass, topPane,
+ argList, args);
+
+ quitButton =
+ XtCreateManagedWidget("Quit",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( quitButton, XtNcallback, pushQuitButton, NULL);
+
+ openButton =
+ XtCreateManagedWidget("Open",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( openButton, XtNcallback, pushOpenFileButton, NULL);
+
+ copyButton =
+ XtCreateManagedWidget("Copy",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( copyButton, XtNcallback, pushOpenFileButton, NULL);
+
+ closeButton =
+ XtCreateManagedWidget("Close",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( closeButton, XtNcallback, pushCloseFileButton, NULL);
+
+ cdButton =
+ XtCreateManagedWidget("Cd",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( cdButton, XtNcallback, pushOpenFileButton, NULL);
+
+
+ pageButton
+ = XtCreateManagedWidget("Page",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( pageButton, XtNcallback, pushPageButton, NULL);
+
+ printAllButton
+ = XtCreateManagedWidget("Print All",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( printAllButton, XtNcallback, pushPrintButton, printAll);
+
+ printMarkedButton
+ = XtCreateManagedWidget("Print Marked",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( printMarkedButton, XtNcallback, pushPrintButton, printMarked);
+
+ printUnmarkedButton
+ = XtCreateManagedWidget("Print Unmarked",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( printUnmarkedButton, XtNcallback,
+ pushPrintButton, printUnmarked);
+
+
+ clearMarksButton
+ = XtCreateManagedWidget("Clear Marks",
+ commandWidgetClass, topPane,
+ 0,0);
+ XtAddCallback( clearMarksButton, XtNcallback,
+ pushClearMarksButton, 0);
+
+ disablePageLevel();
+
+ args = 0;
+ XtSetArg(argList[args], XtNlabel, TeXInputDirNameString); args++;
+ XtSetArg(argList[args], XtNmaximumLength, MAXPATHLEN); args++;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ directoryLabel =
+ XtCreateManagedWidget("Cwd",
+ labelWidgetClass, topPane,
+ argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNlabel, TeXInputFileNameString); args++;
+ XtSetArg(argList[args], XtNmaximumLength, MAXPATHLEN); args++;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ fileLabel =
+ XtCreateManagedWidget("FileLabel",
+ labelWidgetClass, topPane,
+ argList, args);
+}
+
diff --git a/dviware/umddvi/previewers/texx2/texx2-font.c b/dviware/umddvi/previewers/texx2/texx2-font.c
new file mode 100644
index 0000000000..ad188ee719
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-font.c
@@ -0,0 +1,127 @@
+#include "texx2.h"
+#include "dvi-simple.h"
+#include "texx2-font.h"
+#include <assert.h>
+
+extern Widget TopLevelWidget;
+
+/* font handlers */
+
+int MagAtShrink[] = {-1, 1000, 500, 333, 250, 200, 166, 142, 125, 111, -1};
+
+XFontStruct **FontsAtMag[ MAX_SHRINK + 2 ];
+
+int FontRefCnt[ MAX_SHRINK + 2 ];
+
+XFontStruct **
+TeXFontRef(usermag)
+int usermag;
+{
+ int magSlot;
+
+ for ( magSlot = MIN_SHRINK; magSlot <= MAX_SHRINK; magSlot++ ) {
+ if ( usermag >= MagAtShrink[ magSlot ] )
+ break;
+ }
+
+ assert( magSlot >= MIN_SHRINK && magSlot <= MAX_SHRINK );
+
+ if ( FontsAtMag[ magSlot ] == 0 ) {
+
+ int nameSize;
+ char *name;
+ char *args[128];
+ int argCnt;
+ char tmpStr[128];
+ int lth;
+ int missing;
+
+ int font;
+
+ XFontStruct **thisMag = (XFontStruct **)
+ XtMalloc( sizeof( XFontStruct *) * (RegisteredFonts + 1) );
+
+ for ( font = 0; font <= RegisteredFonts; font++ ) {
+ thisMag[ font ] = 0;
+ }
+
+ /* try to load the fonts */
+
+ missing = 0;
+
+ for (font = 0; font < RegisteredFonts; font++ ) {
+
+ /* get the canonical font name */
+
+ char tmpStr[128];
+ double dvimag = TheFontInfo[font].paf.paf_DVIMag;
+ double dvidsz = TheFontInfo[font].paf.paf_DVIDesignSize;
+ double suffMag = dvimag / dvidsz;
+
+ int mag = usermag;
+ int scaled = (suffMag * ThePostAmbleInfo.pai_DVIMag + 0.5);
+ int suff = (DviDpi * scaled * mag ) / (1000 * 1000);
+
+ sprintf(tmpStr,"%s.%d",
+ TheFontInfo[font].paf.paf_name, (int) suff);
+
+ thisMag[ font ]
+ = XLoadQueryFont( XtDisplay ( TopLevelWidget ), tmpStr );
+ if ( thisMag[ font ] == 0 ) {
+ missing++;
+ error(0,0,"Missing %s ( -mag %d -scaled %d %s )",
+ tmpStr, mag, scaled, TheFontInfo[font].paf.paf_name);
+ }
+ }
+
+ FontsAtMag[ magSlot ] = thisMag;
+ }
+
+ FontRefCnt[ magSlot ] ++;
+
+ return( FontsAtMag[ magSlot ] );
+}
+
+XFontStruct **
+ TeXFontUnref(usermag)
+int usermag;
+{
+ int magSlot;
+
+ for ( magSlot = MIN_SHRINK; magSlot <= MAX_SHRINK; magSlot++ ) {
+ if ( usermag >= MagAtShrink[ magSlot ] )
+ break;
+ }
+
+ assert( magSlot >= MIN_SHRINK && magSlot <= MAX_SHRINK );
+
+ if ( FontsAtMag [ magSlot] ) {
+
+ FontRefCnt[ magSlot ] --;
+
+ if (FontRefCnt[ magSlot ] <= 0 ) {
+ int font;
+ XFontStruct **fonts = FontsAtMag[magSlot];
+
+ /* fonts list is null terminated */
+
+ for (font = 0; fonts[ font ] ; font++ ) {
+ XFreeFont(XtDisplay( TopLevelWidget ), fonts[font] );
+ fonts[ font ] = 0;
+ }
+ XtFree( FontsAtMag[ magSlot ] );
+ FontsAtMag[ magSlot ] = 0;
+ FontRefCnt[ magSlot ] = 0;
+ }
+ }
+}
+
+void
+TeXFontNewFile()
+{
+ int mag;
+
+ for ( mag = 1; mag <= MAX_SHRINK ; mag++ ) {
+ TeXFontUnref( MagAtShrink[ mag ] );
+ }
+}
diff --git a/dviware/umddvi/previewers/texx2/texx2-font.h b/dviware/umddvi/previewers/texx2/texx2-font.h
new file mode 100644
index 0000000000..f0a02a0fd9
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-font.h
@@ -0,0 +1,8 @@
+
+#define MIN_SHRINK 1
+#define MAX_SHRINK 9
+
+extern int MagAtShrink[];
+extern void TeXFontNewFile();
+extern XFontStruct **TeXFontRef();
+extern XFontStruct **TeXFontUnref();
diff --git a/dviware/umddvi/previewers/texx2/texx2-mark.c b/dviware/umddvi/previewers/texx2/texx2-mark.c
new file mode 100644
index 0000000000..625c27bf5f
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-mark.c
@@ -0,0 +1,163 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/*
+ * Handle printing of marked pages
+ */
+
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include "dvi-simple.h"
+#include "texx2.h"
+#include "texx2-mark.h"
+
+static Bool *markedPages = 0;
+
+void
+TeXMarkNewFile()
+{
+ int page;
+
+ if ( markedPages ) {
+ XtFree( markedPages );
+ markedPages = 0;
+ }
+
+ if ( DviFile != 0 ) {
+ markedPages = (Bool *) malloc( DviTotalPages * sizeof(Bool) );
+ for ( page = 0; page< DviTotalPages; page++ ) {
+ markedPages[ page ] = False;
+ }
+ }
+}
+
+/*
+ * toggle the mark for a given page
+ */
+
+Bool
+TeXMarkToggle(page)
+int page;
+{
+ assert( page >=0 && page < DviTotalPages );
+ markedPages[ page ] = ~markedPages[ page ];
+ return( markedPages[ page ] );
+}
+
+/*
+ * Simply return the state
+ */
+Bool
+TeXMarkState(page)
+int page;
+{
+ assert( page >=0 && page < DviTotalPages );
+ return( markedPages[ page ] );
+}
+
+void
+TeXMarkAll()
+{
+ int page;
+ for (page = 0; page < DviTotalPages; page++) {
+ markedPages[ page ] = True;
+ }
+}
+
+void
+TeXMarkNone()
+{
+ int page;
+ for (page = 0; page < DviTotalPages; page++) {
+ markedPages[ page ] = False;
+ }
+}
+
+/* Print some pages. The Menu selection dictates what pages get printed */
+
+void
+ TeXMarkPrint(pd)
+PrintDirective pd;
+{
+ char *dvips;
+ int cnt;
+ int i;
+ char buf[20];
+ char printCommand[1024];
+
+ char *fileToPrint;
+ int deletePrintedFile;
+
+ if ( pd == printAll ) {
+ fileToPrint = DviFileName;
+ deletePrintedFile = 0;
+ }
+ else {
+
+ int dviSelectBufferLength = 2048;
+ char dviSelectBuffer[ 2048 ];
+
+ fileToPrint = (char *) tmpnam( 0 );
+ deletePrintedFile = 1;
+
+ /* Now run dviselect to extract the pages */
+
+ sprintf(dviSelectBuffer, "dviselect -i %s -o %s ",
+ DviFileName, fileToPrint);
+
+ cnt = 0;
+ for (i = 0; i < DviTotalPages; i++) {
+ if ( (markedPages[ i ] && pd == printMarked )
+ || (!markedPages[ i ] && pd == printUnmarked )) {
+ sprintf(buf, " =%d", i + 1);
+ strcat(dviSelectBuffer, buf);
+ cnt++;
+ }
+ }
+
+ if (cnt != 0) {
+ error(0,0, dviSelectBuffer);
+ system(dviSelectBuffer);
+ }
+ else {
+
+ /* nothing to print? */
+
+ unlink( fileToPrint );
+ return;
+ }
+ }
+
+ /* Now print pages */
+
+ if (TeXxResources.printProgram == 0) {
+ extern char *getenv();
+ dvips = getenv("DVIPRINT");
+ if (dvips == NULL) {
+ dvips = "Dvi "; /* a good guess on BSD systems */
+ }
+ }
+ else {
+ dvips = TeXxResources.printProgram;
+ }
+
+ error(0,0, "Using default ``%s'' to print\n", dvips);
+
+ sprintf(printCommand, "%s %s ", dvips, fileToPrint);
+
+ error(0,0,printCommand);
+
+ system(printCommand);
+
+ if ( deletePrintedFile ) {
+ unlink( fileToPrint );
+ }
+
+}
diff --git a/dviware/umddvi/previewers/texx2/texx2-mark.h b/dviware/umddvi/previewers/texx2/texx2-mark.h
new file mode 100644
index 0000000000..9750e138fa
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-mark.h
@@ -0,0 +1,24 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+typedef enum {printAll, printMarked, printUnmarked } PrintDirective;
+
+extern char *printProgram;
+
+#ifdef _STDC_
+ void TeXMarkNewFile();
+ Bool TeXMarkToggle(int);
+ Bool TeXMarkState(int);
+ void TeXMarkAll();
+ void TeXMarkNone();
+ void TeXMarkPrint(PrintDirective);
+#else
+ void TeXMarkNewFile();
+ Bool TeXMarkToggle();
+ Bool TeXMarkState();
+ void TeXMarkAll();
+ void TeXMarkNone();
+ void TeXMarkPrint();
+#endif
diff --git a/dviware/umddvi/previewers/texx2/texx2-page.c b/dviware/umddvi/previewers/texx2/texx2-page.c
new file mode 100644
index 0000000000..dd30349c33
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-page.c
@@ -0,0 +1,833 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/*
+ *
+ * This looks kind of strange because, initially, I had intended to
+ * allow you to `put away' a page without destroying it -- but
+ * I've decided not to do that.
+ *
+ */
+
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "dvi-simple.h"
+
+#include "texx2.h"
+
+#include "DviPage.h"
+#include "texx2-page.h"
+#include "texx2-font.h"
+#include <X11/ViewportP.h> /* needed to get scrollbar sizes? */
+
+extern Widget TopLevelWidget;
+
+#ifdef _STCD_
+ void TeXPageRealize(TeXPage *, int);
+ static void showPage(TeXPage *, int);
+#else
+ void TeXPageRealize();
+ static void showPage();
+#endif
+
+int TeXPages;
+TeXPage *TheTeXPages[ MAX_TEX_PAGES ];
+
+typedef struct {
+ char *thePage;
+ int refs;
+} DviPageRef;
+
+DviPageRef *ThePageRefs = 0;
+
+void
+TeXPageCloseFile()
+{
+ int popup;
+
+ /* dispose of existing information */
+
+ for ( popup = 0; popup < TeXPages; popup++ ) {
+ TeXPage *tp = TheTeXPages[popup];
+ if ( tp && tp -> popUpPage) {
+ TeXPageDeref( tp -> pageNumber );
+ TeXFontUnref( tp -> userMag);
+ tp -> pageData = 0;
+ }
+ }
+
+ if ( ThePageRefs ) {
+ int i;
+ for (i = 0; i < DviTotalPages; i++ ) {
+ XtFree( ThePageRefs[i].thePage );
+ ThePageRefs[ i ].thePage = 0;
+ }
+ }
+
+ XtFree( ThePageRefs );
+
+ ThePageRefs = 0;
+}
+
+void
+TeXPageSlamPages()
+{
+ int popup;
+
+ /* take down pages, dispose of existing information */
+
+ for ( popup = 0; popup < TeXPages; popup++ ) {
+ if ( TheTeXPages[popup] && TheTeXPages[ popup ] -> popUpPage) {
+ XtDestroyWidget( TheTeXPages[ popup ] -> popUpPage );
+ }
+ }
+}
+
+void
+TeXPageOpenFile()
+{
+ /* now rebuild it all */
+
+ if ( DviFile != 0 ) {
+ int i;
+ int popup;
+
+ ThePageRefs =
+ (DviPageRef *) XtMalloc( (DviTotalPages+1) * sizeof(DviPageRef) );
+
+ for (i = 0; i < DviTotalPages; i++ ) {
+ ThePageRefs[i].thePage = 0;
+ ThePageRefs[i].refs = 0;
+ }
+
+ for ( popup = 0; popup < TeXPages; popup++ ) {
+ TeXPage *tp = TheTeXPages[ popup ];
+
+ if ( tp && tp -> popUpPage) {
+
+ int pno = tp -> pageNumber;
+
+ if (pno >= 0 && pno < DviTotalPages) {
+ Arg argList[20];
+ int args = 0;
+
+ tp -> pageData = TeXPageRef( tp -> pageNumber );
+
+ XtSetArg(argList[args], XtNpai, &ThePostAmbleInfo); args++;
+ XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
+ XtSetArg(argList[args], XtNdviFonts, TheFontInfo); args++;
+ XtSetArg(argList[args], XtNxFonts,
+ TeXFontRef(tp -> userMag)); args++;
+
+ XtSetValues( tp -> singleDviPage, argList, args);
+
+ showPage( tp, False );
+ }
+ else {
+ XtDestroyWidget( tp -> popUpPage );
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * Reference and dereference a page structure -- these keep track
+ * of the memory allocated for page buffers & disposes of them
+ * when not in use.
+ */
+
+char *
+TeXPageRef(pageno)
+int pageno;
+{
+ assert( pageno >= 0 || pageno < DviTotalPages );
+
+ ThePageRefs[ pageno ].refs++;
+ if ( ThePageRefs[ pageno ].thePage == 0 ) {
+ ThePageRefs[ pageno ].thePage = DviFetchPage( pageno );
+ }
+
+ return(ThePageRefs[ pageno ].thePage );
+}
+
+void
+TeXPageDeref(pageno)
+int pageno;
+{
+ assert( pageno >= 0 || pageno < DviTotalPages );
+ if ( ThePageRefs && ThePageRefs[ pageno ].refs > 0) {
+ ThePageRefs[ pageno ].refs--;
+ if ( ThePageRefs[ pageno ].refs <= 0 ) {
+ XtFree( ThePageRefs[ pageno ].thePage );
+ ThePageRefs[ pageno ].thePage = 0;
+ }
+ }
+}
+
+/*
+ * Locate a free TeXPage structure. See comment at head.
+ */
+
+TeXPage *
+TeXPageLocate()
+{
+ int i;
+ TeXPage *tp;
+
+ for (i = 0; i < TeXPages; i++ ) {
+ if ( ! TheTeXPages[ i ] -> active ) {
+ return( TheTeXPages[ i ] );
+ }
+ }
+
+ tp = (TeXPage *) XtMalloc(sizeof(TeXPage));
+
+ bzero( tp, sizeof(TeXPage) );
+
+ tp -> realized = False;
+ tp -> tied = 0;
+ tp -> tiedTo = 0;
+
+ /* install the page in the page list */
+
+ if ( TeXPages > MAX_TEX_PAGES ) {
+ error(0,0,"No more pages available");
+ return(0);
+ }
+
+ TheTeXPages[ TeXPages++ ] = tp;
+
+ return( tp );
+}
+
+/*
+ * The callback when pages die.
+ */
+
+static void
+ dviPageDied(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData;
+
+ if ( tp != 0 ){
+ tp -> active = False;
+ tp -> realized = False;
+ TeXPageDeref( tp -> pageNumber );
+ TeXFontUnref( tp -> userMag);
+ tp -> popUpPage = 0;
+
+ if ( tp -> tiedTo != 0 && tp -> tiedTo -> active ) {
+ tp -> tiedTo -> tied = 0;
+ }
+
+ if ( tp -> tied != 0 && tp -> tied -> active ) {
+ tp -> tied -> tiedTo = 0;
+ }
+
+ tp -> tiedTo = 0;
+ tp -> tied = 0;
+
+ }
+}
+
+static void
+ pushQuitButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData;
+ XtDestroyWidget( tp -> popUpPage );
+}
+
+/*
+ * Set all the buttons for this page, possibly also
+ * sending the page information
+ */
+
+static Arg sensArgs[] = {
+ {XtNsensitive, (XtArgVal) True}
+};
+
+static Arg insensArgs[] = {
+ {XtNsensitive, (XtArgVal) False}
+};
+
+static void
+ showPage(tp, displayPage)
+TeXPage *tp;
+Bool displayPage;
+{
+ Arg argList[20];
+ Cardinal args;
+
+ Pixel fore;
+ Pixel back;
+
+ if ( displayPage ) {
+ tp -> pageData = TeXPageRef( tp -> pageNumber );
+ args = 0;
+ XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
+
+ XtSetValues(tp -> singleDviPage, argList, args);
+ }
+
+ if ( tp -> pageNumber == 0 ) {
+ XtSetValues( tp -> backwardButton, insensArgs, XtNumber(insensArgs));
+ }
+ else {
+ XtSetValues( tp -> backwardButton, sensArgs, XtNumber(sensArgs));
+ }
+
+ if ( tp -> pageNumber >= (DviTotalPages-1)) {
+ XtSetValues( tp -> forewardButton, insensArgs, XtNumber(insensArgs));
+ }
+ else {
+ XtSetValues( tp -> forewardButton, sensArgs, XtNumber(sensArgs));
+ }
+
+ /* Take normal values from another button */
+
+ args = 0;
+ XtSetArg(argList[args], XtNforeground, &fore); args++;
+ XtSetArg(argList[args], XtNbackground, &back); args++;
+ XtGetValues( tp -> forewardButton, argList, args);
+
+ if (TeXMarkState( tp -> pageNumber ) ) {
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNforeground, back); args++;
+ XtSetArg(argList[args], XtNbackground, fore); args++;
+
+ XtSetValues( tp -> markButton, argList, args );
+ }
+ else {
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNforeground, fore); args++;
+ XtSetArg(argList[args], XtNbackground, back); args++;
+
+ XtSetValues( tp -> markButton, argList, args );
+ }
+}
+
+static void
+ pushForewardButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData; /* */
+ char *p;
+
+ if (tp -> pageNumber >= DviTotalPages) {
+ return;
+ }
+ else {
+ if ( tp -> pageData != 0 ) {
+ TeXPageDeref( tp -> pageNumber );
+ }
+ tp -> pageNumber++;
+ }
+ showPage(tp, True);
+ if ( tp -> tied ) {
+ pushForewardButton( tp -> tied, tp -> tied, 0 );
+ }
+}
+
+static void
+ pushBackwardButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData;
+ char *p;
+
+ if ( tp -> tied ) {
+ pushBackwardButton( tp -> tied, tp -> tied, 0 );
+ }
+
+ if ( tp -> pageNumber <= 0 ) {
+ return;
+ }
+ else {
+ if ( tp -> pageData != 0 ) {
+ TeXPageDeref( tp -> pageNumber );
+ }
+
+ tp -> pageNumber--;
+ }
+ showPage(tp, True);
+}
+
+static void
+ pushMarkButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData;
+
+ TeXMarkToggle( tp -> pageNumber );
+ showPage(tp, False);
+}
+
+static void
+ pushDupButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage *) clientData;
+ TeXPage *newtp = TeXPageLocate();
+ TeXPageRealize(newtp, tp -> pageNumber);
+}
+
+static void
+ pushTieButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage *) clientData;
+ if ( tp -> tied == 0 ) {
+ TeXPage *newtp = TeXPageLocate();
+ tp -> tied = newtp;
+ newtp -> tiedTo = tp;
+ TeXPageRealize(newtp, tp -> pageNumber);
+ }
+}
+
+/*
+ * The goto button. This scans, starting at the current page number,
+ * until a value of ``DviCount[0]'' meets the goto destination.
+ * This allows us to hit the multiple ``page 1'' refs.
+ */
+static void
+ pushGotoButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage*) clientData;
+
+ char *pageNumber = tp -> pageNumberBuffer;
+ if ( pageNumber != 0 && strlen( pageNumber ) > 0 ) {
+
+ int want = atoi( pageNumber );
+ int here = tp -> pageNumber;
+ int page = here;
+
+ for(;;) {
+ page++;
+ if ( page >= DviTotalPages ) {
+ page = 0;
+ }
+ if ( page == here )
+ return;
+
+ if ( DviCount[0][page] == want ) {
+ TeXPageDeref( tp -> pageNumber );
+ tp -> pageNumber = page;
+ TeXPageRef( tp -> pageNumber );
+ showPage(tp, True);
+ return;
+ }
+ }
+ }
+}
+
+void
+changeMag( tp, mag )
+TeXPage *tp;
+int mag;
+{
+ Arg argList[20];
+ Cardinal args;
+
+ if ( mag > 0 && mag != tp -> userMag ) {
+ XFontStruct **x;
+ Dimension maxHt
+ = (int) ((HeightOfScreen(XtScreen(TopLevelWidget))) * 0.90);
+ Dimension maxWd
+ = (int) ((WidthOfScreen(XtScreen(TopLevelWidget))) * 0.95);
+ Dimension dviHt;
+ Dimension dviWd;
+
+ TeXFontUnref( tp -> userMag);
+
+ tp -> userMag = mag; x = TeXFontRef(tp -> userMag);
+
+ args = 0;
+ XtSetArg(argList[args], XtNuserMag, tp -> userMag); args++;
+ XtSetArg(argList[args], XtNxFonts, x); args++;
+ XtSetValues( tp -> singleDviPage, argList, args);
+
+ /* get the size of the dvi page */
+ if ( TeXxResources.autoSize ) {
+ args = 0; XtSetArg(argList[args], XtNwidth, &dviWd); args++;
+ XtSetArg(argList[args], XtNheight, &dviHt); args++;
+ XtGetValues( tp -> singleDviPage, argList, args);
+
+ if ( dviWd <= maxWd ){
+ maxWd = dviWd;
+
+ /* will we need scrollbars? */
+
+ if ( dviHt > maxHt ) {
+ ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
+ maxWd = maxWd
+ + vp -> viewport.vert_bar -> core.width
+ + vp -> viewport.vert_bar -> core.border_width;
+ }
+ }
+ if ( dviHt <= maxHt ) {
+ maxHt = dviHt;
+ if ( dviWd > maxWd ) {
+ ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
+ maxHt = maxHt
+ + vp -> viewport.horiz_bar -> core.width
+ + vp -> viewport.horiz_bar -> core.border_width;
+ }
+ }
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, maxWd); args++;
+ XtSetArg(argList[args], XtNheight, maxHt); args++;
+ XtSetValues( tp -> viewPort, argList, args);
+ }
+ }
+}
+
+static void
+ pushMagButton(w, clientData, callData)
+Widget w;
+caddr_t clientData;
+caddr_t callData;
+{
+ TeXPage *tp = (TeXPage *) clientData;
+ int mag;
+
+ mag = atoi( tp -> pageNumberBuffer );
+ changeMag( tp, mag );
+}
+
+static void
+ pushLargeButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage *) clientData;
+ changeMag( tp, TeXxResources.largeMag );
+}
+
+static void
+ pushSmallButton(w, clientData, callData)
+Widget w;
+caddr_t clientData; /* unused */
+caddr_t callData; /* unused */
+{
+ TeXPage *tp = (TeXPage *) clientData;
+ changeMag( tp, TeXxResources.smallMag );
+}
+
+/*
+ * Realize the TeXPage structure and pop up the corresponding window
+ */
+void
+TeXPageRealize(tp, pageNumber)
+TeXPage *tp;
+int pageNumber;
+{
+ Arg argList[20];
+ int args;
+
+ Dimension maxHt = (int) ((HeightOfScreen(XtScreen(TopLevelWidget))) * 0.90);
+ Dimension maxWd = (int) ((WidthOfScreen(XtScreen(TopLevelWidget))) * 0.95);
+ Dimension dviHt;
+ Dimension dviWd;
+ extern pushReopenButton(); /* from texx2-file */
+
+ Dimension gap = 30;
+
+ if ( tp == NULL ) {
+ return;
+ }
+
+ assert(TopLevelWidget != 0);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNallowShellResize, True); args++;
+ tp -> popUpPage =
+ XtCreatePopupShell("TeXx2-Page-Display",
+ topLevelShellWidgetClass, TopLevelWidget,
+ argList,args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ tp -> dviPageBox =
+ XtCreateManagedWidget("dviPageBox",
+ formWidgetClass, tp -> popUpPage,
+ argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ tp -> quitButton =
+ XtCreateManagedWidget("Quit",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> quitButton, XtNcallback, pushQuitButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> quitButton); args++;
+ XtSetArg(argList[args], XtNhorizDistance, gap); args++;
+ tp -> forewardButton =
+ XtCreateManagedWidget("Forward",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> forewardButton, XtNcallback, pushForewardButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> forewardButton); args++;
+ tp -> backwardButton =
+ XtCreateManagedWidget("Backward",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> backwardButton, XtNcallback, pushBackwardButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> backwardButton); args++;
+ tp -> markButton =
+ XtCreateManagedWidget("Mark",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> markButton, XtNcallback, pushMarkButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> markButton); args++;
+ tp -> dupButton =
+ XtCreateManagedWidget("Dup",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> dupButton, XtNcallback, pushDupButton, tp);
+
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> dupButton); args++;
+ tp -> tieButton =
+ XtCreateManagedWidget("Tied",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> tieButton, XtNcallback, pushTieButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> tieButton); args++;
+ tp -> largeButton =
+ XtCreateManagedWidget("Large",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> largeButton, XtNcallback, pushLargeButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> largeButton); args++;
+ tp -> smallButton =
+ XtCreateManagedWidget("Small",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> smallButton, XtNcallback, pushSmallButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> smallButton); args++;
+ tp -> reopenButton =
+ XtCreateManagedWidget("Reopen",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> reopenButton, XtNcallback, pushReopenButton, tp);
+
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> reopenButton); args++;
+ XtSetArg(argList[args], XtNhorizDistance, gap); args++;
+ XtSetArg(argList[args], XtNeditType, XttextEdit); args++;
+ XtSetArg(argList[args], XtNstring, tp -> pageNumberBuffer); args++;
+ XtSetArg(argList[args], XtNlength, MAXPAGENUMBERBUFFER); args++;
+ XtSetArg(argList[args], XtNtextOptions, resizeWidth); args++;
+ XtSetArg(argList[args], XtNresizable,True); args++;
+ tp -> pageNumberText =
+ XtCreateManagedWidget("",
+ asciiStringWidgetClass, tp -> dviPageBox,
+ argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> pageNumberText); args++;
+ tp -> gotoButton =
+ XtCreateManagedWidget("Goto",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> gotoButton, XtNcallback, pushGotoButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNfromHoriz, tp -> gotoButton); args++;
+ tp -> magButton =
+ XtCreateManagedWidget("Mag",
+ commandWidgetClass, tp -> dviPageBox,
+ argList, args);
+ XtAddCallback(tp -> magButton, XtNcallback, pushMagButton, tp);
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNfromVert, tp -> pageNumberText); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetArg(argList[args], XtNallowHoriz, True); args++;
+ XtSetArg(argList[args], XtNallowVert, True); args++;
+ tp -> viewPort =
+ XtCreateWidget("ViewPort",
+ viewportWidgetClass, tp -> dviPageBox,
+ argList, args);
+
+ bzero(tp -> pageNumberBuffer, MAXPAGENUMBERBUFFER);
+ tp -> realized = True;
+ tp -> pageNumber = pageNumber;
+ tp -> pageData = TeXPageRef( tp -> pageNumber );
+ tp -> userMag = TeXxResources.userMag;
+ tp -> active = True;
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetArg(argList[args], XtNpai, &ThePostAmbleInfo); args++;
+ XtSetArg(argList[args], XtNdviFonts, TheFontInfo); args++;
+
+ XtSetArg(argList[args], XtNdpi, TeXxResources.dpi ); args++;
+ XtSetArg(argList[args], XtNpaperWidth,
+ TeXxResources.paperWidthString ); args++;
+ XtSetArg(argList[args], XtNpaperHeight,
+ TeXxResources.paperHeightString ); args++;
+
+ XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
+ XtSetArg(argList[args], XtNuserMag, tp -> userMag); args++;
+ XtSetArg(argList[args], XtNxFonts, TeXFontRef(tp -> userMag)); args++;
+
+ tp -> singleDviPage =
+ XtCreateWidget("DviPage",
+ dviPageWidgetClass, tp -> viewPort,
+ argList, args);
+
+ XtAddCallback( tp -> singleDviPage, XtNdestroyCallback, dviPageDied, tp);
+
+ /* get the size of the dvi page. This is an attempt to provide
+ a nice default window size */
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, &dviWd); args++;
+ XtSetArg(argList[args], XtNheight, &dviHt); args++;
+ XtGetValues( tp -> singleDviPage, argList, args);
+ if ( dviWd < maxWd ){
+ maxWd = dviWd;
+ }
+ if ( dviHt < maxHt ) {
+ maxHt = dviHt;
+ }
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, maxWd); args++;
+ XtSetArg(argList[args], XtNheight, maxHt); args++;
+ XtSetValues( tp -> viewPort, argList, args);
+
+ /* Now manage the viewport & single page */
+ XtManageChild( tp -> singleDviPage );
+ XtManageChild( tp -> viewPort );
+
+ XtRealizeWidget(tp -> popUpPage);
+
+ /* did we need scrollbars? */
+
+ if ( dviWd <= maxWd ){
+ maxWd = dviWd;
+
+ if ( dviHt > maxHt ) {
+ ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
+ maxWd = maxWd
+ + vp -> viewport.vert_bar -> core.width
+ + vp -> viewport.vert_bar -> core.border_width;
+ }
+ }
+ if ( dviHt <= maxHt ) {
+ maxHt = dviHt;
+ if ( dviWd > maxWd ) {
+ ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
+ maxHt = maxHt
+ + vp -> viewport.horiz_bar -> core.width
+ + vp -> viewport.horiz_bar -> core.border_width;
+ }
+ }
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, maxWd); args++;
+ XtSetArg(argList[args], XtNheight, maxHt); args++;
+ XtSetValues( tp -> viewPort, argList, args);
+
+ /* some bug somewhere makes the first page not appear unless I reset page */
+ args = 0;
+ XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
+ XtSetValues(tp -> singleDviPage, argList, args);
+
+ showPage( tp, False ); /* set remaining buttons */
+
+ XtPopup( tp -> popUpPage, XtGrabNone);
+}
+
+void
+ TeXPageBuild()
+{
+ int i;
+
+ TeXPage *tp = TeXPageLocate();
+
+ if ( ! tp -> realized ) {
+ TeXPageRealize(tp, 0);
+ }
+}
diff --git a/dviware/umddvi/previewers/texx2/texx2-page.h b/dviware/umddvi/previewers/texx2/texx2-page.h
new file mode 100644
index 0000000000..00645b8022
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-page.h
@@ -0,0 +1,63 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/* This is everything that's in a TeXPage */
+
+#include "texx2.h"
+
+#include <X11/Shell.h>
+
+typedef struct TeXPageStruct
+{
+ int pageNumber;
+ char * pageData;
+ int userMag;
+ Bool active;
+ Bool realized;
+#define MAXPAGENUMBERBUFFER 10
+ char pageNumberBuffer[MAXPAGENUMBERBUFFER];
+ Widget popUpPage;
+ Widget dviPageBox;
+ Widget singleDviPage;
+ Widget viewPort;
+ Widget buttonBox;
+ Widget forewardButton;
+ Widget backwardButton;
+ Widget markButton;
+ Widget dupButton;
+ struct TeXPageStruct *tied;
+ struct TeXPageStruct *tiedTo;
+ Widget tieButton;
+ Widget largeButton;
+ Widget smallButton;
+ Widget quitButton;
+ Widget pageNumberText;
+ Widget gotoButton;
+ Widget magButton;
+ Widget reopenButton;
+} TeXPage;
+
+extern int TeXPages;
+#define MAX_TEX_PAGES 10
+extern TeXPage *TheTeXPages [ MAX_TEX_PAGES ];
+
+#ifdef _STDC_
+ extern void TeXPageBuild();
+ extern void TeXPageCloseFile();
+ extern void TeXPageSlamPages();
+ extern void TeXPageOpenFile();
+ extern TeXPage *TeXPageLocate();
+ extern char *TeXPageRef(int);
+ extern void TeXPageDeref(int);
+ extern void TeXPageRealize( TeXPage *);
+#else
+ extern void TeXPageBuild();
+ extern void TeXPageCloseFile();
+ extern void TeXPageSlamPages();
+ extern void TeXPageOpenFile();
+ extern TeXPage *TeXPageLocate();
+ extern char *TeXPageRef();
+ extern void TeXPageDeref();
+#endif
diff --git a/dviware/umddvi/previewers/texx2/texx2-widgets.c b/dviware/umddvi/previewers/texx2/texx2-widgets.c
new file mode 100644
index 0000000000..96abbda5fb
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-widgets.c
@@ -0,0 +1,174 @@
+#include "texx2.h"
+#include <errno.h>
+#include <sys/param.h>
+#include <assert.h>
+#include "texx2-widgets.h"
+
+Widget topPane;
+Widget topFile;
+Widget topPages;
+Widget topError;
+
+/*
+ * Widgets related to file I/O
+ */
+Widget topFileBox;
+Widget fileNameText;
+Widget openButton;
+Widget copyButton;
+Widget cdButton;
+Widget closeButton;
+Widget quitButton;
+Widget directoryLabel;
+Widget fileLabel;
+
+/*
+ * Widgets related to the pages table
+ */
+Widget pageButton;
+Widget printAllButton;
+Widget printMarkedButton;
+Widget printUnmarkedButton;
+Widget clearMarksButton;
+
+/*
+ * Error dialog widgets
+ */
+
+Widget errorMsgBox;
+Widget errorText;
+Widget clearButton;
+
+void
+ BuildTopLevelWidget(topLevel)
+Widget topLevel;
+{
+
+ Dimension width = 650;
+ Dimension littleGap = 15;
+
+ Arg argList[20];
+ Cardinal args;
+
+ args = 0;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ topPane =
+ XtCreateManagedWidget("texx2-top-pane",
+ formWidgetClass, topLevel,
+ argList, args);
+
+ BuildFileLevel(topPane);
+ BuildErrorBox(topPane);
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, width); args++;
+ XtSetArg(argList[args], XtNtop, XtChainTop); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetValues(fileNameText, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileNameText); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(quitButton, argList, args);
+
+ /* Move everything away from the quit button */
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileNameText); args++;
+ XtSetArg(argList[args], XtNfromHoriz, quitButton); args++;
+ XtSetArg(argList[args], XtNhorizDistance, littleGap); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(openButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileNameText); args++;
+ XtSetArg(argList[args], XtNfromHoriz, openButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(copyButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileNameText); args++;
+ XtSetArg(argList[args], XtNfromHoriz, copyButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(closeButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileNameText); args++;
+ XtSetArg(argList[args], XtNfromHoriz, closeButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(cdButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, openButton); args++;
+ XtSetArg(argList[args], XtNfromHoriz, quitButton); args++;
+ XtSetArg(argList[args], XtNhorizDistance, littleGap); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(pageButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, quitButton); args++;
+ XtSetArg(argList[args], XtNfromHoriz, pageButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(printAllButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, quitButton); args++;
+ XtSetArg(argList[args], XtNfromHoriz, printAllButton); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(printMarkedButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, quitButton); args++;
+ XtSetArg(argList[args], XtNfromHoriz, printMarkedButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(printUnmarkedButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, quitButton); args++;
+ XtSetArg(argList[args], XtNfromHoriz, printUnmarkedButton); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(clearMarksButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, width); args++;
+ XtSetArg(argList[args], XtNfromVert, pageButton); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetValues(directoryLabel, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNwidth, width); args++;
+ XtSetArg(argList[args], XtNfromVert, directoryLabel); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetArg(argList[args], XtNresize, True); args++;
+ XtSetValues(fileLabel, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, fileLabel); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresize, False); args++;
+ XtSetArg(argList[args], XtNresizable, False); args++;
+ XtSetValues(clearButton, argList, args);
+
+ args = 0;
+ XtSetArg(argList[args], XtNfromVert, clearButton); args++;
+ XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
+ XtSetArg(argList[args], XtNresizable, True); args++;
+ XtSetArg(argList[args], XtNwidth, width); args++;
+ XtSetArg(argList[args], XtNheight, 150); args++;
+ XtSetValues(errorText, argList, args);
+}
diff --git a/dviware/umddvi/previewers/texx2/texx2-widgets.h b/dviware/umddvi/previewers/texx2/texx2-widgets.h
new file mode 100644
index 0000000000..de0f2c1019
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2-widgets.h
@@ -0,0 +1,40 @@
+extern Widget topPane;
+
+/*
+ * Widgets related to file I/O
+ */
+extern Widget topFileBox;
+extern Widget fileNameText;
+extern Widget openButton;
+extern Widget closeButton;
+extern Widget copyButton;
+extern Widget cdButton;
+extern Widget quitButton;
+
+extern Widget directoryLabel;
+extern Widget fileLabel;
+
+/*
+ * Widgets related to the pages table
+ */
+extern Widget pageButton;
+extern Widget printAllButton;
+extern Widget printMarkedButton;
+extern Widget printUnmarkedButton;
+extern Widget clearMarksButton;
+
+/*
+ * Error dialog widgets
+ */
+
+extern Widget errorMsgBox;
+extern Widget errorText;
+extern Widget clearButton;
+
+/*
+ * Things that build widgets
+ */
+
+extern void BuildErrorBox();
+extern void BuildFileLevel();
+extern void BuildPageLevel();
diff --git a/dviware/umddvi/previewers/texx2/texx2.c b/dviware/umddvi/previewers/texx2/texx2.c
new file mode 100644
index 0000000000..4b15cc4f51
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2.c
@@ -0,0 +1,104 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+#include "texx2.h"
+#include "texx2-mark.h"
+
+char *ProgName, *ClassName;
+
+extern void BuildTopLevelWidget();
+
+TeXxResourceStruct TeXxResources;
+
+#define Offset(field) (XtOffset(TeXxResourceStruct *, field))
+
+static XtResource resources[] = {
+ {"print", XtCString, XtRString, sizeof(char *),
+ Offset(printProgram), XtRString, "Dvi "},
+
+ {"mag", XtCString, XtRInt, sizeof(int),
+ Offset(userMag), XtRString, "500"},
+
+ {"paperWidth", XtCString, XtRString, sizeof(char *),
+ Offset(paperWidthString), XtRString, "8.5"},
+
+ {"paperHeight", XtCString, XtRString, sizeof(char *),
+ Offset(paperHeightString), XtRString, "11.5"},
+
+ {"smallMag", XtCString, XtRInt, sizeof(int),
+ Offset(smallMag), XtRString, "333"},
+
+ {"largeMag", XtCString, XtRInt, sizeof(int),
+ Offset(largeMag), XtRString, "500"},
+
+ {"dpi", XtCString, XtRInt, sizeof(int),
+ Offset(dpi), XtRString, "300"},
+
+ {"autoSize", XtCString, XtRBool, sizeof(Bool),
+ Offset(autoSize), XtRString, "True"}
+};
+
+static XrmOptionDescRec Options[] = {
+ {"-print", "*.print", XrmoptionSepArg, (caddr_t) NULL},
+ {"-mag", "*.mag", XrmoptionSepArg, (caddr_t) NULL},
+ {"-paperWidth", "*.paperWidth", XrmoptionSepArg, (caddr_t) NULL},
+ {"-paperHeight", "*.paperHeight", XrmoptionSepArg, (caddr_t) NULL},
+ {"-smallMag", "*.smallMag", XrmoptionSepArg, (caddr_t) NULL},
+ {"-largeMag", "*.largeMag", XrmoptionSepArg, (caddr_t) NULL},
+ {"-dpi", "*.dpi", XrmoptionSepArg, (caddr_t) NULL},
+ {"-autoSize", "*.autoSize", XrmoptionSepArg, (caddr_t) NULL}
+};
+
+int Argc;
+char **Argv;
+
+Widget TopLevelWidget;
+
+void
+main(argc,argv)
+char ** argv;
+int argc;
+{
+
+ Argc = argc;
+ Argv = argv;
+
+ ClassName = "Texx2";
+
+ if( (ProgName = index(argv[0], '/')) == NULL )
+ ProgName = argv[0];
+
+ TopLevelWidget = XtInitialize(ProgName, ClassName,
+ Options, XtNumber(Options),
+ &Argc, Argv);
+
+ XtGetApplicationResources(TopLevelWidget,
+ (caddr_t) &TeXxResources,
+ resources, XtNumber(resources),
+ NULL, (Cardinal) 0);
+
+
+ BuildTopLevelWidget(TopLevelWidget);
+ XtRealizeWidget(TopLevelWidget);
+
+ if ( Argc > 1 ) {
+ struct stat buf;
+
+ /* set file first incase it's a relative path name */
+
+ setFileName( Argv[1] );
+ setDirectory( Argv[1] );
+ }
+ else {
+ setDirectory(".");
+ }
+
+ if ( Argc > 2 ) {
+ error(0,0,"Additional arguments ignored");
+ }
+
+ XtMainLoop();
+}
+
diff --git a/dviware/umddvi/previewers/texx2/texx2.h b/dviware/umddvi/previewers/texx2/texx2.h
new file mode 100644
index 0000000000..c859f091af
--- /dev/null
+++ b/dviware/umddvi/previewers/texx2/texx2.h
@@ -0,0 +1,58 @@
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ */
+
+/* Std system and C header files */
+
+#ifndef _tex2h_
+#define _tex2h_
+
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+
+/* X include files */
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+/* X toolkit header files */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+/* Widget header files. */
+
+#include <X11/AsciiText.h>
+#include <X11/Box.h>
+#include <X11/Command.h>
+#include <X11/Dialog.h>
+#include <X11/Label.h>
+#include <X11/List.h>
+#include <X11/Scroll.h>
+#include <X11/Shell.h>
+#include <X11/VPaned.h>
+#include <X11/Viewport.h>
+
+#include "texx2-defs.h"
+
+extern char *ProgName;
+
+typedef struct {
+ char *printProgram;
+ int userMag;
+ int dpi;
+ Bool autoSize;
+ int largeMag;
+ int smallMag;
+
+ char *paperWidthString;
+ char *paperHeightString;
+} TeXxResourceStruct;
+
+extern TeXxResourceStruct TeXxResources;
+
+#endif