Písma proměnných OpenType

Toto téma popisuje písma proměnných OpenType, jejich podporu v DirectWrite a Direct2D a způsob jejich použití ve vaší aplikaci. 

Co jsou písma proměnných OpenType?

Verze 1.8 specifikace formátu písma OpenType zavedla nové rozšíření formátu známého jako Varianty písem OpenType. Písma, která tato rozšíření používají, se označují jako písma proměnných OpenType. Proměnná OpenType je jedno písmo, které se může chovat jako několik písem pomocí nepřetržité interpolace mezi různými návrhy, a to vše definované v rámci jednoho písma.

Písmo proměnné OpenType může definovat souvislou variantu návrhu na jedné nebo více nezávislých os, jako je váha nebo šířka:

 

Zobrazuje písmo proměnné OpenType pomocí písmena G a zobrazuje různé varianty podél vodorovné osy šířky a svislé osy hmotnosti.

Vývojář písma určuje sadu os variant, které se mají použít v daném písmu. Tyto osy můžou obsahovat sadu známých (nebo registrovaných) os variant, jako je váha a šířka, ale mohou také zahrnovat libovolnou vlastní osu variace definovanou vývojářem písem.  

Výběrem sady os variant pro písmo definuje vývojář písma abstraktní ndimenzionální prostor varianty návrhu písma. Textové moduly můžou v daném souvislém prostoru pro rozložení a vykreslování textu určit potenciálně libovolnou pozici nebo "instanci". 

Vývojář písem může také vybrat a přiřadit názvy konkrétním instancím v prostoru návrhu varianty; označují se jako pojmenované instance. Například písmo s variací hmotnosti může podporovat souvislou variaci mezi velmi lehkými a velmi těžkými tahy, zatímco vývojář písma vybral konkrétní váhy podél tohoto kontinua a přiřadil jim názvy, jako je "Light", "Regular" a "Semibold". 

Formát písma proměnné OpenType používá tabulky dat nalezené v tradičních písmech OpenType a některé další tabulky, které popisují, jak se hodnoty různých datových položek mění pro různé instance. Formát označuje jednu instanci varianty jako výchozí instanci, která používá tradiční tabulky k získání výchozích hodnot. Všechny ostatní instance závisí na výchozích datech a dalších rozdílových datech. Například tabulka glyf může mít popis bezierové křivky nominálního tvaru glyf, což je obrazec použitý pro výchozí instanci, zatímco tabulka gvar popisuje, jak jsou řídicí body Bezier pro glyf upraveny pro jiné instance. Podobně mohou mít jiné hodnoty písma nominální hodnotu plus rozdílová data popisující, jak se tyto hodnoty mění pro různé instance; Například metriky pro výšku x a další metriky pro šířku písma nebo pozice ukotvení značky specifické pro glyph a úpravy prokládání. 

Vzhledem k tomu, že proměnná písma můžou podporovat libovolnou sadu os variant, vyžadují rozšiřitelný model rodin písem, který přesněji odráží způsob, jakým návrháři písem vytvářejí rodiny písem: rodina písem je definována názvem rodiny a určitými vlastnostmi návrhu, které jsou konstantní, s libovolným číslem (určeným vývojářem písem) způsobů, kterými se návrh může lišit. Jedna řada písem může být vytvořena s variantami pro váhu, ale s variantami pro výšku x, srifovou velikostí, "funkčností" nebo jakýmkoliv přáním vývojáře písem může být vytvořena jiná rodina písem. V tomto modelu je nejlepší použít obecný nebo preferovaný název rodiny nebo typografický název rodiny a sadu párů klíč-hodnota, z nichž každá představuje druh varianty a konkrétní hodnoty, přičemž typy variant obecně představují rozšiřitelnou sadu. Tento obecný pojem řady písem se může použít u tradičních, ne proměnných písem i u proměnných písem. Například v rámci tohoto obecného typografického rodinného modelu může mít rodina "Selawik VF" varianty pro tloušťku, optickou velikost a bezpatkový design s instancemi jako "Semilight Banner Sans". 

Některé stávající softwarové implementace, včetně stávajících rozhraní API DirectWrite, však mohou být navrženy za předpokladu, že je omezenější model rodin písem. Některé aplikace mohou například předpokládat, že řada písem může obsahovat varianty kurzívy a kurzívy, většinou regular, Bold, Kurzíva a Tučné kurzívy. Stávající rozhraní IDWriteFontCollection a IDWriteFontFamily předpokládají model řady weight/stretch/style ("WSS"), který umožňuje zadat varianty v rámci řady pomocí DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH nebo DWRITE_FONT_STYLE výčtů jako parametrů. V předchozím příkladu by optické osy a serifové osy nebyly považovány za osy vnitřní rodiny v modelu WSS. 

Úplná podpora proměnných písem by vyžadovala rozhraní API, která umožňují členovi rodiny zadat potenciálně několik parametrů, jak určuje písmo. Stávající návrhy rozhraní API však mohou být schopné poskytnout částečnou podporu pro různá písma tím, že promítnou pojmenované instance definované v písmu proměnné do více omezených modelů rodiny písem. V předchozím příkladu by "Selawik VF Semilight Banner Sans" mohl být promítnut do modelu WSS jako rodina "Selawik VF Banner Sans" s "Semilight" jako varianta hmotnosti. 

V dalším příkladu zvažte typografickou rodinu písem, jako je Sitka, s variantami hmotnosti a optické velikosti. Pojmenované varianty v rámci rodiny zahrnují Sitka Text Regular a Sitka Banner Bold (plus mnoho dalších). Typografické jméno rodiny je "Sitka", zatímco názvy tváří pro tyto varianty v typografickém rodinném modelu by byly "Text Regular" a "Banner Bold". Modely čtyřčlenné rodiny a řady WSS neumožňují optické varianty velikostí v rámci rodiny, takže rozdíly optické velikosti musí být považovány za rozdíly na úrovni rodiny. Následující tabulka ukazuje, jak by se v modelu rodiny WSS zacházelo s výběrem písem z typografické řady Sitka:

Typografický model rodiny

Model rodiny WSS

Rodina

Obličej

Rodina

Obličej

Sitka

Text – normální

Sitka Text

Pravidelný

Sitka

Banner Tučně

Sitka Banner

Tučný

Sitka

Kurzíva titulků

Titulek Sitka

Kurzíva

 

Projekci názvů z typografického modelu rodiny do modelu rodiny WSS lze použít u ne proměnných písem a na pojmenované instance proměnných písem. To však nelze provést u jiných nenázvových instancí z souvislého prostoru variant návrhu písma proměnné. Z tohoto důvodu bude podpora kompletní funkčnosti proměnných písem vyžadovat rozhraní API navržená tak, aby odkazovala na tváře v typografické rodině z hlediska nekonstruované sady os variant a hodnot os. 

Podpora písma proměnné OpenType v DirectWrite

Od vydání Windows 10 Creators Update je formát písma OpenType stále velmi nový a dodavatelé písem, platformy a aplikace jsou stále v procesu implementace nového formátu. Tato aktualizace poskytuje počáteční implementaci pro tento formát v DirectWrite. 

Interní rozhraní DirectWrite bylo aktualizováno tak, aby podporovalo písma proměnných OpenType. Pomocí aktuálních rozhraní API to poskytuje podporu pro všechny pojmenované instance písma proměnné. Tuto podporu lze použít pro úplné pracovní postupy – od výčtu pojmenovaných instancí, výběru pojmenované instance, použití v rozložení a tvarování až po vykreslování a tisk. Pro výhody aplikací, které také používají interoperabilitu textu GDI pro určité operace, byla v existujících rozhraních API GDI přidána také podobná podpora. 

V systému Windows 10 Creators Update directWrite nepodporuje libovolné instance, které využívají možnosti spojité varianty písem proměnných.

V mnoha operacích nelze chování directWrite pojmenovaných instancí písma proměnné odlišit od chování ne proměnných písem. Vzhledem k tomu, že podpora je poskytována pomocí existujících rozhraní API DirectWrite, pojmenované instance proměnných písem můžou fungovat i v mnoha existujících aplikacích DirectWrite bez jakýchkoli změn. Výjimky však mohou platit v určitých situacích:

  • Pokud aplikace zpracovává data písma přímo pro určité operace. Pokud například aplikace čte data osnovy glyfů přímo ze souboru písem a vytváří určité vizuální efekty.
  • Pokud aplikace pro určité operace používá knihovnu třetí strany. Pokud například aplikace používá pro rozložení DirectWrite, aby získala konečné indexy a pozice glyfů, ale pak k vykreslení používá knihovnu třetí strany.
  • Pokud aplikace vloží data písem do dokumentu nebo jiným způsobem předá data písem podřízeným procesům.

Pokud se operace provádějí pomocí implementací, které nepodporují písma proměnných, nemusí tyto operace vést k očekávaným výsledkům. Například pozice glyfů se můžou vypočítat pro jednu pojmenovanou instanci písma proměnné, ale glyfy se můžou vykreslit za předpokladu, že se jiná pojmenovaná instance. V závislosti na implementaci aplikace můžou výsledky fungovat v některých kontextech, ale ne v jiných kontextech, ve kterých se můžou použít jiné knihovny. Například text se může na obrazovce zobrazovat správně, ale ne při tisku. Pokud jsou kompletní pracovní postupy implementovány pouze pomocí DirectWrite, lze očekávat správné chování pojmenovaných instancí písma proměnné. 

Vzhledem k tomu, že stávající rozhraní API DirectWrite podporují výběr tváří pomocí modelu hmotnosti,roztažení/stylu, budou pojmenované instance písem, které používají jiné osy variant, promítnuty z obecného, typografického rodinného modelu do modelu WSS, jak je popsáno výše. To spoléhá na proměnné písmo, včetně tabulky "atributy stylu" ('STAT') s podtables osy-hodnota, které DWrite používá k rozlišení tokenů názvu tváře, které označují atributy hmotnosti, roztažení nebo stylu od tokenů, které se týkají jiných os variant.  

Pokud písmo proměnné neobsahuje tabulku "STAT", jak je požadováno pro písma proměnných specifikace OpenType, bude directWrite považovat písmo za jiné než proměnné, které obsahuje pouze výchozí instanci.  

Pokud písmo obsahuje tabulku "STAT", ale neobsahuje odpovídající podtabuly hodnot osy, může to vést k neočekávaným výsledkům, jako je například několik tváří, které mají identické názvy tváří. Tato písma nejsou v tuto chvíli podporována. 

Specifikace OpenType umožňuje znázornit data osnovy glyphu v jednom ze dvou formátů: pomocí tabulky glyf, která používá formát osnovy TrueType a nápovědy, nebo pomocí tabulky CFF, která používá reprezentaci Compact Font Format (CFF). V písmu proměnné s obrysy TrueType se tabulka glyf nadále používá a je doplněna tabulkou gvar, která poskytuje data variant pro osnovy. To znamená, že výchozí instance písma proměnné se osnovami TrueType používá pouze tradiční tabulky OpenType, které budou podporovány ve starším softwaru, který nemá podporu písma proměnných. V písmu proměnné se osnovami CFF je však tabulka CFF nahrazena tabulkou CFF2, která zapouzdřuje výchozí data osnovy a přidružená data variant v jedné tabulce. Data CFF se zpracovávají samostatnou rasterizátorem, který se používá pro data TrueType, a tabulka CFF2 vyžaduje aktualizovanou rasterizátor CFF, který má podporu CFF2. Tabulku CFF2 nelze zpracovat staršími rasterizátory CFF. U písma proměnné s daty osnovy CFF to znamená, že i výchozí instance nebude fungovat ve starším softwaru. 

Ve Windows 10 Creators Update directWrite nepodporuje proměnná písma s daty osnovy CFF pomocí tabulky CFF2. 

Použití písem proměnných OpenType

Písma proměnných OpenType se dají snadno používat. Mějte na paměti aktuální omezení uvedená výše:

  • V tuto chvíli se podporují pouze pojmenované instance písma proměnné.
  • V tuto chvíli jsou podporována pouze písma proměnných, která používají data osnovy TrueType (nikoli osnovy CFF). 
  • U písem, která používají osy variant návrhu jiné než váha, roztažení nebo styl, se pojmenované instance promítnou do modelu rodiny WSS, což může vést k tomu, že se některé pojmenované instance zobrazují jako samostatné rodiny (stejně jako v minulosti pro nemístná písma). Aby byla tato možnost podporována, musí mít písma proměnných tabulku STAT, která obsahuje odpovídající podtableny hodnot osy.
  • Pojmenované instance proměnných písem jsou podporovány v rozhraních API DirectWrite, ale pokud se některé operace provádějí ve starších implementacích, které nepodporují písma proměnných, můžou způsobit nesprávné výsledky. 
  • Některá rozhraní API DirectWrite používají při výběru tváří DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH a DWRITE_FONT_STYLE výčty pro určení tloušťky, roztažení a stylu atributů. Pokud písmo proměnné používá odpovídající osy variant, ale má mnoho pojmenovaných instancí, které vyžadují jemně členitost, nebudou v těchto rozhraních API vybrány všechny pojmenované instance.

Písma proměnných OpenType, která vyhovují těmto požadavkům, je možné nainstalovat z prostředí Windows stejně jako jiná písma OpenType a lze je také použít ve vlastních sadách písem vytvořených aplikací.  

Při instalaci v systému budou všechny pojmenované instance proměnné písmo zahrnuty do sady písem vrácené voláním IDWriteFontFamily3::GetSystemFontSet metoda. Všimněte si, že sada písem je plochý seznam bez hierarchie seskupování rodiny, ale každá položka v sadě má vlastnost s názvem rodiny na základě modelu rodiny WSS. Sadu písem lze filtrovat pro konkrétní proměnnou pojmenovanou instanci pomocí IDWriteFontSet::GetMatchingFonts metod. Pokud používáte GetMatchingFonts přetížení, které přebírá familyName, musí zadaný název použít název odpovídající modelu rodiny písem WSS. Úplný seznam názvů rodin kompatibilních s WSS, ke kterým dochází v sadě písem, lze získat pomocí IDWriteFontSet::GetPropertyValues metod pomocí DWRITE_FONT_PROPERTY_ID_FAMILY_NAME.  

Podobně budou všechny pojmenované instance písma proměnné reprezentovány v kolekci písem vrácené IDWriteFactory::GetSystemFontCollection metoda. Vzhledem k tomu, že prvky kolekce písem jsou rodiny písem založené na modelu WSS, pojmenované instance proměnné písmo mohou být reprezentovány v kolekci jako členy dvou nebo více rodin písem. Pokud se používá metoda IDWriteFontCollection::FindFamilyName metoda, musí být parametr familyName název rodiny kompatibilní se službou WSS. Pokud chcete najít všechna rodinná jména kompatibilní s WSS z kolekce písem, aplikace může procházet každou řadu a volat IDWriteFontFamily::GetFamilyNames, i když může být jednodušší získat odpovídající sadu písem a použít GetPropertyValues metodu, jak je popsáno výše. 

Při práci s vlastními písmy je možné k vytvoření sady písem použít různé přístupy popsané v tématu vlastní sady písem. Pokud chcete přidat písmo proměnné do vlastní sady písem, doporučuje se metoda IDWriteFontSetBuilder1::AddFontFile metoda, protože podporuje různá písma a přidá do jednoho volání všechny pojmenované instance písma proměnné. V tuto chvíli neexistuje způsob, jak přidat jednotlivé pojmenované instance vlastní proměnné do sady písem pomocí IDWriteFontSetBuilder::AddFontFaceReference metody, protože neexistuje způsob, jak vytvořit odkaz na řez písma určující, které pojmenované instance ze souboru písma proměnné je určeno. To znamená, že v současné době neexistuje způsob, jak přidat pojmenované instance vlastního písma do vlastní sady písem s přiřazenými vlastními vlastnostmi. To zase znamená, že vlastní písma proměnných se v současné době nedají snadno používat ve spojení s rozhraními API DirectWrite pro vzdálená písma. Pokud jsou pojmenované instance proměnné písma zahrnuty do sady systémových písem, ale odkazy na rozpoznávání tváře písma pro každou pojmenovanou instanci již existují a lze je přidat do vlastních sad písem, včetně použití vlastních hodnot vlastností. Další podrobnosti najdete v tématu Vlastní sady písem. 

Při práci s proměnnými písmy jsou DWRITE_FONT_WEIGHT DirectWrite a DWRITE_FONT_STRETCH výčty úzce spojeny s osami variant hmotnosti a šířky definované ve specifikaci OpenType, ale nejsou stejné. Nejprve číselné měřítko pro libovolnou osu variant vždy podporuje desetinné hodnoty, zatímco fontWeight a fontStretch používají celá čísla. Měřítko osy hmotnosti OpenType používá hodnoty od 1 do 1000, které podporuje také fontWeight. Změna hodnoty osy hmotnosti varianty na fontWeight je relativně malá: Hodnota fontWeight hlášená pro pojmenovanou instanci se proto může zaokrouhlit z přesné hodnoty použité k definování pojmenované instance v rámci písma. Rozdíl mezi měřítkem osy šířky Typu DirectWrite a osou OpenType je větší: DirectWrite používá hodnoty od 1 do 9 za usWidthClass hodnoty tabulky OpenType OS/2, zatímco měřítko osy šířky OpenType používá kladné hodnoty představující procento normální šířky. Dokumentace usWidthClass ve specifikaci OpenType poskytuje mapování mezi hodnotami 1 až 9 a procenty normálních hodnot. Hodnota fontStretch hlášená pro pojmenovanou instanci může zahrnovat zaokrouhlování při převodu z hodnot os šířky. 

Při vytváření IDWriteTextFormatmusí být zadána kolekce písem a vlastnosti písma kompatibilní s WSS (název rodiny, váha, roztažení a styl). To platí také při nastavení vlastností formátování písma v IDWriteTextLayout rozsahu textu. Vlastnosti lze získat z objektu IDWriteFontFace 3 nebo z IDWriteFont a IDWriteFontFamily objekty, které představují konkrétní pojmenovanou instanci. Jak je uvedeno výše, hodnoty vrácené metodou GetWeight a GetStretch mohou být zaokrouhleny aproximace pro skutečné hodnoty osy použité k definování pojmenované instance, ale DirectWrite mapuje kombinaci vlastností zpět na požadovanou pojmenovanou instanci. 

Podobně pokud aplikace používá IDWriteFontFallbackBuilder k vytvoření vlastních záložních dat písma, rodiny jsou určeny pro mapování rozsahů znaků pomocí názvů rodin kompatibilních se službou WSS. Náhradní písmo v rámci DirectWrite je založené na rodinách s DirectWrite, které vyberou variantu v náhradní rodině, která je nejbližší shody pro variantu počáteční rodiny. U variant, které zahrnují jiné rozměry než hmotnost, roztažení a styl, by directWrite v současné době nemohl takové varianty vybrat v rámci náhradní řady, pokud nebyla vytvořena vlastní náhradní data speciálně pro poskytování náhradních mapování pro rodiny, které mají konkrétní atributy mimo WSS, jako jsou například varianty optické velikosti Titulky.