色彩字型支援
本主題描述色彩字型、在 DirectWrite 和 Direct2D 中的支援(以及其他一些架構),以及如何在應用程式中使用這些字型。
什麼是色彩字型?
根據預設,圖像具有圖形,但沒有內建色彩。 DirectWrite 和 Direct2D 都有 DrawGlyphRun 方法,這些方法會藉由以指定的文字色彩填滿字元圖形,以執行圖像。 為了方便起見,我們將這稱為 單色 圖像轉譯。 所有字型都有單色圖像。 另一方面,色彩字型也有一些圖像的色彩表示。 若要以色彩呈現圖像,您的應用程式必須使用不同的圖像轉譯 API(如我們將討論),而不是呼叫單色 DrawGlyphRun 方法。
色彩字型也稱為彩色字型或色度字型。 它們是一種字型技術,可讓字型設計工具在每個圖像中使用多個色彩。 色彩字型在應用程式和網站中啟用多色文字案例,其程式代碼和作系統支援比文字轉譯系統上方實作的臨機作技術更強固。
我們大多數人熟悉的字型 不是 色彩字型。 這類字型只會定義其包含之圖像的形狀;使用向量外框或單色位圖。 在繪製時,文字轉譯器會使用應用程式或檔所指定的單一色彩(字型色彩)填滿圖像圖形。 另一方面,色彩字型除了 圖形資訊之外,還包含色彩資訊。 某些方法可讓字型設計工具提供多個調色盤,提供色彩字型藝術彈性。
以下是來自 Segoe UI Emoji 色彩字型的字元。 圖像會以左邊的單色和右邊的色彩呈現。
色彩字型通常會包含不支持這些字型的平臺後援資訊,或針對已停用色彩功能的案例。 在這些平臺上,色彩字型會轉譯為一般單色字型。
因為色彩字型支援是在圖像轉譯層級實作,所以不會影響文字版面配置。 而不論您使用 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 支援。 |
CBT/CBLC 數據表 | 使用內嵌的色彩點陣圖影像。 |
sbix 數據表 | 使用內嵌的色彩點陣圖影像。 |
使用色彩字型
從用戶的觀點來看,色彩字型只是字型。 例如,它們通常可以透過與單色字型相同的方式,從系統安裝及卸載;而且會轉譯為一般、可選取的文字。
從開發人員的觀點來看,色彩字型通常與單色字型相同。 在 XAML 和 Microsoft Edge 架構中,您可以使用與一般字型相同的方式來設定文字的樣式,而且您的文字預設會以色彩呈現。 不過,如果您的應用程式直接呼叫 Direct2D API(或 Win2D API)來轉譯文字,則必須明確要求色彩字型轉譯。
搭配 DirectWrite 和 Direct2D 使用色彩字型
您的應用程式可以使用 Direct2D 的高階文字繪圖方法(DrawText 和 DrawTextLayout),也可以使用較低層級的技術直接繪製圖像執行。 不論是哪一種情況,您的應用程式都需要特定的程序代碼,才能正確處理色彩圖像。 Direct2D 的 DrawText 和 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
);
如果您的 app 使用較低層級的 API 直接處理圖像執行,則它會繼續在色彩字型存在的情況下運作,但若沒有額外的邏輯,就無法繪製色彩圖像。
若要正確處理色彩圖像,您的應用程式應該:
- 將圖像執行資訊傳遞至 TranslateColorGlyphRun,以及 DWRITE_GLYPH_IMAGE_FORMATS 參數,指出應用程式準備處理的色彩圖像類型。 如果有任何色彩圖像存在(根據字型和所要求的 DWRITE_GLYPH_IMAGE_FORMATS),DirectWrite 會將主要字元分割成個別的色彩圖像執行,這可以透過步驟 4 中的傳回 IDWriteColorGlyphRunEnumerator1 物件來存取。
- 檢查 translateColorGlyphRun 所傳回 HRESULT,以判斷是否偵測到任何色彩字元執行。 HRESULTDWRITE_E_NOCOLOR 表示沒有適用的色彩字元執行。
- 如果 TranslateColorGlyphRun 不會報告任何色彩圖像執行 (傳回 DWRITE_E_NOCOLOR),則整個字元回合會被視為單色字元,而您的應用程式應該視需要繪製它(例如,使用 ID2D1DeviceContext::D rawGlyphRun)。
- 如果 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、Glyphs,以及 FontIcon。 您只要以色彩字型設定文字的樣式,任何色彩圖像都會以色彩呈現。
下列語法顯示一種方式,將 TextBlock 樣式 與應用程式封裝的色彩字型。 相同的技術適用於一般字型。
<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 中使用色彩字型
色彩字型預設會在Microsoft Edge 上執行的網站和 Web 應用程式中呈現,包括 XAML WebView2 控件。 只要使用 HTML 和 CSS 以色彩字型設定文字的樣式,任何色彩字元都會以色彩呈現。
搭配 Win2D 使用色彩字型
與 Direct2D 類似,Win2D 的文字繪圖 API 預設不會轉譯色彩圖像。 若要選擇色彩圖像轉譯,請在應用程式傳遞至文字繪製方法的文字格式物件中,設定 EnableColorFont options 旗標。 下列程式代碼範例示範如何使用 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
);