Bagikan melalui


Dukungan font warna

Topik ini menjelaskan font warna, dukungannya di DirectWrite dan Direct2D (dan beberapa kerangka kerja lainnya), dan cara menggunakannya di aplikasi Anda.

Apa itu font warna?

Secara default, glyph memiliki bentuk tetapi tidak ada warna intrinsik. Baik DirectWrite maupun Direct2D memiliki metode DrawGlyphRun yang merender eksekusi glyph dengan mengisi bentuk glyph dengan warna teks tertentu. Untuk kenyamanan, kita akan menyebutnya sebagai rendering glyph monokrom . Semua font memiliki glefel monokrom. Font warna, di sisi lain, juga memiliki representasi warna dari beberapa glyph. Dan untuk merender glyph berwarna, aplikasi Anda harus menggunakan API penyajian glyph yang berbeda (seperti yang akan kita bahas), alih-alih memanggil metode DrawGlyphRun monokrom.

Font warna juga disebut sebagai font multiwarna atau font klormatik. Ini adalah teknologi font yang memungkinkan perancang font untuk menggunakan beberapa warna dalam setiap glyph. Font warna memungkinkan skenario teks multiwarna di aplikasi dan situs web dengan kode yang lebih sedikit dan dukungan sistem operasi yang lebih kuat daripada teknik ad-hoc yang diterapkan di atas sistem penyajian teks.

Font yang kebanyakan kita kenal bukan font warna. Font seperti itu hanya mendefinisikan bentuk glyph yang dikandungnya; baik dengan kerangka vektor atau bitmap monokromatik. Pada waktu gambar, perender teks mengisi bentuk glyph menggunakan satu warna (warna font) yang ditentukan oleh aplikasi atau dokumen yang sedang dirender. Font warna, di sisi lain, berisi informasi warna selain informasi bentuk. Beberapa pendekatan memungkinkan perancang font untuk menawarkan beberapa palet warna, memberikan fleksibilitas artistik font warna.

Berikut adalah glyph dari font warna Segoe UI Emoji. Glyph dirender dalam monokrom di sebelah kiri, dan berwarna di sebelah kanan.

Memperlihatkan glyph berdampingan, glyph kiri yang dirender dalam monokrom, kanan di font warna Segoe U I Emoji.

Font warna biasanya menyertakan informasi fallback untuk platform yang tidak mendukungnya, atau untuk skenario di mana fungsionalitas warna telah dinonaktifkan. Pada platform tersebut, font warna dirender sebagai font monokromatik biasa.

Karena dukungan font warna diimplementasikan pada tingkat penyajian glyph, itu tidak mempengaruhi tata letak teks. Dan itu benar apakah Anda menggunakan antarmuka IDWriteTextLayout , atau apakah Anda menerapkan algoritma tata letak teks Anda sendiri. Pemetaan karakter ke glyph, dan posisi glyph tersebut, semuanya menggunakan ID glyph monokrom dan metrik terkait. Output dari proses tata letak teks adalah urutan eksekusi glyph monokrom. Dan kemudian dukungan font warna dapat diaktifkan dengan menerjemahkan eksekusi glyph dasar monokrom tersebut ke glyph warna berjalan pada waktu penyajian.

Mengapa menggunakan font warna?

Secara historis, desainer dan pengembang telah menggunakan berbagai teknik untuk mencapai teks beraneka warna. Misalnya, situs web sering menggunakan gambar raster alih-alih teks untuk menampilkan header kaya. Pendekatan itu memungkinkan fleksibilitas artistik, tetapi grafik raster tidak menskalakan dengan baik ke semua ukuran tampilan, dan juga tidak menyediakan fitur aksesibilitas yang sama dengan teks nyata. Teknik umum lainnya adalah melapisi beberapa font monokromatik dalam warna font yang berbeda; tetapi biasanya memerlukan kode tata letak tambahan untuk dikelola.

Font warna menawarkan cara untuk mencapai efek visual tersebut dengan semua kesederhanaan dan fungsionalitas font reguler. Teks yang dirender dalam font warna sama dengan teks lain: teks dapat disalin dan ditempelkan, dapat diurai oleh alat aksesibilitas, dan sebagainya.

Jenis font warna apa yang didukung Windows?

Spesifikasi OpenType menentukan beberapa cara untuk menyematkan informasi warna dalam font. Mulai Windows 10, versi 1607 (Pembaruan Hari Jadi), DirectWrite dan Direct2D (dan kerangka kerja Windows yang dibangun di atasnya) mendukung semua pendekatan ini:

Teknik Deskripsi
COLR/Tabel CPAL Menggunakan lapisan vektor berwarna, yang bentuknya didefinisikan dengan cara yang sama seperti kerangka glyph warna tunggal. Dukungan dimulai di Windows 8.1.
Tabel SVG Menggunakan gambar vektor yang ditulis dalam format Scalable Vector Graphics (SVG). Pada Windows 10, versi 1607 (Anniversary Update), DirectWrite mendukung subset spesifikasi SVG lengkap. Tidak semua konten SVG dijamin akan dirender dalam font OpenType SVG. Untuk detail selengkapnya, lihat dukungan SVG.
CBDT/Tabel CBLC Menggunakan gambar bitmap warna yang disematkan.
tabel sbix Menggunakan gambar bitmap warna yang disematkan.

Menggunakan font warna

Dari perspektif pengguna, font warna hanyalah font. Misalnya, mereka biasanya dapat diinstal dan dihapus instalannya dari sistem dengan cara yang sama seperti font monokromatik; dan dirender sebagai teks biasa yang dapat dipilih.

Dari perspektif pengembang juga, font warna biasanya digunakan dengan cara yang sama seperti font monokromatik. Dalam kerangka kerja XAML dan Microsoft Edge, Anda dapat menata teks dengan font warna dengan cara yang sama seperti font biasa, dan secara default teks Anda akan dirender dalam warna. Namun, jika aplikasi Anda langsung memanggil API Direct2D (atau API Win2D) untuk merender teks, aplikasi harus secara eksplisit meminta penyajian font warna.

Menggunakan font warna dengan DirectWrite dan Direct2D

Aplikasi Anda dapat menggunakan metode gambar teks tingkat lebih tinggi Direct2D (DrawText dan DrawTextLayout), atau dapat menggunakan teknik tingkat bawah untuk menggambar eksekusi glyph secara langsung. Dalam kedua kasus, aplikasi Anda memerlukan kode tertentu untuk menangani glyph warna dengan benar. API DrawText dan DrawTextLayout Direct2D tidak merender glyph warna secara default. Itu untuk menghindari perubahan perilaku tak terduga dalam aplikasi penyajian teks yang dirancang sebelum dukungan font warna.

Untuk ikut serta dalam penyajian glyph warna, teruskan bendera opsi D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT ke metode menggambar. Contoh kode berikut menunjukkan cara memanggil metode DrawText Direct2D untuk merender string dalam font warna:

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

Jika aplikasi Anda menggunakan API tingkat bawah untuk menangani eksekusi glyph secara langsung, aplikasi akan terus berfungsi di hadapan font warna, tetapi tidak akan dapat menggambar glyph warna tanpa logika tambahan.

Untuk menangani glyph warna dengan benar, aplikasi Anda harus:

  1. Teruskan informasi eksekusi glyph ke TranslateColorGlyphRun, bersama dengan parameter DWRITE_GLYPH_IMAGE_FORMATS yang menunjukkan jenis glyph warna mana yang disiapkan untuk ditangani oleh aplikasi. Jika ada glyph warna yang ada (berdasarkan font dan DWRITE_GLYPH_IMAGE_FORMATS yang diminta), maka DirectWrite akan membagi glyph utama yang dijalankan menjadi eksekusi glyph warna individual, yang dapat diakses melalui objek IDWriteColorGlyphRunEnumerator1 yang dikembalikan di Langkah 4.
  2. Periksa HRESULT yang dikembalikan oleh TranslateColorGlyphRun untuk menentukan apakah ada eksekusi glyph warna yang terdeteksi. HRESULTDWRITE_E_NOCOLOR menunjukkan bahwa tidak ada eksekusi glyph warna yang berlaku.
  3. Jika TranslateColorGlyphRun melaporkan tidak ada glyph warna yang berjalan (dengan mengembalikan DWRITE_E_NOCOLOR), maka seluruh eksekusi glyph diperlakukan sebagai monokromatik, dan aplikasi Anda harus menggambarnya seperti yang diinginkan (misalnya, menggunakan ID2D1DeviceContext::D rawGlyphRun).
  4. Jika TranslateColorGlyphRun melaporkan keberadaan eksekusi glyph warna, maka aplikasi Anda harus mengabaikan eksekusi glyph utama, dan sebaliknya menggunakan eksekusi glyph warna yang dikembalikan oleh TranslateColorGlyphRun. Untuk melakukannya, iterasi melalui objek IDWriteColorGlyphRunEnumerator1 yang dikembalikan, mengambil setiap eksekusi glyph warna, dan menggambarnya sesuai dengan format gambar glyph -nya (misalnya, Anda dapat menggunakan DrawColorBitmapGlyphRun dan DrawSvgGlyphRun untuk menggambar glyph bitmap warna dan glyph SVG, masing-masing).

Contoh kode ini menunjukkan struktur umum prosedur ini:

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

Menggunakan font warna di aplikasi XAML

Font warna didukung secara default oleh elemen teks platform XAML—seperti TextBlock, TextBox, RichEditBox, Glyphs, dan FontIcon. Anda cukup menata teks Anda dengan font warna, dan setiap glyph warna akan dirender dalam warna.

Sintaks berikut menunjukkan salah satu cara untuk menata TextBlock dengan font warna yang dikemas dengan aplikasi Anda. Teknik yang sama berlaku untuk font reguler.

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

Jika Anda ingin elemen teks XAML Anda tidak pernah merender teks multiwarna, maka atur properti IsColorFontEnabledProperty ke false.

Tip

Tautan di atas adalah ke versi WinUI 3 dari kontrol XAML tersebut. Anda dapat menemukan Platform Windows Universal (UWP) yang setara di namespace Layanan Windows.UI.Xaml.Controls.

Menggunakan font warna di Microsoft Edge

Font warna dirender secara default di situs web dan aplikasi web yang berjalan di Microsoft Edge, termasuk kontrol XAML WebView2 . Cukup gunakan HTML dan CSS untuk menata teks Anda dengan font warna, dan setiap glyph warna akan dirender dalam warna.

Menggunakan font warna dengan Win2D

Mirip dengan Direct2D, API gambar teks Win2D tidak merender glyph warna secara default. Untuk ikut serta dalam penyajian glyph warna, atur bendera opsi EnableColorFont dalam objek format teks yang diteruskan aplikasi Anda ke metode gambar teks. Contoh kode berikut menunjukkan cara merender string dalam font warna menggunakan 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
    );