[comp.text] TeX HELP

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