hak@elmgate.UUCP (Al Killenbeck) (03/07/87)
I recently obtained a copy of the Washington TeX release tape, and have been busily building it up on a Sun 2/120 running version 3.2 of Sun's OS. For the most part, things have gone well.... HOWEVER ... I'm using various Imagen printers, and am using Chris Torek's "iptex/imagen1" output driver to send the files, and have not yet had much luck avoiding the "tfm and pxl files have different checksums" messages. Since I'm the resident TeX maintainer, I could use a little help solving this detail. Also, if there's a relatively easy fix to allow the driver to accept the invisible fonts needed for SliTeX, I'd like information about that. In addition, METAFONT doesn't seem to quite understand that "showit" should display SOMETHING on the Sun's console. ... or am I not understanding what Knuth wrote in chapter 5 of the METAFONTbook? This is mostly an "unnofficial", unsanctioned effort on my part to get TeX and all of it's pieces working here, so any help would be greatly appreciated. Yes, I have contacted TUG, and expect to join. And I'm reading and re-reading the books and all the README's that are on the tape. This has been a little longer than I originally intended. ... Please respond by e-mail if my path(s) work, or call me on the phone if all else fails. Thanks much. Al Killenbeck ... Eastman Kodak Company, Rochester, NY AT&T:(716)726-9951 UUCP:{allegra,seismo}!rochester!kodak!elmgate!hak
chris@mimsy.UUCP (Chris Torek) (03/09/87)
In article <579@elmgate.UUCP> hak@elmgate.UUCP (Al Killenbeck) writes: >... have not yet had much luck avoiding the "tfm and pxl files >have different checksums" messages. Some of the distributed fonts and TFM files simply do not match. As long as the output looks reasonable, ignore the message. >Also, if there's a relatively easy fix to allow the driver to accept the >invisible fonts needed for SliTeX, I'd like information about that. If you have the invisible fonts (the i*pxl files) and they produce strange output---that is, a pair of slide should say, e.g., red: Some text green: green but what you get is red: Some text green: green ---if this happens, you have the broken i*pxl files. A bug in old Metafont made zero pixel characters have zero TFM widths. There are one character glitches in some other PXL files as well. The following shar file provides some (but not all) of the undistributed `misc' directory, including the `checkw' program, which can fix such PXL files. Beware: This is rather old code, and tested only on a Vax. It was written as a quick hack. : Run this shell script with "sh" not "csh" PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH all=FALSE if [ x$1 = x-a ]; then all=TRUE fi echo Making directory misc mkdir misc echo Extracting misc/Makefile sed 's/^X//' <<'//go.sysin dd *' >misc/Makefile CFLAGS= -O -R LIBS= ../lib/lib.a # showfont STD= fixfix showtfmwidth checkw current: showfont showfont: showfont.o ${LIBS} ${CC} ${CFLAGS} -o $@ $@.o ${LIBS} all: ${STD} ${STD}: ${LIBS} ${CC} ${CFLAGS} -o $@ $@.c ${LIBS} install: all @echo "these programs don't get installed..." depend: for i in ${STD}; do \ ${CC} -M ${CFLAGS} $$i.c | sed -e 's/\.o:/:/' -e 's, ./, ,' | \ awk '{ if ($$1 != prev) { if (rec != "") print rec; \ rec = $$0; prev = $$1; } \ else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ else rec = rec " " $$2 } } \ END { print rec }'; done >makedep echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep echo '$$r makedep' >>eddep echo 'w' >>eddep cp Makefile Makefile.bak ed - Makefile <eddep rm eddep makedep echo '# DEPENDENCIES MUST END AT END OF FILE' >>Makefile echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >>Makefile echo '# see make depend above' >>Makefile # DO NOT DELETE THIS LINE -- make depend uses it fixfix: fixfix.c /usr/include/stdio.h showtfmwidth: showtfmwidth.c /usr/include/stdio.h ../h/types.h ../h/fio.h checkw: checkw.c /usr/include/stdio.h /usr/include/sys/types.h checkw: /usr/include/sys/stat.h ../h/types.h ../h/fio.h showfont.o: showfont.c /usr/include/stdio.h ../h/font.h ../h/types.h ../h/conv.h # DEPENDENCIES MUST END AT END OF FILE # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above //go.sysin dd * if [ `wc -c < misc/Makefile` != 1396 ]; then made=FALSE echo error transmitting misc/Makefile -- echo length should be 1396, not `wc -c < misc/Makefile` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 misc/Makefile echo -n ' '; ls -ld misc/Makefile fi echo Extracting misc/check.sh sed 's/^X//' <<'//go.sysin dd *' >misc/check.sh #! /bin/sh # # check - check the width tables of all the PXL fonts # # usage: check directory-name case $# in 1) ;; *) echo "usage: check directory-name" 1>&2; exit 1;; esac checker=`pwd`/checkw cd "$1" for tfm in *.tfm; do base=`basename $tfm .tfm` for pxl in $base.*pxl; do $checker -q $tfm $pxl done done //go.sysin dd * if [ `wc -c < misc/check.sh` != 317 ]; then made=FALSE echo error transmitting misc/check.sh -- echo length should be 317, not `wc -c < misc/check.sh` else made=TRUE fi if [ $made = TRUE ]; then chmod 755 misc/check.sh echo -n ' '; ls -ld misc/check.sh fi echo Extracting misc/checkw.1 sed 's/^X//' <<'//go.sysin dd *' >misc/checkw.1 X.TH CHECKW 1 X.SH NAME checkw \- check and patch up PXL files whose TFM widths are wrong X.SH SYNOPSIS X.B checkw [ X.B -f ] [ X.B -q ] [ X.B -s ] X.I tfmfile X.I pxlfile X.SH DESCRIPTION X.I Checkw is a program that ought to be unnecessary, but there is a bug in Metafont that produces incorrect TFM widths in PXL files for characters that are zero pixels wide. X.I Checkw reads the named TFM and PXL files, which should be for the same font, and compares the width tables of each. A message is printed indicating whether the tables match. If the X.B -f (``fix'') option is given, X.I checkw writes the correct widths back to the PXL file. X.PP The X.B -s (``silent'') option makes X.I checkw operate silently (only exit status is returned). The X.B -q (``quiet'') option makes checkw complain if the TFM and PXL files do not match, but otherwise run silently. X.SH DIAGNOSTICS Exit value is 0 if the fonts match or were corrected, 1 if they do not, and 2 for any other error. Various messages may be printed to the standard error output if things go wrong; they are intended to be self explanatory, unless they should ``never happen''. If the message does not mention a damaged PXL file, the file has not been touched. X.SH AUTHOR Chris Torek, University of Maryland \" .SH FILES \" .SH "SEE ALSO" X.SH BUGS The bugs are in Metafont. \" :-) //go.sysin dd * if [ `wc -c < misc/checkw.1` != 1327 ]; then made=FALSE echo error transmitting misc/checkw.1 -- echo length should be 1327, not `wc -c < misc/checkw.1` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 misc/checkw.1 echo -n ' '; ls -ld misc/checkw.1 fi echo Extracting misc/checkw.c sed 's/^X//' <<'//go.sysin dd *' >misc/checkw.c #ifndef lint static char rcsid[] = "$Header$"; #endif X/* * checkw -- check & fix the TFM widths in a PXL file * * Usage: checkw [-f] [-s] tfmfile pxlfile */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include "../h/types.h" #include "../h/fio.h" char *ProgName; struct tfmheader { int th_lf; /* length of the file (words) */ int th_lh; /* length of the header data (words) */ int th_bc; /* smallest char code in font */ int th_ec; /* largest char code in font (inclusive) */ int th_nw; /* number of words in width table */ int th_nh; /* number of words in height table */ int th_nd; /* number of words in depth table */ int th_ni; /* number of words in ital. corr. table */ int th_nl; /* number of words in lig/kern table */ int th_nk; /* number of words in kern table */ int th_ne; /* number of words in extensible char table */ int th_np; /* number of font param words */ }; X/* * The rest of the TFM file is composed of the following information, * all of which are 32 bit quantities: * * header: array [0..lh-1] of stuff * char_info: array [bc..ec] of char_info_word * width: array [0..nw-1] of fix_word * height: array [0..nh-1] of fix_word * depth: array [0..nd-1] of fix_word * italic: array [0..ni-1] of fix_word * lig_kern: array [0..nl-1] of lig_kern_command * kern: array [0..nk-1] of fix_word * exten: array [0..ne-1] of extensible_recipie * param: array [1..np] of fix_word * * We are interested only in the width information. This can be * found by taking the first byte of each of the char_info_words * and using it as an index in the width table. That is, the * width of character $n$ is width[char_info[$n$-$bc$].width_index]. */ struct char_info_word { char width_index; char height_and_depth_index; char italic_index_and_tag; char remainder; }; X/* * A PXL file ends with 2068 bytes of information which includes the * TFM widths and some other stuff (some of which we don't need, some * of which we do; it's easiest to just read it all). */ #define PXBUFSIZE 2068 #define PXL_ID 1001 #define PXIDOFF 2064 /* PXL_ID found here */ #define PXTFMOFF(n) (((n) << 4) + 12)/* TFM width of char $n$ here */ int FFlag; /* -f => fix */ int SFlag; /* -s => silent */ int QFlag; /* -q => quiet (like -s if match) */ char *tfname; /* name of the TFM file */ XFILE *tf; /* the TFM file */ char *pxname; /* name of the PXL file */ int px; /* we don't use stdio on the pxl file */ char pxbuf[PXBUFSIZE]; /* the tail of the PXL file */ long pxtailoff; /* tells where pxbuf goes */ struct tfmheader th; /* the TFM file's header information */ i32 *width; /* the TFM width tables */ struct char_info_word *char_info;/* the TFM character info tables */ #define WIDTH(c) width[char_info[(c) - th.th_bc].width_index] extern char *optarg; extern int optind; extern int errno; char *malloc (); long lseek (); X/* * Exit stati. */ #define EX_OK 0 /* all is well in fontland */ #define EX_NOMATCH 1 /* didn't match, didn't update PXL file */ #define EX_OTHER 2 /* other error (invalid command, etc.) */ main (argc, argv) register int argc; register char **argv; { register int c; ProgName = argv[0]; while ((c = getopt (argc, argv, "fqs")) != EOF) { switch (c) { case 'f': FFlag++; break; case 'q': QFlag++; break; case 's': SFlag++; break; case '?': usage: error (EX_OTHER, 0, "usage: %s [-f] [-s] tfmfile pxlfile", ProgName); /*NOTREACHED*/ } } if (argc - optind != 2) goto usage; tfname = argv[optind]; pxname = argv[optind + 1]; if ((tf = fopen (tfname, "r")) == NULL) error (EX_OTHER, errno, "can't open %s for reading", tfname); if ((px = open (pxname, FFlag ? 2 : 0)) < 0) error (EX_OTHER, errno, "can't open %s for %s", pxname, FFlag ? "update" : "reading"); ReadPXLTail (); ReadTFMHeader (); if (th.th_ec < th.th_bc) error (EX_OTHER, 0, "\ Are you sure %s is a TFM file? It contains no characters!", tfname); if (th.th_bc < 0 || th.th_ec > 127) error (EX_OTHER, 0, "\ I don't see how %s can correspond to your PXL file.\n\ (It has a first character entry of %d, and a last of %d.)", tfname, th.th_bc, th.th_ec); AllocateCharTable (th.th_ec - th.th_bc + 1); AllocateWidthTable (th.th_nw); SkipHeader (); ReadCharInfo (th.th_ec - th.th_bc + 1); ReadWidthTable (th.th_nw); if (WidthsMatch ()) { if (!SFlag && !QFlag) printf ("%s: width tables for %s match %s\n", ProgName, pxname, tfname); exit (EX_OK); } if (!FFlag) { if (!SFlag) printf ("%s: width tables for %s and %s do not match\n", ProgName, pxname, tfname); exit (EX_NOMATCH); } if (!SFlag) printf ("%s: width tables for %s and %s do not match; updating...\n", ProgName, pxname, tfname); FixPXLTail (); WritePXLTail (); if (!SFlag) printf ("%s: width tables in %s updated.\n", ProgName, pxname); exit (EX_OK); } X/* * Called if the TFM file seems to be bogus. */ BadTFMFile () { error (EX_OTHER, 0, "unexpected EOF -- are you sure %s is a TFM file?", tfname); /* NOTREACHED */ } X/* * Allocate n character info table entries. */ AllocateCharTable (n) register int n; { char_info = (struct char_info_word *) malloc ((unsigned) n * sizeof *char_info); if (char_info == 0) error (EX_OTHER, errno, "unable to allocate %d char table entries", n); } X/* * Allocate n width table entries. */ AllocateWidthTable (n) register int n; { width = (i32 *) malloc ((unsigned) n * sizeof *width); if (width == 0) error (EX_OTHER, errno, "unable to allocate %d width table entries", n); } X/* * Read the TFM header. */ ReadTFMHeader () { register int *ip, i; for (ip = &th.th_lf; ip <= &th.th_np;) { i = UnSign16 (GetWord (tf)); *ip++ = i; /* ``cheating'' */ } /* We could do something nice like make sure the actual file size and the reported size (tf.tf_lf * 4?) are the same... naaah. */ } X/* * Skip over the miscellaneous header info in the TFM file. */ SkipHeader () { (void) fseek (tf, (long) th.th_lh * sizeof (i32), 1); } X/* * Read the character info table from the TFM file. (We get all * of it, even though we're only going to use the width index.) */ ReadCharInfo (n) register int n; { register struct char_info_word *ci; for (ci = char_info; --n >= 0; ci++) { ci -> width_index = getc (tf); ci -> height_and_depth_index = getc (tf); ci -> italic_index_and_tag = getc (tf); ci -> remainder = getc (tf); } if (feof (tf)) BadTFMFile (); } X/* * Read the width table from the TFM file. */ ReadWidthTable (n) register int n; { register i32 *ip; for (ip = width; --n >= 0; ip++) fGetLong (tf, *ip); if (feof (tf)) BadTFMFile (); } X/* * Get a 32 bit quantity from the specified offset in the pxl buffer. */ i32 GetPXLong (off) { register char *p = pxbuf + off; register i32 rv; rv = UnSign8 (*p++) << 24; rv |= UnSign8 (*p++) << 16; rv |= UnSign8 (*p++) << 8; rv |= UnSign8 (*p); return rv; } X/* * Put the specified value in the pxl buffer at the given offset. * N.B.: assuming 8 bit bytes (since val >> n might be signed). */ PutPXLong (off, val) int off; register i32 val; { register char *p = pxbuf + off; *p++ = val >> 24; *p++ = val >> 16; *p++ = val >> 8; *p = val; } X/* * Read (and verify) the end part of the pxl file. */ ReadPXLTail () { struct stat st; if (fstat (px, &st)) error (EX_OTHER, errno, "fstat(%s)", px, pxname); if (st.st_size & 3 || st.st_size < PXBUFSIZE) error (EX_OTHER, 0, "%s doesn't seem to be a pxl file", pxname); pxtailoff = st.st_size - PXBUFSIZE; if (lseek (px, pxtailoff, 0) != pxtailoff) error (EX_OTHER, errno, "lseek(%s) didn't return %ld", pxname, pxtailoff); if (read (px, pxbuf, PXBUFSIZE) != PXBUFSIZE) error (EX_OTHER, errno, "read(%s)", pxname); if (GetPXLong (PXIDOFF) != PXL_ID) error (EX_OTHER, 0, "%s doesn't seem to be a PXL file.", pxname); } X/* * Write the end part of the PXL file back to the original PXL file. */ WritePXLTail () { if (lseek (px, pxtailoff, 0) != pxtailoff) error (EX_OTHER, errno, "lseek(%s) didn't return %ld", pxname, pxtailoff); if (write (px, pxbuf, PXBUFSIZE) != PXBUFSIZE) error (EX_OTHER, errno, "write(%s) failed---pxl file may be damaged", pxname); } X/* * Compare the width values in the PXL tail buffer with those in the * TFM width tables. Return 1 iff they all match. */ WidthsMatch () { register int i; for (i = th.th_bc; i <= th.th_ec; i++) if (GetPXLong (PXTFMOFF (i)) != WIDTH (i)) return 0; /* a mismatch */ /* perhaps we should make sure the rest are 0... oh well */ return 1; } X/* * Fix the width values in the PXL file tail buffer. */ XFixPXLTail () { register int i; for (i = th.th_bc; i <= th.th_ec; i++) PutPXLong (PXTFMOFF (i), WIDTH (i)); } //go.sysin dd * if [ `wc -c < misc/checkw.c` != 9041 ]; then made=FALSE echo error transmitting misc/checkw.c -- echo length should be 9041, not `wc -c < misc/checkw.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 misc/checkw.c echo -n ' '; ls -ld misc/checkw.c fi echo Extracting misc/getdep.sh sed 's/^X//' <<'//go.sysin dd *' >misc/getdep.sh : getdep - get dependency lists. : change ":" comments to "#" comments if your shell supports those; : the result will run faster. : find cpp cpp=unknown for where in /lib /usr/lib /bin /usr/bin; do if test -f $where/cpp; then cpp=$where/cpp; break; fi done if test $cpp = unknown; then echo "I cannot find cpp, sorry" 1>&2; exit 1 fi : handle arguments incl= for i do case "$i" in -I*) incl="$incl $i";; *) : assume source file : put '$dep' in front of dependencies dep=`echo "$i" | sed -e 's,/,\\\\/,g' -e 's/\.c$/.o/'` : Find includes, remove leading numerics, remove ./, : remove double quotes, and remove trailing numerics. : Sort that, discarding duplicates, and add '$dep'. $cpp $incl "$i" | grep "^#" | sed -e 's/# [0-9]* //' -e 's,"./,",' -e 's/"\(.*\)"/\1/' \ -e 's/ [ 0-9]*$//' | sort -u | sed -e "s/^/$dep: /";; esac done //go.sysin dd * if [ `wc -c < misc/getdep.sh` != 869 ]; then made=FALSE echo error transmitting misc/getdep.sh -- echo length should be 869, not `wc -c < misc/getdep.sh` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 misc/getdep.sh echo -n ' '; ls -ld misc/getdep.sh fi made=TRUE if [ $made = TRUE ]; then chmod 755 misc echo -n ' '; ls -ld misc fi -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu