Condividi tramite


Supporto dei tipi di carattere a colori

Questo argomento descrive i tipi di carattere a colori, il supporto in DirectWrite e Direct2D (e altri framework) e come usarli nell'app.

Che cosa sono i tipi di carattere a colori?

Per impostazione predefinita, un glifo ha una forma ma non un colore intrinseco. Sia DirectWrite che Direct2D dispongono di metodi DrawGlyphRun che eseguono il rendering del glifo riempiendo le forme del glifo con un colore di testo specificato. Per praticità, si farà riferimento a questo come rendering del glifo monocromatico . Tutti i tipi di carattere hanno glifi monocromatici. Un tipo di carattere di colore, d'altra parte, ha anche rappresentazioni di colore di alcuni glifi. Per eseguire il rendering dei glifi a colori, l'app deve usare API per il rendering dei glifi diverse (come verrà illustrato), invece di chiamare i metodi DrawGlyphRun monocromatici.

I tipi di carattere a colori sono detti anche tipi di carattere multicolore o tipi di carattere cromatici. Si tratta di una tecnologia per i tipi di carattere che consente ai progettisti di tipi di carattere di usare più colori all'interno di ogni glifo. I tipi di carattere a colori consentono scenari di testo multicolore in app e siti Web con meno codice e supporto più affidabile del sistema operativo rispetto alle tecniche ad hoc implementate sopra il sistema di rendering del testo.

I tipi di carattere che la maggior parte di noi hanno familiarità con non sono tipi di carattere a colori. Tali tipi di carattere definiscono solo la forma dei glifi che contengono; con contorni vettoriali o bitmap monocromatiche. In fase di disegno, un renderer di testo riempie la forma del glifo usando un singolo colore (il colore del carattere) specificato dall'app o dal documento di cui viene eseguito il rendering. I tipi di carattere color, invece, contengono informazioni sul colore oltre alle informazioni sulla forma. Alcuni approcci consentono ai progettisti di tipi di carattere di offrire più tavolozze di colori, offrendo la flessibilità artistica del tipo di carattere dei colori.

Ecco un glifo del tipo di carattere Segoe UI Emoji. Il rendering del glifo viene eseguito in monocromatico a sinistra e a colori a destra.

Mostra glifi affiancati, il glifo sinistro di cui è stato eseguito il rendering in monocromatico, a destra nel tipo di carattere Colore Segoe U I Emoji.

I tipi di carattere a colori in genere includono informazioni di fallback per le piattaforme che non li supportano o per gli scenari in cui la funzionalità dei colori è stata disabilitata. Su queste piattaforme, i tipi di carattere a colori vengono visualizzati come tipi di carattere monocromatici normali.

Poiché il supporto dei tipi di carattere dei colori viene implementato a livello di rendering del glifo, non influisce sul layout del testo. E questo vale se si usa l'interfaccia IDWriteTextLayout o se si implementa un algoritmo di layout di testo personalizzato. Il mapping dei caratteri ai glifi e il posizionamento di tali glifi usano tutti gli ID glifi monocromatici e le relative metriche associate. L'output del processo di layout del testo è una sequenza di esecuzioni del glifo monocromatico. È quindi possibile abilitare il supporto dei tipi di carattere colore traducendo le esecuzioni del glifo di base monocromatico in glifi a colori in fase di rendering.

Perché usare i tipi di carattere a colori?

Storicamente, i progettisti e gli sviluppatori hanno usato una varietà di tecniche per ottenere testo colorato. Ad esempio, i siti Web usano spesso immagini raster anziché testo per visualizzare intestazioni avanzate. Questo approccio consente flessibilità artistica, ma la grafica raster non è adatta a tutte le dimensioni di visualizzazione e non offre le stesse funzionalità di accessibilità del testo reale. Un'altra tecnica comune consiste nell'sovrapporre più tipi di carattere monocromatici in colori di carattere diversi; ma che in genere richiede codice di layout aggiuntivo da gestire.

I tipi di carattere a colori offrono un modo per ottenere questi effetti visivi con tutta la semplicità e la funzionalità dei tipi di carattere normali. Il rendering del testo in un carattere di colore è identico a quello di un altro testo: può essere copiato e incollato, può essere analizzato dagli strumenti di accessibilità e così via.

Quali tipi di carattere di colore supporta Windows?

La specifica OpenType definisce diversi modi per incorporare informazioni sul colore in un tipo di carattere. A partire da Windows 10, versione 1607 (aggiornamento dell'anniversario), DirectWrite e Direct2D (e i framework di Windows basati su di essi) supportano tutti questi approcci:

Tecnica Descrizione
COLR/Tabelle CPAL Utilizza livelli di vettori colorati, le cui forme sono definite nello stesso modo dei contorni a colori singoli. Supporto avviato in Windows 8.1.
Tabella SVG Usa le immagini vettoriali create nel formato SVG (Scalable Vector Graphics). A partire da Windows 10 versione 1607 (Aggiornamento dell'anniversario), DirectWrite supporta un subset della specifica SVG completa. Non è garantito il rendering di tutti i contenuti SVG in un tipo di carattere SVG OpenType. Per altre informazioni, vedere Supporto SVG.
CBDT/Tabelle CBLC Usa immagini bitmap a colori incorporate.
tabella sbix Usa immagini bitmap a colori incorporate.

Uso dei tipi di carattere a colori

Dal punto di vista dell'utente, i tipi di carattere a colori sono solo tipi di carattere. Ad esempio, in genere possono essere installati e disinstallati dal sistema nello stesso modo in cui i tipi di carattere monocromatici possono; e vengono visualizzati come testo selezionabile regolare.

Anche dal punto di vista dello sviluppatore, i tipi di carattere a colori vengono in genere usati allo stesso modo dei tipi di carattere monocromatici. Nei framework XAML e Microsoft Edge è possibile applicare stili al testo con tipi di carattere a colori nello stesso modo in cui è possibile usare i tipi di carattere normali e per impostazione predefinita verrà eseguito il rendering del testo a colori. Tuttavia, se l'app chiama direttamente api Direct2D (o API Win2D) per eseguire il rendering del testo, deve richiedere in modo esplicito il rendering del tipo di carattere a colori.

Uso dei tipi di carattere a colori con DirectWrite e Direct2D

L'app può usare i metodi di disegno di testo di livello superiore di Direct2D (DrawText eDrawTextLayout) oppure può usare tecniche di livello inferiore per disegnare direttamente le esecuzioni del glifo. In entrambi i casi, l'app richiede codice specifico per gestire correttamente i glifi dei colori. Le API DrawText e DrawTextLayout di Direct2D non eseguono il rendering dei glifi di colore per impostazione predefinita. Ciò consente di evitare modifiche impreviste al comportamento nelle app per il rendering del testo progettate prima del supporto dei tipi di carattere a colori.

Per acconsentire esplicitamente al rendering del glifo di colore, passare il flag di opzioni D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT al metodo di disegno. Nell'esempio di codice seguente viene illustrato come chiamare il metodo DrawText di Direct2D per eseguire il rendering di una stringa in un tipo di carattere a colori:

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

Se l'app usa API di livello inferiore per gestire direttamente le esecuzioni del glifo, continuerà a funzionare in presenza di tipi di carattere a colori, ma non sarà in grado di disegnare glifi di colore senza logica aggiuntiva.

Per gestire correttamente glifi di colore, l'app deve:

  1. Passare le informazioni sull'esecuzione del glifo a TranslateColorGlyphRun, insieme a un parametro DWRITE_GLYPH_IMAGE_FORMATS che indica i tipi di glifo di colore che l'app è pronta a gestire. Se sono presenti glifi di colore (in base al tipo di carattere e al DWRITE_GLYPH_IMAGE_FORMATS richiesto), DirectWrite suddividerà il glifo primario eseguito in singole esecuzioni di glifi di colore, a cui è possibile accedere tramite l'oggetto IDWriteColorGlyphRunEnumerator1 restituito nel passaggio 4.
  2. Controllare il valore HRESULT restituito da TranslateColorGlyphRun per determinare se sono state rilevate esecuzioni di glifi di colore. Un valore HRESULT di DWRITE_E_NOCOLOR indica che non è presente un'esecuzione del glifo di colore applicabile.
  3. Se TranslateColorGlyphRun non segnala esecuzioni di glifi di colore (restituendo DWRITE_E_NOCOLOR), l'intera esecuzione del glifo viene considerata monocromatica e l'app deve disegnare come desiderato (ad esempio, usando ID2D1DeviceContext::D rawGlyphRun).
  4. Se TranslateColorGlyphRun segnala la presenza di esecuzioni del glifo a colori, l'app deve ignorare l'esecuzione del glifo primario e usare invece le esecuzioni di glifi a colori restituite da TranslateColorGlyphRun. A tale scopo, scorrere l'oggetto IDWriteColorGlyphRunEnumerator1 restituito, recuperare ogni esecuzione del glifo di colore e disegnarlo come appropriato per il formato dell'immagine del glifo(ad esempio, è possibile usare DrawColorBitmapGlyphRun e DrawSvgGlyphRun per disegnare rispettivamente glifi bitmap di colore e glifi SVG).

In questo esempio di codice viene illustrata la struttura generale di questa procedura:

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

Uso dei tipi di carattere a colori in un'app XAML

I tipi di carattere color sono supportati per impostazione predefinita dagli elementi di testo della piattaforma XAML, ad esempio TextBlock, TextBox, RichEditBox, Glyphs e FontIcon. È sufficiente applicare uno stile al testo con un tipo di carattere colore e verrà eseguito il rendering di eventuali glifi di colore.

La sintassi seguente mostra un modo per applicare uno stile a un controllo TextBlock con un tipo di carattere a colori in pacchetto con l'app. La stessa tecnica si applica ai tipi di carattere normali.

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

Se vuoi che l'elemento di testo XAML non esegua mai il rendering di testo multicolore, imposta la proprietà IsColorFontEnabledProperty su false.

Suggerimento

I collegamenti precedenti sono alle versioni WinUI 3 di tali controlli XAML. Puoi trovare gli equivalenti piattaforma UWP (Universal Windows Platform) (UWP) nello spazio dei nomi Windows.UI.Xaml.Controls.

Uso dei tipi di carattere a colori in Microsoft Edge

Il rendering dei tipi di carattere colore viene eseguito per impostazione predefinita nei siti Web e nelle app Web in esecuzione in Microsoft Edge, incluso il controllo Xaml WebView2 . È sufficiente usare HTML e CSS per applicare uno stile al testo con un tipo di carattere di colore e verrà eseguito il rendering di eventuali glifi di colore.

Uso dei tipi di carattere a colori con Win2D

Analogamente a Direct2D, le API di disegno di testo win2D non eseguono il rendering dei glifi di colore per impostazione predefinita. Per acconsentire esplicitamente al rendering del glifo a colori, impostare il flag di opzioni EnableColorFont nell'oggetto formato testo che l'app passa al metodo di disegno del testo. L'esempio di codice seguente illustra come eseguire il rendering di una stringa in un tipo di carattere a colori usando 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
    );