Поддержка цветовых шрифтов

В этом разделе описываются цветовые шрифты, их поддержка в DirectWrite и Direct2D (и некоторых других платформах), а также способы их использования в приложении.

Что такое цветовые шрифты?

По умолчанию глиф имеет форму, но не имеет встроенного цвета. И DirectWrite, и Direct2D имеют методы DrawGlyphRun, которые отрисовывают запуски глифов путем заполнения фигур глифов указанным цветом текста. Для удобства мы будем называть это монохромной отрисовкой глифов. Все шрифты имеют монохромные глифы. Цветной шрифт, с другой стороны, также имеет цветовые представления некоторых глифов. А для отрисовки глифов в цвете приложение должно использовать различные API-интерфейсы отрисовки глифов (как мы рассмотрим) вместо вызова монохромных методов DrawGlyphRun .

Цветные шрифты также называются разноцветными шрифтами или хроматическими шрифтами. Это технология шрифтов, которая позволяет конструкторам шрифтов использовать несколько цветов в каждом глифе. Цветные шрифты позволяют использовать многоцветные текстовые сценарии в приложениях и на веб-сайтах с меньшим объемом кода и более надежной поддержкой операционной системы, чем специальные методы, реализованные над системой отрисовки текста.

Шрифты, знакомые большинству из нас, не являются цветными. Такие шрифты определяют только форму содержащихся в них глифов; либо с векторными контурами, либо с монохромными растровыми изображениями. Во время рисования отрисовщик текста заполняет фигуру глифа одним цветом (цветом шрифта), заданным приложением или документом. Цветовые шрифты, с другой стороны, содержат сведения о цвете в дополнение к сведениям о фигуре. Некоторые подходы позволяют конструкторам шрифтов предлагать несколько цветовых палитр, обеспечивая гибкость цветового шрифта.

Ниже приведен глиф из шрифта Segoe UI Emoji color. Глиф отображается в монохромном виде слева и цветом справа.

Отображается рядом глифы, левый глиф, отрисованный монохромно, справа в шрифте Segoe U I Эмодзи.

Цветовые шрифты обычно содержат резервные сведения для платформ, которые не поддерживают их, или для сценариев, в которых функция цвета была отключена. На этих платформах цветовые шрифты отображаются как обычные монохромные шрифты.

Так как поддержка цветовых шрифтов реализована на уровне отрисовки глифов, она не влияет на макет текста. И это верно независимо от того, используете ли вы интерфейс IDWriteTextLayout или реализуете собственный алгоритм разметки текста. При сопоставлении символов с глифами и расположении этих глифов используются идентификаторы монохромных глифов и связанные с ними метрики. Результатом процесса разметки текста является последовательность выполнения монохромных глифов. Затем можно включить поддержку цветовых шрифтов, преобразовав эти монохромные базовые глифы в цветные выполнения глифов во время отрисовки.

Зачем использовать цветовые шрифты?

Исторически дизайнеры и разработчики использовали различные методы для получения разноцветного текста. Например, веб-сайты часто используют растровые изображения вместо текста для отображения форматированных заголовков. Этот подход обеспечивает гибкость в искусстве, но растровая графика не масштабируется для всех размеров экрана и не предоставляет те же функции специальных возможностей, что и реальный текст. Другой распространенный метод — наложение нескольких монохромных шрифтов различными цветами шрифтов; но для управления этим обычно требуется дополнительный код макета.

Цветные шрифты предоставляют способ достижения этих визуальных эффектов со всей простотой и функциональностью обычных шрифтов. Текст, отображаемый цветным шрифтом, такой же, как и другой текст: его можно скопировать и вставить, проанализировать с помощью специальных возможностей и т. д.

Какие виды цветовых шрифтов поддерживает Windows?

Спецификация OpenType определяет несколько способов внедрения цветовой информации в шрифт. Начиная с Windows 10 версии 1607 (юбилейное обновление), DirectWrite и Direct2D (и созданные на них платформы Windows) поддерживают все эти подходы:

Метод Описание
COLR/Таблицы CPAL Использует слои цветных векторов, фигуры которых определяются так же, как одноцветные контуры глифов. Поддержка началась в Windows 8.1.
Таблица SVG Использует векторные изображения, созданные в формате SVG. Начиная с Windows 10 версии 1607 (юбилейное обновление) DirectWrite поддерживает подмножество полной спецификации SVG. Не все содержимое SVG гарантированно будет отображаться в шрифте OPENType SVG. Дополнительные сведения см. в разделе Поддержка SVG.
КБРТ/Таблицы CBLC Использует внедренные цветные растровые изображения.
таблица sbix Использует внедренные цветные растровые изображения.

Использование цветовых шрифтов

С точки зрения пользователя цветные шрифты — это просто шрифты. Например, их обычно можно установить и удалить из системы так же, как монохромные шрифты; и они отображаются как обычный, доступный для выбора текст.

С точки зрения разработчика цветовые шрифты обычно используются так же, как и монохромные шрифты. В платформах XAML и Microsoft Edge вы можете использовать цветные шрифты для текста так же, как обычные шрифты, и по умолчанию текст будет отображаться в цвете. Однако если приложение напрямую вызывает API Direct2D (или API Win2D) для отрисовки текста, оно должно явно запрашивать отрисовку цветного шрифта.

Использование цветовых шрифтов с DirectWrite и Direct2D

Ваше приложение может использовать более высокоуровневые методы рисования текста Direct2D (DrawText и DrawTextLayout) или использовать методы более низкого уровня для рисования запусков глифов напрямую. В любом случае приложению требуется определенный код для правильной обработки цветных глифов. Api Direct2D DrawText и DrawTextLayout не отображают цветные глифы по умолчанию. Это позволяет избежать непредвиденных изменений в поведении в приложениях для отрисовки текста, разработанных до поддержки цветовых шрифтов.

Чтобы согласиться на отрисовку цветных глифов, передайте флаг параметров D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT методу рисования. В следующем примере кода показано, как вызвать метод DrawText Direct2D для отрисовки строки цветным шрифтом:

// 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
    );

Если ваше приложение использует ИНТЕРФЕЙСы API более низкого уровня для обработки запусков глифов напрямую, оно будет продолжать работать в присутствии цветных шрифтов, но не сможет рисовать цветные глифы без дополнительной логики.

Чтобы правильно обрабатывать цветные глифы, приложение должно:

  1. Передайте сведения о выполнении глифа в TranslateColorGlyphRun вместе с параметром DWRITE_GLYPH_IMAGE_FORMATS , указывающим, какие типы цветового глифа подготовлены для обработки приложением. Если присутствуют какие-либо цветные глифы (на основе шрифта и запрошенного DWRITE_GLYPH_IMAGE_FORMATS), то DirectWrite разделит основной глиф на отдельные выполнения цветных глифов, доступ к которым можно получить через возвращенный объект IDWriteColorGlyphRunEnumerator1 на шаге 4.
  2. Проверьте HRESULT , возвращенный TranslateColorGlyphRun , чтобы определить, обнаружены ли какие-либо выполнения цветных глифов. HRESULTDWRITE_E_NOCOLOR указывает, что нет применимого выполнения цветового глифа.
  3. Если TranslateColorGlyphRun не сообщает о выполнении цветного глифа (возвращая DWRITE_E_NOCOLOR), весь запуск глифа обрабатывается как монохромный, и приложение должно рисовать его по желанию (например, с помощью ID2D1DeviceContext::D rawGlyphRun).
  4. Если TranslateColorGlyphRun сообщает о наличии выполнений цветных глифов, ваше приложение должно игнорировать выполнение основного глифа и вместо этого использовать запуски цветового глифа, возвращаемые TranslateColorGlyphRun. Для этого выполните итерацию возвращенного объекта IDWriteColorGlyphRunEnumerator1 , извлекая каждый запуск цветового глифа и рисуя его в соответствии с форматом изображения глифа (например, вы можете использовать DrawColorBitmapGlyphRun и DrawSvgGlyphRun для рисования цветных битовых глифов и SVG глифов соответственно).

В этом примере кода показана общая структура этой процедуры:

// 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; 
} 

Использование цветовых шрифтов в приложении XAML

Цветовые шрифты поддерживаются по умолчанию текстовыми элементами платформы XAML, такими как TextBlock, TextBox, RichEditBox, Глифы и FontIcon. Вы просто начертите текст с помощью цветового шрифта, и все цветные глифы будут отображаться в цвете.

В следующем синтаксисе показан один из способов оформления TextBlock с помощью цветового шрифта, упаковав его в приложение. Тот же метод применяется к обычным шрифтам.

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

Если вы хотите, чтобы текстовый элемент XAML никогда не отображал многоцветный текст, присвойте свойству falseIsColorFontEnabledProperty значение .

Совет

Приведенные выше ссылки относятся к версиям WinUI 3 этих элементов управления XAML. Эквиваленты универсальная платформа Windows (UWP) можно найти в пространстве имен Windows.UI.Xaml.Controls.

Использование цветовых шрифтов в Microsoft Edge

Цветовые шрифты отображаются по умолчанию на веб-сайтах и в веб-приложениях, работающих в Microsoft Edge, включая элемент управления XAML WebView2 . Просто используйте HTML и CSS для оформления текста с помощью цветного шрифта, а любые цветные глифы будут отображаться в цвете.

Использование цветовых шрифтов с Win2D

Как и в Direct2D, API-интерфейсы рисования текста Win2D не отображают цветные глифы по умолчанию. Чтобы согласиться на отрисовку цветных глифов, установите флаг параметров EnableColorFont в объекте форматирования текста, который приложение передает методу рисования текста. В следующем примере кода показано, как отобразить строку цветным шрифтом с помощью 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
    );