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