mf2ff mf2ff est un outil pour créer des polices vectorielles à partir du code Metafont à l'aide de l'API Python de FontForge.
Il est basé sur un concept de la façon dont Metafont peut fonctionner avec un générateur de polices vectoriel sans le détour du traçage bitmap, décrit ci-dessous dans la section du concept MF2VEC. mf2ff est le premier et, à la connaissance du développeur, la seule implémentation de ce concept à ce jour.
Ci-dessous, vous trouverez de l'aide sur la façon de le configurer et comment l'utiliser.
L'outil n'a pas encore été soigneusement testé, mais la plupart des commandes Metafont sont prises en charge. Outre le remplissage et le dessin, les commandes de coupage et de ligature sont également prises en charge. Veuillez jeter un œil aux limites énumérées ci-dessous.
mf2ffmf2ff Vous devez installer FontForge et Metafont pour utiliser mf2ff .
Vous pouvez avoir des problèmes à exécuter le script mf2ff . Un problème peut être que vous devez exécuter Python 3 avec le module FontForge. Voici quelques conseils sur la façon de le faire fonctionner. Je ne peux pas garantir que cela fonctionnera sur votre système, mais vous devriez essayer.
Sur différents systèmes d'exploitation ou configurations système où les conseils ci-dessous ne fonctionnent pas, vérifiez si vous utilisez le module Python de Python et FontForge est présent:
ffpython , python3 , python ). Vérifiez que l'information de la version indique que vous exécutez Python 3 .import fontforge au sein de l'interprète devrait fonctionner sans erreurs.fontforge.font() ne doit pas augmenter une erreur. Si cela ne fonctionne que dans certains répertoires, vous devez vérifier votre PATH ou votre variable PYTHONPATH . Pour un accès temporaire à la version Python de FontForge ffpython , FontForge est livré avec un fichier de lots:
C:Program Files (x86)FontForgeBuilds ) et exécutez fontforge-console.bat puisque la commande set de Windows modifie la variable PATH uniquement dans la session d'invite de commande actuelle, Ffpython n'est disponible que dans chaque emplacement dans l'invite de commande dans laquelle le fichier de commandes actuel a été exécuté.Pour un accès permanent, vous devez modifier la variable de chemin en permanence:
environment variables et Edit the system environment variables . Cliquez sur Environment variables et modifiez la variable PATH de votre compte d'utilisateur ou celle du système si vous avez besoin d'accès à ffpython sur plusieurs comptes d'utilisateurs. Maintenant, ajoutez le chemin de FontForge (par exemple C:Program Files (x86)FontForgeBuildsbin , faites attention au bin !) À la liste.ffpython est désormais disponible dans toutes les nouvelles fenêtres de l'invite de commande et vous devriez pouvoir utiliser ffpython path/to/mf2ff.py ... Pour accéder facilement au script mf2ff de partout, procédez comme suit:
mf2ff à la variable PYTHONPATH . S'il n'y a pas encore de variable PYTHONPATH , ajoutez-le à la liste.mf2ff avec ffpython -m mf2ff ... dans de nouvelles sessions d'invite de commande.Ubuntu est utilisé dans cet exemple.
Certains référentiels expédient les anciennes versions de Fontforge avec le support Python 2. Vous voudrez peut-être construire FontForge à partir de la source:
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 . Cela crée un fontforge/ Directory.fontforge/ Directory:cd fontforge; mkdir build; cd buildcmake -GNinja ..ninjasudo ninja installRemarque: vérifiez la documentation de Fontfore si vous avez des problèmes avec ce processus.
Pour accéder facilement au module Python de FontForge, ajoutez-le à votre PythonPath:
~/.profile : export PYTHONPATH=$PYTHONPATH:/path/to/fontforge/ , où le répertoire /path/to/fontforge/ est celui créé par le clonage FontForge avec git, eg $HOME/fontforge .python3 path/to/mf2ff.py ... dans de nouvelles sessions de shell. Remarque: Selon la configuration de votre système, vous devez taper python au lieu de python3 pour exécuter Python 3.
Pour accéder facilement au script mf2ff de partout, ajoutez son emplacement à la variable PythonPath:
~/.profile : export PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ , où /path/to/mf2ff/ répertoire est celui où vous placez le fichier mf2ff.py , par exemple $HOME/mf2ff/mf2ff .mf2ff facilement avec python3 -m mf2ff ... dans de nouvelles sessions de shell.Remarque: Selon le fichier de points que vous utilisez, un redémarrage de la coquille au lieu d'un redémarrage peut être suffisant.
La solution ci-dessous utilise Homebrew. De cette façon, Fontforge est également accessible avec Python:
brew install fontforge .python3 path/to/mf2ff.py ... dans de nouvelles sessions de shell. Remarque: Selon la configuration de votre système, vous devez taper python au lieu de python3 pour exécuter Python 3.
Pour accéder facilement au script mf2ff de partout, ajoutez son emplacement à la variable PYTHONPATH :
PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ .zsh . Dans votre répertoire domestique, créez ou modifiez le fichier .zshenv .bash . Dans votre répertoire domestique, créez ou modifiez le fichier .bash_profile .tcsh . Dans votre répertoire domestique, créez ou modifiez le fichier correspondant du shell tcsh .mf2ff avec python3 -m mf2ff ... dans de nouvelles sessions de shell. Par défaut, mf2ff générera un fichier de base de données de polices spline (.SFD). Vous pouvez utiliser les options -ttf / mf2ff.options['ttf'] = True ou -otf / mf2ff.options['otf'] = True pour générer des polices directement.
mf2ff ne fait pas beaucoup de nettoyage par défaut, car vous voudrez peut-être retravailler manuellement les glyphes. Vous pouvez utiliser les options -cull-at-shipout / mf2ff.options['cull-at-shipout'] = True ou -remove-artifacts / mf2ff.options['remove-artifacts'] = True pour effectuer un nettoyage automatisé. Notez que les commandes Cull qui font partie d'une définition de glyphes peuvent entraîner l'option cull-at-shipout sans d'autres modifications pour certains glyphes.
Veuillez jeter un œil aux limites énumérées ci-dessous.
L'idée principale du concept MF2VEC est de faire de Metafont pour rediriger les géométries des glyphes vers un autre programme (dans le cas de mf2ff , ce programme est FontForge) au lieu de les utiliser pour générer une police bitmap. Cela est possible en raison du fait que Metafont utilise en interne la même description géométrique qui est par la suite nécessaire dans les fichiers de police vectorielle - les courbes Bézier.
Le détour utilisé par certaines alternatives de conversion des courbes Bézier en graphiques raster et de retour en courbes Bézier est contourné. En utilisant directement la géométrie, aucune information ne se perd.
Étant donné que Metafont est utilisé à la place d'autres outils comme MetaPost pour lire les fichiers .mf , les fichiers de code Metafont non modifié peuvent être utilisés et non seulement la géométrie mais aussi le codage des caractères, les tailles de boîte, les informations de cercueil et de ligature, etc. est expédiée à la police vectorielle sans rétablissement manuel.
Cette interception des informations est effectuée en redéfinissant les commandes Metafont. Comme Metafont ne peut pas interagir avec d'autres programmes pendant l'exécution, l'interprétation du fichier .mf et la génération de la police doivent être séparées à temps. Par conséquent, l'information que Metafont utiliserait pour générer des graphiques bitmap est enregistrée dans le fichier journal de Metafont. Les commandes de Metafont sont redéfinies afin que Metafont écrit les propriétés de géométrie et de police dans son fichier journal. Une fois que Metafont a traité toutes les commandes des fichiers Metafont, les informations sont lues dans le fichier journal, traitées pour créer une police puis supprimée du fichier journal pour le garder clair.
L'idée de cette approche est apparue en octobre 2018. Pour vérifier la praticabilité, une mise en œuvre de Fontforge a été immédiatement réalisée à Python et la gamme des commandes prises en charge a été progressivement élargie. Lorsque les tests initiaux ont montré que l'idée a fonctionné, il a été décidé de mettre mf2ff à la disposition d'autres utilisateurs intéressés. Cela se produit depuis mars 2019. Après quelques améliorations et correctifs de bogues, le développement a été interrompu pendant quelques années. En raison des commentaires de la communauté, le développement mf2ff s'est poursuivi en juillet 2023.
Idée de base
Le concept est basé sur la redéfinition des commandes Metafont de base. Ils sont définis de telle manière que l'information que Metafont utilise normalement pour créer la police bitmap est écrite dans le fichier journal. Par la suite, ce fichier journal est ensuite lu et les instructions sont transmises au programme générant la police vectorielle à partir de celui-ci. Par exemple, mf2ff utilise FontForge à cet effet. Ensuite, les informations ajoutées par les commandes Metafont modifiées sont supprimées du fichier journal pour le garder clair.
Le diagramme suivant illustre le concept utilisant mf2ff comme exemple.
┌──────────┐
│ font.mf │
└──────────┘
v
┌──────────┐ ┌───────────┐
│ │ > │ METAFONT │
│ │ └───────────┘
│ │ v
│ │ ┌───────────┐
│ mf2ff │ < │ font.log │
│ │ └───────────┘
│ │
│ │ ┌───────────┐
│ │ > │ FontForge │
└──────────┘ └───────────┘
v v
┌──────────┐ ┌─────────────────────┐
│ font.log │ │ font.ttf / font.otf │
└──────────┘ └─────────────────────┘
Exemple simple
L'ajout du code suivant à un fichier Metafont amènera Metafont à ne pas fill le contour c , mais à rédiger les opérations dans le fichier journal:
def fill expr c =
message "fill"; show c;
enddef;
Une fois Metafont terminé le traitement du fichier, un script analyse le fichier journal et sait à partir de la commande fill et il sait que le contour sera rempli. Ces informations peuvent être transmises au programme de traitement des polices pour les ajouter au glyphe.
En fait, ce processus est beaucoup plus compliqué. Pour pouvoir traiter les fichiers Metafont non basés sur un méta-méta, des commandes comme addto au lieu de commandes comme fill doivent être redéfinies. Mais ces commandes addto sont plus complexes; Ils forment également la base des autres commandes de métafont ordinaires comme unfill , ( un ) draw , ( un ) drawdot et erase . Ces commandes s'étendent à plusieurs mots clés séparant les différentes parties des informations nécessaires pour effectuer ces différentes opérations ( addto , also , contour , doublepath , withpen , withweight ).
Un autre défi est le côlon dans les conditions et les boucles. Ces structures peuvent apparaître dans n'importe quelle autre commande, même dans les commandes qui utilisent le côlon comme séparateur ( ligtable et fontdimen ), donc : doit être redéfini comme d'autres mots clés pour diffuser des informations dans le fichier journal. Une commutation sophistiquée entre les différentes redéfinitions du côlon est requise dans ces commandes.
En plus de cela, un processus doit être implémenté pour faciliter la recherche de toutes les commandes dans le fichier journal même s'il existe des commandes de message dans le fichier Metafont non lié à la redéfinition des primitives Metafont. Ceux-ci ne doivent pas être interprétés comme des informations pour la génération de polices. Par conséquent, toutes les informations écrites dans le fichier journal doivent être enfermées dans des mots clés spéciaux qui sont peu susceptibles d'être utilisés dans les commandes de message des fichiers Metafont.
Metafont, développé par De Knuth depuis 1977, est un programme qui génère des polices bitmap à partir de fichiers écrits dans la langue Metafont. Les polices de bitmap ont l'inconvénient qu'ils deviennent floues sous le grossissement. Metafont a été développé de sorte que pour la résolution particulière de l'imprimante, une police distincte a été générée. De nos jours, les polices vectorielles sont standard, qui n'ont pas ce problème sous grossissement. Par conséquent, ils conviennent plus à une utilisation sur les écrans. De plus, ils peuvent être utilisés avec chaque imprimante sans aucune restriction.
Outre l'approche MF2VEC avec le mf2ff présenté ici, les scripts suivants pour convertir les fichiers Metafont en polices vectorielles sont disponibles:
| Nom | Méthode |
|---|---|
| Métatype1 | Métapost |
| mf2pt1 | Métapost |
| mftrace | Tracé de bitmap |
| Textrace | Tracé de bitmap |
Dans ce contexte, Metapost signifie que le programme Metapost est utilisé pour convertir chaque caractère du fichier Metafont en un graphique vectoriel. Après cela, les graphiques vectoriels sont mis en place pour obtenir une police vectorielle. Cette méthode présente l'inconvénient selon lequel Metapost peut uniquement traiter une partie de la langue métafont.
Le traçage bitmap signifie que Metafont génère d'abord une police bitmap. Dans un programme séparé, le bitmap de chaque glyphe est tracé puis assemblé pour obtenir une police vectorielle.
Chacune des méthodes a des inconvénients spécifiques. Veuillez jeter un œil à la comparaison ci-dessous pour plus de détails.
Dans le tableau suivant, montre une comparaison des scripts disponibles pour convertir les fichiers Metafont en polices vectorielles.
| Caractéristiques | Métafont | mf2ff | Métatype1 | mf2pt1 | mftrace | Textrace |
|---|---|---|---|---|---|---|
| Le script est écrit dans | - | Python 3 | Perler | Perler | Python 2 | Perler |
| Traitement de fichiers Metafont | Métafont | Métafont | Métapost | Métapost | Métafont | Métafont |
| Traitement ultérieur | - | Fontforge | Awk / t1asm | t1asme | autotrace ou potrace / t1asm | autotrace |
| Format de sortie | GF / TFM | ✅ TTF, OTF, SFD | ? PFB | ? PFB | ✅ AFM / PFA / PFB / TTF / SVG | ? PFB |
| Qualité de sortie | bitmap | ✅ Graphique vectoriel | ✅ Graphique vectoriel | ✅ Graphique vectoriel | ? Bitmap tracé | ? Bitmap tracé |
| Redéfinit les non-initiatifs / nécessite des non-primations | ✅ Non | ✅ Non | Oui | Oui | ✅ Non | ✅ Non |
| Support Unicode | Non | ✅ Oui | ❔ | Non | Non | Non |
| Soutient les communs de stylo | ✅ Oui | ? Limité | Non | ? Limité | ✅ Oui | ✅ Oui |
| Prend en charge les commandes de ligature et de coupure | ✅ Oui | ? Limité | ❔ | ❔ | ❔ | Non |
| Prend en charge les polices variables | Non | Non, peut-être dans le futur | Non | Non | ❔ | Non |
Voici quelques exemples créés avec mf2ff . Les contours et les caractères remplis sont affichés lorsqu'ils sont affichés dans FontForge. Notez que les résultats ne sont pas encore parfaits.
Certains glyphes des polices de caractères modernes de l'ordinateur ne sont pas encore correctement traités, c'est-à-dire la partie médiane de Capital S et sloped_serif en lettres minuscules.

![]() | ![]() | ![]() |
L'image de gauche a été créée par désactiver les commandes cull .
L'arbre de Redwood Stylized Coast El Palo Alto qui est présenté aux pages 124-126 du Metafontbook. Dans la version de gauche, l'option cull-at-shipout est activée. Étant donné que le coffre et la branche la plus supérieure partagent un point de courbe, la mise en œuvre actuelle provoque de mauvais résultats là-bas.
![]() | ![]() | ![]() | ![]() |
Le logo, qui est présenté à la page 138, le Metafontbook. Dans la version de gauche, l'option cull-at-shipout est activée. Le logo rempli est le même dans les deux cas.
![]() | ![]() | ![]() |
mf2ff Étant donné que mf2ff est toujours en cours de développement et n'est pas soigneusement testé, il y a quelques limites. Ils peuvent être traités dans les futures mises à jour.
Si une limitation spécifique retient votre projet, ouvrez un problème afin que les futures mises à jour puissent se concentrer sur les besoins des utilisateurs.
penrazor n'est pas pris en charge (voir Exemple dangereux_bend_symbol), Fontforge: "La largeur de course ne peut pas être nulle"penspeck soulève un avertissement, mais la sortie semble être OK dans certains cas.cull est limité.: :: , kern , skipto ainsi que les opérateurs de ligature =: |=: =:| et |=:| sont pris en charge. La commande ligtable ignore > dans les opérateurs. De plus, l'opérateur ||: n'est pas pris en charge.charlist ni extensible sont encore prises en charge.picture doit être redéfini pour initialiser les variables d'image en tant que couche vectorielle FontForge. Comme Metafont utilise les mots clés de type pour les deux, la déclaration de variable et le test de type dans les expressions booléennes, le mot clé picture ne peut pas être utilisé pour tester si une variable est de type picture .makepen et makepath n'ont aucun effet. Les stylos et le chemin ne peuvent pas être distingués en utilisant pen ou path dans une expression booléenne. Il existe une option is_type qui présente is_pen ou is_path qui pourrait vous aider à contourner ce problème.ligtable et fontdimenmf2ff doit redéfinir le côlon ( : . Cela peut causer des problèmes dans le traitement de plusieurs imbriqués if ... ( elseif ) ... ( end ) ... fi et / ou for / forsuffixes / forever ... endfor pour les commandes qui utilisent le côlon dans leur propre syntaxe, c'est-à-dire ligtable et fontdimen .charlist et extensibleIl y a quelques choses, qui pourraient aider. Gardez à l'esprit que je ne les comprends pas à 100%:
/usr/local/lib/python3/dist-packages à votre $PYTHONPATHexport PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3/dist-packages à votre ~/.profile )/usr/local/lib/python3.4/site-packages sur le chemin de Python