カラー フォントのサポート

このトピックでは、カラー フォント、DirectWriteおよび Direct2D でのサポート (およびその他のフレームワーク)、およびアプリでそれらを使用する方法について説明します。

カラー フォントとは

既定では、グリフは図形を持ちますが、固有の色はありません。 DirectWriteと Direct2D の両方に DrawGlyphRun メソッドがあり、指定したテキスト色でグリフ図形を塗りつぶしてグリフの実行をレンダリングします。 便宜上、 モノクロ グリフ レンダリングと言います。 すべてのフォントにモノクロ グリフがあります。 一方、カラー フォントには、一部のグリフの色表現もあります。 また、グリフを色でレンダリングするには、モノクロ の DrawGlyphRun メソッドを呼び出す代わりに、アプリでさまざまなグリフ レンダリング API を使用する必要があります (説明します)。

カラー フォントは、多色フォントまたは色フォントとも呼ばれます。 フォント デザイナーが各グリフ内で複数の色を使用できるようにするフォント テクノロジです。 カラー フォントを使用すると、テキスト レンダリング システムの上に実装されたアドホック手法よりもコードが少なく、オペレーティング システムのサポートが堅牢なアプリや Web サイトで多色のテキスト シナリオが可能になります。

ほとんどのユーザーが使い慣れているフォントは、カラー フォント ではありません 。 このようなフォントは、グリフに含まれるグリフの形状のみを定義します。ベクトル アウトラインまたは単色ビットマップを使用します。 描画時に、テキスト レンダラーは、レンダリングされるアプリまたはドキュメントで指定された単一の色 (フォントの色) を使用してグリフ図形を塗りつぶします。 一方、色フォントには、図形情報 に加えて 色情報が含まれます。 一部の方法では、フォント デザイナーが複数のカラー パレットを提供し、色フォントの芸術的柔軟性を提供できます。

Segoe UI 絵文字の色フォントのグリフを次に示します。 グリフは、左側にモノクロ、右側に色でレンダリングされます。

横並びのグリフを表示します。左のグリフはモノクロでレンダリングされ、右は Segoe U I Emoji カラー フォントで表示されます。

通常、カラー フォントには、サポートされていないプラットフォームや、カラー機能が無効になっているシナリオのフォールバック情報が含まれます。 これらのプラットフォームでは、カラー フォントは通常の単色フォントとしてレンダリングされます。

カラー フォントのサポートはグリフ レンダリング レベルで実装されるため、テキスト レイアウトには影響しません。 これは、 IDWriteTextLayout インターフェイスを使用するか、独自のテキスト レイアウト アルゴリズムを実装するかに関係なく当てはまります。 文字とグリフのマッピング、およびそれらのグリフの配置はすべて、モノクログリフ ID とそれに関連するメトリックを使用します。 テキスト レイアウト プロセスの出力は、モノクロ グリフ実行のシーケンスです。 また、カラー フォントのサポートを有効にするには、これらのモノクロ ベース グリフの実行をレンダリング時にカラー グリフの実行に変換します。

カラー フォントを使用する理由

これまで、デザイナーと開発者は、多色テキストを実現するためにさまざまな手法を使用してきました。 たとえば、Web サイトでは多くの場合、リッチ ヘッダーを表示するためにテキストではなくラスター イメージが使用されます。 このアプローチにより、芸術的な柔軟性が可能になりますが、ラスター グラフィックスはすべての表示サイズに合わせて適切にスケーリングされるわけではなく、実際のテキストと同じアクセシビリティ機能も提供しません。 もう 1 つの一般的な手法は、複数の単色フォントを異なるフォントの色でオーバーレイすることです。ただし、通常は管理する追加のレイアウト コードが必要です。

カラー フォントは、通常のフォントのすべてのシンプルさと機能を使用して、これらの視覚効果を実現する方法を提供します。 カラー フォントでレンダリングされるテキストは、他のテキストと同じです。コピーと貼り付け、アクセシビリティ ツールで解析できます。

Windows でサポートされているカラー フォントの種類は何ですか?

OpenType 仕様では、フォントに色情報を埋め込むいくつかの方法が定義されています。 Windows 10以降、バージョン 1607 (Anniversary Update)、DirectWrite、Direct2D (およびそれらに基づいて構築された Windows フレームワーク) では、次のすべてのアプローチがサポートされています。

手法 説明
COLR/CPAL テーブル 単色グリフのアウトラインと同じ方法で図形が定義されている、色付きベクターのレイヤーを使用します。 Windows 8.1でサポートが開始されました。
SVG テーブル スケーラブル ベクター グラフィックス (SVG) 形式で作成されたベクター イメージを使用します。 Windows 10バージョン 1607 (Anniversary Update) の時点で、DirectWriteは完全な SVG 仕様のサブセットをサポートしています。すべての SVG コンテンツが OpenType SVG フォントでレンダリングされるとは限りません。 詳細については、 SVG のサポートに関するページを参照してください。
CBDT/CBLC テーブル 埋め込まれたカラー ビットマップ イメージを使用します。
sbix テーブル 埋め込まれたカラー ビットマップ イメージを使用します。

カラー フォントの使用

ユーザーの観点から見ると、カラー フォントは単なるフォントです。 たとえば、通常、単色フォントと同じ方法でシステムからインストールおよびアンインストールできます。また、通常の選択可能なテキストとしてレンダリングされます。

開発者の観点からも、カラー フォントは通常、単色フォントと同じように使用されます。 XAML および Microsoft Edge フレームワークでは、通常のフォントと同じ方法で色フォントを使用してテキストのスタイルを設定できます。既定では、テキストは色でレンダリングされます。 ただし、アプリが直接 Direct2D API (または Win2D API) を呼び出してテキストをレンダリングする場合は、明示的にカラー フォントレンダリングを要求する必要があります。

DirectWriteと Direct2D でのカラー フォントの使用

アプリでは、Direct2D の上位レベルのテキスト描画メソッド (DrawTextDrawTextLayout) を使用することも、下位レベルの手法を使用してグリフの実行を直接描画することもできます。 どちらの場合も、アプリでは、カラー グリフを正しく処理するために特定のコードが必要です。 Direct2D の DrawText API と DrawTextLayout API では、既定ではカラー グリフはレンダリングされません。 これは、色フォントのサポートの前に設計されたテキスト レンダリング アプリで予期しない動作の変更を回避するためです。

カラー グリフレンダリングをオプトインするには、 D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT オプション フラグを描画メソッドに渡します。 次のコード例は、Direct2D の 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 を使用してグリフの実行を直接処理する場合は、カラー フォントの存在下で引き続き機能しますが、追加のロジックがないと色グリフを描画できなくなります。

カラー グリフを正しく処理するには、アプリで次の操作を行う必要があります。

  1. グリフ実行情報を TranslateColorGlyphRun に渡し、アプリで処理する準備ができているカラー グリフの種類を示す DWRITE_GLYPH_IMAGE_FORMATS パラメーターと共に渡します。 (フォントと要求されたDWRITE_GLYPH_IMAGE_FORMATSに基づいて) カラー グリフが存在する場合、DirectWriteはプライマリ グリフ実行を個々のカラー グリフ実行に分割します。これは、手順 4 で返される IDWriteColorGlyphRunEnumerator1 オブジェクトを介してアクセスできます。
  2. TranslateColorGlyphRun によって返される HRESULT を調べて、カラー グリフの実行が検出されたかどうかを確認します。 DWRITE_E_NOCOLORHRESULT は、適用可能なカラー グリフの実行がないことを示します。
  3. TranslateColorGlyphRun が (DWRITE_E_NOCOLORを返すことによって) カラー グリフの実行を報告しない場合、グリフ実行全体が単色として扱われ、アプリで必要に応じて描画されます (たとえば、ID2D1DeviceContext::D rawGlyphRun を使用)。
  4. TranslateColorGlyphRun がカラー グリフの実行の存在を報告する場合、アプリはプライマリ グリフの実行を無視し、代わりに TranslateColorGlyphRun によって返されるカラー グリフの実行を使用する必要があります。 これを行うには、返された 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, 
        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 プラットフォームのテキスト要素 ( TextBlockTextBoxRichEditBoxGlyphsFontIcon など) で既定でサポートされています。 テキストのスタイルを色フォントで設定するだけで、色のグリフはすべて色でレンダリングされます。

次の構文は、アプリにパッケージ化された色フォントで TextBlock のスタイルを設定する 1 つの方法を示しています。 通常のフォントにも同じ手法が適用されます。

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

XAML テキスト要素で多色テキストをレンダリング しない 場合は、 その IsColorFontEnabledProperty プロパティを に false設定します。

ヒント

上記のリンクは、これらの XAML コントロールの WinUI 3 バージョンへのリンクです。 windows.UI.Xaml.Controls 名前空間には、ユニバーサル Windows プラットフォーム (UWP) と同等のものがあります。

Microsoft Edge でのカラー フォントの使用

色フォントは、XAML WebView2 コントロールを含め、Microsoft Edge で実行されている Web サイトと Web アプリで既定でレンダリングされます。 HTML と CSS を使用してテキストのスタイルをカラー フォントで設定するだけで、色のグリフが色でレンダリングされます。

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