mf2ff mf2ff es una herramienta para crear fuentes vectoriales a partir del código MetaFont utilizando la API Python de FontForge.
Se basa en un concepto de cómo MetaFont puede funcionar junto con un generador de fuentes vectoriales sin el desvío del rastreo de mapa de bits, que se describe a continuación en la sección Concepto MF2VEC. mf2ff es el primero y, según el conocimiento del desarrollador, la única implementación de este concepto hasta la fecha.
A continuación encontrará ayuda sobre cómo configurarlo y cómo usarlo.
La herramienta aún no se ha probado a fondo, pero los comandos MetaFont más comunes son compatibles. Además de llenar y dibujar, también se admiten kerning y algunos comandos de ligadura. Por favor, eche un vistazo a las limitaciones enumeradas a continuación.
mf2ffmf2ff Debe instalar FontForge y MetaFont para usar mf2ff .
Es posible que tenga problemas para ejecutar el script mf2ff . Un problema puede ser que necesite ejecutar Python 3 con el módulo FontForge. A continuación hay algunos consejos sobre cómo hacer que funcione. No puedo garantizar que esto funcione en su sistema, pero debe intentarlo.
En diferentes sistemas operativos o configuraciones de sistema donde los consejos a continuación no funcionan, verifique si usa Python y el módulo Python de Fontforge está presente:
ffpython , python3 , python ). Verifique que la información de la versión indique que está ejecutando Python 3 .import fontforge dentro del intérprete debería funcionar sin errores.fontforge.font() no debe aumentar un error. Si esto solo funciona en algunos directorios, debe verificar su PATH o variable PYTHONPATH . Para el acceso temporal a la versión de Python de Fontforge ffpython , FontForge viene con un archivo por lotes:
C:Program Files (x86)FontForgeBuilds ) y ejecute fontforge-console.bat Dado que el comando set de Windows cambia la variable PATH solo en la sesión de indicador del sistema actual, FFPyThon solo está disponible en cada ubicación en el aviso de comandos en el que se ejecutó el archivo por lotes.Para acceso permanente, debe editar la variable de ruta permanentemente:
environment variables y abra Edit the system environment variables . Haga clic en Environment variables y edite la variable PATH de su cuenta de usuario o la que necesita acceso a ffpython en múltiples cuentas de usuario. Ahora, agregue la ruta de FontForge (por C:Program Files (x86)FontForgeBuildsbin , importa el bin !) A la lista.ffpython ahora está disponible en todas las nuevas ventanas del símbolo del sistema y debería poder usar ffpython path/to/mf2ff.py ... Para acceder fácilmente al script mf2ff desde todas partes, haga lo siguiente:
mf2ff a la variable PYTHONPATH . Si todavía no hay una variable PYTHONPATH , agréguela a la lista.mf2ff con ffpython -m mf2ff ... en nuevas sesiones de símbolo del sistema.Ubuntu se usa en este ejemplo.
Algunos repositorios envían versiones antiguas de Fontforge con soporte de Python 2. Es posible que desee construir fontforge desde la fuente:
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 . Esto crea una fontforge/ directorio.fontforge/ :cd fontforge; mkdir build; cd buildcmake -GNinja ..ninjasudo ninja installNota: Verifique la documentación de Fontfore si tiene problemas con este proceso.
Para acceder fácilmente al módulo de Python de Fontforge, agrégalo a su Pythonpath:
~/.profile : export PYTHONPATH=$PYTHONPATH:/path/to/fontforge/ , donde el directorio /path/to/fontforge/ el directorio creado por clonación de fontforge con git, eg $HOME/fontforge .python3 path/to/mf2ff.py ... en nuevas sesiones de shell. Nota: Dependiendo de la configuración de su sistema, debe escribir python en lugar de python3 para ejecutar Python 3.
Para acceder fácilmente al script mf2ff desde todas partes, agregue su ubicación a la variable PythonPath:
~/.profile : export PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ , donde /path/to/mf2ff/ directorio es el que coloca el archivo mf2ff.py , eg $HOME/mf2ff/mf2ff .mf2ff fácilmente con python3 -m mf2ff ... en nuevas sesiones de shell.NOTA: Dependiendo de qué punto está utilizando, un reinicio de la carcasa en lugar de un reinicio puede ser suficiente.
La siguiente solución usa Homebrew. De esta manera, FontForge también es accesible con Python:
brew install fontforge .python3 path/to/mf2ff.py ... en nuevas sesiones de shell. Nota: Dependiendo de la configuración de su sistema, debe escribir python en lugar de python3 para ejecutar Python 3.
Para acceder fácilmente al script mf2ff desde todas partes, agregue su ubicación a la variable PYTHONPATH :
PYTHONPATH=$PYTHONPATH:/path/to/mf2ff/ .zsh . En su directorio de inicio, cree o modifique el archivo .zshenv .bash . En su directorio de inicio, cree o modifique el archivo .bash_profile .tcsh . En su directorio de inicio, cree o modifique el archivo correspondiente del shell tcsh .mf2ff con python3 -m mf2ff ... en nuevas sesiones de shell. De forma predeterminada, mf2ff generará un archivo de base de datos de fuente Spline (.SFD). Puede usar las opciones -ttf / mf2ff.options['ttf'] = True o -otf / mf2ff.options['otf'] = True para generar fuentes directamente.
mf2ff no hace mucha limpieza por defecto, ya que es posible que desee volver a trabajar manualmente los glifos. Puede usar las opciones -cull-at-shipout / mf2ff.options['cull-at-shipout'] = True o -remove-artifacts / mf2ff.options['remove-artifacts'] = True para realizar una limpieza automatizada. Tenga en cuenta que los comandos CULL que forman parte de una definición de glifo pueden dar como resultado que la opción cull-at-shipout no haga más cambios para algunos glifos.
Por favor, eche un vistazo a las limitaciones enumeradas a continuación.
La idea principal del concepto MF2VEC es hacer que MetaFont redirigiera las geometrías de los glifos a otro programa (en el caso de mf2ff , este programa es FONTFORGE) en lugar de usarlas para generar una fuente de mapa de bits. Esto es posible debido al hecho de que MetaFont usa internamente la misma descripción geométrica que posteriormente se necesita en los archivos de fuentes vectoriales: las curvas Bézier.
El desvío utilizado por algunas alternativas de convertir las curvas Bézier en gráficos ráster y de regreso a las curvas Bézier se evita. Al usar directamente la geometría, no se pierde información.
Dado que MetaFont se usa en lugar de otras herramientas como Metapost para leer archivos .mf , se pueden usar archivos de código MetaFont no modificados y no solo la geometría sino también la codificación de caracteres, los tamaños de los casillas, la información de kerning y la ligadura, etc.
Esta intercepción de la información se realiza redefiniendo los comandos de MetaFont. Como MetaFont no puede interactuar con otros programas durante el tiempo de ejecución, la interpretación del archivo .mf y la generación de la fuente deben separarse en el tiempo. Por lo tanto, la información que MetaFont usaría para generar gráficos de mapa de bits se guarda en el archivo de registro de MetaFont. Los comandos de MetaFont se redefinen para que MetaFont escriba las propiedades de geometría y fuente en su archivo de registro. Una vez que MetaFont ha procesado todos los comandos de los archivos MetaFont, la información se lee desde el archivo de registro, se procesa para crear una fuente y luego se elimina del archivo de registro para mantenerla claro.
La idea de este enfoque surgió en octubre de 2018. Para verificar la práctica, una implementación para Fontforge se realizó de inmediato en Python y la gama de comandos respaldados se amplió progresivamente. Cuando las pruebas iniciales mostraron que la idea funcionaba, se decidió hacer que mf2ff esté disponible para otros usuarios interesados. Esto ha estado sucediendo desde marzo de 2019. Después de algunas mejoras y correcciones de errores, el desarrollo se detuvo durante algunos años. Debido a los comentarios de la comunidad, el desarrollo mf2ff se continuó en julio de 2023.
Idea básica
El concepto se basa en redefinir los comandos básicos de MetaFont. Se definen de tal manera que la información que MetaFont normalmente usa para crear la fuente de mapa de bits se escribe en el archivo de registro. Posteriormente, este archivo de registro se lee y las instrucciones se pasan al programa que genera la fuente vectorial a partir de él. Por ejemplo, mf2ff usa FontForge para este propósito. Posteriormente, la información agregada por comandos MetaFont modificados se elimina del archivo de registro para mantenerla claro.
El siguiente diagrama ilustra el concepto que usa mf2ff como ejemplo.
┌──────────┐
│ font.mf │
└──────────┘
v
┌──────────┐ ┌───────────┐
│ │ > │ METAFONT │
│ │ └───────────┘
│ │ v
│ │ ┌───────────┐
│ mf2ff │ < │ font.log │
│ │ └───────────┘
│ │
│ │ ┌───────────┐
│ │ > │ FontForge │
└──────────┘ └───────────┘
v v
┌──────────┐ ┌─────────────────────┐
│ font.log │ │ font.ttf / font.otf │
└──────────┘ └─────────────────────┘
Ejemplo simple
Agregar el siguiente código a un archivo MetaFont hará que MetaFont no fill el contorno c , sino que escriba las operaciones en el archivo de registro:
def fill expr c =
message "fill"; show c;
enddef;
Después de que MetaFont terminó de procesar el archivo, un script analiza el archivo de registro y sabe de que había un comando fill y sabe que el contorno se llenará. Esta información se puede pasar al programa de procesamiento de fuentes para agregarla al glifo.
De hecho, este proceso es mucho más complicado. Para poder procesar archivos MetaFont no basados en MetaFont simple, comandos como addto en lugar de comandos como fill deben ser redefinidos. Pero esos comandos addto son más complejos; También forman la base para otros comandos de metafont simples como unfill , ( un ) draw , ( un ) drawdot y erase . Estos comandos se expanden a varias palabras clave que separan las diferentes partes de la información necesarias para realizar estas operaciones diferentes ( addto , also , contour , doublepath , withpen , withweight ).
Otro desafío es el colon en condiciones y bucles. Estas estructuras pueden aparecer en cualquier otro comando, incluso en comandos que usan el colon como separador ( ligtable y fontdimen ), por lo que : debe redefinirse como otras palabras clave para generar información al archivo de registro. Se requiere un cambio sofisticado entre diferentes redefiniciones del colon dentro de estos comandos.
Además de eso, se debe implementar un proceso para que sea fácil encontrar todos los comandos en el archivo de registro, incluso si hay comandos de mensajes en el archivo MetaFont no relacionados con la redefinición de las primitivas MetaFont. Esos no deben interpretarse como información para la generación de fuentes. Por lo tanto, toda la información escrita en el archivo de registro debe estar encerrada en palabras clave especiales que es poco probable que se utilicen en los comandos de mensajes de los archivos metafont.
MetaFont, desarrollado por De Knuth desde 1977, es un programa que genera fuentes de mapa de bits a partir de archivos escritos en el idioma MetaFont. Las fuentes de mapa de bits tienen la desventaja de que se vuelven borrosos bajo aumento. MetaFont se desarrolló de modo que para la resolución particular de la impresora se generó una fuente separada. Hoy en día, las fuentes vectoriales son estándar, que no tienen este problema bajo aumento. Por lo tanto, son más adecuados para su uso en pantallas. Además, se pueden usar con cada impresora sin ninguna restricción.
Además del enfoque MF2VEC con el mf2ff presentado aquí, los siguientes scripts para convertir archivos MetaFont en fuentes vectoriales están disponibles:
| Nombre | Método |
|---|---|
| Metatype1 | Metapost |
| MF2PT1 | Metapost |
| mftrace | Rastreo de mapa de bits |
| Textrace | Rastreo de mapa de bits |
En este contexto, Metapost significa que el programa Metapost se usa para convertir cada carácter de los archivos de MetaFont a un gráfico vectorial. Después de eso, los gráficos vectoriales se juntan para obtener una fuente vectorial. Este método tiene la desventaja de que Metapost solo puede procesar una parte del lenguaje MetaFont.
El rastreo de mapa de bits significa que MetaFont genera una fuente de mapa de bits primero. En un programa separado, se traza el mapa de bits de cada glifo y luego se junta para obtener una fuente vectorial.
Cada uno de los métodos tiene desventajas específicas. Eche un vistazo a la comparación a continuación para obtener más detalles.
En la siguiente tabla se muestra una comparación de los scripts disponibles para convertir los archivos MetaFont en fuentes vectoriales.
| Característica | Metafont | mf2ff | Metatype1 | MF2PT1 | mftrace | Textrace |
|---|---|---|---|---|---|---|
| El guión está escrito en | - | Python 3 | Perl | Perl | Python 2 | Perl |
| Procesamiento de archivos de MetaFont | Metafont | Metafont | Metapost | Metapost | Metafont | Metafont |
| Procesamiento posterior | - | Fontforge | AWK / T1ASM | t1asm | Autotrace o Potrace / T1asm | autotracas |
| Formato de salida | GF / TFM | ✅ TTF, OTF, SFD | ? PFB | ? PFB | ✅ AFM / PFA / PFB / TTF / SVG | ? PFB |
| Calidad de salida | mapa de bits | ✅ Gráfico vectorial | ✅ Gráfico vectorial | ✅ Gráfico vectorial | ? mapa de bits rastreado | ? mapa de bits rastreado |
| Redefine no predominales / requiere no primos | ✅ No | ✅ No | Sí | Sí | ✅ No | ✅ No |
| Soporte unicode | No | ✅ Sí | ❔ | No | No | No |
| Admite comandos con lápiz | ✅ Sí | ? Limitado | No | ? Limitado | ✅ Sí | ✅ Sí |
| Admite comandos de ligadura y kerning | ✅ Sí | ? Limitado | ❔ | ❔ | ❔ | No |
| Admite fuentes variables | No | No, posiblemente en el futuro | No | No | ❔ | No |
Los siguientes son algunos ejemplos creados con mf2ff . Los contornos y los caracteres llenos se muestran cuando se muestran en Fontforge. Tenga en cuenta que los resultados aún no son perfectos.
Algunos glifos de los tipos de letra modernos de la computadora aún no se procesan correctamente, es decir, la parte media de Capital S y sloped_serif en letras minúsculas.

![]() | ![]() | ![]() |
La imagen de la izquierda fue creada por la desactivación de los comandos cull .
El estilizado árbol de secoyas de la costa el Palo Alto, que se presenta en las páginas 124-126 del MetaFontbook. En la versión izquierda, se activa la opción cull-at-shipout . Dado que la troncal y la rama superior comparten un punto en la curva, la implementación actual causa resultados incorrectos allí.
![]() | ![]() | ![]() | ![]() |
El logotipo, que se presenta en la página 138, el MetaFontbook. En la versión izquierda, se activa la opción cull-at-shipout . El logotipo lleno es el mismo en ambos casos.
![]() | ![]() | ![]() |
mf2ff Dado que mf2ff todavía está en desarrollo y no está a fondo, hay algunas limitaciones. Pueden abordarse en futuras actualizaciones.
Si una limitación específica está retrasando su proyecto, abra un problema para que las actualizaciones futuras puedan centrarse en las necesidades de los usuarios.
penrazor no es compatible (ver Dangerous_bend_symbol Ejemplo), Fontforge: "El ancho de accidente cerebrovascular no puede ser cero"penspeck plantea una advertencia, pero la producción parece estar bien en algunos casos.cull es limitado.: :: , kern , skipto así como los operadores de ligadura =: |=: =:| y |=:| son apoyados. El comando ligable ignora > en los operadores. Además, el operador ||: no es compatible.charlist ni comandos extensible todavía son compatibles.picture debe redefinirse para inicializar las variables de la imagen como una capa vectorial de Fontforge. Como MetaFont utiliza las palabras clave de tipo para ambos, la declaración de variable y la prueba de tipo en expresiones booleanas, la palabra clave picture no se puede usar para probar si una variable es de picture de tipo.makepen y makepath no tienen ningún efecto. Los bolígrafos y la ruta no se pueden distinguir usando pen o path en una expresión booleana. Hay una opción is_type que introduce is_pen o is_path que podría ayudarlo a eludir este problema.ligtable y fontdimenmf2ff necesita redefinir el colon ( : . Esto puede causar problemas en el procesamiento de múltiples anidados if ... ( elseif ) ... ( end ) ... fi y / o for / forsuffixes / forever ... endfor dentro de los comandos que usan el colon en su propia sintaxis, es decir, ligtable y fontdimen .charlist y extensibleHay algunas cosas que podrían ayudar. Tenga en cuenta que no los entiendo al 100%:
/usr/local/lib/python3/dist-packages a su $PYTHONPATHexport PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3/dist-packages a su ~/.profile )/usr/local/lib/python3.4/site-packages a Python's Path