什么是颜色字体?

颜色字体(也称为彩色字体或彩色字体)是一种字体技术,允许字体设计人员在每个字形中使用多种颜色。 颜色字体在应用和网站中启用多色文本方案,其代码更少,操作系统支持比在文本呈现系统之上实现的临时技术更可靠。

你可能最熟悉的字体不是颜色字体。 这些字体仅定义它们包含的字形的形状,包括矢量轮廓或单色位图。 在绘图时,文本呈现器使用单个颜色填充字形形状, (由正在呈现的应用或文档指定的字体颜色) 。 另一方面,除了形状信息之外,颜色字体还包含颜色信息。 一些方法允许字体设计人员提供多个调色板,从而提供颜色字体艺术灵活性。

以下示例显示了 Segoe UI 表情符号颜色字体中的字形。 标志符号呈现在左侧的单色和右侧的颜色。

颜色字体通常包括不支持颜色字体的平台的回退信息,或者对于禁用颜色功能的方案。 在这些平台上,颜色字体呈现为常规单色字体。

为什么使用颜色字体?

从历史上看,设计师和开发人员使用各种技术来实现彩色文本。 例如,网站通常使用光栅图像而不是文本来显示丰富的标头。 此方法可实现艺术灵活性,但光栅图形无法很好地缩放到所有显示大小,也不会提供与真实文本相同的辅助功能。 另一种常见方法是以不同的字体颜色覆盖多个单色字体,但这通常需要额外的布局代码来管理。

颜色字体提供了一种方法,通过常规字体的所有简单性和功能来实现这些视觉效果。 以颜色字体呈现的文本与其他文本相同:可以复制和粘贴文本、可通过辅助功能工具分析文本等。

Windows支持哪种颜色字体?

OpenType 规范 定义了多种在字体中嵌入颜色信息的方法。 从Windows 10周年更新开始,DirectWrite和 Direct2D (以及基于它们构建的Windows框架) 支持所有这些方法。 下表汇总了它们:

SVG 表 使用以可缩放矢量图形格式创作的矢量图像。 注意: 从Windows 10周年更新起,DirectWrite支持完整 SVG 规范的子集。并非所有 SVG 内容都保证以 OpenType SVG 字体呈现。 有关更多详细信息,请参阅 SVG 支持
CBDT / CBLC 表 使用嵌入的颜色位图图像。 sbix 表 使用嵌入的颜色位图图像。

使用颜色字体

从用户的角度来看,颜色字体只是字体。 例如,它们通常可以像单色字体一样从系统安装并卸载,并且它们呈现为常规的可选文本。

从开发人员的角度来看,颜色字体通常与单色字体相同。 在 XAML 和Microsoft Edge框架中,可以采用与常规字体相同的颜色字体设置文本的样式,默认情况下,文本将以颜色呈现。 但是,如果应用直接调用 Direct2D API (或 Win2D API) 来呈现文本,则必须显式请求颜色字体呈现。

在 XAML 应用中使用颜色字体

XAML 平台的文本元素 (,例如 TextBlock TextBox RichEditBox Glyphs FontIcon ) 默认支持颜色字体。 只需使用颜色字体设置文本的样式,任何颜色字形将以颜色呈现。 下面的代码示例演示了一种方法,其中一种方法是使用与应用打包的颜色字体设置 TextBlock 样式。 相同的技术适用于常规字体。

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

如果不希望 XAML 文本元素呈现多色文本,请将其 IsColorFontEnabledProperty 属性设置为 false。

在 Microsoft Edge 中使用颜色字体

默认情况下,颜色字体在Microsoft Edge上运行的网站和 Web 应用中呈现,包括 XAML WebView 控件。 只需使用 HTML 和 CSS 为文本设置颜色字体的样式,任何颜色字形将以颜色呈现。

将颜色字体与 DirectWrite 和 Direct2D 配合使用

你的应用可以使用 Direct2D 的高级文本绘图方法 (DrawText 和 DrawTextLayout) ,也可以使用较低级别的技术直接绘制字形运行。 无论哪种情况,你的应用都需要更改代码才能正确处理颜色字形。 如果应用使用 Direct2D s DrawText 和 DrawTextLayout API,请注意,这些 API 默认不呈现颜色字形。 这是为了避免在颜色字体支持之前设计的文本呈现应用中出现意外的行为更改。

若要选择颜色字形呈现,请将 D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT 选项标志传递给绘图方法。 下面的代码示例演示如何调用 Direct2D s DrawText 方法以颜色字体呈现字符串:

// 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 直接处理字形运行,则它将继续在存在颜色字体的情况下正常运行,但它将无法在没有其他逻辑的情况下绘制颜色字形。

若要正确处理颜色标志符号,应用应:

  • 将字形运行信息传递给 TranslateColorGlyphRun,以及一个 DWRITE_GLYPH_IMAGE_FORMATS 参数,该参数指示应用准备处理的颜色标志符号 () 的类型。 如果根据字体和请求的DWRITE_GLYPH_IMAGE_FORMATS) (存在任何颜色字形,则DirectWrite将主要字形拆分为单个颜色字形运行,可通过步骤 4 中返回的 IDWriteColorGlyphRunEnumerator 对象访问。
  • 检查 TranslateColorGlyphRun 返回的 HRESULT,以确定是否检测到任何颜色字形运行。 DWRITE_E_NOCOLORHRESULT 指示没有适用的颜色标志符号运行。
  • 如果 TranslateColorGlyphRun 通过返回 DWRITE_E_NOCOLOR) 没有报告颜色字形运行 (,则整个字形运行被视为单色,并且你的应用应根据需要绘制它 (,例如,使用 ID2D1DeviceContext::D rawGlyphRun) 。
  • 如果 TranslateColorGlyphRun 确实报告颜色字形运行的状态,则应用应忽略主字形运行,而是使用 TranslateColorGlyphRun 返回的颜色字形运行 (s) 。 为此,请循环访问返回的 IDWriteColorGlyphRunEnumerator1 对象,检索每个颜色字形运行,并根据需要绘制其字形图像格式 (例如,可以使用 DrawColorBitmapGlyphRunDrawSvgGlyphRun 分别绘制颜色位图字形和 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, 
            &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. 
            // 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; 
    

    将颜色字体与 Win2D 配合使用

    与 Direct2D 类似,默认情况下,Win2D 的文本绘图 API 不会呈现颜色字形。 若要选择颜色字形呈现,请在应用传递给文本绘图方法的文本格式对象中设置 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 
    

    DirectWrite彩色字形示例

    IDWriteFontFace4 接口

    IDWriteFactory4::TranslateColorGlyphRun 方法

    ID2D1DeviceContext4::D rawText 方法