Dela via


Stöd för färgteckensnitt

Det här avsnittet beskriver färgteckensnitt, deras stöd i DirectWrite och Direct2D (och några andra ramverk) och hur du använder dem i din app.

Vad är färgteckensnitt?

Som standard har en glyf en form men ingen inbyggd färg. Både DirectWrite och Direct2D har DrawGlyphRun metoder som återger glyph-körningar genom att fylla glyph-formerna med en angiven textfärg. För enkelhetens skull refererar vi till det som monokrom glyph-återgivning. Alla teckensnitt har monokroma glyfer. Ett färgteckensnitt har å andra sidan också färgrepresentationer av vissa tecken. Och för att återge glyfer i färg måste appen använda olika API:er för glyph-rendering (som vi diskuterar), i stället för att anropa de monokroma DrawGlyphRun- metoder.

Färgteckensnitt kallas även för flerfärgade teckensnitt eller kromatiska teckensnitt. De är en teckensnittsteknik som gör att teckensnittsdesigners kan använda flera färger inom varje tecken. Färgteckensnitt möjliggör flerfärgade textscenarier i appar och webbplatser med mindre kod och mer robust operativsystemstöd än ad hoc-tekniker som implementeras ovanför textrenderingssystemet.

De teckensnitt som de flesta av oss är bekanta med är inte färgteckensnitt. Sådana teckensnitt definierar endast formen på de glyfer som de innehåller. antingen med vektordispositioner eller monokromatiska bitmappar. Vid dragningen fyller en textåtergivning formen med hjälp av en enda färg (teckenfärgen) som anges av appen eller dokumentet som återges. Färgteckensnitt innehåller å andra sidan färginformation utöver forminformation. Vissa metoder gör det möjligt för teckensnittsdesigners att erbjuda flera färgpaletter, vilket ger den konstnärliga flexibiliteten för färgteckensnitt.

Här är en glyph från färgteckensnittet Segoe UI Emoji. Glyfen återges i monokromt till vänster och i färg till höger.

Visar glyfer sida vid sida, den vänstra glyfen renderad i monokrom, höger i färgteckensnittet Segoe U I Emoji.

Färgteckensnitt innehåller vanligtvis återställningsinformation för plattformar som inte stöder dem, eller för scenarier där färgfunktioner har inaktiverats. På dessa plattformar återges färgteckensnitt som vanliga monokromatiska teckensnitt.

Eftersom stöd för färgteckensnitt implementeras på glyph-återgivningsnivå påverkar det inte textlayouten. Och det stämmer oavsett om du använder gränssnittet IDWriteTextLayout eller om du implementerar din egen textlayoutalgoritm. Mappningen av tecken till glyfer och placering av dessa glyfer använder alla monokroma glyph-ID:n och deras associerade mått. Utdata från textlayoutprocessen är en sekvens med monokroma glyfkörningar. Och sedan kan stöd för färgteckensnitt aktiveras genom att översätta de monokroma bas- glyph-körningar till färgglyfer körs vid återgivningstiden.

Varför ska du använda färgteckensnitt?

Tidigare har designers och utvecklare använt en mängd olika tekniker för att uppnå flerfärgad text. Webbplatser använder till exempel ofta rasterbilder i stället för text för att visa rtf-rubriker. Den metoden möjliggör konstnärlig flexibilitet, men rastergrafiken skalas inte så bra till alla visningsstorlekar, och de ger inte heller samma hjälpmedelsfunktioner som verklig text. En annan vanlig teknik är att lägga över flera monokromatiska teckensnitt i olika teckensnittsfärger. men det kräver vanligtvis extra layoutkod för att hantera.

Färgteckensnitt erbjuder ett sätt att uppnå dessa visuella effekter med all enkelhet och funktionalitet hos vanliga teckensnitt. Text som återges i ett färgteckensnitt är samma som annan text: den kan kopieras och klistras in, den kan parsas med hjälpmedelsverktyg och så vidare.

Vilka typer av färgteckensnitt stöder Windows?

OpenType-specifikationen definierar flera sätt att bädda in färginformation i ett teckensnitt. Från och med Windows 10, version 1607 (Anniversary Update), DirectWrite och Direct2D (och De Windows-ramverk som bygger på dem) stöder alla dessa metoder:

Teknik Beskrivning
COLR/CPAL- tabeller Använder lager av färgade vektorer, vars former definieras på samma sätt som enfärgsglyfkonturer. Supporten startades i Windows 8.1.
SVG- tabell Använder vektorbilder som skapats i SVG-formatet (Scalable Vector Graphics). Från och med Windows 10 version 1607 (Anniversary Update) stöder DirectWrite en delmängd av den fullständiga SVG-specifikationen. Det är inte säkert att allt SVG-innehåll återges i ett OpenType SVG-teckensnitt. Mer information finns i SVG-stöd.
CBDT-tabeller/CBLC Använder inbäddade bitmappsbilder i färg.
sbix tabell Använder inbäddade bitmappsbilder i färg.

Använda färgteckensnitt

Från användarens perspektiv är färgteckensnitt bara teckensnitt. De kan till exempel vanligtvis installeras och avinstalleras från systemet på samma sätt som monokromatiska teckensnitt kan. och de återges som vanlig, valbar text.

Från utvecklarens perspektiv används vanligtvis färgteckensnitt på samma sätt som monokromatiska teckensnitt. I XAML- och Microsoft Edge-ramverken kan du formatera texten med färgteckensnitt på samma sätt som med vanliga teckensnitt, och som standard återges texten i färg. Men om appen direkt anropar Direct2D-API:er (eller Win2D-API:er) för att återge text måste den uttryckligen begära färgteckensnittsåtergivning.

Använda färgteckensnitt med DirectWrite och Direct2D

Appen kan använda Direct2D:s textritningsmetoder på högre nivå (DrawText och DrawTextLayout), eller använda tekniker på lägre nivå för att rita glyph-körningar direkt. I båda fallen kräver din app specifik kod för att kunna hantera färgglyfer korrekt. Direct2D:s DrawText och DrawTextLayout API:er återger inte färgglyfer som standard. Det är för att undvika oväntade beteendeändringar i textrenderingsappar som har utformats före stöd för färgteckensnitt.

Om du vill välja färgglyph-återgivning skickar du flaggan D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT alternativ till ritningsmetoden. I följande kodexempel visas hur du anropar Metoden DrawText i Direct2D för att återge en sträng i ett färgteckensnitt:

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

Om appen använder API:er på lägre nivå för att hantera glyfkörningar direkt fortsätter den att fungera i närvaro av färgteckensnitt, men den kan inte rita färgglyfer utan ytterligare logik.

Om du vill hantera färgglyfer korrekt bör din app:

  1. Skicka glyph-körningsinformationen till TranslateColorGlyphRun, tillsammans med en DWRITE_GLYPH_IMAGE_FORMATS-parameter som anger vilka typer av färgglyf som appen är beredd att hantera. Om det finns några färgglyfer (baserat på teckensnittet och den begärda DWRITE_GLYPH_IMAGE_FORMATS) delar DirectWrite upp den primära glyph-körningen i enskilda färgglyfkörningar som kan nås via den returnerade IDWriteColorGlyphRunEnumerator1 objekt i steg 4.
  2. Kontrollera HRESULT- som returneras av TranslateColorGlyphRun för att avgöra om några färgglyfkörningar har identifierats. En HRESULT- av DWRITE_E_NOCOLOR anger att det inte finns någon tillämplig färgglyfkörning.
  3. Om TranslateColorGlyphRun inte rapporterar några färgglyfkörningar (genom att returnera DWRITE_E_NOCOLOR) behandlas hela glyph-körningen som monokromatisk och appen bör rita den som önskat (till exempel med hjälp av ID2D1DeviceContext::D rawGlyphRun).
  4. Om TranslateColorGlyphRun rapporterar förekomsten av färgglyfkörningar bör appen ignorera den primära glyph-körningen och i stället använda de färgglyfkörningar som returneras av TranslateColorGlyphRun. Det gör du genom att iterera genom det returnerade IDWriteColorGlyphRunEnumerator1-objektet, hämta varje färgglyph-körning och rita den efter behov för dess glyph-bildformat (du kan till exempel använda DrawColorBitmapGlyphRun och DrawSvgGlyphRun för att rita färgbitmappsglyfer respektive SVG-glyfer).

Det här kodexemplet visar den allmänna strukturen för den här proceduren:

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

Använda färgteckensnitt i en XAML-app

Färgteckensnitt stöds som standard av XAML-plattformens textelement, till exempel TextBlock, TextBox, RichEditBox, Glyphsoch FontIcon. Du formaterar helt enkelt texten med ett färgteckensnitt, och alla färgglyfer återges i färg.

Följande syntax visar ett sätt att formatera en TextBlock- med ett färgteckensnitt som är paketerat med din app. Samma teknik gäller för vanliga teckensnitt.

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

Om du vill att XAML-textelementet ska aldrig återge flerfärgad text anger du egenskapen IsColorFontEnabledProperty till false.

Dricks

Länkarna ovan är till WinUI 3-versionerna av dessa XAML-kontroller. Du hittar UWP-motsvarigheterna (Universal Windows Platform) i Windows.UI.Xaml.Controls namnrymd.

Använda färgteckensnitt i Microsoft Edge

Färgteckensnitt återges som standard på webbplatser och webbappar som körs på Microsoft Edge, inklusive kontrollen XAML WebView2. Använd bara HTML och CSS för att formatera texten med ett färgteckensnitt, och alla färgglyfer återges i färg.

Använda färgteckensnitt med Win2D

Precis som i Direct2D återger Win2D:s API:er för textritning inte färgglyfer som standard. Om du vill välja färgglyph-återgivning anger du flaggan EnableColorFont alternativ i textformatobjektet som appen skickar till textritningsmetoden. I följande kodexempel visas hur du renderar en sträng i ett färgteckensnitt med 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
    );