summaryrefslogtreecommitdiff
path: root/fonts/utilities/mf2pt3/mf2pt3.html
blob: 49da72d4330a2f26c54a480aa40b5bd404874658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
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>