[comp.text] reverse engineering PK extensions

grunwald@foobar.colorado.edu (Dirk Grunwald) (10/06/89)

I'm writing a program that produces a Makefile to build fonts using
metafont.

The input is a striped version of the \font declerations in lfonts.tex,
i.e.:

cmssi10 scaled 900

One option to this program is the DPI for metafont. E.g., at 85dpi,
the above yields:
#
# NAME=cmssi10
# SCALE = 900
# EXTENSION = 77
#
cmssi10.77pk:
	-mf '\mode:=sun;mag=900/1000;input cmssi10'
	-gftopk cmssi10.77gf && rm -f cmssi10.77gf

The question is ``how does metafont generate the number used in the
pk/gf suffix.''

I'm using ROUND( DPI * scale * mag ) / ( 1000 * 1000 ) ),
which gives me ``77gf'' above. Metafont generates a .76gf.
Aha, you say, it must TRUNCATE, not ROUND, i.e.
	ROUND( 85 * 900 * 1000 ) / (1000 * 1000 ) -> 77
	TRUNC( 85 * 900 * 1000 ) / (1000 * 1000 ) -> 76

But, then, consider:
	mf '\mode:=sun;mag=700/1000;input cmssi10'

this gives me cmssi10.60gf, but I compute
	ROUND( 85 * 700 * 1000 ) / (1000 * 1000 ) -> 60
	TRUNC( 85 * 700 * 1000 ) / (1000 * 1000 ) -> 59

and in this case, metafont rounds. So what gives? Anyone have a simple
way to compute what the PK/GF extension is going to be? The reason it's
important is that the next entry in the generated makefile depends on
that PK/GF file, to wit:

cmssi10.77.snf:	cmssi10.77pk
	-mftobdf -dpi 85 cmssi10.77pk
	bdftosnf < cmssi10.77.bdf > cmssi10.77.snf


Dirk Grunwald -- Univ. of Colorado at Boulder	(grunwald@foobar.colorado.edu)

rokicki@polya.Stanford.EDU (Tomas G. Rokicki) (10/06/89)

grunwald@foobar.colorado.edu (Dirk Grunwald) writes:
> The input is a striped version of the \font declerations in lfonts.tex,
> i.e.:
> cmssi10 scaled 900
> One option to this program is the DPI for metafont. E.g., at 85dpi,
> the above yields:
> The question is ``how does metafont generate the number used in the
> pk/gf suffix.''

It's round(dpi * mag).  As you surmised.  But one flaw is that the mag
(as all numbers in MF) is stored in radix format, with 16 bits of
fraction.  Thus, 0.9 is stored as 58982/65536.  This is really
about 0.899993896.  When this is multiplied by 85, you end up with
76.49948, which is then rounded to 76.  (The `real' value should have
been 76.5, rounded up to 77.)  Thus, one possible `more valid' expression
is

   round(round(mag*65536)*dpi/65536)

I believe this will always work.  In general, though, `900' is a bad
number (I realize LaTeX uses it) with odd resolutions (like 85) since
85 * 0.9 is 76.5---right at the borderline where finite precision gives
you problems.  The magsteps used by TeX will almost never present such a
problem.

Also, note that the magnification used in TeX documents is really

   round(mag*1000)

so \magstephalf goes to the integer 1095.  Thus, the arithmetic in the
drivers is somewhat different than the arithmetic in MF.  (ie, MF
says foo scaled 900 requires 76; the drivers normally say 77.  Thus,
for a dpi of 2000 at magstephalf, MF says the output dpi is

   round(round(mag*65536)*dpi/65536)
   =round(71791*2000/65536)
   =round(2190.88)
   =2191

TeX, on the other hand, says the required dpi is

   round(round(mag*1000)*dpi/1000)
   =round(1095*2000/1000)
   =round(2190)
   =2190

And, given the exact numbers MF uses and the exact numbers put in the dvi
file, there is no rounding method that will work.

So drivers have to do a little extra work to find the appropriate font.
And users should stick to the magstep ratios if possible---it makes things
a tad easier to deal with.

-tom