mf2ff mf2ff 、FontForgeのPython APIを使用してMetaFontコードからベクトルフォントを作成するツールです。
これは、MF2VECコンセプトセクションで以下で説明するビットマップトレースの迂回路なしで、MetaFontがベクトルフォントジェネレーターと協力する方法の概念に基づいています。 mf2ffは最初であり、開発者の知る限り、これまでのこの概念の唯一の実装です。
以下に、セットアップ方法と使用方法に関するヘルプがあります。
このツールはまだ徹底的にテストされていませんが、最も一般的なMetafontコマンドがサポートされています。充填と描画に加えて、Kerningといくつかの結晶コマンドもサポートされています。以下にリストされている制限をご覧ください。
mf2ffmf2ffの現在の制限mf2ffを使用するには、FontForgeとMetafontをインストールする必要があります。
mf2ffスクリプトの実行に問題がある場合があります。 1つの問題は、fontforgeモジュールでpython 3を実行する必要があることです。以下は、それを機能させる方法に関するいくつかのヒントです。これがあなたのシステムで機能することを保証することはできませんが、試してみる必要があります。
以下のヒントが機能しないさまざまなオペレーティングシステムまたはシステム構成では、PythonとFontforgeのPythonモジュールを使用するかどうかを確認してください。
ffpython 、 python3 、 python )を実行します。バージョン情報がPython 3を実行していることを確認していることを確認してください。import fontforge 、エラーなしで動作するはずです。fontforge.font()エラーを上げないでください。これが一部のディレクトリでのみ機能する場合は、 PATHまたはPYTHONPATH変数を確認する必要があります。FontforgeのPythonバージョンffpythonへの一時的なアクセスのために、fontforgeにはバッチファイルが付属しています。
C:Program Files (x86)FontForgeBuilds setに移動し、 PATH fontforge-console.batを実行します。永続的なアクセスのために、パス変数を永続的に編集する必要があります。
environment variablesを検索し、 Edit the system environment variables 。 Environment variablesをクリックして、複数のユーザーアカウントでffpythonにアクセスする必要がある場合は、ユーザーアカウントのPATH変数またはシステムのいずれかを編集します。次に、fontforgeのパス( C:Program Files (x86)FontForgeBuildsbin 、 bin !)をリストに追加します。ffpythonはすべての新しいコマンドプロンプトWindowsで利用可能になりましたffpython path/to/mf2ff.py ...どこからでもmf2ffスクリプトに簡単にアクセスするには、次のことを行います。
mf2ffのパスをPYTHONPATH変数に追加します。 PYTHONPATH変数がまだない場合は、リストに追加します。ffpython -m mf2ff ...を使用してmf2ffを実行できるはずです。Ubuntuはこの例で使用されています。
一部のリポジトリは、Python 2サポートを備えたFontforgeの古いバージョンを出荷します。あなたは出典からfontforgeを構築することをお勧めします:
sudo apt install libjpeg-dev libtiff5-dev libpng-dev libfreetype6-dev libgif-dev libgtk-3-dev libxml2-dev libpango1.0-dev libcairo2-dev libspiro-dev libuninameslist-dev python3-dev ninja-build cmake build-essentialsudo apt install gitgit clone https://github.com/fontforge/fontforge 。これにより、 fontforge/ディレクトリが作成されます。fontforge/ディレクトリ内の別のディレクトリに移動します。cd fontforge; mkdir build; cd buildcmake -GNinja ..ninjasudo ninja install注:このプロセスに問題がある場合は、FontForeのドキュメントを確認してください。
FontforgeのPythonモジュールに簡単にアクセスするには、PythonPathに追加します。
~/.profileファイルの最後に次の行を置きます: export PYTHONPATH=$PYTHONPATH:/path/to/fontforge/ 、 /path/to/fontforge/ directoryは、gitでfontforgeを作成することによって作成され$HOME/fontforge 。python3 path/to/mf2ff.py ...を常に使用できるはずです。注:Python 3を実行するには、 python3の代わりにpythonを入力する必要があるシステムの構成によっては、必要です。
どこからでもmf2ffスクリプトに簡単にアクセスするには、その場所をPythonPath変数に追加します。
~/.profileファイルの最後に配置します: export PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ 、ここで/path/to/mf2ff/ディレクトリは、 mf2ff.py $HOME/mf2ff/mf2ffを配置するものです。python3 -m mf2ff ...でいつでもmf2ff簡単に実行できます。注:使用しているドットファイルに応じて、再起動の代わりにシェルを再起動するだけで十分です。
以下のソリューションでは、Homebrewを使用しています。このようにして、fontforgeはpythonでアクセスできます:
brew install fontforge 。python3 path/to/mf2ff.py ...いつでも使用できます。注:Python 3を実行するには、 python3の代わりにpythonを入力する必要があるシステムの構成によっては、必要です。
どこからでもmf2ffスクリプトに簡単にアクセスするには、その場所をPYTHONPATH変数に追加します。
PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/で追加します。zshを使用しています。ホームディレクトリで、ファイル.zshenvを作成または変更します。bashを使用しています。ホームディレクトリで、ファイル.bash_profileを作成または変更します。tcshを使用しています。ホームディレクトリで、 tcshシェルの対応するファイルを作成または変更します。python3 -m mf2ff ...を使用していつでもmf2ffを実行できます。 デフォルトでは、 mf2ff Spline Fontデータベース(.SFD)ファイルを生成します。 Options -ttf / mf2ff.options['ttf'] = Trueまたは-otf / mf2ff.options['otf'] = Trueを使用するには、フォントを直接生成できます。
mf2ff 、グリフを手動で作り直したいと思うため、デフォルトではあまりクリーンアップしません。 Options -cull-at-shipout / mf2ff.options['cull-at-shipout'] = Trueまたは-remove-artifacts / mf2ff.options['remove-artifacts'] = True Trueを使用して、自動化されたクリーンアップを実行できます。 Glyph定義の一部であるCullコマンドは、一部のcull-at-shipoutにさらに変更を加えない場合がある場合があることに注意してください。
以下にリストされている制限をご覧ください。
MF2VECコンセプトの主なアイデアは、MetaFontにGlyphsのジオメトリを別のプログラムにリダイレクトすることです( mf2ffの場合、このプログラムはFontForgeです)。ビットマップフォントを生成する代わりに使用します。これは、Metafontがベクトルフォントファイル、つまりBézierCurvesでその後必要になるのと同じ幾何学的説明を内部的に使用しているために可能です。
Bézier曲線をグラフィックスをラスターし、Bézier曲線に戻すためのいくつかの代替案で使用される迂回路は回避されます。ジオメトリを直接使用することにより、情報は失われません。
Metapostなどの他のツールの代わりにMetafontが使用されているため、 .mfファイルを読み取るために、変更されていないMetafontコードファイルを使用できます。ジオメトリだけでなく、文字エンコード、ボックスサイズ、カーニング情報、派生情報なども、手動で手動でリワークせずにベクターフォントに出荷されます。
情報のこの傍受は、Metafontコマンドを再定義することによって行われます。 Metafontはランタイム中に他のプログラムと対話できないため、.MFファイルの解釈とフォントの生成は時間内に分離する必要があります。したがって、Metafontがビットマップグラフィックを生成するために使用する情報は、Metafontのログファイルに保存されます。 Metafontのコマンドは再定義され、Metafontがログファイルにジオメトリとフォントのプロパティを書き込むようになります。 MetafontがMetafontファイルのすべてのコマンドを処理すると、情報はログファイルから読み取り、処理されてフォントを作成し、ログファイルから削除して削除してクリアします。
このアプローチに対するアイデアは2018年10月に発表されました。慣習を確認するために、Fontforgeの実装がPythonですぐに実現され、サポートされたコマンドの範囲が徐々に拡大されました。最初のテストでアイデアが機能することが示されたとき、他の関心のあるユーザーがmf2ff利用できるようにすることが決定されました。これは2019年3月から発生しています。いくつかの改善とバグ修正の後、開発は数年間一時停止されました。コミュニティのフィードバックにより、 mf2ff開発は2023年7月に継続されました。
基本的なアイデア
この概念は、基本的なMetafontコマンドの再定義に基づいています。これらは、情報メタフォントが通常使用してビットマップフォントを作成するように定義されています。ログファイルに書き込まれます。その後、このログファイルが読み取られ、命令がプログラムに渡され、そこからベクトルフォントが生成されます。たとえば、 mf2ffこの目的にFontForgeを使用します。その後、変更されたMetaFontコマンドによって追加された情報は、ログファイルから削除され、明確にします。
次の図は、例としてmf2ffを使用した概念を示しています。
┌──────────┐
│ font.mf │
└──────────┘
v
┌──────────┐ ┌───────────┐
│ │ > │ METAFONT │
│ │ └───────────┘
│ │ v
│ │ ┌───────────┐
│ mf2ff │ < │ font.log │
│ │ └───────────┘
│ │
│ │ ┌───────────┐
│ │ > │ FontForge │
└──────────┘ └───────────┘
v v
┌──────────┐ ┌─────────────────────┐
│ font.log │ │ font.ttf / font.otf │
└──────────┘ └─────────────────────┘
簡単な例
次のコードをMetaFontファイルに追加すると、MetaFontは輪郭c fillず、操作をログファイルに書き込むことになります。
def fill expr c =
message "fill"; show c;
enddef;
Metafontがファイルの処理を終了した後、スクリプトがログファイルを分析し、 fillコマンドがあり、輪郭が入力されることを知っていることを知っています。この情報は、フォント処理プログラムに渡してGLYPHに追加できます。
実際、このプロセスははるかに複雑です。 Plain Metafontに基づいていないMetaFontファイルを処理できるようにするには、 fillのようなコマンドの代わりにaddtoのようなコマンドを再定義する必要があります。しかし、それらのaddtoコマンドはより複雑です。また、 unfill 、( un ) draw 、( un ) drawdot 、 eraseなど、他のプレーンメタフォントコマンドの基礎を形成します。これらのコマンドは、これらの異なる操作also実行するために必要な情報のさまざまな部分を分離するいくつかのキーワードに拡張されます( addto 、 contour 、 doublepath 、 withpen 、 withweight )。
別の課題は、条件とループのコロンです。これらの構造は、コロンをセパレーターとして使用するコマンド( ligtable and fontdimen )として使用するコマンドでも、他のコマンドに表示される可能性があるため:ログファイルに情報を出力するために他のキーワードと同様に再定義する必要があります。これらのコマンド内では、コロンの異なる再定義間の洗練された切り替えが必要です。
それに加えて、Metafont Primitivesの再定義に関連しないMetaFontファイルにメッセージコマンドがある場合でも、ログファイル内のすべてのコマンドを簡単に見つけるためにプロセスを実装する必要があります。それらは、フォント生成の情報として解釈されるべきではありません。したがって、ログファイルに記載されているすべての情報は、Metafontファイルのメッセージコマンドで使用される可能性が低い特別なキーワードに囲む必要があります。
1977年以来De Knuthによって開発されたMetafontは、Metafont言語で記述されたファイルからビットマップフォントを生成するプログラムです。ビットマップフォントには、拡大下でぼやけているという不利な点があります。メタフォントは、プリンターの特定の解像度のために別のフォントが生成されるように開発されました。現在、ベクトルフォントは標準であり、倍率でこの問題はありません。したがって、それらはディスプレイでの使用に適しています。さらに、制限なしにすべてのプリンターで使用できます。
ここに示されているmf2ffを使用したMF2VECアプローチに加えて、メタフォントファイルをベクトルフォントに変換するための次のスクリプトが利用可能です。
| 名前 | 方法 |
|---|---|
| Metatype1 | メタポスト |
| MF2PT1 | メタポスト |
| mftrace | ビットマップトレース |
| Textrace | ビットマップトレース |
これに関連して、MetaPostは、MetaFontファイルのすべての文字をベクトルグラフィックに変換するためにプログラムMetapostを使用することを意味します。その後、ベクトルグラフィックがまとめられてベクトルフォントを取得します。この方法には、MetaPostがMetafont言語の一部のみを処理できるという欠点があります。
ビットマップトレースとは、MetaFontが最初にビットマップフォントを生成することを意味します。別のプログラムでは、すべてのグリフのビットマップがトレースされ、ベクトルフォントを取得するためにまとめられます。
各メソッドには特定の欠点があります。詳細については、以下の比較をご覧ください。
次の表では、MetaFontファイルをベクトルフォントに変換するための利用可能なスクリプトの比較を示しています。
| 特性 | Metafont | mf2ff | Metatype1 | MF2PT1 | mftrace | Textrace |
|---|---|---|---|---|---|---|
| スクリプトは書かれています | - | Python 3 | Perl | Perl | Python 2 | Perl |
| Metafontファイル処理 | Metafont | Metafont | メタポスト | メタポスト | Metafont | Metafont |
| 後続の処理 | - | fontforge | awk / t1asm | t1asm | オートトレースまたはPotrace / T1asm | 自己球形 |
| 出力形式 | GF / TFM | ✅TTF、OTF、SFD | ? PFB | ? PFB | ✅AFM / PFA / PFB / TTF / SVG | ? PFB |
| 出力品質 | ビットマップ | ✅ベクトルグラフィック | ✅ベクトルグラフィック | ✅ベクトルグラフィック | ?トレースビットマップ | ?トレースビットマップ |
| 非プリミティブ /非プリミティブを再定義します | ✅NO | ✅NO | はい | はい | ✅NO | ✅NO |
| ユニコードサポート | いいえ | ✅はい | ❔ | いいえ | いいえ | いいえ |
| ペンコマンドをサポートします | ✅はい | ?限定 | いいえ | ?限定 | ✅はい | ✅はい |
| リガチャーとカーニングコマンドをサポートします | ✅はい | ?限定 | ❔ | ❔ | ❔ | いいえ |
| 可変フォントをサポートします | いいえ | いいえ、おそらく将来 | いいえ | いいえ | ❔ | いいえ |
以下は、 mf2ffで作成されたいくつかの例です。アウトラインと塗りつぶされた文字は、fontforgeに表示されるときに表示されます。結果はまだ完全ではないことに注意してください。
コンピューターの最新の書体のいくつかのグリフは、まだ正しく処理されていません。つまり、首都sとsloped_serifの中央部は小文字のsloped_serifです。

![]() | ![]() | ![]() |
左側の画像は、 cullコマンドを非アクティブ化することによって作成されました。
様式化されたコーストレッドウッドツリーエルパロアルトは、メタフォントブックの124〜126ページに記載されています。左バージョンでは、オプションcull-at-shipoutがアクティブになります。トランクと最上部のブランチはカーブ上のポイントを共有するため、現在の実装はそこで間違った結果をもたらします。
![]() | ![]() | ![]() | ![]() |
138ページに記載されているロゴ、Metafontbook。左バージョンでは、オプションcull-at-shipoutがアクティブになります。いっぱいのロゴはどちらの場合も同じです。
![]() | ![]() | ![]() |
mf2ffの現在の制限mf2ffまだ開発中であり、徹底的にテストされていないため、いくつかの制限があります。彼らは将来の更新で対処されるかもしれません。
特定の制限がプロジェクトを抑制している場合は、将来の更新がユーザーのニーズに焦点を合わせることができるように問題を開きます。
penrazorはサポートされていません(Dangerse_bend_symbolの例を参照)、fontforge:「ストローク幅はゼロではありません」penspeckを使用すると警告が発生しますが、出力は場合によっては問題ないようです。cullコマンドのサポートは限られています。: 、 :: 、 kern 、 skiptoおよびligature演算子=: |=: 、 =:|および|=:|サポートされています。 LigTableコマンドは、オペレーターで>無視します。さらに、オペレーター||:サポートされていません。charlistやextensibleコマンドはまだサポートされています。pictureキーワードを再定義して、fontforgeベクターレイヤーとして画像変数を初期化する必要があります。 Metafontは、ブール式での可変宣言とタイプテストの両方にタイプキーワードを使用するため、 pictureキーワードを使用して、変数が型pictureであるかどうかをテストすることはできません。makepenやmakepathなどのコマンドは効果がありません。ペンとパスは、ブール式のpenまたはpathを使用して区別することはできません。 is_penまたはis_pathを導入するOption is_typeがあり、この問題を回避するのに役立つ可能性があります。ligtableとfontdimen内のネストされた条件またはループmf2ff結腸を再定義する必要があります( : 。これにより、複数のネストされたif ...( elseif )...( end )...(end)... fiおよび / or for / forsuffixes / forever ...独自の構文、すなわちligtable 、 fontdimenでコロンを使用するコマンドの内部のendforに問題が発生する可能性があります。charlistとextensible役立つかもしれないことがいくつかあります。私はそれらを100%理解していないことに留意してください:
$PYTHONPATHに/usr/local/lib/python3/dist-packagesを追加しますexport PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3/dist-packagesを~/.profileに追加)/usr/local/lib/python3.4/site-packages