Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento dokument ukazuje, jak pomocí DirectWrite a Direct2D vytvořit jednoduchý text, který obsahuje jeden formát, a text, který obsahuje více formátů.
Tento kurz obsahuje následující části:
Zdrojový kód
Zdrojový kód zobrazený v tomto přehledu pochází z ukázky DirectWrite Hello World. Každá část je implementována v samostatné třídě (SimpleText a MultiformattedText) a je zobrazena v samostatném podřízené okně. Každá třída představuje okno Microsoft Win32. Kromě metody WndProc obsahuje každá třída následující metody:
| Funkce | Popis |
|---|---|
| CreateDeviceIndependentResources | Vytvoří prostředky, které jsou nezávislé na zařízení, aby je bylo možné opakovaně používat kdekoli. |
| DiscardDeviceIndependentResources | Uvolní prostředky nezávislé na zařízení, jakmile už nejsou potřeba. |
| CreateDeviceResources | Vytvoří prostředky, jako jsou štětce a vykreslovací cíle, které jsou svázané s konkrétním zařízením. |
| ZahoditZařízeníZdroje | Uvolní prostředky závislé na zařízení, jakmile už nebudou potřeba. |
| DrawD2DContent | Používá Direct2D k vykreslení na obrazovku. |
| KreslitText | Kreslí textový řetězec pomocí Direct2D. |
| OnResize | Změní velikost Direct2D vykreslovacího cíle, když se změní velikost okna. |
Můžete použít poskytnutou ukázku nebo podle pokynů přidat DirectWrite a Direct2D do vlastní aplikace Win32. Další informace o ukázce a přidružených souborech projektu naleznete v DirectWrite HelloWorld.
Kreslení jednoduchého textu
Tato část ukazuje, jak pomocí DirectWrite a Direct2D vykreslit jednoduchý text, který má jeden formát, jak je znázorněno na následujícím snímku obrazovky.
Kreslení jednoduchého textu na obrazovku vyžaduje čtyři součásti:
- Řetězec znaků, který se má vykreslit.
- Instance IDWriteTextFormat.
- Rozměry oblasti určené k obsahování textu.
- Objekt, který může vykreslit text. V tomto tutoriálu. používáte Direct2D jako cílovou plochu pro vykreslování.
Rozhraní IDWriteTextFormat popisuje název rodiny písem, velikost, tloušťku, styl a roztažení použité k formátování textu a popisuje informace o národním prostředí. IDWriteTextFormat také definuje metody pro nastavení a získání následujících vlastností:
- Řádkování.
- Zarovnání textu vzhledem k levému a pravému okraji pole rozložení
- Zarovnání odstavce vůči hornímu a dolnímu okraji rámce rozložení.
- Směr čtení.
- Granularita ořezávání textu, který přetéká přes pole rozvržení.
- Přírůstková zarážka tabulátoru.
- Směr toku odstavce.
Rozhraní IDWriteTextFormat je vyžadováno pro kreslicí text, který používá oba procesy popsané v tomto dokumentu .
Před vytvořením objektu IDWriteTextFormat nebo jakéhokoli jiného objektu DirectWrite potřebujete instanciIDWriteFactory. Pomocí IDWriteFactory můžete vytvořit IDWriteTextFormat instance a další objekty DirectWrite. K získání instance továrny použijte funkci DWriteCreateFactory.
Část 1: Deklarujte prostředky DirectWrite a Direct2D.
V této části deklarujete objekty, které použijete později k vytvoření a zobrazení textu jako soukromých datových členů třídy. Všechna rozhraní, funkce a datové typy pro DirectWrite jsou deklarována v souboru hlaviček dwrite.h a ty pro Direct2D jsou deklarovány v d2d1.h; Pokud jste to ještě neudělali, zahrňte do projektu tyto hlavičky.
V souboru záhlaví třídy (SimpleText.h) deklarujte ukazatele na IDWriteFactory a IDWriteTextFormat rozhraní jako privátní členy.
IDWriteFactory* pDWriteFactory_; IDWriteTextFormat* pTextFormat_;Deklarujte členy, které mají obsahovat textový řetězec pro vykreslení a délku řetězce.
const wchar_t* wszText_; UINT32 cTextLength_;Deklarujte ukazatele na ID2D1Factory, ID2D1HwndRenderTargeta ID2D1SolidColorBrush rozhraní pro vykreslení textu pomocí Direct2D.
ID2D1Factory* pD2DFactory_; ID2D1HwndRenderTarget* pRT_; ID2D1SolidColorBrush* pBlackBrush_;
Část 2: Vytvoření prostředků nezávislých na zařízení
direct2D poskytuje dva typy prostředků: prostředky závislé na zařízení a prostředky nezávislé na zařízeních. Prostředky závislé na zařízení jsou přidružené k vykreslovacímu zařízení a už nefungují, pokud je toto zařízení odebráno. Prostředky nezávislé na zařízení mohou naopak existovat po dobu trvání vaší aplikace.
prostředky DirectWrite jsou nezávislé na zařízení.
V této části vytvoříte prostředky nezávislé na zařízení, které vaše aplikace používá. Tyto prostředky musí být uvolněny voláním metody rozhraní Release.
Některé prostředky, které se používají, musí být vytvořeny pouze jednou a nejsou svázané se zařízením. Inicializace těchto prostředků probíhá v metodě SimpleText::CreateDeviceIndependentResources, která je volána při inicializaci třídy.
Uvnitř metody SimpleText::CreateDeviceIndependentResources v souboru implementace třídy (SimpleText.cpp) zavolejte funkci D2D1CreateFactory k vytvoření rozhraní ID2D1Factory, což je kořenové rozhraní továrny pro všechny objekty Direct2D. Stejnou továrnu použijete k vytvoření instance dalších prostředků Direct2D.
hr = D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory_ );Voláním funkce DWriteCreateFactory vytvořte rozhraní IDWriteFactory, což je rozhraní kořenové továrny pro všechny objekty DirectWrite. Stejnou továrnu použijete k vytvoření instance jiných prostředků DirectWrite.
if (SUCCEEDED(hr)) { hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&pDWriteFactory_) ); }Inicializuje textový řetězec a uloží jeho délku.
wszText_ = L"Hello World using DirectWrite!"; cTextLength_ = (UINT32) wcslen(wszText_);Vytvořte objekt rozhraní IDWriteTextFormat pomocí metody IDWriteFactory::CreateTextFormat. IDWriteTextFormat určuje písmo, tloušťku, roztažení, styl a národní prostředí, které se použije k vykreslení textového řetězce.
if (SUCCEEDED(hr)) { hr = pDWriteFactory_->CreateTextFormat( L"Gabriola", // Font family name. NULL, // Font collection (NULL sets it to use the system font collection). DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0f, L"en-us", &pTextFormat_ ); }Vycentrujte text vodorovně a svisle voláním metod IDWriteTextFormat::SetTextAlignment a IDWriteTextFormat::SetParagraphAlignment.
// Center align (horizontally) the text. if (SUCCEEDED(hr)) { hr = pTextFormat_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); } if (SUCCEEDED(hr)) { hr = pTextFormat_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); }
V této části jste inicializovali prostředky nezávislé na zařízení, které vaše aplikace používá. V další části inicializujete prostředky závislé na zařízení.
Část 3: Vytvoření prostředků Device-Dependent
V této části vytvoříte ID2D1HwndRenderTarget a ID2D1SolidColorBrush pro vykreslení textu.
Cíl vykreslení je objekt Direct2D, který vytváří prostředky výkresu a vykresluje příkazy kreslení do vykreslovacího zařízení. ID2D1HwndRenderTarget je cíl vykreslení, který se vykreslí na HWND.
Jedním z kreslicích prostředků, které může vytvořit cílový objekt vykreslování, je štětec na malování obrysů, výplní a textu. ID2D1SolidColorBrush maluje jednolitou barvou.
Rozhraní ID2D1HwndRenderTarget a ID2D1SolidColorBrush jsou svázané s vykreslovacím zařízením při jejich vytvoření a musí být uvolněny a znovu vytvořeny, pokud se zařízení stane neplatným.
Uvnitř metody SimpleText::CreateDeviceResources zkontrolujte, zda je ukazatel cílového vykreslení NULL. Pokud ano, načtěte velikost oblasti vykreslení a vytvořte ID2D1HwndRenderTarget této velikosti. Pomocí ID2D1HwndRenderTarget vytvořte ID2D1SolidColorBrush.
RECT rc; GetClientRect(hwnd_, &rc); D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); if (!pRT_) { // Create a Direct2D render target. hr = pD2DFactory_->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hwnd_, size ), &pRT_ ); // Create a black brush. if (SUCCEEDED(hr)) { hr = pRT_->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::Black), &pBlackBrush_ ); } }Ve funkci SimpleText::DiscardDeviceResources uvolněte jak štětec, tak cílový renderovací objekt.
SafeRelease(&pRT_); SafeRelease(&pBlackBrush_);
Teď, když jste vytvořili cíl vykreslení a štětec, můžete ho použít k vykreslení textu.
Část 4: Nakreslete text pomocí metody Direct2D DrawText.
Ve třídě SimpleText::DrawText definujte oblast pro rozložení textu načtením dimenzí vykreslovací oblasti a vytvořte Direct2D obdélník se stejnými dimenzemi.
D2D1_RECT_F layoutRect = D2D1::RectF( static_cast<FLOAT>(rc.left) / dpiScaleX_, static_cast<FLOAT>(rc.top) / dpiScaleY_, static_cast<FLOAT>(rc.right - rc.left) / dpiScaleX_, static_cast<FLOAT>(rc.bottom - rc.top) / dpiScaleY_ );K vykreslení textu na obrazovku použijte metodu ID2D1RenderTarget::DrawText a objekt IDWriteTextFormat. Metoda ID2D1RenderTarget::DrawText přijímá následující parametry:
- Řetězec, který se má vykreslit.
- Ukazatel na rozhraní IDWriteTextFormat.
- Obdélník rozložení Direct2D .
- Ukazatel na rozhraní, které zveřejňuje ID2D1Brush.
pRT_->DrawText( wszText_, // The string to render. cTextLength_, // The string's length. pTextFormat_, // The text format. layoutRect, // The region of the window where the text will be rendered. pBlackBrush_ // The brush used to draw the text. );
Část 5: Vykreslení obsahu okna pomocí Direct2D
Chcete-li vykreslit obsah okna pomocí Direct2D, když je přijata zpráva o malování, postupujte takto:
- Vytvořte prostředky závislé na zařízení voláním metody SimpleText::CreateDeviceResources implementované v části 3.
- Zavolejte metodu ID2D1HwndRenderTarget::BeginDraw vykreslovacího cíle.
- Proveďte metodu volání ID2D1HwndRenderTarget::Clear k vymazání cíle vykreslování.
- Volání metody SimpleText::DrawText, která byla implementována v části 4.
- Volejte metodu ID2D1HwndRenderTarget::EndDraw vykreslovacího cíle.
- V případě potřeby zahoďte prostředky závislé na zařízení, aby se mohly znovu vytvořit při překreslení okna.
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
pRT_->BeginDraw();
pRT_->SetTransform(D2D1::IdentityMatrix());
pRT_->Clear(D2D1::ColorF(D2D1::ColorF::White));
// Call the DrawText method of this class.
hr = DrawText();
if (SUCCEEDED(hr))
{
hr = pRT_->EndDraw(
);
}
}
if (FAILED(hr))
{
DiscardDeviceResources();
}
Třída SimpleText je implementována v SimpleText.h a SimpleText.cpp.
Kreslení textu s více formáty
Tato část ukazuje, jak pomocí DirectWrite a Direct2D vykreslit text s více formáty, jak je znázorněno na následujícím snímku obrazovky.
Kód této části je implementován jako třída MultiformattedText v DirectWrite HelloWorld. Je založená na krocích z předchozí části.
Chcete-li vytvořit víceformátovaný text, použijete rozhraní IDWriteTextLayout a rozhraní IDWriteTextFormat, jak bylo uvedeno v předchozí části. Rozhraní IDWriteTextLayout popisuje formátování a rozložení bloku textu. Kromě výchozího formátování určeného objektem IDWriteTextFormat lze formátování pro konkrétní oblasti textu změnit pomocí IDWriteTextLayout. To zahrnuje název písma, velikost, tloušťku, styl, roztažení, přeškrtnutí a podtržení.
IDWriteTextLayout také poskytuje metody hit-testování. Metriky hit-testování vrácené těmito metodami jsou relativní vzhledem k poli rozložení zadanému při vytvoření objektu rozhraní IDWriteTextLayout pomocí metody CreateTextLayout rozhraní IDWriteFactory.
Rozhraní IDWriteTypography se používá k přidání volitelných OpenType typografických funkcí do rozložení textu, jako jsou swashes a alternativní stylistické sady textu. Typografické funkce lze přidat do určitého rozsahu textu v rámci rozložení textu voláním metody AddFontFeature rozhraní IDWriteTypography. Tato metoda obdrží DWRITE_FONT_FEATURE strukturu jako parametr, který obsahuje konstantu výčtu DWRITE_FONT_FEATURE_TAG a parametr spuštění UINT32. Seznam registrovaných funkcí OpenType najdete v registru OpenType Layout Tag Registry na microsoft.com. Ekvivalentní konstanty výčtu DirectWrite naleznete v tématu DWRITE_FONT_FEATURE_TAG.
Část 1: Vytvoření rozhraní IDWriteTextLayout.
Deklarujte ukazatel na rozhraní IDWriteTextLayout jako člen třídy MultiformattedText.
IDWriteTextLayout* pTextLayout_;Na konci metody MultiformattedText::CreateDeviceIndependentResources vytvořte objekt rozhraní IDWriteTextLayout voláním metody CreateTextLayout. Rozhraní IDWriteTextLayout poskytuje další funkce formátování, jako je možnost použití různých formátů u vybraných částí textu.
// Create a text layout using the text format. if (SUCCEEDED(hr)) { RECT rect; GetClientRect(hwnd_, &rect); float width = rect.right / dpiScaleX_; float height = rect.bottom / dpiScaleY_; hr = pDWriteFactory_->CreateTextLayout( wszText_, // The string to be laid out and formatted. cTextLength_, // The length of the string. pTextFormat_, // The text format to apply to the string (contains font information, etc). width, // The width of the layout box. height, // The height of the layout box. &pTextLayout_ // The IDWriteTextLayout interface pointer. ); }
Část 2: Použití formátování pomocí IDWriteTextLayout.
Formátování, jako je velikost písma, váha a podtržení, lze použít u podřetězeců textu, které se mají zobrazit pomocí rozhraní IDWriteTextLayout.
Nastavte velikost písma pro podřetězec "Di" z "DirectWrite" na 100 deklarací DWRITE_TEXT_RANGE a voláním metody IDWriteTextLayout::SetFontSize.
// Format the "DirectWrite" substring to be of font size 100. if (SUCCEEDED(hr)) { DWRITE_TEXT_RANGE textRange = {20, // Start index where "DirectWrite" appears. 6 }; // Length of the substring "Direct" in "DirectWrite". hr = pTextLayout_->SetFontSize(100.0f, textRange); }Podtrhněte podřetězec "DirectWrite" voláním metody IDWriteTextLayout::SetUnderline.
// Format the word "DWrite" to be underlined. if (SUCCEEDED(hr)) { DWRITE_TEXT_RANGE textRange = {20, // Start index where "DirectWrite" appears. 11 }; // Length of the substring "DirectWrite". hr = pTextLayout_->SetUnderline(TRUE, textRange); }Nastavte tloušťku písma na tučné pro podřetězec "DirectWrite" voláním IDWriteTextLayout::SetFontWeight metodou.
if (SUCCEEDED(hr)) { // Format the word "DWrite" to be bold. DWRITE_TEXT_RANGE textRange = {20, 11 }; hr = pTextLayout_->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, textRange); }
Část 3: Přidání typografických funkcí pomocí IDWriteTypography
Deklarujte a vytvořte objekt rozhraní IDWriteTypography voláním metody IDWriteFactory::CreateTypography.
// Declare a typography pointer. IDWriteTypography* pTypography = NULL; // Create a typography interface object. if (SUCCEEDED(hr)) { hr = pDWriteFactory_->CreateTypography(&pTypography); }Přidejte funkci písma deklarací objektu DWRITE_FONT_FEATURE, který má zadanou stylistickou sadu 7, a voláním metody IDWriteTypography::AddFontFeature.
// Set the stylistic set. DWRITE_FONT_FEATURE fontFeature = {DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7, 1}; if (SUCCEEDED(hr)) { hr = pTypography->AddFontFeature(fontFeature); }Nastavte rozložení textu tak, aby používalo typografii po celém řetězci deklarováním proměnné DWRITE_TEXT_RANGE a voláním IDWriteTextLayout::SetTypography metody a předáním textové oblasti.
if (SUCCEEDED(hr)) { // Set the typography for the entire string. DWRITE_TEXT_RANGE textRange = {0, cTextLength_}; hr = pTextLayout_->SetTypography(pTypography, textRange); }Nastavte novou šířku a výšku objektu rozložení textu v metodě MultiformattedText::OnResize.
if (pTextLayout_) { pTextLayout_->SetMaxWidth(static_cast<FLOAT>(width / dpiScaleX_)); pTextLayout_->SetMaxHeight(static_cast<FLOAT>(height / dpiScaleY_)); }
Část 4: Kreslení textu pomocí Direct2D DrawTextLayout Metoda.
Chcete-li nakreslit text s nastavením rozložení textu určeným objektem IDWriteTextLayout, změňte kód v metodě MultiformattedText::DrawText tak, aby používal IDWriteTextLayout::DrawTextLayout.
Deklarujte D2D1_POINT_2F proměnnou a nastavte ji na levý horní bod okna.
D2D1_POINT_2F origin = D2D1::Point2F( static_cast<FLOAT>(rc.left / dpiScaleX_), static_cast<FLOAT>(rc.top / dpiScaleY_) );Nakreslete text na obrazovku zavoláním ID2D1RenderTarget::D rawTextLayout metody Direct2D render target a předáním IDWriteTextLayout ukazatel.
pRT_->DrawTextLayout( origin, pTextLayout_, pBlackBrush_ );
MultiformattedText třída je implementována v MultiformattedText.h a MultiformattedText.cpp.