Přehled DWriteCore
DWriteCore je Windows App SDK implementací DirectWrite (DirectWrite je rozhraní DirectX API pro vysoce kvalitní vykreslování textu, kontury písem nezávislých na rozlišení a plnou podporu Unicode pro text a rozvržení). DWriteCore je forma DirectWrite, která běží ve verzích Windows až do Windows 10 verze 1809 (10.0; Build 17763). DWriteCore implementuje stejné rozhraní API jako DirectWrite, s několika dodatky, jak je popsáno v tomto tématu.
Toto úvodní téma popisuje, co je DWriteCore, a ukazuje, jak ho nainstalovat do vývojového prostředí a programovat s ním.
U aplikace, která už používá DirectWrite, vyžaduje přepnutí na DWriteCore minimální změny:
- Přidejte odkaz na balíček Windows App SDK.
- Místo
dwrite_3.h
zahrňtedwrite_core.h
. - Propoj
DWriteCore.lib
místoDWrite.lib
. - Volání DWriteCoreCreateFactory místo DWriteCreateFactory.
Aplikace zase získá výhody sady Windows App SDK – konkrétně přístup k nejnovějším rozhraním API a funkcím bez ohledu na to, jakou verzi Windows zákazník používá.
Tip
Popisy komponent DirectX a odkazy na komponenty DirectX v aktivním vývoji naleznete v blogovém příspěvku Úvodní stránka DirectX.
DirectWrite sám podporuje celou řadu funkcí, díky kterým je preferovaný nástroj pro vykreslování písem na Windows pro většinu aplikací – ať už prostřednictvím přímých volání, nebo prostřednictvím Direct2D. DirectWrite zahrnuje systém rozložení textu nezávislý na zařízení, vysoce kvalitní subpixelové vykreslování textu Microsoft ClearType, hardwarově akcelerovaný text, víceformátový text, pokročilé typografické funkce OpenType®, širokou jazykovou podporu a GDIkompatibilní rozložení a vykreslování. DirectWrite je k dispozici od systému Windows Vista SP2 a v průběhu let se vyvinul, aby zahrnoval pokročilejší funkce, jako jsou proměnná písma, které umožňují použít styly, tloušťky a další atributy na písmo s využitím pouze jednoho fontového zdroje.
Vzhledem k dlouhé životnosti DirectWrite však pokroky ve vývoji mají tendenci opustit starší verze Windows. Kromě toho je postavení DirectWrite jako přední technologie pro vykreslování textu omezeno pouze na systém Windows, takže aplikace pro různé platformy buď vyvíjejí vlastní technologii pro vykreslování textu, nebo se spoléhají na řešení třetích stran.
DWriteCore řeší zásadní problémy jako osiření funkcí jednotlivých verzí a kompatibilitu napříč platformami tím, že odebere knihovnu ze systému a zaměří se na všechny možné podporované koncové body. Za tímto účelem jsme integrovali DWriteCore do sady Windows App SDK.
Primární hodnota, kterou vám DWriteCore poskytuje jako vývojář v sadě Windows App SDK, je, že poskytuje přístup k mnoha (a nakonec všem) funkcím DirectWrite. Všechny funkce DWriteCore budou fungovat stejně ve všech verzích nižší úrovně bez jakýchkoli rozdílů v tom, které funkce můžou fungovat na kterých verzích.
DWriteCore je demonstrován prostřednictvím DWriteCoreGallery ukázkové aplikace, která je nyní k dispozici ke stažení a studiu.
DWriteCore je součástí sady Windows App SDK. Tato část popisuje, jak nastavit vývojové prostředí pro programování pomocí DWriteCore.
Viz Nástroje pro instalaci sady Windows App SDK.
V aplikaci Visual Studio vytvořte nový projekt pomocí šablony projektu Blank App, Packaged (WinUI 3 in Desktop). Tuto šablonu projektu najdete tak, že zvolíte jazyk: jazyk C++; platforma: Windows App SDK; typ projektu: Desktop.
Další informace najdete v tématu šablony projektu pro WinUI 3.
V sadě Visual Studio klikněte na Project>Spravovat balíčky NuGet...>Procházet, zadejte nebo vložte Microsoft.ProjectReunion.DWrite do vyhledávacího pole, vyberte položku ve výsledcích hledání a potom kliknutím na Nainstalovat nainstalujte balíček pro tento projekt.
Alternativně můžete programovat pomocí DWriteCore tak, že začnete s DWriteCoreGallery ukázkový projekt aplikace a založíte vývoj na tomto projektu. Pak můžete z ukázkového projektu odebrat jakýkoli existující zdrojový kód (nebo soubory) a přidat do projektu nový zdrojový kód (nebo soubory).
Další informace o programování pomocí DWriteCore naleznete v části Programování pomocí DWriteCore dále v tomto tématu.
Portování DirectWrite do DWriteCore je dostatečně velký projekt, který zahrnuje více cyklů vydání Windows. Tento projekt je rozdělený do fází, z nichž každá odpovídá bloku funkcí dodaných ve vydané verzi.
DWriteCore je součástí sady Windows App SDK. Obsahuje základní nástroje, které jako vývojář potřebujete využívat DWriteCore, včetně následujících funkcí.
- Výčet písem
- Rozhraní API pro písmo
- Formování.
- Rozhraní nízkoúrovňového vykreslování API Toto je v současné fázi částečné – DWriteCore nespolupracuje s Direct2D, ale můžete použít IDWriteGlyphRunAnalysis a IDWriteBitmapRenderTarget.
- Základní funkce rozložení textu
- Rozhraní API pro vykreslování textu
- Cíl vykreslení rastrového obrázku
- Barevná písma
- Různé optimalizace (čištění mezipaměti písem, nahrávač písem v paměti a podobně)
- Podpora podtržení – viz IDWriteTextLayout::GetUnderline a IDWriteTextLayout::SetUnderline.
- Podpora přeškrtnutí – viz IDWriteTextLayout::GetStrikethrough a IDWriteTextLayout::SetStrikethrough.
- Podpora svislého textu prostřednictvím idWriteTextLayout– viz Svislý text.
- Implementují se všechny metody IDWriteTextAnalyzer a IDWriteTextAnalyzer1 rozhraní.
Výrazným rysem je použití barevných písem. Barevná písma umožňují vykreslovat písma s více sofistikovanými funkcemi barev nad rámec jednoduchých barev. Například barevná písma umožňují vykreslit emoji a písma ikon panelu nástrojů (druhá z nich se používá například v Office). Barevná písma byla poprvé představena ve Windows 8.1, ale tato funkce byla značně rozšířena ve Windows 10 verze 1607 (Anniversary Update).
Práce na vyčištění mezipaměti písem a paměťového zavaděče písem umožňují rychlejší načítání písem a zefektivnění využití paměti.
Díky těmto funkcím můžete okamžitě začít využívat některé moderní základní funkce DirectWrite, jako jsou například různá písma. Proměnná písma jsou jednou z nejdůležitějších funkcí pro zákazníky DirectWrite.
DWriteCore spolu s dalšími komponentami sady Windows App SDK budou vyvinuty s otevřeností vůči zpětné vazbě vývojářů. Zveme vás, abyste začali zkoumat DWriteCore a poskytovat přehledy nebo žádosti o vývoj funkcí v našem úložišti Windows App SDK na GitHubu.
Stejně jako u DirectWrite, programujete pomocí DWriteCore prostřednictvím jeho rozhraní COM-light API, přes rozhraní IDWriteFactory.
Pokud chcete použít DWriteCore, je nutné zahrnout soubor hlavičky dwrite_core.h
.
// pch.h
...
// DWriteCore header file.
#include <dwrite_core.h>
Soubor hlavičky dwrite_core.h
nejprve definuje token DWRITE_COREa pak obsahuje soubor hlavičky dwrite_3.h
. Token DWRITE_CORE je důležitý, protože nasměruje všechny následně zahrnuté hlavičky tak, aby vám zpřístupnila všechna rozhraní API DirectWrite. Jakmile projekt zahrne dwrite_core.h
, můžete pokračovat a psát kód, sestavit a spustit.
Povrch rozhraní API DWriteCore je z velké části stejný jako pro directWrite. Existuje však malý počet nových rozhraní API, která jsou v současné době pouze v DWriteCore.
Volná funkce DWriteCoreCreateFactory vytvoří objekt továrny, který se použije k následnému vytvoření jednotlivých objektů DWriteCore.
DWriteCoreCreateFactory je funkčně stejný jako funkce DWriteCreateFactory exportované systémovou verzí DirectWrite. Funkce DWriteCore má jiný název, aby se zabránilo nejednoznačnosti.
Výčet DWRITE_FACTORY_TYPE má novou konstantu –DWRITE_FACTORY_TYPE_ISOLATED2označující omezenou továrnu. Omezená továrna je více uzamčená než izolovaná továrna. Neinteraguje žádným způsobem s meziprocesní ani s trvalou mezipamětí písem. Kromě toho systémová kolekce písem vrácená z této továrny zahrnuje pouze dobře známá písma. Tady je postup, jak můžete použít DWRITE_FACTORY_TYPE_ISOLATED2 k vytvoření objektu omezené továrny při volání DWriteCoreCreateFactory funkce free.
// Create a factory that doesn't interact with any cross-process nor
// persistent cache state.
winrt::com_ptr<::IDWriteFactory7> spFactory;
winrt::check_hresult(
::DWriteCoreCreateFactory(
DWRITE_FACTORY_TYPE_ISOLATED2,
__uuidof(spFactory),
reinterpret_cast<IUnknown**>(spFactory.put())
)
);
Pokud předáte DWRITE_FACTORY_TYPE_ISOLATED2 starší verzi DirectWrite, která ho nepodporuje, DWriteCreateFactory vrátí E_INVALIDARG.
DirectWrite má rozhraní bitmapového vykreslování, které podporuje vykreslování glyfů do bitmapy v systémové paměti. V současné době je ale jediným způsobem, jak získat přístup k podkladovým pixelovým datům, projít GDI, takže rozhraní API není použitelné pro různé platformy. To se dá snadno napravit přidáním metody pro načtení dat pixelů.
A tak DWriteCore zavádí IDWriteBitmapRenderTarget2 rozhraní a jeho metoda IDWriteBitmapRenderTarget2::GetBitmapData. Tato metoda přijímá parametr typu (ukazatel na) DWRITE_BITMAP_DATA_BGRA32, která je nová struktura.
Aplikace vytvoří bitmapový cíl renderování voláním IDWriteGdiInterop::CreateBitmapRenderTarget. Ve Windows rastrový cíl vykreslování zapouzdřuje GDI paměťové DC s vybranou GDI bitovou mapou nezávislou na zařízení (DIB). IDWriteBitmapRenderTarget::DrawGlyphRun vykresluje glyfy do DIB. DirectWrite vykreslí samotné glyfy bez procházení GDI. Aplikace pak může získat HDC z cíle vykreslení rastrového obrázku a pomocí BitBlt zkopírovat pixely do okna HDC.
Na jiných platformách než Windows může vaše aplikace stále vytvořit cíl vykreslení rastrového obrázku, ale jednoduše zapouzdří pole systémové paměti bez HDC a bez DIB. Bez HDCmusí existovat jiný způsob, jak aplikace získat rastrové pixely, aby je mohl kopírovat, nebo je jinak použít. I ve Windows je někdy užitečné získat skutečná data pixelů a v následujícím příkladu kódu si ukážeme aktuální způsob, jak to udělat.
// pch.h
#pragma once
#include <windows.h>
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>
// WinMain.cpp
#include "pch.h"
#include <dwrite_core.h>
#pragma comment(lib, "Gdi32")
class TextRenderer
{
DWRITE_BITMAP_DATA_BGRA32 m_targetBitmapData;
public:
void InitializeBitmapData(winrt::com_ptr<IDWriteBitmapRenderTarget> const& renderTarget)
{
// Query the bitmap render target for the new interface.
winrt::com_ptr<IDWriteBitmapRenderTarget2> renderTarget2;
renderTarget2 = renderTarget.try_as<IDWriteBitmapRenderTarget2>();
if (renderTarget2)
{
// IDWriteBitmapRenderTarget2 exists, so we can get the bitmap the easy way.
winrt::check_hresult(renderTarget2->GetBitmapData(OUT & m_targetBitmapData));
}
else
{
// We're using an older version that doesn't implement IDWriteBitmapRenderTarget2,
// so we have to get the bitmap by going through GDI. First get the bitmap handle.
HDC hdc = renderTarget->GetMemoryDC();
winrt::handle dibHandle{ GetCurrentObject(hdc, OBJ_BITMAP) };
winrt::check_bool(bool{ dibHandle });
// Call a GDI function to fill in the DIBSECTION structure for the bitmap.
DIBSECTION dib;
winrt::check_bool(GetObject(dibHandle.get(), sizeof(dib), &dib));
m_targetBitmapData.width = dib.dsBm.bmWidth;
m_targetBitmapData.height = dib.dsBm.bmHeight;
m_targetBitmapData.pixels = static_cast<uint32_t*>(dib.dsBm.bmBits);
}
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
TextRenderer textRenderer;
winrt::com_ptr<IDWriteBitmapRenderTarget> renderTarget{ /* ... */ };
textRenderer.InitializeBitmapData(renderTarget);
}
Existuje několik rozhraní API, která jsou pouze stuby, nebo se chovají poněkud odlišně na platformách mimo Windows. Například IDWriteGdiInterop::CreateFontFaceFromHdc vrací E_NOTIMPL na jiných platformách než Windows, protože neexistuje žádná taková věc jako HDC bez GDI.
A nakonec existují určitá další rozhraní API systému Windows, která se obvykle používají společně s Rozhraním DirectWrite (to je velmi praktický příklad Direct2D). V současné době ale direct2D a DWriteCore nespolupracují. Pokud například vytvoříte IDWriteTextLayout pomocí DWriteCore a předáte ho D2D1RenderTarget::DrawTextLayout, pak toto volání selže.