summaryrefslogtreecommitdiff
path: root/support/mf2pt1
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 /support/mf2pt1
Initial commit
Diffstat (limited to 'support/mf2pt1')
-rw-r--r--support/mf2pt1/ChangeLog420
-rw-r--r--support/mf2pt1/README40
-rw-r--r--support/mf2pt1/mf2pt1.mp495
-rw-r--r--support/mf2pt1/mf2pt1.pdfbin0 -> 229650 bytes
-rwxr-xr-xsupport/mf2pt1/mf2pt1.pl1090
-rw-r--r--support/mf2pt1/mf2pt1.texi977
6 files changed, 3022 insertions, 0 deletions
diff --git a/support/mf2pt1/ChangeLog b/support/mf2pt1/ChangeLog
new file mode 100644
index 0000000000..57b9ec2b0d
--- /dev/null
+++ b/support/mf2pt1/ChangeLog
@@ -0,0 +1,420 @@
+2014-04-30 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi
+ Updated the formatting to work with Makeinfo 5.
+
+ * mf2pt1.texi, mf2pt1.pl
+ Updated the version number to 2.5a and the copyright year to 2014.
+
+2014-04-30 Karl Berry <karl@freefriends.org>
+
+ * mf2pt1.texi
+ Standardized the dir entry.
+
+2012-06-29 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi, mf2pt1.pl
+ Increased the version number from 2.4.6 to 2.5. Updated the
+ Acknowledgments section.
+
+2012-06-29 Michael Ummels <michael@ummels.de>
+
+ * mf2pt1.mp:
+ Made the to_bp function round to nearest rather than round up.
+
+2012-06-29 Michael Ummels <michael@ummels.de>
+
+ * mf2pt1.pl:
+ Changed the computation of character widths to use TeX points
+ instead of PostScript points.
+
+2012-03-24 Scott Pakin <scott+mf@pakin.org>
+
+ * README, mf2pt1.pl, mf2pt1.texi, mf2pt1.mp:
+ Updated the copyright date from 2011 to 2012 and increased the
+ version number from 2.4.5 to 2.4.6.
+
+2012-03-24 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Modified the code to pass "nonstopmode" to the Metafont
+ invocation.
+
+2011-08-02 Scott Pakin <scott+mf@pakin.org>
+
+ * README, mf2pt1.pl, mf2pt1.texi:
+ Updated the copyright date from 2008 to 2011 and increased the version
+ number from 2.4.4 to 2.4.5.
+
+2011-08-02 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Prevented non-integer arguments from being passed to hsbw in the
+ definition of ".notdef".
+
+2008-01-27 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl, mf2pt1.texi:
+ Increased the version number from 2.4.3 to 2.4.4
+
+2008-01-27 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl: Modified to sort the MetaPost output files so that
+ the glyph order in the PFB is the same as in the MF sources.
+
+2008-01-13 Scott Pakin <scott+mf@pakin.org>
+
+ * README, mf2pt1.mp, mf2pt1.pl:
+ Updated the copyright year from 2007 to 2008 and increased the version
+ number from 2.4.2 to 2.4.3.
+
+ * mf2pt1.texi:
+ Modified to format the document with a ragged bottom instead of the
+ default flush bottom.
+
+2008-01-13 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp: Bug fix: Patched the is_clockwise macro to prevent it
+ from failing so often.
+
+ * mf2pt1.mp:
+ Bug fix: Changed "=" to ":=" in the makeline function.
+
+2007-06-30 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp, mf2pt1.pl:
+ Renamed "bbox" to "glyph_dimensions".
+
+2007-05-28 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi: Updated the version to 2.4 and documented --bpppix.
+
+2007-05-28 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Bug fix: Modified to set bpppix before calling get_bboxes.
+
+ * mf2pt1.mp, mf2pt1.pl:
+ Added a --bpppix option to change the number of big points per pixel.
+
+2007-05-26 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl:
+ Documented --version. Rewrote the option descriptions as full
+ sentences. Increased the version number to 2.4.
+
+2007-02-04 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Retypeset the parameter example and added a section showing how to
+ recover the original definitions of filldraw, unfilldraw, and
+ pencircle.
+
+ * mf2pt1.mp: Made minor modifications.
+
+ * README, mf2pt1.mp, mf2pt1.pl, mf2pt1.texi:
+ Updated the copyright date and increased the version number from 2.2 to 2.3.
+
+ * mf2pt1.mp:
+ Modified to back up the original (mfplain.mp) definitions of
+ pencircle, filldraw, and unfilldraw.
+
+2007-02-04 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Bug fix: Made the default underline thickness a positive number.
+
+2006-07-08 Scott Pakin <scott+mf@pakin.org>
+
+ * README:
+ Rewrote the description to compare mf2pt1 to TeXtrace and mftrace.
+
+2006-05-29 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Updated the documentation to match the latest code. Specifically, the
+ new format for .enc files and the new new defaults for underline
+ thickness and position are now correct.
+
+ * mf2pt1.pl:
+ Corrected the handling of the underline thickness and position.
+
+ * README, mf2pt1.mp: Updated the license agreement to LPPL 1.3c.
+
+ * mf2pt1.pl:
+ Completely rewrote the command-line processing code so that (a)
+ command-line options override options specified in the .mf file and
+ (b) the --encoding flag works as intended.
+
+2005-12-04 Scott Pakin <scott+mf@pakin.org>
+
+ * README, mf2pt1.mp, mf2pt1.pl, mf2pt1.texi:
+ Increased the acceptable LPPL version number from 1.2 to 1.3a.
+
+2005-12-04 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp: Patched the clockwise and counterclockwise functions
+ to circumvent the turning-number bug in MetaPost.
+
+2005-02-27 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Proofread and updated accordingly. Also, increased the version number
+ from 1.2 to 2.0.
+
+ * mf2pt1.pl: Increased the version number from 1.2 to 2.0.
+
+2005-02-26 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Wrote an Acknowledgments section. Corrected the @MF macro. Added PDF
+ metadata. Added a @dircategory and @direntry.
+
+2005-02-20 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl, mf2pt1.texi:
+ Added a --ffscript option which lets the user override the default
+ FontForge script.
+
+ * mf2pt1.texi:
+ Removed the mention of roex.mf because, according to Werner Lemberg,
+ it doesn't work with MetaPost. Inserted in its place a pointer to a
+ 6Jan2005 article on the MetaPost mailing list which includes an
+ overlap-removal library as an attachment.
+
+ * mf2pt1.texi: Added mention of the "t1" and "asis" font encodings.
+
+ * mf2pt1.pl:
+ Added Ralf Stubner's T1 encoding vector. Replaced "FontType-1.0" with
+ "FontType1-1.0", as directed by Ralf. Added Werner Lemberg's "asis"
+ font encoding.
+
+ * mf2pt1.mp:
+ Reintroduced the Angle macro as it turns out it's still needed.
+
+2005-02-20 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Replaced the FontForge script with one that performs a lot more
+ font cleanup.
+
+2005-02-14 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp:
+ Replaced the Angle and is_clockwise functions with the improved
+ versions provided by Boguslaw Jackowski.
+
+2005-02-06 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp:
+ Incorporated a turningnumber bug workaround.
+
+2005-02-06 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Documented the environment variables that mf2pt1 honors and replaced
+ all occurrences of @ifinfo with @ifnottex so as not to preclude HTML
+ generation.
+
+ * mf2pt1.texi:
+ Documented the glyph_name command, the new way of dumping MetaPost
+ memory, the --rounding option, and the fact that mf2pt1 now invokes
+ t1asm and fontforge automatically.
+
+ * mf2pt1.pl:
+ Modified to tell FontForge to fix any overlapping paths found in
+ the font.
+
+ * mf2pt1.mp:
+ Added a user-callable glyph_name macro which enables a character to
+ specify explicitly the PostScript glyph name associated with it.
+
+ * mf2pt1.pe:
+ Removed; <fontname>.pe is now generated automatically by mf2pt1.pl.
+
+ * mf2pt1.pl:
+ Modified to automatically try running the output through t1asm and
+ fontforge.
+
+ * mf2pt1.pl:
+ Hoisted extraction of the font extension above MF2PT1_CMD and assigned
+ the value to $charnum instead of leaving it for a long time in $1.
+ Renamed $dx[123]m and $dy[123]m to $dx[123]d and $dy[123]d (for
+ "denominator"). Renamed "precision" to "rounding". Added blank lines
+ after each section of output.
+
+ * mf2pt1.pl:
+ Made the following changes: replaced --mem with -mem; renamed $gn
+ to $gname and used ?: for assignment to it; cleaned up the spacing
+ around the frac_string and frac_approx uses; cleaned up the
+ `rmoveto' comment; fixed the "good" lines comment; renamed $dxm
+ and $dym to $dxd and $dyd (for "denominator"); fixed the precision
+ warnings; moved Werner's new functions to the top of the file with
+ the others; added prototypes for those functions; and, added a SEE
+ ALSO for FontForge.
+
+ * mf2pt1.mp: Modified the comments to be more compatible with mftinc.
+
+2005-02-06 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.pl:
+ Incorporated various changes up to and including 4Feb2005.
+
+2005-01-30 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pe:
+ Created: FontForge script to autohint all of the characters in a
+ given font.
+
+2005-01-30 Werner Lemberg <wl@gnu.org>
+
+ * mf2pt1.mp: Patched charwd.
+
+ * mf2pt1.pl: Performed a major revision of the code.
+
+2005-01-08 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl:
+ Bug fix: Corrected rounding to work properly on negative numbers.
+ Bug fix: Corrected the check for hvcurveto suitability.
+ Added my e-mail address to the --help output.
+ Cleaned up the code by moving subroutine definitions above the main program.
+
+2005-01-03 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl:
+ Made rounding actually round. Added code to dump font parameters.
+ Corrected definitions of $underlinepos and $underlinethick to defer
+ computation until $designsize is defined.
+
+ * mf2pt1.texi:
+ Changed "PfaEdit" in all occurences to "FontForge" and mentioned its
+ "Remove Overlap" feature.
+
+ * mf2pt1.pl: Cleaned up command-line processing.
+
+2005-01-02 Scott Pakin <scott+mf@pakin.org>
+
+ * README, mf2pt1.mp, mf2pt1.pl, mf2pt1.texi:
+ Updated the year from 2004 to 2005.
+
+ * README, mf2pt1.mp, mf2pt1.pl, mf2pt1.texi:
+ Added support for custom encodings and updated the copyright year and
+ my e-mail address.
+
+2001-06-19 Scott Pakin <scott+mf@pakin.org>
+
+ * README: Removed angled brackets to avoid confusing HTML renderings.
+
+ * README: Description of mf2pt1 and a pointer to the user manual
+
+ * mf2pt1.texi: Proofread and modified text accordingly.
+
+2001-06-17 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi:
+ Added more Future Work (specifically, additional encodings).
+
+ * mf2pt1.texi: Added a Future Work section.
+
+2001-06-04 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp, mf2pt1.pl, mf2pt1.texi: Added license information.
+ N.B. The previous log message was supposed to indicate that
+ font_underline_position and font_underline_thickness now work in
+ Metafont units within the .mf file.
+
+2001-06-02 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.texi: Made various modifications.
+
+ * mf2pt1.pl:
+ Wrote some POD documentation and added a --help option to display
+ excerpts from it.
+
+ * mf2pt1.texi: Added a font parameter usage example.
+
+ * mf2pt1.texi: Added more text to the Usage section.
+
+ * mf2pt1.texi: Added the start of a Usage section.
+
+ * mf2pt1.texi: User documentation for mf2pt1
+
+2001-06-01 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp: Modified comments to use LaTeX and mftinc.
+
+2001-05-30 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp, mf2pt1.pl:
+ Added PostScript-specific font parameters.
+
+2001-05-21 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp, mf2pt1.pl:
+ Modified to convert the Metafont font_slant to a Type 1 ItalicAngle.
+
+2001-05-20 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl: Added command-line options.
+
+2001-05-16 Scott Pakin <scott+mf@pakin.org>
+
+2001-05-15 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp:
+ Rewrote to use the turningnumber to determine if a path runs
+ clockwise or counterclockwise instead of calculating that
+ manually.
+
+2001-05-12 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl:
+ Added a warning message for characters that lack a beginchar.
+
+2001-05-10 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl:
+ Bug fix: Argument to font_size is now correctly treated as TeX
+ points, not PostScript points.
+
+ * mf2pt1.mp:
+ Made using_pencircle robust to scaling (although not to rotation).
+
+ * mf2pt1.mp:
+ Introduced a special case to drawdot and undrawdot: If the pen
+ looks like a circular pen, draw a clean circle instead of the
+ jagged pen path.
+
+2001-05-09 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp, mf2pt1.pl:
+ Modified mf2pt1 to honor the font-specified design size (the font_size
+ command in Metafont).
+
+ * mf2pt1.mp:
+ Added and improved the implementations of more Plain Metafont
+ primitives.
+
+2001-05-05 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp: Added a draw macro.
+
+2001-05-04 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.mp: Added an undrawdot macro.
+
+ * mf2pt1.mp: Defined "safe" versions of the various fill commands.
+ Made is_clockwise more robust.
+
+ * mf2pt1.mp:
+ Added code to replace the primitive pencircle with a non-primitive
+ approximation.
+
+ * mf2pt1.mp:
+ Added (but do not yet use) a clockwise function for determining path
+ direction.
+
+2001-04-29 Scott Pakin <scott+mf@pakin.org>
+
+ * mf2pt1.pl: Corrected curveto handling.
diff --git a/support/mf2pt1/README b/support/mf2pt1/README
new file mode 100644
index 0000000000..4ba418f279
--- /dev/null
+++ b/support/mf2pt1/README
@@ -0,0 +1,40 @@
+ +------------------------------------+
+ | MF2PT1: |
+ | Produce PostScript Type 1 |
+ | fonts from Metafont source |
+ | |
+ | By Scott Pakin, scott+mf@pakin.org |
+ +------------------------------------+
+
+Description
+-----------
+
+mf2pt1 facilitates producing PostScript Type 1 fonts from a Metafont
+source file. mf2pt1's advantage over tools such as TeXtrace and
+mftrace is that it does not rely on bitmap tracing and therefore can
+produce higher-quality Type 1 fonts than trace-based tools. The catch
+is that mf2pt1 imposes a number of restrictions on the Metafont input
+so it is not, as the name may imply, an automatic converter of
+arbitrary Metafont fonts to Type 1 format.
+
+
+Installation
+------------
+
+For installation instructions, see the mf2pt1 manual (mf2pt1.pdf).
+
+
+Copyright and license
+---------------------
+
+Copyright (C) 2014 Scott Pakin, scott+mf@pakin.org
+
+This package may be distributed and/or modified under the conditions
+of the LaTeX Project Public License, either version 1.3c of this
+license or (at your option) any later version. The latest version of
+this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2006/05/20 or later.
diff --git a/support/mf2pt1/mf2pt1.mp b/support/mf2pt1/mf2pt1.mp
new file mode 100644
index 0000000000..588bc57cbb
--- /dev/null
+++ b/support/mf2pt1/mf2pt1.mp
@@ -0,0 +1,495 @@
+%%%%
+%%%% MF2PT1.MP, by Scott Pakin, scott+mf@pakin.org
+%%%%
+%%%% This file is used to dump a special version of MetaPost with:
+%%%% mpost -progname=mpost -ini mf2pt1 \\dump
+%%%%
+%%%% To pretty-print this file, you'll need LaTeX and the mftinc package
+%%%% (available from CTAN).
+%%%%
+
+%%%% ==================================================================== %%%%
+%%%% mf2pt1 %%%%
+%%%% Copyright (C) 2014 Scott Pakin %%%%
+%%%% %%%%
+%%%% This program may be distributed and/or modified under the conditions %%%%
+%%%% of the LaTeX Project Public License, either version 1.3c of this %%%%
+%%%% license or (at your option) any later version. %%%%
+%%%% %%%%
+%%%% The latest version of this license is in: %%%%
+%%%% %%%%
+%%%% http://www.latex-project.org/lppl.txt %%%%
+%%%% %%%%
+%%%% and version 1.3c or later is part of all distributions of LaTeX %%%%
+%%%% version 2006/05/20 or later. %%%%
+%%%% ==================================================================== %%%%
+
+input mfplain;
+
+%%% addto makepath makepen
+%%% length clockwise counterclockwise
+%%% scaled dashed withcolor
+
+%% \begin{explaincode}
+%% Enable a \MF\ file to determine if it's being built with
+%% \texttt{mf2pt1}.
+%% \end{explaincode}
+
+newinternal ps_output;
+ps_output := 1;
+
+
+%% \begin{explaincode}
+%% The following was taken right out of \texttt{mfplain.mp}. The \mfcomment
+% |def| and the |special|s at the end
+%% are the sole additions. Normally, MetaPost outputs a tight bounding
+%% box around the character in its PostScript output. The purpose of the
+%% first \mfcomment
+% |special|
+%% is to pass \texttt{mf2pt1} a bounding box that includes the proper
+%% surrounding whitespace. The purpose of the second special is to
+%% provide \texttt{mf2pt1} with a default PostScript font name.
+%% \end{explaincode}
+
+def beginchar(expr c,w_sharp,h_sharp,d_sharp) =
+ begingroup
+ charcode:=if known c: byte c else: 0 fi;
+ charwd:=w_sharp; charht:=h_sharp; chardp:=d_sharp;
+ w:=charwd*pt; h:=charht*pt; d:=chardp*pt;
+ charic:=0; clearxy; clearit; clearpen; scantokens extra_beginchar;
+
+ def to_bp (expr num) = decimal (round (num*bp_per_pixel)) enddef;
+ special "% MF2PT1: glyph_dimensions 0 " & to_bp (-d) & " " & to_bp(w) & " " & to_bp(h);
+ special "% MF2PT1: font_size " & decimal designsize;
+ special "% MF2PT1: font_slant " & decimal font_slant_;
+ special "% MF2PT1: charwd " & decimal charwd; % Must come after the |font_size| |special|
+ for fvar = "font_identifier", "font_coding_scheme", "font_version",
+ "font_comment", "font_family", "font_weight", "font_unique_id",
+ "font_name":
+ if known scantokens (fvar & "_"):
+ special "% MF2PT1: " & fvar & " " & scantokens (fvar & "_");
+ fi;
+ endfor;
+ for fvar = "font_underline_position", "font_underline_thickness":
+ if known scantokens (fvar & "_"):
+ special "% MF2PT1: " & fvar & " " &
+ scantokens ("decimal " & fvar & "_");
+ fi;
+ endfor;
+ special "% MF2PT1: font_fixed_pitch " &
+ (if font_fixed_pitch_: "1" else: "0" fi);
+enddef;
+
+
+%% \begin{explaincode}
+%% Enable a character to specify explicitly the PostScript glyph
+%% name associated with it.
+%% \end{explaincode}
+def glyph_name expr name =
+ special "% MF2PT1: glyph_name " & name;
+enddef;
+
+
+%% \begin{explaincode}
+%% Store the value of \mfcomment
+% |font_slant_|, so we can recall it at each |beginchar|.
+%% \end{explaincode}
+
+font_slant_ := 0;
+
+def font_slant expr x =
+ font_slant_ := x;
+ fontdimen 1: x
+enddef;
+
+
+%% \begin{explaincode}
+%% Redefine \mfcomment
+% |bpppix_|, the number of ``big'' points per pixel. \mfcomment
+% This in turn redefines |mm|, |in|, |pt|, and other derived units.
+%% \end{explaincode}
+
+def bpppix expr x =
+ bpppix_ := x;
+ mm := 2.83464 / bpppix_;
+ pt := 0.99626 / bpppix_;
+ dd := 1.06601 / bpppix_;
+ bp := 1 / bpppix_;
+ cm := 28.34645 / bpppix_;
+ pc := 11.95517 / bpppix_;
+ cc := 12.79213 / bpppix_;
+ in := 72 / bpppix_;
+ hppp := pt;
+ vppp := pt;
+enddef;
+
+
+%% \begin{explaincode}
+%% Define a bunch of PostScript font parameters to be used by
+%% \texttt{mf2pt1.pl}. Default values are specified in
+%% \texttt{mf2pt1.pl}, not here.
+%% \end{explaincode}
+
+forsuffixes fvar = font_version, font_comment, font_family, font_weight,
+ font_name, font_unique_id:
+ scantokens ("string " & str fvar & "_;");
+ scantokens ("def " & str fvar & " expr x = " & str fvar & "_ := x enddef;");
+endfor;
+
+forsuffixes fvar = font_underline_position, font_underline_thickness:
+ scantokens ("numeric " & str fvar & "_;");
+ scantokens ("def " & str fvar & " expr x = " & str fvar & "_ := x enddef;");
+endfor;
+
+boolean font_fixed_pitch_;
+font_fixed_pitch_ := false;
+def font_fixed_pitch expr x = font_fixed_pitch_ := x enddef;
+
+
+%% \begin{explaincode}
+%% We'd like to be able to use calligraphic pens. Normally, MetaPost's
+%% output routine does all the work for us of converting these to filled
+%% PostScript paths. The only exception occurs for paths drawn using a
+%% pen that was transformed from \mfcomment
+% |pencircle|. MetaPost outputs these paths as stroked PostScript
+%% paths. The following code tricks MetaPost into using a filled path
+%% for \mfcomment
+% |pencircle| by replacing the primitive |pencircle| pen with a
+%% non-primitive approximation. Note that we use a 20-gon for our circle
+%% instead of a diamond, so we get better results from \mfcomment
+% |draw|.
+%% \end{explaincode}
+
+pen fakepencircle, mfplain_pencircle;
+mfplain_pencircle := pencircle;
+fakepencircle := makepen (for deg=0 step 360/20 until 359:
+ (0.5 cosd deg, 0.5 sind deg)--
+ endfor cycle);
+save pencircle;
+pen pencircle;
+pencircle := fakepencircle;
+
+
+%% \begin{explaincode}
+%% Return \mfcomment
+% |true| if a path is cyclic, |false| otherwise.
+%% \end{explaincode}
+
+def is_cyclic expr cpath =
+ (point 0 of cpath = point (length cpath) of cpath)
+enddef;
+
+
+%% \begin{explaincode}
+%% Determine the direction of a path which doesn't intersect
+%% itself. \mfcomment
+% Returns |true| if the curve is clockwise, |false| if
+%% counterclockwise. For non-cyclic paths the result is not
+%% predictable.
+%% \bigskip
+%%
+%% The \mfcomment
+% |crossproduct|, |makeline|, and |is_clockwise| functions were
+%% provided by Werner Lemberg.
+%% \bigskip
+%%
+%% The algorithm used is quite simple:
+%%
+%% \begin{itemize}
+%% \item Find a point~$P$ on the path which has a non-zero direction,
+%% and which is on a not-too-short path element.
+%%
+%% \item Construct a ray of ``infinite'' length, starting in the
+%% vicinity of~$P$ which intersects the path at this point.
+%%
+%% \item Use \mfcomment
+% |intersectiontimes| to find the intersection. If the direction of
+%% the path at this point is (near) zero, or if we have a grazing
+%% intersection or even a tangent, get a new ray.
+%%
+%% \item Shorten the ray so that it starts right after the
+%% intersection. Repeat the previous step until no intersection is
+%% found. Then go back to the last intersection and compare the path's
+%% direction with the direction of the ray. According to the
+%% \emph{nonzero winding number} rule we have found a clockwise
+%% oriented path if it crosses the ray from left to right.
+%% \end{itemize}
+%%
+%% This method completely avoids any problems with the geometry of
+%% B\'{e}zier curves. If problems arise, a different ray is tried.
+%% Since it isn't necessary to analyze the whole path it runs quite fast
+%% in spite of using \mfcomment
+% |intersectiontimes| which is a slow MetaPost command.
+%% \end{explaincode}
+
+vardef crossproduct (expr u, v) =
+ save u_, v_;
+ pair u_, v_;
+
+ u_ := unitvector u;
+ v_ := unitvector v;
+
+ abs (xpart u_ * ypart v_ - ypart u_ * xpart v_)
+enddef;
+
+vardef makeline primary p =
+ save start, bad_n, loop, distance, d, i, n;
+ pair start, d;
+
+ loop := 0;
+ bad_n := -1;
+ for i := 0 step 1 until length p - 1:
+ distance := length (point i of p - point (i + 1) of p);
+ if distance <> 0:
+ if distance < 1:
+ % In case we don't find something better.
+ bad_n := i;
+ else:
+ n := i;
+ loop := 1;
+ fi;
+ fi;
+ exitif loop = 1;
+ endfor;
+
+ if loop = 0:
+ if bad_n <> -1:
+ n := bad_n;
+ loop = 1;
+ fi;
+ fi;
+
+ % Add some randomness to get different lines for each function call.
+ n := n + uniformdeviate 0.8 + 0.1;
+ start := point n of p;
+
+ if loop = 0:
+ % Construct a line which misses the degenerated path.
+ start + (1, 0)
+ -- start + (1, 1)
+ else:
+ d := direction n of p;
+
+ % Again, some added randomness.
+ n := uniformdeviate 150 + 15;
+ d := unitvector (d rotated n);
+
+ % Construct a line which intersects the path at least once.
+ start - eps * d
+ -- infinity * d
+ fi
+enddef;
+
+vardef is_clockwise primary p =
+ save line, cut, cut_new, res, line_dir, tangent_dir;
+ path line;
+ pair cut, cut_new, line_dir, tangent_dir;
+
+ line := makeline p;
+ line_dir := direction 0 of line;
+
+ % Find the outermost intersection.
+ cut := (0, 0);
+ forever:
+ cut_new := line intersectiontimes p;
+ exitif cut_new = (-1, -1);
+
+ % Compute a new line if we have a strange intersection.
+ tangent_dir := direction (ypart cut_new) of p;
+ if abs tangent_dir < eps:
+ % The vector is zero or too small.
+ line := makeline p;
+ line_dir := direction 0 of line;
+
+ elseif abs (ypart cut_new - floor (ypart cut_new + 0.5)) < eps:
+ % Avoid possible tangent touching in a corner or cusp.
+ line := makeline p;
+ line_dir := direction 0 of line;
+
+ elseif crossproduct (tangent_dir, line_dir) < 0.2:
+ % Grazing intersection (arcsin 0.2 ~= 11.5 degrees).
+ line := makeline p;
+ line_dir := direction 0 of line;
+
+ else:
+ % Go ahead.
+ cut := cut_new;
+ line := subpath (xpart cut + eps, infinity) of line;
+ fi;
+ endfor;
+
+ tangent_dir := direction (ypart cut) of p;
+ if tangent_dir <> (0, 0):
+ res := (angle tangent_dir - angle line_dir + 180) mod 360 - 180;
+ res < 0
+ else:
+ false
+ fi
+enddef;
+
+
+%% \begin{explaincode}
+%% Make a given path run clockwise or counterclockwise. \mfcomment
+% (|counterclockwise| is defined by \texttt{mfplain} but we override
+%% it here.)
+%% \end{explaincode}
+
+vardef counterclockwise primary c =
+ (if is_clockwise c: (reverse c) else: c fi)
+enddef;
+
+vardef clockwise primary c =
+ (if is_clockwise c: c else: (reverse c) fi)
+enddef;
+
+
+%% \begin{explaincode}
+%% Redefine \mfcomment
+% |fill| and |unfill| to ensure that filled paths run
+%% counterclockwise and unfilled paths run clockwise, as is required
+%% by PostScript Type~1 fonts.
+%% \end{explaincode}
+
+def fill expr c =
+ addto currentpicture contour counterclockwise c t_ pc_
+enddef;
+
+def unfill expr c =
+ addto currentpicture contour clockwise c t_ pc_ withcolor background
+enddef;
+
+
+%% \begin{explaincode}
+%% Convert \mfcomment
+% |filldraw| and |unfilldraw| to |fill| and |unfill|.
+%% \end{explaincode}
+
+let mfplain_filldraw := filldraw;
+def filldraw expr c =
+ begingroup
+ message "! Warning: Replacing filldraw with fill.";
+ fill c
+ endgroup
+enddef;
+
+let mfplain_unfilldraw := unfilldraw;
+def unfilldraw expr c =
+ begingroup
+ message "! Warning: Replacing unfilldraw with unfill.";
+ unfill c
+ endgroup
+enddef;
+
+
+%% \begin{explaincode}
+%% Return \mfcomment
+% |true| if |currentpen| looks like a |pencircle|.
+%% \end{explaincode}
+
+def using_pencircle =
+ begingroup
+ path qpath, circlepath;
+ qpath = makepath currentpen;
+ numeric circlediv;
+ circlepath = makepath pencircle;
+ circlediv = xpart (lrcorner circlepath);
+
+ (length qpath = length circlepath) and (pen_rt <> 0) and (pen_top <> 0)
+ for pp = 0 upto (length qpath)-1:
+ and ((xpart (point pp of qpath) / pen_rt,
+ ypart (point pp of qpath) / pen_top) =
+ point pp of circlepath / circlediv)
+ endfor
+ endgroup
+enddef;
+
+
+%% \begin{explaincode}
+%% If the pen looks like a circular pen, draw a nice circle. Otherwise,
+%% draw the pen as is.
+%% \end{explaincode}
+
+def drawdot expr z =
+ if using_pencircle:
+ begingroup
+ path cpath;
+ numeric clength;
+ cpath = makepath currentpen;
+ clength = length cpath;
+ fill ((point 0 of cpath)
+ ..(point clength/4 of cpath)
+ ..(point clength/2 of cpath)
+ ..(point 3*clength/4 of cpath)
+ ..cycle) shifted z t_
+ endgroup
+ else:
+ addto currentpicture contour makepath currentpen shifted z
+ t_ pc_
+ fi
+enddef;
+
+
+%% \begin{explaincode}
+%% Do the same as the above, but unfill the current pen.
+%% \end{explaincode}
+
+def undrawdot expr z =
+ if using_pencircle:
+ begingroup
+ path cpath;
+ numeric clength;
+ cpath = makepath currentpen;
+ clength = length cpath;
+ unfill ((point 0 of cpath)
+ ..(point clength/4 of cpath)
+ ..(point clength/2 of cpath)
+ ..(point 3*clength/4 of cpath)
+ ..cycle) shifted z t_
+ endgroup
+ else:
+ unfill makepath currentpen shifted z t_
+ fi
+enddef;
+
+
+%% \begin{explaincode}
+%% MetaPost renders \mfcomment
+% |draw| with a filled curve.
+%% Hence, we need to ensure the orientation is correct (i.e.,
+%% counterclockwise). Unfortunately, we have no way to check for
+%% overlap, and it's fairly common for MetaPost to output
+%% self-overlapping curve outlines, even if the curve itself has no
+%% overlap.
+%% \end{explaincode}
+
+def draw expr p =
+ addto currentpicture
+ if picture p:
+ also p
+ elseif is_cyclic p:
+ doublepath counterclockwise p t_ withpen currentpen
+ else:
+ if is_clockwise (p--cycle):
+ doublepath (reverse p) t_ withpen currentpen
+ else:
+ doublepath p t_ withpen currentpen
+ fi
+ fi
+ pc_
+enddef;
+
+def undraw expr p =
+ addto currentpicture
+ if picture p:
+ also p
+ elseif is_cyclic p:
+ doublepath clockwise p t_ withpen currentpen
+ else:
+ if is_clockwise (p--cycle):
+ doublepath p t_ withpen currentpen
+ else:
+ doublepath (reverse p) t_ withpen currentpen
+ fi
+ fi
+ pc_ withcolor background
+enddef;
diff --git a/support/mf2pt1/mf2pt1.pdf b/support/mf2pt1/mf2pt1.pdf
new file mode 100644
index 0000000000..94b586a4d2
--- /dev/null
+++ b/support/mf2pt1/mf2pt1.pdf
Binary files differ
diff --git a/support/mf2pt1/mf2pt1.pl b/support/mf2pt1/mf2pt1.pl
new file mode 100755
index 0000000000..abfd02c2f8
--- /dev/null
+++ b/support/mf2pt1/mf2pt1.pl
@@ -0,0 +1,1090 @@
+#! /usr/bin/perl
+
+##################################################
+# Convert stylized Metafont to PostScript Type 1 #
+# By Scott Pakin <scott+mf@pakin.org> #
+##################################################
+
+########################################################################
+# mf2pt1 #
+# Copyright (C) 2014 Scott Pakin #
+# #
+# This program may be distributed and/or modified under the conditions #
+# of the LaTeX Project Public License, either version 1.3c of this #
+# license or (at your option) any later version. #
+# #
+# The latest version of this license is in: #
+# #
+# http://www.latex-project.org/lppl.txt #
+# #
+# and version 1.3c or later is part of all distributions of LaTeX #
+# version 2006/05/20 or later. #
+########################################################################
+
+our $VERSION = "2.5a"; # mf2pt1 version number
+require 5.6.1; # I haven't tested mf2pt1 with older Perl versions
+
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use Pod::Usage;
+use Math::Trig;
+use warnings;
+use strict;
+
+# Define some common encoding vectors.
+my @standardencoding =
+ ((map {"_a$_"} (0..31)),
+ qw (space exclam quotedbl numbersign dollar percent ampersand
+ quoteright parenleft parenright asterisk plus comma hyphen
+ period slash zero one two three four five six seven eight
+ nine colon semicolon less equal greater question at A B C D E
+ F G H I J K L M N O P Q R S T U V W X Y Z bracketleft
+ backslash bracketright asciicircum underscore quoteleft a b c
+ d e f g h i j k l m n o p q r s t u v w x y z braceleft bar
+ braceright asciitilde),
+ (map {"_a$_"} (127..160)),
+ qw (exclamdown cent sterling fraction yen florin section currency
+ quotesingle quotedblleft guillemotleft guilsinglleft
+ guilsinglright fi fl _a176 endash dagger daggerdbl
+ periodcentered _a181 paragraph bullet quotesinglbase
+ quotedblbase quotedblright guillemotright ellipsis
+ perthousand _a190 questiondown _a192 grave acute circumflex
+ tilde macron breve dotaccent dieresis _a201 ring cedilla
+ _a204 hungarumlaut ogonek caron emdash),
+ (map {"_a$_"} (209..224)),
+ qw (AE _a226 ordfeminine _a228 _a229 _a230 _a231 Lslash Oslash OE
+ ordmasculine _a236 _a237 _a238 _a239 _a240 ae _a242 _a243
+ _a244 dotlessi _a246 _a247 lslash oslash oe germandbls _a252
+ _a253 _a254 _a255));
+my @isolatin1encoding =
+ ((map {"_a$_"} (0..31)),
+ qw (space exclam quotedbl numbersign dollar percent ampersand
+ quoteright parenleft parenright asterisk plus comma minus
+ period slash zero one two three four five six seven eight
+ nine colon semicolon less equal greater question at A B C D E
+ F G H I J K L M N O P Q R S T U V W X Y Z bracketleft
+ backslash bracketright asciicircum underscore quoteleft a b c
+ d e f g h i j k l m n o p q r s t u v w x y z braceleft bar
+ braceright asciitilde),
+ (map {"_a$_"} (128..143)),
+ qw (dotlessi grave acute circumflex tilde macron breve dotaccent
+ dieresis _a153 ring cedilla _a156 hungarumlaut ogonek
+ caron space exclamdown cent sterling currency yen brokenbar
+ section dieresis copyright ordfeminine guillemotleft
+ logicalnot hyphen registered macron degree plusminus
+ twosuperior threesuperior acute mu paragraph periodcentered
+ cedilla onesuperior ordmasculine guillemotright onequarter
+ onehalf threequarters questiondown Agrave Aacute Acircumflex
+ Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex
+ Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde
+ Ograve Oacute Ocircumflex Otilde Odieresis multiply Oslash
+ Ugrave Uacute Ucircumflex Udieresis Yacute Thorn germandbls
+ agrave aacute acircumflex atilde adieresis aring ae ccedilla
+ egrave eacute ecircumflex edieresis igrave iacute icircumflex
+ idieresis eth ntilde ograve oacute ocircumflex otilde
+ odieresis divide oslash ugrave uacute ucircumflex udieresis
+ yacute thorn ydieresis));
+my @ot1encoding =
+ qw (Gamma Delta Theta Lambda Xi Pi Sigma Upsilon Phi
+ Psi Omega ff fi fl ffi ffl dotlessi dotlessj grave acute caron
+ breve macron ring cedilla germandbls ae oe oslash AE OE Oslash
+ suppress exclam quotedblright numbersign dollar percent
+ ampersand quoteright parenleft parenright asterisk plus comma
+ hyphen period slash zero one two three four five six seven
+ eight nine colon semicolon exclamdown equal questiondown
+ question at A B C D E F G H I J K L M N O P Q R S T U V W X Y
+ Z bracketleft quotedblleft bracketright circumflex dotaccent
+ quoteleft a b c d e f g h i j k l m n o p q r s t u v w x y z
+ endash emdash hungarumlaut tilde dieresis);
+my @t1encoding =
+ qw (grave acute circumflex tilde dieresis hungarumlaut ring caron
+ breve macron dotaccent cedilla ogonek quotesinglbase
+ guilsinglleft guilsinglright quotedblleft quotedblright
+ quotedblbase guillemotleft guillemotright endash emdash cwm
+ perthousand dotlessi dotlessj ff fi fl ffi ffl space exclam
+ quotedbl numbersign dollar percent ampersand quoteright
+ parenleft parenright asterisk plus comma hyphen period slash
+ zero one two three four five six seven eight nine colon
+ semicolon less equal greater question at A B C D E F G H I J K L
+ M N O P Q R S T U V W X Y Z bracketleft backslash bracketright
+ asciicircum underscore quoteleft a b c d e f g h i j k l m n o p
+ q r s t u v w x y z braceleft bar braceright asciitilde
+ sfthyphen Abreve Aogonek Cacute Ccaron Dcaron Ecaron Eogonek
+ Gbreve Lacute Lcaron Lslash Nacute Ncaron Eng Ohungarumlaut
+ Racute Rcaron Sacute Scaron Scedilla Tcaron Tcedilla
+ Uhungarumlaut Uring Ydieresis Zacute Zcaron Zdotaccent IJ
+ Idotaccent dcroat section abreve aogonek cacute ccaron dcaron
+ ecaron eogonek gbreve lacute lcaron lslash nacute ncaron eng
+ ohungarumlaut racute rcaron sacute scaron scedilla tcaron
+ tcedilla uhungarumlaut uring ydieresis zacute zcaron zdotaccent
+ ij exclamdown questiondown sterling Agrave Aacute Acircumflex
+ Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex
+ Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde Ograve
+ Oacute Ocircumflex Otilde Odieresis OE Oslash Ugrave Uacute
+ Ucircumflex Udieresis Yacute Thorn SS agrave aacute acircumflex
+ atilde adieresis aring ae ccedilla egrave eacute ecircumflex
+ edieresis igrave iacute icircumflex idieresis eth ntilde ograve
+ oacute ocircumflex otilde odieresis oe oslash ugrave uacute
+ ucircumflex udieresis yacute thorn germandbls);
+
+# Define font parameters that the user can override.
+my $fontversion;
+my $creationdate;
+my $comment;
+my $familyname;
+my $weight;
+my $fullname;
+my $fixedpitch;
+my $italicangle;
+my $underlinepos;
+my $underlinethick;
+my $fontname;
+my $uniqueID;
+my $designsize;
+my ($mffile, $pt1file, $pfbfile, $ffscript);
+my $encoding;
+my $rounding;
+my $bpppix;
+
+# Define all of our other global variables.
+my $progname = basename $0, ".pl";
+my $mag;
+my @fontbbox;
+my @charbbox;
+my @charwd;
+my @glyphname;
+my @charfiles;
+my $filebase;
+my $filedir;
+my $filenoext;
+my $versionmsg = "mf2pt1 version $VERSION
+
+Copyright (C) 2012 Scott Pakin
+
+This program may be distributed and/or modified under the conditions
+of the LaTeX Project Public License, either version 1.3c of this
+license or (at your option) any later version.
+
+The latest version of this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2006/05/20 or later.
+";
+
+
+######################################################################
+
+# The routines to compute the fractional approximation of a real number
+# are heavily based on code posted by Ben Tilly
+# <http://www.perlmonks.org/?node_id=26179> on Nov 16th, 2000, to the
+# PerlMonks list. See <http://www.perlmonks.org/index.pl?node_id=41961>.
+
+
+# Takes numerator/denominator pairs.
+# Returns a PS fraction string representation (with a trailing space).
+sub frac_string (@)
+{
+ my $res = "";
+
+ while (@_) {
+ my $n = shift;
+ my $d = shift;
+ $res .= $n . " ";
+ $res .= $d . " div " if $d > 1;
+ }
+
+ return $res;
+}
+
+
+# Takes a number.
+# Returns a numerator and denominator with the smallest denominator
+# so that the difference of the resulting fraction to the number is
+# smaller or equal to $rounding.
+sub frac_approx ($)
+{
+ my $num = shift;
+ my $f = ret_frac_iter ($num);
+
+ while (1) {
+ my ($n, $m) = $f->();
+ my $approx = $n / $m;
+ my $delta = abs ($num - $approx);
+ return ($n, $m) if ($delta <= $rounding);
+ }
+}
+
+
+# Takes a number, returns the best integer approximation and (in list
+# context) the error.
+sub best_int ($)
+{
+ my $x = shift;
+ my $approx = sprintf '%.0f', $x;
+ if (wantarray) {
+ return ($approx, $x - $approx);
+ }
+ else {
+ return $approx;
+ }
+}
+
+
+# Takes a numerator and denominator, in scalar context returns
+# the best fraction describing them, in list the numerator and
+# denominator.
+sub frac_standard ($$)
+{
+ my $n = best_int(shift);
+ my $m = best_int(shift);
+ my $k = gcd($n, $m);
+ $n /= $k;
+ $m /= $k;
+ if ($m < 0) {
+ $n *= -1;
+ $m *= -1;
+ }
+ if (wantarray) {
+ return ($n, $m);
+ }
+ else {
+ return "$n/$m";
+ }
+}
+
+
+# Euclidean algorithm for calculating a GCD.
+# Takes two integers, returns the greatest common divisor.
+sub gcd ($$)
+{
+ my ($n, $m) = @_;
+ while ($m) {
+ my $k = $n % $m;
+ ($n, $m) = ($m, $k);
+ }
+ return $n;
+}
+
+
+# Takes a list of terms in a continued fraction, and converts it
+# into a fraction.
+sub ints_to_frac (@)
+{
+ my ($n, $m) = (0, 1); # Start with 0
+ while (@_) {
+ my $k = pop;
+ if ($n) {
+ # Want frac for $k + 1/($n/$m)
+ ($n, $m) = frac_standard($k*$n + $m, $n);
+ }
+ else {
+ # Want $k
+ ($n, $m) = frac_standard($k, 1);
+ }
+ }
+ return frac_standard($n, $m);
+}
+
+
+# Takes a number, returns an anon sub which iterates through a set of
+# fractional approximations that converges very quickly to the number.
+sub ret_frac_iter ($)
+{
+ my $x = shift;
+ my $term_iter = ret_next_term_iter($x);
+ my @ints;
+ return sub {
+ push @ints, $term_iter->();
+ return ints_to_frac(@ints);
+ }
+}
+
+
+# Terms of a continued fraction converging on that number.
+sub ret_next_term_iter ($)
+{
+ my $x = shift;
+ return sub {
+ (my $n, $x) = best_int($x);
+ if (0 != $x) {
+ $x = 1/$x;
+ }
+ return $n;
+ }
+}
+
+######################################################################
+
+# Round a number to the nearest integer.
+sub round ($)
+{
+ return int($_[0] + 0.5*($_[0] <=> 0));
+}
+
+
+# Round a number to a given precision.
+sub prec ($)
+{
+ return round ($_[0] / $rounding) * $rounding;
+}
+
+
+# Set a variable's value to the first defined value in the given list.
+# If the variable was not previously defined and no value in the list
+# is defined, do nothing.
+sub assign_default (\$@)
+{
+ my $varptr = shift; # Pointer to variable to define
+ return if defined $$varptr && $$varptr ne "UNSPECIFIED";
+ foreach my $val (@_) {
+ next if !defined $val;
+ $$varptr = $val;
+ return;
+ }
+}
+
+
+# Print and execute a shell command. An environment variable with the
+# same name as the command overrides the command name. Return 1 on
+# success, 0 on failure. Optionally abort if the command fails, based
+# on the first argument to execute_command.
+sub execute_command ($@)
+{
+ my $abort_on_failure = shift;
+ my @command = @_;
+ $command[0] = $ENV{uc $command[0]} || $command[0];
+ my $prettyargs = join (" ", map {/[\\ ]/ ? "'$_'" : $_} @command);
+ print "Invoking \"$prettyargs\"...\n";
+ my $result = system @command;
+ die "${progname}: \"$prettyargs\" failed ($!)\n" if $result && $abort_on_failure;
+ return !$result;
+}
+
+
+# Output the font header.
+sub output_header ()
+{
+ # Show the initial boilerplate.
+ print OUTFILE <<"ENDHEADER";
+%!FontType1-1.0: $fontname $fontversion
+%%CreationDate: $creationdate
+% Font converted to Type 1 by mf2pt1, written by Scott Pakin.
+11 dict begin
+/FontInfo 11 dict dup begin
+/version ($fontversion) readonly def
+/Notice ($comment) readonly def
+/FullName ($fullname) readonly def
+/FamilyName ($familyname) readonly def
+/Weight ($weight) readonly def
+/ItalicAngle $italicangle def
+/isFixedPitch $fixedpitch def
+/UnderlinePosition $underlinepos def
+/UnderlineThickness $underlinethick def
+end readonly def
+/FontName /$fontname def
+ENDHEADER
+
+ # If we're not using an encoding that PostScript knows about, then
+ # create an encoding vector.
+ if ($encoding==\@standardencoding) {
+ print OUTFILE "/Encoding StandardEncoding def\n";
+ }
+ else {
+ print OUTFILE "/Encoding 256 array\n";
+ print OUTFILE "0 1 255 {1 index exch /.notdef put} for\n";
+ foreach my $charnum (0 .. $#{$encoding}) {
+ if ($encoding->[$charnum] && $encoding->[$charnum]!~/^_a\d+$/) {
+ print OUTFILE "dup $charnum /$encoding->[$charnum] put\n";
+ }
+ }
+ print OUTFILE "readonly def\n";
+ }
+
+ # Show the final boilerplate.
+ print OUTFILE <<"ENDHEADER";
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/UniqueID $uniqueID def
+/FontBBox{@fontbbox}readonly def
+currentdict end
+currentfile eexec
+dup /Private 5 dict dup begin
+/RD{string currentfile exch readstring pop}executeonly def
+/ND{noaccess def}executeonly def
+/NP{noaccess put}executeonly def
+ENDHEADER
+}
+
+
+# Use MetaPost to generate one PostScript file per character. We
+# calculate the font bounding box from these characters and store them
+# in @fontbbox. If the input parameter is 1, set other font
+# parameters, too.
+sub get_bboxes ($)
+{
+ execute_command 1, ("mpost", "-mem=mf2pt1", "-progname=mpost",
+ "\\mode:=localfont; mag:=$mag; bpppix $bpppix; nonstopmode; input $mffile");
+ opendir (CURDIR, ".") || die "${progname}: $! ($filedir)\n";
+ @charfiles = sort
+ { ($a=~ /\.(\d+)$/)[0] <=> ($b=~ /\.(\d+)$/)[0] }
+ grep /^$filebase.*\.\d+$/, readdir(CURDIR);
+ close CURDIR;
+ @fontbbox = (1000000, 1000000, -1000000, -1000000);
+ foreach my $psfile (@charfiles) {
+ # Read the character number from the output file's extension.
+ $psfile =~ /\.(\d+)$/;
+ my $charnum = $1;
+
+ # Process in turn each line of the current PostScript file.
+ my $havebbox = 0;
+ open (PSFILE, "<$psfile") || die "${progname}: $! ($psfile)\n";
+ while (<PSFILE>) {
+ my @tokens = split " ";
+ if ($tokens[0] eq "%%BoundingBox:") {
+ # Store the MetaPost-produced bounding box, just in case
+ # the given font doesn't use beginchar.
+ @tokens = ("%", "MF2PT1:", "glyph_dimensions", @tokens[1..4]);
+ $havebbox--;
+ }
+ next if $#tokens<1 || $tokens[1] ne "MF2PT1:";
+
+ # Process a "special" inserted into the generated PostScript.
+ MF2PT1_CMD:
+ {
+ # glyph_dimensions llx lly urx ury -- specified glyph dimensions
+ $tokens[2] eq "glyph_dimensions" && do {
+ my @bbox = @tokens[3..6];
+ $fontbbox[0]=$bbox[0] if $bbox[0]<$fontbbox[0];
+ $fontbbox[1]=$bbox[1] if $bbox[1]<$fontbbox[1];
+ $fontbbox[2]=$bbox[2] if $bbox[2]>$fontbbox[2];
+ $fontbbox[3]=$bbox[3] if $bbox[3]>$fontbbox[3];
+ $charbbox[$charnum] = \@bbox;
+ $havebbox++;
+ last MF2PT1_CMD;
+ };
+
+ # If all we want is the bounding box, exit the loop now.
+ last MF2PT1_CMD if !$_[0];
+
+ # glyph_name name -- glyph name
+ $tokens[2] eq "glyph_name" && do {
+ $glyphname[$charnum] = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # charwd wd -- character width as in TFM
+ $tokens[2] eq "charwd" && do {
+ $charwd[$charnum] = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_identifier name -- full font name
+ $tokens[2] eq "font_identifier" && do {
+ $fullname = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_size number -- font design size (pt, not bp)
+ $tokens[2] eq "font_size" && $tokens[3] && do {
+ $designsize = $tokens[3] * 72 / 72.27;
+ last MF2PT1_CMD;
+ };
+
+ # font_slant number -- italic amount
+ $tokens[2] eq "font_slant" && do {
+ $italicangle = 0 + rad2deg (atan(-$tokens[3]));
+ last MF2PT1_CMD;
+ };
+
+ # font_coding_scheme string -- font encoding
+ $tokens[2] eq "font_coding_scheme" && do {
+ $encoding = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_version string -- font version number (xxx.yyy)
+ $tokens[2] eq "font_version" && do {
+ $fontversion = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_comment string -- font comment notice
+ $tokens[2] eq "font_comment" && do {
+ $comment = join (" ", @tokens[3..$#tokens]);
+ last MF2PT1_CMD;
+ };
+
+ # font_family string -- font family name
+ $tokens[2] eq "font_family" && do {
+ $familyname = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_weight string -- font weight (e.g., "Book" or "Heavy")
+ $tokens[2] eq "font_weight" && do {
+ $weight = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_fixed_pitch number -- fixed width font (0=false, 1=true)
+ $tokens[2] eq "font_fixed_pitch" && do {
+ $fixedpitch = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_underline_position number -- vertical underline position
+ $tokens[2] eq "font_underline_position" && do {
+ # We store $underlinepos in points and later
+ # scale it by 1000/$designsize.
+ $underlinepos = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_underline_thickness number -- thickness of underline
+ $tokens[2] eq "font_underline_thickness" && do {
+ # We store $underlinethick in points and later
+ # scale it by 1000/$designsize.
+ $underlinethick = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_name string -- font name
+ $tokens[2] eq "font_name" && do {
+ $fontname = $tokens[3];
+ last MF2PT1_CMD;
+ };
+
+ # font_unique_id number (as string) -- globally unique font ID
+ $tokens[2] eq "font_unique_id" && do {
+ $uniqueID = 0+$tokens[3];
+ last MF2PT1_CMD;
+ };
+ }
+ }
+ close PSFILE;
+ if (!$havebbox) {
+ warn "${progname}: No beginchar in character $charnum; glyph dimensions are probably incorrect\n";
+ }
+ }
+}
+
+
+# Convert ordinary, MetaPost-produced PostScript files into Type 1
+# font programs.
+sub output_font_programs ()
+{
+ # Iterate over all the characters. We convert each one, line by
+ # line and token by token.
+ print "Converting PostScript graphics to Type 1 font programs...\n";
+ foreach my $psfile (@charfiles) {
+ # Initialize the font program.
+ $psfile =~ /\.(\d+)$/;
+ my $charnum = $1;
+ my $gname = $glyphname[$charnum] || $encoding->[$charnum];
+ my @fontprog;
+ push @fontprog, ("/$gname {",
+ frac_string (frac_approx ($charbbox[$charnum]->[0]),
+ frac_approx ($charbbox[$charnum]->[2]))
+ . "hsbw");
+ my ($cpx, $cpy) =
+ ($charbbox[$charnum]->[0], 0); # Current point (PostScript)
+
+ # Iterate over every line in the current file.
+ open (PSFILE, "<$psfile") || die "${progname}: $! ($psfile)\n";
+ while (my $oneline=<PSFILE>) {
+ next if $oneline=~/^\%/;
+ next if $oneline=~/set/; # Fortunately, "set" never occurs on "good" lines.
+ my @arglist; # Arguments to current PostScript function
+
+ # Iterate over every token in the current line.
+ TOKENLOOP:
+ foreach my $token (split " ", $oneline) {
+ # Number: Round and push on the argument list.
+ $token =~ /^[-.\d]+$/ && do {
+ push @arglist, prec ($&);
+ next TOKENLOOP;
+ };
+
+ # curveto: Convert to vhcurveto, hvcurveto, or rrcurveto.
+ $token eq "curveto" && do {
+ my ($dx1, $dy1) = ($arglist[0] - $cpx,
+ $arglist[1] - $cpy);
+ my ($dx1n, $dx1d) = frac_approx ($dx1);
+ my ($dy1n, $dy1d) = frac_approx ($dy1);
+ $cpx += $dx1n / $dx1d;
+ $cpy += $dy1n / $dy1d;
+
+ my ($dx2, $dy2) = ($arglist[2] - $cpx,
+ $arglist[3] - $cpy);
+ my ($dx2n, $dx2d) = frac_approx ($dx2);
+ my ($dy2n, $dy2d) = frac_approx ($dy2);
+ $cpx += $dx2n / $dx2d;
+ $cpy += $dy2n / $dy2d;
+
+ my ($dx3, $dy3) = ($arglist[4] - $cpx,
+ $arglist[5] - $cpy);
+ my ($dx3n, $dx3d) = frac_approx ($dx3);
+ my ($dy3n, $dy3d) = frac_approx ($dy3);
+ $cpx += $dx3n / $dx3d;
+ $cpy += $dy3n / $dy3d;
+
+ if (!$dx1n && !$dy3n) {
+ push @fontprog, frac_string ($dy1n, $dy1d,
+ $dx2n, $dx2d,
+ $dy2n, $dy2d,
+ $dx3n, $dx3d)
+ . "vhcurveto";
+ }
+ elsif (!$dy1n && !$dx3n) {
+ push @fontprog, frac_string ($dx1n, $dx1d,
+ $dx2n, $dx2d,
+ $dy2n, $dy2d,
+ $dy3n, $dy3d)
+ . "hvcurveto";
+ }
+ else {
+ push @fontprog, frac_string ($dx1n, $dx1d,
+ $dy1n, $dy1d,
+ $dx2n, $dx2d,
+ $dy2n, $dy2d,
+ $dx3n, $dx3d,
+ $dy3n, $dy3d)
+ . "rrcurveto";
+ }
+ next TOKENLOOP;
+ };
+
+ # lineto: Convert to vlineto, hlineto, or rlineto.
+ $token eq "lineto" && do {
+ my ($dx, $dy) = ($arglist[0] - $cpx,
+ $arglist[1] - $cpy);
+ my ($dxn, $dxd) = frac_approx ($dx);
+ my ($dyn, $dyd) = frac_approx ($dy);
+ $cpx += $dxn / $dxd;
+ $cpy += $dyn / $dyd;
+
+ if (!$dxn) {
+ push @fontprog, frac_string ($dyn, $dyd)
+ . "vlineto" if $dyn;
+ }
+ elsif (!$dyn) {
+ push @fontprog, frac_string ($dxn, $dxd)
+ . "hlineto";
+ }
+ else {
+ push @fontprog, frac_string ($dxn, $dxd, $dyn, $dyd)
+ . "rlineto";
+ }
+ next TOKENLOOP;
+ };
+
+ # moveto: Convert to vmoveto, hmoveto, or rmoveto.
+ $token eq "moveto" && do {
+ my ($dx, $dy) = ($arglist[0] - $cpx,
+ $arglist[1] - $cpy);
+ my ($dxn, $dxd) = frac_approx ($dx);
+ my ($dyn, $dyd) = frac_approx ($dy);
+ $cpx += $dxn / $dxd;
+ $cpy += $dyn / $dyd;
+
+ if (!$dxn) {
+ push @fontprog, frac_string ($dyn, $dyd)
+ . "vmoveto";
+ }
+ elsif (!$dyn) {
+ push @fontprog, frac_string ($dxn, $dxd)
+ . "hmoveto";
+ }
+ else {
+ push @fontprog, frac_string ($dxn, $dxd, $dyn, $dyd)
+ . "rmoveto";
+ }
+ next TOKENLOOP;
+ };
+
+ # closepath: Output as is.
+ $token eq "closepath" && do {
+ push @fontprog, $token;
+ next TOKENLOOP;
+ };
+ }
+ }
+ close PSFILE;
+ push @fontprog, ("endchar",
+ "} ND");
+ print OUTFILE join ("\n\t", @fontprog), "\n";
+ }
+}
+
+
+# Output the final set of code for the Type 1 font.
+sub output_trailer ()
+{
+ print OUTFILE <<"ENDTRAILER";
+/.notdef {
+ 0 @{[frac_string (frac_approx ($fontbbox[2] - $fontbbox[0]))]} hsbw
+ endchar
+ } ND
+end
+end
+readonly put
+noaccess put
+dup/FontName get exch definefont pop
+mark currentfile closefile
+cleartomark
+ENDTRAILER
+}
+
+######################################################################
+
+# Parse the command line. Asterisks in the following represents
+# commands also defined by Plain Metafont.
+my %opthash = ();
+GetOptions (\%opthash,
+ "fontversion=s", # font_version
+ "comment=s", # font_comment
+ "family=s", # font_family
+ "weight=s", # font_weight
+ "fullname=s", # font_identifier (*)
+ "fixedpitch!", # font_fixed_pitch
+ "italicangle=f", # font_slant (*)
+ "underpos=f", # font_underline_position
+ "underthick=f", # font_underline_thickness
+ "name=s", # font_name
+ "uniqueid=i", # font_unique_id
+ "designsize=f", # font_size (*)
+ "encoding=s", # font_coding_scheme (*)
+ "rounding=f",
+ "bpppix=f",
+ "ffscript=s",
+ "h|help",
+ "V|version") || pod2usage(2);
+if (defined $opthash{"h"}) {
+ pod2usage(-verbose => 1,
+ -output => \*STDOUT, # Bug workaround for Pod::Usage
+ -exitval => "NOEXIT");
+ print "Please e-mail bug reports to scott+mf\@pakin.org.\n";
+ exit 1;
+}
+do {print $versionmsg; exit 1} if defined $opthash{"V"};
+pod2usage(2) if $#ARGV != 0;
+
+# Extract the filename from the command line.
+$mffile = $ARGV[0];
+my @fileparts = fileparse $mffile, ".mf";
+$filebase = $fileparts[0];
+$filedir = $fileparts[1];
+$filenoext = File::Spec->catfile ($filedir, $filebase);
+$pt1file = $filebase . ".pt1";
+$pfbfile = $filebase . ".pfb";
+
+assign_default $bpppix, $opthash{bpppix}, 0.02;
+
+# Make our first pass through the input, to set values for various options.
+$mag = 100; # Get a more precise bounding box.
+get_bboxes(1); # This might set $designsize.
+
+# Sanity-check the specified precision.
+assign_default $rounding, $opthash{rounding}, 1;
+if ($rounding<=0.0 || $rounding>1.0) {
+ die sprintf "%s: Invalid rounding amount \"%g\"; value must be a positive number no greater than 1.0\n", $progname, $rounding;
+}
+
+# Ensure that every user-definable parameter is assigned a value.
+assign_default $fontversion, $opthash{fontversion}, "001.000";
+assign_default $creationdate, scalar localtime;
+assign_default $comment, $opthash{comment}, "Font converted to Type 1 by mf2pt1, written by Scott Pakin.";
+assign_default $weight, $opthash{weight}, "Medium";
+assign_default $fixedpitch, $opthash{fixedpitch}, 0;
+assign_default $uniqueID, $opthash{uniqueid}, int(rand(1000000)) + 4000000;
+assign_default $designsize, $opthash{designsize};
+die "${progname}: a design size must be specified in $mffile or on the command line\n" if !defined $designsize;
+die "${progname}: the design size must be a positive number\n" if $designsize<=0.0;
+assign_default $underlinepos, $opthash{underpos}, -1;
+$underlinepos = round(1000*$underlinepos/$designsize);
+assign_default $underlinethick, $opthash{underthick}, 0.5;
+$underlinethick = round(1000*$underlinethick/$designsize);
+assign_default $fullname, $opthash{fullname}, $filebase;
+assign_default $familyname, $opthash{family}, $fullname;
+assign_default $italicangle, $opthash{italicangle}, 0;
+assign_default $fontname, $opthash{name}, "$familyname-$weight";
+$fontname =~ s/\s//g;
+assign_default $encoding, $opthash{encoding}, "standard";
+my $encoding_name = $encoding;
+ENCODING:
+{
+ if (-e $encoding) {
+ # Filenames take precedence over built-in encodings.
+ my @enc_array;
+ open (ENCFILE, "<$encoding") || die "${progname}: $! ($encoding)\n";
+ while (my $oneline = <ENCFILE>) {
+ $oneline =~ s/\%.*$//;
+ foreach my $word (split " ", $oneline) {
+ push @enc_array, substr($word, 1) if substr($word, 0, 1) eq "/";
+ }
+ }
+ close ENCFILE;
+ $encoding_name = substr (shift @enc_array, 1);
+ $encoding = \@enc_array;
+ last ENCODING;
+ }
+ $encoding=\@standardencoding, last ENCODING if $encoding eq "standard";
+ $encoding=\@isolatin1encoding, last ENCODING if $encoding eq "isolatin1";
+ $encoding=\@ot1encoding, last ENCODING if $encoding eq "ot1";
+ $encoding=\@t1encoding, last ENCODING if $encoding eq "t1";
+ $encoding=\@glyphname, last ENCODING if $encoding eq "asis";
+ warn "${progname}: Unknown encoding \"$encoding\"; using standard Adobe encoding\n";
+ $encoding=\@standardencoding; # Default to standard encoding
+}
+assign_default $fixedpitch, $opthash{fixedpitch}, 0;
+$fixedpitch = $fixedpitch ? "true" : "false";
+assign_default $ffscript, $opthash{ffscript};
+
+# Output the final values of all of our parameters.
+print "\n";
+print <<"PARAMVALUES";
+mf2pt1 is using the following font parameters:
+ font_version: $fontversion
+ font_comment: $comment
+ font_family: $familyname
+ font_weight: $weight
+ font_identifier: $fullname
+ font_fixed_pitch: $fixedpitch
+ font_slant: $italicangle
+ font_underline_position: $underlinepos
+ font_underline_thickness: $underlinethick
+ font_name: $fontname
+ font_unique_id: $uniqueID
+ font_size: $designsize (bp)
+ font_coding_scheme: $encoding_name
+PARAMVALUES
+ ;
+print "\n";
+
+# Scale by a factor of 1000/design size.
+$mag = 1000.0 / $designsize;
+get_bboxes(0);
+print "\n";
+
+# Output the font in disassembled format.
+open (OUTFILE, ">$pt1file") || die "${progname}: $! ($pt1file)\n";
+output_header();
+printf OUTFILE "2 index /CharStrings %d dict dup begin\n",
+ 1+scalar(grep {defined($_)} @charbbox);
+output_font_programs();
+output_trailer();
+close OUTFILE;
+unlink @charfiles;
+print "\n";
+
+# Convert from the disassembled font format to Type 1 binary format.
+if (!execute_command 0, ("t1asm", $pt1file, $pfbfile)) {
+ die "${progname}: You'll need either to install t1utils and rerun $progname or find another way to convert $pt1file to $pfbfile\n";
+ exit 1;
+}
+print "\n";
+unlink $pt1file;
+
+# Use FontForge to autohint the result.
+my $user_script = 0; # 1=script file was provided by the user; 0=created here
+if (defined $ffscript) {
+ # The user provided his own script.
+ $user_script = 1;
+}
+else {
+ # Create a FontForge script file.
+ $ffscript = $filebase . ".pe";
+ open (FFSCRIPT, ">$ffscript") || die "${progname}: $! ($ffscript)\n";
+ print FFSCRIPT <<'AUTOHINT';
+Open($1);
+SelectAll();
+RemoveOverlap();
+AddExtrema();
+Simplify(0, 2);
+CorrectDirection();
+Simplify(0, 2);
+RoundToInt();
+AutoHint();
+Generate($1);
+Quit(0);
+AUTOHINT
+ ;
+ close FFSCRIPT;
+}
+if (!execute_command 0, ("fontforge", "-script", $ffscript, $pfbfile)) {
+ warn "${progname}: You'll need to install FontForge if you want $pfbfile autohinted (not required, but strongly recommended)\n";
+}
+unlink $ffscript if !$user_script;
+print "\n";
+
+# Finish up.
+print "*** Successfully generated $pfbfile! ***\n";
+exit 0;
+
+######################################################################
+
+__END__
+
+=head1 NAME
+
+mf2pt1 - produce a PostScript Type 1 font program from a Metafont source
+
+
+=head1 SYNOPSIS
+
+mf2pt1
+[B<--help>]
+[B<--version>]
+[B<--comment>=I<string>]
+[B<--designsize>=I<number>]
+[B<--encoding>=I<encoding>]
+[B<--family>=I<name>]
+[B<-->[B<no>]B<fixedpitch>]
+[B<--fontversion>=I<MMM.mmm>]
+[B<--fullname>=I<name>]
+[B<--italicangle>=I<number>]
+[B<--name>=I<name>]
+[B<--underpos>=I<number>]
+[B<--underthick>=I<number>]
+[B<--uniqueid>=I<number>]
+[B<--weight>=I<weight>]
+[B<--rounding>=I<number>]
+[B<--bpppix>=I<number>]
+[B<--ffscript>=I<file.pe>]
+I<infile>.mf
+
+
+=head1 WARNING
+
+The B<mf2pt1> Info file is the main source of documentation for
+B<mf2pt1>. This man page is merely a brief summary.
+
+
+=head1 DESCRIPTION
+
+B<mf2pt1> facilitates producing PostScript Type 1 fonts from a
+Metafont source file. It is I<not>, as the name may imply, an
+automatic converter of arbitrary Metafont fonts to Type 1 format.
+B<mf2pt1> imposes a number of restrictions on the Metafont input. If
+these restrictions are met, B<mf2pt1> will produce valid Type 1
+output. (Actually, it produces "disassembled" Type 1; the B<t1asm>
+program from the B<t1utils> suite will convert this to a true Type 1
+font.)
+
+=head2 Usage
+
+ mf2pt1 myfont.mf
+
+=head1 OPTIONS
+
+Font parameters are best specified within a Metafont program. If
+necessary, though, command-line options can override any of these
+parameters. The B<mf2pt1> Info page, the primary source of B<mf2pt1>
+documentation, describes the following in greater detail.
+
+=over 4
+
+=item B<--help>
+
+Provide help on B<mf2pt1>'s command-line options.
+
+=item B<--version>
+
+Output the B<mf2pt1> version number, copyright, and license.
+
+=item B<--comment>=I<string>
+
+Include a font comment, usually a copyright notice.
+
+=item B<--designsize>=I<number>
+
+Specify the font design size in points.
+
+=item B<--encoding>=I<encoding>
+
+Designate the font encoding, either the name of a---typically
+F<.enc>---file which contains a PostScript font-encoding vector or one
+of C<standard> (the default), C<ot1>, C<t1>, or C<isolatin1>.
+
+=item B<--family>=I<name>
+
+Specify the font family.
+
+=item B<--fixedpitch>, B<--nofixedpitch>
+
+Assert that the font uses either monospaced (B<--fixedpitch>) or
+proportional (B<--nofixedpitch>) character widths.
+
+=item B<--fontversion>=I<MMM.mmm>
+
+Specify the font's major and minor version number.
+
+=item B<--fullname>=I<name>
+
+Designate the full font name (family plus modifiers).
+
+=item B<--italicangle>=I<number>
+
+Designate the italic angle in degrees counterclockwise from vertical.
+
+=item B<--name>=I<name>
+
+Provide the font name.
+
+=item B<--underpos>=I<number>
+
+Specify the vertical position of the underline in thousandths of the
+font height.
+
+=item B<--underthick>=I<number>
+
+Specify the thickness of the underline in thousandths of the font
+height.
+
+=item B<--uniqueid>=I<number>
+
+Specify a globally unique font identifier.
+
+=item B<--weight>=I<weight>
+
+Provide a description of the font weight (e.g., ``Heavy'').
+
+=item B<--rounding>=I<number>
+
+Specify the fraction of a font unit (0.0 < I<number> <= 1.0) to which
+to round coordinate values [default: 1.0].
+
+=item B<--bpppix>=I<number>
+
+Redefine the number of big points per pixel from 0.02 to I<number>.
+
+=item B<--ffscript>=I<file.pe>
+
+Name a script to pass to FontForge.
+
+=back
+
+
+=head1 FILES
+
+F<mf2pt1.mem> (which is generated from F<mf2pt1.mp> and F<mfplain.mp>)
+
+
+=head1 NOTES
+
+As stated in L</"WARNING">, the complete source of documentation for
+B<mf2pt1> is the Info page, not this man page.
+
+
+=head1 SEE ALSO
+
+mf(1), mpost(1), t1asm(1), fontforge(1)
+
+
+=head1 AUTHOR
+
+Scott Pakin, I<scott+mf@pakin.org>
diff --git a/support/mf2pt1/mf2pt1.texi b/support/mf2pt1/mf2pt1.texi
new file mode 100644
index 0000000000..45fe6e309d
--- /dev/null
+++ b/support/mf2pt1/mf2pt1.texi
@@ -0,0 +1,977 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename mf2pt1.info
+@settitle mf2pt1
+@setchapternewpage off
+@dircategory TeX
+@direntry
+* mf2pt1: (mf2pt1). PostScript Type 1 fonts from Metafont source.
+@end direntry
+@finalout
+@c %**end of header
+
+@copying
+Copyright @copyright{} 2014 Scott Pakin
+
+@sp 2
+
+This program may be distributed and/or modified under the conditions
+of the @LaTeX{} Project Public License, either version 1.3c of this
+license or (at your option) any later version.
+
+@sp 1
+
+The latest version of this license is in:
+@sp 1
+@center @uref{http://www.latex-project.org/lppl.txt}
+@sp 1
+and version 1.3c or later is part of all distributions of @LaTeX{}
+version 2006/05/20 or later.
+
+@end copying
+
+@set VERSION 2.5a
+@set DATE 30 April 2014
+
+@c Define some fonts we intend to use.
+@iftex
+@tex
+@global@font@tenlogo=logo10 % font used for the METAFONT logo
+@global@font@eightrm=cmr8 % needed for the "A" in "LaTeX"
+@end tex
+@end iftex
+
+@c Define a macro for the Metafont logo.
+@iftex
+@macro MF {}
+@tex
+@tenlogo @leavevmode@hbox{METAFONT}@unskip
+@end tex
+@end macro
+@end iftex
+@ifnottex
+@macro MF {}
+Metafont
+@end macro
+@end ifnottex
+
+@macro copt {option}
+@w{@code{--\option\}}
+@end macro
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+@iftex
+@tex
+% If we're using pdfTeX in PDF-generating mode then include some
+% document metadata.
+\ifx\pdfoutput\undefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdfinfo {
+ /Title (mf2pt1)
+ /Subject (Produce PostScript Type 1 fonts from Metafont source)
+ /Author (Scott Pakin <scott+mf@@pakin.org>)
+ /Keywords (PostScript Type 1 fonts, Metafont, MetaPost, FontForge)
+ }
+ \fi
+ \fi
+\fi
+@end tex
+@end iftex
+
+@titlepage
+@title mf2pt1
+@subtitle Produce PostScript @w{Type 1} fonts from Metafont source
+@author Scott Pakin, @email{scott+mf@@pakin.org}
+
+@page
+
+@vskip 0pt plus 2filll
+
+This file documents @command{mf2pt1} version @value{VERSION}, dated
+@value{DATE}.
+
+@vskip 0pt plus 1filll
+
+@insertcopying
+
+@contents
+
+@end titlepage
+
+@ifnottex
+@node Top, Introduction, (dir), (dir)
+@top mf2pt1
+
+@command{mf2pt1} is a tool that lets font designers design PostScript
+@w{Type 1} fonts using the @MF{} language. The same source file can be
+used to produce both @w{Type 1} (@file{.pfb}) and bitmap (@file{.pk})
+fonts.
+@end ifnottex
+
+@menu
+* Introduction:: Introduction to mf2pt1
+* Usage:: How to use mf2pt1
+* Future Work:: Features I may one day add to mf2pt1
+* Acknowledgments:: People who helped with mf2pt1
+@end menu
+
+
+@node Introduction, Usage, Top, Top
+@chapter Introduction
+
+@MF{} is a high-level, mathematically oriented language for producing
+fonts. The @MF{} interpreter produces device-dependent bitmaps, which
+render well at the target resolution on the target device, but poorly
+at other resolutions or on other devices. Adobe's PostScript @w{Type 1}
+font format is the de facto font standard for printers these days. It
+is a vector format, which implies that it scales better than bitmaps,
+and it delegates the device- and resolution-dependent tweaking from
+the font source to the target device's PostScript renderer. However,
+@w{Type 1} fonts are extremely difficult to code by hand. Usually, one
+uses a @acronym{WYSIWYG} program to design a @w{Type 1} font. @MF{}, with
+its font-specific programming language, is an elegant alternative. A
+font designer can write reusable subroutines for repeated features,
+such as serifs and accents. He can define a font in terms of
+arbitrary parameters, such as ``boldness'' or ``italicness'', making
+it trivial to produce entire families of fonts from a single source
+(hence the ``meta'' in the name ``@MF{}''). Ideally, we would like to
+design a font using the @MF{} language, but produce PostScript @w{Type 1}
+output instead of bitmaps.
+
+@command{mf2pt1} helps bridge the gap between @MF{} and @w{Type 1} fonts.
+@command{mf2pt1} facilitates producing PostScript @w{Type 1} fonts from a
+@MF{} source file. It is @emph{not}, as the name may imply, an
+automatic converter of arbitrary @MF{} fonts to @w{Type 1} format.
+@command{mf2pt1} imposes a number of restrictions on the @MF{} input.
+If these restrictions are met, @command{mf2pt1} will produce valid
+@w{Type 1} output.
+
+@menu
+* Requirements:: Pre-installation checklist
+* Installation:: How to install mf2pt1
+@end menu
+
+
+@node Requirements, Installation, Introduction, Introduction
+@section Requirements
+
+Before using @command{mf2pt1}, you will need to install the following
+programs:
+
+@table @asis
+@item Perl
+@command{mf2pt1} is written in Perl. You will need a Perl interpreter
+to run it.
+
+@item MetaPost
+@command{mf2pt1} actually uses MetaPost, not @MF{}, to produce
+PostScript output. Specifically, you will need the @command{mpost}
+executable and the @file{mfplain.mp} base file.
+
+@item @w{Type 1} Utilities
+Producing properly encoded @w{Type 1} fonts is tricky.
+@command{mf2pt1} delegates the effort to the @w{Type 1} Utilities,
+specifically, to the @command{t1asm} program within that suite.
+
+@item FontForge (optional)
+FontForge is a @acronym{WYSIWYG}, but scriptable, @w{Type 1}
+font-editing program. Although FontForge is not strictly required for
+@command{mf2pt1} to produce a @w{Type 1} font, @command{mf2pt1} uses
+FontForge when available to autohint the generated @w{Type 1} font,
+thereby making it look better especially at lower resolutions.
+@end table
+
+Perl is available from @uref{http://www.cpan.org, the Comprehensive
+Perl Archive Network}; MetaPost and the @w{Type 1} utilities are
+available from @uref{http://www.ctan.org, the Comprehensive @TeX{}
+Archive Network}; and, FontForge is available from
+@uref{http://fontforge.sourceforge.net/}. In addition, MetaPost's
+home page is @uref{http://cm.bell-labs.com/who/hobby/MetaPost.html},
+and the @w{Type 1} utilities' home page is
+@uref{http://www.lcdf.org/type/}.
+
+Besides being useful for autohinting fonts, FontForge enables a font
+designer to hint fonts manually for additional fine-tuning and to
+convert among a variety of font formats, such as PostScript, TrueType,
+and @w{X Window} fonts. FontForge is strongly recommended as a
+complement to @command{mf2pt1}.
+
+
+@node Installation, , Requirements, Introduction
+@section Installation
+
+To install @command{mf2pt1}, move the @file{mf2pt1} executable
+someplace where your operating system can find it. If you're running
+Microsoft Windows, you should rename the program to @file{mf2pt1.pl},
+so that Windows knows it's a Perl script. (Alternatively, if you have
+@command{pl2bat}, use that to produce a @file{mf2pt1.bat} file, which
+you can run as simply @file{mf2pt1}.)
+
+The next step is to produce a @file{mf2pt1.mem} file from the supplied
+@file{mf2pt1.mp}. The command to do this differs from system to
+system but is usually something like the following:
+
+@example
+mpost -progname=mpost -ini mf2pt1 \\dump
+@end example
+
+Move the resulting @file{mf2pt1.mem} file someplace where MetaPost can
+find it.
+
+@sp 1
+
+The @command{mf2pt1} documentation (what you're reading now) is written
+in Texinfo and can therefore easily be converted to a variety of
+formats:
+
+@table @asis
+@item PDF (@file{mf2pt1.pdf})
+@example
+texi2pdf mf2pt1.texi
+@end example
+
+@item PostScript (@file{mf2pt1.ps})
+@example
+texi2dvi mf2pt1.texi
+dvips mf2pt1.dvi -o mf2pt1.ps
+@end example
+
+@item HTML (@file{mf2pt1.html})
+@example
+makeinfo --html mf2pt1.texi
+@end example
+
+@item Info (@file{mf2pt1.info})
+@example
+makeinfo mf2pt1.texi
+@end example
+@end table
+
+@noindent
+N.B@. The @command{install-info} command is a convenient way to install
+@file{mf2pt1.info} on your system.
+
+@sp 1
+
+On Unix, you may also want to generate an @command{mf2pt1} man page.
+The man page is embedded within the @file{mf2pt1} Perl script and can be
+extracted with @command{pod2man}:
+
+@example
+pod2man --center="User Commands" --date="@value{DATE}" \
+ --release="v@value{VERSION}" mf2pt1 > mf2pt1.1
+@end example
+
+@noindent
+You can then move @file{mf2pt1.1} into @file{/usr/man/man1} or any other
+man page directory. Note that the @command{mf2pt1} man page is fairly
+rudimentary. It is primarily a list of the command-line options
+(@pxref{Font information}) and a pointer to the document that you're
+reading now.
+
+
+@node Usage, Future Work, Introduction, Top
+@chapter Usage
+
+@command{mf2pt1} is fairly straightforward to use. To process a
+@MF{} source file, merely specify the filename:
+
+@example
+mf2pt1 myfont.mf
+@end example
+
+@noindent
+That simple command automatically performs all of the following
+operations:
+
+@enumerate
+@item
+Read @file{myfont.mf}.
+
+@item
+Use @command{mpost} to convert each character to a separate
+Encapsulated PostScript (@acronym{EPS}) file named
+@file{myfont.@var{num}}.
+
+@item
+Process and merge the @acronym{EPS} files into a single
+``disassembled'' @w{Type 1} font called @file{myfont.pt1}.
+
+@item
+Run @command{t1asm} from the @w{Type 1} Utilities to convert the
+disassembled font into a true, binary @w{Type 1} font called
+@file{myfont.pfb}.
+
+@item
+Invoke @command{fontforge} to apply rendering hints to
+@file{myfont.pfb} and to attempt to remove overlapping paths.
+@end enumerate
+
+The external programs launched by @command{mf2pt1}---@command{mpost},
+@command{t1asm}, and @command{fontforge}---can be overridden by
+setting the eponymous, uppercase environment variable. For example,
+invoking FontForge's predecessor, PfaEdit, instead of FontForge is
+simply a matter of setting the @samp{FONTFORGE} environment variable
+to @samp{pfaedit} before invoking @command{mf2pt1}. As a corollary,
+you can inhibit an @command{mf2pt1} external program from running by
+setting the corresponding environment variable to the name of a
+nonexistent program.
+
+@menu
+* Restrictions:: Restrictions imposed on the font source code
+* Font information:: Specifying PostScript font characteristics
+* Additional command-line options:: Options unrelated to font characteristics
+* Custom font encodings:: Altering the mapping from character name to number
+* Restoring mfplain defaults:: Using the original (un)filldraw and pencircle
+@end menu
+
+
+@node Restrictions, Font information, Usage, Usage
+@section Restrictions
+
+If @command{mf2pt1} sounds too good to be true, it is---somewhat.
+@command{mf2pt1} is not a general-purpose @MF{}-to-@w{Type 1}
+converter. Rather, it can convert only certain @MF{} constructs.
+This is not a showstopper for new fonts designed with @command{mf2pt1}
+in mind, but it is unlikely that @command{mf2pt1} will work on an
+arbitrary @MF{} source file.
+
+@command{mf2pt1}'s biggest restriction is that each glyph must be
+drawn entirely from closed paths, using @MF{}'s @strong{fill} and
+@strong{unfill} commands. (@command{mf2pt1} has limited support for
+@strong{draw} and @strong{undraw}, but their use is currently
+discouraged. @strong{filldraw} and @strong{unfilldraw} issue a
+warning message and invoke @strong{draw} and @strong{undraw},
+respectively.) The @w{Type 1} format requires that these paths be
+nonoverlapping. The following are some of the alternatives for
+removing path overlaps:
+
+@enumerate
+@item
+Install FontForge. As part of its final step in producing a @w{Type
+1} font, @command{mf2pt1} instructs FontForge to replace overlapping
+paths with nonoverlapping paths.
+
+@item
+Remove overlaps using @MF{} code within the font program itself. A
+@file{.zip} file attachment to
+@uref{http://tug.org/mailman/htdig/metapost/2005-January/000080.html,
+a @w{6 January} 2005 article} by
+@iftex
+@tex
+Bogus\l{}aw
+@end tex
+@end iftex
+@ifnottex
+Boguslaw
+@end ifnottex
+Jackowski on the MetaPost mailing list (subject: ``Re: all
+intersections between two paths'') includes a MetaPost library which
+assists with that task. The library provides a @strong{find_outlines}
+command which can be used to define a path as the union of two other
+paths. A number of MetaPost example programs are also included in the
+@file{.zip} file.
+
+@item
+Design your fonts from the beginning without using overlapping paths.
+@end enumerate
+
+A secondary restriction is that @command{mf2pt1} redefines a number of
+Plain @MF{} commands, such as @strong{beginchar}, @strong{fill}, and
+@strong{unfill}. @MF{} font programs which redefine or bypass these
+(using @MF{} primitives) will not be convertible with
+@command{mf2pt1}.
+
+A far less severe restriction is due to @command{mf2pt1}'s utilizing
+MetaPost's @MF{} interface instead of @MF{} itself. The implication
+is that commands not defined by MetaPost's @file{mfplain.mp} cannot be
+handled by @command{mf2pt1}, either. Very few fonts will have a
+problem with this restriction but see the MetaPost manual for more
+information.
+
+
+@node Font information, Additional command-line options, Restrictions, Usage
+@section Specifying font information
+
+@iftex
+@tex
+@leavevmode
+@end tex
+@end iftex
+@MF{} fonts normally specify a set of @strong{fontdimen}s which
+provide information about a particular font that cannot otherwise be
+inferred. These include features such as the font's x-height, quad
+width, interword stretchability and shrinkability, and other design
+characteristics that @TeX{} makes use of. PostScript fonts utilize a
+largely different set of font parameters, such as the underline
+position and thickness, font family name, and copyright notice.
+@command{mf2pt1} provides @MF{} commands to define the PostScript font
+parameters in the generated @w{Type 1} font. These parameters should
+appear in the @MF{} source file as follows:
+
+@display
+@b{if} known @i{ps_output}:
+ @dots{}
+@b{fi}
+@end display
+
+@noindent
+@code{ps_output} is defined by @command{mf2pt1} but not by Plain
+@MF{}. Checking if it is known is the recommended way to determine if
+the font is being built under @command{mf2pt1}.
+
+@ifnottex
+@menu
+* Parameters:: Font-information commands available to Metafont
+* Command-line equivalents:: Specifying font features on the command line
+* Default values:: Types and default values of each parameter
+* Parameter example:: Metafont example which specifies all parameters
+@end menu
+
+
+@node Parameters, Command-line equivalents, Font information, Font information
+@subsection Parameters
+@end ifnottex
+
+The following list presents all of the font-information commands
+provided by @command{mf2pt1} and describes what each command means.
+Commands marked with an asterisk are also defined by Plain @MF{} and
+therefore do not need to be enveloped within a test for
+@code{ps_output}.
+
+@table @strong
+@item font_coding_scheme
+The mapping between character numbers and PostScript names. If this
+is the name of a file, @command{mf2pt1} expects it to contain
+PostScript code defining a font-encoding vector. @xref{Custom font
+encodings}, for an example of such a file. If
+@strong{font_coding_scheme} is not the name of a file,
+@command{mf2pt1} expects it to be one of the literal strings
+@code{standard} (Adobe standard encoding), @code{isolatin1} (ISO Latin
+1 encoding), @code{ot1} (@TeX{} 7-bit encoding), @code{t1} (@TeX{}
+8-bit encoding), or @code{asis} (encoding integrated with the
+character programs using the @strong{glyph_name} command as described
+in @ref{Custom font encodings}). Anything else will generate a
+warning message and cause @command{mf2pt1} to use @code{standard}
+instead.
+
+@item font_comment
+A textual comment that will appear within the generated font. This is
+often used for copyright notices.
+
+@item font_family
+The family that this font belongs to. For example, ``Utopia Bold
+Italic'' belongs to the @code{Utopia} family.
+
+@item font_fixed_pitch
+Whether the font is monospaced (if @strong{true}) or or proportionally
+spaced (if @strong{false}).
+
+@item font_identifier (*)
+The full name of the font, e.g., @code{Utopia Bold Italic}.
+
+@item font_name
+The symbolic font name, used to load the font from a PostScript
+document. Spaces are forbidden. Generally, the font name is of the
+form @code{@var{family}-@var{modifiers}}. For example, the font name
+of Utopia Bold Italic would be @code{Utopia-BoldItalic}.
+
+@item font_size (*)
+The font design size. This is specified in ``sharped'' units within
+@MF{} code or as a point size on the command line.
+
+@item font_slant (*)
+When specified with @strong{font_slant}, the amount of slant per
+point. When specified with @copt{italicangle}, the angle in
+counterclockwise degrees from the vertical (i.e., zero for an upright
+font, negative for a right-slanting italic font).
+
+@item font_underline_position
+The vertical position at which an underline should lie, specified in
+``sharped'' units within @MF{} code or as a number of points on the
+command line.
+
+@item font_underline_thickness
+The thickness of an underline, specified in ``sharped'' units within
+@MF{} code or as a number of points on the command line.
+
+@item font_unique_id
+The unique ID for this font. The ID should be between 0 and
+16,777,215. If not specified, @command{mf2pt1} will choose an ID at
+random from the ``open'' range, 4,000,000-4,999,999. All IDs not in
+that range are allocated by contacting Adobe's UniqueID Coordinator.
+(I don't believe a fee is involved, but I don't know for sure.)
+
+@item font_version
+The version number of the font. This should be of the form
+@code{@var{MMM}.@var{mmm}}, where @var{MMM} is the major version
+number and @var{mmm} is the minor version number.
+
+@item font_weight
+The font weight. For example, the font weight of Utopia Bold Italic
+is @code{Bold}.
+@end table
+
+
+@ifnottex
+@node Command-line equivalents, Default values, Parameters, Font information
+@subsection Command-line equivalents
+@end ifnottex
+
+Each of the
+@iftex
+preceding font-information commands
+@end iftex
+@ifnottex
+font-information commands listed in @ref{Parameters}
+@end ifnottex
+has a command-line equivalent. Their use is discouraged but they are
+listed here for completeness:
+
+@multitable {@strong{font_underline_thickness}} {@copt{fontversion}}
+@item
+@strong{font_coding_scheme}
+@tab @copt{encoding}
+
+@item
+@strong{font_comment}
+@tab @copt{comment}
+
+@item
+@strong{font_family}
+@tab @copt{family}
+
+@item
+@strong{font_fixed_pitch}
+@tab @copt{fixedpitch}
+
+@item
+@strong{font_identifier}
+@tab @copt{fullname}
+
+@item
+@strong{font_name}
+@tab @copt{name}
+
+@item
+@strong{font_size}
+@tab @copt{designsize}
+
+@item
+@strong{font_slant}
+@tab @copt{italicangle}
+
+@item
+@strong{font_underline_position}
+@tab @copt{underpos}
+
+@item
+@strong{font_underline_thickness}
+@tab @copt{underthick}
+
+@item
+@strong{font_unique_id}
+@tab @copt{uniqueid}
+
+@item
+@strong{font_version}
+@tab @copt{fontversion}
+
+@item
+@strong{font_weight}
+@tab @copt{weight}
+@end multitable
+
+A special case is @copt{fixedpitch} which does not take an argument.
+Rather, you should use @copt{fixedpitch} as the equivalent of
+@samp{font_fixed_pitch true} and @copt{nofixedpitch} as the equivalent
+of @samp{font_fixed_pitch false}.
+
+
+@ifnottex
+@node Default values, Parameter example, Command-line equivalents, Font information
+@subsection Default values
+@end ifnottex
+
+The next table lists the @MF{} type and default value of each of the
+parameters listed in
+@ifnottex
+@ref{Parameters}.
+@end ifnottex
+@ifnotinfo
+the previous table.
+@end ifnotinfo
+
+@multitable {@strong{font_underline_thickness}} {@strong{numeric}} {MMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @strong{font_coding_scheme}
+@tab @strong{string}
+@tab @code{"standard"}
+
+@item @strong{font_comment}
+@tab @strong{string}
+@tab @code{"Font converted to @w{Type 1} by mf2pt1, written by Scott Pakin."}
+
+@item @strong{font_family}
+@tab @strong{string}
+@tab (The value of @strong{font_identifier})
+
+@item @strong{font_fixed_pitch}
+@tab @strong{boolean}
+@tab @strong{false}
+
+@item @strong{font_identifier}
+@tab @strong{string}
+@tab (The input filename, minus @file{.mf})
+
+@item @strong{font_name}
+@tab @strong{string}
+@tab (The value of @strong{font_family}, plus an underscore, plus the
+ value of @strong{font_weight}, with all spaces removed)
+
+@item @strong{font_size}
+@tab @strong{numeric}
+@tab (Must be specified or @command{mf2pt1} will abort with an error message)
+
+@item @strong{font_slant}
+@tab @strong{numeric}
+@tab 0
+
+@item @strong{font_underline_position}
+@tab @strong{numeric}
+@tab -1
+
+@item @strong{font_underline_thickness}
+@tab @strong{numeric}
+@tab 0.5
+
+@item @strong{font_unique_id}
+@tab @strong{string}
+@tab (Randomly generated in the range 4000000-4999999)
+
+@item @strong{font_version}
+@tab @strong{string}
+@tab @code{"001.000"}
+
+@item @strong{font_weight}
+@tab @strong{string}
+@tab @code{"Medium"}
+@end multitable
+
+@sp 1
+
+
+@ifnottex
+@node Parameter example, , Default values, Font information
+@subsection Parameter example
+@end ifnottex
+
+As an example, the following @MF{} code shows the usage of all of the
+parameters that @command{mf2pt1} accepts:
+
+@noindent
+@b{if} known @i{ps_output}:
+@multitable {@b{if}} {@b{font_underline_thickness}} {@t{"Copyright (C) 2014 Scott Pakin.";}}
+@item @tab @b{font_coding_scheme} @tab @t{"ot1"};
+@item @tab @b{font_comment} @tab @t{"Copyright (C) 2014 Scott Pakin."};
+@item @tab @b{font_family} @tab @t{"Kerplotz"};
+@item @tab @b{font_fixed_pitch} @tab @b{false};
+@item @tab @b{font_identifier} @tab @t{"Kerplotz Light Oblique"};
+@item @tab @b{font_name} @tab @t{"Kerplotz-LightOblique"};
+@item @tab @b{font_size} @tab 10@i{pt}#; @ @ @ @ @ % Important to include this.
+@item @tab @b{font_slant} @tab 1/6;
+@item @tab @b{font_underline_position} @tab -1@i{pt}#;
+@item @tab @b{font_underline_thickness} @tab 1/2@i{pt}#;
+@item @tab @b{font_unique_id} @tab @t{"4112233"}; @ @ @ @ @ % Better to omit this.
+@item @tab @b{font_version} @tab @t{"002.005"};
+@item @tab @b{font_weight} @tab @t{"Light"};
+@end multitable
+@noindent
+@b{fi}
+
+@noindent
+In the above, the @strong{font_fixed_pitch} call could have been
+omitted, as it defaults to @strong{false}. Also, unless you've
+requested a unique ID from Adobe, it's generally better not to assign
+@strong{font_unique_id}; let @command{mf2pt1} choose a random value
+itself.
+
+The same parameters can also be specified on the command line as
+follows:
+
+@example
+mf2pt1 --encoding=ot1 --comment="Copyright (C) 2014 Scott Pakin."
+ --family=Kerplotz --nofixedpitch --fullname="Kerplotz Light Oblique"
+ --name=Kerplotz-LightOblique --designsize=10 --italicangle=-9.5
+ --underpos=-100 --underthick=50 --uniqueid=4112233 --version=002.005
+ --weight=Light kerplotz.mf
+@end example
+
+@noindent
+Note that a @MF{} font slant of 1/6 is equal to a PostScript italic
+angle of approximately -9.5. The conversion formula is
+@iftex
+@tex
+$s = -@tan @theta$, in which $s$ is the slant and $@theta$ is the
+italic angle.
+@end tex
+@end iftex
+@ifnottex
+slant = -tan(angle).
+@end ifnottex
+In addition, the underline position and thickness must be multiplied by
+1000/@strong{font_size} to convert from the @MF{} units that are used
+within the @file{.mf} file to the PostScript units that are used on the
+command line.
+
+
+@node Additional command-line options, Custom font encodings, Font information, Usage
+@section Additional command-line options
+
+In addition to the command-line options for setting font parameters
+that were presented in
+@iftex
+@ref{Font information},
+@end iftex
+@ifnottex
+@ref{Parameters},
+@end ifnottex
+@command{mf2pt1} supports a @copt{rounding} option. While
+@command{mf2pt1} normally rounds all font coordinates to the nearest
+integer, @copt{rounding} increases coordinate precision by
+instructing @command{mf2pt1} to round instead to the nearest multiple
+of a given fractional number. For example, @samp{--rounding=0.25}
+rounds the coordinate @math{(7.4, 10.3)} to @math{(7.5, 10.25)} while
+it would otherwise be rounded to the less-precise @math{(7, 10)}.
+
+Large glyphs can be problematic in MetaPost and therefore in
+@command{mf2pt1}. Unlike @MF{}, MetaPost does not honor @samp{mag}
+for magnifying dimensions. Rather, the number of PostScript
+(a.k.a. ``big'') points per pixel---@samp{bpppix}---is hardwired @w{to
+0.02} and all other dimensions (@samp{mm}, @samp{in}, @samp{pt},
+etc.@:) are expressed in terms of that. Consequently, glyphs that
+multiply a large number of font units by a dimension are likely to
+exceed 4096, the largest value that MetaPost can represent in its
+fixed-point format. If numerical overflow becomes a problem you can
+use the @copt{bpppix} option to @command{mf2pt1} to change the value
+of @samp{bpppix}. For example, specifying @samp{--bpppix=0.2} enables
+a tenfold increase in maximum glyph size (with a corresponding
+decrease in precision).
+
+After generating a @w{Type 1} font, @command{mf2pt1} runs it through
+FontForge to add hinting information, remove overlaps, and otherwise
+clean up the generated font. The @copt{ffscript} option specifies
+the filename of a FontForge script to use instead of the default
+script, which is listed below:
+
+@example
+Open($1);
+SelectAll();
+RemoveOverlap();
+AddExtrema();
+Simplify(0, 2);
+CorrectDirection();
+Simplify(0, 2);
+RoundToInt();
+AutoHint();
+Generate($1);
+Quit(0);
+@end example
+
+@noindent
+See the FontForge documentation for an explanation of each of those
+commands and a description of other commands made available to
+FontForge scripts. @command{mf2pt1} runs the script with one argument
+(@code{$1}), which is the name of the generated @file{.pfb} file.
+
+@command{mf2pt1} also supports a @copt{help} option which summarizes
+all of the program's command-line options.
+
+@c Improve formatting by keeping the large cartouche on the same
+@c page as the text that introduces it.
+@page
+
+@node Custom font encodings, Restoring mfplain defaults, Additional command-line options, Usage
+@section Custom font encodings
+
+@iftex
+@ref{Font information},
+@end iftex
+@ifnottex
+@ref{Parameters},
+@end ifnottex
+lists the font encodings currently supported by @command{mf2pt1} and
+mentions that an alternate encoding can be specified by providing the
+name of an encoding file. To elaborate, the following example
+represents the contents of an encoding file which defines a---largely
+useless nowadays---@acronym{EBCDIC} font encoding:
+
+@cartouche
+@quotation
+@code{% Sample encoding vector: @acronym{EBCDIC}@*
+@*
+% The encoding vector must have a name and be defined as a PostScript array.@*
+/ebcdic_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 /space /_a65 /_a66 /_a67
+/_a68 /_a69 /_a70 /_a71 /_a72 /_a73 /bracketleft /period /less
+/parenleft /plus /exclam /ampersand /_a81 /_a82 /_a83 /_a84 /_a85
+/_a86 /_a87 /_a88 /_a89 /bracketright /dollar /asterisk /parenright
+/semicolon /asciicircum /hyphen /slash /_a98 /_a99 /_a100 /_a101
+/_a102 /_a103 /_a104 /_a105 /bar /comma /percent /underscore /greater
+/question /_a112 /_a113 /_a114 /_a115 /_a116 /_a117 /_a118 /_a119
+/_a120 /_a121 /colon /numbersign /at /quoteright /equal /quotedbl
+/_a128 /a /b /c /d /e /f /g /h /i /_a138 /_a139 /_a140 /_a141 /_a142
+/_a143 /_a144 /j /k /l /m /n /o /p /q /r /_a154 /_a155 /_a156 /_a157
+/_a158 /_a159 /_a160 /asciitilde /s /t /u /v /w /x /y /z /_a170 /_a171
+/_a172 /_a173 /_a174 /_a175 /_a176 /_a177 /_a178 /_a179 /_a180 /_a181
+/_a182 /_a183 /_a184 /quoteleft /_a186 /_a187 /_a188 /_a189 /_a190
+/_a191 /braceleft /A /B /C /D /E /F /G /H /I /_a202 /_a203 /_a204
+/_a205 /_a206 /_a207 /braceright /J /K /L /M /N /O /P /Q /R /_a218
+/_a219 /_a220 /_a221 /_a222 /_a223 /backslash /_a225 /S /T /U /V /W /X
+/Y /Z /_a234 /_a235 /_a236 /_a237 /_a238 /_a239 /zero /one /two /three
+/four /five /six /seven /eight /nine /_a250 /_a251 /_a252 /_a253
+/_a254 /_a255@*
+% Don't forget to end the array.@*
+] def}
+@end quotation
+@end cartouche
+
+All entries in the encoding vector are PostScript ``names'' and
+therefore must be prefixed with a slash. Unnamed characters such as
+control characters are commonly named @samp{_a@var{number}}, where
+@var{number} is the decimal offset into the character table.
+Undefined characters are indicated by @samp{.notdef}. In the
+@acronym{EBCDIC} example, the character at @w{position 0} in the font
+will be named @samp{a0}; the character at @w{position 1} will be named
+@samp{a1}; the character at @w{position 74} will be named
+@samp{bracketleft}; the character at @w{position 129} will be named
+@samp{a}; and so forth.
+
+Individual characters can be mapped to an encoding either numerically
+or by executing a @strong{glyph_name} command within a character
+definition. For example, the following code overrides the character
+position passed to @strong{beginchar} @w{(i.e., 123)} with whatever
+character position the current encoding has designated for the
+@samp{ohungarumlaut} glyph:
+
+@display
+@b{beginchar} (123, cap_height#-1/2pt#, cap_height#, 0);
+ @b{if} known @i{ps_output}:
+ @i{glyph_name} @t{"ohungarumlaut"};
+ @b{fi}
+ @dots{}
+@b{endchar};
+@end display
+
+
+@node Restoring mfplain defaults, , Custom font encodings, Usage
+@section Restoring @file{mfplain} defaults
+
+@command{mf2pt1} normally redefines @strong{filldraw} as @strong{fill}
+and @strong{unfilldraw} and @strong{unfill} because @w{Type 1} fonts
+don't allow overlapping curves. Similarly, @command{mf2pt1} redefines
+@strong{pencircle} as a 20-gon to coerce MetaPost into drawing it
+using a filled instead of a stroked PostScript path.
+
+If you know you'll be postprocessing your fonts using FontForge, which
+can automatically convert overlapping paths to nonoverlapping paths,
+then you can restore the original @file{mfplain.mp} definitions of
+@strong{filldraw}, @strong{unfilldraw}, and @strong{pencircle} as
+follows:
+
+@display
+@b{if} known @i{ps_output}:
+ @b{pencircle} := @i{mfplain_pencircle};
+ @b{let filldraw} := @i{mfplain_filldraw};
+ @b{let unfilldraw} := @i{mfplain_unfilldraw};
+@b{fi}
+@end display
+
+
+@node Future Work, Acknowledgments, Usage, Top
+@chapter Future Work
+
+One avenue for future work is to enable the font designer to specify
+@w{Type 1} font hints directly in the @MF{} font program. Hinting is
+a way for a font designer to specify how a font should be rendered at
+low resolutions, for example, at typical monitor resolutions. In
+@MF{}, this is done by controlling the way that points are mapped to
+pixel locations, using commands such as
+@strong{define_corrected_pixels}, @strong{define_blacker_pixels}, and
+@strong{lowres_fix}. @w{Type 1} fonts are hinted in a completely
+different manner. @w{Type 1} hints distinguish key character
+features, such as stems and dots, from decorations which can be
+discarded at low resolutions. The PostScript interpreter uses that
+information to determine how to map points to pixels. Although
+@command{mf2pt1} employs FontForge to autohint the fonts it generates,
+the approach is mechanical and unlikely to hint as well as a human can
+do manually. It would be convenient for @command{mf2pt1} one day to
+provide @MF{} commands for @strong{hstem}, @strong{vstem},
+@strong{dotsection}, and the other @w{Type 1} hints. That way, hints
+will no longer need to be re-added manually every time
+@command{mf2pt1} regenerates a @w{Type 1} font.
+
+Another future addition to @command{mf2pt1} is the addition of more
+font encodings. The following are the encodings that @command{mf2pt1}
+will most likely accept:
+
+@table @code
+@item TeXMathItalicEncoding
+Upper- and lowercase Greek and Latin letters, old-style digits, and a
+few symbols and accents.
+
+@item TeXMathSymbolEncoding
+A variety of symbols, as well as calligraphic Latin majuscules.
+
+@item TeXMathExtensionEncoding
+Variable-sized symbols, such as braces, integrals, and radicals.
+
+@item AdobeExpert
+Small caps, currency symbols, old-style digits, and various superior and
+inferior letters and digits.
+@end table
+
+
+@node Acknowledgments, , Future Work, Top
+@unnumbered Acknowledgments
+
+Many thanks are owed to Werner Lemberg for writing the code underlying
+the @copt{rounding} option; for introducing the @strong{glyph_name}
+command and @code{asis} encoding vector; for providing the default
+FontForge script listed in @ref{Additional command-line options}; for
+fixing some code-generation bugs in @command{mf2pt1}; for finding a
+more robust way to dump @file{mf2pt1.mem}; for directing me to the
+overlap-removal code mentioned in @ref{Restrictions}; for supplying
+the @emph{crossproduct}, @emph{makeline}, and @emph{is_clockwise}
+functions used by @file{mf2pt1.mp}; for proposing the @copt{bpppix}
+command-line option; and, for suggesting various features and
+improvements to @command{mf2pt1}. Thanks also go to Werner Lemberg
+and
+@iftex
+@tex
+Bogus\l{}aw
+@end tex
+@end iftex
+@ifnottex
+Boguslaw
+@end ifnottex
+Jackowski for updating the @strong{is_clockwise} function in
+@file{mf2pt1.mp} to work around a bug in MetaPost which relates to the
+@strong{turningnumber} command. Finally, thanks go to Ralf Stubner
+for providing the T1 encoding vector and for pointing out a typo in
+the generated font programs; to Michael Zedler for alerting me to
+problems with @copt{encoding} and suggesting I modify that option to
+accept PostScript @file{.enc} files; and to Michael Ummels for fixing
+a couple of bugs that made character widths in the generated fonts
+slightly too large.
+
+@bye