Compatibilidad con fuentes de color

En este tema se describen las fuentes de color, su compatibilidad con DirectWrite y Direct2D (y otros marcos) y cómo usarlas en la aplicación.

¿Qué son las fuentes de color?

De forma predeterminada, un glifo tiene una forma pero ningún color intrínseco. Tanto DirectWrite como Direct2D tienen métodos DrawGlyphRun que representan las ejecuciones del glifo rellenando las formas del glifo con un color de texto especificado. Para mayor comodidad, nos referiremos a eso como representación de glifos monocromo . Todas las fuentes tienen glifos monocromáticos. Por otro lado, una fuente de color también tiene representaciones de color de algunos glifos. Y para representar glifos en color, la aplicación debe usar diferentes API de representación de glifos (como analizaremos), en lugar de llamar a los métodos DrawGlyphRun monocromo.

Las fuentes de color también se conocen como fuentes multicolor o fuentes cromáticas. Son una tecnología de fuentes que permite a los diseñadores de fuentes usar varios colores dentro de cada glifo. Las fuentes de color permiten escenarios de texto multicolor en aplicaciones y sitios web con menos código y compatibilidad con sistemas operativos más sólidos que las técnicas ad hoc implementadas encima del sistema de representación de texto.

Las fuentes con las que la mayoría de nosotros estamos familiarizados no son fuentes de color. Estas fuentes definen únicamente la forma de los glifos que contienen; ya sea con contornos vectoriales o mapas de bits monocromáticos. En tiempo de dibujo, un representador de texto rellena la forma del glifo mediante un solo color (el color de fuente) especificado por la aplicación o el documento que se va a representar. Por otro lado, las fuentes de color contienen información de color además de la información de formas. Algunos enfoques permiten a los diseñadores de fuentes ofrecer varias paletas de colores, lo que proporciona flexibilidad artística de fuente de color.

Este es un glifo de la fuente de color Emoji de Segoe UI. El glifo se representa en monocromo a la izquierda y en color a la derecha.

Muestra glifos en paralelo, el glifo izquierdo representado en monocromo, la derecha en la fuente de color Segoe U I Emoji.

Las fuentes de color suelen incluir información de reserva para plataformas que no las admiten o para escenarios en los que se ha deshabilitado la funcionalidad de color. En esas plataformas, las fuentes de color se representan como fuentes monocromáticas normales.

Dado que la compatibilidad con fuentes de color se implementa en el nivel de representación del glifo, no afecta al diseño de texto. Y eso es cierto si usa la interfaz IDWriteTextLayout o si implementa su propio algoritmo de diseño de texto. La asignación de caracteres a glifos y el posicionamiento de esos glifos, todos usan identificadores de glifo monocromo y sus métricas asociadas. La salida del proceso de diseño de texto es una secuencia de ejecuciones de glifo monocromo. Y, a continuación, la compatibilidad con fuentes de color se puede habilitar mediante la traducción de esos glifos base monocromáticos a las ejecuciones de glifos de color en tiempo de representación.

¿Por qué usar fuentes de color?

Históricamente, los diseñadores y desarrolladores han usado una variedad de técnicas para lograr texto multicolor. Por ejemplo, los sitios web suelen usar imágenes ráster en lugar de texto para mostrar encabezados enriquecidos. Este enfoque permite flexibilidad artística, pero los gráficos ráster no se escalan bien a todos los tamaños de pantalla y tampoco proporcionan las mismas características de accesibilidad que el texto real. Otra técnica común es superponer varias fuentes monocromáticas en diferentes colores de fuente; pero esto normalmente requiere código de diseño adicional para administrar.

Las fuentes de color ofrecen una manera de lograr esos efectos visuales con toda la simplicidad y la funcionalidad de las fuentes normales. El texto representado en una fuente de color es el mismo que el de otro texto: se puede copiar y pegar, se puede analizar mediante herramientas de accesibilidad, etc.

¿Qué tipos de fuentes de color admite Windows?

La especificación OpenType define varias maneras de insertar información de color en una fuente. A partir de Windows 10, versión 1607 (actualización de aniversario), DirectWrite y Direct2D (y los marcos de Windows basados en ellos) admiten todos estos enfoques:

Técnica Descripción
COLR/Tablas CPAL Usa capas de vectores coloreados, cuyas formas se definen de la misma manera que los contornos de glifo de un solo color. Compatibilidad iniciada en Windows 8.1.
Tabla SVG Usa imágenes vectoriales creadas en el formato De gráficos vectoriales escalables (SVG). A partir de Windows 10, versión 1607 (Actualización de aniversario), DirectWrite admite un subconjunto de la especificación SVG completa. No se garantiza que todo el contenido SVG se represente en una fuente SVG openType. Para más información, consulte Compatibilidad con SVG.
CBDT/Tablas CBLC Usa imágenes de mapa de bits de color incrustadas.
tabla sbix Usa imágenes de mapa de bits de color incrustadas.

Uso de fuentes de color

Desde la perspectiva del usuario, las fuentes de color son simplemente fuentes. Por ejemplo, normalmente se pueden instalar y desinstalar del sistema de la misma manera que las fuentes monocromáticas pueden; y se representan como texto seleccionable normal.

Desde la perspectiva del desarrollador también, las fuentes de color se suelen usar del mismo modo que las fuentes monocromáticas. En los marcos XAML y Microsoft Edge, puedes aplicar estilo al texto con fuentes de color de la misma manera que puedes con fuentes normales y, de forma predeterminada, el texto se representará en color. Sin embargo, si la aplicación llama directamente a las API de Direct2D (o API de Win2D) para representar texto, debe solicitar explícitamente la representación de fuentes de color.

Uso de fuentes de color con DirectWrite y Direct2D

La aplicación puede usar los métodos de dibujo de texto de nivel superior de Direct2D (DrawText y DrawTextLayout), o bien puede usar técnicas de nivel inferior para dibujar ejecuciones de glifo directamente. En cualquier caso, la aplicación requiere código específico para controlar correctamente los glifos de color. Las API DrawText y DrawTextLayout de Direct2D no representan glifos de color de forma predeterminada. Esto es para evitar cambios de comportamiento inesperados en las aplicaciones de representación de texto que se diseñaron antes de la compatibilidad con fuentes de color.

Para participar en la representación del glifo de color, pase la marca de opciones de D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT al método de dibujo. En el ejemplo de código siguiente se muestra cómo llamar al método DrawText de Direct2D para representar una cadena en una fuente de color:

// If m_textFormat points to a font with color glyphs, then the following
// call will render m_string using the color glyphs available in that font.
// Any monochromatic glyphs will be rendered with m_defaultFillBrush.
m_deviceContext->DrawText(
    m_string->Data(),
    m_string->Length(),
    m_textFormat.Get(),
    m_layoutRect,
    m_defaultFillBrush.Get(),
    D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
    );

Si la aplicación usa API de nivel inferior para controlar las ejecuciones de glifos directamente, seguirá funcionando en presencia de fuentes de color, pero no podrá dibujar glifos de color sin lógica adicional.

Para controlar correctamente los glifos de color, la aplicación debe:

  1. Pase la información de ejecución del glifo a TranslateColorGlyphRun, junto con un parámetro DWRITE_GLYPH_IMAGE_FORMATS que indica qué tipos de glifo de color está preparado para controlar la aplicación. Si hay glifos de color presentes (según la fuente y el DWRITE_GLYPH_IMAGE_FORMATS solicitado), DirectWrite dividirá la ejecución del glifo principal en ejecuciones de glifo de color individuales, a las que se puede tener acceso a través del objeto IDWriteColorGlyphRunEnumerator1 devuelto en el paso 4.
  2. Compruebe el HRESULT devuelto por TranslateColorGlyphRun para determinar si se detectaron ejecuciones de glifo de color. Un HRESULT de DWRITE_E_NOCOLOR indica que no hay una ejecución de glifo de color aplicable.
  3. Si TranslateColorGlyphRun indica que no se ejecuta ningún glifo de color (devolviendo DWRITE_E_NOCOLOR), la ejecución de glifo completo se trata como monocromática y la aplicación debe dibujarla como desee (por ejemplo, mediante ID2D1DeviceContext::D rawGlyphRun).
  4. Si TranslateColorGlyphRun notifica la presencia de ejecuciones de glifo de color, la aplicación debe omitir la ejecución del glifo principal y, en su lugar, usar las ejecuciones de glifo de color devueltas por TranslateColorGlyphRun. Para ello, recorra en iteración el objeto IDWriteColorGlyphRunEnumerator1 devuelto, recuperar cada glifo de color y dibujarlo según corresponda para su formato de imagen de glifo (por ejemplo, puede usar DrawColorBitmapGlyphRun y DrawSvgGlyphRun para dibujar glifos de mapa de bits de color y glifos SVG, respectivamente).

En este ejemplo de código se muestra la estructura general de este procedimiento:

// An example code snippet demonstrating how to use TranslateColorGlyphRun 
// to handle different kinds of color glyphs. This code does not make any 
// actual drawing calls. 
HRESULT DrawGlyphRun( 
    FLOAT baselineOriginX, 
    FLOAT baselineOriginY, 
    DWRITE_MEASURING_MODE measuringMode, 
    _In_ DWRITE_GLYPH_RUN const* glyphRun, 
    _In_ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, 
) 
{ 
    // Specify the color glyph formats your app supports. In this example, 
    // the app requests only glyphs defined with PNG or SVG. 
    DWRITE_GLYPH_IMAGE_FORMATS requestedFormats = 
        DWRITE_GLYPH_IMAGE_FORMATS_PNG | DWRITE_GLYPH_IMAGE_FORMATS_SVG; 

    ComPtr<IDWriteColorGlyphRunEnumerator1> glyphRunEnumerator; 
    HRESULT hr = m_dwriteFactory->TranslateColorGlyphRun( 
        D2D1::Point2F(baselineOriginX, baselineOriginY), 
        glyphRun, 
        glyphRunDescription, 
        requestedFormats, // The glyph formats supported by this renderer.
        measuringMode, 
        nullptr, 
        0, 
        &glyphRunEnumerator // On return, may contain color glyph runs.
        ); 

    if (hr == DWRITE_E_NOCOLOR) 
    { 
        // The glyph run has no color glyphs. Draw it as a monochrome glyph 
        // run, for example using the DrawGlyphRun method on a Direct2D 
        // device context. 
    } 
    else 
    { 
        // The glyph run has one or more color glyphs. 
        DX::ThrowIfFailed(hr); 

        // Iterate through the color glyph runs, and draw them. 
        for (;;) 
        { 
            BOOL haveRun; 
            DX::ThrowIfFailed(glyphRunEnumerator->MoveNext(&haveRun)); 
            if (!haveRun) 
            { 
                break; 
            } 

            // Retrieve the color glyph run. 
            DWRITE_COLOR_GLYPH_RUN1 const* colorRun; 
            DX::ThrowIfFailed(glyphRunEnumerator->GetCurrentRun(&colorRun)); 

            // Draw the color glyph run depending on its format. 
            switch (colorRun->glyphImageFormat) 
            { 
            case DWRITE_GLYPH_IMAGE_FORMATS_PNG: 
                // Draw the PNG glyph, for example with 
                // ID2D1DeviceContext4::DrawColorBitmapGlyphRun. 
                break; 

            case DWRITE_GLYPH_IMAGE_FORMATS_SVG: 
                // Draw the SVG glyph, for example with 
                // ID2D1DeviceContext4::DrawSvgGlyphRun. 
                break; 

                // ...etc. 
            } 
        } 
    } 

    return hr; 
} 

Uso de fuentes de color en una aplicación XAML

Las fuentes de color son compatibles de forma predeterminada con los elementos de texto de la plataforma XAML, como TextBlock, TextBox, RichEditBox, Glifos y FontIcon. Simplemente se aplica estilo al texto con una fuente de color y cualquier glifo de color se representará en color.

La sintaxis siguiente muestra una manera de aplicar estilo a un TextBlock con una fuente de color empaquetada con la aplicación. La misma técnica se aplica a las fuentes normales.

<TextBlock FontFamily="Assets/TMyColorFont.otf#MyFontFamilyName">Here's some text.</TextBlock>

Si quieres que el elemento de texto XAML nunca represente texto multicolor, establece su propiedad falseIsColorFontEnabledProperty en .

Sugerencia

Los vínculos anteriores son a las versiones de WinUI 3 de esos controles XAML. Puedes encontrar los equivalentes de Plataforma universal de Windows (UWP) en el espacio de nombres Windows.UI.Xaml.Controls.

Uso de fuentes de color en Microsoft Edge

Las fuentes de color se representan de forma predeterminada en sitios web y aplicaciones web que se ejecutan en Microsoft Edge, incluido el control WebView2 xaml . Simplemente use HTML y CSS para aplicar estilo al texto con una fuente de color y cualquier glifo de color se representará en color.

Uso de fuentes de color con Win2D

De forma similar a Direct2D, las API de dibujo de texto de Win2D no representan glifos de color de forma predeterminada. Para participar en la representación de glifos de color, establezca la marca de opciones EnableColorFont en el objeto de formato de texto que la aplicación pasa al método de dibujo de texto. En el ejemplo de código siguiente se muestra cómo representar una cadena en una fuente de color mediante Win2D:

// The text format that will be used to draw the text. (Declared elsewhere 
// and initialized elsewhere by the app to point to a color font.) 
CanvasTextFormat m_textFormat; 

// Set the EnableColorFont option. 
m_textFormat.Options = CanvasDrawTextOptions.EnableColorFont; 

// If m_textFormat points to a font with color glyphs, then the following
// call will render m_string using the color glyphs available in that font.
// Any monochromatic glyphs will be rendered with m_color.
args.DrawingSession.DrawText(
    m_string,
    m_point,
    m_color,
    m_textFormat
    );