summaryrefslogtreecommitdiff
path: root/fonts/utilities/mf2pt3
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/utilities/mf2pt3
Initial commit
Diffstat (limited to 'fonts/utilities/mf2pt3')
-rw-r--r--fonts/utilities/mf2pt3/mf2pt3.html577
-rw-r--r--fonts/utilities/mf2pt3/mf2pt3.nw530
-rwxr-xr-xfonts/utilities/mf2pt3/mf2pt3.pl305
3 files changed, 1412 insertions, 0 deletions
diff --git a/fonts/utilities/mf2pt3/mf2pt3.html b/fonts/utilities/mf2pt3/mf2pt3.html
new file mode 100644
index 0000000000..49da72d433
--- /dev/null
+++ b/fonts/utilities/mf2pt3/mf2pt3.html
@@ -0,0 +1,577 @@
+<html><head><title>mf2pt3.nw</title></head><body><b>mf2pt3</b> (c) Copyright 1998 Apostolos Syropoulos
+<code>apostolo@obelix.ee.duth.gr</code> <p>
+This is program <code>mf2pt3</code> a Perl script that generates a PostScript
+<a name="NWD1">T</a>ype 3 font that corresponds to a METAFONT font description. In order
+to achieve its goal the program utilizes another program: mfplain
+(METAPOST with the mfplain base preloaded). This program generates EPSF
+files for each character. This document assumes that the reader is
+familiar with the Type 3 font terminology and its structure. For
+more information one should consult the ``PostScript User Manual'',
+or any good book on PostScript like ``Postscript by Example'',
+by Henry McGilton and Mary Campione, published by Addison-Wesley Pub Co.
+
+<a name="NWD2">W</a>e now describe the way the program operates. First of all, we
+generate for each character of a METAFONT font an EPSF file. Next
+we collect the <code>BoundingBox</code> information for each character, as this
+piece of information is vital to the construction of the Type 3 font.
+Now we can proceed with the construction of the font. Finally, we
+delete some unnecessary files and we output the line the user must
+add to his/her <code>psfonts.map</code> file in order to use the Type 3 font
+when he/she creates a PostScript file from a DVI file.
+
+<pre><a name="NWmf29-*-1" href="#NWD2"><dfn>&lt;*&gt;=</dfn></a>
+#!/usr/bin/perl
+#
+#(c) Copyright 1998 Apostolos Syropoulos
+# apostolo@obelix.ee.duth.gr
+#
+<a name="NWmf29-*-1-u1" href="#NWD3"><i>&lt;Initialization of constants&gt;</i></a>
+<a name="NWmf29-*-1-u2" href="#NWD8"><i>&lt;Command line argument handling&gt;</i></a>
+<a name="NWmf29-*-1-u3" href="#NWDD"><i>&lt;Generation of EPSF files&gt;</i></a>
+<a name="NWmf29-*-1-u4" href="#NWDE"><i>&lt;Construction of Type 3 font&gt;</i></a>
+<a name="NWmf29-*-1-u5" href="#NWDO"><i>&lt;Delete unnecessary files&gt;</i></a>
+print &quot;\n$MFfile $MFfile &lt;$MFfile.pt3\n&quot;;
+
+</pre><blockquote>This code is written to a file (or else not used).<p></blockquote><p><a name="NWD3">S</a>ince we don't know on what system the program will be used, we
+must make sure it calls the GhostScript and METAPOST programs in the proper
+way. Moreover, we supply to each command the proper command line switches.
+The magnification is set to 100 as the usual design size is 10 pt.
+The <code>BoundingBox</code> information are kept in a compact format in an array.
+
+<pre><a name="NWmf29-IniR-1" href="#NWD3"><dfn>&lt;Initialization of constants&gt;=</dfn></a>
+ $mfplain=&quot;mfplain \'\\mode=localfont; \\batchmode; &quot;;
+ <a name="NWmf29-IniR-1-u1" href="#NWD4"><i>&lt;BoundingBox initialization&gt;</i></a>
+ <a name="NWmf29-IniR-1-u2" href="#NWD5"><i>&lt;Encoding array initialization&gt;</i></a>
+
+</pre><blockquote>Used <a href="#NWD2">above</a>.<p>
+</blockquote><p><a name="NWmf29-IniR-1-u2">S</a>ince Perl does not provide record structures, we use the <code>pack</code>
+<a name="NWD4">f</a>unction to create a structure which will contain the <code>BoundingBox</code>
+information. Each <code>BoundingBox</code> corresponds to four numbers: <code>llx</code>,
+<code>lly</code>, <code>urx</code>, and <code>ury</code>. If any of the 256 character slots is
+undefined each of these four numbers is set to zero. For efficiency reasons
+each <code>BoundingBox</code> structure contains one more piece of information--- an
+ASCII character, which indicates whether the corresponding character is
+defined ("d") or undefined ("u"). All the <code>BoundingBox</code> information are
+kept in an array which is assumed to contain only undefined characters.
+
+<pre><a name="NWmf29-BouQ-1" href="#NWD4"><dfn>&lt;BoundingBox initialization&gt;=</dfn></a>
+$notdef=pack(&quot;ai4&quot;,&quot;u&quot;,0,0,0,0);
+for($i=0; $i&lt;=255; $i++){ $BoundingBox[$i]=$notdef }
+
+</pre><blockquote>Used <a href="#NWD3">above</a>.<p>
+</blockquote><p><a name="NWD5">T</a>he encoding vector is a vital part of a PostScript font. The internal
+name of each character is completely irrelevant to the final output. So,
+someone can choose any name it pleases him.
+
+<pre><a name="NWmf29-EncT-1" href="#NWD5"><dfn>&lt;Encoding array initialization&gt;=</dfn></a>
+@Encoding = (&quot;/_a0&quot;, &quot;/_a1&quot;, &quot;/_a2&quot;, &quot;/_a3&quot;, &quot;/_a4&quot;,
+ &quot;/_a5&quot;, &quot;/_a6&quot;, &quot;/_a7&quot;, &quot;/_a8&quot;,
+ &quot;/_a9&quot;, &quot;/_a10&quot;, &quot;/_a11&quot;, &quot;/_a12&quot;,
+ &quot;/_a13&quot;, &quot;/_a14&quot;, &quot;/_a15&quot;, &quot;/_a16&quot;,
+ &quot;/_a17&quot;, &quot;/_a18&quot;, &quot;/_a19&quot;, &quot;/_a20&quot;,
+ &quot;/_a21&quot;, &quot;/_a22&quot;, &quot;/_a23&quot;, &quot;/_a24&quot;,
+ &quot;/_a25&quot;, &quot;/_a26&quot;, &quot;/_a27&quot;, &quot;/_a28&quot;,
+ &quot;/_a29&quot;, &quot;/_a30&quot;, &quot;/_a31&quot;, &quot;/_a32&quot;,
+ &quot;/_a33&quot;, &quot;/_a34&quot;, &quot;/_a35&quot;, &quot;/_a36&quot;,
+ &quot;/_a37&quot;, &quot;/_a38&quot;, &quot;/_a39&quot;, &quot;/_a40&quot;,
+ &quot;/_a41&quot;, &quot;/_a42&quot;, &quot;/_a43&quot;, &quot;/_a44&quot;,
+ &quot;/_a45&quot;, &quot;/_a46&quot;, &quot;/_a47&quot;, &quot;/_a48&quot;,
+ &quot;/_a49&quot;, &quot;/_a50&quot;, &quot;/_a51&quot;, &quot;/_a52&quot;,
+ &quot;/_a53&quot;, &quot;/_a54&quot;, &quot;/_a55&quot;, &quot;/_a56&quot;,
+ &quot;/_a57&quot;, &quot;/_a58&quot;, &quot;/_a59&quot;, &quot;/_a60&quot;,
+ &quot;/_a61&quot;, &quot;/_a62&quot;, &quot;/_a63&quot;, &quot;/_a64&quot;,
+ &quot;/_a65&quot;, &quot;/_a66&quot;, &quot;/_a67&quot;, &quot;/_a68&quot;,
+ &quot;/_a69&quot;, &quot;/_a70&quot;, &quot;/_a71&quot;, &quot;/_a72&quot;,
+ &quot;/_a73&quot;, &quot;/_a74&quot;, &quot;/_a75&quot;, &quot;/_a76&quot;,
+ &quot;/_a77&quot;, &quot;/_a78&quot;, &quot;/_a79&quot;, &quot;/_a80&quot;,
+ &quot;/_a81&quot;, &quot;/_a82&quot;, &quot;/_a83&quot;, &quot;/_a84&quot;,
+ &quot;/_a85&quot;, &quot;/_a86&quot;, &quot;/_a87&quot;, &quot;/_a88&quot;,
+ &quot;/_a89&quot;, &quot;/_a90&quot;, &quot;/_a91&quot;, &quot;/_a92&quot;,
+ &quot;/_a93&quot;, &quot;/_a94&quot;, &quot;/_a95&quot;, &quot;/_a96&quot;,
+ &quot;/_a97&quot;, &quot;/_a98&quot;, &quot;/_a99&quot;, &quot;/_a100&quot;,
+ &quot;/_a101&quot;, &quot;/_a102&quot;, &quot;/_a103&quot;, &quot;/_a104&quot;,
+ &quot;/_a105&quot;, &quot;/_a106&quot;, &quot;/_a107&quot;, &quot;/_a108&quot;,
+ &quot;/_a109&quot;, &quot;/_a110&quot;, &quot;/_a111&quot;, &quot;/_a112&quot;,
+ &quot;/_a113&quot;, &quot;/_a114&quot;, &quot;/_a115&quot;, &quot;/_a116&quot;,
+ &quot;/_a117&quot;, &quot;/_a118&quot;, &quot;/_a119&quot;, &quot;/_a120&quot;,
+ &quot;/_a121&quot;, &quot;/_a122&quot;, &quot;/_a123&quot;, &quot;/_a124&quot;,
+ &quot;/_a125&quot;, &quot;/_a126&quot;, &quot;/_a127&quot;, &quot;/_a128&quot;,
+ &quot;/_a129&quot;, &quot;/_a130&quot;, &quot;/_a131&quot;, &quot;/_a132&quot;,
+ &quot;/_a133&quot;, &quot;/_a134&quot;, &quot;/_a135&quot;, &quot;/_a136&quot;,
+ &quot;/_a137&quot;, &quot;/_a138&quot;, &quot;/_a139&quot;, &quot;/_a140&quot;,
+ &quot;/_a141&quot;, &quot;/_a142&quot;, &quot;/_a143&quot;, &quot;/_a144&quot;,
+ &quot;/_a145&quot;, &quot;/_a146&quot;, &quot;/_a147&quot;, &quot;/_a148&quot;,
+ &quot;/_a149&quot;, &quot;/_a150&quot;, &quot;/_a151&quot;, &quot;/_a152&quot;,
+ &quot;/_a153&quot;, &quot;/_a154&quot;, &quot;/_a155&quot;, &quot;/_a156&quot;,
+ &quot;/_a157&quot;, &quot;/_a158&quot;, &quot;/_a159&quot;, &quot;/_a160&quot;,
+ &quot;/_a161&quot;, &quot;/_a162&quot;, &quot;/_a163&quot;, &quot;/_a164&quot;,
+ &quot;/_a165&quot;, &quot;/_a166&quot;, &quot;/_a167&quot;, &quot;/_a168&quot;,
+ &quot;/_a169&quot;, &quot;/_a170&quot;, &quot;/_a171&quot;, &quot;/_a172&quot;,
+ &quot;/_a173&quot;, &quot;/_a174&quot;, &quot;/_a175&quot;, &quot;/_a176&quot;,
+ &quot;/_a177&quot;, &quot;/_a178&quot;, &quot;/_a179&quot;, &quot;/_a180&quot;,
+ &quot;/_a181&quot;, &quot;/_a182&quot;, &quot;/_a183&quot;, &quot;/_a184&quot;,
+ &quot;/_a185&quot;, &quot;/_a186&quot;, &quot;/_a187&quot;, &quot;/_a188&quot;,
+ &quot;/_a189&quot;, &quot;/_a190&quot;, &quot;/_a191&quot;, &quot;/_a192&quot;,
+ &quot;/_a193&quot;, &quot;/_a194&quot;, &quot;/_a195&quot;, &quot;/_a196&quot;,
+ &quot;/_a197&quot;, &quot;/_a198&quot;, &quot;/_a199&quot;, &quot;/_a200&quot;,
+ &quot;/_a201&quot;, &quot;/_a202&quot;, &quot;/_a203&quot;, &quot;/_a204&quot;,
+ &quot;/_a205&quot;, &quot;/_a206&quot;, &quot;/_a207&quot;, &quot;/_a208&quot;,
+ &quot;/_a209&quot;, &quot;/_a210&quot;, &quot;/_a211&quot;, &quot;/_a212&quot;,
+ &quot;/_a213&quot;, &quot;/_a214&quot;, &quot;/_a215&quot;, &quot;/_a216&quot;,
+ &quot;/_a217&quot;, &quot;/_a218&quot;, &quot;/_a219&quot;, &quot;/_a220&quot;,
+ &quot;/_a221&quot;, &quot;/_a222&quot;, &quot;/_a223&quot;, &quot;/_a224&quot;,
+ &quot;/_a225&quot;, &quot;/_a226&quot;, &quot;/_a227&quot;, &quot;/_a228&quot;,
+ &quot;/_a229&quot;, &quot;/_a230&quot;, &quot;/_a231&quot;, &quot;/_a232&quot;,
+ &quot;/_a233&quot;, &quot;/_a234&quot;, &quot;/_a235&quot;, &quot;/_a236&quot;,
+ &quot;/_a237&quot;, &quot;/_a238&quot;, &quot;/_a239&quot;, &quot;/_a240&quot;,
+ &quot;/_a241&quot;, &quot;/_a242&quot;, &quot;/_a243&quot;, &quot;/_a244&quot;,
+ &quot;/_a245&quot;, &quot;/_a246&quot;, &quot;/_a247&quot;, &quot;/_a248&quot;,
+ &quot;/_a249&quot;, &quot;/_a250&quot;, &quot;/_a251&quot;, &quot;/_a252&quot;,
+ &quot;/_a253&quot;, &quot;/_a254&quot;, &quot;/_a255&quot;);
+
+</pre><blockquote>Used <a href="#NWD3">above</a>.<p>
+</blockquote><p>The program accepts at most five command line arguments:
+<ul>
+<li> <code>-d size</code> --- explicitly specify the <code>$design_size</code>.</li>
+<li> <code>-nodel</code> --- suppress deleting of intermediate files,
+ such as <code>foo.tfm</code> or <code>foo.ddd</code>.</li>
+<li> <code>-eofill</code> --- ignore <b>fill</b> commands that are not
+ immediately after <b>gsave</b>. If this happens
+ <a name="NWD6">p</a>ut <b>eofill</b> in the end of the character.
+<li> The UniqueID, i.e., a unique font identity number, if not specified the
+ program will automatically generate one</li>
+<li> The name of the METAFONT file with or without extension.</li>
+</ul>
+In case it is invoked without any command line arguments,
+it prints usage information. In order to properly use the program,
+one has to provide only the font name.
+
+ <a name="NWD7">C</a>ommand line processing is being done in a relatively standard way.
+A while loop goes through each command line argument, checks its form
+and sets special global variables. In the case of the UniqueID argument
+we make sure it lies within the valid range, i.e., it is a number
+greater or equal than 4,000,000 and less than 5,000,000.
+
+<a name="NWD8">O</a>nce we have finished with the scanning of the command line arguments
+we must further process certain pieces of information.
+
+<pre><a name="NWmf29-ComU-1" href="#NWD8"><dfn>&lt;Command line argument handling&gt;=</dfn></a>
+$argc = @ARGV;
+$design_size = -1;
+$nodel = 0;
+$eofill = 0;
+$noID = 1;
+SWITCHES: while($_ = $ARGV[0], /^-/)
+{
+ shift;
+ if(/^-d(\d+)/)
+ {
+ $design_size = $1;
+ }
+ elsif(/^-nodel$/)
+ {
+ $nodel = 1;
+ }
+ elsif(/^-eofill$/)
+ {
+ $eofill = 1;
+ }
+ elsif(/^-I(\d+)$/)
+ {
+ die &quot;UniqueID must lie in the range 4,000,000...4,999,999\n&quot;
+ if ($1 &gt; 4999999 || $1 &lt; 4000000);
+ $UniqueID = $1;
+ $noID = 0;
+ }
+ elsif (!@ARGV)
+ {
+ last SWITCHES;
+ }
+}
+if (!@ARGV)
+{
+ print &lt;&lt;Usage;
+This ``mf2pt3'' version 1.1
+Usage: mf2pt3 [-dsize] [-nodel] [-eofill] [-IUniqueID] &lt;METAFONT file name&gt;
+Usage
+exit(0);
+}
+else
+{
+ $MFfile = $ARGV[0];
+}
+<a name="NWmf29-ComU-1-u1" href="#NWD9"><i>&lt;Further command line argument processing&gt;</i></a>
+
+</pre><blockquote>Used <a href="#NWD2">above</a>.<p>
+</blockquote><p> <a name="NWD9">I</a>f the user has specified a Unique Font Identity number, the program
+must generate one. Moreover, if the user hasn't explicitly specified a
+design size, the program must extract it from the font name. Finally, we
+have to remove the file name extension in order to get the name of
+the new PostScript font.
+
+<pre><a name="NWmf29-Fure-1" href="#NWD9"><dfn>&lt;Further command line argument processing&gt;=</dfn></a>
+if ($noID)
+{
+ <a name="NWmf29-Fure-1-u1" href="#NWDA"><i>&lt;Generate UniqueID&gt;</i></a>
+}
+<a name="NWmf29-Fure-1-u2" href="#NWDB"><i>&lt;Get design size&gt;</i></a>
+<a name="NWmf29-Fure-1-u3" href="#NWDC"><i>&lt;Remove file extension&gt;</i></a>
+
+</pre><blockquote>Used <a href="#NWD8">above</a>.<p>
+</blockquote><p><a name="NWDA">I</a>n case the user hasn't specified a UniqueID we must generate one
+For this purpose we use function <code>rand</code> and the random number generator
+seed (<code>srand</code>), in order to ensure some sort of... randomness.
+Since <code>rand</code> produces a number in
+the range 0...1, we multiply the output of <code>rand</code> by 999999 so that
+we have a number number in the range 0...999999, and we add to this
+the number 4000000 so that the final random number is in the expected
+range.
+
+<pre><a name="NWmf29-GenH-1" href="#NWDA"><dfn>&lt;Generate UniqueID&gt;=</dfn></a>
+ srand();
+ $UniqueID = int(999999*rand())+4000000;
+
+</pre><blockquote>Used <a href="#NWD9">above</a>.<p>
+</blockquote><p> As it is know a METAFONT font name consists of two parts: a symbolic
+acronym, specifying its characteristics, and a number specifying its
+design size. The number can be either a two or a four digit number (compare
+<a name="NWDB">c</a>mr17 with ecsx1095.) In both cases we extract the number from the
+font name and then in the first case we divide it by 10 and in the second
+case we divide it by 1000 to get the magnification factor. Finally, we
+set the magnification. The number 100 is chosen because font data
+must be integers greater than 100. Of course, nn case the user has already
+given the design size, there is no reason to extract if from the font name.
+But, still we must process it in oder to ensure the generation of valid
+output.
+
+<pre><a name="NWmf29-GetF-1" href="#NWDB"><dfn>&lt;Get design size&gt;=</dfn></a>
+
+if ($design_size == -1)
+{
+ if ($MFfile =~ /\D+(\d+)$/)
+ {
+ $design_size=$1;
+ }
+ else
+ {
+ die &quot;$MFfile must be a PostScript font name: there is no design size.\n&quot;;
+ }
+}
+if($design_size &gt;100)
+{
+ $mag_factor=$design_size/1000;
+}
+else
+{
+ $mag_factor=$design_size/10;
+}
+$mag = 100 /$mag_factor;
+
+</pre><blockquote>Used <a href="#NWD9">above</a>.<p>
+</blockquote><p><a name="NWDC">I</a>f the user supplies the METAFONT file name with an extension
+we simple chop it off. This is done pretty simple by employing Perl's
+fantastic regular-expression mechanism.
+
+<pre><a name="NWmf29-RemL-1" href="#NWDC"><dfn>&lt;Remove file extension&gt;=</dfn></a>
+ $MFfile = $1 if $MFfile =~ /(\w+)\.\w*/;
+
+</pre><blockquote>Used <a href="#NWD9">above</a>.<p>
+</blockquote><p><a name="NWDD">W</a>e proceed now to the generation of the EPSF files. This task
+is performed by METAPOST. Initially, we create the EPSF files by executing
+<code>mfplain</code>. If for some reason there is no TFM file, the program
+stops and prints an error message. (It is most likely that the user has
+typed the name of non-existing METAFONT font.) The <code>$mfplain</code> command
+is augmented by the magnification factor and the input part.
+
+<pre><a name="NWmf29-GenO-1" href="#NWDD"><dfn>&lt;Generation of EPSF files&gt;=</dfn></a>
+ $mfplain .= &quot;mag=$mag; input $MFfile \'&quot;;
+ system($mfplain);
+ if (!(-e &quot;$MFfile.tfm&quot;))
+ {
+ $nodel || unlink &quot;mpout.log&quot;;
+ die &quot;$MFfile: no such font in system\n&quot;;
+ }
+
+</pre><blockquote>Used <a href="#NWD2">above</a>.<p>
+</blockquote><p>Since, the various EPSF files have been generated successfully, we
+can now start collecting the <code>BoundingBox</code> information. First, we
+<a name="NWDE">g</a>et the names of all EPSF files. Next, we must open each EPSF file,
+and find the line that contains the <code>BoundingBox</code> information.
+This is easy, since in an EPSF file the line that contains this
+piece of information look like the following one:
+<code>%%BoundingBox: 0 -1 6 6</code>. While doing this we must get the
+<code>FontBBox</code> information. We use four variables for this purpose.
+The next step is produce the first part of the font, i.e., the
+metrics section and the encoding information.
+
+<pre><a name="NWmf29-ConR-1" href="#NWDE"><dfn>&lt;Construction of Type 3 font&gt;=</dfn></a>
+ <a name="NWmf29-ConR-1-u1" href="#NWDF"><i>&lt;Get the file names of the EPSF files&gt;</i></a>
+ $Min_llx = $Min_lly = $Max_urx = $Max_ury = 0;
+ <a name="NWmf29-ConR-1-u2" href="#NWDG"><i>&lt;get bounding boxes&gt;</i></a>
+<a name="NWmf29-ConR-1-u3" href="#NWDH"><i>&lt;Generate Type 3 Font&gt;</i></a>
+
+
+</pre><blockquote>Used <a href="#NWD2">above</a>.<p>
+</blockquote><p><a name="NWDF">I</a>t could be easy to get the file names by a simple pipe, but
+since this program may be used in OS other that Unix, we prefer
+to do it in a more portable way--- we simply open the directory
+and store all the file names that fulfill with a name that is
+identical to <code>$MFfile</code>.
+
+<pre><a name="NWmf29-Geta-1" href="#NWDF"><dfn>&lt;Get the file names of the EPSF files&gt;=</dfn></a>
+ opendir(Dir, &quot;.&quot;);
+ $pattern = &quot;$MFfile&quot; . &quot;\\.\\d+&quot;;
+ @EPSFs = grep(/$pattern/, readdir(Dir));
+ closedir Dir;
+
+</pre><blockquote>Used <a href="#NWDE">above</a>.<p>
+</blockquote><p><a name="NWDG">I</a>n order to get the <code>BoundingBox</code> information we open each
+EPSF file and we get the line that contains these information. For
+this we simply employ the pattern matching capabilities of Perl. Then
+we store these information in a compact way to the appropriate index
+in the <code>BoundingBox</code> array. (Readers not familiar with regular
+expressions should consult the Perl manual.) As a side effect we calculate
+the total number of characters that the font will provide in variable
+<code>$total_chars</code> (plus one as there is always the <code>/.notdef</code> character).
+
+<pre><a name="NWmf29-getI-1" href="#NWDG"><dfn>&lt;get bounding boxes&gt;=</dfn></a>
+
+ $total_chars = @EPSFs+1;
+ foreach $file (@EPSFs)
+ {
+ open(EPSF_FILE,&quot;$file&quot;)||die &quot;Can't open file $file\n&quot;;
+ while (&lt;EPSF_FILE&gt;)
+ {
+ $BBox = pack(&quot;ai4&quot;,&quot;d&quot;,$1,$2,$3,$4)
+ if /%%BoundingBox: (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
+ }
+ close EPSF_FILE;
+ $_=$file;
+ /$MFfile\.(\d+)/;
+ $BoundingBox[$1] = $BBox;
+ ($_, $llx, $lly, $urx, $ury) = unpack(&quot;ai4&quot;, $BBox);
+ $Min_llx = $llx if $llx &lt; $Min_llx;
+ $Min_lly = $lly if $lly &lt; $Min_lly;
+ $Max_urx = $urx if $urx &gt; $Max_urx;
+ $Max_ury = $ury if $ury &gt; $Max_ury;
+ }
+
+</pre><blockquote>Used <a href="#NWDE">above</a>.<p>
+</blockquote><p><a name="NWDH">W</a>e now have all the information we need in order to generate the complete
+Type 3 font. We first, create the font file and then we print
+to it some information which are pretty standard, such as the <code>/FontType</code>,
+etc. Next, we let PostScript know which characters will the font provide,
+and then we generate the <code>BoundingBox</code> dictionary, the <code>Metrics</code>
+dictionary, and the <code>CharProcs</code> dictionary. Finally, we generate the
+<code>BuildGlyph</code> procedure and we define the font.
+
+
+<pre><a name="NWmf29-GenK-1" href="#NWDH"><dfn>&lt;Generate Type 3 Font&gt;=</dfn></a>
+ open(TYPE3, &quot;&gt;$MFfile.pt3&quot;)||die &quot;Can't create file $MFfile.pt3\n&quot;;
+ $date = localtime;
+ print TYPE3 &lt;&lt;DATA;
+%!PS-Adobe-2.0
+%%Creator: mf2pt3 1.1 Copyright 1998 Apostolos Syropoulos
+%%CreationDate: $date
+%%EndComments
+11 dict % 11 entries
+begin
+ /FontType 3 def
+ /UniqueID $UniqueID def
+ /FontName /$MFfile def
+ /FontBBox [ $Min_llx $Min_lly $Max_urx $Max_ury] def
+ /FontMatrix [ 0.001 0 0 0.001 0 0 ] def
+ /Encoding 256 array def
+ 0 1 255 { Encoding exch /.notdef put } for
+DATA
+ <a name="NWmf29-GenK-1-u1" href="#NWDI"><i>&lt;make known all the characters of the font&gt;</i></a>
+ <a name="NWmf29-GenK-1-u2" href="#NWDJ"><i>&lt;generate bounding box dictionary&gt;</i></a>
+ <a name="NWmf29-GenK-1-u3" href="#NWDK"><i>&lt;generate metrics dictionary&gt;</i></a>
+ <a name="NWmf29-GenK-1-u4" href="#NWDL"><i>&lt;generate CharProcs dictionary&gt;</i></a>
+<a name="NWmf29-GenK-1-u5" href="#NWDN"><i>&lt;generate BuildGlyph procedure&gt;</i></a>
+
+</pre><blockquote>Used <a href="#NWDE">above</a>.<p>
+</blockquote><p><a name="NWDI">A</a>fter initializing the Encoding vector, we must make all those
+assignments so that PostScript will know which characters are in this font.
+This is trivial--- we simply scan the <code>BoundingBox</code> array and for
+each defined character we print a line of the form <code>Encoding N Name</code>,
+where <code>N</code> is the number of the character and <code>Name</code> the <code>N</code>th
+entry in the Encoding array.
+
+<pre><a name="NWmf29-makf-1" href="#NWDI"><dfn>&lt;make known all the characters of the font&gt;=</dfn></a>
+ for($i=0; $i&lt;=256; $i++)
+ {
+ $_ = unpack(&quot;ai4&quot;, $BoundingBox[$i]);
+ print TYPE3 &quot;Encoding $i $Encoding[$i] put\n&quot; if $_ eq &quot;d&quot;;
+ }
+
+</pre><blockquote>Used <a href="#NWDH">above</a>.<p>
+</blockquote><p><a name="NWDJ">I</a>n general the bounding boxes dictionary consists of some of entries
+like the following one: <code>/A [ 0 -100 600 700 ] def</code>. Since, the numbers
+are stored in the <code>BoundingBox</code> array our task is simple. However we must
+print some data that let PostScript know the size of the dictionary.
+
+<pre><a name="NWmf29-genW-1" href="#NWDJ"><dfn>&lt;generate bounding box dictionary&gt;=</dfn></a>
+ print TYPE3 &quot;/BoundingBoxes $total_chars dict def\n&quot;;
+ print TYPE3 &quot;BoundingBoxes begin\n&quot;;
+ print TYPE3 &quot;/.notdef { 0 0 0 0 } def\n&quot;;
+ for($i=0; $i&lt;=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack(&quot;ai4&quot;,$BoundingBox[$i]);
+ print TYPE3 &quot;$Encoding[$i] [ $llx $lly $urx $ury ] def\n&quot;
+ if $_ eq &quot;d&quot;;
+ }
+ print TYPE3 &quot;end %BoundingBoxes\n&quot;;
+
+
+</pre><blockquote>Used <a href="#NWDH">above</a>.<p>
+</blockquote><p><a name="NWDK">T</a>he metrics dictionary is created in way similar to the bounding box
+dictionary. Generally it consists of lines of the form: <code>/A 600 def</code>
+where the number is the difference urx-llx. As usual we must first
+output some book-keeping information.
+
+<pre><a name="NWmf29-genR-1" href="#NWDK"><dfn>&lt;generate metrics dictionary&gt;=</dfn></a>
+ print TYPE3 &quot;/Metrics $total_chars dict def\n&quot;;
+ print TYPE3 &quot;Metrics begin\n&quot;;
+ print TYPE3 &quot;/.notdef 0 def\n&quot;;
+ for($i=0; $i&lt;=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack(&quot;ai4&quot;,$BoundingBox[$i]);
+ $diff = $urx - $llx;
+ print TYPE3 &quot;$Encoding[$i] $diff def\n&quot; if $_ eq &quot;d&quot;;
+ }
+ print TYPE3 &quot;end %Metrics\n&quot;;
+
+
+</pre><blockquote>Used <a href="#NWDH">above</a>.<p>
+</blockquote><p>Generating the CharProcs dictionary involves the extraction of
+the PostScript code from the various EPSF files. Moreover, we must
+be careful to avoid extracting comments and to delete the keyword
+<code><a name="NWDL">showpage</a></code> from the source code. Both, operations are getting done
+by making use of the regular expression facilities and operators that
+Perl provide. Apart from that we generation process is similar to
+the previous ones. First, we generate some standard code and then
+the PostScript code for each character. Please note, that after
+initial experimentation I have found that METAPOST generates
+a lot of strange <code>setgray</code> commands which actually confuse a
+PostScript interpreter, so the program eliminates all such commands.
+
+<pre><a name="NWmf29-genT-1" href="#NWDL"><dfn>&lt;generate CharProcs dictionary&gt;=</dfn></a>
+ print TYPE3 &quot;/CharProcs $total_chars dict def\n&quot;;
+ print TYPE3 &quot;CharProcs begin\n&quot;;
+ print TYPE3 &quot;/.notdef { } def\n&quot;;
+ for($i=0; $i&lt;=256; $i++)
+ {
+ $_ = unpack(&quot;ai4&quot;, $BoundingBox[$i]);
+ if ($_ eq &quot;d&quot;)
+ {
+ open(CHAR, &quot;$MFfile.$i&quot;)||
+ die &quot;Can't open file $MFfile.$i\n&quot;;
+ $code = &quot;&quot;; #&quot;100 100 scale\n&quot;;
+ while (&lt;CHAR&gt;)
+ {
+ $code .= $_ if $_ !~ /^%/;
+ }
+ close CHAR;
+ $code =~ s/showpage\n*//mg; #eliminate showpage
+ $code =~ s/\d setgray//mg; #eliminate setgray
+ $code =~ s/(\d*)\.\d+/$1/mg; #chop decimal digits
+ print TYPE3 $Encoding[$i], &quot; { %\n&quot;;
+ if ($eofill)
+ {
+ <a name="NWmf29-genT-1-u1" href="#NWDM"><i>&lt;Manipulate fills and newpaths&gt;</i></a>
+ }
+ else
+ {
+ print TYPE3 $code;
+ }
+ print TYPE3 &quot;} bind def\n&quot;;
+ }
+ }
+ print TYPE3 &quot;end %CharProcs\n&quot;;
+
+</pre><blockquote>Used <a href="#NWDH">above</a>.<p>
+</blockquote><p><a name="NWDM">I</a>n the <code>eofill</code> mode, we eliminate <b>newpath</b> calls and
+<b>fill</b> calls that are not following <b>gsave</b>.
+And in the end we call eofill.
+<pre><a name="NWmf29-ManT-1" href="#NWDM"><dfn>&lt;Manipulate fills and newpaths&gt;=</dfn></a>
+$code =~ s/gsave fill/GSAVE FILL/mg; # save for soon restore
+$code =~ s/fill//mg; # eliminate fill
+$code =~ s/newpath//mg; # eliminate fill
+$code =~ s/GSAVE FILL/gsave fill/mg; # restore
+print TYPE3 $code, &quot;eofill\n&quot;;
+
+</pre><blockquote>Used <a href="#NWDL">below</a>.<p>
+</blockquote><p><a name="NWDN">P</a>rocedure <code>BuildGlyph</code> is very important as it defines the way
+PostScript will be able to use the font. The generated code is
+pretty standard.
+
+<pre><a name="NWmf29-genT.2-1" href="#NWDN"><dfn>&lt;generate BuildGlyph procedure&gt;=</dfn></a>
+ print TYPE3 &lt;&lt;BUILDGLYPH;
+ /BuildGlyph {
+ exch
+ begin
+ dup
+ Metrics exch get % get x displacement
+ 0 % set y displacement
+ 2 index
+ BoundingBoxes
+ exch get aload pop
+ setcachedevice
+ CharProcs exch get
+ exec
+ fill
+ end
+ } def
+ currentdict
+end
+/$MFfile exch definefont
+pop
+BUILDGLYPH
+close TYPE3;
+
+</pre><blockquote>Used <a href="#NWDH">above</a>.<p>
+</blockquote><p><a name="NWDO">N</a>ow that we are done we must free some space on our hard disks, unless
+of course the user has decided the opposite. In case we are allowed to free
+space, we remove all the EPSF files, the log file and the TFM file, leaving
+only the Type 3 font file.
+
+<pre><a name="NWmf29-DelO-1" href="#NWDO"><dfn>&lt;Delete unnecessary files&gt;=</dfn></a>
+ if (!$nodel)
+ {
+ unlink @EPSFs;
+ unlink &quot;$MFfile.log&quot;, &quot;$MFfile.tfm&quot;;
+ }
+
+</pre><blockquote>Used <a href="#NWD2">above</a>.<p>
+</blockquote><p><a name="NWDP">*</a><b><h2>Acknowledgments</h2></b><br>
+John Hobby (the creator of METAPOST) and Yotam Medini
+had helped me in the development phase and the debugging phase
+correspondingly. Many thanks to both of you!
+
+
+<ul>
+<li><a href="#NWD2"><i>&lt;*&gt;</i></a>: <a href="#NWD2">D1</a>
+<li><a href="#NWD4"><i>&lt;BoundingBox initialization&gt;</i></a>: <a href="#NWD3">U1</a>, <a href="#NWD4">D2</a>
+<li><a href="#NWD8"><i>&lt;Command line argument handling&gt;</i></a>: <a href="#NWD2">U1</a>, <a href="#NWD8">D2</a>
+<li><a href="#NWDE"><i>&lt;Construction of Type 3 font&gt;</i></a>: <a href="#NWD2">U1</a>, <a href="#NWDE">D2</a>
+<li><a href="#NWDO"><i>&lt;Delete unnecessary files&gt;</i></a>: <a href="#NWD2">U1</a>, <a href="#NWDO">D2</a>
+<li><a href="#NWD5"><i>&lt;Encoding array initialization&gt;</i></a>: <a href="#NWD3">U1</a>, <a href="#NWD5">D2</a>
+<li><a href="#NWD9"><i>&lt;Further command line argument processing&gt;</i></a>: <a href="#NWD8">U1</a>, <a href="#NWD9">D2</a>
+<li><a href="#NWDH"><i>&lt;Generate Type 3 Font&gt;</i></a>: <a href="#NWDE">U1</a>, <a href="#NWDH">D2</a>
+<li><a href="#NWDA"><i>&lt;Generate UniqueID&gt;</i></a>: <a href="#NWD9">U1</a>, <a href="#NWDA">D2</a>
+<li><a href="#NWDD"><i>&lt;Generation of EPSF files&gt;</i></a>: <a href="#NWD2">U1</a>, <a href="#NWDD">D2</a>
+<li><a href="#NWDB"><i>&lt;Get design size&gt;</i></a>: <a href="#NWD9">U1</a>, <a href="#NWDB">D2</a>
+<li><a href="#NWDF"><i>&lt;Get the file names of the EPSF files&gt;</i></a>: <a href="#NWDE">U1</a>, <a href="#NWDF">D2</a>
+<li><a href="#NWD3"><i>&lt;Initialization of constants&gt;</i></a>: <a href="#NWD2">U1</a>, <a href="#NWD3">D2</a>
+<li><a href="#NWDM"><i>&lt;Manipulate fills and newpaths&gt;</i></a>: <a href="#NWDL">U1</a>, <a href="#NWDM">D2</a>
+<li><a href="#NWDC"><i>&lt;Remove file extension&gt;</i></a>: <a href="#NWD9">U1</a>, <a href="#NWDC">D2</a>
+<li><a href="#NWDN"><i>&lt;generate BuildGlyph procedure&gt;</i></a>: <a href="#NWDH">U1</a>, <a href="#NWDN">D2</a>
+<li><a href="#NWDL"><i>&lt;generate CharProcs dictionary&gt;</i></a>: <a href="#NWDH">U1</a>, <a href="#NWDL">D2</a>
+<li><a href="#NWDJ"><i>&lt;generate bounding box dictionary&gt;</i></a>: <a href="#NWDH">U1</a>, <a href="#NWDJ">D2</a>
+<li><a href="#NWDK"><i>&lt;generate metrics dictionary&gt;</i></a>: <a href="#NWDH">U1</a>, <a href="#NWDK">D2</a>
+<li><a href="#NWDG"><i>&lt;get bounding boxes&gt;</i></a>: <a href="#NWDE">U1</a>, <a href="#NWDG">D2</a>
+<li><a href="#NWDI"><i>&lt;make known all the characters of the font&gt;</i></a>: <a href="#NWDH">U1</a>, <a href="#NWDI">D2</a>
+</ul>
+</body></html>
+
diff --git a/fonts/utilities/mf2pt3/mf2pt3.nw b/fonts/utilities/mf2pt3/mf2pt3.nw
new file mode 100644
index 0000000000..a7393932c7
--- /dev/null
+++ b/fonts/utilities/mf2pt3/mf2pt3.nw
@@ -0,0 +1,530 @@
+<b>mf2pt3</b> (c) Copyright 1998 Apostolos Syropoulos
+[[apostolo@obelix.ee.duth.gr]] <p>
+This is program [[mf2pt3]] a Perl script that generates a PostScript
+Type 3 font that corresponds to a METAFONT font description. In order
+to achieve its goal the program utilizes another program: mfplain
+(METAPOST with the mfplain base preloaded). This program generates EPSF
+files for each character. This document assumes that the reader is
+familiar with the Type 3 font terminology and its structure. For
+more information one should consult the ``PostScript User Manual'',
+or any good book on PostScript like ``Postscript by Example'',
+by Henry McGilton and Mary Campione, published by Addison-Wesley Pub Co.
+
+@ We now describe the way the program operates. First of all, we
+generate for each character of a METAFONT font an EPSF file. Next
+we collect the [[BoundingBox]] information for each character, as this
+piece of information is vital to the construction of the Type 3 font.
+Now we can proceed with the construction of the font. Finally, we
+delete some unnecessary files and we output the line the user must
+add to his/her [[psfonts.map]] file in order to use the Type 3 font
+when he/she creates a PostScript file from a DVI file.
+
+<<*>>=
+#!/usr/bin/perl
+#
+#(c) Copyright 1998 Apostolos Syropoulos
+# apostolo@obelix.ee.duth.gr
+#
+<<Initialization of constants>>
+<<Command line argument handling>>
+<<Generation of EPSF files>>
+<<Construction of Type 3 font>>
+<<Delete unnecessary files>>
+print "\n$MFfile $MFfile <$MFfile.pt3\n";
+
+@ Since we don't know on what system the program will be used, we
+must make sure it calls the GhostScript and METAPOST programs in the proper
+way. Moreover, we supply to each command the proper command line switches.
+The magnification is set to 100 as the usual design size is 10 pt.
+The [[BoundingBox]] information are kept in a compact format in an array.
+
+<<Initialization of constants>>=
+ $mfplain="mfplain \'\\mode=localfont; \\batchmode; ";
+ <<BoundingBox initialization>>
+ <<Encoding array initialization>>
+
+@ Since Perl does not provide record structures, we use the [[pack]]
+function to create a structure which will contain the [[BoundingBox]]
+information. Each [[BoundingBox]] corresponds to four numbers: [[llx]],
+[[lly]], [[urx]], and [[ury]]. If any of the 256 character slots is
+undefined each of these four numbers is set to zero. For efficiency reasons
+each [[BoundingBox]] structure contains one more piece of information--- an
+ASCII character, which indicates whether the corresponding character is
+defined ("d") or undefined ("u"). All the [[BoundingBox]] information are
+kept in an array which is assumed to contain only undefined characters.
+
+<<BoundingBox initialization>>=
+$notdef=pack("ai4","u",0,0,0,0);
+for($i=0; $i<=255; $i++){ $BoundingBox[$i]=$notdef }
+
+@ The encoding vector is a vital part of a PostScript font. The internal
+name of each character is completely irrelevant to the final output. So,
+someone can choose any name it pleases him.
+
+<<Encoding array initialization>>=
+@Encoding = ("/_a0", "/_a1", "/_a2", "/_a3", "/_a4",
+ "/_a5", "/_a6", "/_a7", "/_a8",
+ "/_a9", "/_a10", "/_a11", "/_a12",
+ "/_a13", "/_a14", "/_a15", "/_a16",
+ "/_a17", "/_a18", "/_a19", "/_a20",
+ "/_a21", "/_a22", "/_a23", "/_a24",
+ "/_a25", "/_a26", "/_a27", "/_a28",
+ "/_a29", "/_a30", "/_a31", "/_a32",
+ "/_a33", "/_a34", "/_a35", "/_a36",
+ "/_a37", "/_a38", "/_a39", "/_a40",
+ "/_a41", "/_a42", "/_a43", "/_a44",
+ "/_a45", "/_a46", "/_a47", "/_a48",
+ "/_a49", "/_a50", "/_a51", "/_a52",
+ "/_a53", "/_a54", "/_a55", "/_a56",
+ "/_a57", "/_a58", "/_a59", "/_a60",
+ "/_a61", "/_a62", "/_a63", "/_a64",
+ "/_a65", "/_a66", "/_a67", "/_a68",
+ "/_a69", "/_a70", "/_a71", "/_a72",
+ "/_a73", "/_a74", "/_a75", "/_a76",
+ "/_a77", "/_a78", "/_a79", "/_a80",
+ "/_a81", "/_a82", "/_a83", "/_a84",
+ "/_a85", "/_a86", "/_a87", "/_a88",
+ "/_a89", "/_a90", "/_a91", "/_a92",
+ "/_a93", "/_a94", "/_a95", "/_a96",
+ "/_a97", "/_a98", "/_a99", "/_a100",
+ "/_a101", "/_a102", "/_a103", "/_a104",
+ "/_a105", "/_a106", "/_a107", "/_a108",
+ "/_a109", "/_a110", "/_a111", "/_a112",
+ "/_a113", "/_a114", "/_a115", "/_a116",
+ "/_a117", "/_a118", "/_a119", "/_a120",
+ "/_a121", "/_a122", "/_a123", "/_a124",
+ "/_a125", "/_a126", "/_a127", "/_a128",
+ "/_a129", "/_a130", "/_a131", "/_a132",
+ "/_a133", "/_a134", "/_a135", "/_a136",
+ "/_a137", "/_a138", "/_a139", "/_a140",
+ "/_a141", "/_a142", "/_a143", "/_a144",
+ "/_a145", "/_a146", "/_a147", "/_a148",
+ "/_a149", "/_a150", "/_a151", "/_a152",
+ "/_a153", "/_a154", "/_a155", "/_a156",
+ "/_a157", "/_a158", "/_a159", "/_a160",
+ "/_a161", "/_a162", "/_a163", "/_a164",
+ "/_a165", "/_a166", "/_a167", "/_a168",
+ "/_a169", "/_a170", "/_a171", "/_a172",
+ "/_a173", "/_a174", "/_a175", "/_a176",
+ "/_a177", "/_a178", "/_a179", "/_a180",
+ "/_a181", "/_a182", "/_a183", "/_a184",
+ "/_a185", "/_a186", "/_a187", "/_a188",
+ "/_a189", "/_a190", "/_a191", "/_a192",
+ "/_a193", "/_a194", "/_a195", "/_a196",
+ "/_a197", "/_a198", "/_a199", "/_a200",
+ "/_a201", "/_a202", "/_a203", "/_a204",
+ "/_a205", "/_a206", "/_a207", "/_a208",
+ "/_a209", "/_a210", "/_a211", "/_a212",
+ "/_a213", "/_a214", "/_a215", "/_a216",
+ "/_a217", "/_a218", "/_a219", "/_a220",
+ "/_a221", "/_a222", "/_a223", "/_a224",
+ "/_a225", "/_a226", "/_a227", "/_a228",
+ "/_a229", "/_a230", "/_a231", "/_a232",
+ "/_a233", "/_a234", "/_a235", "/_a236",
+ "/_a237", "/_a238", "/_a239", "/_a240",
+ "/_a241", "/_a242", "/_a243", "/_a244",
+ "/_a245", "/_a246", "/_a247", "/_a248",
+ "/_a249", "/_a250", "/_a251", "/_a252",
+ "/_a253", "/_a254", "/_a255");
+
+@ The program accepts at most five command line arguments:
+<ul>
+<li> [[-d size]] --- explicitly specify the [[$design_size]].</li>
+<li> [[-nodel]] --- suppress deleting of intermediate files,
+ such as [[foo.tfm]] or [[foo.ddd]].</li>
+<li> [[-eofill]] --- ignore <b>fill</b> commands that are not
+ immediately after <b>gsave</b>. If this happens
+ put <b>eofill</b> in the end of the character.
+<li> The UniqueID, i.e., a unique font identity number, if not specified the
+ program will automatically generate one</li>
+<li> The name of the METAFONT file with or without extension.</li>
+</ul>
+In case it is invoked without any command line arguments,
+it prints usage information. In order to properly use the program,
+one has to provide only the font name.
+
+@ Command line processing is being done in a relatively standard way.
+A while loop goes through each command line argument, checks its form
+and sets special global variables. In the case of the UniqueID argument
+we make sure it lies within the valid range, i.e., it is a number
+greater or equal than 4,000,000 and less than 5,000,000.
+
+@ Once we have finished with the scanning of the command line arguments
+we must further process certain pieces of information.
+
+<<Command line argument handling>>=
+$argc = @ARGV;
+$design_size = -1;
+$nodel = 0;
+$eofill = 0;
+$noID = 1;
+SWITCHES: while($_ = $ARGV[0], /^-/)
+{
+ shift;
+ if(/^-d(\d+)/)
+ {
+ $design_size = $1;
+ }
+ elsif(/^-nodel$/)
+ {
+ $nodel = 1;
+ }
+ elsif(/^-eofill$/)
+ {
+ $eofill = 1;
+ }
+ elsif(/^-I(\d+)$/)
+ {
+ die "UniqueID must lie in the range 4,000,000...4,999,999\n"
+ if ($1 > 4999999 || $1 < 4000000);
+ $UniqueID = $1;
+ $noID = 0;
+ }
+ elsif (!@ARGV)
+ {
+ last SWITCHES;
+ }
+}
+if (!@ARGV)
+{
+ print <<Usage;
+This ``mf2pt3'' version 1.1
+Usage: mf2pt3 [-dsize] [-nodel] [-eofill] [-IUniqueID] <METAFONT file name>
+Usage
+exit(0);
+}
+else
+{
+ $MFfile = $ARGV[0];
+}
+<<Further command line argument processing>>
+
+@ If the user has specified a Unique Font Identity number, the program
+must generate one. Moreover, if the user hasn't explicitly specified a
+design size, the program must extract it from the font name. Finally, we
+have to remove the file name extension in order to get the name of
+the new PostScript font.
+
+<<Further command line argument processing>>=
+if ($noID)
+{
+ <<Generate UniqueID>>
+}
+<<Get design size>>
+<<Remove file extension>>
+
+@ In case the user hasn't specified a UniqueID we must generate one
+For this purpose we use function [[rand]] and the random number generator
+seed ([[srand]]), in order to ensure some sort of... randomness.
+Since [[rand]] produces a number in
+the range 0...1, we multiply the output of [[rand]] by 999999 so that
+we have a number number in the range 0...999999, and we add to this
+the number 4000000 so that the final random number is in the expected
+range.
+
+<<Generate UniqueID>>=
+ srand();
+ $UniqueID = int(999999*rand())+4000000;
+
+@ As it is know a METAFONT font name consists of two parts: a symbolic
+acronym, specifying its characteristics, and a number specifying its
+design size. The number can be either a two or a four digit number (compare
+cmr17 with ecsx1095.) In both cases we extract the number from the
+font name and then in the first case we divide it by 10 and in the second
+case we divide it by 1000 to get the magnification factor. Finally, we
+set the magnification. The number 100 is chosen because font data
+must be integers greater than 100. Of course, nn case the user has already
+given the design size, there is no reason to extract if from the font name.
+But, still we must process it in oder to ensure the generation of valid
+output.
+
+<<Get design size>>=
+
+if ($design_size == -1)
+{
+ if ($MFfile =~ /\D+(\d+)$/)
+ {
+ $design_size=$1;
+ }
+ else
+ {
+ die "$MFfile must be a PostScript font name: there is no design size.\n";
+ }
+}
+if($design_size >100)
+{
+ $mag_factor=$design_size/1000;
+}
+else
+{
+ $mag_factor=$design_size/10;
+}
+$mag = 100 /$mag_factor;
+
+@ If the user supplies the METAFONT file name with an extension
+we simple chop it off. This is done pretty simple by employing Perl's
+fantastic regular-expression mechanism.
+
+<<Remove file extension>>=
+ $MFfile = $1 if $MFfile =~ /(\w+)\.\w*/;
+
+@ We proceed now to the generation of the EPSF files. This task
+is performed by METAPOST. Initially, we create the EPSF files by executing
+[[mfplain]]. If for some reason there is no TFM file, the program
+stops and prints an error message. (It is most likely that the user has
+typed the name of non-existing METAFONT font.) The [[$mfplain]] command
+is augmented by the magnification factor and the input part.
+
+<<Generation of EPSF files>>=
+ $mfplain .= "mag=$mag; input $MFfile \'";
+ system($mfplain);
+ if (!(-e "$MFfile.tfm"))
+ {
+ $nodel || unlink "mpout.log";
+ die "$MFfile: no such font in system\n";
+ }
+
+@ Since, the various EPSF files have been generated successfully, we
+can now start collecting the [[BoundingBox]] information. First, we
+get the names of all EPSF files. Next, we must open each EPSF file,
+and find the line that contains the [[BoundingBox]] information.
+This is easy, since in an EPSF file the line that contains this
+piece of information look like the following one:
+[[%%BoundingBox: 0 -1 6 6]]. While doing this we must get the
+[[FontBBox]] information. We use four variables for this purpose.
+The next step is produce the first part of the font, i.e., the
+metrics section and the encoding information.
+
+<<Construction of Type 3 font>>=
+ <<Get the file names of the EPSF files>>
+ $Min_llx = $Min_lly = $Max_urx = $Max_ury = 0;
+ <<get bounding boxes>>
+<<Generate Type 3 Font>>
+
+
+@ It could be easy to get the file names by a simple pipe, but
+since this program may be used in OS other that Unix, we prefer
+to do it in a more portable way--- we simply open the directory
+and store all the file names that fulfill with a name that is
+identical to [[$MFfile]].
+
+<<Get the file names of the EPSF files>>=
+ opendir(Dir, ".");
+ $pattern = "$MFfile" . "\\.\\d+";
+ @EPSFs = grep(/$pattern/, readdir(Dir));
+ closedir Dir;
+
+@ In order to get the [[BoundingBox]] information we open each
+EPSF file and we get the line that contains these information. For
+this we simply employ the pattern matching capabilities of Perl. Then
+we store these information in a compact way to the appropriate index
+in the [[BoundingBox]] array. (Readers not familiar with regular
+expressions should consult the Perl manual.) As a side effect we calculate
+the total number of characters that the font will provide in variable
+[[$total_chars]] (plus one as there is always the [[/.notdef]] character).
+
+<<get bounding boxes>>=
+
+ $total_chars = @EPSFs+1;
+ foreach $file (@EPSFs)
+ {
+ open(EPSF_FILE,"$file")||die "Can't open file $file\n";
+ while (<EPSF_FILE>)
+ {
+ $BBox = pack("ai4","d",$1,$2,$3,$4)
+ if /%%BoundingBox: (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
+ }
+ close EPSF_FILE;
+ $_=$file;
+ /$MFfile\.(\d+)/;
+ $BoundingBox[$1] = $BBox;
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4", $BBox);
+ $Min_llx = $llx if $llx < $Min_llx;
+ $Min_lly = $lly if $lly < $Min_lly;
+ $Max_urx = $urx if $urx > $Max_urx;
+ $Max_ury = $ury if $ury > $Max_ury;
+ }
+
+@ We now have all the information we need in order to generate the complete
+Type 3 font. We first, create the font file and then we print
+to it some information which are pretty standard, such as the [[/FontType]],
+etc. Next, we let PostScript know which characters will the font provide,
+and then we generate the [[BoundingBox]] dictionary, the [[Metrics]]
+dictionary, and the [[CharProcs]] dictionary. Finally, we generate the
+[[BuildGlyph]] procedure and we define the font.
+
+
+<<Generate Type 3 Font>>=
+ open(TYPE3, ">$MFfile.pt3")||die "Can't create file $MFfile.pt3\n";
+ $date = localtime;
+ print TYPE3 <<DATA;
+%!PS-Adobe-2.0
+%%Creator: mf2pt3 1.1 Copyright 1998 Apostolos Syropoulos
+%%CreationDate: $date
+%%EndComments
+11 dict % 11 entries
+begin
+ /FontType 3 def
+ /UniqueID $UniqueID def
+ /FontName /$MFfile def
+ /FontBBox [ $Min_llx $Min_lly $Max_urx $Max_ury] def
+ /FontMatrix [ 0.001 0 0 0.001 0 0 ] def
+ /Encoding 256 array def
+ 0 1 255 { Encoding exch /.notdef put } for
+DATA
+ <<make known all the characters of the font>>
+ <<generate bounding box dictionary>>
+ <<generate metrics dictionary>>
+ <<generate CharProcs dictionary>>
+<<generate BuildGlyph procedure>>
+
+@ After initializing the Encoding vector, we must make all those
+assignments so that PostScript will know which characters are in this font.
+This is trivial--- we simply scan the [[BoundingBox]] array and for
+each defined character we print a line of the form [[Encoding N Name]],
+where [[N]] is the number of the character and [[Name]] the [[N]]th
+entry in the Encoding array.
+
+<<make known all the characters of the font>>=
+ for($i=0; $i<=256; $i++)
+ {
+ $_ = unpack("ai4", $BoundingBox[$i]);
+ print TYPE3 "Encoding $i $Encoding[$i] put\n" if $_ eq "d";
+ }
+
+@ In general the bounding boxes dictionary consists of some of entries
+like the following one: [[/A [ 0 -100 600 700 ] def]]. Since, the numbers
+are stored in the [[BoundingBox]] array our task is simple. However we must
+print some data that let PostScript know the size of the dictionary.
+
+<<generate bounding box dictionary>>=
+ print TYPE3 "/BoundingBoxes $total_chars dict def\n";
+ print TYPE3 "BoundingBoxes begin\n";
+ print TYPE3 "/.notdef { 0 0 0 0 } def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4",$BoundingBox[$i]);
+ print TYPE3 "$Encoding[$i] [ $llx $lly $urx $ury ] def\n"
+ if $_ eq "d";
+ }
+ print TYPE3 "end %BoundingBoxes\n";
+
+
+@ The metrics dictionary is created in way similar to the bounding box
+dictionary. Generally it consists of lines of the form: [[/A 600 def]]
+where the number is the difference urx-llx. As usual we must first
+output some book-keeping information.
+
+<<generate metrics dictionary>>=
+ print TYPE3 "/Metrics $total_chars dict def\n";
+ print TYPE3 "Metrics begin\n";
+ print TYPE3 "/.notdef 0 def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4",$BoundingBox[$i]);
+ $diff = $urx - $llx;
+ print TYPE3 "$Encoding[$i] $diff def\n" if $_ eq "d";
+ }
+ print TYPE3 "end %Metrics\n";
+
+
+@ Generating the CharProcs dictionary involves the extraction of
+the PostScript code from the various EPSF files. Moreover, we must
+be careful to avoid extracting comments and to delete the keyword
+[[showpage]] from the source code. Both, operations are getting done
+by making use of the regular expression facilities and operators that
+Perl provide. Apart from that we generation process is similar to
+the previous ones. First, we generate some standard code and then
+the PostScript code for each character. Please note, that after
+initial experimentation I have found that METAPOST generates
+a lot of strange [[setgray]] commands which actually confuse a
+PostScript interpreter, so the program eliminates all such commands.
+
+<<generate CharProcs dictionary>>=
+ print TYPE3 "/CharProcs $total_chars dict def\n";
+ print TYPE3 "CharProcs begin\n";
+ print TYPE3 "/.notdef { } def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ $_ = unpack("ai4", $BoundingBox[$i]);
+ if ($_ eq "d")
+ {
+ open(CHAR, "$MFfile.$i")||
+ die "Can't open file $MFfile.$i\n";
+ $code = ""; #"100 100 scale\n";
+ while (<CHAR>)
+ {
+ $code .= $_ if $_ !~ /^%/;
+ }
+ close CHAR;
+ $code =~ s/showpage\n*//mg; #eliminate showpage
+ $code =~ s/\d setgray//mg; #eliminate setgray
+ $code =~ s/(\d*)\.\d+/$1/mg; #chop decimal digits
+ print TYPE3 $Encoding[$i], " { %\n";
+ if ($eofill)
+ {
+ <<Manipulate fills and newpaths>>
+ }
+ else
+ {
+ print TYPE3 $code;
+ }
+ print TYPE3 "} bind def\n";
+ }
+ }
+ print TYPE3 "end %CharProcs\n";
+
+@ In the [[eofill]] mode, we eliminate <b>newpath</b> calls and
+<b>fill</b> calls that are not following <b>gsave</b>.
+And in the end we call eofill.
+<<Manipulate fills and newpaths>>=
+$code =~ s/gsave fill/GSAVE FILL/mg; # save for soon restore
+$code =~ s/fill//mg; # eliminate fill
+$code =~ s/newpath//mg; # eliminate fill
+$code =~ s/GSAVE FILL/gsave fill/mg; # restore
+print TYPE3 $code, "eofill\n";
+
+@ Procedure [[BuildGlyph]] is very important as it defines the way
+PostScript will be able to use the font. The generated code is
+pretty standard.
+
+<<generate BuildGlyph procedure>>=
+ print TYPE3 <<BUILDGLYPH;
+ /BuildGlyph {
+ exch
+ begin
+ dup
+ Metrics exch get % get x displacement
+ 0 % set y displacement
+ 2 index
+ BoundingBoxes
+ exch get aload pop
+ setcachedevice
+ CharProcs exch get
+ exec
+ fill
+ end
+ } def
+ currentdict
+end
+/$MFfile exch definefont
+pop
+BUILDGLYPH
+close TYPE3;
+
+@ Now that we are done we must free some space on our hard disks, unless
+of course the user has decided the opposite. In case we are allowed to free
+space, we remove all the EPSF files, the log file and the TFM file, leaving
+only the Type 3 font file.
+
+<<Delete unnecessary files>>=
+ if (!$nodel)
+ {
+ unlink @EPSFs;
+ unlink "$MFfile.log", "$MFfile.tfm";
+ }
+
+@ <b><h2>Acknowledgments</h2></b><br>
+John Hobby (the creator of METAPOST) and Yotam Medini
+had helped me in the development phase and the debugging phase
+correspondingly. Many thanks to both of you!
diff --git a/fonts/utilities/mf2pt3/mf2pt3.pl b/fonts/utilities/mf2pt3/mf2pt3.pl
new file mode 100755
index 0000000000..46bc574e8e
--- /dev/null
+++ b/fonts/utilities/mf2pt3/mf2pt3.pl
@@ -0,0 +1,305 @@
+#!/usr/bin/perl
+#
+#(c) Copyright 1998 Apostolos Syropoulos
+# apostolo@obelix.ee.duth.gr
+#
+ $mfplain="mfplain \'\\mode=localfont; \\batchmode; ";
+ $notdef=pack("ai4","u",0,0,0,0);
+ for($i=0; $i<=255; $i++){ $BoundingBox[$i]=$notdef }
+
+ @Encoding = ("/_a0", "/_a1", "/_a2", "/_a3", "/_a4",
+ "/_a5", "/_a6", "/_a7", "/_a8",
+ "/_a9", "/_a10", "/_a11", "/_a12",
+ "/_a13", "/_a14", "/_a15", "/_a16",
+ "/_a17", "/_a18", "/_a19", "/_a20",
+ "/_a21", "/_a22", "/_a23", "/_a24",
+ "/_a25", "/_a26", "/_a27", "/_a28",
+ "/_a29", "/_a30", "/_a31", "/_a32",
+ "/_a33", "/_a34", "/_a35", "/_a36",
+ "/_a37", "/_a38", "/_a39", "/_a40",
+ "/_a41", "/_a42", "/_a43", "/_a44",
+ "/_a45", "/_a46", "/_a47", "/_a48",
+ "/_a49", "/_a50", "/_a51", "/_a52",
+ "/_a53", "/_a54", "/_a55", "/_a56",
+ "/_a57", "/_a58", "/_a59", "/_a60",
+ "/_a61", "/_a62", "/_a63", "/_a64",
+ "/_a65", "/_a66", "/_a67", "/_a68",
+ "/_a69", "/_a70", "/_a71", "/_a72",
+ "/_a73", "/_a74", "/_a75", "/_a76",
+ "/_a77", "/_a78", "/_a79", "/_a80",
+ "/_a81", "/_a82", "/_a83", "/_a84",
+ "/_a85", "/_a86", "/_a87", "/_a88",
+ "/_a89", "/_a90", "/_a91", "/_a92",
+ "/_a93", "/_a94", "/_a95", "/_a96",
+ "/_a97", "/_a98", "/_a99", "/_a100",
+ "/_a101", "/_a102", "/_a103", "/_a104",
+ "/_a105", "/_a106", "/_a107", "/_a108",
+ "/_a109", "/_a110", "/_a111", "/_a112",
+ "/_a113", "/_a114", "/_a115", "/_a116",
+ "/_a117", "/_a118", "/_a119", "/_a120",
+ "/_a121", "/_a122", "/_a123", "/_a124",
+ "/_a125", "/_a126", "/_a127", "/_a128",
+ "/_a129", "/_a130", "/_a131", "/_a132",
+ "/_a133", "/_a134", "/_a135", "/_a136",
+ "/_a137", "/_a138", "/_a139", "/_a140",
+ "/_a141", "/_a142", "/_a143", "/_a144",
+ "/_a145", "/_a146", "/_a147", "/_a148",
+ "/_a149", "/_a150", "/_a151", "/_a152",
+ "/_a153", "/_a154", "/_a155", "/_a156",
+ "/_a157", "/_a158", "/_a159", "/_a160",
+ "/_a161", "/_a162", "/_a163", "/_a164",
+ "/_a165", "/_a166", "/_a167", "/_a168",
+ "/_a169", "/_a170", "/_a171", "/_a172",
+ "/_a173", "/_a174", "/_a175", "/_a176",
+ "/_a177", "/_a178", "/_a179", "/_a180",
+ "/_a181", "/_a182", "/_a183", "/_a184",
+ "/_a185", "/_a186", "/_a187", "/_a188",
+ "/_a189", "/_a190", "/_a191", "/_a192",
+ "/_a193", "/_a194", "/_a195", "/_a196",
+ "/_a197", "/_a198", "/_a199", "/_a200",
+ "/_a201", "/_a202", "/_a203", "/_a204",
+ "/_a205", "/_a206", "/_a207", "/_a208",
+ "/_a209", "/_a210", "/_a211", "/_a212",
+ "/_a213", "/_a214", "/_a215", "/_a216",
+ "/_a217", "/_a218", "/_a219", "/_a220",
+ "/_a221", "/_a222", "/_a223", "/_a224",
+ "/_a225", "/_a226", "/_a227", "/_a228",
+ "/_a229", "/_a230", "/_a231", "/_a232",
+ "/_a233", "/_a234", "/_a235", "/_a236",
+ "/_a237", "/_a238", "/_a239", "/_a240",
+ "/_a241", "/_a242", "/_a243", "/_a244",
+ "/_a245", "/_a246", "/_a247", "/_a248",
+ "/_a249", "/_a250", "/_a251", "/_a252",
+ "/_a253", "/_a254", "/_a255");
+
+
+$argc = @ARGV;
+$design_size = -1;
+$nodel = 0;
+$eofill = 0;
+$noID = 1;
+SWITCHES: while($_ = $ARGV[0], /^-/)
+{
+ shift;
+ if(/^-d(\d+)/)
+ {
+ $design_size = $1;
+ }
+ elsif(/^-nodel$/)
+ {
+ $nodel = 1;
+ }
+ elsif(/^-eofill$/)
+ {
+ $eofill = 1;
+ }
+ elsif(/^-I(\d+)$/)
+ {
+ die "UniqueID must lie in the range 4,000,000...4,999,999\n"
+ if ($1 > 4999999 || $1 < 4000000);
+ $UniqueID = $1;
+ $noID = 0;
+ }
+ elsif (!@ARGV)
+ {
+ last SWITCHES;
+ }
+}
+if (!@ARGV)
+{
+ print <<Usage;
+This ``mf2pt3'' version 1.1
+Usage: mf2pt3 [-dsize] [-nodel] [-eofill] [-IUniqueID] <METAFONT file name>
+Usage
+exit(0);
+}
+else
+{
+ $MFfile = $ARGV[0];
+}
+if ($noID)
+{
+ srand();
+ $UniqueID = int(999999*rand())+4000000;
+
+}
+
+if ($design_size == -1)
+{
+ if ($MFfile =~ /\D+(\d+)$/)
+ {
+ $design_size=$1;
+ }
+ else
+ {
+ die "$MFfile must be a PostScript font name: there is no design size.\n";
+ }
+}
+if($design_size >100)
+{
+ $mag_factor=$design_size/1000;
+}
+else
+{
+ $mag_factor=$design_size/10;
+}
+$mag = 100 /$mag_factor;
+
+ $MFfile = $1 if $MFfile =~ /(\w+)\.\w*/;
+
+
+
+ $mfplain .= "mag=$mag; input $MFfile \'";
+ system($mfplain);
+ if (!(-e "$MFfile.tfm"))
+ {
+ $nodel || unlink "mpout.log";
+ die "$MFfile: no such font in system\n";
+ }
+
+ opendir(Dir, ".");
+ $pattern = "$MFfile" . "\\.\\d+";
+ @EPSFs = grep(/$pattern/, readdir(Dir));
+ closedir Dir;
+
+ $Min_llx = $Min_lly = $Max_urx = $Max_ury = 0;
+
+ $total_chars = @EPSFs+1;
+ foreach $file (@EPSFs)
+ {
+ open(EPSF_FILE,"$file")||die "Can't open file $file\n";
+ while (<EPSF_FILE>)
+ {
+ $BBox = pack("ai4","d",$1,$2,$3,$4)
+ if /%%BoundingBox: (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
+ }
+ close EPSF_FILE;
+ $_=$file;
+ /$MFfile\.(\d+)/;
+ $BoundingBox[$1] = $BBox;
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4", $BBox);
+ $Min_llx = $llx if $llx < $Min_llx;
+ $Min_lly = $lly if $lly < $Min_lly;
+ $Max_urx = $urx if $urx > $Max_urx;
+ $Max_ury = $ury if $ury > $Max_ury;
+ }
+
+ open(TYPE3, ">$MFfile.pt3")||die "Can't create file $MFfile.pt3\n";
+ $date = localtime;
+ print TYPE3 <<DATA;
+%!PS-Adobe-2.0
+%%Creator: mf2pt3 1.1 Copyright 1998 Apostolos Syropoulos
+%%CreationDate: $date
+%%EndComments
+11 dict % 11 entries
+begin
+ /FontType 3 def
+ /UniqueID $UniqueID def
+ /FontName /$MFfile def
+ /FontBBox [ $Min_llx $Min_lly $Max_urx $Max_ury] def
+ /FontMatrix [ 0.001 0 0 0.001 0 0 ] def
+ /Encoding 256 array def
+ 0 1 255 { Encoding exch /.notdef put } for
+DATA
+ for($i=0; $i<=256; $i++)
+ {
+ $_ = unpack("ai4", $BoundingBox[$i]);
+ print TYPE3 "Encoding $i $Encoding[$i] put\n" if $_ eq "d";
+ }
+
+ print TYPE3 "/BoundingBoxes $total_chars dict def\n";
+ print TYPE3 "BoundingBoxes begin\n";
+ print TYPE3 "/.notdef { 0 0 0 0 } def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4",$BoundingBox[$i]);
+ print TYPE3 "$Encoding[$i] [ $llx $lly $urx $ury ] def\n"
+ if $_ eq "d";
+ }
+ print TYPE3 "end %BoundingBoxes\n";
+
+
+ print TYPE3 "/Metrics $total_chars dict def\n";
+ print TYPE3 "Metrics begin\n";
+ print TYPE3 "/.notdef 0 def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ ($_, $llx, $lly, $urx, $ury) = unpack("ai4",$BoundingBox[$i]);
+ $diff = $urx - $llx;
+ print TYPE3 "$Encoding[$i] $diff def\n" if $_ eq "d";
+ }
+ print TYPE3 "end %Metrics\n";
+
+
+ print TYPE3 "/CharProcs $total_chars dict def\n";
+ print TYPE3 "CharProcs begin\n";
+ print TYPE3 "/.notdef { } def\n";
+ for($i=0; $i<=256; $i++)
+ {
+ $_ = unpack("ai4", $BoundingBox[$i]);
+ if ($_ eq "d")
+ {
+ open(CHAR, "$MFfile.$i")||
+ die "Can't open file $MFfile.$i\n";
+ $code = ""; #"100 100 scale\n";
+ while (<CHAR>)
+ {
+ $code .= $_ if $_ !~ /^%/;
+ }
+ close CHAR;
+ $code =~ s/showpage\n*//mg; #eliminate showpage
+ $code =~ s/\d setgray//mg; #eliminate setgray
+ $code =~ s/(\d*)\.\d+/$1/mg; #chop decimal digits
+ print TYPE3 $Encoding[$i], " { %\n";
+ if ($eofill)
+ {
+ $code =~ s/gsave fill/GSAVE FILL/mg; # save for soon restore
+ $code =~ s/fill//mg; # eliminate fill
+ $code =~ s/newpath//mg; # eliminate fill
+ $code =~ s/GSAVE FILL/gsave fill/mg; # restore
+ print TYPE3 $code, "eofill\n";
+
+ }
+ else
+ {
+ print TYPE3 $code;
+ }
+ print TYPE3 "} bind def\n";
+ }
+ }
+ print TYPE3 "end %CharProcs\n";
+
+ print TYPE3 <<BUILDGLYPH;
+ /BuildGlyph {
+ exch
+ begin
+ dup
+ Metrics exch get % get x displacement
+ 0 % set y displacement
+ 2 index
+ BoundingBoxes
+ exch get aload pop
+ setcachedevice
+ CharProcs exch get
+ exec
+ fill
+ end
+ } def
+ currentdict
+end
+/$MFfile exch definefont
+pop
+BUILDGLYPH
+close TYPE3;
+
+
+
+
+ if (!$nodel)
+ {
+ unlink @EPSFs;
+ unlink "$MFfile.log", "$MFfile.tfm";
+ }
+
+print "\n$MFfile $MFfile <$MFfile.pt3\n";
+