Udostępnij za pośrednictwem


Wprowadzenie do funkcji DirectWrite

Ludzie komunikują się z tekstem przez cały czas w swoim codziennym życiu. Jest to podstawowy sposób, w jaki ludzie używają coraz większej ilości informacji. W przeszłości była to treść drukowana, głównie dokumenty, gazety, książki itd. Coraz częściej jest to zawartość online na komputerze z systemem Windows. Typowy użytkownik systemu Windows spędza dużo czasu na odczytywaniu z ekranu komputera. Mogą oni surfować po Internecie, skanować pocztę e-mail, komponować raport, wypełniać arkusz kalkulacyjny lub pisać oprogramowanie, ale to, co naprawdę robi, to czytanie. Mimo że tekst i czcionki przenikają prawie każdą część środowiska użytkownika w systemie Windows, dla większości użytkowników czytanie na ekranie nie jest tak przyjemne, jak odczytywanie drukowanych danych wyjściowych.

W przypadku deweloperów aplikacji systemu Windows pisanie kodu obsługującego tekst jest wyzwaniem ze względu na zwiększone wymagania dotyczące lepszej czytelności, zaawansowanego formatowania i kontrolki układu oraz obsługę wielu języków, które musi wyświetlać aplikacja. Nawet najbardziej podstawowy system obsługi tekstu musi zezwalać na wprowadzanie tekstu, układ, wyświetlanie, edytowanie i kopiowanie i wklejanie. Użytkownicy systemu Windows często oczekują więcej niż te podstawowe funkcje, wymagają nawet prostych edytorów obsługi wielu czcionek, różnych stylów akapitu, obrazów osadzonych, sprawdzania pisowni i innych funkcji. Nowoczesny projekt interfejsu użytkownika nie jest już ograniczony do pojedynczego formatu, zwykłego tekstu, ale musi zapewnić lepsze doświadczenie z bogatymi czcionkami i formatowaniem tekstu.

Jest to wprowadzenie do tego, jak DirectWrite umożliwia aplikacjom systemu Windows ulepszenie środowiska tekstowego interfejsu użytkownika i dokumentów.

Ulepszanie środowiska tekstowego

Nowoczesne aplikacje systemu Windows mają zaawansowane wymagania dotyczące tekstu w interfejsie użytkownika i dokumentach. Obejmują one lepszą czytelność, obsługę wielu języków i skryptów oraz lepszą wydajność renderowania. Ponadto większość istniejących aplikacji wymaga sposobu przeprowadzenia istniejących inwestycji w bazę kodu WindowsWin32.

DirectWrite udostępnia następujące trzy funkcje, które umożliwiają deweloperom aplikacji systemu Windows ulepszanie środowiska tekstowego w aplikacjach: niezależność od systemu renderowania, typografii wysokiej jakości i wielu warstw funkcjonalności.

niezależność Rendering-System

DirectWrite jest niezależny od jakiejkolwiek konkretnej technologii grafiki. Aplikacje mogą korzystać z technologii renderowania najlepiej dopasowanej do ich potrzeb. Zapewnia to aplikacjom elastyczność dalszego renderowania niektórych części aplikacji za pomocą interfejsu GDI i innych części za pośrednictwem direct3D lub Direct2D. W rzeczywistości aplikacja może wybrać renderowanie funkcji DirectWrite przez własny stos renderowania.

High-Quality Typografia

DirectWrite korzysta z zalet technologii OpenType Font w celu włączenia wysokiej jakości typografii w aplikacji systemu Windows. System czcionek DirectWrite zapewnia usługi do obsługi wyliczania czcionek, rezerwowania czcionek i buforowania czcionek, które są potrzebne przez aplikacje do obsługi czcionek.

Obsługa OpenType zapewniana przez DirectWrite umożliwia deweloperom dodawanie do aplikacji zaawansowanych funkcji typograficznych i obsługę tekstu międzynarodowego.

Obsługa zaawansowanych funkcji typograficznych

DirectWrite umożliwia deweloperom aplikacji odblokowanie funkcji czcionek OpenType, których nie mogli używać w narzędziach WinForms lub GDI. Obiekt DirectWrite IDWriteTypography uwidacznia wiele zaawansowanych funkcji czcionek OpenType, takich jak alternatywy stylistyczne i zawijasy. Zestaw Microsoft Windows Software Development Kit (SDK) udostępnia zestaw przykładowych czcionek OpenType zaprojektowanych z rozbudowanymi funkcjami, takimi jak czcionki Pericles i Pescadero. Aby uzyskać więcej informacji na temat funkcji OpenType, zobacz Funkcje czcionek OpenType.

Obsługa tekstu międzynarodowego

DirectWrite używa czcionek OpenType w celu zapewnienia szerokiej obsługi tekstu międzynarodowego. Obsługiwane są funkcje Unicode, takie jak zastępcze, BIDI, łamanie linii i UVS. Podział na elementy skryptu z przewodnikiem językowym, zamiana liczb i formowanie glifów zapewniają, że tekst w dowolnym skrypcie ma prawidłowy układ i wyświetlanie.

Obecnie obsługiwane są następujące skrypty:

Notatka

W przypadku skryptów oznaczonych znakiem *nie ma domyślnych czcionek systemowych. Aplikacje muszą instalować czcionki, które obsługują te skrypty.

 

  • Arabski język
  • Armeński
  • Bengala
  • Bopomofo
  • Braille'a*
  • Kanadyjskie sylabiki aborygeńskie
  • Cherokee
  • Chiński (uproszczony & tradycyjny)
  • Cyrylica
  • Koptyjski*
  • Dewanagari
  • Etiopski
  • Gruziński
  • Glagolitic*
  • Grecki
  • Gudżarati
  • Gurmukhi
  • Hebrajski
  • Japoński
  • Kannada
  • Khmer
  • Koreański
  • Laotański
  • Łacina
  • Malayalam
  • Mongolski
  • Myanmar
  • Nowy Tai Lue
  • Ogham*
  • Odia
  • "Phags-pa
  • Runiczny*
  • Sinhala
  • Syryjski
  • Tai Le
  • Tamilowie / tamilski język
  • Telugu
  • Thaana
  • Tajski
  • Tybetański
  • Yi

Wiele warstw funkcjonalności

DirectWrite zapewnia rozwarstwione funkcjonalności, a każda warstwa bezproblemowo współdziała z następną. Projekt interfejsu API zapewnia deweloperom aplikacji swobodę i elastyczność wdrażania poszczególnych warstw w zależności od ich potrzeb i harmonogramu. Na poniższym diagramie przedstawiono relację między tymi warstwami.

diagram warstw DirectWrite i ich komunikacji z aplikacją lub strukturą interfejsu użytkownika oraz interfejsem API grafiki

Interfejs API do układu tekstu zapewnia najwyższą funkcjonalność dostępną w DirectWrite. Udostępnia ona usługi umożliwiające aplikacji mierzenie, wyświetlanie i interakcję z sformatowanymi ciągami tekstowymi. Ten interfejs API tekstu może być używany w aplikacjach, które obecnie używają metody DrawText systemu Win32 do tworzenia nowoczesnego interfejsu użytkownika z sformatowanym tekstem.

Aplikacje intensywnie korzystające z tekstu, które implementują własny aparat układu, mogą używać następnej warstwy w dół: procesora skryptów. Procesor skryptu dzieli fragment tekstu na bloki skryptów i obsługuje mapowanie reprezentacji Unicode na odpowiednią reprezentację glifów w czcionce, dzięki czemu tekst skryptu może być poprawnie wyświetlany w odpowiednim języku. System układu używany przez warstwę interfejsu API układu tekstu jest oparty na systemie przetwarzania czcionek i skryptów.

Warstwa renderowania glifów jest najniższą warstwą odpowiadającą za funkcjonalność i zapewnia funkcje renderowania glifów dla aplikacji, które implementują własny aparat układu tekstu. Warstwa renderowania glifów jest również przydatna w aplikacjach, które implementują niestandardowy moduł renderowania, aby modyfikować sposób rysowania glifów za pomocą funkcji wywołania zwrotnego w interfejsie API DirectWrite formatowania tekstu.

System czcionek DirectWrite jest dostępny dla wszystkich warstw funkcjonalnych DirectWrite i umożliwia aplikacji dostęp do informacji o czcionkach i glyph. Jest przeznaczony do obsługi typowych technologii czcionek i formatów danych. Model czcionek DirectWrite jest zgodny ze wspólną praktyką typograficzną obsługiwania dowolnej liczby wag, stylów i odmian szerokości w tej samej rodzinie czcionek. Ten model, ten sam model, który stosują WPF i CSS, określa, że czcionki różniące się tylko odmianą (pogrubioną, lekką itd.), stylem (prostym, kursywą lub ukośnym) lub rozciągnięciem (wąskie, skondensowane, szerokie itd.) są uważane za członków jednej rodziny czcionek.

Ulepszone renderowanie tekstu przy użyciu funkcji ClearType

Poprawa czytelności na ekranie jest kluczowym wymaganiem dla wszystkich aplikacji systemu Windows. Dowody z badań w psychologii poznawczej wskazują, że musimy być w stanie dokładnie rozpoznać każdą literę, a nawet odstęp między literami ma kluczowe znaczenie dla szybkiego przetwarzania. Litery i słowa, które nie są symetryczne, są postrzegane jako brzydkie i obniżają doświadczenie czytania. Kevin Larson, grupa Microsoft Advanced Reading Technologies, napisał artykuł na ten temat, który został opublikowany w Spectrum IEEE. Artykuł nosi nazwę "Technologia tekstu".

Tekst w DirectWrite jest renderowany przy użyciu funkcji Microsoft ClearType, co zwiększa przejrzystość i czytelność tekstu. ClearType wykorzystuje fakt, że nowoczesne wyświetlacze LCD mają paski RGB dla każdego piksela, które można kontrolować indywidualnie. Funkcja DirectWrite używa najnowszych ulepszeń funkcji ClearType, po raz pierwszy dołączonych do systemu Windows Vista z Windows Presentation Foundation, która umożliwia analizę nie tylko pojedynczych liter, ale także odstępów między literami. Przed wprowadzeniem tych ulepszeń ClearType, tekst o rozmiarze 10 lub 12 punktów był trudny do wyświetlenia: mogliśmy umieścić albo 1 piksel między literami, co często było zbyt mało, albo 2 piksele, co często było zbyt wiele. Użycie dodatkowej rozdzielczości w subpixels zapewnia nam odstępy ułamkowe, co poprawia równomierność i symetrię całej strony.

Na poniższych dwóch ilustracjach pokazano, jak glify mogą zaczynać się od dowolnej granicy sub-piksela, gdy używane jest pozycjonowanie sub-pikselowe.

Poniższa ilustracja jest renderowana za pomocą wersji GDI modułu renderowania ClearType, która nie korzystała z pozycjonowania subpikselowego.

ilustracja przedstawiająca pozycjonowania pod pikselami

Poniższa ilustracja jest renderowana przy użyciu wersji DirectWrite modułu renderowania ClearType, który używa pozycjonowania subpikselowego.

ilustracja przedstawiająca

Należy zauważyć, że odstęp między literami h i n jest bardziej wyrównany na drugim obrazie, a litera o jest umieszczona dalej od litery n, bardziej wyrównana z literą l. Zwróć również uwagę, jak elementy liter l mają bardziej naturalny wygląd.

Pozycjonowanie ClearType subpixel oferuje najdokładniejsze odstępy między znakami na ekranie, zwłaszcza w małych rozmiarach, gdzie różnica między sub-pikselem a całym pikselem stanowi znaczną część szerokości glifów. Umożliwia pomiar tekstu w idealnej rozdzielczości przestrzeni i renderowanie w jego naturalnej pozycji na pasku kolorów LCD-u, z dokładnością do subpikseli. Tekst mierzony i renderowany przy użyciu tej technologii jest z definicji niezależny od rozdzielczości, co oznacza, że dokładnie taki sam układ tekstu jest osiągany w różnych rozdzielczościach wyświetlania.

W przeciwieństwie do dowolnego typu renderowania GDI ClearType, ClearType sub-pikselowy oferuje najdokładniejszą szerokość znaków.

Interfejs API ciągów tekstowych domyślnie przyjmuje renderowanie tekstu z wykorzystaniem subpikseli, co oznacza, że mierzy tekst w idealnej rozdzielczości, niezależnie od bieżącej rozdzielczości ekranu, i generuje wynik pozycjonowania glifów na podstawie prawdziwie skalowanych szerokości przesunięć glifów do przodu oraz przesunięć pozycjonowania.

W przypadku tekstu o dużym rozmiarze DirectWrite umożliwia również antyaliasowanie wzdłuż osi y, aby krawędzie wygładziły i odwzorować litery zgodnie z zamysłem projektanta czcionek. Na poniższej ilustracji przedstawiono antyaliasing w kierunku Y.

ilustracja

Mimo że DirectWrite tekst jest domyślnie umieszczany i wyświetlany przy użyciu subpikselowego ClearType, dostępne są inne opcje renderowania. Wiele istniejących aplikacji używa interfejsu GDI do renderowania większości interfejsu użytkownika, a niektóre aplikacje używają kontrolek edycji systemu, które nadal używają interfejsu GDI do renderowania tekstu. Podczas dodawania tekstu DirectWrite do tych aplikacji może być konieczne poświęcenie ulepszeń komfortu czytania udostępnianych przez subpikselowy ClearType, aby tekst miał spójny wygląd w aplikacjach.

Aby spełnić te wymagania, DirectWrite obsługuje również następujące opcje renderowania:

  • Sub-pixel ClearType (wartość domyślna).
  • Sub-pixel ClearType z wygładzaniem krawędzi w poziomym i pionowym wymiarze.
  • Tekst aliasowany.
  • Naturalna szerokość GDI (wykorzystywana na przykład przez widok do odczytu w Microsoft Word).
  • Zgodna szerokość GDI (w tym mapa bitowa osadzona w Azji Wschodniej).

Każdy z tych trybów renderowania można dostosować za pomocą API DirectWrite i nowego wbudowanego narzędzia do dostrajania ClearType systemu Windows 7.

Notatka

Począwszy od systemu Windows 8, w większości przypadków należy używać antyaliasingu tekstu w skali szarej. Aby uzyskać więcej informacji, zobacz następną sekcję.

 

Obsługa układu naturalnego

Układ naturalny jest niezależny od rozdzielczości, więc odstępy znaków nie zmieniają się w miarę powiększania lub pomniejszania ani w zależności od dpi ekranu. Dodatkową zaletą jest to, że odstępy są zgodnie z projektem fontu. Układ naturalny jest możliwy dzięki obsłudze naturalnego renderowania przez DirectWrite, co oznacza, że poszczególne glify można ustawić na ułamek piksela.

Chociaż układ naturalny jest domyślny, niektóre aplikacje muszą renderować tekst z tym samym odstępem i wyglądem co interfejs GDI. W przypadku takich aplikacji DirectWrite udostępnia klasyczne i naturalne tryby pomiaru GDI oraz odpowiadające im tryby renderowania.

Każdy z powyższych trybów renderowania może być połączony z jednym z dwóch trybów antyaliasingowych: ClearType lub grayscale. Symulacja antyaliasingu ClearType polega na symulacji wyższej rozdzielczości poprzez indywidualne manipulowanie wartościami kolorów czerwonego, zielonego i niebieskiego każdego piksela. Antyaliasing w skali szarości oblicza tylko jedną wartość pokrycia (lub alfa) dla każdego piksela. ClearType jest wartością domyślną, ale antyaliasing skali szarości jest zalecany w przypadku aplikacji ze Sklepu Windows, ponieważ jest szybszy i jest zgodny ze standardowym antyaliasingiem, a jednocześnie jest wysoce czytelny.

Omówienie interfejsu API

Interfejs IDWriteFactory jest punktem wyjścia do korzystania z funkcji DirectWrite. Fabryka jest obiektem głównym, który tworzy zestaw obiektów, które mogą być używane razem.

Operacja formatowania i układu jest wymaganiem wstępnym dla operacji, ponieważ tekst musi być poprawnie sformatowany i rozmieszczony do określonego zestawu ograniczeń, zanim będzie można go renderować lub testować pod kątem trafień. Dwa kluczowe obiekty, które można utworzyć za pomocą IDWriteFactory w tym celu, to IDWriteTextFormat i IDWriteTextLayout. Obiekt IDWriteTextFormat reprezentuje informacje o formatowaniu akapitu tekstu. Funkcja IDWriteFactory::CreateTextLayout przyjmuje ciąg wejściowy, skojarzone ograniczenia, takie jak wymiar miejsca do wypełnienia, oraz obiekt IDWriteTextFormat i umieszcza w pełni przeanalizowany i sformatowany wynik w IDWriteTextLayout do użycia w kolejnych operacjach.

Aplikacja może następnie renderować tekst przy użyciu funkcji DrawTextLayout udostępnionej przez Direct2D lub implementując funkcję wywołania zwrotnego, która może używać GDI, Direct2D lub innych systemów graficznych do renderowania glifów. W przypadku pojedynczego tekstu w formacie funkcja DrawText w trybie Direct2D zapewnia prostszy sposób narysowania tekstu bez konieczności uprzedniego utworzenia obiektu IDWriteTextLayout.

Formatowanie i rysowanie "Hello World" przy użyciu funkcji DirectWrite

Poniższy przykład kodu pokazuje, jak aplikacja może sformatować pojedynczy akapit przy użyciu IDWriteTextFormat i narysować go przy użyciu funkcji Direct2DDrawText.

HRESULT DemoApp::DrawHelloWorld(
    ID2D1HwndRenderTarget* pIRenderTarget
    )
{
    HRESULT hr = S_OK;
    ID2D1SolidColorBrush* pIRedBrush = NULL;
    IDWriteTextFormat* pITextFormat = NULL;
    IDWriteFactory* pIDWriteFactory = NULL;

    if (SUCCEEDED(hr))
    {
        hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
                __uuidof(IDWriteFactory),
                reinterpret_cast<IUnknown**>(&pIDWriteFactory));
    }

    if(SUCCEEDED(hr))
    {
        hr = pIDWriteFactory->CreateTextFormat(
            L"Arial", 
            NULL,
            DWRITE_FONT_WEIGHT_NORMAL, 
            DWRITE_FONT_STYLE_NORMAL, 
            DWRITE_FONT_STRETCH_NORMAL, 
            10.0f * 96.0f/72.0f, 
            L"en-US", 
            &pITextFormat
        );
    }

    if(SUCCEEDED(hr))
    {
        hr = pIRenderTarget->CreateSolidColorBrush(
            D2D1:: ColorF(D2D1::ColorF::Red),
            &pIRedBrush
        );
    }
    
   D2D1_RECT_F layoutRect = D2D1::RectF(0.f, 0.f, 100.f, 100.f);

    // Actually draw the text at the origin.
    if(SUCCEEDED(hr))
    {
        pIRenderTarget->DrawText(
            L"Hello World",
            wcslen(L"Hello World"),
            pITextFormat,
            layoutRect, 
            pIRedBrush
        );
    }

    // Clean up.
    SafeRelease(&pIRedBrush);
    SafeRelease(&pITextFormat);
    SafeRelease(&pIDWriteFactory);

    return hr;
}

Uzyskiwanie dostępu do systemu czcionek

Oprócz określenia nazwy rodziny czcionek dla ciągu tekstowego przy użyciu interfejsuIDWriteTextFormat w powyższym przykładzie, DirectWrite zapewnia aplikacjom większą kontrolę nad wyborem czcionek za pomocą wyliczenia czcionek i możliwość tworzenia niestandardowej kolekcji czcionek na podstawie osadzonych czcionek dokumentów.

Obiekt IDWriteFontCollection jest kolekcją rodzin czcionek. Funkcja DirectWrite zapewnia dostęp do zestawu czcionek zainstalowanych w systemie za pośrednictwem specjalnej kolekcji czcionek nazywanej kolekcją czcionek systemowych. Jest to uzyskiwane przez wywołanie metody GetSystemFontCollection obiektu IDWriteFactory. Aplikacja może również utworzyć niestandardową kolekcję czcionek z zestawu czcionek wyliczanych przez wywołanie zwrotne zdefiniowane przez aplikację, czyli czcionki prywatne zainstalowane przez aplikację lub czcionki osadzone w dokumencie.

Następnie aplikacja może wywołać GetFontFamily, aby przejść do określonego obiektu FontFamily w kolekcji, a następnie wywołać IDWriteFontFamily::GetFirstMatchingFont, aby przejść do określonego obiektu IDWriteFont. Obiekt IDWriteFont reprezentuje czcionkę w kolekcji czcionek i uwidacznia właściwości oraz kilka podstawowych metryk czcionek.

IDWriteFontFace to inny obiekt reprezentujący czcionkę i uwidacznia pełny zestaw metryk dla czcionki. IDWriteFontFace można utworzyć bezpośrednio na podstawie nazwy czcionki; aplikacja nie musi pobierać kolekcji czcionek, aby uzyskać do niej dostęp. Jest to przydatne w przypadku aplikacji układu tekstu, takiej jak Microsoft Word, która musi wykonywać zapytania dotyczące szczegółów określonej czcionki.

Na poniższym diagramie przedstawiono relację między tymi obiektami.

diagram relacji między kolekcją czcionek, rodziną czcionek i odmianą czcionki

IDWriteFontFace

Obiekt IDWriteFontFace reprezentuje czcionkę i zawiera bardziej szczegółowe informacje na temat czcionki niż idWriteFont obiekt. Metryki czcionek i glyph z IDWriteFontFace są przydatne w przypadku aplikacji implementujących układ tekstu.

Większość popularnych aplikacji nie będzie używać tych interfejsów API bezpośrednio, a zamiast tego użyje IDWriteFont lub będzie stosować bezpośrednio nazwę rodziny czcionek.

W poniższej tabeli przedstawiono podsumowanie scenariuszy użycia dla dwóch obiektów.

Kategoria IDWriteFont IDWriteFontFace
API wspierające interakcje użytkownika, np. interfejs wyboru czcionek: opis oraz inne informacyjne API Tak Nie
Interfejsy API do obsługi mapowania czcionek: rodzina, styl, waga, rozciągnięcie, zasięg znaków Tak Nie
DrawText API Tak Nie
API używane do renderowania Nie Tak
Interfejsy API używane do układu tekstu: metryki glifu itd. Nie Tak
Interfejsy API dla kontrolki interfejsu użytkownika i układu tekstu: metryki dla całej czcionki Tak Tak

 

Poniżej przedstawiono przykładową aplikację, która wylicza czcionki w kolekcji czcionek systemowych.

#include <dwrite.h>
#include <string.h>
#include <stdio.h>
#include <new>

// SafeRelease inline function.
template <class T> inline void SafeRelease(T **ppT)
{
    if (*ppT)
    {
        (*ppT)->Release();
        *ppT = NULL;
    }
}

void wmain()
{
    IDWriteFactory* pDWriteFactory = NULL;

    HRESULT hr = DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            reinterpret_cast<IUnknown**>(&pDWriteFactory)
            );

    IDWriteFontCollection* pFontCollection = NULL;

    // Get the system font collection.
    if (SUCCEEDED(hr))
    {
        hr = pDWriteFactory->GetSystemFontCollection(&pFontCollection);
    }

    UINT32 familyCount = 0;

    // Get the number of font families in the collection.
    if (SUCCEEDED(hr))
    {
        familyCount = pFontCollection->GetFontFamilyCount();
    }

    for (UINT32 i = 0; i < familyCount; ++i)
    {
        IDWriteFontFamily* pFontFamily = NULL;

        // Get the font family.
        if (SUCCEEDED(hr))
        {
            hr = pFontCollection->GetFontFamily(i, &pFontFamily);
        }

        IDWriteLocalizedStrings* pFamilyNames = NULL;
        
        // Get a list of localized strings for the family name.
        if (SUCCEEDED(hr))
        {
            hr = pFontFamily->GetFamilyNames(&pFamilyNames);
        }

        UINT32 index = 0;
        BOOL exists = false;
        
        wchar_t localeName[LOCALE_NAME_MAX_LENGTH];

        if (SUCCEEDED(hr))
        {
            // Get the default locale for this user.
            int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);

            // If the default locale is returned, find that locale name, otherwise use "en-us".
            if (defaultLocaleSuccess)
            {
                hr = pFamilyNames->FindLocaleName(localeName, &index, &exists);
            }
            if (SUCCEEDED(hr) && !exists) // if the above find did not find a match, retry with US English
            {
                hr = pFamilyNames->FindLocaleName(L"en-us", &index, &exists);
            }
        }
        
        // If the specified locale doesn't exist, select the first on the list.
        if (!exists)
            index = 0;

        UINT32 length = 0;

        // Get the string length.
        if (SUCCEEDED(hr))
        {
            hr = pFamilyNames->GetStringLength(index, &length);
        }

        // Allocate a string big enough to hold the name.
        wchar_t* name = new (std::nothrow) wchar_t[length+1];
        if (name == NULL)
        {
            hr = E_OUTOFMEMORY;
        }

        // Get the family name.
        if (SUCCEEDED(hr))
        {
            hr = pFamilyNames->GetString(index, name, length+1);
        }
        if (SUCCEEDED(hr))
        {
            // Print out the family name.
            wprintf(L"%s\n", name);
        }

        SafeRelease(&pFontFamily);
        SafeRelease(&pFamilyNames);

        delete [] name;
    }

    SafeRelease(&pFontCollection);
    SafeRelease(&pDWriteFactory);
}

Renderowanie tekstu

Interfejsy API renderowania tekstu umożliwiają renderowanie glyphs w DirectWrite czcionki do renderowania na powierzchnię direct2D Direct2D lub na niezależną mapę bitową urządzenia GDI lub przekonwertować na kontury lub mapy bitowe. Renderowanie ClearType w funkcji DirectWrite obsługuje pozycjonowanie na poziomie subpikseli z lepszą ostrością i kontrastem w porównaniu z poprzednimi implementacjami w systemie Windows. DirectWrite obsługuje również tekst czarno-biały z aliasingiem w scenariuszach obejmujących czcionki wschodnioazjatyckie z osadzonymi mapami bitowymi lub gdy użytkownik wyłączył wygładzanie czcionek dowolnego typu.

Wszystkie opcje są regulowane przez wszystkie dostępne pokrętła ClearType dostępne za pośrednictwem interfejsów API DirectWrite, a także uwidocznione za pośrednictwem nowego apletu panelu sterowania tunera ClearType systemu Windows 7.

Istnieją dwa interfejsy API dostępne do renderowania glifów, jeden zapewniający sprzętowe przyspieszenie renderowania za pośrednictwem Direct2D, a drugi oferuje renderowanie programowe dla mapy bitowej GDI. Aplikacja korzystająca z IDWriteTextLayout i implementująca IDWriteTextRenderer może wywołać jedną z tych funkcji w odpowiedzi na DrawGlyphRun jako wywołanie zwrotne. Ponadto aplikacje, które implementują własny układ lub zajmują się danymi na poziomie glifów, mogą korzystać z tych interfejsów API.

  1. ID2DRenderTarget::DrawGlyphRun

    Aplikacje mogą używać interfejsu API Direct2D DrawGlyphRun do zapewnienia sprzętowego przyspieszenia renderowania tekstu za pomocą GPU. Przyspieszanie sprzętowe wpływa na wszystkie fazy potoku renderowania tekstu — od scalania glifów w przebiegi glifów i filtrowania mapy bitowej przebiegu glifów, po zastosowanie algorytmu mieszania ClearType do końcowego wyświetlanego obrazu. Jest to zalecany interfejs API umożliwiający uzyskanie najlepszej wydajności renderowania.

  2. IDWriteBitmapRenderTarget::DrawGlyphRun

    Aplikacje mogą używać metody IDWriteBitmapRenderTarget::DrawGlyphRun, aby wykonać renderowanie programowe serii glifów na mapie bitowej 32-bpp. Obiekt IDWriteBitmapRenderTarget zawiera mapę bitową i kontekst urządzenia pamięci, który może służyć do renderowania glifów. To API jest przydatne, jeśli chcesz pozostać przy GDI, ponieważ masz już istniejącą bazę kodu renderującą w GDI.

Jeśli masz aplikację, która ma istniejący kod układu tekstu używający GDI i chcesz zachować ten kod, ale użyć DirectWrite tylko w ostatnim kroku renderowania symboli, IDWriteGdiInterop::CreateFontFaceFromHdc stanowi pomost między dwoma interfejsami API. Przed wywołaniem tej funkcji aplikacja będzie używać funkcji IDWriteGdiInterop::CreateFontFaceFromHdc, aby uzyskać odwołanie do czcionki twarzy z kontekstu urządzenia.

Notatka

W większości scenariuszy aplikacje mogą nie potrzebować użycia tych interfejsów API renderowania glifów. Po utworzeniu obiektu IDWriteTextLayout można użyć metody ID2D1RenderTarget::DrawTextLayout do renderowania tekstu.

 

Niestandardowe tryby renderowania

Wiele parametrów wpływa na renderowanie tekstu, takie jak gamma, poziom ClearType, geometria pikseli i rozszerzony kontrast. Parametry renderowania są hermetyzowane przez obiekt, który implementuje publiczny interfejs IDWriteRenderingParams. Obiekt parametrów renderowania jest automatycznie inicjowany na podstawie właściwości sprzętu i/lub preferencji użytkownika określonych za pomocą apletu Panelu sterowania ClearType w systemie Windows 7. Ogólnie rzecz biorąc, jeśli klient korzysta z interfejsu API układu DirectWrite, funkcja DirectWrite automatycznie wybierze tryb renderowania odpowiadający określonemu trybowi pomiaru.

Aplikacje, które chcą mieć większą kontrolę, mogą używać IDWriteFactory::CreateCustomRenderingParams w celu zaimplementowania różnych opcji renderowania. Ta funkcja może również służyć do ustawiania gamma, geometrii pikseli i rozszerzonego kontrastu.

Poniżej przedstawiono różne dostępne opcje renderowania:

  • Sub-pixel anti-aliasing

    Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_NATURAL, aby określić renderowanie z wygładzaniem krawędzi tylko w wymiarze poziomym.

  • Antyaliasing subpikselowy w wymiarach poziomych i pionowych.

    Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, aby określić renderowanie z antyaliasingiem w wymiarach zarówno poziomych, jak i pionowych. Sprawia to, że krzywe i linie ukośne wyglądają płynniej, kosztem pewnej miękkości, i są zazwyczaj stosowane w rozmiarach powyżej 16 ppem.

  • Tekst aliasowany

    Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_ALIASED, aby określić tekst aliasowany.

  • Tekst w skali szarości

    Aplikacja ustawia parametr pixelGeometry na DWRITE_PIXEL_GEOMETRY_FLAT w celu określenia tekstu w skali szarości.

  • Zgodna szerokość GDI (w tym mapa bitowa osadzona w Azji Wschodniej)

    Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_GDI_CLASSIC, aby określić antyaliasing szerokości zgodnej z GDI.

  • GDI naturalna szerokość

    Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_GDI_NATURAL, aby określić wygładzanie krawędzi zgodne z naturalną szerokością GDI.

  • Tekst konspektu

    W przypadku renderowania w dużych rozmiarach deweloper aplikacji może preferować użycie obrysu czcionki zamiast rasteryzacji w mapie bitowej. Aplikacja ustawia parametr renderingMode na DWRITE_RENDERING_MODE_OUTLINE, aby określić, że renderowanie powinno pominąć rasteryzator i użyć konturów bezpośrednio.

Interoperacyjność GDI

Interfejs IDWriteGdiInterop zapewnia współdziałanie z interfejsem GDI. Dzięki temu aplikacje mogą kontynuować istniejące inwestycje w bazy kodu GDI i selektywnie używać DirectWrite do renderowania lub układu.

Poniżej przedstawiono interfejsy API, które umożliwiają aplikacji migrację do systemu czcionek GDI lub z systemu czcionek GDI:

Konkluzja

Ulepszanie środowiska czytania jest bardzo ważne dla użytkowników, niezależnie od tego, czy jest na ekranie, czy na papierze. DirectWrite zapewnia łatwość użycia oraz model programowania warstwowego dla deweloperów aplikacji w celu ulepszenia środowiska tekstowego dla aplikacji systemu Windows. Aplikacje mogą używać funkcji DirectWrite do renderowania sformatowanego tekstu dla interfejsu użytkownika i dokumentów za pomocą API układu. W przypadku bardziej złożonych scenariuszy aplikacja może pracować bezpośrednio z glifami, czcionkami dostępu itd. i wykorzystać możliwości funkcji DirectWrite w celu zapewnienia wysokiej jakości typografii.

Możliwości współdziałania DirectWrite umożliwiają deweloperom aplikacji przenoszenie istniejących baz kodu Win32 i selektywne wdrażanie funkcji DirectWrite w swoich aplikacjach.