Unidades de fuente SVG por em a mm

En una aplicación que estoy escribiendo, necesito tomar la ruta de un glifo de una fuente SVG y escalarla a un tamaño particular, que se especifica en milímetros. Tomo la propiedad de la ruta 'd' de la fuente SVG, la escalo aplicando un factor de escala a las coordenadas de la ruta y luego la uso como una ruta normal en el SVG que estoy generando. (Para mi aplicación, no puedo usar 'matriz', 'alto', 'ancho' ni ningún otro método de escala incorporado; las coordenadas de la ruta deben reflejar la dimensión y escala finales exactas). La mecánica de aplicar una escala al camino no es un problema; Solo necesito averiguar el factor de escala correcto para aplicar.

La fuente SVG proporciona 'unidad por em' que es 2048 o 1000. Sé que 'em' es una unidad de medida relativa y que 'mm' es una unidad absoluta, y estoy bastante seguro de que la conversión puede hacerse. Sería útil si alguien pudiera explicar los detalles de dicha conversión o indicar si lo que estoy tratando de hacer no tiene sentido.

Un poco de contexto: el archivo SVG que estoy generando con mi software (Python) se convierte luego en un archivo de coordenadas (Gerber) que se usa para fabricar físicamente un objeto. Todos los elementos en ambos archivos deben representar las dimensiones exactas sin ninguna otra escala o transformación.

¿Puede dar más información sobre lo que quiere decir con "las dimensiones deben especificarse en mm"? O por el contrario, ¿cómo vas a hacer la conversión de archivos? ¿Es suficiente convertir el glifo de la fuente SVG en un gráfico SVG estándar con una altura y un ancho definidos en mm, o desea que todas las coordenadas de las curvas Bezier estén en mm?
He editado la pregunta; Espero que sea más claro ahora.

Respuestas (1)

En tipografía, una unidad "em" es la altura máxima de un conjunto de caracteres. Para texto latino, eso significa la altura desde el acento en la parte superior de las letras mayúsculas hasta la parte inferior de las letras minúsculas descendentes. Por ejemplo, sería la altura total de Ég.

El valor "em" es lo que configura cuando define el tamaño de la fuente; si configura la fuente en 24 puntos, entonces 1 em = 24 puntos = 1/3 de pulgada. En CSS, también puede establecer el tamaño de la fuente usando unidades métricas, por lo que podría establecer específicamente font-size:20mmy el visor SVG escalaría la fuente para que tenga esa altura cuando se imprima (o una aproximación en la pantalla).

Sin embargo, eso no resuelve el problema de su archivo de fabricación, que necesita que las coordenadas reales de las curvas Bezier estén en mm. Para hacer eso, necesita saber cómo se relacionan las coordenadas de las curvas en la fuente con el tamaño de salida final.

Como ha descubierto, la clave está en el units-per-ematributo de un <font-face>elemento o @font-facedeclaración CSS. Los valores estándar (1000 y 2048) se derivan de otros formatos de fuente; en teoría, podría usar cualquier valor para las fuentes SVG.

De cualquier manera, esto define el número de coordenadas entre la parte superior e inferior de los caracteres, es decir, el número de unidades de coordenadas en la unidad 1em. A partir de ahí, puede calcular cuánto debe escalarse cada coordenada para que coincida con el tamaño de fuente deseado.

Si tiene 1000 unidades por em y desea que la altura máxima final de sus palabras sea de 500 mm, entonces su factor de escala es

scalingFactor = (desired em height)/(units per em) 
              = (500mm/em) / (1000 units/em)
              = 0.5mm/unit

En otras palabras, para convertir las unidades en bruto a mm, multiplicarías cada coordenada por 0,5.

Sin embargo, hay un par de otros detalles que pueden causar confusión, dependiendo de los requisitos de su software de conversión y corte de material y cómo está definiendo el tamaño deseado de las letras:

  • La unidad em solo define la altura de los caracteres. El ancho (en la mayoría de las fuentes) variará. En SVG, el horiz-adv-xatributo de cada glifo (o, si no se especifica en el glifo individual, de la propia fuente) define el ancho de ese carácter, incluido el espaciado de caracteres predeterminado, como un número de unidades de coordenadas. Si desea escalar su texto a un ancho específico en lugar de una altura específica en mm, esta es la cantidad de unidades que debe usar en su cálculo:

    scalingFactor = (desired width)/(horizontal advance in coordinate units) 
    
  • Alternativamente, si le importa la altura, pero solo la altura de una letra mayúscula (sin descendentes, por lo que no es la altura completa de em), entonces deberá calcular la cantidad de unidades en esa altura a partir de los atributos y cap-height, alphabeticalque defina la posición de la parte superior e inferior de las letras mayúsculas en el sistema de coordenadas:

    scalingFactor = (desired height of capital letter) /
                   [(cap-height coordinate)-(alphabetic baseline coordinate)] 
    

    (Hay varias otras alturas que se pueden definir que podría usar para calcular su escala de manera similar).

  • A diferencia de todo lo demás en SVG, las coordenadas Y de las fuentes aumentan a medida que subes, no hacia abajo. (Esto se hace nuevamente para mantener la coherencia con otros formatos de fuente). Si su software de conversión espera lo contrario, tendrá que cambiar cada coordenada Y antes de escalarla:

    newYValue = [(units-per-em) - (oldY)] * scalingFactor
    
  • Finalmente, es posible que deba ajustar el valor absoluto de las coordenadas para que el origen (0,0) esté en la posición correcta para lo que está haciendo. Puede trabajar desde uno de los atributos dados en el elemento<font-face> , o los horiz// atributosvert-origin-xy en el <font>elemento. Estos atributos definen la posición del origen del glifo (para texto latino, la intersección de la línea de base con el borde izquierdo de la letra) en el sistema de coordenadas. Si estos son cero (el valor predeterminado si no se especifican), los descendientes se darán en coordenadas negativas. Si las coordenadas negativas son un problema, deberá calcular la coordenada mínima en cada dirección y traducir cada coordenada en esa cantidad para que todo sea positivo.

Espero que sea suficiente para que descubras qué representan los números y cómo puedes adaptarlos a tus necesidades.

Una opción final, especialmente si se trata de una conversión única y no necesita crear un script reutilizable, es abrir el SVG en un editor visual como Inkscape. Puede escribir el texto y luego usar el comando "Ruta> Objeto a ruta". No puedo encontrar una manera fácil de forzarlo a escalar las coordenadas a mm, ¡pero eliminará la mayoría de los dolores de cabeza de tamaño de fuente específicos! Si ya tiene un programa de conversión que funciona con rutas SVG, este sería el enfoque más fácil.

¡Vaya, qué respuesta! Sí, eso me acerca mucho más a lo que quiero lograr. Para más contexto, este es el proyecto: bitbucket.org/boldport/pcbmode y esto es lo que hago con él;) boldport.com
¡Decir ah! Circuitboard como arte, definitivamente un proyecto interesante. Me sorprendió un poco cuando busqué el formato Gerber y la mayoría de los resultados relacionados con las placas de circuitos, pero supuse que el mismo formato de archivo había sido adoptado por equipos de corte de materiales más genéricos.
¿No hace ninguna diferencia si desea convertir el ancho o la altura de un glifo en unidades de mm o px entonces? Si quiero tener una altura de, digamos, 500 px, ¿debo multiplicar cada coordenada por un factor de 0,5 para una altura deseada de 500 mm?
@ user141169 Sí, sustituiría el valor que quisiera en la parte de la fórmula "altura em deseada" y obtendría un resultado en las mismas unidades.