Compartir a través de


Fuentes de variables OpenType

En este tema se describen las fuentes de variables OpenType, su compatibilidad con DirectWrite y Direct2D y cómo usarlas en la aplicación. 

¿Qué son las fuentes de variables OpenType?

La versión 1.8 de la especificación de formato de fuente OpenType de introdujo una nueva extensión al formato conocido como Variaciones de fuente OpenType. Las fuentes que usan estas extensiones se conocen como fuentes de variables OpenType. Una fuente de variable OpenType es una sola fuente que puede comportarse como varias fuentes mediante la interpolación continua entre diferentes diseños, todos definidos dentro de la única fuente.

Una fuente de variable OpenType puede definir una variación continua de su diseño a lo largo de uno o varios ejes independientes, como el peso o el ancho:

 

Muestra una fuente de variable OpenType con la letra

Un desarrollador de fuentes determina un conjunto de ejes de variación que se van a usar en una fuente determinada. Estos ejes pueden incluir un conjunto de ejes conocidos (o "registrados") de variación, como el peso y el ancho, pero también pueden incluir ejes arbitrarios y personalizados de variación definidos por el desarrollador de fuentes.  

Al seleccionar un conjunto de ejes de variación para una fuente, el desarrollador de fuentes define un espacio abstracto y n dimensional de variación de diseño para la fuente. Los motores de texto pueden especificar potencialmente cualquier posición, o "instancia", dentro de ese espacio continuo para diseñar y representar texto. 

El desarrollador de fuentes también puede seleccionar y asignar nombres a instancias concretas dentro del espacio de variación de diseño; se denominan "instancias con nombre". Por ejemplo, una fuente con variación de peso puede admitir la variación continua entre trazos muy ligeros y muy pesados, mientras que el desarrollador de fuentes ha seleccionado pesos concretos a lo largo de ese continuum y los nombres asignados a ellos, como "Light", "Regular" y "Semibold". 

El formato de fuente de variable OpenType usa tablas de datos que se encuentran en fuentes OpenType tradicionales, además de determinadas tablas adicionales que describen cómo cambian los valores de varios elementos de datos para distintas instancias. El formato designa una instancia de variación como una "instancia predeterminada", que usa tablas tradicionales para obtener valores predeterminados. Todas las demás instancias dependen de los datos predeterminados más otros datos delta. Por ejemplo, una tabla "glyf" puede tener una descripción de curva Bezier de una forma nominal de glifo, que es la forma usada para la instancia predeterminada, mientras que una tabla "gvar" describirá cómo se ajustan los puntos de control Bezier para el glifo para otras instancias. Del mismo modo, otros valores de fuente pueden tener un valor nominal más datos delta que describen cómo cambian esos valores para diferentes instancias; por ejemplo, x-height y otras métricas de ancho de fuente, o posiciones de delimitación de marcas específicas del glifo y ajustes de kerning. 

Dado que las fuentes variables pueden admitir un conjunto arbitrario de ejes de variación, requieren un modelo extensible de familias de fuentes que reflejan más directamente cómo los diseñadores de fuentes crean familias de fuentes: una familia de fuentes se define mediante un nombre de familia y determinadas características de diseño que son constantes, con un número arbitrario (determinado por el desarrollador de fuentes) de maneras en las que el diseño puede variar. Se puede crear una familia de fuentes con variantes para peso, pero se puede crear una familia de fuentes diferente con variantes para x altura, serif-size, "funkiness" o lo que desee el desarrollador de fuentes. En este modelo, una selección de caras de fuente se describe mejor usando el general, o "preferido" o "tipográfico", nombre de familia más un conjunto de pares clave-valor, cada uno que representa un tipo de variación y un valor específico, con los tipos de variación en general un conjunto extensible. Esta noción general de una familia de fuentes se puede aplicar a fuentes tradicionales, no variables, así como a fuentes variables. Por ejemplo, bajo este modelo de familia tipográfica general, una familia "Selawik VF" podría tener variaciones para el peso, el tamaño óptico y el diseño serif, con instancias como "Semilight Banner Sans". 

Sin embargo, algunas implementaciones de software existentes, incluidas las API de DirectWrite existentes, se pueden diseñar suponiendo un modelo más limitado de familias de fuentes. Por ejemplo, algunas aplicaciones pueden suponer que una familia de fuentes puede tener, como máximo, variantes regular, negrita, cursiva y cursiva en negrita. Las interfaces IDWriteFontCollection existentes y IDWriteFontFamily asumen un modelo de familia weight/stretch/style ("WSS"), lo que permite especificar variantes dentro de una familia mediante las enumeraciones DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH o DWRITE_FONT_STYLE como parámetros. Tomando el ejemplo anterior, el tamaño óptico y los ejes serif no se tratarían como ejes internos de familia de variación en el modelo WSS. 

La compatibilidad completa con fuentes variables requeriría API que permitan especificar un miembro de la familia con potencialmente varios parámetros, según lo determinado por la fuente. Sin embargo, los diseños de API existentes pueden proporcionar compatibilidad parcial con fuentes variables mediante la proyección de las instancias con nombre definidas en una fuente variable en los modelos de familia de fuentes más limitados. En el ejemplo anterior, "Selawik VF Semilight Banner Sans" podría proyectarse en el modelo WSS como una familia "Selawik VF Banner Sans" con "Semilight" como variante de peso. 

Por otro ejemplo, considere una familia de fuentes tipográficas como Sitka, con variantes de tamaño óptico y peso. Las variantes con nombre dentro de la familia incluyen Sitka Text Regular y Sitka Banner Bold (más muchos otros). El nombre de familia tipográfico es "Sitka", mientras que los nombres de caras de estas variantes en el modelo de familia tipográfica serían "Text Regular" y "Banner Bold". Los modelos de familia WSS y de cuatro miembros no permiten variantes de tamaño óptico dentro de una familia, por lo que las distinciones de tamaño óptico deben tratarse como distinciones de nivel de familia. En la tabla siguiente se muestra cómo se trataría una selección de fuentes de la familia tipográfica Sitka en el modelo de familia WSS:

Modelo de familia tipográfica

Modelo de familia WSS

Familia

Cara

Familia

Cara

Sitka

Texto normal

Sitka Text

Regular

Sitka

Banner Bold

Sitka Banner

Audaz

Sitka

Cursiva de título

Título de Sitka

Itálico

 

La proyección de nombres de un modelo de familia tipográfica al modelo de familia WSS se puede aplicar a fuentes no variables y a las instancias con nombre de fuentes de variables. Sin embargo, esto no se puede hacer para otras instancias sin nombre del espacio de variación de diseño continuo de una fuente variable. Por este motivo, la compatibilidad con la funcionalidad completa de fuentes variables requerirá API diseñadas para hacer referencia a caras dentro de una familia tipográfica en términos de un conjunto sin restricciones de ejes de variación y valores de eje. 

Compatibilidad con fuentes de variables OpenType en DirectWrite

A partir del lanzamiento de Windows 10 Creators Update, el formato de fuente de la variable OpenType sigue siendo muy nuevo, y los proveedores de fuentes, plataformas y aplicaciones siguen en proceso de implementar el nuevo formato. Esta actualización proporciona implementación inicial para este formato en DirectWrite. 

Se han actualizado los elementos internos de DirectWrite para admitir fuentes de variables OpenType. Con las API actuales, esto proporciona compatibilidad con las instancias con nombre de una fuente variable. Esta compatibilidad se puede usar para flujos de trabajo completos, desde la enumeración de las instancias con nombre, la selección de una instancia con nombre, el uso en el diseño y la forma, para representar e imprimir. Para beneficiarse de las aplicaciones que también usan la interoperabilidad de texto GDI para determinadas operaciones, también se ha agregado compatibilidad similar en las API de GDI existentes. 

En Windows 10 Creators Update, DirectWrite no admite instancias arbitrarias que usan la funcionalidad de variación continua de fuentes de variables.

En muchas operaciones, el comportamiento de DirectWrite de instancias con nombre de una fuente variable no se puede distinguir del comportamiento de las fuentes que no son variables. Y dado que se proporciona compatibilidad con las API de DirectWrite existentes, las instancias con nombre de fuentes variables pueden incluso funcionar en muchas aplicaciones de DirectWrite existentes sin cambios. Sin embargo, las excepciones se pueden aplicar en determinadas situaciones:

  • Si una aplicación procesa los datos de fuente directamente para determinadas operaciones. Por ejemplo, si una aplicación lee datos de esquema de glifo directamente desde el archivo de fuente para crear determinados efectos visuales.
  • Si una aplicación usa una biblioteca de terceros para determinadas operaciones. Por ejemplo, si una aplicación usa DirectWrite para el diseño, para obtener los índices y posiciones finales del glifo, pero después usa una biblioteca de terceros para la representación.
  • Si una aplicación inserta datos de fuente en un documento o de alguna otra manera pasa los datos de fuente a un proceso de bajada.

Si las operaciones se realizan mediante implementaciones que no admiten fuentes variables, es posible que estas operaciones no generen los resultados esperados. Por ejemplo, las posiciones del glifo se pueden calcular para una instancia con nombre de la fuente variable, pero los glifos se pueden representar suponiendo una instancia con nombre diferente. En función de la implementación de la aplicación, los resultados pueden funcionar en algunos contextos, pero no en otros contextos en los que se pueden usar otras bibliotecas. Por ejemplo, el texto puede mostrarse correctamente en pantalla, pero no cuando se imprime. Si los flujos de trabajo de un extremo a otro se implementan solo con DirectWrite, se puede esperar un comportamiento correcto para las instancias con nombre de una fuente de variable. 

Dado que las API de DirectWrite existentes admiten la selección de caras mediante el modelo de peso, ajuste y estilo, las instancias con nombre de las fuentes que usan otros ejes de variación se proyectarán desde el modelo de familia tipográfica general en el modelo WSS, como se ha descrito anteriormente. Esto se basa en una fuente variable que incluye una tabla de "atributos de estilo" ("STAT") con subtables de valor de eje, que DWrite usa para distinguir los tokens de nombre de cara que designan atributos de peso, stretch o style de tokens que pertenecen a otros ejes de variación.  

Si una fuente de variable no incluye una tabla "STAT", según sea necesario para las fuentes de variable según la especificación OpenType, DirectWrite tratará la fuente como una fuente que no sea variable que contenga solo la instancia predeterminada.  

Si una fuente contiene una tabla "STAT", pero no incluye subtables de valores de eje adecuadas, esto puede dar lugar a resultados inesperados, como tener varias caras que tengan nombres de caras idénticas. Estas fuentes no se admiten en este momento. 

La especificación OpenType permite representar los datos de esquema de glifo en uno de los dos formatos: mediante una tabla "glyf", que usa el esquema TrueType y el formato de sugerencia, o mediante una tabla "CFF", que usa la representación de formato de fuente compacta ("CFF"). En una fuente variable con esquemas TrueType, la tabla "glyf" continúa utilizándose y se complementa con una tabla "gvar" que proporciona los datos de variación para los esquemas. Esto significa que la instancia predeterminada de una fuente de variable con esquemas TrueType usa solo tablas OpenType tradicionales que se admitirán en software anterior que no tenga compatibilidad con fuentes variables. Sin embargo, en una fuente variable con esquemas CFF, la tabla "CFF" se sustituye por la tabla "CFF2", que encapsula los datos de esquema predeterminados y los datos de variación asociados en una tabla. Los datos de CFF se procesan mediante un rasterizador independiente de que se usa para los datos TrueType y una tabla "CFF2" requiere un rasterizador CFF actualizado que tenga compatibilidad con "CFF2". Los rasterizadores CFF anteriores no pueden procesar una tabla 'CFF2'. Para una fuente variable con datos de esquema de CFF, esto significa que incluso la instancia predeterminada no funcionará en software anterior. 

En Windows 10 Creators Update, DirectWrite no admite fuentes variables con datos de esquema de CFF mediante la tabla "CFF2". 

Uso de fuentes de variables OpenType

Las fuentes de variables OpenType pueden ser fáciles de usar, teniendo en cuenta las limitaciones actuales indicadas anteriormente:

  • En este momento solo se admiten instancias con nombre de una fuente variable.
  • En este momento solo se admiten fuentes variables que usan datos de esquema de glifo TrueType (no esquemas de CFF). 
  • En el caso de las fuentes que usan ejes de variación de diseño que no sean weight, stretch o style, las instancias con nombre se proyectarán en el modelo de familia WSS, lo que puede dar lugar a que algunas instancias con nombre aparezcan como familias independientes (como sucede en el pasado para fuentes no variables). Para admitir esto, las fuentes variables deben tener una tabla "STAT" que incluya subtables de valores de eje adecuadas.
  • Las instancias con nombre de fuentes de variables se admiten en las API de DirectWrite, pero si ciertas operaciones se realizan en implementaciones anteriores que no admiten fuentes variables, pueden producir resultados incorrectos. 
  • Algunas API de DirectWrite usan las enumeraciones de DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH y DWRITE_FONT_STYLE para especificar atributos de peso, ajuste y estilo al seleccionar caras. Si una fuente de variable usa los ejes de variación correspondientes, pero tiene muchas instancias con nombre que requieren una granularidad más fina, no todas las instancias con nombre se podrán seleccionar en esas API.

Las fuentes de variables OpenType que cumplan estos requisitos se pueden instalar desde el shell de Windows, al igual que otras fuentes OpenType, y también se pueden usar en conjuntos de fuentes personalizados creados por una aplicación.  

Cuando se instala en el sistema, todas las instancias con nombre de una fuente variable se incluirán en el conjunto de fuentes devuelto llamando al método IDWriteFontFamily3::GetSystemFontSet. Tenga en cuenta que un conjunto de fuentes es una lista plana sin una jerarquía de agrupación familiar, pero cada elemento del conjunto tiene una propiedad de nombre de familia basada en el modelo de familia de WSS. El conjunto de fuentes se puede filtrar para una instancia con nombre de variable determinada mediante los métodos IDWriteFontSet::GetMatchingFonts. Si usa el GetMatchingFonts sobrecarga que toma un familyName, sin embargo, el familyName especificado debe usar el nombre que se ajusta al modelo de familia de fuentes WSS. La lista completa de nombres de familia compatibles con WSS que se producen en un conjunto de fuentes se puede obtener mediante los métodos IDWriteFontSet::GetPropertyValues mediante DWRITE_FONT_PROPERTY_ID_FAMILY_NAME.  

Del mismo modo, todas las instancias con nombre de una fuente de variable se representarán en la colección de fuentes devuelta por el método IDWriteFactory::GetSystemFontCollection. Dado que los elementos de una colección de fuentes son familias de fuentes basadas en el modelo WSS, las instancias con nombre de una fuente variable se pueden representar en una colección como miembros de dos o más familias de fuentes. Si se usa el método IDWriteFontCollection::FindFamilyName, el parámetro familyName debe ser un nombre de familia compatible con WSS. Para buscar todos los nombres de familia compatibles con WSS de una colección de fuentes, una aplicación puede recorrer en bucle cada familia y llamar a IDWriteFontFamily::GetFamilyNames, aunque puede ser más fácil obtener un conjunto de fuentes correspondiente y usar el método GetPropertyValues como se ha descrito anteriormente. 

Al trabajar con fuentes personalizadas, se pueden usar varios enfoques descritos en el tema Custom Font Sets para crear un conjunto de fuentes. Para agregar una fuente variable a un conjunto de fuentes personalizado, se recomienda el método IDWriteFontSetBuilder1::AddFontFile, ya que admite fuentes variables y agregará todas las instancias con nombre de una fuente variable en una sola llamada. En este momento no hay ninguna manera de agregar instancias con nombre individuales de una fuente de variable personalizada a un conjunto de fuentes mediante el IDWriteFontSetBuilder::AddFontFaceReference métodos, ya que no hay ninguna manera de crear una referencia facial de fuente que especifique cuál de las instancias con nombre de un archivo de fuente variable está pensada. Esto significa que actualmente no hay ninguna manera de agregar instancias con nombre de una fuente personalizada a un conjunto de fuentes personalizado con propiedades personalizadas asignadas. Esto significa, a su vez, que las fuentes de variables personalizadas actualmente no se pueden usar fácilmente junto con las API de DirectWrite para fuentes remotas. Si las instancias con nombre de una fuente variable se incluyen en un conjunto de fuentes del sistema, sin embargo, las referencias de caras de fuente para cada instancia con nombre ya existirán y se pueden agregar a conjuntos de fuentes personalizados, incluido el uso de valores de propiedad personalizados. Consulte el tema Conjuntos de fuentes personalizados para obtener más información. 

Al trabajar con fuentes variables, las enumeraciones directWrite DWRITE_FONT_WEIGHT y DWRITE_FONT_STRETCH están estrechamente conectadas a los ejes de variación de peso y ancho definidos en la especificación OpenType, pero no son los mismos. En primer lugar, la escala numérica de cualquier eje de variación siempre admite valores fraccionarios, mientras que fontWeight y fontStretch usan enteros. La escala del eje de peso OpenType usa valores que van de 1 a 1000, que también es compatible con fontWeight. Por lo tanto, el cambio de un valor de eje de peso de variación a fontWeight es relativamente menor: fontWeight notificado para una instancia con nombre se puede redondear del valor preciso utilizado para definir la instancia con nombre dentro de la fuente. La distinción entre la fuente DirectWrite fontStretch y la escala del eje de ancho OpenType es mayor: DirectWrite usa valores de 1 a 9, siguiendo las usWidthClass valores de la tabla OpenType OS/2, mientras que la escala del eje de ancho OpenType usa valores positivos que representan un porcentaje de ancho normal. La documentación de usWidthClass de la especificación OpenType proporciona una asignación entre los valores del 1 al 9 y el porcentaje de valores normales. El valor fontStretch notificado para una instancia con nombre puede implicar redondeo al convertir valores del eje de ancho. 

Al crear una IDWriteTextFormat, debe especificarse una colección de fuentes y propiedades de fuente compatibles con WSS (nombre de familia, peso, stretch y estilo). Esto también se aplica al establecer propiedades de formato de fuente en un IDWriteTextLayout intervalo de texto. Las propiedades se pueden obtener de un objeto IDWriteFontFace 3 o de IDWriteFont y IDWriteFontFamily objetos que representan una instancia con nombre determinada. Como se observó anteriormente, los valores devueltos por los métodos GetWeight y GetStretch pueden redondear aproximaciones para los valores de eje reales usados para definir la instancia con nombre, pero DirectWrite asignará la combinación de propiedades a la instancia con nombre deseada. 

Del mismo modo, si una aplicación usa IDWriteFontFallbackBuilder para crear datos de reserva de fuentes personalizados, las familias se especifican para las asignaciones de intervalo de caracteres mediante nombres de familia compatibles con WSS. La reserva de fuentes dentro de DirectWrite se basa en familias con DirectWrite seleccionando una variante dentro de una familia de reserva que sea una coincidencia más cercana para la variante de la familia inicial. En el caso de las variantes que implican dimensiones distintas del peso, el stretch y el estilo, DirectWrite actualmente no podría seleccionar estas variantes dentro de una familia de reserva a menos que se crearan datos de reserva personalizados específicamente para proporcionar asignaciones de reserva para familias que tienen atributos no WSS concretos, como variantes de tamaño óptico "Caption".