mf2ff mf2ff ist ein Tool zum Erstellen von Vektor -Schriftarten aus dem Metafont -Code mithilfe der Python -API von Fontforge.
Es basiert auf einem Konzept, wie Metafont mit einem Vektor -Schriftgenerator ohne den Umweg der Bitmap -Verfolgung zusammenarbeiten kann, die unten im Abschnitt MF2VEC -Konzept beschrieben wird. mf2ff ist der erste und nach dem Wissen des Entwicklers die einzige Implementierung dieses Konzepts.
Im Folgenden finden Sie einige Hilfe, wie Sie es einrichten und wie man es benutzt.
Das Tool wurde noch nicht gründlich getestet, aber die häufigsten Metafont -Befehle werden unterstützt. Neben Füllen und Zeichnen werden auch Kerning und einige Ligaturbefehle unterstützt. Bitte werfen Sie einen Blick auf die unten aufgeführten Einschränkungen.
mf2ffmf2ff Sie müssen Fontforge und Metafont installieren, um mf2ff zu verwenden.
Möglicherweise haben Sie Probleme, das mf2ff -Skript auszuführen. Ein Problem kann sein, dass Sie Python 3 mit dem Fontforge -Modul ausführen müssen. Im Folgenden finden Sie einige Tipps, wie Sie es zum Laufen bringen können. Ich kann nicht garantieren, dass dies auf Ihrem System funktioniert, aber Sie sollten es versuchen.
Bei verschiedenen Betriebssystemen oder Systemkonfigurationen, bei denen die folgenden Tipps nicht funktionieren, überprüfen Sie, ob Sie das Python -Modul von Python und Fontforge verwenden:
ffpython , python3 , python ) aus. Überprüfen Sie, ob die Versionsinformationen feststellen, dass Sie Python 3 ausführen.import fontforge innerhalb des Dolmetschers sollte ohne Fehler funktionieren.fontforge.font() sollte keinen Fehler aufnehmen. Wenn dies nur in einigen Verzeichnissen funktioniert, sollten Sie Ihren PATH oder PYTHONPATH -Variable überprüfen. Für den temporären Zugriff auf die Python -Version ffpython von Fontforge wird Fontforge mit einer Batch -Datei geliefert:
C:Program Files (x86)FontForgeBuilds ) und führen Sie fontforge-console.bat aus, da der set "Windows" die PATH nur in der aktuellen Eingabeaufforderung geändert hat. FFPython ist nur in der Aufforderung zur Aufforderung zur Aufforderung verfügbar, in der die Batch-Datei ausgefordert wurde.Für den dauerhaften Zugriff müssen Sie die Pfadvariable dauerhaft bearbeiten:
environment variables und öffnen Edit the system environment variables . Klicken Sie auf Environment variables und bearbeiten Sie entweder die PATH Ihres Benutzerkontos oder das System, wenn Sie auf mehreren Benutzerkonten Zugriff auf ffpython benötigen. Fügen Sie nun den Pfad von Fontforge (z. B. C:Program Files (x86)FontForgeBuildsbin , Machen Sie die bin !) Zu der Liste.ffpython ist jetzt in allen neuen Eingabeaufforderungen verfügbar und Sie sollten in der Lage sein, ffpython path/to/mf2ff.py ... Um einfach auf das mf2ff -Skript von überall zugreifen zu können, machen Sie Folgendes:
mf2ff der PYTHONPATH -Variablen hinzu. Wenn es noch keine PYTHONPATH -Variable gibt, fügen Sie sie der Liste hinzu.mf2ff mit ffpython -m mf2ff ... in neuen Eingabeaufforderung -Sitzungen auszuführen.Ubuntu wird in diesem Beispiel verwendet.
Einige Repositories versenden alte Versionen von Fontforge mit Python 2 -Unterstützung. Möglicherweise möchten Sie Fontforge aus Quelle erstellen:
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 . Dies schafft eine fontforge/ ein Verzeichnis.fontforge/ Verzeichnis:cd fontforge; mkdir build; cd buildcmake -GNinja ..ninjasudo ninja installHinweis: Überprüfen Sie die Dokumentation von Fontfore, wenn Sie Probleme mit diesem Prozess haben.
Um einfach auf das Python -Modul von Fontforge zuzugreifen, fügen Sie es Ihrem Pythonpath hinzu:
~/.profile Datei ein: export PYTHONPATH=$PYTHONPATH:/path/to/fontforge/ wobei /path/to/fontforge/ verzeichnis das durch klonende fontforge mit git, z. $HOME/fontforge erstellt wurde.python3 path/to/mf2ff.py ... zu verwenden. Hinweis: Abhängig von der Konfiguration Ihres Systems müssen Sie python anstelle von python3 eingeben, um Python 3 auszuführen.
Um einfach auf das mf2ff -Skript von überall zugreifen zu können, fügen Sie seinen Standort zur Variablen Pythonpath hinzu:
~/.profile Datei: export PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ , wobei /path/to/mf2ff/ verzeichnis dasjenige, in dem Sie die mf2ff.py -Datei, z. $HOME/mf2ff/mf2ff eingestellt haben, exportieren.mf2ff immer leicht mit python3 -m mf2ff ... in neuen Shell -Sitzungen ausführen.Hinweis: Je nachdem, welche Dotfile Sie verwenden, kann ein Neustart der Schale anstelle eines Neustarts ausreichen.
Die folgende Lösung verwendet Homebrew. Auf diese Weise ist Fontforge auch mit Python zugänglich:
brew install fontforge .python3 path/to/mf2ff.py ... in neuen Shell -Sitzungen verwenden. Hinweis: Abhängig von der Konfiguration Ihres Systems müssen Sie python anstelle von python3 eingeben, um Python 3 auszuführen.
Um einfach auf das mf2ff -Skript von überall zugreifen zu können, fügen Sie seinen Standort zur Variablen PYTHONPATH hinzu:
PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ hinzu.zsh . Erstellen oder ändern Sie in Ihrem Heimverzeichnis die Datei .zshenv .bash . Erstellen oder ändern Sie in Ihrem Heimverzeichnis die Datei .bash_profile .tcsh . Erstellen oder ändern Sie in Ihrem Home -Verzeichnis die entsprechende Datei der tcsh -Shell.mf2ff mit python3 -m mf2ff ... in neuen Shell -Sitzungen ausführen. Standardmäßig generiert mf2ff eine Spline -Font -Datenbank (.sfd) -Datei. Sie können die Optionen -ttf / mf2ff.options['ttf'] = True oder -otf / mf2ff.options['otf'] = True verwenden, um Schriftarten direkt zu generieren.
mf2ff säubert standardmäßig nicht viel, da Sie die Glyphen möglicherweise manuell überarbeiten möchten. Sie können die Optionen -cull-at-shipout / mf2ff.options['cull-at-shipout'] = True oder -remove-artifacts / mf2ff.options['remove-artifacts'] = True verwenden, um eine automatisierte Reinigung durchzuführen. Beachten Sie, dass CULL-Befehle, die Teil einer Glyphendefinition sind, dazu führen können, dass die Option cull-at-shipout für einige Glyphen keine weiteren Änderungen vornimmt.
Bitte werfen Sie einen Blick auf die unten aufgeführten Einschränkungen.
Die Hauptidee des MF2VEC -Konzepts besteht darin, Metafont zu machen, um die Geometrien der Glyphen in ein anderes Programm (im Fall von mf2ff dieses Programms) umzuleiten, anstatt sie zu verwenden, um eine Bitmap -Schriftart zu generieren. Dies ist möglich, da Metafont intern die gleiche geometrische Beschreibung verwendet, die anschließend in den Vektor -Schriftart Dateien benötigt wird - den Bézier -Kurven.
Der Umweg, der von einigen Alternativen zur Umwandlung der Bézier -Kurven in Rastergrafiken und zurück in Bézier -Kurven umgewandelt wird, ist umgangen. Durch die direkte Verwendung der Geometrie gehen keine Informationen verloren.
Da MetaFont anstelle anderer Tools wie Metapost zum Lesen .mf -Dateien verwendet wird, können nicht nur die Geometrie, sondern auch die Charaktercodierung, Kastengrößen, Kern- und Ligaturinformationen usw. nicht nur die Geometrie, sondern auch die Vektor -Schriftart ohne manuelle Nacharbeiten versendet werden.
Dieses Abfangen der Informationen erfolgt durch Neudefinition von Metafont -Befehlen. Da Metafont während der Laufzeit nicht mit anderen Programmen interagieren kann, muss die Interpretation der .MF -Datei und die Erzeugung der Schriftart rechtzeitig getrennt werden. Daher wird die Information Metafont zum Generieren von Bitmap -Grafiken in der Protokolldatei von Metafont gespeichert. Die Befehle von Metafont werden neu definiert, so dass Metafont die Geometrie- und Schrifteigenschaften in seiner Protokolldatei schreibt. Sobald Metafont alle Befehle der MetaFont -Dateien verarbeitet hat, werden die Informationen aus der Protokolldatei gelesen, verarbeitet, um eine Schriftart zu erstellen, und dann aus der Protokolldatei entfernt, um sie klar zu halten.
Die Idee dieses Ansatzes kam im Oktober 2018 auf. In Python wurde sofort eine Implementierung für Fontforge realisiert, und der Bereich der unterstützten Befehle wurde zunehmend erweitert. Als erste Tests zeigten, dass die Idee funktionierte, wurde beschlossen, mf2ff anderen interessierten Benutzern zur Verfügung zu stellen. Dies geschieht seit März 2019. Nach einigen Verbesserungen und Fehlerbehebungen wurde die Entwicklung für einige Jahre inne. Aufgrund des Feedbacks der Gemeinschaft wurde mf2ff -Entwicklung im Juli 2023 fortgesetzt.
Grundgedanke
Das Konzept basiert auf der Neudefinition grundlegender Metafont -Befehle. Sie werden so definiert, dass die Information Metafont normalerweise zum Erstellen der Bitmap -Schriftart in die Protokolldatei geschrieben wird. Anschließend wird diese Protokolldatei gelesen und die Anweisungen an das Programm übergeben, das die Vektor -Schriftart daraus erzeugt. Zum Beispiel verwendet mf2ff Fontforge zu diesem Zweck. Anschließend werden die von modifizierten Metafont -Befehlen hinzugefügten Informationen aus der Protokolldatei entfernt, um sie zu klären.
Das folgende Diagramm zeigt das Konzept unter Verwendung von mf2ff als Beispiel.
┌──────────┐
│ font.mf │
└──────────┘
v
┌──────────┐ ┌───────────┐
│ │ > │ METAFONT │
│ │ └───────────┘
│ │ v
│ │ ┌───────────┐
│ mf2ff │ < │ font.log │
│ │ └───────────┘
│ │
│ │ ┌───────────┐
│ │ > │ FontForge │
└──────────┘ └───────────┘
v v
┌──────────┐ ┌─────────────────────┐
│ font.log │ │ font.ttf / font.otf │
└──────────┘ └─────────────────────┘
Einfaches Beispiel
Durch das Hinzufügen des folgenden Codes zu einer Metafont -Datei wird Metafont nicht die Kontur c fill , sondern die Vorgänge in die Protokolldatei schreiben:
def fill expr c =
message "fill"; show c;
enddef;
Nachdem Metafont die Datei verarbeitet hat, analysiert ein Skript die Protokolldatei und weiß, dass es einen fill gab und die zugefüllte Kontur weiß. Diese Informationen können an das Schriftverarbeitungsprogramm übergeben werden, um es der Glyphe hinzuzufügen.
Tatsächlich ist dieser Prozess viel komplizierter. Um Metafont -Dateien zu verarbeiten, die nicht auf Plain Metafont basieren, müssen Befehle wie addto anstelle von Befehlen wie fill neu definiert werden. Aber diese addto -Befehle sind komplexer; Sie bilden auch die Grundlage für andere einfache Metafont -Befehle wie unfill , ( un ) draw , ( un ) drawdot und erase . Diese Befehle erweitern sich auf mehrere Schlüsselwörter, die die verschiedenen Teile von Informationen trennen, die für diese unterschiedlichen Vorgänge erforderlich sind ( addto , also contour , doublepath , withpen , withweight ).
Eine weitere Herausforderung ist der Dickdarm unter Bedingungen und Schleifen. Diese Strukturen können in jedem anderen Befehl angezeigt werden, selbst in Befehlen, die den Dickdarm als Trennzeichen ( ligtable und fontdimen ) verwenden, müssen also : wie andere Schlüsselwörter neu definiert werden, um Informationen in die Protokolldatei auszugeben. Ein ausgeklügelter Wechsel zwischen verschiedenen Neudefinitionen des Dickdarms ist innerhalb dieser Befehle erforderlich.
Darüber hinaus muss ein Prozess implementiert werden, um alle Befehle in der Protokolldatei einfach zu finden, selbst wenn in der Metafont -Datei keine Nachrichtenbefehle vorhanden sind, die nicht mit der Neudefinition der Metafont -Primitiven zusammenhängen. Diese sollten nicht als Informationen für die Schriftgenerierung interpretiert werden. Daher müssen alle in der Protokolldatei geschriebenen Informationen in speziellen Schlüsselwörtern eingeschlossen sein, die in den Meldungsbefehlen der Metafont -Dateien wahrscheinlich nicht verwendet werden.
Metafont, der seit 1977 von De Knuth entwickelt wurde, ist ein Programm, das Bitmap -Schriftarten aus Dateien generiert, die in der Metafont -Sprache geschrieben sind. Bitmap -Schriftarten haben den Nachteil, dass sie unter Vergrößerung verschwommen sind. Metafont wurde so entwickelt, dass für die jeweilige Auflösung des Druckers eine separate Schriftart generiert wurde. Heutzutage sind Vektor -Schriftarten Standard, die dieses Problem nicht unter Vergrößerung haben. Daher eignen sie sich besser für die Verwendung von Displays. Darüber hinaus können sie mit jedem Drucker ohne Beschränkungen verwendet werden.
Neben dem MF2VEC -Ansatz mit dem hier vorgestellten mf2ff sind die folgenden Skripte zum Konvertieren von Metafont -Dateien in Vektor -Schriftarten verfügbar:
| Name | Verfahren |
|---|---|
| Metatyp1 | Metapost |
| MF2PT1 | Metapost |
| mftrace | Bitmap -Verfolgung |
| Textrace | Bitmap -Verfolgung |
In diesem Zusammenhang bedeutet Metapost, dass der Programm -Metapost verwendet wird, um jedes einzelne Zeichen der Metafont -Datei in eine Vektorgrafik umzuwandeln. Danach werden die Vektorgrafiken zusammengestellt, um eine Vektorschrift zu erhalten. Diese Methode hat den Nachteil, dass Metapost nur einen Teil der Metafont -Sprache verarbeiten kann.
Bitmap Tracing bedeutet, dass Metafont zuerst eine Bitmap -Schriftart generiert. In einem separaten Programm wird die Bitmap jeder Glyphe verfolgt und dann zusammengestellt, um eine Vektorschrift zu erhalten.
Jede der Methoden hat spezifische Nachteile. Bitte werfen Sie einen Blick auf den folgenden Vergleich, um weitere Informationen zu erhalten.
In der folgenden Tabelle zeigt ein Vergleich der verfügbaren Skripte zum Umwandeln von Metafont -Dateien in Vektor -Schriftarten.
| Merkmal | Metafont | mf2ff | Metatyp1 | MF2PT1 | mftrace | Textrace |
|---|---|---|---|---|---|---|
| Das Skript ist geschrieben in | - - | Python 3 | Perl | Perl | Python 2 | Perl |
| Metafont -Dateiverarbeitung | Metafont | Metafont | Metapost | Metapost | Metafont | Metafont |
| Anschließende Verarbeitung | - - | Schriftart | Awk / t1asm | t1asm | Autotrace oder Potrace / T1ASM | Autotrace |
| Ausgangsformat | GF / TFM | ✅ TTF, OTF, SFD | ? PFB | ? PFB | ✅ AFM / PFA / PFB / TTF / SVG | ? PFB |
| Ausgangsqualität | Bitmap | ✅ Vektorgrafik | ✅ Vektorgrafik | ✅ Vektorgrafik | ? Bitmap nachverfolgt | ? Bitmap nachverfolgt |
| Definiert nicht primitive / erfordert nicht-primitive | ✅ nein | ✅ nein | Ja | Ja | ✅ nein | ✅ nein |
| Unicode -Unterstützung | NEIN | ✅ Ja | ❔ | NEIN | NEIN | NEIN |
| Unterstützt Stiftbefehle | ✅ Ja | ? Beschränkt | NEIN | ? Beschränkt | ✅ Ja | ✅ Ja |
| Unterstützt Ligatur- und Kerning -Befehle | ✅ Ja | ? Beschränkt | ❔ | ❔ | ❔ | NEIN |
| Unterstützt variable Schriftarten | NEIN | Nein, möglicherweise in der Zukunft | NEIN | NEIN | ❔ | NEIN |
Im Folgenden sind einige Beispiele mit mf2ff erstellt. Die Umrisse und gefüllten Zeichen werden angezeigt, wie sie in Fontforge angezeigt werden. Beachten Sie, dass die Ergebnisse noch nicht perfekt sind.
Einige Glyphen der modernen Schriftarten werden noch nicht korrekt verarbeitet, dh der mittlere Teil von Kapital S und sloped_serif in Kleinbuchstaben.

![]() | ![]() | ![]() |
Das Bild links wurde durch Deaktivieren von cull -Befehlen erstellt.
Die stilisierte Küste Redwood Tree El Palo Alto, die auf den Seiten 124-126 des Metafontbooks präsentiert wird. In der linken Version wird die Option cull-at-shipout aktiviert. Da der Kofferraum und der oberste Zweig einen Punkt auf dem Kurve teilen, verursacht die aktuelle Implementierung dort falsche Ergebnisse.
![]() | ![]() | ![]() | ![]() |
Das Logo, das auf Seite 138, dem Metafontbook, präsentiert wird. In der linken Version wird die Option cull-at-shipout aktiviert. Das gefüllte Logo ist in beiden Fällen gleich.
![]() | ![]() | ![]() |
mf2ff Da mf2ff noch in der Entwicklung ist und nicht gründlich getestet wird, gibt es einige Einschränkungen. Sie werden möglicherweise in zukünftigen Updates angesprochen.
Wenn eine bestimmte Einschränkung Ihr Projekt zurückhält, öffnen Sie ein Problem, damit sich zukünftige Updates auf die Bedürfnisse der Benutzer konzentrieren können.
penrazor wird nicht unterstützt (siehe Beispiel DANGELD_BEND_SYMBOL), FONTFORGE: "Schlagbreite kann nicht Null sein"penspeck erhebt eine Warnung, aber die Ausgabe scheint in einigen Fällen in Ordnung zu sein.cull -Befehlen ist begrenzt.: :: , kern , skipto sowie die Ligaturoperatoren =: |=: =:| und |=:| werden unterstützt. Der Befehl ligtable ignoriert > in den Operatoren. Darüber hinaus wird der Operator ||: wird nicht unterstützt.charlist noch extensible Befehle werden unterstützt.picture muss neu definiert werden, um die Bildvariablen als Fontforge -Vektorschicht zu initialisieren. Da Metafont die Typ -Schlüsselwörter für beide, die variable Deklaration und den Typtest in booleschen Ausdrücken verwendet, kann das Keyword picture verwendet werden, um zu testen, ob eine Variable vom Typ picture ist.makepen und makepath keine Wirkung. Stifte und Pfad können nicht unter Verwendung von pen oder path in einem booläischen Ausdruck unterschieden werden. Es gibt eine Option is_type , die is_pen oder is_path einführt, die Ihnen helfen könnte, dieses Problem zu umgehen.ligtable und fontdimenmf2ff den Dickdarm neu definieren ( : . Dies kann zu Problemen bei der Verarbeitung mehrerer verschachtelter, if ... ( elseif ) ... ( end ) ... fi und / oder for / forsuffixes / forever ... endfor Innere von Befehlen, die den Dickdarm in ihrer eigenen Syntax, dh ligtable und fontdimen , verwenden.charlist und extensibleEs gibt ein paar Dinge, die helfen könnten. Denken Sie daran, dass ich sie nicht zu 100%verstehe:
/usr/local/lib/python3/dist-packages zu Ihrem $PYTHONPATHexport PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3/dist-packages zu Ihrem ~/.profile )/usr/local/lib/python3.4/site-packages zu Pythons Pfad hinzuzufügen