montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 6)." # Contents: Makefile Makefile.orig dviselect.1 dviselect.c # dviselect.c.orig h lib # Wrapped by montnaro@sprite on Sat Nov 11 17:13:26 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(1356 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' XDESTDIR= XCFLAGS= -O -I./h XMAKE= make X XBINDIR = $(HOME)/.commands XIPRBIN = /usr/local XMANDIR = $(HOME)/.man X XCSRCS = dviselect.c XSRCS = $(CSRCS) dviselect.1 X Xdefault: dviselect lib/lib.a X Xsrc: $(SRCS) X @echo Done X Xclean: X cd lib; $(MAKE) $(MFLAGS) clean X -rm -f core *.o dviselect imagen1 dviselect.shar* X Xinst-dviselect: dviselect dviselect.1 X install -s dviselect ${BINDIR}/dviselect X -install -c -m 444 dviselect.1 ${MANDIR}/man1/dviselect.1 X Xdviselect: dviselect.o lib/lib.a X ${CC} ${CFLAGS} -o dviselect dviselect.o lib/lib.a X Xlib/lib.a : X cd lib; $(MAKE) $(MFLAGS) X Xdvidvi: dvidvi.c X $(CC) $(CFLAGS) -o dvidvi dvidvi.c X Xdepend: X makedepend $(CFLAGS) $(CSRCS) X Xshar : X $(MAKE) $(MFLAGS) clean X shar -n1 -e6 -t "Now do 'make dviselect'" * >dviselect.shar.1 X shar -n2 -e6 -t "Now do 'make dviselect'" h/* >dviselect.shar.2 X shar -n3 -e6 -t "Now do 'make dviselect'" lib/[a-f]* >dviselect.shar.3 X shar -n4 -e6 -t "Now do 'make dviselect'" lib/[g-m]* >dviselect.shar.4 X shar -n5 -e6 -t "Now do 'make dviselect'" lib/[n-p]* >dviselect.shar.5 X shar -n6 -e6 -t "Now do 'make dviselect'" lib/[q-zM]* >dviselect.shar.6 X X# DO NOT DELETE THIS LINE -- make depend depends on it. X Xdviselect.o: ../h/types.h ../h/dvi.h ../h/dviclass.h ../h/dvicodes.h Xdviselect.o: ../h/fio.h ../h/search.h /usr/include/stdio.h Xdviselect.o: /usr/include/ctype.h END_OF_Makefile if test 1356 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi chmod +x Makefile # end of overwriting check fi if test -f Makefile.orig -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile.orig\" else echo shar: Extracting \"Makefile.orig\" \(820 characters\) sed "s/^X//" >Makefile.orig <<'END_OF_Makefile.orig' XDESTDIR= XCFLAGS= -O -I../h XMAKE= make X XBINDIR = $(HOME)/.commands XIPRBIN = /usr/local XMANDIR = $(HOME)/.man X XCSRCS = dviselect.c XSRCS = $(CSRCS) dviselect.1 X Xdefault: all X X$(SRCS):; co -q $@ X Xsrc: $(SRCS) X @echo Done X Xclean: X -ci -q $(SRCS) X -rm core *.o dviselect imagen1 X Xinst-dviselect: dviselect dviselect.1 X install -s dviselect ${BINDIR}/dviselect X -install -c -m 444 dviselect.1 ${MANDIR}/man1/dviselect.1 X Xdviselect: dviselect.o ../lib/lib.a X ${CC} ${CFLAGS} -o dviselect dviselect.o ../lib/lib.a X Xdvidvi: dvidvi.c X $(CC) $(CFLAGS) -o dvidvi dvidvi.c X Xdepend: X makedepend $(CFLAGS) $(CSRCS) X X# DO NOT DELETE THIS LINE -- make depend depends on it. X Xdviselect.o: ../h/types.h ../h/dvi.h ../h/dviclass.h ../h/dvicodes.h Xdviselect.o: ../h/fio.h ../h/search.h /usr/include/stdio.h Xdviselect.o: /usr/include/ctype.h END_OF_Makefile.orig if test 820 -ne `wc -c <Makefile.orig`; then echo shar: \"Makefile.orig\" unpacked with wrong size! fi chmod +x Makefile.orig # end of overwriting check fi if test -f dviselect.1 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dviselect.1\" else echo shar: Extracting \"dviselect.1\" \(3897 characters\) sed "s/^X//" >dviselect.1 <<'END_OF_dviselect.1' X.TH DVISELECT 1 X.SH NAME Xdviselect \- extract pages from DVI files X.SH SYNOPSIS X.B dviselect X[ X.B \-s X] [ X.B \-i X.I infile X] [ X.B \-o X.I outfile X] X.I "list of pages" X[ X.I infile X[ X.I outfile X] ] X.SH DESCRIPTION X.I Dviselect Xselects pages from a DVI file produced by TeX, creating a new DVI Xfile usable by any of TeX's conversion program (e.g., iptex), or even Xby dviselect itself. X.PP XA X.I range Xis a string of the form X.I first:last Xwhere both X.I first Xand X.I last Xare optional numeric strings, with negative numbers indicated by Xa leading underscore character ``_''. If both X.I first Xand X.I last Xare omitted, the colon may also be omitted, or may be replaced Xwith an asterisk ``*''. A X.I page range Xis a list of ranges separated by periods. A X.I "list of pages" Xis described by a set of page ranges separated by commas and/or white space. X.PP X.I Dviselect Xactually looks at the ten X.I count Xvariables that TeX writes; the first of these (\ecount0) is the Xpage number, with \ecount1 through \ecount9 having varied uses Xdepending on which macro packages are in use. (Typically \ecount1 Xis a chapter or section number.) A page is included in X.IR dviselect 's Xoutput if all its \ecount values are within any one of the ranges Xlisted on the command line. For example, the command X``dviselect *.1,35:'' Xmight select everything in chapter 1, as well as pages 35 and up. X``dviselect 10:30'' would select pages 10 through 30 (inclusive). X``:43'' means everything up to and including page 43 (including Xnegative-numbered pages). XIf a Table of Contents has negative page numbers, ``:_1'' will select it. X``*.4 .........1'' might Xmean everything in every chapter 4 and an index, presuming \ecount9 Xwas set to 1 in the index. (``*'' must be quoted from the shell; Xthe null string is more convenient to use, if harder to read.) X.PP XInstead of \ecount values, X.I dviselect Xcan also select by ``absolute page number'', where the first page Xis page 1, the second page 2, and so forth. Absolute page numbers Xare indicated by a leading equal sign ``=''. Ranges of absolute Xpages are also allowed: ``dviselect =3:7'' will extract the third Xthrough seventh pages. Dot separators are not legal in absolute Xranges, and there are no negative absolute page numbers. X.PP XMore precisely, an asterisk or a null string implies no limit; Xan equal sign means absolute pages rather than \ecounts; Xa leading colon means everything up to and including the given page; a Xtrailing colon means everything from the given page on; and Xa period indicates that the next \ecount should be examined. XIf fewer than 10 ranges are specified, the remaining \ecounts Xare left unrestricted (that is, ``1:5'' and ``1:5.*'' are equivalent). XA single number \fIn\fP is treated as if it were the range \fIn:n\fP. XAn arbitrary number of page selectors may be given, separated by commas Xor whitespace; a page is selected if any of the selectors matches Xits \ecounts or absolute page number. X.PP XDviselect normally prints the page numbers of the pages selected; the X.I \-s Xoption suppresses this. X.SH AUTHOR XChris Torek, University of Maryland X.SH "SEE ALSO" Xdvipr(1), iptex(1), tex(1), \fIThe TeXbook\fP X.SH BUGS XA leading ``-'' ought to be allowed for negative numbers, but it Xis currently used as a synonym for ``:'', for backwards compatibility. X.PP XSection or subsection selection will sometimes fail, for the DVI Xfile lists only the \ecount values that were active when the page Xended. Clever macro packages can alleviate this by making use of Xother ``free'' \ecount registers. Chapters normally begin on new Xpages, and do not suffer from this particular problem. X.PP X.I Dviselect Xdoes not adjust the parameters in the postamble; however, since these Xvalues are normally used only to size certain structures in the output Xconversion programs, and the parameters never need to be adjusted upward, Xthis has not proven to be a problem. END_OF_dviselect.1 if test 3897 -ne `wc -c <dviselect.1`; then echo shar: \"dviselect.1\" unpacked with wrong size! fi chmod +x dviselect.1 # end of overwriting check fi if test -f dviselect.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dviselect.c\" else echo shar: Extracting \"dviselect.c\" \(22215 characters\) sed "s/^X//" >dviselect.c <<'END_OF_dviselect.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/utilities/RCS/dviselect.c,v 1.3 87/12/06 12:27:33 grunwald Exp $"; X#endif X X/* X * DVI page selection program X * X * Reads DVI version 2 files and selects pages, writing a new DVI X * file. The new DVI file is technically correct, though we do not X * adjust the tallest and widest page values, nor the DVI stack size. X * This is all right since the values will never become too small, X * but it might be nice to fix them up. Perhaps someday . . . . X */ X X#include "types.h" X#include "dvi.h" X#include "dviclass.h" X#include "dvicodes.h" X#include "fio.h" X#include "search.h" X#include <stdio.h> X#include <ctype.h> X Xchar *ProgName; Xextern int errno; Xextern char *optarg; Xextern int optind; X X/* Globals */ Xchar serrbuf[BUFSIZ]; /* buffer for stderr */ X X/* X * We will try to keep output lines shorter than MAXCOL characters. X */ X#define MAXCOL 75 X X/* X * We use the following structure to keep track of fonts we have seen. X * The final DVI file lists only the fonts it uses. X */ Xstruct fontinfo { X i32 fi_newindex; /* font number in output file */ X int fi_reallyused; /* true => used on a page we copied */ X i32 fi_checksum; /* the checksum */ X i32 fi_mag; /* the magnification */ X i32 fi_designsize; /* the design size */ X short fi_n1; /* the name header length */ X short fi_n2; /* the name body length */ X char *fi_name; /* the name itself */ X}; X X/* X * We need to remember which pages the user would like. We build a linked X * list that allows us to decide (for any given page) whether it should X * be included in the output file. Each page has ten \count variables X * associated with it. We put a bound on the values allowed for each, and X * keep a linked list of alternatives should any be outside the allowed X * range. For example, `dviselect *.3,10-15' would generate a two-element X * page list, with the first allowing any value for \count0 (and \counts 2 to X * 9) but \count1 restricted to the range 3-3, and the second restricting X * \count0 to the range 10-15 but leaving \counts 1 to 9 unrestrained. X * X * In case no bound is specified, the `nol' or `noh' flag is set (so that X * we need not fix some `large' number as a maximum value). X * X * We also allow `absolute' page references, where the first page is X * page 1, the second 2, and so forth. These are specified with an X * equal sign: `dviselect =4:10' picks up the fourth through tenth X * sequential pages, irrespective of \count values. X */ Xstruct pagesel { X i32 ps_low; /* lower bound */ X int ps_nol; /* true iff no lower bound */ X i32 ps_high; /* upper bound */ X int ps_noh; /* true iff no upper bound */ X}; Xstruct pagelist { X struct pagelist *pl_alt; /* next in a series of alternates */ X int pl_len; /* number of ranges to check */ X int pl_abs; /* true iff absolute page ref */ X struct pagesel pl_pages[10]; /* one for each \count variable */ X}; X Xint SFlag; /* true => -s, silent operation */ X Xstruct search *FontFinder; /* maps from input indicies to fontinfo */ Xi32 NextOutputFontIndex; /* generates output indicies */ Xi32 CurrentFontIndex; /* current (old) index in input */ Xi32 OutputFontIndex; /* current (new) index in ouput */ X Xstruct pagelist *PageList; /* the list of allowed pages */ X XFILE *inf; /* the input DVI file */ XFILE *outf; /* the output DVI file */ X Xint ExpectBOP; /* true => BOP ok */ Xint ExpectEOP; /* true => EOP ok */ X Xlong StartOfLastPage; /* The file position just before we started X the last page (this is later written to X the output file as the previous page X pointer). */ Xlong CurrentPosition; /* The current position of the file */ X Xint UseThisPage; /* true => current page is selected */ X Xi32 InputPageNumber; /* current absolute page in old DVI file */ Xint NumberOfOutputPages; /* number of pages in new DVI file */ X Xi32 Numerator; /* numerator from DVI file */ Xi32 Denominator; /* denominator from DVI file */ Xi32 DVIMag; /* magnification from DVI file */ X Xi32 Count[10]; /* the 10 \count variables */ X X/* save some string space: we use this a lot */ Xchar writeerr[] = "error writing DVI file"; X Xchar *malloc(), *realloc(), *sprintf(); X X/* X * lint gets rather confused with the current definitions of getc and putc, X * so we redefine them here (#if lint). This should really be in the X * standard I/O library, but I am not about to go change it now! X */ X#ifdef lint X#undef putc X#undef getc X#define putc(c,f) (*(f)->_ptr++ = (unsigned) (c)) X#define getc(f) (*(f)->_ptr++) X#endif X X/* X * Return true iff the 10 \counts are one of the desired output pages. X */ XDesiredPageP() X{ X register struct pagelist *pl; X X for (pl = PageList; pl != NULL; pl = pl->pl_alt) { X register struct pagesel *ps = pl->pl_pages; X register int i; X register i32 *pagep; X X pagep = pl->pl_abs ? &InputPageNumber : &Count[0]; X for (i = 0; i < pl->pl_len; i++, ps++, pagep++) X if (!ps->ps_nol && *pagep < ps->ps_low || X !ps->ps_noh && *pagep > ps->ps_high) X break; /* not within bounds */ X if (i >= pl->pl_len) X return (1); /* success */ X } X return (0); X} X X/* X * Print a message to stderr, with an optional leading space, and handling X * long line wraps. X */ Xmessage(space, str, len) X int space; X register char *str; X register int len; X{ X static int beenhere; X static int col; X X if (!beenhere) X space = 0, beenhere++; X if (len == 0) X len = strlen(str); X col += len; X if (space) { X if (col >= MAXCOL) X (void) putc('\n', stderr), col = len; X else X (void) putc(' ', stderr), col++; X } X while (--len >= 0) X (void) putc(*str++, stderr); X (void) fflush(stderr); X} X X/* X * Start a page (process a DVI_BOP). X */ XBeginPage() X{ X register i32 *i; X X if (!ExpectBOP) X GripeUnexpectedOp("BOP"); X ExpectBOP = 0; X ExpectEOP++; /* set the new "expect" state */ X X OutputFontIndex = -1; /* new page requires respecifying font */ X InputPageNumber++; /* count it */ X for (i = Count; i < &Count[10]; i++) X fGetLong(inf, *i); X (void) GetLong(inf); /* previous page pointer */ X X if ((UseThisPage = DesiredPageP()) == 0) X return; X X (void) putc(DVI_BOP, outf); X for (i = Count; i < &Count[10]; i++) X PutLong(outf, *i); X PutLong(outf, StartOfLastPage); X if (ferror(outf)) X error(1, errno, writeerr); X X StartOfLastPage = CurrentPosition; X CurrentPosition += 45; /* we just wrote this much */ X X if (!SFlag) { /* write nice page usage messages */ X register int z = 0; X register int mlen = 0; X char msg[80]; X X (void) sprintf(msg, "[%d", Count[0]); X mlen = strlen(msg); X for (i = &Count[1]; i < &Count[10]; i++) { X if (*i == 0) { X z++; X continue; X } X while (--z >= 0) X msg[mlen++] = '.', msg[mlen++] = '0'; X z = 0; X (void) sprintf(msg + mlen, ".%d", *i); X mlen += strlen(msg + mlen); X } X message(1, msg, mlen); X } X} X X/* X * End a page (process a DVI_EOP). X */ XEndPage() X{ X if (!ExpectEOP) X GripeUnexpectedOp("EOP"); X ExpectEOP = 0; X ExpectBOP++; X X if (!UseThisPage) X return; X X if (!SFlag) X message(0, "]", 1); X X putc(DVI_EOP, outf); X if (ferror(outf)) X error(1, errno, writeerr); X CurrentPosition++; X NumberOfOutputPages++; X} X X/* X * For each of the fonts used in the new DVI file, write out a definition. X */ X/* ARGSUSED */ XPostAmbleFontEnumerator(addr, key) X char *addr; X i32 key; X{ X X if (((struct fontinfo *) addr)->fi_reallyused) X WriteFont((struct fontinfo *) addr); X} X XHandlePostAmble() X{ X register i32 c; X X (void) GetLong(inf); /* previous page pointer */ X if (GetLong(inf) != Numerator) X GripeMismatchedValue("numerator"); X if (GetLong(inf) != Denominator) X GripeMismatchedValue("denominator"); X if (GetLong(inf) != DVIMag) X GripeMismatchedValue("\\magfactor"); X X putc(DVI_POST, outf); X PutLong(outf, StartOfLastPage); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X c = GetLong(inf); X PutLong(outf, c); /* tallest page height */ X c = GetLong(inf); X PutLong(outf, c); /* widest page width */ X c = GetWord(inf); X PutWord(outf, c); /* DVI stack size */ X PutWord(outf, NumberOfOutputPages); X StartOfLastPage = CurrentPosition; /* point at post */ X CurrentPosition += 29; /* count all those `put's */ X#ifdef notdef X (void) GetWord(inf); /* skip original number of pages */ X#endif X X /* X * just ignore all the incoming font definitions; we are done with X * input file X */ X X /* X * run through the FontFinder table and dump definitions for the X * fonts we have used. X */ X SEnumerate(FontFinder, PostAmbleFontEnumerator); X X putc(DVI_POSTPOST, outf); X PutLong(outf, StartOfLastPage); /* actually start of postamble */ X putc(DVI_VERSION, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X CurrentPosition += 10; X while (CurrentPosition & 3) X putc(DVI_FILLER, outf), CurrentPosition++; X if (ferror(outf)) X error(1, errno, writeerr); X} X X/* X * Write a font definition to the output file X */ XWriteFont(fi) X register struct fontinfo *fi; X{ X register int l; X register char *s; X X if (fi->fi_newindex < 256) { X putc(DVI_FNTDEF1, outf); X putc(fi->fi_newindex, outf); X CurrentPosition += 2; X } else if (fi->fi_newindex < 65536) { X putc(DVI_FNTDEF2, outf); X PutWord(outf, fi->fi_newindex); X CurrentPosition += 3; X } else if (fi->fi_newindex < 16777216) { X putc(DVI_FNTDEF3, outf); X Put3Byte(outf, fi->fi_newindex); X CurrentPosition += 4; X } else { X putc(DVI_FNTDEF4, outf); X PutLong(outf, fi->fi_newindex); X CurrentPosition += 5; X } X PutLong(outf, fi->fi_checksum); X PutLong(outf, fi->fi_mag); X PutLong(outf, fi->fi_designsize); X putc(fi->fi_n1, outf); X putc(fi->fi_n2, outf); X l = fi->fi_n1 + fi->fi_n2; X CurrentPosition += 14 + l; X s = fi->fi_name; X while (--l >= 0) X putc(*s, outf), s++; X} X X/* X * Handle the preamble. Someday we should update the comment field. X */ XHandlePreAmble() X{ X register int n, c; X X if (GetByte(inf) != Sign8(DVI_PRE)) X GripeMissingOp("PRE"); X if (GetByte(inf) != Sign8(DVI_VERSION)) X GripeMismatchedValue("DVI version number"); X Numerator = GetLong(inf); X Denominator = GetLong(inf); X DVIMag = GetLong(inf); X putc(DVI_PRE, outf); X putc(DVI_VERSION, outf); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X X n = UnSign8(GetByte(inf)); X CurrentPosition = 15 + n; /* well, almost */ X putc(n, outf); X while (--n >= 0) { X c = GetByte(inf); X putc(c, outf); /* never trust a macro, I always say */ X } X} X Xmain(argc, argv) X int argc; X register char **argv; X{ X register int c; X register char *s; X char *inname = NULL, *outname = NULL; X X ProgName = *argv; X setbuf(stderr, serrbuf); X X while ((c = getopt(argc, argv, "i:o:s")) != EOF) { X switch (c) { X X case 's': /* silent */ X SFlag++; X break; X X case 'i': X if (inname != NULL) X goto usage; X inname = optarg; X break; X X case 'o': X if (outname != NULL) X goto usage; X outname = optarg; X break; X X case '?': Xusage: X fprintf(stderr, "\ XUsage: %s [-s] [-i infile] [-o outfile] pages [...] [infile [outfile]]\n", X ProgName); X (void) fflush(stderr); X exit(1); X } X } X X while (optind < argc) { X s = argv[optind++]; X c = *s; X if (!isalpha(c) && c != '/') { X if (ParsePages(s)) X goto usage; X } else if (inname == NULL) X inname = s; X else if (outname == NULL) X outname = s; X else X goto usage; X } X if (PageList == NULL) X goto usage; X if (inname == NULL) X inf = stdin; X else if ((inf = fopen(inname, "r")) == 0) X error(1, errno, "cannot read %s", inname); X if (outname == NULL) X outf = stdout; X else if ((outf = fopen(outname, "w")) == 0) X error(1, errno, "cannot write %s", outname); X X if ((FontFinder = SCreate(sizeof(struct fontinfo))) == 0) X error(1, 0, "cannot create font finder (out of memory?)"); X X ExpectBOP++; X StartOfLastPage = -1; X HandlePreAmble(); X HandleDVIFile(); X HandlePostAmble(); X if (!SFlag) X fprintf(stderr, "\nWrote %d pages, %d bytes\n", X NumberOfOutputPages, CurrentPosition); X if (NumberOfOutputPages == 0) X exit(1); X else X exit(0); X} X Xstruct pagelist * XInstallPL(ps, n, absolute) X register struct pagesel *ps; X register int n; X int absolute; X{ X register struct pagelist *pl; X X pl = (struct pagelist *) malloc(sizeof *pl); X if (pl == NULL) X GripeOutOfMemory(sizeof *pl, "page list"); X pl->pl_alt = PageList; X PageList = pl; X pl->pl_len = n; X while (--n >= 0) X pl->pl_pages[n] = ps[n]; X pl->pl_abs = absolute; X} X X/* X * Parse a string representing a list of pages. Return 0 iff ok. As a X * side effect, the page selection(s) is (are) prepended to PageList. X */ XParsePages(s) X register char *s; X{ X register struct pagesel *ps; X register int c; /* current character */ X register i32 n; /* current numeric value */ X register int innumber; /* true => gathering a number */ X int i; /* next index in page select list */ X int range; /* true => saw a range indicator */ X int negative; /* true => number being built is negative */ X int absolute; /* true => absolute, not \count */ X struct pagesel pagesel[10]; X X#define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',') X X range = 0; X innumber = 0; X absolute = 0; X i = 0; X ps = pagesel; X /* X * Talk about ad hoc! (Not to mention convoluted.) X */ X for (;;) { X c = *s++; X if (i == 0 && !innumber && !range) { X /* nothing special going on */ X if (c == 0) X return 0; X if (white(c)) X continue; X } X if (c == '_') { X /* kludge: should be '-' for negatives */ X if (innumber || absolute) X return (-1); X innumber++; X negative = 1; X n = 0; X continue; X } X if (c == '=') { X /* absolute page */ X if (innumber || range || i > 0) X return (-1); X absolute++; X /* X * Setting innumber means that there is always X * a lower bound, but this is all right since X * `=:4' is treated as if it were `=0:4'. As X * there are no negative absolute page numbers, X * this selects pages 1:4, which is the proper X * action. X */ X innumber++; X negative = 0; X n = 0; X continue; X } X if (isdigit(c)) { X /* accumulate numeric value */ X if (!innumber) { X innumber++; X negative = 0; X n = c - '0'; X continue; X } X n *= 10; X n += negative ? '0' - c : c - '0'; X continue; X } X if (c == '-' || c == ':') { X /* here is a range */ X if (range) X return (-1); X if (innumber) { /* have a lower bound */ X ps->ps_low = n; X ps->ps_nol = 0; X } else X ps->ps_nol = 1; X range++; X innumber = 0; X continue; X } X if (c == '*') { X /* no lower bound, no upper bound */ X c = *s++; X if (innumber || range || i >= 10 || X (c && c != '.' && !white(c))) X return (-1); X ps->ps_nol = 1; X ps->ps_noh = 1; X goto finishnum; X } X if (c == 0 || c == '.' || white(c)) { X /* end of this range */ X if (i >= 10) X return (-1); X if (!innumber) { /* no upper bound */ X ps->ps_noh = 1; X if (!range) /* no lower bound either */ X ps->ps_nol = 1; X } else { /* have an upper bound */ X ps->ps_high = n; X ps->ps_noh = 0; X if (!range) { X /* no range => lower bound == upper */ X ps->ps_low = ps->ps_high; X ps->ps_nol = 0; X } X } Xfinishnum: X i++; X if (c == '.') { X if (absolute) X return (-1); X ps++; X } else { X InstallPL(pagesel, i, absolute); X ps = pagesel; X i = 0; X absolute = 0; X } X if (c == 0) X return (0); X range = 0; X innumber = 0; X continue; X } X /* illegal character */ X return (-1); X } X#undef white X} X X/* X * Handle a font definition. X */ XHandleFontDef(index) X i32 index; X{ X register struct fontinfo *fi; X register int i; X register char *s; X int def = S_CREATE | S_EXCL; X X if ((fi = (struct fontinfo *) SSearch(FontFinder, index, &def)) == 0) X if (def & S_COLL) X error(1, 0, "font %d already defined", index); X else X error(1, 0, "cannot stash font %d (out of memory?)", X index); X fi->fi_reallyused = 0; X fi->fi_checksum = GetLong(inf); X fi->fi_mag = GetLong(inf); X fi->fi_designsize = GetLong(inf); X fi->fi_n1 = UnSign8(GetByte(inf)); X fi->fi_n2 = UnSign8(GetByte(inf)); X i = fi->fi_n1 + fi->fi_n2; X if ((s = malloc((unsigned) i)) == 0) X GripeOutOfMemory(i, "font name"); X fi->fi_name = s; X while (--i >= 0) X *s++ = GetByte(inf); X} X X/* X * Handle a \special. X */ XHandleSpecial(c, l, p) X int c; X register int l; X register i32 p; X{ X register int i; X X if (UseThisPage) { X putc(c, outf); X switch (l) { X X case DPL_UNS1: X putc(p, outf); X CurrentPosition += 2; X break; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X break; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X break; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X break; X X default: X panic("HandleSpecial l=%d", l); X /* NOTREACHED */ X } X CurrentPosition += p; X while (--p >= 0) { X i = getc(inf); X putc(i, outf); X } X if (feof(inf)) X error(1, 0, "unexpected EOF"); X if (ferror(outf)) X error(1, errno, writeerr); X } else X while (--p >= 0) X (void) getc(inf); X} X XReallyUseFont() X{ X register struct fontinfo *fi; X int look = S_LOOKUP; X X fi = (struct fontinfo *) SSearch(FontFinder, CurrentFontIndex, &look); X if (fi == 0) X error(1, 0, "index %d not in font table!", CurrentFontIndex); X if (fi->fi_reallyused == 0) { X fi->fi_reallyused++; X fi->fi_newindex = NextOutputFontIndex++; X WriteFont(fi); X } X if (fi->fi_newindex != OutputFontIndex) { X PutFontSelector(fi->fi_newindex); X OutputFontIndex = fi->fi_newindex; X } X} X X/* X * Write a font selection command to the output file X */ XPutFontSelector(index) X i32 index; X{ X X if (index < 64) { X putc(index + DVI_FNTNUM0, outf); X CurrentPosition++; X } else if (index < 256) { X putc(DVI_FNT1, outf); X putc(index, outf); X CurrentPosition += 2; X } else if (index < 65536) { X putc(DVI_FNT2, outf); X PutWord(outf, index); X CurrentPosition += 3; X } else if (index < 16777216) { X putc(DVI_FNT3, outf); X Put3Byte(outf, index); X CurrentPosition += 4; X } else { X putc(DVI_FNT4, outf); X PutLong(outf, index); X CurrentPosition += 5; X } X} X X/* X * The following table describes the length (in bytes) of each of the DVI X * commands that we can simply copy, starting with DVI_SET1 (128). X */ Xchar oplen[128] = { X 0, 0, 0, 0, /* DVI_SET1 .. DVI_SET4 */ X 9, /* DVI_SETRULE */ X 0, 0, 0, 0, /* DVI_PUT1 .. DVI_PUT4 */ X 9, /* DVI_PUTRULE */ X 1, /* DVI_NOP */ X 0, /* DVI_BOP */ X 0, /* DVI_EOP */ X 1, /* DVI_PUSH */ X 1, /* DVI_POP */ X 2, 3, 4, 5, /* DVI_RIGHT1 .. DVI_RIGHT4 */ X 1, /* DVI_W0 */ X 2, 3, 4, 5, /* DVI_W1 .. DVI_W4 */ X 1, /* DVI_X0 */ X 2, 3, 4, 5, /* DVI_X1 .. DVI_X4 */ X 2, 3, 4, 5, /* DVI_DOWN1 .. DVI_DOWN4 */ X 1, /* DVI_Y0 */ X 2, 3, 4, 5, /* DVI_Y1 .. DVI_Y4 */ X 1, /* DVI_Z0 */ X 2, 3, 4, 5, /* DVI_Z1 .. DVI_Z4 */ X 0, /* DVI_FNTNUM0 (171) */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 172 .. 179 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 180 .. 187 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 188 .. 195 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 196 .. 203 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 204 .. 211 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 212 .. 219 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 220 .. 227 */ X 0, 0, 0, 0, 0, 0, 0, /* 228 .. 234 */ X 0, 0, 0, 0, /* DVI_FNT1 .. DVI_FNT4 */ X 0, 0, 0, 0, /* DVI_XXX1 .. DVI_XXX4 */ X 0, 0, 0, 0, /* DVI_FNTDEF1 .. DVI_FNTDEF4 */ X 0, /* DVI_PRE */ X 0, /* DVI_POST */ X 0, /* DVI_POSTPOST */ X 0, 0, 0, 0, 0, 0, /* 250 .. 255 */ X}; X X/* X * Here we read the input DVI file and write relevant pages to the X * output DVI file. We also keep track of font changes, handle font X * definitions, and perform some other housekeeping. X */ XHandleDVIFile() X{ X register int c, l; X register i32 p; X register int CurrentFontOK = 0; X X /* Only way out is via "return" statement */ X for (;;) { X c = getc(inf); /* getc() returns unsigned values */ X if (DVI_IsChar(c)) { X /* X * Copy chars, note font usage, but ignore if X * page is not interesting. X */ X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putc(c, outf); X CurrentPosition++; X continue; X } X if (DVI_IsFont(c)) { /* note font change */ X CurrentFontIndex = c - DVI_FNTNUM0; X CurrentFontOK = 0; X continue; X } X if ((l = (oplen - 128)[c]) != 0) { /* simple copy */ X if (!UseThisPage) { X while (--l > 0) X (void) getc(inf); X continue; X } X CurrentPosition += l; X putc(c, outf); X while (--l > 0) { X c = getc(inf); X putc(c, outf); X } X if (ferror(outf)) X error(1, errno, writeerr); X continue; X } X if ((l = DVI_OpLen(c)) != 0) { X /* X * Handle other generics. X * N.B.: there should only be unsigned parameters X * here (save SGN4), for commands with negative X * parameters have been taken care of above. X */ X switch (l) { X X case DPL_UNS1: X p = getc(inf); X break; X X case DPL_UNS2: X fGetWord(inf, p); X break; X X case DPL_UNS3: X fGet3Byte(inf, p); X break; X X case DPL_SGN4: X fGetLong(inf, p); X break; X X default: X panic("HandleDVIFile l=%d", l); X } X X /* X * Now that we have the parameter, perform the X * command. X */ X switch (DVI_DT(c)) { X X case DT_SET: X case DT_PUT: X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putc(c, outf); X switch (l) { X X case DPL_UNS1: X putc(p, outf); X CurrentPosition += 2; X continue; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X continue; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X continue; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X continue; X } X X case DT_FNT: X CurrentFontIndex = p; X CurrentFontOK = 0; X continue; X X case DT_XXX: X HandleSpecial(c, l, p); X continue; X X case DT_FNTDEF: X HandleFontDef(p); X continue; X X default: X panic("HandleDVIFile DVI_DT(%d)=%d", X c, DVI_DT(c)); X } X continue; X } X X switch (c) { /* handle the few remaining cases */ X X case DVI_BOP: X BeginPage(); X CurrentFontOK = 0; X break; X X case DVI_EOP: X EndPage(); X break; X X case DVI_PRE: X GripeUnexpectedOp("PRE"); X /* NOTREACHED */ X X case DVI_POST: X return; X X case DVI_POSTPOST: X GripeUnexpectedOp("POSTPOST"); X /* NOTREACHED */ X X default: X GripeUndefinedOp(c); X /* NOTREACHED */ X } X } X} END_OF_dviselect.c if test 22215 -ne `wc -c <dviselect.c`; then echo shar: \"dviselect.c\" unpacked with wrong size! fi chmod +x dviselect.c # end of overwriting check fi if test -f dviselect.c.orig -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dviselect.c.orig\" else echo shar: Extracting \"dviselect.c.orig\" \(22164 characters\) sed "s/^X//" >dviselect.c.orig <<'END_OF_dviselect.c.orig' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/utilities/RCS/dviselect.c,v 1.3 87/12/06 12:27:33 grunwald Exp $"; X#endif X X/* X * DVI page selection program X * X * Reads DVI version 2 files and selects pages, writing a new DVI X * file. The new DVI file is technically correct, though we do not X * adjust the tallest and widest page values, nor the DVI stack size. X * This is all right since the values will never become too small, X * but it might be nice to fix them up. Perhaps someday . . . . X */ X X#include "types.h" X#include "dvi.h" X#include "dviclass.h" X#include "dvicodes.h" X#include "fio.h" X#include "search.h" X#include <stdio.h> X#include <ctype.h> X Xchar *ProgName; Xextern int errno; Xextern char *optarg; Xextern int optind; X X/* Globals */ Xchar serrbuf[BUFSIZ]; /* buffer for stderr */ X X/* X * We will try to keep output lines shorter than MAXCOL characters. X */ X#define MAXCOL 75 X X/* X * We use the following structure to keep track of fonts we have seen. X * The final DVI file lists only the fonts it uses. X */ Xstruct fontinfo { X i32 fi_newindex; /* font number in output file */ X int fi_reallyused; /* true => used on a page we copied */ X i32 fi_checksum; /* the checksum */ X i32 fi_mag; /* the magnification */ X i32 fi_designsize; /* the design size */ X short fi_n1; /* the name header length */ X short fi_n2; /* the name body length */ X char *fi_name; /* the name itself */ X}; X X/* X * We need to remember which pages the user would like. We build a linked X * list that allows us to decide (for any given page) whether it should X * be included in the output file. Each page has ten \count variables X * associated with it. We put a bound on the values allowed for each, and X * keep a linked list of alternatives should any be outside the allowed X * range. For example, `dviselect *.3,10-15' would generate a two-element X * page list, with the first allowing any value for \count0 (and \counts 2 to X * 9) but \count1 restricted to the range 3-3, and the second restricting X * \count0 to the range 10-15 but leaving \counts 1 to 9 unrestrained. X * X * In case no bound is specified, the `nol' or `noh' flag is set (so that X * we need not fix some `large' number as a maximum value). X * X * We also allow `absolute' page references, where the first page is X * page 1, the second 2, and so forth. These are specified with an X * equal sign: `dviselect =4:10' picks up the fourth through tenth X * sequential pages, irrespective of \count values. X */ Xstruct pagesel { X i32 ps_low; /* lower bound */ X int ps_nol; /* true iff no lower bound */ X i32 ps_high; /* upper bound */ X int ps_noh; /* true iff no upper bound */ X}; Xstruct pagelist { X struct pagelist *pl_alt; /* next in a series of alternates */ X int pl_len; /* number of ranges to check */ X int pl_abs; /* true iff absolute page ref */ X struct pagesel pl_pages[10]; /* one for each \count variable */ X}; X Xint SFlag; /* true => -s, silent operation */ X Xstruct search *FontFinder; /* maps from input indicies to fontinfo */ Xi32 NextOutputFontIndex; /* generates output indicies */ Xi32 CurrentFontIndex; /* current (old) index in input */ Xi32 OutputFontIndex; /* current (new) index in ouput */ X Xstruct pagelist *PageList; /* the list of allowed pages */ X XFILE *inf; /* the input DVI file */ XFILE *outf; /* the output DVI file */ X Xint ExpectBOP; /* true => BOP ok */ Xint ExpectEOP; /* true => EOP ok */ X Xlong StartOfLastPage; /* The file position just before we started X the last page (this is later written to X the output file as the previous page X pointer). */ Xlong CurrentPosition; /* The current position of the file */ X Xint UseThisPage; /* true => current page is selected */ X Xi32 InputPageNumber; /* current absolute page in old DVI file */ Xint NumberOfOutputPages; /* number of pages in new DVI file */ X Xi32 Numerator; /* numerator from DVI file */ Xi32 Denominator; /* denominator from DVI file */ Xi32 DVIMag; /* magnification from DVI file */ X Xi32 Count[10]; /* the 10 \count variables */ X X/* save some string space: we use this a lot */ Xchar writeerr[] = "error writing DVI file"; X Xchar *malloc(), *realloc(), *sprintf(); X X/* X * lint gets rather confused with the current definitions of getc and putc, X * so we redefine them here (#if lint). This should really be in the X * standard I/O library, but I am not about to go change it now! X */ X#ifdef lint X#undef putc X#undef getc X#define putc(c,f) (*(f)->_ptr++ = (unsigned) (c)) X#define getc(f) (*(f)->_ptr++) X#endif X X/* X * Return true iff the 10 \counts are one of the desired output pages. X */ XDesiredPageP() X{ X register struct pagelist *pl; X X for (pl = PageList; pl != NULL; pl = pl->pl_alt) { X register struct pagesel *ps = pl->pl_pages; X register int i; X register i32 *pagep; X X pagep = pl->pl_abs ? &InputPageNumber : &Count[0]; X for (i = 0; i < pl->pl_len; i++, ps++, pagep++) X if (!ps->ps_nol && *pagep < ps->ps_low || X !ps->ps_noh && *pagep > ps->ps_high) X break; /* not within bounds */ X if (i >= pl->pl_len) X return (1); /* success */ X } X return (0); X} X X/* X * Print a message to stderr, with an optional leading space, and handling X * long line wraps. X */ Xmessage(space, str, len) X int space; X register char *str; X register int len; X{ X static int beenhere; X static int col; X X if (!beenhere) X space = 0, beenhere++; X if (len == 0) X len = strlen(str); X col += len; X if (space) { X if (col >= MAXCOL) X (void) putc('\n', stderr), col = len; X else X (void) putc(' ', stderr), col++; X } X while (--len >= 0) X (void) putc(*str++, stderr); X (void) fflush(stderr); X} X X/* X * Start a page (process a DVI_BOP). X */ XBeginPage() X{ X register i32 *i; X X if (!ExpectBOP) X GripeUnexpectedOp("BOP"); X ExpectBOP = 0; X ExpectEOP++; /* set the new "expect" state */ X X OutputFontIndex = -1; /* new page requires respecifying font */ X InputPageNumber++; /* count it */ X for (i = Count; i < &Count[10]; i++) X fGetLong(inf, *i); X (void) GetLong(inf); /* previous page pointer */ X X if ((UseThisPage = DesiredPageP()) == 0) X return; X X (void) putc(DVI_BOP, outf); X for (i = Count; i < &Count[10]; i++) X PutLong(outf, *i); X PutLong(outf, StartOfLastPage); X if (ferror(outf)) X error(1, errno, writeerr); X X StartOfLastPage = CurrentPosition; X CurrentPosition += 45; /* we just wrote this much */ X X if (!SFlag) { /* write nice page usage messages */ X register int z = 0; X register int mlen = 0; X char msg[80]; X X (void) sprintf(msg, "[%d", Count[0]); X mlen = strlen(msg); X for (i = &Count[1]; i < &Count[10]; i++) { X if (*i == 0) { X z++; X continue; X } X while (--z >= 0) X msg[mlen++] = '.', msg[mlen++] = '0'; X z = 0; X (void) sprintf(msg + mlen, ".%d", *i); X mlen += strlen(msg + mlen); X } X message(1, msg, mlen); X } X} X X/* X * End a page (process a DVI_EOP). X */ XEndPage() X{ X if (!ExpectEOP) X GripeUnexpectedOp("EOP"); X ExpectEOP = 0; X ExpectBOP++; X X if (!UseThisPage) X return; X X if (!SFlag) X message(0, "]", 1); X X putc(DVI_EOP, outf); X if (ferror(outf)) X error(1, errno, writeerr); X CurrentPosition++; X NumberOfOutputPages++; X} X X/* X * For each of the fonts used in the new DVI file, write out a definition. X */ X/* ARGSUSED */ XPostAmbleFontEnumerator(addr, key) X char *addr; X i32 key; X{ X X if (((struct fontinfo *) addr)->fi_reallyused) X WriteFont((struct fontinfo *) addr); X} X XHandlePostAmble() X{ X register i32 c; X X (void) GetLong(inf); /* previous page pointer */ X if (GetLong(inf) != Numerator) X GripeMismatchedValue("numerator"); X if (GetLong(inf) != Denominator) X GripeMismatchedValue("denominator"); X if (GetLong(inf) != DVIMag) X GripeMismatchedValue("\\magfactor"); X X putc(DVI_POST, outf); X PutLong(outf, StartOfLastPage); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X c = GetLong(inf); X PutLong(outf, c); /* tallest page height */ X c = GetLong(inf); X PutLong(outf, c); /* widest page width */ X c = GetWord(inf); X PutWord(outf, c); /* DVI stack size */ X PutWord(outf, NumberOfOutputPages); X StartOfLastPage = CurrentPosition; /* point at post */ X CurrentPosition += 29; /* count all those `put's */ X#ifdef notdef X (void) GetWord(inf); /* skip original number of pages */ X#endif X X /* X * just ignore all the incoming font definitions; we are done with X * input file X */ X X /* X * run through the FontFinder table and dump definitions for the X * fonts we have used. X */ X SEnumerate(FontFinder, PostAmbleFontEnumerator); X X putc(DVI_POSTPOST, outf); X PutLong(outf, StartOfLastPage); /* actually start of postamble */ X putc(DVI_VERSION, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X putc(DVI_FILLER, outf); X CurrentPosition += 10; X while (CurrentPosition & 3) X putc(DVI_FILLER, outf), CurrentPosition++; X if (ferror(outf)) X error(1, errno, writeerr); X} X X/* X * Write a font definition to the output file X */ XWriteFont(fi) X register struct fontinfo *fi; X{ X register int l; X register char *s; X X if (fi->fi_newindex < 256) { X putc(DVI_FNTDEF1, outf); X putc(fi->fi_newindex, outf); X CurrentPosition += 2; X } else if (fi->fi_newindex < 65536) { X putc(DVI_FNTDEF2, outf); X PutWord(outf, fi->fi_newindex); X CurrentPosition += 3; X } else if (fi->fi_newindex < 16777216) { X putc(DVI_FNTDEF3, outf); X Put3Byte(outf, fi->fi_newindex); X CurrentPosition += 4; X } else { X putc(DVI_FNTDEF4, outf); X PutLong(outf, fi->fi_newindex); X CurrentPosition += 5; X } X PutLong(outf, fi->fi_checksum); X PutLong(outf, fi->fi_mag); X PutLong(outf, fi->fi_designsize); X putc(fi->fi_n1, outf); X putc(fi->fi_n2, outf); X l = fi->fi_n1 + fi->fi_n2; X CurrentPosition += 14 + l; X s = fi->fi_name; X while (--l >= 0) X putc(*s, outf), s++; X} X X/* X * Handle the preamble. Someday we should update the comment field. X */ XHandlePreAmble() X{ X register int n, c; X X if (GetByte(inf) != Sign8(DVI_PRE)) X GripeMissingOp("PRE"); X if (GetByte(inf) != Sign8(DVI_VERSION)) X GripeMismatchedValue("DVI version number"); X Numerator = GetLong(inf); X Denominator = GetLong(inf); X DVIMag = GetLong(inf); X putc(DVI_PRE, outf); X putc(DVI_VERSION, outf); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X X n = UnSign8(GetByte(inf)); X CurrentPosition = 15 + n; /* well, almost */ X putc(n, outf); X while (--n >= 0) { X c = GetByte(inf); X putc(c, outf); /* never trust a macro, I always say */ X } X} X Xmain(argc, argv) X int argc; X register char **argv; X{ X register int c; X register char *s; X char *inname = NULL, *outname = NULL; X X ProgName = *argv; X setbuf(stderr, serrbuf); X X while ((c = getopt(argc, argv, "i:o:s")) != EOF) { X switch (c) { X X case 's': /* silent */ X SFlag++; X break; X X case 'i': X if (inname != NULL) X goto usage; X inname = optarg; X break; X X case 'o': X if (outname != NULL) X goto usage; X outname = optarg; X break; X X case '?': Xusage: X fprintf(stderr, "\ XUsage: %s [-s] [-i infile] [-o outfile] pages [...] [infile [outfile]]\n", X ProgName); X (void) fflush(stderr); X exit(1); X } X } X X while (optind < argc) { X s = argv[optind++]; X c = *s; X if (!isalpha(c) && c != '/') { X if (ParsePages(s)) X goto usage; X } else if (inname == NULL) X inname = s; X else if (outname == NULL) X outname = s; X else X goto usage; X } X if (PageList == NULL) X goto usage; X if (inname == NULL) X inf = stdin; X else if ((inf = fopen(inname, "r")) == 0) X error(1, errno, "cannot read %s", inname); X if (outname == NULL) X outf = stdout; X else if ((outf = fopen(outname, "w")) == 0) X error(1, errno, "cannot write %s", outname); X X if ((FontFinder = SCreate(sizeof(struct fontinfo))) == 0) X error(1, 0, "cannot create font finder (out of memory?)"); X X ExpectBOP++; X StartOfLastPage = -1; X HandlePreAmble(); X HandleDVIFile(); X HandlePostAmble(); X if (!SFlag) X fprintf(stderr, "\nWrote %d pages, %d bytes\n", X NumberOfOutputPages, CurrentPosition); X exit(0); X} X Xstruct pagelist * XInstallPL(ps, n, absolute) X register struct pagesel *ps; X register int n; X int absolute; X{ X register struct pagelist *pl; X X pl = (struct pagelist *) malloc(sizeof *pl); X if (pl == NULL) X GripeOutOfMemory(sizeof *pl, "page list"); X pl->pl_alt = PageList; X PageList = pl; X pl->pl_len = n; X while (--n >= 0) X pl->pl_pages[n] = ps[n]; X pl->pl_abs = absolute; X} X X/* X * Parse a string representing a list of pages. Return 0 iff ok. As a X * side effect, the page selection(s) is (are) prepended to PageList. X */ XParsePages(s) X register char *s; X{ X register struct pagesel *ps; X register int c; /* current character */ X register i32 n; /* current numeric value */ X register int innumber; /* true => gathering a number */ X int i; /* next index in page select list */ X int range; /* true => saw a range indicator */ X int negative; /* true => number being built is negative */ X int absolute; /* true => absolute, not \count */ X struct pagesel pagesel[10]; X X#define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',') X X range = 0; X innumber = 0; X absolute = 0; X i = 0; X ps = pagesel; X /* X * Talk about ad hoc! (Not to mention convoluted.) X */ X for (;;) { X c = *s++; X if (i == 0 && !innumber && !range) { X /* nothing special going on */ X if (c == 0) X return 0; X if (white(c)) X continue; X } X if (c == '_') { X /* kludge: should be '-' for negatives */ X if (innumber || absolute) X return (-1); X innumber++; X negative = 1; X n = 0; X continue; X } X if (c == '=') { X /* absolute page */ X if (innumber || range || i > 0) X return (-1); X absolute++; X /* X * Setting innumber means that there is always X * a lower bound, but this is all right since X * `=:4' is treated as if it were `=0:4'. As X * there are no negative absolute page numbers, X * this selects pages 1:4, which is the proper X * action. X */ X innumber++; X negative = 0; X n = 0; X continue; X } X if (isdigit(c)) { X /* accumulate numeric value */ X if (!innumber) { X innumber++; X negative = 0; X n = c - '0'; X continue; X } X n *= 10; X n += negative ? '0' - c : c - '0'; X continue; X } X if (c == '-' || c == ':') { X /* here is a range */ X if (range) X return (-1); X if (innumber) { /* have a lower bound */ X ps->ps_low = n; X ps->ps_nol = 0; X } else X ps->ps_nol = 1; X range++; X innumber = 0; X continue; X } X if (c == '*') { X /* no lower bound, no upper bound */ X c = *s++; X if (innumber || range || i >= 10 || X (c && c != '.' && !white(c))) X return (-1); X ps->ps_nol = 1; X ps->ps_noh = 1; X goto finishnum; X } X if (c == 0 || c == '.' || white(c)) { X /* end of this range */ X if (i >= 10) X return (-1); X if (!innumber) { /* no upper bound */ X ps->ps_noh = 1; X if (!range) /* no lower bound either */ X ps->ps_nol = 1; X } else { /* have an upper bound */ X ps->ps_high = n; X ps->ps_noh = 0; X if (!range) { X /* no range => lower bound == upper */ X ps->ps_low = ps->ps_high; X ps->ps_nol = 0; X } X } Xfinishnum: X i++; X if (c == '.') { X if (absolute) X return (-1); X ps++; X } else { X InstallPL(pagesel, i, absolute); X ps = pagesel; X i = 0; X absolute = 0; X } X if (c == 0) X return (0); X range = 0; X innumber = 0; X continue; X } X /* illegal character */ X return (-1); X } X#undef white X} X X/* X * Handle a font definition. X */ XHandleFontDef(index) X i32 index; X{ X register struct fontinfo *fi; X register int i; X register char *s; X int def = S_CREATE | S_EXCL; X X if ((fi = (struct fontinfo *) SSearch(FontFinder, index, &def)) == 0) X if (def & S_COLL) X error(1, 0, "font %d already defined", index); X else X error(1, 0, "cannot stash font %d (out of memory?)", X index); X fi->fi_reallyused = 0; X fi->fi_checksum = GetLong(inf); X fi->fi_mag = GetLong(inf); X fi->fi_designsize = GetLong(inf); X fi->fi_n1 = UnSign8(GetByte(inf)); X fi->fi_n2 = UnSign8(GetByte(inf)); X i = fi->fi_n1 + fi->fi_n2; X if ((s = malloc((unsigned) i)) == 0) X GripeOutOfMemory(i, "font name"); X fi->fi_name = s; X while (--i >= 0) X *s++ = GetByte(inf); X} X X/* X * Handle a \special. X */ XHandleSpecial(c, l, p) X int c; X register int l; X register i32 p; X{ X register int i; X X if (UseThisPage) { X putc(c, outf); X switch (l) { X X case DPL_UNS1: X putc(p, outf); X CurrentPosition += 2; X break; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X break; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X break; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X break; X X default: X panic("HandleSpecial l=%d", l); X /* NOTREACHED */ X } X CurrentPosition += p; X while (--p >= 0) { X i = getc(inf); X putc(i, outf); X } X if (feof(inf)) X error(1, 0, "unexpected EOF"); X if (ferror(outf)) X error(1, errno, writeerr); X } else X while (--p >= 0) X (void) getc(inf); X} X XReallyUseFont() X{ X register struct fontinfo *fi; X int look = S_LOOKUP; X X fi = (struct fontinfo *) SSearch(FontFinder, CurrentFontIndex, &look); X if (fi == 0) X error(1, 0, "index %d not in font table!", CurrentFontIndex); X if (fi->fi_reallyused == 0) { X fi->fi_reallyused++; X fi->fi_newindex = NextOutputFontIndex++; X WriteFont(fi); X } X if (fi->fi_newindex != OutputFontIndex) { X PutFontSelector(fi->fi_newindex); X OutputFontIndex = fi->fi_newindex; X } X} X X/* X * Write a font selection command to the output file X */ XPutFontSelector(index) X i32 index; X{ X X if (index < 64) { X putc(index + DVI_FNTNUM0, outf); X CurrentPosition++; X } else if (index < 256) { X putc(DVI_FNT1, outf); X putc(index, outf); X CurrentPosition += 2; X } else if (index < 65536) { X putc(DVI_FNT2, outf); X PutWord(outf, index); X CurrentPosition += 3; X } else if (index < 16777216) { X putc(DVI_FNT3, outf); X Put3Byte(outf, index); X CurrentPosition += 4; X } else { X putc(DVI_FNT4, outf); X PutLong(outf, index); X CurrentPosition += 5; X } X} X X/* X * The following table describes the length (in bytes) of each of the DVI X * commands that we can simply copy, starting with DVI_SET1 (128). X */ Xchar oplen[128] = { X 0, 0, 0, 0, /* DVI_SET1 .. DVI_SET4 */ X 9, /* DVI_SETRULE */ X 0, 0, 0, 0, /* DVI_PUT1 .. DVI_PUT4 */ X 9, /* DVI_PUTRULE */ X 1, /* DVI_NOP */ X 0, /* DVI_BOP */ X 0, /* DVI_EOP */ X 1, /* DVI_PUSH */ X 1, /* DVI_POP */ X 2, 3, 4, 5, /* DVI_RIGHT1 .. DVI_RIGHT4 */ X 1, /* DVI_W0 */ X 2, 3, 4, 5, /* DVI_W1 .. DVI_W4 */ X 1, /* DVI_X0 */ X 2, 3, 4, 5, /* DVI_X1 .. DVI_X4 */ X 2, 3, 4, 5, /* DVI_DOWN1 .. DVI_DOWN4 */ X 1, /* DVI_Y0 */ X 2, 3, 4, 5, /* DVI_Y1 .. DVI_Y4 */ X 1, /* DVI_Z0 */ X 2, 3, 4, 5, /* DVI_Z1 .. DVI_Z4 */ X 0, /* DVI_FNTNUM0 (171) */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 172 .. 179 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 180 .. 187 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 188 .. 195 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 196 .. 203 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 204 .. 211 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 212 .. 219 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 220 .. 227 */ X 0, 0, 0, 0, 0, 0, 0, /* 228 .. 234 */ X 0, 0, 0, 0, /* DVI_FNT1 .. DVI_FNT4 */ X 0, 0, 0, 0, /* DVI_XXX1 .. DVI_XXX4 */ X 0, 0, 0, 0, /* DVI_FNTDEF1 .. DVI_FNTDEF4 */ X 0, /* DVI_PRE */ X 0, /* DVI_POST */ X 0, /* DVI_POSTPOST */ X 0, 0, 0, 0, 0, 0, /* 250 .. 255 */ X}; X X/* X * Here we read the input DVI file and write relevant pages to the X * output DVI file. We also keep track of font changes, handle font X * definitions, and perform some other housekeeping. X */ XHandleDVIFile() X{ X register int c, l; X register i32 p; X register int CurrentFontOK = 0; X X /* Only way out is via "return" statement */ X for (;;) { X c = getc(inf); /* getc() returns unsigned values */ X if (DVI_IsChar(c)) { X /* X * Copy chars, note font usage, but ignore if X * page is not interesting. X */ X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putc(c, outf); X CurrentPosition++; X continue; X } X if (DVI_IsFont(c)) { /* note font change */ X CurrentFontIndex = c - DVI_FNTNUM0; X CurrentFontOK = 0; X continue; X } X if ((l = (oplen - 128)[c]) != 0) { /* simple copy */ X if (!UseThisPage) { X while (--l > 0) X (void) getc(inf); X continue; X } X CurrentPosition += l; X putc(c, outf); X while (--l > 0) { X c = getc(inf); X putc(c, outf); X } X if (ferror(outf)) X error(1, errno, writeerr); X continue; X } X if ((l = DVI_OpLen(c)) != 0) { X /* X * Handle other generics. X * N.B.: there should only be unsigned parameters X * here (save SGN4), for commands with negative X * parameters have been taken care of above. X */ X switch (l) { X X case DPL_UNS1: X p = getc(inf); X break; X X case DPL_UNS2: X fGetWord(inf, p); X break; X X case DPL_UNS3: X fGet3Byte(inf, p); X break; X X case DPL_SGN4: X fGetLong(inf, p); X break; X X default: X panic("HandleDVIFile l=%d", l); X } X X /* X * Now that we have the parameter, perform the X * command. X */ X switch (DVI_DT(c)) { X X case DT_SET: X case DT_PUT: X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putc(c, outf); X switch (l) { X X case DPL_UNS1: X putc(p, outf); X CurrentPosition += 2; X continue; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X continue; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X continue; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X continue; X } X X case DT_FNT: X CurrentFontIndex = p; X CurrentFontOK = 0; X continue; X X case DT_XXX: X HandleSpecial(c, l, p); X continue; X X case DT_FNTDEF: X HandleFontDef(p); X continue; X X default: X panic("HandleDVIFile DVI_DT(%d)=%d", X c, DVI_DT(c)); X } X continue; X } X X switch (c) { /* handle the few remaining cases */ X X case DVI_BOP: X BeginPage(); X CurrentFontOK = 0; X break; X X case DVI_EOP: X EndPage(); X break; X X case DVI_PRE: X GripeUnexpectedOp("PRE"); X /* NOTREACHED */ X X case DVI_POST: X return; X X case DVI_POSTPOST: X GripeUnexpectedOp("POSTPOST"); X /* NOTREACHED */ X X default: X GripeUndefinedOp(c); X /* NOTREACHED */ X } X } X} END_OF_dviselect.c.orig if test 22164 -ne `wc -c <dviselect.c.orig`; then echo shar: \"dviselect.c.orig\" unpacked with wrong size! fi chmod +x dviselect.c.orig # end of overwriting check fi if test ! -d h ; then echo shar: Creating directory \"h\" mkdir h fi if test ! -d lib ; then echo shar: Creating directory \"lib\" mkdir lib fi echo shar: End of archive 1 \(of 6\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 6)." # Contents: h/Makefile h/README h/conv.h h/convstruct.h h/dvi.h # h/dviclass.h h/dvicodes.h h/dvistruct.h h/fio.h h/font.h # h/gfclass.h h/gfcodes.h h/imPcodes.h h/imagen.h h/num.h # h/postamble.h h/search.h h/tfm.h h/types.h # Wrapped by montnaro@sprite on Sat Nov 11 17:13:28 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f h/Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/Makefile\" else echo shar: Extracting \"h/Makefile\" \(271 characters\) sed "s/^X//" >h/Makefile <<'END_OF_h/Makefile' XHDR =arith.h binding.h box.h conv.h dvi.h dviclass.h dvicodes.h \ X error.h fio.h font.h gfclass.h gfcodes.h imPcodes.h imagen.h \ X io.h num.h postamble.h search.h str.h tfm.h types.h verser.h X Xgoal: X @echo Nothing to make here X X$(HDR): X co -q $@ X Xhdr: $(HDR) X @echo Done END_OF_h/Makefile if test 271 -ne `wc -c <h/Makefile`; then echo shar: \"h/Makefile\" unpacked with wrong size! fi chmod +x h/Makefile # end of overwriting check fi if test -f h/README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/README\" else echo shar: Extracting \"h/README\" \(36 characters\) sed "s/^X//" >h/README <<'END_OF_h/README' XThis directory is for header files. END_OF_h/README if test 36 -ne `wc -c <h/README`; then echo shar: \"h/README\" unpacked with wrong size! fi chmod +x h/README # end of overwriting check fi if test -f h/conv.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/conv.h\" else echo shar: Extracting \"h/conv.h\" \(3295 characters\) sed "s/^X//" >h/conv.h <<'END_OF_h/conv.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Conversions. Conversion factors convert between values in scaled X * points and values in device-dependenent units. The results of all X * conversions are rounded to the nearest integral value, of type (i32). X */ X X/* X * This is now done using `double' values, but may be changed to X * fixed-point or some other `fast' method, as long as the results X * are consistent and reasonably accurate. The structure `conversion' X * holds the conversion-method-dependent quantities; the macros X * fromSP and toSP apply the conversion to a value. (Note that X * fromSP and toSP need not be macros, but should be fast.) X * X * SetConversion sets the (single, global) conversion factor. X * If a driver needs special conversions, there is another routine, X * CSetConversion that sets a specific conversion, and cfromSP and X * ctoSP to apply these. X * X * IS USING DOTS PER INCH SUFFICIENT? (Pixels per point might be better.) X * X * Note that it is necessary to set the global conversion factor before X * using any fonts. X */ X Xtypedef struct conversion { X double c_fromsp; /* multiplier to convert from scaled points */ X double c_tosp; /* multiplier to convert to scaled points: X could divide by c_fromsp, but this should X be faster and more accurate */ X double c_mag; /* the magnification this conversion X represents; mainly for GetFont() */ X double c_dpi; /* dpi (should be pixels per point?) */ X} Conv; X X/* X * In order to do this, we need to round properly. The compilers I X * have tend to generate very poor code for this. The following is X * intended to help them out. Smarter compilers can do better, but X * if they are smart enough, they will realise that the variables X * here are not used anywhere else, and discard them. (For a compiler X * to do this given separate compliation, `static' is a must.) X */ X X#ifdef lint /* or a smart compiler */ X X#define ROUND(f) ((i32) ((f) < 0.0 ? (f) - 0.5 : (f) + 0.5)) X#define CEIL(f) ((double) (i32) (f) < (f) ? (i32) (f) + 1 : (i32) (f)) X X#else X Xstatic double _half = 0.5; Xstatic double _zero = 0.0; Xstatic double _d; X X#define ROUND(f) ((i32) (_d = (f), _d < _zero ? _d - _half : _d + _half)) X X#ifdef NEGATIVE_FLOAT_ROUNDS_TO_NEGATIVE_INFINITY X X#define CEIL(f) (-(i32) -(f)) X X#else /* we will assume that floating to integer truncates */ X Xstatic i32 _i; X X#define CEIL(f) (_i = _d = (f), _i < _d ? _i + 1 : _i) X X#endif /* round towards negative infinity */ X X#endif /* lint */ X X#define SetConversion(dpi, usermag, num, denom, dvimag) \ X CSetConversion(&Conversion, dpi, usermag, num, denom, dvimag) X X#define cfromSP(c, v) ROUND((c)->c_fromsp * (v)) X#define ctoSP(c, v) ROUND((c)->c_tosp * (v)) X X#define fromSP(v) cfromSP(&Conversion, v) X#define toSP(v) ctoSP(&Conversion, v) X X/* X * Conversions for rules are a bit different: we must round up, rather X * than off. ConvRule applies the global conversion value for a rule X * value (height or width); CConvRule applies a specific conversion. X */ X X#define CConvRule(c, v) CEIL((c)->c_fromsp * (v)) X#define ConvRule(v) CConvRule(&Conversion, v) X Xvoid CSetConversion(); END_OF_h/conv.h if test 3295 -ne `wc -c <h/conv.h`; then echo shar: \"h/conv.h\" unpacked with wrong size! fi chmod +x h/conv.h # end of overwriting check fi if test -f h/convstruct.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/convstruct.h\" else echo shar: Extracting \"h/convstruct.h\" \(400 characters\) sed "s/^X//" >h/convstruct.h <<'END_OF_h/convstruct.h' Xtypedef struct conversion { X double c_fromsp; /* multiplier to convert from scaled points */ X double c_tosp; /* multiplier to convert to scaled points: X could divide by c_fromsp, but this should X be faster and more accurate */ X double c_mag; /* the magnification this conversion X represents; mainly for GetFont() */ X double c_dpi; /* dpi (should be pixels per point?) */ X} Conv; END_OF_h/convstruct.h if test 400 -ne `wc -c <h/convstruct.h`; then echo shar: \"h/convstruct.h\" unpacked with wrong size! fi chmod +x h/convstruct.h # end of overwriting check fi if test -f h/dvi.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/dvi.h\" else echo shar: Extracting \"h/dvi.h\" \(876 characters\) sed "s/^X//" >h/dvi.h <<'END_OF_h/dvi.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* DVI file info */ X X/* X * Units of distance are stored in scaled points, but we can convert to X * units of 10^-7 meters by multiplying by the numbers in the preamble. X */ X X/* the structure of the stack used to hold the values (h,v,w,x,y,z) */ X Xtypedef struct dvi_stack { X i32 h; /* the saved h */ X i32 v; /* the saved v */ X i32 w; /* etc */ X i32 x; X i32 y; X i32 z; X} DviStack; X Xextern DviStack dvi_current; /* the current values of h, v, etc */ Xextern int dvi_f; /* the current font */ X X#define dvi_h dvi_current.h X#define dvi_v dvi_current.v X#define dvi_w dvi_current.w X#define dvi_x dvi_current.x X#define dvi_y dvi_current.y X#define dvi_z dvi_current.z END_OF_h/dvi.h if test 876 -ne `wc -c <h/dvi.h`; then echo shar: \"h/dvi.h\" unpacked with wrong size! fi chmod +x h/dvi.h # end of overwriting check fi if test -f h/dviclass.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/dviclass.h\" else echo shar: Extracting \"h/dviclass.h\" \(1662 characters\) sed "s/^X//" >h/dviclass.h <<'END_OF_h/dviclass.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Macros to convert DVI opcodes to (hopefully) simpler values. X */ X X/* X * Large range types. X */ X#define DVI_IsChar(code) ((code) < 128) X#define DVI_IsFont(code) ((code) >= 171 && (code) < 235) X X/* X * Symbolic names for generic types (for things with parameters). X * These are obtained via the macro DVI_DT(int c), where 0 <= c <= 255. X */ X#define DT_CHAR 0 X#define DT_SET 1 X#define DT_SETRULE 2 X#define DT_PUT 3 X#define DT_PUTRULE 4 X#define DT_NOP 5 X#define DT_BOP 6 X#define DT_EOP 7 X#define DT_PUSH 8 X#define DT_POP 9 X#define DT_RIGHT 10 X#define DT_W0 11 X#define DT_W 12 X#define DT_X0 13 X#define DT_X 14 X#define DT_DOWN 15 X#define DT_Y0 16 X#define DT_Y 17 X#define DT_Z0 18 X#define DT_Z 19 X#define DT_FNTNUM 20 X#define DT_FNT 21 X#define DT_XXX 22 X#define DT_FNTDEF 23 X#define DT_PRE 24 X#define DT_POST 25 X#define DT_POSTPOST 26 X#define DT_UNDEF 27 X X/* X * Symbolic names for parameter lengths, obtained via the macro X * DVL_OpLen(int c). X * X * N.B.: older drivers may assume that 0 => none, 1-4 => 1-4 bytes X * and 5-7 => unsigned version of 1-4---so DO NOT change these values! X */ X#define DPL_NONE 0 X#define DPL_SGN1 1 X#define DPL_SGN2 2 X#define DPL_SGN3 3 X#define DPL_SGN4 4 X#define DPL_UNS1 5 X#define DPL_UNS2 6 X#define DPL_UNS3 7 X/* there are no unsigned four byte parameters */ X X#define DVI_OpLen(code) (dvi_oplen[code]) X#define DVI_DT(code) (dvi_dt[code]) Xextern char dvi_oplen[]; Xextern char dvi_dt[]; END_OF_h/dviclass.h if test 1662 -ne `wc -c <h/dviclass.h`; then echo shar: \"h/dviclass.h\" unpacked with wrong size! fi chmod +x h/dviclass.h # end of overwriting check fi if test -f h/dvicodes.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/dvicodes.h\" else echo shar: Extracting \"h/dvicodes.h\" \(2554 characters\) sed "s/^X//" >h/dvicodes.h <<'END_OF_h/dvicodes.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* DVI opcodes */ X X#define DVI_VERSION 2 /* version number that should appear in X pre- and post-ambles */ X X#define DVI_SET1 128 /* set character, 1 byte param */ X#define DVI_SET2 129 /* set character, 2 byte param */ X#define DVI_SET3 130 /* set character, 3 byte param */ X#define DVI_SET4 131 /* set character, 4 byte param */ X#define DVI_SETRULE 132 /* set a rule */ X#define DVI_PUT1 133 /* put char, don't move right */ X#define DVI_PUT2 134 /* put char, 2 byte */ X#define DVI_PUT3 135 /* etc */ X#define DVI_PUT4 136 X#define DVI_PUTRULE 137 /* put rule, don't move right */ X#define DVI_NOP 138 /* no-op */ X#define DVI_BOP 139 /* begin page */ X#define DVI_EOP 140 /* end page */ X#define DVI_PUSH 141 /* push h,v,w,x,y,z */ X#define DVI_POP 142 /* pop h,v,w,x,y,z */ X#define DVI_RIGHT1 143 /* move right, 1 byte signed param */ X#define DVI_RIGHT2 144 /* move right, 2 byte signed param */ X#define DVI_RIGHT3 145 /* etc */ X#define DVI_RIGHT4 146 X#define DVI_W0 147 /* h += w */ X#define DVI_W1 148 /* w = 1 byte signed param, h += w */ X#define DVI_W2 149 /* w = 2 byte etc, h += w */ X#define DVI_W3 150 X#define DVI_W4 151 X#define DVI_X0 152 /* like DVI_W0 but for x */ X#define DVI_X1 153 /* etc */ X#define DVI_X2 154 X#define DVI_X3 155 X#define DVI_X4 156 X#define DVI_DOWN1 157 /* v += 1 byte signed param */ X#define DVI_DOWN2 158 /* v += 2 byte signed param */ X#define DVI_DOWN3 159 /* etc */ X#define DVI_DOWN4 160 X#define DVI_Y0 161 /* y = 1 byte signed param, v += y */ X#define DVI_Y1 162 /* etc */ X#define DVI_Y2 163 X#define DVI_Y3 164 X#define DVI_Y4 165 X#define DVI_Z0 166 /* z = 1 byte signed param, v += z */ X#define DVI_Z1 167 /* etc */ X#define DVI_Z2 168 X#define DVI_Z3 169 X#define DVI_Z4 170 X#define DVI_FNTNUM0 171 X X#define DVI_FNT1 235 /* select font, 1 byte param */ X#define DVI_FNT2 236 /* etc */ X#define DVI_FNT3 237 X#define DVI_FNT4 238 X#define DVI_XXX1 239 /* for \special: if length < 256 */ X#define DVI_XXX2 240 /* etc */ X#define DVI_XXX3 241 X#define DVI_XXX4 242 X#define DVI_FNTDEF1 243 /* Define font, 1 byte param (0 to 63) */ X#define DVI_FNTDEF2 244 /* etc */ X#define DVI_FNTDEF3 245 X#define DVI_FNTDEF4 246 X#define DVI_PRE 247 /* preamble */ X#define DVI_POST 248 /* postamble */ X#define DVI_POSTPOST 249 /* end of postamble */ X#define DVI_FILLER 223 /* filler bytes at end of dvi file */ END_OF_h/dvicodes.h if test 2554 -ne `wc -c <h/dvicodes.h`; then echo shar: \"h/dvicodes.h\" unpacked with wrong size! fi chmod +x h/dvicodes.h # end of overwriting check fi if test -f h/dvistruct.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/dvistruct.h\" else echo shar: Extracting \"h/dvistruct.h\" \(595 characters\) sed "s/^X//" >h/dvistruct.h <<'END_OF_h/dvistruct.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* DVI file info */ X X/* X * Units of distance are stored in scaled points, but we can convert to X * units of 10^-7 meters by multiplying by the numbers in the preamble. X */ X X/* the structure of the stack used to hold the values (h,v,w,x,y,z) */ Xtypedef struct dvi_stack { X i32 h; /* the saved h */ X i32 v; /* the saved v */ X i32 w; /* etc */ X i32 x; X i32 y; X i32 z; X} DviStack; END_OF_h/dvistruct.h if test 595 -ne `wc -c <h/dvistruct.h`; then echo shar: \"h/dvistruct.h\" unpacked with wrong size! fi chmod +x h/dvistruct.h # end of overwriting check fi if test -f h/fio.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/fio.h\" else echo shar: Extracting \"h/fio.h\" \(1456 characters\) sed "s/^X//" >h/fio.h <<'END_OF_h/fio.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * File I/O: numbers. X * X * We deal in fixed format numbers and (FILE *)s here. X * For pointer I/O, see pio.h. X * X * N.B.: These do the `wrong thing' at EOF. It is imperative X * that the caller add appropriate `if (feof(fp))' statements. X */ X X/* X * Get one unsigned byte. Note that this is a proper expression. X * The reset have more limited contexts, and are therefore OddLy X * CapItaliseD. X */ X#define fgetbyte(fp) (getc(fp)) X X/* X * Get a two-byte unsigned integer, a three-byte unsigned integer, X * or a four-byte signed integer. X */ X#define fGetWord(fp, r) ((r) = getc(fp) << 8, (r) |= getc(fp)) X#define fGet3Byte(fp,r) ((r) = getc(fp) << 16, (r) |= getc(fp) << 8, \ X (r) |= getc(fp)) X#define fGetLong(fp, r) ((r) = getc(fp) << 24, (r) |= getc(fp) << 16, \ X (r) |= getc(fp) << 8, (r) |= getc(fp)) X X/* X * Fast I/O write (and regular write) macros. X */ X#define putbyte(fp, r) (putc((r), fp)) X X#define PutWord(fp, r) (putc((r) >> 8, fp), putc((r), fp)) X#define Put3Byte(fp, r) (putc((r) >> 16, fp), putc((r) >> 8, fp), \ X putc((r), fp)) X#define PutLong(fp, r) (putc((r) >> 24, fp), putc((r) >> 16, fp), \ X putc((r) >> 8, fp), putc((r), fp)) X X/* X * Function types X */ Xi32 GetByte(), GetWord(), Get3Byte(), GetLong(); END_OF_h/fio.h if test 1456 -ne `wc -c <h/fio.h`; then echo shar: \"h/fio.h\" unpacked with wrong size! fi chmod +x h/fio.h # end of overwriting check fi if test -f h/font.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/font.h\" else echo shar: Extracting \"h/font.h\" \(7100 characters\) sed "s/^X//" >h/font.h <<'END_OF_h/font.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Font file information, readers, etc. X */ X X#ifndef _CTEX_TYPES_ X#include "types.h" X#endif X X/* X * First, font independent information: per glyph info, and per font X * info. X */ Xstruct glyph { X short g_flags; /* see below */ X /* X * The following cannot be used with GetRasterlessFont X */ X short g_rotation; /* see below */ X char *g_raster; /* raster, if known */ X /* X * These, however, do come with rasterless fonts, X * even though they relate only to the raster. X */ X i32 g_height; /* height of bounding box */ X i32 g_width; /* width of bounding box */ X i32 g_yorigin; /* y origin (>= 0 -> within box) */ X i32 g_xorigin; /* x origin (>= 0 -> within box) */ X /* X * This of course comes with every font. X */ X i32 g_rawtfmwidth; /* the tfmwidth as read from the file */ X i32 g_tfmwidth; /* width in scaled points (not FIXes!) */ X i32 g_xescapement; /* x escapement (`chardx') */ X i32 g_yescapement; /* y escapement (`chardy') */ X /* X * This is provided purely for DVI to device conversion programs. X */ X int g_pixwidth; /* width in pixels */ X /* X * Mainly for internal use, index is the glyph index within the X * font. That is, f->f_gly[i]->g_index == i. X */ X int g_index; /* character index */ X /* X * g_details and g_integer are purely for the font reading X * subroutines to use however they will. g_next makes lists X * of glyphs while the glyphs are free. X */ X union { /* various options */ X char *g_details; /* details: arbitrary */ X i32 g_integer; /* 32 bit integer */ X struct glyph *g_next; /* linked list */ X } g_un; X}; X X/* X * Glyph flags. X */ X#define GF_VALID 0x0001 /* glyph is `real' */ X#define GF_USR0 0x0100 /* reserved to user code */ X#define GF_USR1 0x0200 /* reserved to user code */ X#define GF_USR2 0x0400 /* reserved to user code */ X#define GF_USR3 0x0800 /* reserved to user code */ X X/* X * Rotations are in quarter-pi steps, counterclockwise of course. X * This order must be maintained; see rotate.c. X */ X#define ROT_NORM 0 /* no rotation: `normal' position */ X#define ROT_LEFT 1 /* 1/4 turn counterclockwise */ X#define ROT_DOWN 2 /* 1/2 turn, i.e., upside-down */ X#define ROT_RIGHT 3 /* 3/4 turn ccw, or 1/4 turn cw */ X Xstruct font { X int f_flags; /* see below */ X struct fontops *f_ops; /* operations */ X /* X * f_details is provided for font reading subroutines. X * It is intended to be cast to a pointer to a structure X * that is allocated by those routines, and used to keep X * track of whatever information those routines need to X * determine glyph boxes and (if asked for) rasters. X */ X char *f_details; /* type dependent stuff */ X /* X * f_path is the full pathname to the font file, filled in X * by GetFont and GetRasterlessFont. Note that since we X * hold on to the path until the font is freed, it should be X * possible to cache glyph accesses on memory-poor machines. X */ X char *f_path; /* font file pathname */ X /* X * f_dvimag and f_dvidsz are the magnification and design size X * values from the DVI file. f_font and f_scaled correspond to X * TeX's idea of the proper name for the font (e.g., `cmr10', X * `cmbx10 scaled 1440'). (Note that f_scaled is just the X * ratio of f_dvimag and f_dvidsz; you could save a bit of memory X * by eliminating it and altering the routine Font_TeXName()). X * f_checksum should be set by the font reading routines to X * the font checksum. If the value is nonzero, it will be X * compared to the checksum in the DVI file. X */ X i32 f_dvimag; /* magnification from DVI file */ X i32 f_dvidsz; /* design size from DVI file */ X char *f_font; /* TeX's name for the font */ X int f_scaled; /* the ratio of dvimag to dvidsz, x1000 */ X i32 f_design_size; X i32 f_checksum; /* font checksum, or 0 */ X i32 f_hppp; /* horizontal pixels per point */ X i32 f_vppp; /* vertical pixels per point */ X /* X * f_lowch and f_highch bound the region in which f_gly X * indicies are valid. Specificially, f_gly[i] may be X * read or written if and only if i is in the half-open X * interval [f_lowch..f_highch). f_gly is an array of X * pointers to glyph structures. The structures themselves X * are not allocated until requested. X * X * f_glybase is the actual return from malloc(), since it X * is theoretically possible for f_gly-f_lowch to become X * NULL. X */ X int f_lowch; /* first character */ X int f_highch; /* last character, plus 1 */ X struct glyph **f_gly; /* glyphs */ X struct glyph **f_glybase; X}; X X/* X * Font flags. X */ X#define FF_RASTERS 0x0001 /* font has rasters */ X#define FF_USR0 0x0100 /* reserved to user code */ X#define FF_USR1 0x0200 /* reserved to user code */ X#define FF_USR2 0x0400 /* reserved to user code */ X#define FF_USR3 0x0800 /* reserved to user code */ X X/* X * Operations on fonts. X * X * The `fo_dpitomag' field is used as a multiplier for a desired X * resolution in dots per inch. The result of the multiplication X * is converted to a font name by multipying by 1000.0 and rounding. X * The idea is that PXL files will have a multiplier of 5.0, and X * others will have a multiplier of 1.0. This suffices for the X * present, at any rate; in the future, this field may be replaced X * with something more general. X * X * N.B.: more operations may be added as they are discovered to be X * useful. X */ Xstruct fontops { X char *fo_name; /* name, e.g., "gf" */ X double fo_dpitomag; /* multiplier */ X int (*fo_read)(); /* open and read the font itself */ X int (*fo_getgly)(); /* obtain specified glyphs (range) */ X#ifdef notdef X int (*fo_freegly)(); /* release specified glyphs */ X#endif X int (*fo_rasterise)(); /* rasterise specified glyphs */ X int (*fo_freefont)(); /* discard font (free details) */ X struct fontops *fo_next; /* purely for font.c */ X}; X X/* X * Return a pointer to the glyph information for character `c' in X * font `f'. X */ X#define GLYPH(f, c) \ X ((c) < (f)->f_lowch || (c) >= (f)->f_highch ? (struct glyph *) 0 : \ X ((f)->f_gly[c] ? (f)->f_gly[c] : GetGlyph(f, c))) X X/* X * True iff glyph `g' is valid. Useful for checking return values X * from GLYPH(). X */ X#define GVALID(g) ((g) && ((g)->g_flags & GF_VALID)) X X/* X * True iff glyph g has a raster. X */ X#define HASRASTER(g) ((g)->g_height || (g)->g_width) X X/* X * Return a pointer to the raster information for glyph `g' in font X * `f' at rotation `r'. X */ X#define RASTER(g, f, r) ((g)->g_rotation == (r) && (g)->g_raster ? \ X (g)->g_raster : GetRaster(g, f, r)) X X/* X * Function types. X */ Xstruct font *GetFont(), *GetRasterlessFont(); Xstruct glyph *GetGlyph(); Xchar *GetRaster(); Xvoid FreeFont(); Xvoid FreeGlyph(); Xvoid FreeRaster(); Xchar *Font_TeXName(); Xdouble DMagFactor(); /* from magfactor.c */ X X/* X * Normally from stdio.h X */ X#ifndef NULL X#define NULL 0 X#endif X X/* X * The following environment variable overrides the default font X * configuration file. That default is used when fontinit() is not X * called, or is passed a null pointer. X */ X#define CONFENV "TEXFONTDESC" END_OF_h/font.h if test 7100 -ne `wc -c <h/font.h`; then echo shar: \"h/font.h\" unpacked with wrong size! fi chmod +x h/font.h # end of overwriting check fi if test -f h/gfclass.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/gfclass.h\" else echo shar: Extracting \"h/gfclass.h\" \(1730 characters\) sed "s/^X//" >h/gfclass.h <<'END_OF_h/gfclass.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * GF classification codes X */ X X/* X * Predicate for simple paint commands. This is presumably the most X * common GF operation; it may be profitable to check for this before X * switching out on the command type. X */ X#define GF_IsPaint(c) ((c) < 64) X X/* X * Symbolic names for command `types', as returned by the macro X * GT_TYPE(int c). X */ X#define GT_PAINT0 0 /* paint without parameter */ X#define GT_PAINT 1 /* paint with parameter */ X#define GT_BOC 2 /* long BOC */ X#define GT_BOC1 3 /* short BOC */ X#define GT_EOC 4 /* EOC */ X#define GT_SKIP0 5 /* parameterless SKIP */ X#define GT_SKIP 6 /* parmeterised SKIP */ X#define GT_NEW_ROW 7 /* NEW_ROW_n */ X#define GT_XXX 8 /* XXXn */ X#define GT_YYY 9 /* YYY */ X#define GT_NOP 10 /* no op */ X#define GT_CHAR_LOC 11 /* CHAR_LOC */ X#define GT_CHAR_LOC0 12 /* abbreviated CHAR_LOC */ X#define GT_PRE 13 X#define GT_POST 14 X#define GT_POSTPOST 15 X#define GT_UNDEF 16 X X/* X * Symbolic names for parameter lengths, obtained via the macro X * GT_OpLen(int c). X */ X#define GPL_NONE 0 /* no parameter, or too complex */ X#define GPL_UNS1 1 /* one one-byte parameter in 0..255 */ X#define GPL_UNS2 2 /* one two-byte parameter in 0..65535 */ X#define GPL_UNS3 3 /* one three-byte parameter in 0..16777215 */ X#define GPL_SGN4 4 /* one four-byte signed parameter */ X/* X * there are no unsigned four byte parameters, and no shorter signed X * parameters X */ X X#define GF_OpLen(code) (gf_oplen[code]) X#define GF_TYPE(code) (gf_gt[code]) Xextern char gf_oplen[]; Xextern char gf_gt[]; END_OF_h/gfclass.h if test 1730 -ne `wc -c <h/gfclass.h`; then echo shar: \"h/gfclass.h\" unpacked with wrong size! fi chmod +x h/gfclass.h # end of overwriting check fi if test -f h/gfcodes.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/gfcodes.h\" else echo shar: Extracting \"h/gfcodes.h\" \(1732 characters\) sed "s/^X//" >h/gfcodes.h <<'END_OF_h/gfcodes.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * GF (generic font) opcodes. X */ X X#define GF_PAINT_0 0 /* paint with `d' = 0 */ X /* ... through PAINT_63, d = 63 */ X#define GF_PAINT1 64 /* paint, with a one-byte parameter */ X#define GF_PAINT2 65 /* paint, with a two-byte parameter */ X#define GF_PAINT3 66 /* paint, with a three-byte parameter */ X#define GF_BOC 67 /* beginning of character */ X#define GF_BOC1 68 /* compressed form of BOC */ X#define GF_EOC 69 /* end of character */ X#define GF_SKIP0 70 /* finish this row, begin next with white */ X#define GF_SKIP1 71 /* finish row, one byte parameter */ X#define GF_SKIP2 72 X#define GF_SKIP3 73 X#define GF_NEW_ROW_0 74 /* begin a new row, ready to blacken */ X#define GF_NEW_ROW_1 75 /* begin a new row, but one col. from left */ X /* through GF_NEW_ROW_164 */ X#define GF_XXX1 239 /* special (interpreter dependent) command */ X#define GF_XXX2 240 /* like XXX1, but two byte length parameter */ X#define GF_XXX3 241 X#define GF_XXX4 242 X#define GF_YYY 243 /* takes four byte parameter, otherwise nop */ X /* (generated by METAFONT for numspecial) */ X#define GF_NOP 244 /* no op */ X#define GF_CHAR_LOC 245 /* character locator */ X#define GF_CHAR_LOC0 246 /* abbreviated form of CHAR_LOC */ X#define GF_PRE 247 /* introduces preamble */ X#define GF_POST 248 /* introduces postamble */ X#define GF_POSTPOST 249 /* marks end of postamble */ X X /* codes 250 through 255 are undefined */ X X#define GF_ID 131 /* identifies this revision of GF */ X X#define GF_FILLER 223 /* filler bytes at end of GF file */ END_OF_h/gfcodes.h if test 1732 -ne `wc -c <h/gfcodes.h`; then echo shar: \"h/gfcodes.h\" unpacked with wrong size! fi chmod +x h/gfcodes.h # end of overwriting check fi if test -f h/imPcodes.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/imPcodes.h\" else echo shar: Extracting \"h/imPcodes.h\" \(2346 characters\) sed "s/^X//" >h/imPcodes.h <<'END_OF_h/imPcodes.h' X/* imPRESS command codes */ X X#define imP_SP 128 /* advance one space */ X#define imP_SP1 129 /* advance one space plus 1 pixel */ X X#define imP_OLD_MMOVE 130 X#define imP_Forw 131 /* one pixel forward */ X#define imP_Backw 132 /* one pixel backward */ X#define imP_MMove 133 /* move in main advance dir. */ X#define imP_SMove 134 /* move in secondary advance dir. */ X#define imP_SetHAbs 135 /* set absolute H pos */ X#define imP_SetHRel 136 /* set relative H pos */ X#define imP_SetVAbs 137 /* set absolute V pos */ X#define imP_SetVRel 138 /* set relative V pos */ X X/* X * rephrase for imagen1-special.c X */ X#define imP_SET_ABS_H 135 /* set absolute H pos */ X#define imP_SET_REL_H 136 /* set relative H pos */ X#define imP_SET_ABS_V 137 /* set absolute V pos */ X#define imP_SET_REL_V 138 /* set relative V pos */ X X#define CIRC_ARC 150 X#define ELLIPSE_ARC 151 X#define CIRC_SEGM 160 X X#define imSRULE 192 X#define imP_Rule 193 /* print a rule */ X X#define imP_SET_HPOS 195 X#define imP_SET_VPOS 196 X#define imP_CRLF 197 /* move to begin. of line */ X#define imP_SGLY 198 X X#define imP_DefGlyph 199 /* define a glyph */ X X#define imP_BGLY 199 /* for imagen1-special.c */ X X#define imP_DelGlyph 200 /* mark a glyph for deletion */ X#define imP_DELC 201 X#define imP_DELF 202 X X#define imP_SetHVSystem 205 /* set the H/V coordinate system */ X#define imP_SET_HV_SYSTEM 205 /* for imagen1-special.c */ X X#define imP_SetAdvDirs 206 /* set the advance directions */ X#define imP_SetFamily 207 /* use this particular family */ X#define imP_SetILSpace 208 /* set the interline spacing */ X#define imP_SetBOL 209 /* define the beginning of line */ X#define imP_SetSP 210 /* define the space between words */ X X#define imP_CreateFam 211 /* define a family table */ X#define imP_PUSH 211 /* for imagen1-special.c */ X#define imP_POP 212 X X#define imP_Page 213 /* go to (0,0) */ X#define imP_SET_PUSH_MASK 214 X X#define imP_EndPage 219 /* print the current page */ X X#define imP_CREATE_FAMILY_TABLE 221 X#define imP_CREATE_MAP 222 X X#define SET_PUM 225 X X#define imP_CREATE_PATH 230 X#define imP_SET_TEXTURE 231 X#define imP_SET_PEN 232 X#define imP_FILL_PATH 233 X#define imP_DRAW_PATH 234 X#define imP_BITMAP 235 X#define imP_SET_MAGN 236 X X X#define imP_ForceDel 240 /* force glyph deletion */ X X#define imP_DEFINE_MACRO 242 X#define imP_EXEC_MACRO 243 X#define imP_EOF 255 /* end of document */ END_OF_h/imPcodes.h if test 2346 -ne `wc -c <h/imPcodes.h`; then echo shar: \"h/imPcodes.h\" unpacked with wrong size! fi chmod +x h/imPcodes.h # end of overwriting check fi if test -f h/imagen.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/imagen.h\" else echo shar: Extracting \"h/imagen.h\" \(777 characters\) sed "s/^X//" >h/imagen.h <<'END_OF_h/imagen.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* imagen globals */ X X/* Accounting: */ X#ifndef ACCOUNT_FILE X/* X#define ACCOUNT_FILE "/usr/adm/imagen_acct"/* if defined, the name of the X imagen page accounting file */ X#endif ACCOUNT_FILE X X#define MaxImFamily 128 /* hardware limitation on font family index */ X#define DefaultDPI 300 /* 300 for Imagen 8/300, 240 for Imprint-10 */ X X#define DefaultMaxDrift 3 /* default value for MaxDrift */ X X/* Default margins, in dots */ X/* CRUFT ALERT: depending on DPI variable */ X#define DefaultTopMargin (DPI) /* 1" margins */ X#define DefaultLeftMargin (DPI) END_OF_h/imagen.h if test 777 -ne `wc -c <h/imagen.h`; then echo shar: \"h/imagen.h\" unpacked with wrong size! fi chmod +x h/imagen.h # end of overwriting check fi if test -f h/num.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/num.h\" else echo shar: Extracting \"h/num.h\" \(1123 characters\) sed "s/^X//" >h/num.h <<'END_OF_h/num.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Pointer I/O: numbers. X * X * We deal in fixed format numbers and pointers here. X * For file I/O, see fio.h. X */ X X/* X * Get one unsigned byte. Note that this is a proper expression. X * The rest have more limited contexts, and are therefore OddLy X * CapItaliseD. X */ X#define pgetbyte(p) UnSign8(*(p)++) X X/* X * Get a two-byte unsigned integer, a three-byte unsigned integer, X * or a four-byte signed integer. X */ X#define pGetWord(p, r) ((r) = UnSign8(*(p)++) << 8, \ X (r) |= UnSign8(*(p)++)) X#define pGet3Byte(p,r) ((r) = UnSign8(*(p)++) << 16, \ X (r) |= UnSign8(*(p)++) << 8, \ X (r) |= UnSign8(*(p)++)) X#define pGetLong(p, r) ((r) = UnSign8(*(p)++) << 24, \ X (r) |= UnSign8(*(p)++) << 16, \ X (r) |= UnSign8(*(p)++) << 8, \ X (r) |= UnSign8(*(p)++)) X X/* X * ADD pputbyte, pPutWord, pPut3Byte, pPutLong HERE IF THEY PROVE X * USEFUL. (But then must consider changing PutWord &c in fio.h.) X */ END_OF_h/num.h if test 1123 -ne `wc -c <h/num.h`; then echo shar: \"h/num.h\" unpacked with wrong size! fi chmod +x h/num.h # end of overwriting check fi if test -f h/postamble.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/postamble.h\" else echo shar: Extracting \"h/postamble.h\" \(1895 characters\) sed "s/^X//" >h/postamble.h <<'END_OF_h/postamble.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* Definitions for ScanPostAmble */ X X/* X * ScanPostAmble reads the postamble of a DVI file from the (stdio) X * file specified in its first argument. It is handed two pointers to X * functions. The first (ScanPostAmble's second argument) is called X * after the header information has been read, and given a pointer to a X * PostAmbleInfo structure. It is the job of this function to extract the X * required information from this structure (which is deallocated when X * ScanPostAmble returns). X * X * The second function is called once for each font definition occurring in X * the postamble, and is given a pointer to a PostAmbleFont structure. This X * function should do whatever the device needs to read the actual font. X * X * If the DVI file appears malformed, ScanPostAmble will print an error X * message and exit. (Drastic, perhaps, but effective.) X */ X Xstruct PostAmbleInfo { X i32 pai_PrevPagePointer; /* previous page pointer */ X i32 pai_Numerator; /* numerator from dvi file */ X i32 pai_Denominator; /* denominator from dvi file*/ X i32 pai_DVIMag; /* \magnification */ X i32 pai_TallestPageHeight; /* height of tallest page */ X i32 pai_WidestPageWidth; /* width of widest page */ X int pai_DVIStackSize; /* DVI stack size required */ X int pai_NumberOfPages; /* total number of pages in DVI file */ X}; X Xstruct PostAmbleFont { X char *paf_name; /* name of font (null terminated) */ X int paf_n1; /* length of first part of name */ X int paf_n2; /* length of second part of name */ X i32 paf_DVIFontIndex; /* font index number */ X i32 paf_DVIChecksum; /* checksum from DVI file */ X i32 paf_DVIMag; /* "at size" */ X i32 paf_DVIDesignSize; /* design size of font */ X}; END_OF_h/postamble.h if test 1895 -ne `wc -c <h/postamble.h`; then echo shar: \"h/postamble.h\" unpacked with wrong size! fi chmod +x h/postamble.h # end of overwriting check fi if test -f h/search.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/search.h\" else echo shar: Extracting \"h/search.h\" \(1279 characters\) sed "s/^X//" >h/search.h <<'END_OF_h/search.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* search structures and routines for 32-bit key, arbitrary data */ X Xstruct search { X unsigned s_dsize; /* data object size (includes key size) */ X unsigned s_space; /* space left (in terms of objects) */ X unsigned s_n; /* number of objects in the table */ X char *s_data; /* data area */ X}; X X/* returns a pointer to the search table (for future search/installs) */ Xstruct search *SCreate(); /* create a search table */ X X/* returns a pointer to the data object found or created */ Xchar *SSearch(); /* search for a data object */ X X/* the third argument to SSearch controls operation as follows: */ X#define S_LOOKUP 0x00 /* pseudo flag */ X#define S_CREATE 0x01 /* create object if not found */ X#define S_EXCL 0x02 /* complain if already exists */ X X/* in addition, it is modified before return to hold status: */ X#define S_COLL 0x04 /* collision (occurs iff S_EXCL set) */ X#define S_FOUND 0x08 /* found (occurs iff existed already) */ X#define S_NEW 0x10 /* created (occurs iff S_CREATE && !S_EXCL) */ X#define S_ERROR 0x20 /* problem creating (out of memory) */ END_OF_h/search.h if test 1279 -ne `wc -c <h/search.h`; then echo shar: \"h/search.h\" unpacked with wrong size! fi chmod +x h/search.h # end of overwriting check fi if test -f h/tfm.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/tfm.h\" else echo shar: Extracting \"h/tfm.h\" \(2711 characters\) sed "s/^X//" >h/tfm.h <<'END_OF_h/tfm.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * TFM file information. X */ X X/* X * TFM files start with a series of unsigned 16 bit integers. We X * read this into the structure `tfm_header'. These are type i32 X * so that they may be used as integer quantities without concern X * as to sign extension. X */ Xstruct tfmheader { X i32 th_lf; /* length of the file (16 bit words) */ X i32 th_lh; /* length of the header data (words) */ X i32 th_bc; /* beginning character */ X i32 th_ec; /* ending character (inclusive) */ X i32 th_nw; /* number of words in width table */ X i32 th_nh; /* number of words in height table */ X i32 th_nd; /* number of words in depth table */ X i32 th_ni; /* words in italic correction table */ X i32 th_nl; /* words in ligature/kern table */ X i32 th_nk; /* words in kern table */ X i32 th_ne; /* words in extensible character table */ X i32 th_np; /* number of font parameter words */ X}; X X/* X * The remainder of the TFM file comprises the following information, X * all of which are 32 bit quantities: X * X * header: array [0..lh-1] of stuff X * char_info: array [bc..ec] of char_info_word X * width: array [0..nw-1] of fix_word X * height: array [0..nh-1] of fix_word X * depth: array [0..nd-1] of fix_word X * italic: array [0..ni-1] of fix_word X * lig_kern: array [0..nl-1] of lig_kern_command X * kern: array [0..ne-1] of extensible_recipie X * param: array [0..np-1] of fix_word X */ X X/* X * A char_info_word is built of four unsigned eight-bit quantities. The first X * is an index into the width table (this saves 24 bits for every X * character that has the same width as another character). The X * second is a composite height and depth index. The third is a X * composite italic index and tag, and the fourth is a remainder. X * X * XXX needs explaining X */ Xstruct char_info_word { X char ci_width; /* width index */ X char ci_h_d; /* height and depth index */ X char ci_i_t; /* italic index and tag */ X char ci_remainder; /* ??? */ X}; X X/* X * These macros split up h_and_d and i_and_t values. X */ X#define T_CI_H(ci) (((ci)->ci_h_d >> 4) & 0xf) X#define T_CI_D(ci) ((ci)->ci_h_d & 0xf) X#define T_CI_I(ci) (((ci)->ci_i_t >> 2) & 0x3f) X#define T_CI_T(ci) ((ci)->ci_i_t & 3) X X/* X * This structure contains everything one might need to know about X * a TFM file at run-time. X * X * XXX incomplete, or wrong, as yet X */ Xstruct tfmdata { X struct tfmheader t_hdr; /* full header */ X struct char_info_word *t_ci; /* char info */ X i32 *t_width; /* widths table */ X i32 *t_height; /* heights */ X i32 *t_depth; /* depths */ X}; END_OF_h/tfm.h if test 2711 -ne `wc -c <h/tfm.h`; then echo shar: \"h/tfm.h\" unpacked with wrong size! fi chmod +x h/tfm.h # end of overwriting check fi if test -f h/types.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"h/types.h\" else echo shar: Extracting \"h/types.h\" \(1282 characters\) sed "s/^X//" >h/types.h <<'END_OF_h/types.h' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * C-TeX types (system dependent). X */ X X#ifndef _CTEX_TYPES_ X#define _CTEX_TYPES_ X X/* a 16 bit integer (signed) */ Xtypedef short i16; X X/* a 32 bit integer (signed) */ Xtypedef long i32; X X/* macros to sign extend quantities that are less than 32 bits long */ X#if defined(u3b) || defined(u3b2) || defined(u3b5) || defined(ibm03) X#define Sign8(n) ((n) & (1 << 7) ? ((n) | 0xffffff00) : (n)) X#define Sign16(n) ((i32) (short) (n)) X#define Sign24(n) ((n) & (1 << 23) ? ((n) | 0xff000000) : (n)) X#else X#if defined(sun) || defined(hp300) X/* Sun mishandles (int)(char)(constant), but this subterfuge works: */ X#define Sign8(n) ((i32) (char) (int) (n)) X#else X#define Sign8(n) ((i32) (char) (n)) X#endif /* sun */ X#define Sign16(n) ((i32) (short) (n)) X#define Sign24(n) (((n) << 8) >> 8) X#endif /* u3b || u3b2 || u3b5 */ X X/* macros to truncate quantites that are signed but shouldn't be */ X#define UnSign8(n) ((n) & 0xff) X#define UnSign16(n) ((n) & 0xffff) X#define UnSign24(n) ((n) & 0xffffff) X X/* note that we never have unsigned 32 bit integers */ X X#endif /* _CTEX_TYPES_ */ END_OF_h/types.h if test 1282 -ne `wc -c <h/types.h`; then echo shar: \"h/types.h\" unpacked with wrong size! fi chmod +x h/types.h # end of overwriting check fi echo shar: End of archive 2 \(of 6\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 6)." # Contents: lib/conv.c lib/dviclass.c lib/error.c lib/findpost.c # lib/fio.c lib/font.c lib/font_subr.c # Wrapped by montnaro@sprite on Sat Nov 11 17:13:29 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f lib/conv.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/conv.c\" else echo shar: Extracting \"lib/conv.c\" \(1325 characters\) sed "s/^X//" >lib/conv.c <<'END_OF_lib/conv.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/conv.c,v 1.3 89/02/13 14:30:55 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Conversions. X */ X X#include "types.h" X#include "conv.h" X XConv Conversion; X Xdouble DMagFactor(); X X/* X * Set a conversion (possibly the global conversion). X */ Xvoid XCSetConversion(c, dpi, usermag, num, denom, dvimag) X register struct conversion *c; X int dpi, usermag; X i32 num, denom, dvimag; X{ X double ddpi = dpi; X X c->c_mag = DMagFactor((int) dvimag) * DMagFactor(usermag); X c->c_dpi = ddpi; X X /* X * The conversion facture is figured as follows: there are exactly X * num/denom DVI units per decimicron, and 254000 decimicrons per X * inch, and dpi pixels per inch. Then we have to adjust this by X * the stated magnification. X */ X c->c_fromsp = (num / 254000.0) * (ddpi / denom) * c->c_mag; X X /* X * c->c_tosp is 1/c->c_fromsp, but we will invert the expression X * above in the hopes of some extra accuracy. X * X * IS THIS ANY GOOD? I NEED A NUMERICAL ANALYST! X */ X c->c_tosp = (254000.0 / num) * (denom / ddpi) * (1.0 / c->c_mag); X} END_OF_lib/conv.c if test 1325 -ne `wc -c <lib/conv.c`; then echo shar: \"lib/conv.c\" unpacked with wrong size! fi chmod +x lib/conv.c # end of overwriting check fi if test -f lib/dviclass.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/dviclass.c\" else echo shar: Extracting \"lib/dviclass.c\" \(3242 characters\) sed "s/^X//" >lib/dviclass.c <<'END_OF_lib/dviclass.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/dviclass.c,v 1.3 89/02/13 14:30:57 grunwald Exp Locker: grunwald $"; X#endif X X/* X * dviclass - DVI code classification tables. X */ X X#include "dviclass.h" X X/* shorthand---in lowercase for contrast (read on!) */ X#define four(x) x, x, x, x X#define six(x) four(x), x, x X#define sixteen(x) four(x), four(x), four(x), four(x) X#define sixty_four(x) sixteen(x), sixteen(x), sixteen(x), sixteen(x) X#define one_twenty_eight(x) sixty_four(x), sixty_four(x) X X/* X * This table contains the byte length of the single operand, or DPL_NONE X * if no operand, or if it cannot be decoded this way. X * X * The sequences UNS1, UNS2, UNS3, SGN4 (`SEQ_U') and SGN1, SGN2, SGN3, X * SGN4 (`SEQ_S') are rather common, and so we define macros for these. X */ X#define SEQ_U DPL_UNS1, DPL_UNS2, DPL_UNS3, DPL_SGN4 X#define SEQ_S DPL_SGN1, DPL_SGN2, DPL_SGN3, DPL_SGN4 X Xchar dvi_oplen[256] = { X one_twenty_eight(DPL_NONE), X /* characters 0 through 127 */ X SEQ_U, /* DVI_SET1 through DVI_SET4 */ X DPL_NONE, /* DVI_SETRULE */ X SEQ_U, /* DVI_PUT1 through DVI_PUT4 */ X DPL_NONE, /* DVI_PUTRULE */ X DPL_NONE, /* DVI_NOP */ X DPL_NONE, /* DVI_BOP */ X DPL_NONE, /* DVI_EOP */ X DPL_NONE, /* DVI_PUSH */ X DPL_NONE, /* DVI_POP */ X SEQ_S, /* DVI_RIGHT1 through DVI_RIGHT4 */ X DPL_NONE, /* DVI_W0 */ X SEQ_S, /* DVI_W1 through DVI_W4 */ X DPL_NONE, /* DVI_X0 */ X SEQ_S, /* DVI_X1 through DVI_X4 */ X SEQ_S, /* DVI_DOWN1 through DVI_DOWN4 */ X DPL_NONE, /* DVI_Y0 */ X SEQ_S, /* DVI_Y1 through DVI_Y4 */ X DPL_NONE, /* DVI_Z0 */ X SEQ_S, /* DVI_Z1 through DVI_Z4 */ X sixty_four(DPL_NONE), /* DVI_FNTNUM0 through DVI_FNTNUM63 */ X SEQ_U, /* DVI_FNT1 through DVI_FNT4 */ X SEQ_U, /* DVI_XXX1 through DVI_XXX4 */ X SEQ_U, /* DVI_FNTDEF1 through DVI_FNTDEF4 */ X DPL_NONE, /* DVI_PRE */ X DPL_NONE, /* DVI_POST */ X DPL_NONE, /* DVI_POSTPOST */ X six(DPL_NONE) /* 250 through 255 */ X}; X Xchar dvi_dt[256] = { X one_twenty_eight(DT_CHAR), X /* characters 0 through 127 */ X four(DT_SET), /* DVI_SET1 through DVI_SET4 */ X DT_SETRULE, /* DVI_SETRULE */ X four(DT_PUT), /* DVI_PUT1 through DVI_PUT4 */ X DT_PUTRULE, /* DVI_PUTRULE */ X DT_NOP, /* DVI_NOP */ X DT_BOP, /* DVI_BOP */ X DT_EOP, /* DVI_EOP */ X DT_PUSH, /* DVI_PUSH */ X DT_POP, /* DVI_POP */ X four(DT_RIGHT), /* DVI_RIGHT1 through DVI_RIGHT4 */ X DT_W0, /* DVI_W0 */ X four(DT_W), /* DVI_W1 through DVI_W4 */ X DT_X0, /* DVI_X0 */ X four(DT_X), /* DVI_X1 through DVI_X4 */ X four(DT_DOWN), /* DVI_DOWN1 through DVI_DOWN4 */ X DT_Y0, /* DVI_Y0 */ X four(DT_Y), /* DVI_Y1 through DVI_Y4 */ X DT_Z0, /* DVI_Z0 */ X four(DT_Z), /* DVI_Z1 through DVI_Z4 */ X sixty_four(DT_FNTNUM), /* DVI_FNTNUM0 through DVI_FNTNUM63 */ X four(DT_FNT), /* DVI_FNT1 through DVI_FNT4 */ X four(DT_XXX), /* DVI_XXX1 through DVI_XXX4 */ X four(DT_FNTDEF), /* DVI_FNTDEF1 through DVI_FNTDEF4 */ X DT_PRE, /* DVI_PRE */ X DT_POST, /* DVI_POST */ X DT_POSTPOST, /* DVI_POSTPOST */ X six(DT_UNDEF) /* 250 through 255 */ X}; END_OF_lib/dviclass.c if test 3242 -ne `wc -c <lib/dviclass.c`; then echo shar: \"lib/dviclass.c\" unpacked with wrong size! fi chmod +x lib/dviclass.c # end of overwriting check fi if test -f lib/error.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/error.c\" else echo shar: Extracting \"lib/error.c\" \(2104 characters\) sed "s/^X//" >lib/error.c <<'END_OF_lib/error.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/error.c,v 1.3 89/02/13 14:30:59 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Print an error message with an optional system error number, and X * optionally quit. X * X * THIS CODE IS SYSTEM DEPENDENT UNLESS varargs WORKS WITH vprintf X * OR _doprnt. It should work properly under System V using vprintf. X * (If you have vprintf, define HAVE_VPRINTF.) X */ X X#include <stdio.h> X#include <varargs.h> X X#ifdef lint X X/* VARARGS3 ARGSUSED */ Xerror(quit, e, fmt) int quit, e; char *fmt; {;} X X/* VARARGS1 ARGSUSED */ Xpanic(fmt) char *fmt; { exit(1); /* NOTREACHED */ } X X#else lint X Xextern char *ProgName; Xextern int errno; Xextern char *sys_errlist[]; Xextern int sys_nerr; X Xerror(va_alist) X va_dcl X{ X va_list l; X int quit, e; X char *fmt; X X (void) fflush(stdout); /* sync error messages */ X (void) fprintf(stderr, "%s: ", ProgName); X va_start(l); X /* pick up the constant arguments: quit, errno, printf format */ X quit = va_arg(l, int); X e = va_arg(l, int); X if (e < 0) X e = errno; X fmt = va_arg(l, char *); X#if defined(sys5) || defined(HAVE_VPRINTF) X (void) vfprintf(stderr, fmt, l); X#else X _doprnt(fmt, l, stderr); X#endif X va_end(l); X if (e) { X if (e < sys_nerr) X (void) fprintf(stderr, ": %s", sys_errlist[e]); X else X (void) fprintf(stderr, ": Unknown error code %d", e); X } X (void) putc('\n', stderr); X (void) fflush(stderr); /* just in case */ X if (quit) X exit(quit); X} X Xpanic(va_alist) X va_dcl X{ X va_list l; X char *fmt; X X (void) fflush(stdout); X (void) fprintf(stderr, "%s: panic: ", ProgName); X va_start(l); X /* pick up the constant argument: printf format */ X fmt = va_arg(l, char *); X#if defined(sys5) || defined(HAVE_VPRINTF) X (void) vfprintf(stderr, fmt, l); X#else X _doprnt(fmt, l, stderr); X#endif X va_end(l); X (void) putc('\n', stderr); X (void) fflush(stderr); X abort(); X} X X#endif /* lint */ END_OF_lib/error.c if test 2104 -ne `wc -c <lib/error.c`; then echo shar: \"lib/error.c\" unpacked with wrong size! fi chmod +x lib/error.c # end of overwriting check fi if test -f lib/findpost.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/findpost.c\" else echo shar: Extracting \"lib/findpost.c\" \(3945 characters\) sed "s/^X//" >lib/findpost.c <<'END_OF_lib/findpost.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/findpost.c,v 1.4 89/02/13 14:31:00 grunwald Exp Locker: grunwald $"; X#endif X X/* X * FindPostAmble - Find the postamble of a DVI file. X * X * N.B.: This routine assumes that ftell() returns byte offsets, X * not magic cookies. X */ X X#include <stdio.h> X#include "types.h" X#include "dvicodes.h" X#include "fio.h" X X/* X * I am making the assumption that 530 bytes will always be enough X * to find the end of the DVI file. 12 should suffice, as there X * should be at most seven DVI_FILLER bytes, preceded by the version X * number, preceded by the four byte postamble pointer; but at least X * one VMS TeX must pad to a full `sector'. X */ X/* X * The above is not correct. The DVItype program, as authoritative on X * DVI format, states regarding postambles: X * X * The [last] byte is followed by four or more bytes that are all X * equal to the decimal number 223 (i.e., 337 in octal). TeX puts X * out four to seven of these trailing bytes, until the total length X * of the file is a multiple of four bytes, since this works out X * best on machines that pack four bytes per word; but any number X * of 223's is allowed, as long as there are at least four of them. X * X * Thus assuming "at most seven DVI_FILLER bytes" is wrong. In fact, X * PC-TeX seems to put out liberal amounts of DVI_FILLER at the end. X * X * The original code was efficient, but had to assume a certain X * number of bytes. Since the postamble is only read once anyway, X * efficiency is not really a consideration. Plus, like I always X * say, it's better to get the right answer slowly than the wrong X * answer fast.... X * X * Vahe Sarkissian, UCLA Math. Sci., 4/13/88. X */ X X#ifdef ORIGINAL_CODE X#ifdef vms X#define POSTSIZE 530 /* make only VMS pay for its errors; */ X#else X#define POSTSIZE 16 /* others get to use something reasonable */ X#endif X Xlong ftell(); X XFindPostAmble(f) X register FILE *f; X{ X register long offset; X register char *p; X register int i; X register i32 n; X char postbuf[POSTSIZE]; X X /* X * Avoid fseek'ing beyond beginning of file; it may X * give odd results. X */ X fseek(f, 0L, 2); /* seek to end */ X offset = ftell(f) - POSTSIZE; /* and compute where to go next */ X if (offset < 0L) /* but make sure it is positive */ X offset = 0L; X fseek(f, offset, 0); X p = postbuf; X for (i = 0; i < POSTSIZE; i++) { X *p++ = getc(f); X if (feof(f)) { X p--; X break; X } X } X X /* X * Now search backwards for the VERSION byte. The postamble X * pointer will be four bytes behind that. X */ X while (--i >= 0) { X if (UnSign8(*--p) == DVI_VERSION) X goto foundit; X if (UnSign8(*p) != DVI_FILLER) X break; X } X return (-1); /* cannot find postamble ptr */ X Xfoundit: X /* X * Change offset from the position at the beginning of postbuf X * to the position of the VERSION byte, and seek to four bytes X * before that. Then get a long and use its value to seek to X * the postamble itself. X */ X offset += p - postbuf; X fseek(f, offset - 4L, 0); X fGetLong(f, n); X offset = n; X fseek(f, offset, 0); X return (0); /* success */ X} X X#else !ORIGINAL_CODE X XFindPostAmble(f) X register FILE *f; X{ X register long offset; X register i32 n; X X offset = -4; /* At least four bytes of DVI_FILLER must be present. */ X do { X offset -= 1; X (void) fseek(f, offset, 2); X n = fgetbyte(f); X } while (n == DVI_FILLER); X X if (n != DVI_VERSION) X return (-1); /* Bad version of DVI file */ X X /* X * Position file four bytes before DVI_VERSION byte, X * and read a long. Use that long to seek to the X * beginning of the postamble itself. X */ X offset -= 4; X (void) fseek(f, offset, 2); X fGetLong(f, n); X offset = n; X (void) fseek(f, offset, 0); X return (0); /* success */ X} X#endif ORIGINAL_CODE END_OF_lib/findpost.c if test 3945 -ne `wc -c <lib/findpost.c`; then echo shar: \"lib/findpost.c\" unpacked with wrong size! fi chmod +x lib/findpost.c # end of overwriting check fi if test -f lib/fio.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/fio.c\" else echo shar: Extracting \"lib/fio.c\" \(965 characters\) sed "s/^X//" >lib/fio.c <<'END_OF_lib/fio.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/fio.c,v 1.3 89/02/13 14:31:01 grunwald Exp Locker: grunwald $"; X#endif X X/* X * File I/O subroutines for getting bytes, words, 3bytes, and longwords. X */ X X#include <stdio.h> X#include "types.h" X#include "fio.h" X Xstatic char eofmsg[] = "unexpected EOF"; X X/* for symmetry: */ X#define fGetByte(fp, r) ((r) = getc(fp)) X#define Sign32(i) (i) X X#define make(name, func, signextend) \ Xi32 \ Xname(fp) \ X register FILE *fp; \ X{ \ X register i32 n; \ X \ X func(fp, n); \ X if (feof(fp)) \ X error(1, 0, eofmsg); \ X return (signextend(n)); \ X} X Xmake(GetByte, fGetByte, Sign8) Xmake(GetWord, fGetWord, Sign16) Xmake(Get3Byte, fGet3Byte, Sign24) Xmake(GetLong, fGetLong, Sign32) END_OF_lib/fio.c if test 965 -ne `wc -c <lib/fio.c`; then echo shar: \"lib/fio.c\" unpacked with wrong size! fi chmod +x lib/fio.c # end of overwriting check fi if test -f lib/font.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/font.c\" else echo shar: Extracting \"lib/font.c\" \(9825 characters\) sed "s/^X//" >lib/font.c <<'END_OF_lib/font.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font.c,v 1.6 89/02/13 14:31:02 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Routines for working with fonts. In particular, the configuration X * dependent code is here. X * X * Specific fonts (GF, PXL, etc.) have functions in separate files. X */ X X#include <stdio.h> X#include <errno.h> X#include <sys/file.h> X#include "types.h" X#include "conv.h" X#include "font.h" X X/* X * Define the default configuration file. X * Also define the maximum path name length. X */ X#ifndef FONTDESC X you need to define FONTDESC in the compile line X#endif X X#define PATHLEN 1024 X X/* X * A font configuration. The font list is ordered. X * X * A specifier is typically a particular print engine, since X * different engines need slightly different fonts. X */ Xstruct fontconf { X struct fontconf *fc_next; X struct fontops *fc_ops; X char *fc_path; /* path, with metacharacters */ X char *fc_spec; /* specifier */ X int fc_slop; /* slop value */ X}; X X/* X * EQ is a fast way to check for string equivalence. X */ X#define EQ(a, b) (*(a) == *(b) && strcmp(a, b) == 0) X X/* X * Private variables. X */ Xstatic int didinit; /* true => initialised already */ Xstatic char *cfname; /* config file name, for errors */ Xstatic int cfline; /* config file line, likewise */ Xstatic struct fontops *fontops;/* font operations code: list head */ Xstatic struct fontconf *fonts; /* font list */ Xstatic struct fontconf **nextfc;/* used during initialisation */ Xstatic char spec_any[] = "*"; /* the `anything' specifier */ X X/* X * Imports. X */ Xextern int errno; Xchar *getenv(), *malloc(), *strsave(); X#ifndef sys5 Xchar *sprintf(); X#endif X Xstatic readconf(); Xstatic setfont(); Xstatic badcf(); Xstatic struct font *getafont(); /* get a font and optional rasters */ X X/* X * Here, alas, we know about all the kinds of fonts. X * This also means that every DVI interpreter pulls in X * the full set of font manipulation routines. X * X * PERHAPS THIS SHOULD BE CONFIGURABLE. X */ X#define ADDFONT(x) { \ X extern struct fontops x; \ X x.fo_next = fontops; \ X fontops = &x; \ X} X Xfontinit(file) X char *file; X{ X X if (didinit) { X /* X * Could free the old configuration and fire up X * a new one, but for now . . . X */ X error(1, 0, "attempt to reinit fonts"); X /* NOTREACHED */ X } X didinit++; X ADDFONT(boxops); X ADDFONT(blankops); X ADDFONT(invisops); X ADDFONT(pxlops); X ADDFONT(pkops); X ADDFONT(gfops); X nextfc = &fonts; X if (file == NULL) X if ((file = getenv(CONFENV)) == NULL) X file = FONTDESC; X readconf(file); X} X X/* X * A proto resembles a fontspec (indeed, it is a prototype X * fontspec) but is not quite the same. It is used to gather X * the information needed per fontspec before allocating X * the fontspec itself. X */ Xstruct proto { X char *p_type; X char *p_spec; X char *p_slop; X char *p_path; X}; X X/* X * Read the named configuration file. The file is split into X * lines, and lines are split into words; if the first word is X * "font", this is a fontconf, and we read the remainder of the X * words and make a fontconf entry. X */ Xstatic Xreadconf(name) X char *name; X{ X register FILE *f; /* config file */ X register char **p; /* pointer into word vector */ X register int c; X char line[1024]; /* input line */ X char *v[100]; /* word vector */ X struct proto proto; /* prototype fontconf */ X X#define GETWORD(x, ifnone) \ X if (--c <= 0) \ X badcf(ifnone); \ X else \ X (x) = *p++ X X if ((f = fopen(name, "r")) == NULL) X error(1, errno, "cannot read font configuration file \"%s\"", X name); X cfname = name; X cfline = 0; X while (fgets(line, sizeof (line), f) != NULL) { X cfline++; X if ((c = strlen(line)) > 0) { X if (line[--c] != '\n') X badcf("line too long"); X line[c] = 0; X } X if ((c = split(line, v, sizeof (v) / sizeof (*v))) < 0) X badcf("too many words"); X p = v; X /* skip things that are not fonts */ X if (c == 0 || !EQ(*p, "font")) X continue; X p++; X GETWORD(proto.p_type, "missing font typename"); X GETWORD(proto.p_spec, "missing font spec (engine)"); X GETWORD(proto.p_slop, "missing slop value"); X GETWORD(proto.p_path, "need pathname"); X (void) setfont(&proto); X } X} X X/* X * Find a font's operations, given its name. X */ Xstatic struct fontops * Xfindops(name) X register char *name; X{ X register struct fontops *fo; X X for (fo = fontops; fo != NULL; fo = fo->fo_next) X if (EQ(fo->fo_name, name)) X return (fo); X return (NULL); X} X X/* X * Turn a prototype fontconf into a real one. X */ Xstatic int Xsetfont(p) X register struct proto *p; X{ X register struct fontconf *fc; X struct fontops *ops = findops(p->p_type); X X if (ops == NULL) { X error(0, 0, X "\"%s\", line %d: unknown font type \"%s\" ignored", X cfname, cfline, p->p_type); X return (-1); X } X if ((fc = (struct fontconf *) malloc(sizeof (*fc))) == NULL) X error(1, errno, X "out of memory for font configuration (sorry)"); X fc->fc_ops = ops; X fc->fc_next = NULL; X fc->fc_path = strsave(p->p_path); X fc->fc_spec = EQ(p->p_spec, spec_any) ? NULL : strsave(p->p_spec); X fc->fc_slop = atoi(p->p_slop); X if (fc->fc_slop < 1) /* quietly enforce proper slops */ X fc->fc_slop = 1; X *nextfc = fc; X nextfc = &fc->fc_next; X return (0); X} X X/* X * Complain about a problem in the configuration file. X */ Xstatic Xbadcf(why) X char *why; X{ X X error(1, 0, "\"%s\", line %d: %s", cfname, cfline, why); X /* NOTREACHED */ X} X X/* X * Turn a prototype path, name, and magnification into a full X * path. X */ Xstatic Xpave(result, proto, name, mag) X char *result, *proto, *name; X int mag; X{ X register int c; X register char *s, *d, *p; X char num[30]; X X d = result; X p = proto; X s = NULL; X num[0] = 0; /* will need changing for other bases */ X X while (p != NULL) { X /* X * If sourcing from s, take its next character, and X * insert it directly. Otherwise take the next path X * character and interpret it. X */ X if (s != NULL) { X if ((c = *s++) == 0) { X s = NULL; X continue; X } X goto put; X } X if ((c = *p++) == 0) X p = NULL; X if (c != '%') X goto put; X X switch (c = *p++) { X X case 'f': X case 'n': X case 's': X s = name; X continue; X X case 'd': X case 'm': X if (num[0] == 0) X (void) sprintf(num, "%d", mag); X s = num; X continue; X X case 0: X c = '%'; X p--; X /* FALLTHROUGH */ X } Xput: X if (d - result >= PATHLEN) X error(1, 0, "font path `%s' too long (sorry)", proto); X *d++ = c; X } X} X X X/* X * Given a font name and size, return the first font that fits, along X * with its name (via fname). If we cannot find such a font, we set X * *fname to point to a `canonical' example font name, unless there are X * are no fonts for the device, in which case we set *fname to NULL. X */ Xstruct font * XGetFont(nm, dvimag, dvidsz, dev, fname) X char *nm; X i32 dvimag, dvidsz; X char *dev, **fname; X{ X X return (getafont(nm, dvimag, dvidsz, dev, fname, 1)); X} X X/* X * Same as GetFont, but caller promises never to ask for rasters. X */ Xstruct font * XGetRasterlessFont(nm, dvimag, dvidsz, dev, fname) X char *nm; X i32 dvimag, dvidsz; X char *dev, **fname; X{ X X return (getafont(nm, dvimag, dvidsz, dev, fname, 0)); X} X X/* X * NEED TO THINK ABOUT gf NAMING CONVENTIONS HERE: ARE THEY LIKE pxl? X * WHAT ABOUT OTHERS? X */ Xstatic struct font * Xgetafont(nm, dvimag, dvidsz, dev, fname, wantrast) X char *nm; X i32 dvimag, dvidsz; X char *dev, **fname; X int wantrast; X{ X register int slop, fmag; X register struct font *f; X register struct fontconf *fc; X register char *path; X static char firstpath[PATHLEN], laterpath[PATHLEN]; X double mag; X int scaled; X X extern Conv Conversion; X X if (!didinit) X fontinit((char *) NULL); X X /* X * The equation below means, approximately, `the font is X * magnified by the ratio of the actual size dvimag to the X * design size dvidsz, and then further scaled by the X * global magnification.' We multiply this by the printer's X * resolution in dots per inch, then use the per-font X * conversion factor to convert a dots-per-inch value to X * a font name `%m' magnification (extension). X */ X mag = (double) dvimag / (double) dvidsz; X scaled = mag * 1000.0 + 0.5; X mag *= Conversion.c_mag * Conversion.c_dpi; X X path = firstpath; X for (fc = fonts; fc != NULL; fc = fc->fc_next) { X if (dev != NULL && fc->fc_spec != NULL && X !EQ(dev, fc->fc_spec)) X continue; X fmag = mag * fc->fc_ops->fo_dpitomag + 0.5; X for (slop = 0; slop < fc->fc_slop; slop++) { X pave(path, fc->fc_path, nm, fmag + slop); X if (access(path, R_OK) == 0) X goto found; X X X /* if someone could explain this, I'd appreicate it. X On ultrix 2.2, checking R_OK on a RO filesyste X fails, with the following errno. Why? */ X X if ( errno == EROFS ) { X goto found; X } X X if (slop) { X pave(path, fc->fc_path, nm, fmag - slop); X if (access(path, R_OK) == 0) X goto found; X if ( errno == EROFS ) { X goto found; X } X } X path = laterpath; X } X } X X /* not found */ X if (path == firstpath) { /* never got to try any paths */ X *fname = NULL; X errno = ENXIO; X } else { X *fname = firstpath; X errno = ENOENT; X } X return (NULL); X Xfound: X *fname = path; X X /* allocate space for the per-font info, and read it in */ X f = (struct font *) malloc(sizeof (struct font)); X if (f == NULL) X return (NULL); X f->f_flags = wantrast ? FF_RASTERS : 0; X f->f_ops = fc->fc_ops; X f->f_path = strsave(path); X f->f_font = strsave(nm); X f->f_dvimag = dvimag; X f->f_dvidsz = dvidsz; X f->f_scaled = scaled; X f->f_checksum = 0; /* in case the font reader cannot get one */ X errno = 0; X if ((*f->f_ops->fo_read)(f)) { X int e = errno; /* paranoid */ X X free(f->f_path); f -> f_path = 0; X free(f->f_font); f -> f_font = 0; X free((char *) f); f = 0; X errno = e; X return (NULL); X } X return (f); X} END_OF_lib/font.c if test 9825 -ne `wc -c <lib/font.c`; then echo shar: \"lib/font.c\" unpacked with wrong size! fi chmod +x lib/font.c # end of overwriting check fi if test -f lib/font_subr.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/font_subr.c\" else echo shar: Extracting \"lib/font_subr.c\" \(4984 characters\) sed "s/^X//" >lib/font_subr.c <<'END_OF_lib/font_subr.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font_subr.c,v 1.5 89/02/13 14:31:04 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Subroutines common to all fonts. X */ X X#include "font.h" X Xstatic struct glyph *freeglyphs; X Xchar *malloc(); Xextern errno; X X/* X * Set up the font structures to note that a font has glyphs in X * the half-open interval [low, high). X * X * SHOULD I ALLOW ADDITIONS TO THE RANGE VIA SUBSEQUENT CALLS TO X * FontHasGlyphs? X */ XFontHasGlyphs(f, low, high) X register struct font *f; X register int low, high; X{ X register struct glyph **gp; X X /* record bounds */ X f->f_lowch = low; X f->f_highch = high; X X /* X * Allocate space for all the glyph pointers, and set X * them all to NULL. X */ X if (low >= high) /* no glyphs */ X gp = NULL; X else { X gp = (struct glyph **) malloc((unsigned) (high - low) * X sizeof (*gp)); X if (gp == NULL) X return (-1); X } X f->f_glybase = gp; X f->f_gly = gp - low; X while (++low <= high) X *gp++ = NULL; X return (0); X} X X/* X * AllocGlyph allocates a new glyph. ReleaseGlyph puts one onto the free X * list. We maintain a local list of free glyphs. X */ X#define ReleaseGlyph(g) \ X ((g)->g_un.g_next = freeglyphs, freeglyphs = (g)) X Xstatic struct glyph * XAllocGlyph(n) X int n; X{ X register struct glyph *g; X register int i; X X if ((g = freeglyphs) == NULL) { X g = (struct glyph *) malloc((unsigned) (128 * sizeof (*g))); X if (g == NULL) X error(1, errno, "out of glyph memory"); X g += (i = 128); X while (--i >= 0) { X g--; X ReleaseGlyph(g); X } X } X freeglyphs = g->g_un.g_next; X g->g_flags = 0; X g->g_raster = NULL; X g->g_index = n; X return (g); X} X X/* X * Free one glyph. X */ Xvoid XFreeGlyph(f, n) X struct font *f; X register int n; X{ X register struct glyph *g; X X if (n < f->f_lowch || n >= f->f_highch) X return; X#ifdef notdef X (*f->f_ops->fo_freegly)(f, n, n); X#endif X if ((g = f->f_gly[n]) == NULL) X return; X if (g->g_raster != NULL) { X free(g->g_raster); g -> g_raster = 0; X } X ReleaseGlyph(g); X} X X/* X * Free a font. X */ Xvoid XFreeFont(f) X register struct font *f; X{ X register struct glyph *g; X register int i; X X#ifdef notdef X (*f->f_ops->fo_freegly)(f, f->f_lowch, f->f_highch); X#endif X for (i = f->f_lowch; i < f->f_highch; i++) { X if ((g = f->f_gly[i]) == NULL) X continue; X if (g->g_raster != NULL) { X free(g->g_raster); g -> g_raster = 0; X } X ReleaseGlyph(g); X } X if (f->f_glybase != NULL) { X free((char *) f->f_glybase); g -> g_raster = 0; X } X (*f->f_ops->fo_freefont)(f); X free(f->f_path); f -> f_path = 0; X free(f->f_font); f -> f_font = 0; X free((char *) f); f = 0; X} X X/* X * Get glyph `c' in font `f'. We pull in a few adjacent glyphs here X * under the (perhaps naive) assumption that things will go faster X * that way. X * X * TODO: X * try different adjacency values X * make adjacency a font attribute? (or an op) X */ X#define ADJ 8 /* must be a power of 2 */ X#define GET_ADJ(c, l, h) ((h) = ADJ + ((l) = (c) & ~(ADJ - 1))) X Xstruct glyph * XGetGlyph(f, c) X register struct font *f; X int c; X{ X register int i, h, l; X X GET_ADJ(c, l, h); X if (l < f->f_lowch) X l = f->f_lowch; X if (h > f->f_highch) X h = f->f_highch; X if (l >= h) X return (NULL); X for (i = l; i < h; i++) X if (f->f_gly[i] == NULL) X f->f_gly[i] = AllocGlyph(i); X X if ((*f->f_ops->fo_getgly)(f, l, h)) { X /* X * I do not know what to do about this just yet, so: X */ X panic("getgly fails and I am confused ... help!"); X } X X /* X * Apply the appropriate scale factor to the TFM widths. X * This makes them come out in scaled points, instead of FIXes. X */ X ScaleGlyphs(f, l, h); /* ??? */ X X return (f->f_gly[c]); X} X X/* X * Get the raster for glyph g in font f at rotation r. X */ Xchar * XGetRaster(g, f, r) X register struct glyph *g; X register struct font *f; X int r; X{ X int l, h; X X /* abort if caller did not ask for rasters in advance */ X if ((f->f_flags & FF_RASTERS) == 0) X panic("GetRaster(%s)", f->f_path); X X /* X * If there is no raster, get one. Blank characters, X * however, never have rasters. X */ X if (g->g_raster == NULL) { X if (!HASRASTER(g)) X return (NULL); X /* X * THE FOLLOWING DEPENDS ON THE ADJACENCY MATCHING THAT IN X * GetGlyph() ABOVE. X */ X GET_ADJ(g->g_index, l, h); X if (l < f->f_lowch) X l = f->f_lowch; X if (h > f->f_highch) X h = f->f_highch; X if ((*f->f_ops->fo_rasterise)(f, l, h)) X error(1, 0, "rasterise fails (out of memory?)"); X } X if (g->g_rotation != r) X SetRotation(g, r); X return (g->g_raster); X} X X/* X * Return a TeX-style font name, including scale factor. X * SHOULD I BOTHER WITH \magstep STYLE NAMES? X */ Xchar * XFont_TeXName(f) X register struct font *f; X{ X static char result[200]; X X if (f->f_scaled == 1000) X return (f->f_font); X sprintf(result, "%s scaled %d", f->f_font, f->f_scaled); X return (result); X} END_OF_lib/font_subr.c if test 4984 -ne `wc -c <lib/font_subr.c`; then echo shar: \"lib/font_subr.c\" unpacked with wrong size! fi chmod +x lib/font_subr.c # end of overwriting check fi echo shar: End of archive 3 \(of 6\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 6)." # Contents: lib/getopt.c lib/gfclass.c lib/gffont.c lib/gripes.c # lib/magfactor.c # Wrapped by montnaro@sprite on Sat Nov 11 17:13:31 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f lib/getopt.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/getopt.c\" else echo shar: Extracting \"lib/getopt.c\" \(1380 characters\) sed "s/^X//" >lib/getopt.c <<'END_OF_lib/getopt.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * getopt - get option letter from argv X * (From Henry Spencer @ U of Toronto Zoology, slightly edited) X */ X X#include <stdio.h> X Xchar *optarg; /* Global argument pointer. */ Xint optind; /* Global argv index. */ X Xstatic char *scan; /* Private scan pointer. */ X Xextern char *index(); X Xint Xgetopt(argc, argv, optstring) X register int argc; X register char **argv; X char *optstring; X{ X register int c; X register char *place; X X optarg = NULL; X if (scan == NULL || *scan == 0) { X if (optind == 0) X optind++; X if (optind >= argc || argv[optind][0] != '-' || X argv[optind][1] == 0) X return (EOF); X if (strcmp(argv[optind], "--") == 0) { X optind++; X return (EOF); X } X scan = argv[optind] + 1; X optind++; X } X c = *scan++; X place = index(optstring, c); X X if (place == NULL || c == ':') { X fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); X return ('?'); X } X place++; X if (*place == ':') { X if (*scan != '\0') { X optarg = scan; X scan = NULL; X } else { X if (optind >= argc) { X fprintf(stderr, X "%s: missing argument after -%c\n", X argv[0], c); X return ('?'); X } X optarg = argv[optind]; X optind++; X } X } X return (c); X} END_OF_lib/getopt.c if test 1380 -ne `wc -c <lib/getopt.c`; then echo shar: \"lib/getopt.c\" unpacked with wrong size! fi chmod +x lib/getopt.c # end of overwriting check fi if test -f lib/gfclass.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/gfclass.c\" else echo shar: Extracting \"lib/gfclass.c\" \(2408 characters\) sed "s/^X//" >lib/gfclass.c <<'END_OF_lib/gfclass.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/gfclass.c,v 1.3 89/02/13 14:31:07 grunwald Exp Locker: grunwald $"; X#endif X X/* X * gfclass - GF code classification tables. X */ X X#include "gfclass.h" X X/* shorthand---in lowercase for contrast (read on!) */ X#define three(x) x, x, x X#define four(x) x, x, x, x X#define five(x) four(x), x X#define six(x) four(x), x, x X#define eight(x) four(x), four(x) X#define sixteen(x) eight(x), eight(x) X#define thirty_two(x) sixteen(x), sixteen(x) X#define sixty_four(x) thirty_two(x), thirty_two(x) X#define one_twenty_eight(x) sixty_four(x), sixty_four(x) X#define one_sixty_five(x) one_twenty_eight(x), thirty_two(x), five(x) X X/* X * Length of the single (or first) operand, if any. X */ Xchar gf_oplen[256] = { X sixty_four(GPL_NONE), /* GF_PAINT_0 through GF_PAINT_63 */ X GPL_UNS1, /* GF_PAINT1 */ X GPL_UNS2, /* GF_PAINT2 */ X GPL_UNS3, /* GF_PAINT3 */ X GPL_NONE, /* GF_BOC */ X GPL_NONE, /* GF_BOC1 */ X GPL_NONE, /* GF_EOC */ X GPL_NONE, /* GF_SKIP0 */ X GPL_UNS1, /* GF_SKIP1 */ X GPL_UNS2, /* GF_SKIP2 */ X GPL_UNS3, /* GF_SKIP3 */ X one_sixty_five(GPL_NONE),/* GF_NEW_ROW_0 through GF_NEW_ROW_164 */ X GPL_UNS1, /* GF_XXX1 */ X GPL_UNS2, /* GF_XXX2 */ X GPL_UNS3, /* GF_XXX3 */ X GPL_SGN4, /* GF_XXX4 */ X GPL_SGN4, /* GF_YYY */ X GPL_NONE, /* GF_NOP */ X GPL_NONE, /* GF_CHAR_LOC */ X GPL_NONE, /* GF_CHAR_LOC0 */ X GPL_NONE, /* GF_PRE */ X GPL_NONE, /* GF_POST */ X GPL_NONE, /* GF_POSTPOST */ X six(GPL_NONE) /* 250 through 255 */ X}; X X/* X * Types of the various opcodes. X */ Xchar gf_gt[256] = { X sixty_four(GT_PAINT0), /* GF_PAINT_0 through GF_PAINT_63 */ X three(GT_PAINT), /* GF_PAINT1 through GF_PAINT3 */ X GT_BOC, /* GF_BOC */ X GT_BOC1, /* GF_BOC1 */ X GT_EOC, /* GF_EOC */ X GT_SKIP0, /* GF_SKIP0 */ X three(GT_SKIP), /* GF_SKIP1 through GF_SKIP3 */ X one_sixty_five(GT_NEW_ROW),/* GF_NEW_ROW_0 throgh GF_NEW_ROW_164 */ X four(GT_XXX), /* GF_XXX1 through GF_XXX4 */ X GT_YYY, /* GF_YYY */ X GT_NOP, /* GF_NOP */ X GT_CHAR_LOC, /* GF_CHAR_LOC */ X GT_CHAR_LOC0, /* GF_CHAR_LOC0 */ X GT_PRE, /* GF_PRE */ X GT_POST, /* GF_POST */ X GT_POSTPOST, /* GF_POSTPOST */ X six(GT_UNDEF) /* 250 through 255 */ X}; END_OF_lib/gfclass.c if test 2408 -ne `wc -c <lib/gfclass.c`; then echo shar: \"lib/gfclass.c\" unpacked with wrong size! fi chmod +x lib/gfclass.c # end of overwriting check fi if test -f lib/gffont.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/gffont.c\" else echo shar: Extracting \"lib/gffont.c\" \(22029 characters\) sed "s/^X//" >lib/gffont.c <<'END_OF_lib/gffont.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/gffont.c,v 1.4 89/02/13 14:31:08 grunwald Exp Locker: grunwald $"; X#endif X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include "types.h" X#include "font.h" X#include "gfcodes.h" X#include "gfclass.h" X#include "num.h" X X/* X * GF font operations. X * X * GF files may be compact, but this code surely is not! X * X * TODO: X * think about fonts with characters outside [0..255] X * find some way to free gf body when done X */ X Xstatic gf_read(); Xstatic gf_getgly(); Xstatic gf_rasterise(); Xstatic gf_freefont(); X Xstruct fontops gfops = X { "gf", 1.0, gf_read, gf_getgly, gf_rasterise, gf_freefont }; X X/* X * Local info. X */ X X/* X * A bounding box. The names follow those in the GF documentation. X */ Xstruct bounds { X i32 min_m, max_m; /* min and max `m' (colunm) values */ X i32 min_n, max_n; /* min and max `n' (row) values */ X}; X X/* X * char_loc is one `character locator' from a GF file, save for the X * `character residue', which we need not. X */ Xstruct char_loc { X i32 cl_dx; /* x escapement (scaled pixels) */ X i32 cl_dy; /* y escapement (scaled pixels) */ X i32 cl_w; /* TFM width */ X i32 cl_p; /* pointer to BOC (or specials) */ X}; X X/* X * GF details include: X * -> the main body of the GF file (all bytes save pre- and post-amble); X * -> global box boundaries; X * and character locators, addressed by `character residue'. Empty X * slots are indicated by a -1 `pointer'. X */ Xstruct gf_details { X char *gd_body; /* GF body */ X char *gd_base; /* == gd_body - preamble_size */ X struct bounds gd_gb; /* global boundaries */ X struct char_loc gd_cl[256]; /* character locators */ X}; X X/* X * Get the gf_details from font f. X */ X#define ftogd(f) ((struct gf_details *) (f)->f_details) X Xextern int errno; Xchar *malloc(), *copyit(); X Xstatic int gf_read(); Xstatic int gf_read(); Xstatic int gf_rasterise(); Xstatic int gf_freefont(); X X/* X * I am making the assumption that 530 bytes will always be enough X * to find the end of the GF file. 12 should suffice, as there X * should be at most seven GF_FILLER bytes, preceded by the GF ID, X * preceded by the four byte postamble pointer; but at least one X * VMS TeX pads pads DVI files to a full `sector', so I am assuming X * it may do the same to GF files. X */ X#ifdef vms X#define POSTSIZE 530 /* make only VMS pay for its ways; */ X#else X#define POSTSIZE 16 /* others get to use something reasonable */ X#endif X X/* X * Find the GF postamble. Store the offsets of the POST and POSTPOST X * opcodes through postp and postpostp. X */ Xstatic XfindGFpostamble(fd, postp, postpostp) X int fd; X long *postp, *postpostp; X{ X register long offset; X register char *p; X register int i; X register i32 n; X char postbuf[POSTSIZE]; X X /* X * Avoid lseek()ing beyond beginning of file; it may give odd X * results. Read the last POSTSIZE bytes (or however many we X * can get). X */ X offset = lseek(fd, 0L, 2) - (long) POSTSIZE; X if (offset < 0L) X offset = 0L; X (void) lseek(fd, offset, 0); X i = read(fd, postbuf, POSTSIZE); X if (i <= 0) X return (-1); X p = &postbuf[i]; X i -= 4; /* account for the pointer in advance */ X X /* X * Now search backwards for the GF_ID byte. The postamble X * pointer will be four bytes behind that. X */ X while (--i >= 0) { X if (UnSign8(*--p) == GF_ID) X goto foundit; X if (UnSign8(*p) != GF_FILLER) X break; X } X return (-1); /* cannot find postamble ptr */ X Xfoundit: X /* X * Store the (presumed) position of the POSTPOST byte, which X * is i-1 bytes beyond `offset'. X */ X *postpostp = offset + i - 1; X X /* X * Read out the postamble pointer and seek to the postamble, X * also saving the offset. X */ X p -= 4; X pGetLong(p, n); X *postp = offset = n; X (void) lseek(fd, offset, 0); X return (0); /* made it */ X} X X/* X * Read a GF file. X */ Xstatic int Xgf_read(f) X register struct font *f; X{ X register struct gf_details *gd; X register char *p; X register struct char_loc *cl; X register int i; X int fd, presize, postsize, bodysize, firstc, lastc; X char *postamble; X long postaddr, postpostaddr; X i32 lasteoc; X char *problem = NULL; X struct stat st; X char b[4]; X int saverr; X X if ((fd = open(f->f_path, 0)) < 0) X return (-1); X gd = NULL; /* prepare for failure */ X postamble = NULL; X X /* X * The file had best be at least 50 bytes long. A X * `completely empty' GF file might consist of a PRE, a GF_ID, X * no comment (one zero byte), then: POST, pointer to last X * EOC, design size, checksum, hppp, vppp, min_m, max_m, X * min_n, max_n, POSTPOST, pointer to POST, GF_ID, and four X * FILLERs. X */ X (void) fstat(fd, &st); X if (st.st_size < 50) { /* too small to be a GF file */ X problem = "file is too short"; X goto fail; X } X X /* X * Read the very beginning and pick up the preamble size. X */ X if (read(fd, b, 4) != 4) X goto fail; X if (UnSign8(b[0]) != GF_PRE) { X problem = "file does not begin with PRE"; X goto fail; X } X i = UnSign8(b[1]); X if (i != GF_ID) X error(0, 0, "Warning: strange GF id (%d) in \"%s\"", i, X f->f_path); X presize = 3 + UnSign8(b[2]); X X /* X * Find the postamble, allocate space, and read it in. X */ X if (findGFpostamble(fd, &postaddr, &postpostaddr)) { X problem = "cannot find postamble"; X goto fail; X } X postsize = postpostaddr - postaddr + 1; X if ((p = malloc(postsize)) == NULL) X goto fail; X if (read(fd, p, postsize) != postsize) X goto fail; X postamble = p; X X /* X * Make sure we found it. X */ X if (pgetbyte(p) != GF_POST) { X problem = "no GF_POST at postamble"; X goto fail; X } X X /* X * Looks okay. Allocate detail space and poke through the postamble. X */ X if ((gd = (struct gf_details *) malloc(sizeof (*gd))) == NULL) X goto fail; X gd->gd_body = NULL; X X pGetLong(p, lasteoc); /* actually one past last EOC */ X pGetLong(p, f -> f_design_size ); X pGetLong(p, f->f_checksum); X pGetLong(p, f -> f_hppp); X pGetLong(p, f -> f_vppp); X X pGetLong(p, gd->gd_gb.min_m); X pGetLong(p, gd->gd_gb.max_m); X pGetLong(p, gd->gd_gb.min_n); X pGetLong(p, gd->gd_gb.max_n); X X /* X * Zap all the character locators, then read those that are X * defined in the postamble. Remember the first and last X * characters so that we know which glyphs are defined. Lastc X * is actually the last-plus-one'th character. X */ X for (cl = gd->gd_cl, i = 256; --i >= 0; cl++) X cl->cl_p = -1; X firstc = 256; X lastc = 0; X for (;;) { X i32 dx, dy; X X switch (pgetbyte(p)) { X X case GF_CHAR_LOC: X i = pgetbyte(p); X pGetLong(p, dx); X pGetLong(p, dy); X goto merge; X X case GF_CHAR_LOC0: X i = pgetbyte(p); X dx = ((i32) pgetbyte(p)) << 16; X dy = 0; Xmerge: X if (i < firstc) X firstc = i; X if (i >= lastc) X lastc = i + 1; X cl = &gd->gd_cl[i]; X cl->cl_dx = dx; X cl->cl_dy = dy; X pGetLong(p, cl->cl_w); X pGetLong(p, cl->cl_p); X break; X X case GF_POSTPOST: X goto done; X X default: X error(0, 0, "I do not understand %d here", X UnSign8(p[-1])); X problem = "unexpected opcode in postamble"; X goto fail; X } X } Xdone: X free(postamble); X postamble = NULL; /* all done with it */ X X /* X * Alas, we need the instructions whether or not we need X * the rasters, since the raster bounding box information X * can only be properly determined by converting the rasters. X * Compute the size of the main body of the GF file, then X * read it in. X */ X bodysize = lasteoc - presize; X if ((gd->gd_body = malloc(bodysize + 1)) == NULL) X goto fail; X (void) lseek(fd, (long) presize, 0); X if (read(fd, gd->gd_body, bodysize) != bodysize) X goto fail; X /* X * The next byte might be a special, so we just X * arbitrarily stuff in a POST. X */ X gd->gd_body[bodysize] = GF_POST; X gd->gd_base = gd->gd_body - presize; X X f->f_details = (char *) gd; X if (FontHasGlyphs(f, firstc, lastc)) X goto fail2; X (void) close(fd); X return (0); X Xfail: X if (problem == NULL) X error(0, errno, "trouble reading \"%s\"", f->f_path); X else X error(0, 0, "%s\n\t(are you sure \"%s\" is a GF file?)", X problem, f->f_path); X errno = 0; Xfail2: X saverr = errno; X if (postamble != NULL) { X free(postamble); postamble = 0; X } X if (gd != NULL) { X if (gd->gd_body != NULL) { X free(gd->gd_body); gd -> gd_body = 0; X } X free((char *) gd); gd = 0; X } X (void) close(fd); X errno = saverr; X return (-1); X} X X/* X * Some global variables, used while building rasters. (These are X * referenced also in copyit(), so must be global. Fortunately, no X * one yet requires the font routines to be re-entrant.) X */ Xstatic char *buildraster; /* raster being built */ Xstatic int buildsize; /* size of buildraster (bytes) */ X Xstatic struct bounds tempb; /* bounds used during buildraster */ Xstatic struct bounds ob; /* observed bounds */ X X/* X * Bit tables: `left' and `right' bits. lbits[b] has all the bits X * that are to the left of bit b set; rbits[b] has all the bits X * that are to the right of bit b set, as well as bit b itself. X */ Xstatic char lbits[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; Xstatic char rbits[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; X X/* X * The magic address `nullraster' is known in getgly() as a valid X * but empty raster, and changed there to NULL. A NULL return from X * drawchar indicates failure; we need something to distinguish the X * empty raster. X */ Xstatic char nullraster[1]; X X/* X * `Inline functions': X * -> convert a bit number to a byte number (round down); X * -> convert a number of bits to a number of bytes (round up); X * and convert a bit to a bit index. X */ X#define btoby(b) ((b) >> 3) X#define btonb(b) (((b) + 7) >> 3) X#define btobi(b) ((b) & 7) X X/* X * Helper function for getgly: build the raster, and compute its X * minimal bounding box. Called with `p' pointing past the backpointer X * field of the BOC command (i.e., at min_m or del_m). `abbrev' is true X * iff this was a BOC1. `globalb' are the global bounds from the GF file, X * whose name is pointed to by gfname. X */ Xstatic char * Xdrawchar(p, abbrev, globalb, gfname) X register char *p; X int abbrev; X struct bounds globalb; X char *gfname; X{ X register i32 m; /* m register (column) */ X register char *colp; /* pointer to byte corresponding to m */ X register int c; /* temporary */ X register i32 i; /* temporary */ X register int black; /* true when paint_switch==black */ X register i32 n; /* n register (row) */ X int stride; /* multiplier to convert linear to 2d array */ X int wrotethisrow; /* true iff we wrote in the current row */ X char *virtrast; /* virtual origin version of buildraster */ X int mustcopy; /* true if we must copy the built raster */ X struct bounds gb; /* bounds from the GF file */ X X /* get the bounds */ X if (abbrev) { X c = pgetbyte(p);/* del_m */ X gb.min_m = (gb.max_m = pgetbyte(p)) - c; X c = pgetbyte(p);/* del_n */ X gb.min_n = (gb.max_n = pgetbyte(p)) - c; X } else { X pGetLong(p, gb.min_m); X pGetLong(p, gb.max_m); X pGetLong(p, gb.min_n); X pGetLong(p, gb.max_n); X } X X /* X * Trim the GF bounds according to the global bounds. We X * use the trimmed values to allocate the build space. X */ X tempb = gb; X#define GB_ADJ(field, cmp) \ X if (tempb.field cmp globalb.field) \ X tempb.field = globalb.field X GB_ADJ(min_m, <); X GB_ADJ(max_m, >); X GB_ADJ(min_n, <); X GB_ADJ(max_n, >); X#undef GB_ADJ X X /* X * Compute the distance between rows (the number of bytes per X * column), then make sure there is room in the build space X * for [min_n..max_n] of these, possibly by allocating a new raster. X */ X stride = btonb(tempb.max_m - tempb.min_m + 1); X c = stride * (tempb.max_n - tempb.min_n + 1); X if (c <= 0) /* completely empty character */ X return (nullraster); X if (c > buildsize) { X if (buildraster != NULL) { X free(buildraster); buildraster = 0; X } X if ((buildraster = malloc(c)) == NULL) { X buildsize = 0; X return (NULL); X } X buildsize = c; X } X X /* X * If we are using an old raster that is too big, remember to X * scrunch it down later. X */ X mustcopy = buildsize > c; X X /* clear the raster to white */ X bzero(buildraster, c); X X /* X * Make a virtual origin raster pointer. The virtual origin is X * where raster[0][0] is, whether or not there is a raster[0][0]. X * Normally, this would be X * &buildraster[-gb.min_n * stride - btoby(gb.min_m)], X * but it is complicated by two things. Firstly, we would like X * n==max_n to be the bottommost point in the raster (low X * addresses), and n==min_n to be the topmost (high addresses). X * In other words, we need to reflect the n (Y) values about X * the X axis: negate them. Secondly, the raster we create X * must be `flush left'. That is, somewhere along its rows, X * bit 0x80 must be set at the left edge of one of its columns. X * We need to subtract away the minimum bit index before X * calculating bit values. This cannot really be done in X * advance, since we cannot address bits directly. X */ X virtrast = &buildraster[gb.max_n * stride]; X X /* X * Set up the bounds-trimming variables. The observed m bounds X * are kept offset by gb.min_m until we finish drawing the X * character. X */ X ob.min_m = tempb.max_m - gb.min_m + 1; X ob.max_m = tempb.min_m - gb.min_m - 1; X ob.min_n = tempb.max_n + 1; X ob.max_n = tempb.min_n - 1; X wrotethisrow = 0; X X#define FIX_N_BOUNDS() { \ X if (wrotethisrow) { \ X c = -n; /* recall that n is reflected about X axis */ \ X if (c < ob.min_n) \ X ob.min_n = c; \ X if (c > ob.max_n) \ X ob.max_n = c; \ X wrotethisrow = 0; \ X } \ X} X X /* X * Initialise state variables: m = min_m, n = max_n, X * paint_switch = white. X */ X m = 0; /* gb.min_m - gb.min_m */ X n = -gb.max_n; /* reflected */ X colp = &virtrast[n * stride]; Xif (colp != buildraster) Xpanic("gffont drawchar colp != buildraster"); X black = 0; X X /* X * Now interpret the character. X * `for (;;)' pushes everything off the right edge, alas. X */ Xmore: X c = pgetbyte(p); X if (GF_IsPaint(c)) /* faster? */ X goto paint; X switch (GF_OpLen(c)) { X X case GPL_NONE: X break; X X case GPL_UNS1: X i = pgetbyte(p); X break; X X case GPL_UNS2: X pGetWord(p, i); X break; X X case GPL_UNS3: X pGet3Byte(p, i); X break; X X case GPL_SGN4: X pGetLong(p, i); X break; X X default: X panic("gffont drawchar GF_OpLen(%d) = %d", c, GF_OpLen(c)); X /* NOTREACHED */ X } X X switch (GF_TYPE(c)) { X X case GT_PAINT0: Xpaint: X i = c - GF_PAINT_0; X /* FALLTHROUGH */ X X case GT_PAINT: X /* X * Paint `i' bits in the current row at columns [m..m+i). X */ X if (i && black) { X /* remember to adjust n bounds later */ X wrotethisrow = 1; X /* adjust minimum m bound */ X if (m < ob.min_m) X ob.min_m = m; X X /* X * Finish the partial byte at colp. There are 8-k X * bits to set to finish it, where k is the bit X * index value from m. If we need to set fewer X * than 8-k bits, set them now and skip the rest X * of this. X */ X c = 8 - btobi(m); X if (i < c) { /* cannot finish it off */ X *colp |= UnSign8(lbits[i]) >> btobi(m); X m += i; X } else { /* finish it off */ X *colp++ |= rbits[btobi(m)]; X i -= c; X m += c; X X /* X * Update m to reflect having written the X * remaining i bits, then write them. X * First write all the full bytes, then X * start a partial byte with whatever X * is left over, if anything. X */ X m += i; X i >>= 3; X while (--i >= 0) X *colp++ = 0xff; X *colp |= lbits[btobi(m)]; X } X X /* adjust maximum m bound */ X if (m > ob.max_m) X ob.max_m = m; X } else { X /* X * Add the bit index so that we round up whenever X * this fills the partial byte at colp. X */ X colp += (i + btobi(m)) >> 3; X m += i; X } X black = !black; X break; X X case GT_EOC: /* all done */ X FIX_N_BOUNDS(); X goto done; X X case GT_SKIP0: /* skip no rows */ X i = 0; X /* FALLTHROUGH */ X X case GT_SKIP: /* skip some rows, draw white */ X m = 0; X black = 0; X goto skip_or_new_row; X X case GT_NEW_ROW: /* next row near left col, draw black */ X m = c - GF_NEW_ROW_0; X black = 1; X i = 0; /* n offset is 1: skip no rows */ Xskip_or_new_row: X FIX_N_BOUNDS(); X n += i + 1; /* += because reflected */ X colp = &virtrast[n * stride + btoby(m)]; X break; X X case GT_XXX: /* special */ X p += i; X break; X X case GT_YYY: /* numspecial */ X break; X X case GT_NOP: /* dull */ X break; X X case GT_BOC: /* should not appear */ X case GT_BOC1: X case GT_CHAR_LOC: X case GT_CHAR_LOC0: X case GT_PRE: X case GT_POST: X case GT_POSTPOST: X case GT_UNDEF: X error(0, 0, "unexpected GF opcode %d", c); X error(1, 0, "bad GF file \"%s\"", gfname); X /* NOTREACHED */ X X default: X panic("gffont drawchar GF_TYPE(%d) = %d", c, GF_TYPE(c)); X /* NOTREACHED */ X } X goto more; X Xdone: X /* X * The observed bounds `m' values are both off by gb.min_m, so X * fix them now. CONSIDER ADJUSTING n HERE TOO X */ X ob.min_m += gb.min_m; X ob.max_m += gb.min_m; X X /* X * If we used too much memory for the raster, copy it now. X */ X if (mustcopy || tempb.min_n != ob.min_n || tempb.max_n != ob.max_n || X btonb(ob.max_m - ob.min_m + 1) != stride) X return (copyit()); X X /* X * If the left column bounds match, just move the raster in place. X */ X if (tempb.min_m == ob.min_m) { X p = buildraster; X buildraster = NULL; X buildsize = 0; X return (p); X } X X /* X * The raster must be copied, but only because it is not X * `left justified'. X * X * CONSIDER DEFERRING THIS PHASE UNTIL THE RASTER IS USED X */ X return (copyit()); X} X X/* X * Copy the built raster to newly allocated space. X * We may need to shift all the bits left as well. X */ Xchar * Xcopyit() X{ X register char *o, *p; X register int i, oldoff, newoff; X char *n; X X /* X * Compute the observed minimum stride. If it is zero or negative, X * there is no raster at all, else allocate just enough space X * to hold the new raster. X */ X newoff = btonb(ob.max_m - ob.min_m + 1); X if (newoff <= 0) X return (nullraster); Xif (ob.max_n < ob.min_n) Xpanic("gffont copyit max_n < min_n"); X n = malloc((unsigned) (newoff * (ob.max_n - ob.min_n + 1))); X if ((p = n) == NULL) X return (NULL); X X /* X * Compute the old stride. X */ X oldoff = btonb(tempb.max_m - tempb.min_m + 1); Xif (oldoff < newoff) Xpanic("gffont copyit oldoff < newoff"); X X /* X * Point at the old raster, then add the offset to the first X * written row, and then the offset to the first written column. X */ X o = buildraster; X o += (ob.max_n - tempb.max_n) * oldoff; X i = ob.min_m - tempb.min_m; X o += btoby(i); X X /* X * Now copy each row, doing shifting if required. X */ X if ((i = btobi(i)) != 0) { /* must shift, alas */ X register int r = 8 - i, j, k; X X oldoff -= newoff; X for (k = ob.max_n; k >= ob.min_n; k--) { X for (j = newoff; --j >= 0;) { X *p++ = *o++ << i; X p[-1] |= UnSign8(*o) >> r; X } X o += oldoff; X } X } else if (oldoff > newoff) { /* compressing columns */ X for (i = ob.max_n; i >= ob.min_n; i--) { X bcopy(o, p, newoff); X o += oldoff; X p += newoff; X } X } else /* just squeezing out extra rows */ X bcopy(o, p, newoff * (ob.max_n - ob.min_n + 1)); X X /* finally, return the copy */ X return (n); X} X X/* X * Obtain the specified range of glyphs. X */ Xstatic int Xgf_getgly(f, l, h) X register struct font *f; X int l, h; X{ X register struct glyph *g; X register struct char_loc *cl; X register char *p; X register i32 c; X register int i; X register i32 thisboc; X int abbrev; X struct gf_details *gd = ftogd(f); X X /* X * For each glyph, make sure there exists an instance of that X * character residue. Go find the actual glyph (which may be X * arbitrarily far down a chain of pointers) and get its info. X */ X for (cl = &gd->gd_cl[i = l]; i < h; i++, cl++) { X g = f->f_gly[i]; X thisboc = cl->cl_p; X X /* X * Screw around locating the character for real. X */ X while (thisboc != -1) { X p = gd->gd_base + thisboc; Xskip: X c = pgetbyte(p); X switch (GF_TYPE(c)) { X X case GT_XXX: X switch (GF_OpLen(c)) { X X case GPL_UNS1: X c = pgetbyte(p); X break; X X case GPL_UNS2: X pGetWord(p, c); X break; X X case GPL_UNS3: X pGet3Byte(p, c); X break; X X case GPL_SGN4: X pGetLong(p, c); X break; X X default: X panic("gf_getgly GF_OpLen(%d) = %d", X c, GF_OpLen(c)); X /* NOTREACHED */ X } X p += c; X goto skip; X X case GT_YYY: X p += 4; X goto skip; X X case GT_BOC: X abbrev = 0; X pGetLong(p, c); X break; X X case GT_BOC1: X abbrev = 1; X c = pgetbyte(p); X break; X X default: X error(0, 0, "GF code %d; I expected BOC", c); X error(1, 0, "bad GF file \"%s\"", f->f_path); X /* NOTREACHED */ X } X /* X * Found a BOC. If it is the right character, X * go handle it. X */ X if (c == i) X goto handleit; X if ((c & 255) != i) { X error(0, 0, "%d != %d mod 256", c, i); X error(1, 0, "Bad GF file \"%s\"", f->f_path); X } X /* X * Follow the backpointer. X */ X if (abbrev) X thisboc = -1; X else X pGetLong(p, thisboc); X } X X /* X * If we get here, the glyph is not valid after all. X */ X continue; X X /* X * The glyph is okay. Set it up. X */ Xhandleit: X g->g_flags = GF_VALID; X g->g_xescapement = cl->cl_dx; X g->g_yescapement = cl->cl_dy; X g->g_tfmwidth = cl->cl_w; X g -> g_rawtfmwidth = g -> g_tfmwidth; X if (!abbrev) X p += 4; /* skip backpointer */ X if ((p = drawchar(p, abbrev, gd->gd_gb, f->f_path)) == NULL) X return (-1); /* ??? */ X if (p == nullraster) X p = NULL; X /* set height &c based on observed bounds */ X g->g_height = ob.max_n - ob.min_n + 1; X g->g_width = ob.max_m - ob.min_m + 1; X g->g_yorigin = ob.max_n; X g->g_xorigin = -ob.min_m; X g->g_raster = p; X g->g_rotation = ROT_NORM; X } X return (0); X} X X/* X * Obtain rasters for the specified glyphs. We did this above, while X * adjusting the bounding boxes, so this routine should never get called. X */ Xstatic int Xgf_rasterise(f, l, h) X struct font *f; X int l, h; X{ X X panic("gf_rasterise(%s, %d, %d)", f->f_path, l, h); X} X X/* X * Discard the font details. X */ Xstatic Xgf_freefont(f) X struct font *f; X{ X struct gf_details *gd; X X if ((gd = ftogd(f)) != NULL) { X free(gd->gd_body); gd -> gd_body = 0; X free((char *) gd); gd = 0; X } X} END_OF_lib/gffont.c if test 22029 -ne `wc -c <lib/gffont.c`; then echo shar: \"lib/gffont.c\" unpacked with wrong size! fi chmod +x lib/gffont.c # end of overwriting check fi if test -f lib/gripes.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/gripes.c\" else echo shar: Extracting \"lib/gripes.c\" \(3046 characters\) sed "s/^X//" >lib/gripes.c <<'END_OF_lib/gripes.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/gripes.c,v 1.3 89/02/13 14:31:11 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Common errors (`gripes'). X */ X X#include <stdio.h> X#include "types.h" X Xstatic char areyousure[] = "Are you sure this is a DVI file?"; X Xextern errno; X X/* X * DVI file requests a font it never defined. X */ XGripeNoSuchFont(n) X i32 n; X{ X X error(0, 0, "DVI file wants font %ld, which it never defined", n); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * DVI file redefines a font. X */ XGripeFontAlreadyDefined(n) X i32 n; X{ X X error(0, 0, "DVI file redefines font %ld", n); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Unexpected DVI opcode. X */ XGripeUnexpectedOp(s) X char *s; X{ X X error(0, 0, "unexpected %s", s); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Missing DVI opcode. X */ XGripeMissingOp(s) X char *s; X{ X X error(0, 0, "missing %s", s); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Cannot find DVI postamble. X */ XGripeCannotFindPostamble() X{ X X error(0, 0, "cannot find postamble"); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Inconsistent DVI value. X */ XGripeMismatchedValue(s) X char *s; X{ X X error(0, 0, "mismatched %s", s); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Undefined DVI opcode. X */ XGripeUndefinedOp(n) X int n; X{ X X error(0, 0, "undefined DVI opcode %d"); X error(1, 0, areyousure); X /* NOTREACHED */ X} X X/* X * Cannot allocate memory. X */ XGripeOutOfMemory(n, why) X int n; X char *why; X{ X X error(1, errno, "ran out of memory allocating %d bytes for %s", X n, why); X /* NOTREACHED */ X} X X/* X * Cannot get a font. X * RETURNS TO CALLER X */ XGripeCannotGetFont(name, mag, dsz, dev, fullname) X char *name; X i32 mag, dsz; X char *dev, *fullname; X{ X int e = errno; X char scale[40]; X X if (mag == dsz) /* no scaling */ X scale[0] = 0; X else X (void) sprintf(scale, " scaled %d", X (int) ((double) mag / (double) dsz * 1000.0 + .5)); X X error(0, e, "cannot get font %s%s", name, scale); X if (fullname) X error(0, 0, "(wanted, e.g., \"%s\")", fullname); X else { X if (dev) X error(1, 0, "(there are no fonts for the %s engine!)", X dev); X else X error(1, 0, "(I cannot find any fonts!)"); X /* NOTREACHED */ X } X} X X/* X * Font checksums do not match. X * RETURNS TO CALLER X */ XGripeDifferentChecksums(font, tfmsum, fontsum) X char *font; X i32 tfmsum, fontsum; X{ X X error(0, 0, "\ XWARNING: TeX and I have different checksums for font\n\ X\t\"%s\"\n\ X\tPlease notify your TeX maintainer\n\ X\t(TFM checksum = 0%o, my checksum = 0%o)", X font, tfmsum, fontsum); X} X X/* X * A font, or several fonts, are missing, so no output. X */ XGripeMissingFontsPreventOutput(n) X int n; X{ X static char s[2] = {'s', 0}; X X error(1, 0, "%d missing font%s prevent%s output (sorry)", n, X n > 1 ? s : &s[1], n == 1 ? s : &s[1]); X /* NOTREACHED */ X} END_OF_lib/gripes.c if test 3046 -ne `wc -c <lib/gripes.c`; then echo shar: \"lib/gripes.c\" unpacked with wrong size! fi chmod +x lib/gripes.c # end of overwriting check fi if test -f lib/magfactor.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/magfactor.c\" else echo shar: Extracting \"lib/magfactor.c\" \(869 characters\) sed "s/^X//" >lib/magfactor.c <<'END_OF_lib/magfactor.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Convert a magnification factor to floating point. This is used in X * conjunction with the FONT_SLOP stuff to try to get the file names X * right, and may also be used by DVI reading programs to get slightly X * more accurate values for (mag/1000.0). X */ Xdouble XDMagFactor(mag) X int mag; X{ X X switch (mag) { X X case 1095: /* stephalf */ X return (1.095445); X X case 1315: /* stepihalf */ X return (1.314534); X X case 2074: /* stepiv */ X return (2.0736); X X case 2488: /* stepv */ X return (2.48832); X X case 2986: /* stepiv */ X return (2.985984); X X default: /* remaining mags have been ok */ X return ((double) mag / 1000.); X } X /* NOTREACHED */ X} END_OF_lib/magfactor.c if test 869 -ne `wc -c <lib/magfactor.c`; then echo shar: \"lib/magfactor.c\" unpacked with wrong size! fi chmod +x lib/magfactor.c # end of overwriting check fi echo shar: End of archive 4 \(of 6\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 5 (of 6)." # Contents: lib/pkfont.c lib/pxlfont.c # Wrapped by montnaro@sprite on Sat Nov 11 17:13:32 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f lib/pkfont.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/pkfont.c\" else echo shar: Extracting \"lib/pkfont.c\" \(18209 characters\) sed "s/^X//" >lib/pkfont.c <<'END_OF_lib/pkfont.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/pkfont.c,v 1.9 89/02/13 14:31:13 grunwald Exp Locker: grunwald $"; X#endif X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include "types.h" X#include "font.h" X#include "num.h" X X/* X * PK font operations. X * X * The spelling `nybble' is a concession to the authors of the PK format. X */ X Xstatic pk_read(); Xstatic scan_characters(); Xstatic pk_getgly(); Xstatic pk_rasterise(); Xstatic pk_freefont(); X Xstruct fontops pkops = X { "pk", 1.0, pk_read, pk_getgly, pk_rasterise, pk_freefont }; X X/* X * Local info. X */ X X/* X * Commands. X */ X#define PK_XXX1 240 /* 1 byte special */ X#define PK_XXX2 241 /* 2 byte special */ X#define PK_XXX3 242 /* 3 byte special */ X#define PK_XXX4 243 /* 4 byte special */ X#define PK_YYY 244 /* METAFONT numspecial */ X#define PK_POST 245 /* marks postamble */ X#define PK_NO_OP 246 /* do nothing */ X#define PK_PRE 247 /* marks preamble */ X /* 248..255 undefined */ X#define PK_IsUndef(c) ((c) > PK_PRE) X X#define PK_ID 89 /* marks this brand of PK file */ X X/* X * Information about a character packet. X */ Xstruct cp { X char *cp_packet; /* the beginning of the packet */ X int cp_type; /* decoded pre type, see below */ X}; X X#define CP_SHORT 0 /* short preamble */ X#define CP_EXT_SHORT 1 /* extended short preamble */ X#define CP_LONG 2 /* long preamble */ X X/* X * The PK details include: X * -> a pointer to the next byte to fetch; X * -> the most recent byte fetched (when we are using nextnyb()); X * -> a flag indicating that we have used nybble 0 (bits 4..7) and X * should use nybble 1 next; X * -> the base address of the memory allocated for the PK file; X * -> the value of dyn_f (during character translation); X * -> the repeat count (during rasterisation); X * -> the lowest glyph number that is legal; X * -> the highest glyph number that is legal; X * -> glyph instructions for the standard glyphs; X * -> glyph instructions for more (nonstandard) glyphs; X * and the number of glyphs left unrasterised. X */ Xstruct pk_details { X char *pk_ptr; /* next byte to fetch */ X int pk_c; /* most recent byte fetched, if nybbling */ X int pk_1nyb; /* true => nybble 1 is next (bits 0..3) */ X char *pk_base; /* base of allocated memory */ X int pk_dyn_f; /* the dyn_f value */ X int pk_repeat; /* the repeat count */ X int pk_minc; /* minimum character value */ X int pk_maxc; /* maximum character value */ X#define MAXSTD 256 /* maximum `standard' character value */ X int pk_gleft; /* number of valid glyphs left uninterpreted */ X struct cp pk_cpack[MAXSTD]; /* for characters in [0..MAXSTD) */ X struct cp *pk_morec; /* for characters in [MAXSTD..maxc] */ X}; X X/* X * Fetch the next byte from the PK file. X */ X#define nextbyte(pk) pgetbyte((pk)->pk_ptr) X X/* X * PK packed number encoding. Nybbles in [1..dyn_f] represent themselves. X * Values in (dyn_f..13] are two-nybble values, and represent values X * dyn_f+1 through (13-dyn_f+1)*16+15. Zero marks a long number; 14 and X * 15 specify repeat counts instead (which are another packed number). X * Note that we cannot represent the number zero as a packed number. X */ X#define PK_LONGNUM 0 /* a `long number' */ X#define PK_REPEAT 14 /* set repeat count */ X#define PK_REPEAT1 15 /* set repeat to 1 */ X X/* X * Get the next nybble. This is an expression rendition of X * if (--pk->pk_1nyb < 0) { X * pk->pk_1nyb = 1; X * pk->pk_c = nextbyte(pk); X * return (pk->pk_c >> 4); X * } else X * return (pk->pk_c & 0xf); X */ X#define nextnyb(f) \ X (--(pk)->pk_1nyb < 0 ? \ X ((pk)->pk_1nyb = 1, ((pk)->pk_c = nextbyte(pk)) >> 4) : \ X (pk)->pk_c & 0xf) X X/* X * Get the pk_details from font f. X */ X#define ftopk(f) ((struct pk_details *) (f)->f_details) X Xextern int errno; Xchar *malloc(); X X/* X * PK subroutines. X */ X X/* X * Unpack a packed number. X */ Xstatic int Xpk_unpack(pk) X register struct pk_details *pk; X{ X register int i, j; X Xtop: X if ((i = nextnyb(pk)) == PK_LONGNUM) { X#if PK_LONGNUM != 0 /* this may be silly, but . . . */ X i = 0; X#endif X /* X * Expand a long number. There are one fewer leading X * zeros than there are nonzero digits to obtain, so X * count up the leading zeros, add one, and get that X * many digits. (The `digits' are hexadecimal values.) X */ X do { X i++; X } while ((j = nextnyb(pk)) == 0); X while (--i >= 0) { X j <<= 4; X j += nextnyb(pk); X } X return (j - 15 + (13 - pk->pk_dyn_f) * 16 + pk->pk_dyn_f); X } X if (i <= pk->pk_dyn_f) X return (i); X if (i < PK_REPEAT) X return ((i - pk->pk_dyn_f - 1) * 16 + nextnyb(pk) + X pk->pk_dyn_f + 1); X X /* X * There is a repeat count, either one or a packed number. X * Get it first, then start over. (tail recursion) X */ X if (i == PK_REPEAT) X pk->pk_repeat = pk_unpack(pk); X else X pk->pk_repeat = 1; X goto top; X} X X/* X * Skip over special commands (PK_XXX?, PK_YYY). X */ Xstatic Xskip_specials(f) X struct font *f; X{ X struct pk_details *pk = ftopk(f); X register char *p = pk->pk_ptr; X register i32 i; X X for (;;) { X int tmp; X tmp = UnSign8(*p); X p++; X switch (tmp) { X X case PK_XXX1: X i = UnSign8(*p); X p++; X p += i; X break; X X case PK_XXX2: X pGetWord(p, i); X p += i; X break; X X case PK_XXX3: X pGet3Byte(p, i); X p += i; X break; X X case PK_XXX4: X pGetLong(p, i); X p += i; X break; X X case PK_YYY: X p += 4; X break; X X case PK_NO_OP: X break; X X case PK_PRE: X error(1, 0, "unexpected PK_PRE in \"%s\"", f->f_path); X break; X X default: X p--; X if (PK_IsUndef(UnSign8(*p))) X error(1, 0, "invalid opcode %d in \"%s\"", X f->f_path); X pk->pk_ptr = p; X return; X } X } X} X X/* X * Read a PK file. X */ Xstatic int Xpk_read(f) X register struct font *f; X{ X register struct pk_details *pk; X register char *p; X int i, fd; X struct stat st; X char *reason; X X if ((fd = open(f->f_path, 0)) < 0) X return (-1); X pk = NULL; /* prepare for failure */ X reason = NULL; X (void) fstat(fd, &st); X if (st.st_size < 4) { /* ??? */ X reason = "file is too small"; X goto fail; X } X if ((pk = (struct pk_details *) malloc(sizeof (*pk))) == NULL) X goto fail; X pk->pk_morec = NULL; X if ((pk->pk_base = malloc(st.st_size)) == NULL) X goto fail; X if (read(fd, pk->pk_base, st.st_size) != st.st_size) X goto fail; X pk->pk_ptr = pk->pk_base; X if (nextbyte(pk) != PK_PRE) { X reason = "file does not begin with PK_PRE"; X goto fail; X } X if (nextbyte(pk) != PK_ID) { X reason = "bad PK_ID"; X goto fail; X } X i = nextbyte(pk); X p = pk->pk_ptr + i; /* skip comment */ X pGetLong(p, f -> f_design_size); X pGetLong(p, f -> f_checksum); X pGetLong(p, f -> f_hppp); X pGetLong(p, f -> f_vppp); X pk->pk_ptr = p; X/* DEBUG */ X f->f_details = (char *) pk; X X /* scan the characters, fail if necessary */ X if (scan_characters(f, &reason)) X goto fail; X X /* ignore the postamble */ X X /* COMPRESS pk->pk_base DATA? */ X X if (FontHasGlyphs(f, pk->pk_minc, pk->pk_maxc + 1)) X goto fail; X (void) close(fd); X return (0); X Xfail: X if (reason) { X error(0, 0, "%s", reason); X error(0, 0, "(are you sure %s is a PK file?)", f->f_path); X errno = 0; X } X if (pk != NULL) { X if (pk->pk_base != NULL) { X free(pk->pk_base); pk -> pk_base = 0; X } X if (pk->pk_morec != NULL) { X free((char *) pk->pk_morec); pk -> pk_morec = 0; X } X free((char *) pk); pk = 0; X } X (void) close(fd); X return (-1); X} X X/* X * Scan through the characters in the PK file, and set the offsets X * and preamble types for each of the character packets. X */ Xstatic int Xscan_characters(f, reason) X struct font *f; X char **reason; X{ X register struct pk_details *pk = ftopk(f); X register i32 c, pl; X register char *p; X register struct cp *cp; X int type; X X#ifdef lint X /* reason will be used someday ... I think */ X reason = reason; X#endif X X /* set up the minimisers and the glyph count */ X pk->pk_minc = 1; X pk->pk_maxc = 0; X pk->pk_gleft = 0; X X /* mark all character packets as untouched */ X for (cp = pk->pk_cpack, c = MAXSTD; --c >= 0; cp++) X cp->cp_packet = NULL; X X /* X * Loop through the packets until we reach a POST, skipping X * the glyph instructions themselves after each definition, X * and specials (if any) before each. X */ X for (;; pk->pk_ptr = p + pl) { X skip_specials(f); X p = pk->pk_ptr; X if ((c = pgetbyte(p)) == PK_POST) X break; /* whoops, done after all */ X X /* X * Look at the low three bits to decide preamble size. X * A value of 7 is a `long preamble'; 4, 5, and 6 are X * `extended short preambles'; and 0, 1, 2, and 3 are X * `short preambles'. X * X * We ignore most of the preamble, reading only the X * `packet length' and the character code at this time. X */ X switch (c & 7) { X X case 7: /* long */ X type = CP_LONG; X pGetLong(p, pl); X pGetLong(p, c); X break; X X case 6: X case 5: X case 4: /* extended short */ X type = CP_EXT_SHORT; X pGetWord(p, pl); X pl += (c & 3) << 16; X c = pgetbyte(p); X break; X X default: /* short */ X type = CP_SHORT; X pl = ((c & 3) << 8) + pgetbyte(p); X c = pgetbyte(p); X break; X } X X if (c >= MAXSTD) { X /* X * BEGIN XXX - should alloc pk_morec, but is hard X * and not now useful X */ X error(0, 0, "ignoring character %d in \"%s\"", X f->f_path); X error(0, 0, "because some darn programmer was lazy!"); X continue; X /* END XXX */ X } else X cp = &pk->pk_cpack[c]; X X cp->cp_packet = pk->pk_ptr; X cp->cp_type = type; X X /* adjust range */ X if (c < pk->pk_minc) X pk->pk_minc = c; X if (c > pk->pk_maxc) X pk->pk_maxc = c; X X pk->pk_gleft++; /* and count the glyph */ X } X return (0); /* no problems */ X} X X/* X * Obtain the specified range of glyphs. X */ Xstatic int Xpk_getgly(f, l, h) X register struct font *f; X int l, h; X{ X register struct pk_details *pk = ftopk(f); X register char *p; X register struct glyph *g; X register int i; X register struct cp *cp; X X if (pk == NULL) X panic("pk_getgly(%s)", f->f_path); X for (i = l; i < h; i++) { X if (i < MAXSTD) X cp = &pk->pk_cpack[i]; X else { X if (i > pk->pk_maxc) X panic("pk_getgly(%s, %d)", f->f_path, i); X cp = &pk->pk_morec[i - MAXSTD]; X } X p = cp->cp_packet; X if (p == NULL) /* glyph is not valid */ X continue; X g = f->f_gly[i]; X p++; /* skip flag */ X switch (cp->cp_type) { X X case CP_LONG: X p += 8; /* skip packet len, character code */ X pGetLong(p, g->g_tfmwidth); X g -> g_rawtfmwidth = g -> g_tfmwidth; X pGetLong(p, g->g_xescapement); X pGetLong(p, g->g_yescapement); X pGetLong(p, g->g_width); X pGetLong(p, g->g_height); X pGetLong(p, g->g_xorigin); X pGetLong(p, g->g_yorigin); X break; X X case CP_EXT_SHORT: X p += 3; /* skip packet len, character code */ X pGet3Byte(p, g->g_tfmwidth); X g -> g_rawtfmwidth = g -> g_tfmwidth; X { i32 dm; pGetWord(p, dm); X g->g_xescapement = dm << 16; } X g->g_yescapement = 0; X pGetWord(p, g->g_width); X pGetWord(p, g->g_height); X pGetWord(p, g->g_xorigin); X g->g_xorigin = Sign16(g->g_xorigin); X pGetWord(p, g->g_yorigin); X g->g_yorigin = Sign16(g->g_yorigin); X break; X X case CP_SHORT: X p += 2; /* skip packet len, character code */ X pGet3Byte(p, g->g_tfmwidth); X g -> g_rawtfmwidth = g -> g_tfmwidth; X g->g_xescapement = pgetbyte(p) << 16; X g->g_yescapement = 0; X g->g_width = pgetbyte(p); X g->g_height = pgetbyte(p); X g->g_xorigin = pgetbyte(p); X g->g_xorigin = Sign8(g->g_xorigin); X g->g_yorigin = pgetbyte(p); X g->g_yorigin = Sign8(g->g_yorigin); X break; X } X g->g_flags = GF_VALID; X g->g_un.g_details = p; X } X return (0); X} X X/* X * Bit masks for pk_rasterise(). X */ Xstatic char bmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; Xstatic char rbits[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; X X/* X * Obtain rasters for the specified glyphs. X */ Xstatic int Xpk_rasterise(f, l, h) X struct font *f; X int l, h; X{ X struct pk_details *pk0; X struct glyph *g0; X char *p0, *rp0; X int flag, ii; X X if ((pk0 = ftopk(f)) == NULL) X panic("pk_rasterise(%s)", f->f_path); X for (ii = l; ii < h; ii++) { X { X register struct glyph *g; X register char *p; X register int i; X X g = f->f_gly[i = ii]; X if ((g->g_flags & GF_VALID) == 0) X continue; /* no glyph */ X if (!HASRASTER(g)) /* empty raster */ X goto done; X X /* X * Allocate a raster. X */ X rp0 = malloc(((g->g_width + 7) >> 3) * g->g_height); X if ((g->g_raster = rp0) == NULL) X return (-1);/* ??? */ X g->g_rotation = ROT_NORM; X X /* X * Pick up the flag byte, then start at the real X * packet, which we saved in g_details. X */ X if (i < MAXSTD) X p = pk0->pk_cpack[i].cp_packet; X else X p = pk0->pk_morec[i - MAXSTD].cp_packet; X flag = UnSign8(*p); X p0 = g->g_un.g_details; X g0 = g; X } X if ((pk0->pk_dyn_f = flag >> 4) == 14) { X register char *p = p0, *rp = rp0; X register int j, ls, rs, i, w; X X /* X * Expand a bit-packed representation. X * If we get lucky, it is byte packed and X * we can just copy it over. X */ X i = g0->g_height; X j = g0->g_width; X if ((j & 7) == 0) { X bcopy(p, rp, i * (j >> 3)); X goto done; X } X X /* X * No such luck. X */ X w = j; X ls = 0; X while (--i >= 0) { X X /* IF THE COMPILER IS BROKEN, FIX IT */ X#ifdef BROKEN_COMPILER_HACKS X /* have to work on the compiler someday */ X rs = ls - 8; X#else X rs = 8 - ls; X#endif X /* know j always != 8 */ X for (j = w; j > 8; j -= 8) { X X /* IF THE COMPILER IS BROKEN, FIX IT */ X#ifdef BROKEN_COMPILER_HACKS X asm(" movb (r11)+,r0"); X asm(" ashl r8,r0,r0"); X asm(" movb r0,(r10)"); X asm(" movzbl (r11),r0"); X asm(" ashl r7,r0,r0"); X asm(" bisb2 r0,(r10)+"); X#else X *rp = *p << ls; X p++; X *rp |= UnSign8(*p) >> rs; X rp++; X#endif X } X X /* X * We need j more bits; there are rs X * bits available at *p. Ask for j, X * which gets min(j, rs). X */ X X /* IF THE COMPILER IS BROKEN, FIX IT */ X X#ifdef BROKEN_COMPILER_HACKS X /*void*/; /* avoid asm() label botch */ X asm(" movb (r11),r0"); X asm(" ashl r8,r0,r0"); X asm(" mcomb _bmask[r9],r1"); X asm(" bicb2 r1,r0"); X asm(" movb r0,(r10)+"); X#else X *rp++ = (*p << ls) & bmask[j]; X#endif X /* account for j bits */ X ls += j; ls &= 7; X /* then adjust j based on rs */ X X /* IF THE COMPILER IS BROKEN, FIX IT */ X#ifdef BROKEN_COMPILER_HACKS X j += rs; X#else X j -= rs; X#endif X /* still need j more bits */ X if (j < 0) /* got them all */ X continue; X p++; X if (j == 0) /* there were just enough */ X continue; X /* take j more bits */ X X /* IF THE COMPILER IS BROKEN, FIX IT */ X#ifdef BROKEN_COMPILER_HACKS X /*void*/; /* avoid asm() label botch */ X asm(" mcomb _bmask[r9],r0"); X asm(" bicb3 r0,(r11),r0"); X asm(" movzbl r0,r0"); X asm(" ashl r7,r0,r0"); X asm(" bisb2 r0,-1(r10)"); X#else X rp[-1] |= UnSign8(*p & bmask[j]) >> rs; X#endif X } X } else { X register struct pk_details *pk = pk0; X register int on = flag & 8 ? 0xff : 0; X register char *rowp; /* pointer into this row */ X register int j; /* trimmed run count */ X register int k; /* misc */ X register int b; /* bit index in current col */ X register int i; /* run count */ X register int colsleft; /* columns left this row */ X register int rowsleft; /* rows left */ X static char *row; /* a one-row buffer */ X static int rowsize; /* and its size in bytes */ X int wb; /* row width in bytes */ X X wb = (g0->g_width + 7) >> 3; X if (rowsize < wb) { /* get more row space */ X if (row) { X free(row); row = 0; X } X /* keep a slop byte */ X row = malloc((unsigned) (wb + 1)); X if (row == NULL) X return (-1); /* ??? */ X rowsize = wb; X } X bzero(row, wb); X rowsleft = g0->g_height; X colsleft = g0->g_width; X pk->pk_repeat = 0; X pk->pk_ptr = p0; X pk->pk_1nyb = 0; /* start on nybble 0 */ X rowp = row; X b = 0; X while (rowsleft > 0) { /* do all rows */ X /* EXPAND IN LINE? */ X i = pk_unpack(pk); X /* X * Work until the run count is exhausted X * (or at least pretty tired). X * X * (Okay, so the joke is stolen!) X */ X while ((j = i) > 0) { X /* X * If the count is more than the X * rest of this row, trim it down. X */ X if (j > colsleft) X j = colsleft; X i -= j; /* call them done */ X /* X * We need k=8-b bits to finish X * up the current byte. If we X * can finish it, do so; the proper X * bits to set are in rbits[k]. X */ X if (j >= (k = 8 - b)) { X j -= k; X colsleft -= k; X *rowp++ |= on & rbits[k]; X b = 0; X } X /* X * Set any full bytes. X */ X while (j >= 8) { X *rowp++ = on; X j -= 8; X colsleft -= 8; X } X /* X * Finally, begin a new byte, or X * add to the current byte, with X * j more bits. We know j <= 8-b. X * (If j==0, we may be writing on X * our slop byte, which is why we X * keep one around....) X */ Xif (j > 8-b) panic("pk_rasterise j>8-b"); X *rowp |= (on & bmask[j]) >> b; X colsleft -= j; X b += j; b &= 7; X if (colsleft == 0) { X pk->pk_repeat++; X rowsleft -= pk->pk_repeat; X while (--pk->pk_repeat >= 0) { X bcopy(row, rp0, wb); X rp0 += wb; X } Xif (rowsleft == 0 && i) panic("pk_rasterise leftover bits"); X pk->pk_repeat = 0; X rowp = row; X colsleft = g0->g_width; X bzero(row, wb); X b = 0; X } X } X on = 0xff - on; X } X } X Xdone: X /* X * Successfully converted another glyph. X */ X pk0->pk_gleft--; X } X Xif (pk0->pk_gleft < 0) Xpanic("%s: gleft==%d", f->f_path, pk0->pk_gleft); X if (pk0->pk_gleft == 0) { X free(pk0->pk_base); pk0 -> pk_base = 0; X if (pk0->pk_morec != NULL) { X free((char *) pk0->pk_morec); pk0 -> pk_morec = 0; X } X free((char *) pk0); pk0 = 0; X f->f_details = NULL; X } X return (0); X} X X/* X * Discard the font details. X */ Xstatic Xpk_freefont(f) X struct font *f; X{ X register struct pk_details *pk = ftopk(f); X X if (pk != NULL) { X free(pk->pk_base); pk -> pk_base = 0; X if (pk->pk_morec != NULL) { X free((char *) pk->pk_morec); (char *) pk->pk_morec = 0; X } X free((char *) pk); (char *) pk = 0; X } X} END_OF_lib/pkfont.c if test 18209 -ne `wc -c <lib/pkfont.c`; then echo shar: \"lib/pkfont.c\" unpacked with wrong size! fi chmod +x lib/pkfont.c # end of overwriting check fi if test -f lib/pxlfont.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/pxlfont.c\" else echo shar: Extracting \"lib/pxlfont.c\" \(6872 characters\) sed "s/^X//" >lib/pxlfont.c <<'END_OF_lib/pxlfont.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/pxlfont.c,v 1.4 89/02/13 14:31:16 grunwald Exp Locker: grunwald $"; X#endif X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <errno.h> X#include "types.h" X#include "font.h" X#include "fio.h" X X/* X * PXL font operations. X */ X Xstatic pxl_read(); Xstatic pxl_getgly(); Xstatic pxl_rasterise(); Xstatic pxl_freefont(); X X Xstruct fontops pxlops = X { "pxl", 5.0, pxl_read, pxl_getgly, pxl_rasterise, pxl_freefont }; X X/* X * Local info. X */ X X#define PXLID 1001 /* ID denoting PXL files */ X#define TAILSIZE (517 * 4) /* size of pxl tail info */ X X/* X * pc describes one PXL character information block. X */ Xstruct pc { X i16 pc_width; /* character width (pixels) */ X i16 pc_height; /* character height (pixels) */ X i16 pc_xoffset; /* X offset of reference point */ X i16 pc_yoffset; /* Y offset of reference point */ X i32 pc_rastoff; /* raster offset */ X i32 pc_TFMwidth; /* TFM width (FIXes) */ X}; X X/* X * pxl_details are the PXL-specific font details. X * X * We keep track of the number of characters converted to internal X * glyph form, and when all have been done, we discard the now- X * useless details. X */ Xstruct pxl_details { X int pd_nconv; /* number of characters converted */ X char *pd_ras; /* raster space, until converted */ X struct pc pd_pc[128]; /* `font directory' */ X}; X X/* X * Get the pxl_details from font f. X */ X#define ftopd(f) ((struct pxl_details *) (f)->f_details) X Xextern errno; Xchar *malloc(); X X/* X * Read a PXL file. X */ Xstatic int Xpxl_read(f) X struct font *f; X{ X register struct pxl_details *pd; X register FILE *fp; X register struct pc *pc; X register int i; X int fd, saverr; X i32 pxlid; X struct stat st; X X if ((fd = open(f->f_path, 0)) < 0) X return (-1); X X fp = NULL; X if ((pd = (struct pxl_details *) malloc(sizeof (*pd))) == 0) X goto fail; X pd->pd_ras = 0; X X /* X * There should be 4n bytes, with an absolute minimum of TAILSIZE+4 X * (+4 for the initial PXLID). X */ X (void) fstat(fd, &st); X if ((st.st_size & 3) != 0 || st.st_size < (TAILSIZE + 4)) { X errno = EINVAL; X goto fail; X } X X /* X * Set up the raster pointer (if we need rasters). X */ X if (f->f_flags & FF_RASTERS) { X i = st.st_size - (TAILSIZE + 4); X if (i != 0) { X if ((pd->pd_ras = malloc((unsigned) i)) == 0) X goto fail; X (void) lseek(fd, 4L, 0); X if (read(fd, pd->pd_ras, i) != i) X goto fail; X } X } X X /* X * Read the glyph information. X */ X errno = 0; /* try to make errno meaningful */ X if ((fp = fdopen(fd, "r")) == NULL) { X if (errno == 0) X errno = EMFILE; X goto fail; X } X (void) fseek(fp, (long) -TAILSIZE, 2); X for (i = 128, pc = pd->pd_pc; --i >= 0; pc++) { X fGetWord(fp, pc->pc_width); X fGetWord(fp, pc->pc_height); X fGetWord(fp, pc->pc_xoffset); X fGetWord(fp, pc->pc_yoffset); X fGetLong(fp, pc->pc_rastoff); X fGetLong(fp, pc->pc_TFMwidth); X } X f->f_checksum = GetLong(fp); X (void) GetLong(fp); /* mag */ X f -> f_design_size = GetLong(fp); /* designsize */ X (void) GetLong(fp); /* dirpointer */ X pxlid = GetLong(fp); X if (pxlid != PXLID) X error(0, 0, "Warning: strange PXL id (%d) in \"%s\"", X pxlid, f->f_path); X X f->f_details = (char *) pd; X if (FontHasGlyphs(f, 0, 128)) X goto fail; X (void) fclose(fp); X pd->pd_nconv = 0; X return (0); X Xfail: X saverr = errno; X if (pd) { X if (pd->pd_ras) { X free(pd->pd_ras); pd->pd_ras = 0; X } X free((char *) pd); (char *) pd = 0; X } X if (fp) X (void) fclose(fp); X else X (void) close(fd); X errno = saverr; X return (-1); X} X X/* X * Obtain the specified range of glyphs. X */ Xstatic int Xpxl_getgly(f, l, h) X register struct font *f; X int l; X register int h; X{ X register struct glyph *g; X register struct pc *pc; X register int i; X struct pxl_details *pd; X X if ((pd = ftopd(f)) == NULL) X error(1, 0, "pxl_getgly details==0: cannot happen"); X /* X * By definition, all 128 glyphs are valid. Just copy the X * PXL information. X */ X for (pc = &pd->pd_pc[i = l]; i < h; i++, pc++) { X g = f->f_gly[i]; X g->g_flags = GF_VALID; X g->g_height = pc->pc_height; X g->g_width = pc->pc_width; X g->g_yorigin = pc->pc_yoffset; X g->g_xorigin = pc->pc_xoffset; X g->g_tfmwidth = pc->pc_TFMwidth; X g -> g_rawtfmwidth = g -> g_tfmwidth; X } X return (0); X} X X/* X * Helper function for rasterise: return a pointer to a converted X * (malloc()ed and minimised) raster. X */ Xstatic char * Xmakeraster(h, w, rp) X register int h, w; X register char *rp; X{ X register char *cp; X register int i, o; X char *rv; X X /* X * The height and width values are in bits. Convert width to X * bytes, rounding up. The raw raster (at rp) is almost what X * we want, but not quite: it has `extra' bytes at the end of X * each row, to pad out to a multiple of four bytes. X */ X w = (w + 7) >> 3; X o = (4 - w) & 3; /* offset (number of `extra' bytes) */ X if ((cp = malloc((unsigned) (h * w))) == NULL) X return (NULL); X if (o == 0) { X /* X * The raster fits exactly; just copy it to the allocated X * memory space. (We must copy anyway, so that glyphs X * can be freed, e.g., after rotation.) X */ X bcopy(rp, cp, h * w); X return (cp); X } X rv = cp; X while (--h >= 0) { X /* X * Copy each row, then skip over the extra stuff. X */ X for (i = w; --i >= 0;) X *cp++ = *rp++; X rp += o; X } X return (rv); X} X X/* X * Obtain rasters for the specified glyphs. X */ Xstatic int Xpxl_rasterise(f, l, h) X register struct font *f; X int l; X register int h; X{ X register struct glyph *g; X register struct pc *pc; X register int i; X register struct pxl_details *pd; X X if ((pd = ftopd(f)) == NULL) X error(1, 0, "pxl_rasterise details==0: cannot happen"); X if (pd->pd_ras == NULL) X error(1, 0, "pxl_rasterise pd_ras==NULL: cannot happen"); X for (pc = &pd->pd_pc[i = l]; i < h; i++, pc++) { X g = f->f_gly[i]; X if (pc->pc_rastoff == 0) { X /* X * g should not claim a raster, since it has none. X */ X if (HASRASTER(g)) X error(1, 0, "bad PXL glyph %d in \"%s\"", X g->g_index, f->f_path); X } else { X g->g_raster = makeraster(pc->pc_height, pc->pc_width, X pd->pd_ras + ((pc->pc_rastoff - 1) << 2)); X if (g->g_raster == NULL) X return (-1); /* ??? */ X g->g_rotation = ROT_NORM; X } X } X X /* X * If we have converted all the characters, dump the X * pre-conversion rasters. In fact, dump everything. X */ X pd->pd_nconv += h - l; X if (pd->pd_nconv == 128) { X free(pd->pd_ras); pd->pd_ras = 0; X free((char *) pd); (char *) pd = 0; X f->f_details = NULL; X } X return (0); X} X X/* X * Discard the font details. X */ Xstatic Xpxl_freefont(f) X struct font *f; X{ X struct pxl_details *pd; X X if ((pd = ftopd(f)) != NULL) { X if (pd->pd_ras != NULL) { X free(pd->pd_ras); pd->pd_ras = 0; X } X free((char *) pd); (char *) pd = 0; X } X} END_OF_lib/pxlfont.c if test 6872 -ne `wc -c <lib/pxlfont.c`; then echo shar: \"lib/pxlfont.c\" unpacked with wrong size! fi chmod +x lib/pxlfont.c # end of overwriting check fi echo shar: End of archive 5 \(of 6\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
montnaro@sprite.crd.ge.com (Skip Montanaro) (11/14/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 6)." # Contents: lib/Makefile lib/rotate.c lib/scaletfm.c lib/scanpost.c # lib/search.c lib/seek.c lib/split.c lib/strsave.c lib/tfm.c # lib/tfmfont.c # Wrapped by montnaro@sprite on Sat Nov 11 17:13:33 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f lib/Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/Makefile\" else echo shar: Extracting \"lib/Makefile\" \(3637 characters\) sed "s/^X//" >lib/Makefile <<'END_OF_lib/Makefile' X# X# Copyright (c) 1987 University of Maryland Department of Computer Science. X# All rights reserved. Permission to copy for any purpose is hereby granted X# so long as this copyright notice remains intact. X# X# Makefile for ctex/lib (C-TeX library routines) X# X# $Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/Makefile,v 1.6 89/02/13 14:31:29 grunwald Exp Locker: grunwald $ X# XDESTDIR= X# Alas, -R makes ALL initialised variables read-only, and we cannot X# use it on font files; hence, FCFLAGS. XCC=cc XCFLAGS= -O -I../h XFCFLAGS=-O -I../h X X# 4.1BSD Vax: X#ASSRC= bcopy.s bzero.s X#ASOBJ= bcopy.o bzero.o X#MISCC= getopt.c X#MISCO= getopt.o X X# 4.2BSD Vax: X#ASSRC= X#ASOBJ= X#MISCC= getopt.c X#MISCO= getopt.o X X# 4.2BSD Sun: X#ASSRC= X#ASOBJ= X#MISCC= X#MISCO= X X# 4.2BSD Pyramid: X#ASSRC= X#ASOBJ= X#MISCC= getopt.c X#MISCO= getopt.o X X# 4.3BSD Vax: XASSRC= XASOBJ= XMISCC= XMISCO= X# all XCSRC= conv.c dviclass.c error.c findpost.c fio.c font.c font_subr.c \ X gfclass.c gripes.c magfactor.c rotate.c scaletfm.c scanpost.c \ X search.c seek.c split.c strsave.c tfm.c ${MISCC} XCOBJ= conv.o dviclass.o error.o findpost.o fio.o font.o font_subr.o \ X gfclass.o gripes.o magfactor.o rotate.o scaletfm.o scanpost.o \ X search.o seek.o split.o strsave.o tfm.o ${MISCO} XFSRC= gffont.c pkfont.c pxlfont.c tfmfont.c XFOBJ= gffont.o pkfont.o pxlfont.o tfmfont.o X XOBJS= ${COBJ} ${ASOBJ} ${FOBJ} X Xall: lib.a X Xlib.a: ${OBJS} X ar cr lib.a ${OBJS} X ranlib lib.a X Xsrc: $(CSRC) $(FSRC) X @echo Done X X# no installation is necessary; this entry is just for standardisation Xinstall: X Xclean: X rm -f *.o lib.a X X#pxl.o: X# ${CC} ${CFLAGS} -c -DPXLPATH=\"${PXLPATH}\" pxl.c X X# font.o needs to know where to find the font description file Xfont.o: X ${CC} ${CFLAGS} -c -DFONTDESC=\"${FONTDESC}\" font.c X X# special rules for font objects X${FOBJ}: X ${CC} ${FCFLAGS} -c $*.c X X# DO NOT DELETE THIS LINE -- make depend uses it X# DEPENDENCIES MUST END AT END OF FILE X# IF YOU PUT STUFF HERE IT WILL GO AWAY X# see make depend above X# DO NOT DELETE THIS LINE -- make depend depends on it. X Xconv.o: ../h/types.h ../h/conv.h Xdviclass.o: ../h/dviclass.h Xerror.o: /usr/include/stdio.h /usr/include/varargs.h Xfindpost.o: /usr/include/stdio.h ../h/types.h ../h/dvicodes.h ../h/fio.h Xfio.o: /usr/include/stdio.h ../h/types.h ../h/fio.h Xfont.o: /usr/include/stdio.h /usr/include/errno.h /usr/include/sys/errno.h Xfont.o: ../h/types.h ../h/conv.h ../h/font.h Xfont_subr.o: ../h/font.h Xgetopt.o: /usr/include/stdio.h Xgfclass.o: ../h/gfclass.h Xgffont.o: /usr/include/stdio.h /usr/include/sys/types.h Xgffont.o: /usr/include/sys/stat.h ../h/types.h Xgffont.o: ../h/font.h ../h/gfcodes.h ../h/gfclass.h ../h/num.h Xgripes.o: /usr/include/stdio.h ../h/types.h Xpkfont.o: /usr/include/stdio.h /usr/include/sys/types.h Xpkfont.o: /usr/include/sys/stat.h ../h/types.h Xpkfont.o: ../h/font.h ../h/num.h Xpxlfont.o: /usr/include/stdio.h /usr/include/sys/types.h Xpxlfont.o: /usr/include/sys/stat.h Xpxlfont.o: /usr/include/errno.h /usr/include/sys/errno.h ../h/types.h Xpxlfont.o: ../h/font.h ../h/fio.h Xrotate.o: ../h/font.h Xscaletfm.o: ../h/types.h ../h/font.h Xscanpost.o: /usr/include/stdio.h ../h/types.h ../h/dvicodes.h ../h/fio.h Xscanpost.o: ../h/postamble.h Xsearch.o: ../h/types.h ../h/search.h Xseek.o: /usr/include/stdio.h /usr/include/sys/param.h Xseek.o: /usr/include/sys/signal.h Xseek.o: /usr/include/sys/types.h Xseek.o: /usr/include/sys/file.h Xseek.o: /usr/include/sys/stat.h Xsplit.o: /usr/include/ctype.h Xtfm.o: /usr/include/stdio.h ../h/types.h ../h/fio.h ../h/tfm.h Xtfmfont.o: /usr/include/stdio.h /usr/include/sys/types.h Xtfmfont.o: /usr/include/sys/stat.h ../h/types.h Xtfmfont.o: ../h/conv.h ../h/font.h ../h/tfm.h END_OF_lib/Makefile if test 3637 -ne `wc -c <lib/Makefile`; then echo shar: \"lib/Makefile\" unpacked with wrong size! fi chmod +x lib/Makefile # end of overwriting check fi if test -f lib/rotate.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/rotate.c\" else echo shar: Extracting \"lib/rotate.c\" \(3519 characters\) sed "s/^X//" >lib/rotate.c <<'END_OF_lib/rotate.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/rotate.c,v 1.4 89/02/13 14:31:18 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Routines to generate rotated bitmaps given unrotated inputs. X * X * The rotated bitmap is indistinguishable from the unrotated one (aside X * from being rotated of course!). X */ X X#include "font.h" X Xextern int errno; X Xchar *malloc(); X Xstatic RotateClockwise(); X X/* X * Rounding, but by powers of two only. X */ X#define ROUND(n,r) (((n) + ((r) - 1)) & ~((r) - 1)) X X/* X * Set the rotation of glyph g to r. X */ XSetRotation(g, r) X register struct glyph *g; X int r; X{ X X if (r < ROT_NORM || r > ROT_RIGHT) X error(1, 0, "bad rotation value %d", r); X X /* X * The null glyph is trivial to rotate by any amount. X * X * Note that this assumes that any raster has been obtained X * BEFORE calling SetRotation()! X */ X if (g->g_raster == NULL) { X g->g_rotation = r; X return; X } X X /* X * This is hardly efficient, but it *is* expedient.... X */ X while (g->g_rotation != r) { X RotateClockwise(g); X g->g_rotation = (g->g_rotation - 1) & 3; X } X} X X/* X * Rotation by 1/4 turn clockwise (from ROT_NORM to ROT_RIGHT, e.g.). X */ Xstatic XRotateClockwise(glyph) X struct glyph *glyph; X{ X register char *nrast; /* new raster */ X register char *orast; /* old raster */ X register int oheight; /* old raster height, new raster width */ X register int owidth; /* old raster width, new raster height */ X unsigned int size; /* size of new raster (in bytes) */ X int nplus; /* offset between rows in nrast */ X X /* X * First, get a new raster. X */ X { X register struct glyph *g = glyph; X register int t; X X oheight = g->g_height; X owidth = g->g_width; X X /* X * Offset is (new width) rounded to bytes. X */ X nplus = ROUND(oheight, 8) >> 3; X X /* X * Size of new raster is (new height) * (new rounded width, X * in bytes). X */ X size = nplus * owidth; X if ((nrast = malloc(size)) == NULL) X error(1, errno, "out of memory"); X bzero(nrast, size); X X /* X * New y origin is old x origin; new x origin is old height X * minus old y origin - 1. X */ X t = g->g_yorigin; X g->g_yorigin = g->g_xorigin; X g->g_xorigin = oheight - t - 1; X X /* While we are at it, exchange height & width... */ X g->g_height = owidth; X g->g_width = oheight; X X /* and grab a pointer to the old raster. */ X orast = g->g_raster; X } X X /* X * Now copy bits from the old raster to the new one. The mapping X * function is X * X * for i in [0..height) X * for j in [0..width) X * new[j, height-i-1] = old[i, j] X * X * Thus i maps to height-i-1 and (since we have to do our own 2 X * dimensional array indexing) j to nplus*j. We call the mapped X * variables mapi and mapj, and, since we scan sequentially through X * the old raster, can discard the original i and j. X */ X { X register int mapj, c, k, mapi; X X mapi = oheight; X owidth *= nplus; X while (--mapi >= 0) { X k = 7; X for (mapj = 0; mapj < owidth; mapj += nplus) { X if (++k == 8) /* get another byte */ X c = *orast++, k = 0; X if (c & 0x80) /* old[i,j] was set */ X nrast[mapj + (mapi >> 3)] |= X 1 << (7 - (mapi & 7)); X c <<= 1; X } X } X } X X /* X * Finally, free the storage associated with the original raster. X */ X free(glyph->g_raster); glyph->g_raster = 0; X glyph->g_raster = nrast; X} END_OF_lib/rotate.c if test 3519 -ne `wc -c <lib/rotate.c`; then echo shar: \"lib/rotate.c\" unpacked with wrong size! fi chmod +x lib/rotate.c # end of overwriting check fi if test -f lib/scaletfm.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/scaletfm.c\" else echo shar: Extracting \"lib/scaletfm.c\" \(3302 characters\) sed "s/^X//" >lib/scaletfm.c <<'END_OF_lib/scaletfm.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/scaletfm.c,v 1.3 89/02/13 14:31:19 grunwald Exp Locker: grunwald $"; X#endif X X#include "types.h" X#include "font.h" X X/* X * From DVITYPE.WEB: X * X * ``The most important part of in_TFM is the width computation, which X * involvles multiplying the relative widths in the TFM file by the scaling X * factor in the DVI file. This fixed-point multiplication must be done with X * precisely the same accuracy by all DVI-reading programs, in order to X * validate the assumptions made by DVI-writing programs like \TeX 82. X * X * Let us therefore summarize what needs to be done. Each width in a TFM X * file appears as a four-byte quantity called a fix_word. A fix_word whose X * respective bytes are (a,b,c,d) represents the number X * X * {{ b * 2^{-4} + c * 2^{-12} + d * 2^{-20}, if a = 0; X * x = {{ X * {{ -16 + b * 2^{-4} + c * 2^{-12} + d * 2^{-20}, if a = 255. X * X * (No other choices of a are allowed, since the magnitude of a TFM dimension X * must be less than 16.) We want to multiply this quantity by the integer X * z, which is known to be less than 2^{27}. Let \alpha = 16z. If z < X * 2^{23}, the individual multiplications b * z, c * z, d * z cannot X * overflow; otherwise we will divide z by 2, 4, 8, or 16, to obtain a X * multiplier less than 2^{23}, and we can compensate for this later. If z X * has thereby been replaced by z' = z/2^e, let \beta = 2^{4-e}; we shall X * compute X * X * \lfloor (b + c * 2^{-8} + d * 2^{-16})z' / \beta \rfloor X * X * if a = 0, or the same quantity minus \alpha if a = 255. This calculation X * must be done exactly, for the reasons stated above; the following program X * does the job in a system-independent way, assuming that arithmetic is X * exact on numbers less than 2^{31} in magnitude.'' X */ X X/* X * Scale the single TFM width t by z. X */ Xi32 XScaleOneWidth(t, z) X register i32 t, z; X{ X register i32 alpha, log2beta; X X /* First compute \alpha, \beta, and z': */ X alpha = 16 * z; X log2beta = 4; X while (z >= (1 << 23)) { X z >>= 1; X log2beta--; X } X X /* The four values 'a', 'b', 'c', and 'd' are fields within t: */ X#define a (UnSign8(t >> 24)) X#define b (UnSign8(t >> 16)) X#define c (UnSign8(t >> 8)) X#define d (UnSign8(t)) X if (t) { X t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> log2beta; X if (a) { X if (a != 255) X error(0, 0, "bad TFM width! [ScaleOneWidth]"); X t -= alpha; X } X } X return (t); X} X X/* X * Scale a set of glyphs [l..h) in font f according to f->f_dvimag. X */ XScaleGlyphs(f, l, h) X register struct font *f; X int l, h; X{ X register int i; X register i32 t, z, alpha, log2beta; X X z = f->f_dvimag; X alpha = 16 * z; X log2beta = 4; X while (z >= (1 << 23)) { X z >>= 1; X log2beta--; X } X X for (i = l; i < h; i++) { X if ((t = f->f_gly[i]->g_tfmwidth) == 0) X continue; X t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> log2beta; X if (a) { X if (a != 255) X error(0, 0, "\"%s\", glyph %d: bad TFM width", X f->f_path, i); X t -= alpha; X } X f->f_gly[i]->g_tfmwidth = t; X } X} END_OF_lib/scaletfm.c if test 3302 -ne `wc -c <lib/scaletfm.c`; then echo shar: \"lib/scaletfm.c\" unpacked with wrong size! fi chmod +x lib/scaletfm.c # end of overwriting check fi if test -f lib/scanpost.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/scanpost.c\" else echo shar: Extracting \"lib/scanpost.c\" \(2244 characters\) sed "s/^X//" >lib/scanpost.c <<'END_OF_lib/scanpost.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/scanpost.c,v 1.3 89/02/13 14:31:20 grunwald Exp Locker: grunwald $"; X#endif X X/* X * ScanPostAmble - read a DVI postamble. X */ X X#include <stdio.h> X#include "types.h" X#include "dvicodes.h" X#include "fio.h" X#include "postamble.h" X XScanPostAmble(f, headerfunc, fontfunc) X register FILE *f; X int (*headerfunc)(); X register int (*fontfunc)(); X{ X register int n; X register char *s; X char name[512]; X X if (FindPostAmble(f)) { X GripeCannotFindPostamble(); X return(1); X } X if (GetByte(f) != Sign8(DVI_POST)) { X GripeMissingOp("POST"); X return(1); X } X X /* Read the postamble info stuff. */ X { X struct PostAmbleInfo pai; X register struct PostAmbleInfo *p = &pai; X X p->pai_PrevPagePointer = GetLong(f); X p->pai_Numerator = GetLong(f); X p->pai_Denominator = GetLong(f); X p->pai_DVIMag = GetLong(f); X p->pai_TallestPageHeight = GetLong(f); X p->pai_WidestPageWidth = GetLong(f); X p->pai_DVIStackSize = GetWord(f); X p->pai_NumberOfPages = GetWord(f); X X (*headerfunc)(p); X } X X /* Now read all the font definitions. */ X { X struct PostAmbleFont paf; X register struct PostAmbleFont *p = &paf; X X for (;;) { X switch (UnSign8(getc(f))) { X X case DVI_FNTDEF1: X p->paf_DVIFontIndex = UnSign8(getc(f)); X break; X X case DVI_FNTDEF2: X p->paf_DVIFontIndex = UnSign16(GetWord(f)); X break; X X case DVI_FNTDEF3: X p->paf_DVIFontIndex = UnSign24(Get3Byte(f)); X break; X X case DVI_FNTDEF4: X p->paf_DVIFontIndex = GetLong(f); X break; X X case DVI_POSTPOST: X return(0); X X default: X GripeMissingOp("POSTPOST"); X return(1); X /*NOTREACHED*/ X } X p->paf_DVIChecksum = GetLong(f); X p->paf_DVIMag = GetLong(f); X p->paf_DVIDesignSize = GetLong(f); X p->paf_n1 = UnSign8(getc(f)); X p->paf_n2 = UnSign8(getc(f)); X p->paf_name = name; /* never trust people not to X clobber it */ X n = p->paf_n1 + p->paf_n2; X s = name; X while (--n >= 0) X *s++ = GetByte(f); X *s = 0; X (*fontfunc)(p); X } X } X} END_OF_lib/scanpost.c if test 2244 -ne `wc -c <lib/scanpost.c`; then echo shar: \"lib/scanpost.c\" unpacked with wrong size! fi chmod +x lib/scanpost.c # end of overwriting check fi if test -f lib/search.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/search.c\" else echo shar: Extracting \"lib/search.c\" \(4599 characters\) sed "s/^X//" >lib/search.c <<'END_OF_lib/search.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/search.c,v 1.4 89/02/13 14:31:21 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Key search routines (for a 32 bit key) X * X * SCreate initializes the search control area. X * X * SSearch returns the address of the data area (if found or created) X * or a null pointer (if not). The last argument controls the disposition X * in various cases, and is a ``value-result'' parameter. X * X * SEnumerate calls the given function on each data object within the X * search table. Note that no ordering is specified (though currently X * it runs in increasing-key-value sequence). X */ X X#include "types.h" X#include "search.h" X X#if vax || mc68000 || ns32000 || pyr X#define HARD_ALIGNMENT 4 X#else X#define HARD_ALIGNMENT 16 /* should suffice for most everyone */ X#endif X Xstatic int DOffset; /* part of alignment code */ X Xchar *malloc(), *realloc(); X Xstruct search * XSCreate(dsize) X register unsigned int dsize; X{ X register struct search *s; X X if ((s = (struct search *) malloc(sizeof *s)) == 0) X return (0); X X if (DOffset == 0) { X#ifndef HARD_ALIGNMENT X DOffset = sizeof(i32); X#else X DOffset = (sizeof(i32) + HARD_ALIGNMENT - 1) & X ~(HARD_ALIGNMENT - 1); X#endif X } X dsize += DOffset; /* tack on space for keys */ X X#ifdef HARD_ALIGNMENT X /* X * For machines with strict alignment constraints, it may be X * necessary to align the data at a multiple of some positive power X * of two. In general, it would suffice to make dsize a power of X * two, but this could be very space-wasteful, so instead we align it X * to HARD_ALIGNMENT. 64 bit machines might ``#define HARD_ALIGNMENT X * 8'', for example. N.B.: we assume that HARD_ALIGNMENT is a power X * of two. X */ X X dsize = (dsize + HARD_ALIGNMENT - 1) & ~(HARD_ALIGNMENT - 1); X#endif X X s->s_dsize = dsize; /* save data object size */ X s->s_space = 10; /* initially, room for 10 objects */ X s->s_n = 0; /* and none in the table */ X if ((s->s_data = malloc(s->s_space * dsize)) == 0) { X free((char *) s); (char *) s = 0; X return (0); X } X return (s); X} X X/* X * We actually use a binary search right now - this may change. X */ Xchar * XSSearch(s, key, disp) X register struct search *s; X register i32 key; X int *disp; X{ X register char *keyaddr; X int itemstomove; X X *disp &= S_CREATE | S_EXCL; /* clear return codes */ X if (s->s_n) { /* look for the key */ X register int h, l, m; X X h = s->s_n - 1; X l = 0; X while (l <= h) { X m = (l + h) >> 1; X keyaddr = s->s_data + m * s->s_dsize; X if (*(i32 *) keyaddr > key) X h = m - 1; X else if (*(i32 *) keyaddr < key) X l = m + 1; X else { /* found it, now what? */ X if (*disp & S_EXCL) { X *disp |= S_COLL; X return (0); /* collision */ X } X *disp |= S_FOUND; X return (keyaddr + DOffset); X } X } X keyaddr = s->s_data + l * s->s_dsize; X } else X keyaddr = s->s_data; X X /* keyaddr is now where the key should have been found, if anywhere */ X if ((*disp & S_CREATE) == 0) X return (0); /* not found */ X X /* avoid using realloc so as to retain old data if out of memory */ X if (s->s_space <= 0) { /* must expand; double it */ X register char *new; X X if ((new = malloc((s->s_n << 1) * s->s_dsize)) == 0) { X *disp |= S_ERROR; /* no space */ X return (0); X } X keyaddr = (keyaddr - s->s_data) + new; /* relocate */ X bcopy(s->s_data, new, s->s_n * s->s_dsize); X free(s->s_data); s->s_data = 0; X s->s_data = new; X s->s_space = s->s_n; X } X /* now move any keyed data that is beyond keyaddr down */ X itemstomove = s->s_n - (keyaddr - s->s_data) / s->s_dsize; X if (itemstomove) { X#ifndef USE_BCOPY /* often bcopy doesn't handle overlap */ X register char *from, *to; X X from = s->s_data + s->s_n * s->s_dsize; X to = from + s->s_dsize; X while (from > keyaddr) X *--to = *--from; X#else X bcopy(keyaddr + s->s_dsize, keyaddr + (s->s_dsize << 1), X itemstomove * s->s_dsize); X#endif X } X *disp |= S_NEW; X s->s_n++; X s->s_space--; X *(i32 *) keyaddr = key; X keyaddr += DOffset; /* now actually dataaddr */ X /* the bzero is just a frill... */ X bzero(keyaddr, s->s_dsize - DOffset); X return (keyaddr); X} X X/* X * Call function `f' for each element in the search table `s'. X */ XSEnumerate(s, f) X register struct search *s; X register int (*f)(); X{ X register int n; X register char *p; X X n = s->s_n; X p = s->s_data; X while (--n >= 0) { X (*f)(p + DOffset, *(i32 *) p); X p += s->s_dsize; X } X} END_OF_lib/search.c if test 4599 -ne `wc -c <lib/search.c`; then echo shar: \"lib/search.c\" unpacked with wrong size! fi chmod +x lib/search.c # end of overwriting check fi if test -f lib/seek.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/seek.c\" else echo shar: Extracting \"lib/seek.c\" \(3044 characters\) sed "s/^X//" >lib/seek.c <<'END_OF_lib/seek.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/seek.c,v 1.3 89/02/13 14:31:23 grunwald Exp Locker: grunwald $"; X#endif X X/* X * Seekable is a predicate which returns true iff a Unix fd is seekable. X * X * MakeSeekable forces an input stdio file to be seekable, by copying to X * a temporary file if necessary. X */ X X#include <stdio.h> X#ifdef sys5 X#include <sys/types.h> X#include <sys/fcntl.h> X#else X#include <sys/param.h> X#endif X#include <sys/file.h> X#include <sys/stat.h> X Xlong lseek(); Xchar *getenv(); X Xint XSeekable(fd) X int fd; X{ X X return (lseek(fd, 0L, 1) >= 0 && !isatty(fd)); X} X X/* X * We use the despicable trick of unlinking an open temporary file. X * The alternatives are too painful. If it becomes necessary to X * do this another way, however, here is a method suggested by Fred X * Blonder: fork, and have the parent wait for the child to exit. X * (The parent must avoid being killed during this phase.) When X * the child exits, the parent should then remove the temporary file, X * then exit with the same status, or send itself the same signal. X */ Xint XMakeSeekable(f) X register FILE *f; X{ X register int tf, n; X int mypid, tries, blksize; X char *tmpdir; X#ifdef MAXBSIZE X char buf[MAXBSIZE]; X struct stat st; X#else X char buf[BUFSIZ]; X#endif X X if (Seekable(fileno(f))) X return (0); X X if ((tmpdir = getenv("TMPDIR")) == 0) X tmpdir = "/tmp"; X X /* compose a suitable temporary file name, and get an r/w descriptor */ X mypid = getpid(); X n = 0; X tries = 0; X do { X sprintf(buf, "%s/#%d.%d", tmpdir, mypid, n++); X (void) unlink(buf); X#ifdef O_CREAT /* have three-argument open syscall */ X tries++; X tf = open(buf, O_RDWR | O_CREAT | O_EXCL, 0666); X#else X if (access(buf, 0) == 0) { X /* X * Skip existing files. Note that tf might X * not be set yet. X */ X tf = -1; X continue; X } X tries++; X tf = creat(buf, 0666); X if (tf >= 0) { X (void) close(tf); X tf = open(buf, 2); X if (tf < 0) X (void) unlink(buf); X } X#endif X } while (tf < 0 && tries < 20); X if (tf < 0) /* probably unrecoverable user error */ X return (-1); X X (void) unlink(buf); X X /* copy from input file to temp file */ X#ifdef MAXBSIZE X if (fstat(tf, &st)) /* how can this ever fail? */ X blksize = MAXBSIZE; X else X blksize = MIN(MAXBSIZE, st.st_blksize); X#else X blksize = BUFSIZ; X#endif X while ((n = fread(buf, 1, blksize, f)) > 0) { X if (write(tf, buf, n) != n) { X (void) close(tf); X return (-1); X } X } X /* ferror() is broken in Ultrix 1.2; hence the && */ X if (ferror(f) && !feof(f)) { X (void) close(tf); X return (-1); X } X X /* X * Now switch f to point at the temp file. Since we hit EOF, there X * is nothing in f's stdio buffers, so we can play a dirty trick: X */ X clearerr(f); X if (dup2(tf, fileno(f))) { X (void) close(tf); X return (-1); X } X (void) close(tf); X return (0); X} END_OF_lib/seek.c if test 3044 -ne `wc -c <lib/seek.c`; then echo shar: \"lib/seek.c\" unpacked with wrong size! fi chmod +x lib/seek.c # end of overwriting check fi if test -f lib/split.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/split.c\" else echo shar: Extracting \"lib/split.c\" \(4603 characters\) sed "s/^X//" >lib/split.c <<'END_OF_lib/split.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/split.c,v 1.3 89/02/13 14:31:24 grunwald Exp Locker: grunwald $"; X#endif X X#include <ctype.h> X X/* X * Split a line into an array of words. This is destructive of X * the original line; the word pointers point to places within X * that line. X * X * Return the number of words made, or -1 for overflow. X */ X X/* X * The lexical states are much like `sh's, except that we also do X * C-style backslash-escapes. X */ Xenum lexstate { X S_BLANK, /* outside a word */ X S_WORD, /* inside a word, no quoting */ X S_SQUOTE, /* inside a single quote */ X S_DQUOTE, /* inside a double quote */ X S_BKSL0, /* last char was \ */ X S_BKSL1, /* last chars were \, [0-7] */ X S_BKSL2 /* last chars were \, [0-7][0-7] */ X}; X Xint Xsplit(s, w, nw) X register char *s, **w; X int nw; X{ X register int c; X register char *canon = s; X register int wleft = nw; X enum lexstate state, prebkstate; X X /* X * Start out in the `blank' state (outside a word). Handle X * quotes and things. Backslashes are handled by saving the X * `pre-backslash' state, doing the backslash, and restoring X * that state at the end of the backslash sequence. X */ X state = S_BLANK; X while ((c = *s++) != 0) { Xreswitch: X switch (state) { X X /* X * Blanks: spaces stay in blank state; anything X * else starts a word. However, quotes may put X * us into quote states, rather than word states. X */ X case S_BLANK: X if (isspace(c)) X continue; X if (--wleft < 0) X return (-1); X *w++ = canon; X state = S_WORD; X /* FALLTHROUGH */ X X /* X * In a word. Spaces take us out (and end the X * current word). Quotes, however, put us into X * quote states. X */ X case S_WORD: X if (isspace(c)) { X *canon++ = 0; X state = S_BLANK; X break; X } X if (c == '\'') { X state = S_SQUOTE; X break; X } X if (c == '"') { X state = S_DQUOTE; X break; X } X if (c == '\\') { X prebkstate = S_WORD; X state = S_BKSL0; X break; X } X *canon++ = c; X break; X X /* X * Inside a single quote, the only special character X * is another single quote. This matches the Bourne X * shell quoting convention exactly. X */ X case S_SQUOTE: X if (c == '\'') X state = S_WORD; X else X *canon++ = c; X break; X X /* X * Inside a double quote, double quotes get us out, X * but backslashes must be interpreted. X */ X case S_DQUOTE: X if (c == '\\') { X prebkstate = S_DQUOTE; X state = S_BKSL0; X } else if (c == '"') X state = S_WORD; X else X *canon++ = c; X break; X X /* X * If we are handling a backslash, we will either X * restore the state, or go to BKSL1 state. In X * the latter case, do not advance the canonicalisation X * pointer, since we might have more octal digits X * to insert. X */ X case S_BKSL0: X state = prebkstate; /* probably */ X switch (c) { X X case 'b': X *canon++ = '\b'; X break; X X case 'f': X *canon++ = '\f'; X break; X X case 'n': X *canon++ = '\n'; X break; X X case 'r': X *canon++ = '\r'; X break; X X case 't': X *canon++ = '\t'; X break; X X case '0': case '1': case '2': case '3': X case '4': case '5': case '6': case '7': X *canon = c - '0'; X state = S_BKSL1; X break; X X default: X *canon++ = c; X break; X } X break; X X X /* X * In BKSL1, we have seen backslash and one octal X * digit. There may be more (in which case just X * count them on in), or there might be something X * that requires we restore the state and try again. X */ X case S_BKSL1: X switch (c) { X X case '0': case '1': case '2': case '3': X case '4': case '5': case '6': case '7': X *canon <<= 3; X *canon |= c - '0'; X state = S_BKSL2; X break; X X default: X canon++; X state = prebkstate; X goto reswitch; X } X break; X X /* X * BKSL2 is like BKSL1, except that it cannot X * help but restore the original state, since X * there are no four-character octal sequences. X */ X case S_BKSL2: X state = prebkstate; /* assuredly */ X switch (c) { X X case '0': case '1': case '2': case '3': X case '4': case '5': case '6': case '7': X *canon <<= 3; X *canon++ |= c - '0'; X break; X X default: X canon++; X goto reswitch; X } X break; X } X } X#ifdef notdef X if (state != S_WORD && state != S_BLANK) X error(0, 0, "warning: unclosed quote"); X#endif X if (state != S_BLANK) X *canon = 0; X return (nw - wleft); X} END_OF_lib/split.c if test 4603 -ne `wc -c <lib/split.c`; then echo shar: \"lib/split.c\" unpacked with wrong size! fi chmod +x lib/split.c # end of overwriting check fi if test -f lib/strsave.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/strsave.c\" else echo shar: Extracting \"lib/strsave.c\" \(522 characters\) sed "s/^X//" >lib/strsave.c <<'END_OF_lib/strsave.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X/* X * Save a string in managed memory. X */ X Xchar *malloc(), *realloc(); Xextern int errno; X Xchar * Xstrsave(s) X register char *s; X{ X register int l = strlen(s) + 1; X register char *p = malloc((unsigned) l); X X if (p == 0) X error(1, errno, "no room for %d bytes of string", l); X bcopy(s, p, l); X return (p); X} END_OF_lib/strsave.c if test 522 -ne `wc -c <lib/strsave.c`; then echo shar: \"lib/strsave.c\" unpacked with wrong size! fi chmod +x lib/strsave.c # end of overwriting check fi if test -f lib/tfm.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/tfm.c\" else echo shar: Extracting \"lib/tfm.c\" \(2549 characters\) sed "s/^X//" >lib/tfm.c <<'END_OF_lib/tfm.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/tfm.c,v 1.4 89/02/13 14:31:26 grunwald Exp Locker: grunwald $"; X#endif X X/* X * TFM file reading routines. X * X * TODO: X * finish X */ X X#include <stdio.h> X#include "types.h" X#include "fio.h" X#include "tfm.h" X Xchar *malloc(); X X#define ALLOC(n, type) ((type *) malloc((unsigned) ((n) * sizeof (type)))) X Xstatic trd_header(); Xstatic trd_ci(); Xstatic trd_fix(); X Xint Xreadtfmfile(f, t, stopafterwidth) X register FILE *f; X register struct tfmdata *t; X int stopafterwidth; /* ??? */ X{ X i32 nc; X X if (trd_header(f, &t->t_hdr)) X return (-1); X nc = t->t_hdr.th_ec - t->t_hdr.th_bc + 1; X X t->t_ci = NULL; X t->t_width = NULL; X t->t_height = NULL; X t->t_depth = NULL; X X (void) fseek(f, t->t_hdr.th_lh * 4L, 1); /* XXX */ X X if ((t->t_ci = ALLOC(nc, struct char_info_word)) == NULL || X trd_ci(f, nc, t->t_ci) || X (t->t_width = ALLOC(t->t_hdr.th_nw, i32)) == NULL || X trd_fix(f, t->t_hdr.th_nw, t->t_width)) X goto bad; X if (stopafterwidth) X return (0); X if ((t->t_height = ALLOC(t->t_hdr.th_nh, i32)) == NULL || X trd_fix(f, t->t_hdr.th_nh, t->t_height) || X (t->t_depth = ALLOC(t->t_hdr.th_nd, i32)) == NULL || X trd_fix(f, t->t_hdr.th_nd, t->t_depth)) X goto bad; X return (0); X X bad: X if (t->t_ci != NULL) { X free((char *) t->t_ci); (char *) t->t_ci = 0; X } X if (t->t_width != NULL) { X free((char *) t->t_width); (char *) t->t_width = 0; X } X if (t->t_height != NULL) { X free((char *) t->t_height); (char *) t->t_height = 0; X } X if (t->t_depth != NULL) { X free((char *) t->t_depth); (char *) t->t_depth = 0; X } X return (-1); X } X Xstatic int Xtrd_header(f, th) X register FILE *f; X register struct tfmheader *th; X{ X register i32 *p; X X for (p = &th->th_lf; p <= &th->th_np; p++) X fGetWord(f, *p); X if (feof(f)) X return (-1); X return (0); X} X Xstatic int Xtrd_ci(f, nc, ci) X register FILE *f; X register int nc; X register struct char_info_word *ci; X{ X X while (--nc >= 0) { X ci->ci_width = fgetbyte(f); X ci->ci_h_d = fgetbyte(f); X ci->ci_i_t = fgetbyte(f); X ci->ci_remainder = fgetbyte(f); X ci++; X } X if (feof(f)) X return (-1); X return (0); X} X Xstatic int Xtrd_fix(f, nf, p) X register FILE *f; X register int nf; X register i32 *p; X{ X X while (--nf >= 0) { X fGetLong(f, *p); X p++; X } X if (feof(f)) X return (-1); X return (0); X} END_OF_lib/tfm.c if test 2549 -ne `wc -c <lib/tfm.c`; then echo shar: \"lib/tfm.c\" unpacked with wrong size! fi chmod +x lib/tfm.c # end of overwriting check fi if test -f lib/tfmfont.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/tfmfont.c\" else echo shar: Extracting \"lib/tfmfont.c\" \(5607 characters\) sed "s/^X//" >lib/tfmfont.c <<'END_OF_lib/tfmfont.c' X/* X * Copyright (c) 1987 University of Maryland Department of Computer Science. X * All rights reserved. Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/tfmfont.c,v 1.5 89/02/13 14:31:27 grunwald Exp Locker: grunwald $"; X#endif X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include "types.h" X#include "conv.h" X#include "font.h" X#include "tfm.h" X X/* X * TFM font operations. This defines three fonts: X * X * box - prints as little square boxes, outlining what TeX X * thinks is the character. X * blank - prints as entirely blank. X * invis - prints as entirely blank. X * X * The first two also complain that no font is available in the X * requested size; these are intended to be used as a last resort X * so that users can always print DVI files. You should configure X * in exactly one of box or blank. X * X * TODO: X * base box edge widths on Conversion.c_dpi X */ X Xstatic box_read(); Xstatic blank_read(); Xstatic invis_read(); Xstatic do_read(); Xstatic tfm_getgly(); Xstatic tfm_rasterise(); Xstatic tfm_freefont(); X X /* magnifications are unused in tfm fonts */ Xstruct fontops boxops = /* `boxtops'? Is this a cereal driver? */ X { "box", 0.0, box_read, tfm_getgly, tfm_rasterise, tfm_freefont }; Xstruct fontops blankops = X { "blank", 0.0, blank_read, tfm_getgly, tfm_rasterise, tfm_freefont }; Xstruct fontops invisops = X { "invis", 0.0, invis_read, tfm_getgly, tfm_rasterise, tfm_freefont }; X X/* X * Local info. X */ X Xstruct tfm_details { X int tfm_edge; /* box edge widths, in pixels */ X struct conversion tfm_conv; /* conv. from scaled pts to pixels */ X struct tfmdata tfm_data; /* the TFM file data */ X}; X X/* X * Get the tfm_details from font f. X */ X#define ftotfm(f) ((struct tfm_details *) (f)->f_details) X Xextern int errno; Xchar *malloc(); X X/* X * Read a Box font. X */ Xstatic int Xbox_read(f) X struct font *f; X{ X X return (do_read(f, 0, 1)); X} X X/* X * Read a Blank font. X */ Xstatic int Xblank_read(f) X struct font *f; X{ X X return (do_read(f, 1, 1)); X} X X/* X * Read an Invisible font. X */ Xstatic int Xinvis_read(f) X struct font *f; X{ X X return (do_read(f, 1, 0)); X} X X/* X * Read a TFM font. It is blank if `blank'; complain if `complain'. X */ Xstatic int Xdo_read(f, blank, complain) X register struct font *f; X int blank, complain; X{ X register struct tfm_details *tfm; X FILE *fd; X X if ((fd = fopen(f->f_path, "r")) == 0) X return (-1); X if ((tfm = (struct tfm_details *) malloc(sizeof (*tfm))) == NULL) X goto fail; X if (readtfmfile(fd, &tfm->tfm_data, blank)) X goto fail; X if (blank) X tfm->tfm_edge = 0; X else { X extern Conv Conversion; X X tfm->tfm_edge = 2; /* XXX should be based on dpi */ X tfm->tfm_conv = Conversion; X tfm->tfm_conv.c_fromsp *= DMagFactor(f->f_scaled); X /* XXX !data abstraction */ X } X if (FontHasGlyphs(f, tfm->tfm_data.t_hdr.th_bc, X tfm->tfm_data.t_hdr.th_ec + 1)) X goto fail; X f->f_details = (char *) tfm; X (void) fclose(fd); X if (complain) X error(0, 0, "Warning: no font for %s", Font_TeXName(f)); X return (0); X Xfail: X (void) fclose(fd); X if (tfm != NULL) { X free((char *) tfm); (char *) tfm = 0; X } X return (-1); X} X X/* X * Obtain the specified range of glyphs. X */ Xstatic int Xtfm_getgly(f, l, h) X register struct font *f; X int l; X register int h; X{ X register struct tfm_details *tfm = ftotfm(f); X register struct glyph *g; X register int i; X register struct char_info_word *ci; X#define t (&tfm->tfm_data) X i32 ScaleOneWidth(); X X#define ftop(fix) cfromSP(&tfm->tfm_conv, ScaleOneWidth(fix, f->f_dvimag)) X X for (i = l; i < h; i++) { X ci = &t->t_ci[i - t->t_hdr.th_bc]; X /* zero widths mark invalid characters */ X if (ci->ci_width == 0) X continue; X g = f->f_gly[i]; X g->g_flags = GF_VALID; X g->g_tfmwidth = t->t_width[UnSign8(ci->ci_width)]; X if (tfm->tfm_edge != 0) { X g->g_xorigin = 0; X g->g_yorigin = ftop(t->t_height[T_CI_H(ci)]); X g->g_width = ftop(g->g_tfmwidth); X g->g_height = g->g_yorigin + X ftop(t->t_depth[T_CI_D(ci)]); X } X } X return (0); X#undef t X} X X/* X * Obtain rasters for the specified glyphs. X * X * IGNORES tfm->tfm_edge: 2 HARDCODED FOR NOW X */ Xstatic int Xtfm_rasterise(f, l, h) X struct font *f; X int l, h; X{ X register struct glyph *g; X register char *p; X register int w, j, i; X struct tfm_details *tfm = ftotfm(f); X#define EDGE 2 X X if (tfm->tfm_edge == 0) X return; Xif (tfm->tfm_edge != 2) panic("tfm_rasterise"); X for (i = l; i < h; i++) { X g = f->f_gly[i]; X if ((g->g_flags & GF_VALID) == 0 || !HASRASTER(g)) X continue; X w = (g->g_width + 7) >> 3; X p = malloc((unsigned) (g->g_height * w)); X if (p == NULL) X return (-1); X g->g_raster = p; X g->g_rotation = ROT_NORM; X if (g->g_width < 2 * EDGE) { X w = 2 * EDGE - g->g_width; X for (j = g->g_height; --j >= 0;) X *p++ = 0xf0 << w; X } else { X bzero(p, g->g_height * w); X for (j = 0; j < g->g_height;) { X if (j < EDGE || j >= g->g_height - EDGE) { X register int k = w; X X while (--k > 0) X *p++ = 0xff; X *p++ = 0xff << ((8 - g->g_width) & 7); X j++; X continue; X } X /* the following depends on EDGE==2 */ X *p = 0xc0; X p += w - ((g->g_width & 7) == 1 ? 2 : 1); X *p++ |= 0xc0 >> ((g->g_width - EDGE) & 7); X if ((g->g_width & 7) == 1) X *p++ = 0x80; X /* end dependencies */ X if (++j == EDGE && g->g_height >= 2 * EDGE) { X register int n = g->g_height - EDGE; X X p += (n - j) * w; X j = n; X } X } X } X } X return (0); X} X X/* X * Discard the font details. X */ Xstatic Xtfm_freefont(f) X struct font *f; X{ X X free(f->f_details); f->f_details = 0; X} END_OF_lib/tfmfont.c if test 5607 -ne `wc -c <lib/tfmfont.c`; then echo shar: \"lib/tfmfont.c\" unpacked with wrong size! fi chmod +x lib/tfmfont.c # end of overwriting check fi echo shar: End of archive 6 \(of 6\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. echo "Now do 'make dviselect'" rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Skip Montanaro (montanaro@crdgw1.ge.com)
wabit@cbnewsm.ATT.COM (david.w.mundhenk) (11/18/89)
Isn't it customary to put a short description of the code somewhere near the beginning of a posting, or is this something that, if it's not obvious what it is, I wouldn't know what to do with it? (It isn't obvious, but I'm curious!) Thanks, -- Dave Mundhenk [...!att!lc15a!doc] EMAIL: ...!att!lc15a!doc | "I can't complain but | /^, VOICE: (201)-580-4943 | sometimes I still do"| / } _, , , __ #include <std.disclaimer> | - Joe Walsh | /_./ (_l |/ <~_