色彩字型支援
本主題描述色彩字型、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 版 (年度更新版) 起,DirectWrite支援完整 SVG 規格的子集。並非所有 SVG 內容都保證會在 OpenType SVG 字型中轉譯。 如需詳細資訊,請參閱 SVG 支援。 |
/ 版面上CBLC資料表 | 使用內嵌色彩點陣圖影像。 |
sbix 資料表 | 使用內嵌色彩點陣圖影像。 |
使用色彩字型
從使用者的觀點來看,色彩字型只是字型。 例如,通常可以透過與單色字型相同的方式,從系統安裝及卸載它們;和 它們會轉譯為一般、可選取的文字。
從開發人員的觀點來看,色彩字型通常與單色字型相同。 在 XAML 和 Microsoft Edge 架構中,您可以使用色彩字型來設定文字樣式,就像使用一般字型一樣,而且根據預設,您的文字會以色彩呈現。 不過,如果您的 app 直接呼叫 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
);
如果您的應用程式使用較低層級的 API 直接處理圖像執行,則它會繼續在色彩字型存在的情況下運作,但無法在沒有其他邏輯的情況下繪製色彩圖像。
若要正確處理色彩圖像,您的應用程式應該:
- 將字元執行資訊傳遞至 TranslateColorGlyphRun,以及 指出 應用程式準備處理之色彩圖像) 類型 (DWRITE_GLYPH_IMAGE_FORMATS參數。 如果根據字型和要求的DWRITE_GLYPH_IMAGE_FORMATS) (出現任何色彩圖像,則DirectWrite會將主要圖像分割成個別的色彩字元執行,這可以透過傳回的IDWriteColorGlyphRunEnumerator1物件存取。
- 檢查TranslateColorGlyphRun傳回的HRESULT,以判斷是否偵測到任何色彩圖像執行。 DWRITE_E_NOCOLOR的HRESULT表示沒有適用的色彩字元執行。
- 如果 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 選項旗標。 下列程式碼範例示範如何使用 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
);