OpenType-Variablenschriftarten

In diesem Thema werden OpenType-Variablenschriftarten, deren Unterstützung in DirectWrite und Direct2D sowie deren Verwendung in Ihrer App beschrieben. 

Was sind OpenType-Variablenschriftarten?

Version 1.8 der OpenType-Schriftformatspezifikation führte eine neue Erweiterung für das Format ein, das als OpenType-Schriftartvariationen bekannt ist. Schriftarten, die diese Erweiterungen verwenden, werden als OpenType-Variablenschriftarten bezeichnet. Eine OpenType-Variablenschriftart ist eine einzelne Schriftart, die sich wie mehrere Schriftarten verhalten kann, indem sie eine kontinuierliche Interpolation zwischen verschiedenen Designs verwendet, die alle innerhalb der einzelnen Schriftart definiert sind.

Eine OpenType-Variablenschriftart kann eine kontinuierliche Variation ihres Designs entlang einer oder mehrerer unabhängiger Achsen definieren, z. B. Gewichtung oder Breite:

 

Zeigt eine OpenType-Variablenschriftart mit dem Buchstaben

Ein Schriftartenentwickler bestimmt eine Reihe von Variationsachsen, die in einer bestimmten Schriftart verwendet werden sollen. Diese Achsen können eine Reihe bekannter (oder "registrierter") Variationsachsen wie Gewichtung und Breite enthalten, aber sie können auch beliebige, benutzerdefinierte Variationsachsen enthalten, die vom Schriftartenentwickler definiert werden.  

Durch Auswählen einer Reihe von Variationsachsen für eine Schriftart definiert der Schriftartentwickler einen abstrakten, n-dimensionalen Raum der Entwurfsvariation für die Schriftart. Text-Engines können potenziell eine beliebige Position oder "instance" innerhalb dieses kontinuierlichen Raums zum Auslegen und Rendern von Text angeben. 

Der Schriftartenentwickler kann auch bestimmte Instanzen innerhalb des Entwurfsvariationsraums auswählen und Namen zuweisen. diese werden als "benannte Instanzen" bezeichnet. Beispielsweise kann eine Schriftart mit Gewichtsvariation kontinuierliche Variationen zwischen sehr leichten und sehr schweren Strichen unterstützen, während der Schriftartentwickler bestimmte Gewichte entlang dieses Kontinuums ausgewählt und ihnen Namen zugewiesen hat, z. B. "Light", "Regular" und "Semibold". 

Das OpenType-Variablenschriftformat verwendet Datentabellen in herkömmlichen OpenType-Schriftarten sowie bestimmte zusätzliche Tabellen, die beschreiben, wie sich die Werte verschiedener Datenelemente für verschiedene Instanzen ändern. Das Format bezeichnet eine Variante instance als "Standard-instance", die herkömmliche Tabellen verwendet, um Standardwerte abzurufen. Alle anderen Instanzen hängen von den Standarddaten und anderen Deltadaten ab. Beispielsweise kann eine "glyf"-Tabelle eine Bezierkurvenbeschreibung einer nominalen Glyphe-Form aufweisen, die für die Standard-instance verwendet wird, während eine "gvar"-Tabelle beschreibt, wie die Bezier-Kontrollpunkte für die Glyphe für andere Instanzen angepasst werden. Ebenso können andere Schriftartwerte einen Nominalwert plus Deltadaten aufweisen, die beschreiben, wie sich diese Werte für verschiedene Instanzen ändern. beispielsweise x-height und andere schriftartweite Metriken oder glyphenspezifische Mark-Anchoring-Positionen und Kerninganpassungen. 

Da variable Schriftarten einen beliebigen Satz von Schwankungsachsen unterstützen können, benötigen sie ein erweiterbares Modell von Schriftartenfamilien, das direkter widerspiegelt, wie Schriftartendesigner Schriftartfamilien erstellen: Eine Schriftartenfamilie wird durch einen Familiennamen und bestimmte konstante Designmerkmale definiert, mit einer beliebigen Anzahl (vom Schriftartenentwickler bestimmt), wie der Entwurf variieren kann. Eine Schriftfamilie kann mit Varianten für die Gewichtung erstellt werden, aber eine andere Schriftfamilie kann mit Varianten für x-Height, Serifengröße, Funkiness oder was auch immer der Schriftartenentwickler wünscht, erstellt werden. In diesem Modell wird eine Schriftartenauswahl am besten mithilfe des allgemeinen oder "bevorzugten" oder "typografischen" Familiennamens sowie einer Reihe von Schlüssel-Wert-Paaren beschrieben, die jeweils eine Art von Variation und einen bestimmten Wert darstellen, wobei die Arten von Variationen im Allgemeinen eine erweiterbare Menge sind. Dieser allgemeine Begriff einer Schriftartenfamilie kann sowohl für herkömmliche, nicht variable Schriftarten als auch für variable Schriftarten gelten. Unter diesem allgemeinen typografischen Familienmodell kann beispielsweise eine Familie "Selawik VF" Variationen für Gewicht, optische Größe und Serifendesign mit Instanzen wie "Semilight Banner Sans" aufweisen. 

Einige vorhandene Softwareimplementierungen, einschließlich vorhandener DirectWrite-APIs, können jedoch unter der Annahme eines eingeschränkteren Modells von Schriftfamilien entworfen werden. Einige Anwendungen können beispielsweise davon ausgehen, dass eine Schriftfamilie höchstens die Varianten Regular, Bold, Italic und Bold Italic aufweisen kann. Die vorhandenen Schnittstellen IDWriteFontCollection und IDWriteFontFamily gehen von einem WSS-Familienmodell (Weight/Stretch/Style) aus, sodass Varianten innerhalb einer Familie mithilfe der DWRITE_FONT_WEIGHT-, DWRITE_FONT_STRETCH- oder DWRITE_FONT_STYLE-Enumerationen als Parameter angegeben werden können. Im vorherigen Beispiel würden die optische Größe und die Serifenachse im WSS-Modell nicht als familieninterne Variationsachsen behandelt. 

Für die vollständige Unterstützung von Variablenschriftarten wären APIs erforderlich, mit denen ein Familienmitglied mit potenziell mehreren Parametern angegeben werden kann, die von der Schriftart bestimmt werden. Vorhandene API-Designs können jedoch möglicherweise teilweise Unterstützung für Variablenschriftarten bieten, indem die benannten Instanzen, die in einer Variablenschriftart definiert sind, in die stärker eingeschränkten Schriftartenmodelle projiziert werden. Im vorherigen Beispiel konnte "Selawik VF Semilight Banner Sans" als "Selawik VF Banner Sans"-Familie mit "Semilight" als Gewichtsvariante in das WSS-Modell projiziert werden. 

Ein weiteres Beispiel ist eine typografische Schriftfamilie wie Sitka mit Varianten der Gewichtung und optischen Größe. Benannte Varianten innerhalb der Familie umfassen Sitka Text Regular und Sitka Banner Bold (sowie viele andere). Der typografische Familienname lautet "Sitka", während die Gesichtsnamen für diese Varianten im typografischen Familienmodell "Text Regular" und "Banner Bold" sein würden. Die Vier-Mitglieder- und WSS-Familienmodelle lassen keine optischen Größenvarianten innerhalb einer Familie zu, sodass optische Größenunterschiede wie Unterscheidungen auf Familienebene behandelt werden müssen. Die folgende Tabelle veranschaulicht, wie eine Auswahl von Schriftarten aus der typografischen Sitka-Familie im WSS-Familienmodell behandelt wird:

Typografisches Familienmodell

WSS-Familienmodell

Familie

Gesicht

Familie

Gesicht

Sitka

Regulärer Text

Sitka-Text

Regulär

Sitka

Banner fett

Sitka Banner

Fett

Sitka

Beschriftung kursiv

Sitka-Beschriftung

Kursiv

 

Die Projektion von Namen aus einem typografischen Familienmodell auf das WSS-Familienmodell kann auf nicht variable Schriftarten und auf die benannten Instanzen von Variablenschriftarten angewendet werden. Dies kann jedoch nicht für andere, nicht benannte Instanzen aus dem kontinuierlichen Entwurfsvariationsraum einer variablen Schriftart erfolgen. Aus diesem Grund erfordert die Unterstützung der vollständigen Funktionalität von Variablenschriftarten APIs, die entwickelt wurden, um auf Gesichter innerhalb einer typografischen Familie in Bezug auf einen uneingeschränkten Satz von Variationsachsen und Achsenwerten zu verweisen. 

Unterstützung der OpenType-Variablenschriftart in DirectWrite

Seit der Veröffentlichung des Windows 10 Creators Update ist das OpenType-Variablenschriftformat noch sehr neu, und Schriftartenhersteller, Plattformen und Apps sind noch dabei, das neue Format zu implementieren. Dieses Update bietet die erste Implementierung für dieses Format in DirectWrite. 

DirectWrite internen Elemente wurden aktualisiert, um OpenType-Variablenschriftarten zu unterstützen. Mit aktuellen APIs bietet dies Unterstützung für alle benannten Instanzen einer Variablenschriftart. Diese Unterstützung kann für vollständige Workflows verwendet werden – von der Enumeration der benannten Instanzen über die Auswahl eines benannten instance, die Verwendung in Layout und Strukturierung bis hin zum Rendern und Drucken. Für Apps, die auch GDI-Textinterop für bestimmte Vorgänge verwenden, wurde eine ähnliche Unterstützung auch in vorhandenen GDI-APIs hinzugefügt. 

Im Windows 10 Creators Update unterstützt DirectWrite keine beliebigen Instanzen, die die Continuous-Variation-Funktion von Variablenschriftarten nutzen.

In vielen Vorgängen kann das Verhalten in DirectWrite benannter Instanzen einer Variablenschriftart nicht vom Verhalten nicht variabler Schriftarten unterschieden werden. Und da die Unterstützung mithilfe vorhandener DirectWrite-APIs bereitgestellt wird, können die benannten Instanzen von Variablenschriftarten sogar in vielen vorhandenen DirectWrite-Apps ohne Änderungen funktionieren. Ausnahmen können jedoch in bestimmten Situationen gelten:

  • Wenn eine App Schriftartdaten für bestimmte Vorgänge direkt verarbeitet. Beispielsweise, wenn eine App Glyphenkonturdaten direkt aus der Schriftartdatei liest, um bestimmte visuelle Effekte zu erzeugen.
  • Wenn eine App eine Drittanbieterbibliothek für bestimmte Vorgänge verwendet. Wenn eine App z. B. DirectWrite für das Layout verwendet, um endgültige Glyphenindizes und Positionen abzurufen, dann aber eine Drittanbieterbibliothek zum Rendern verwendet.
  • Wenn eine App Schriftartdaten in ein Dokument einbettet oder auf andere Weise Schriftartdaten an einen nachgeschalteten Prozess übergibt.

Wenn Vorgänge mit Implementierungen ausgeführt werden, die keine Variablenschriftarten unterstützen, führen diese Vorgänge möglicherweise nicht zu den erwarteten Ergebnissen. Beispielsweise können Glyphenpositionen für eine benannte instance der Variablenschriftart berechnet werden, aber die Glyphen können unter der Annahme eines anderen namens instance gerendert werden. Abhängig von der Anwendungsimplementierung funktionieren Ergebnisse möglicherweise in einigen Kontexten, aber nicht in anderen Kontexten, in denen andere Bibliotheken verwendet werden können. Beispielsweise wird Text möglicherweise ordnungsgemäß auf dem Bildschirm angezeigt, aber nicht, wenn er gedruckt wird. Wenn End-to-End-Workflows nur mit DirectWrite implementiert werden, kann ein korrektes Verhalten für benannte Instanzen einer Variablenschriftart erwartet werden. 

Da vorhandene DirectWrite-APIs die Gesichtsauswahl mithilfe des Gewichtungs-/ Stretch-/Stilmodells unterstützen, werden die benannten Instanzen von Schriftarten, die andere Variationsachsen verwenden, wie oben beschrieben aus dem allgemeinen typografischen Familienmodell in das WSS-Modell projiziert. Dies basiert auf einer variablen Schriftart, einschließlich einer STAT-Tabelle (Formatvorlagenattribute) mit Achsen-Wert-Untertabellen, die DWrite verwendet, um Gesichtsnamenstoken zu unterscheiden, die Gewichtungs-, Stretch- oder Stilattribute festlegen, von Token, die sich auf andere Variationsachsen beziehen.  

Wenn eine Variablenschriftart keine Tabelle "STAT" enthält, wie dies für Variablenschriftarten nach der OpenType-Spezifikation erforderlich ist, behandelt DirectWrite die Schriftart als nicht variable Schriftart, die nur die Standard-instance enthält.  

Wenn eine Schriftart eine "STAT"-Tabelle enthält, aber keine geeigneten Achsenwertuntertabellen enthält, kann dies zu unerwarteten Ergebnissen führen, z. B. zu mehreren Gesichtern mit identischen Gesichtsnamen. Solche Schriftarten werden derzeit nicht unterstützt. 

Die OpenType-Spezifikation ermöglicht die Darstellung von Glyphengliederungsdaten in einem von zwei Formaten: mit einer "glyf"-Tabelle, die trueType-Gliederung und -Hintingformat verwendet, oder mit einer "CFF"-Tabelle, die die Darstellung der kompakten Schriftarten (Compact Font Format, CFF) verwendet. In einer Variablenschriftart mit TrueType-Konturen wird die Tabelle "glyf" weiterhin verwendet und durch eine "gvar"-Tabelle ergänzt, die die Variationsdaten für die Gliederungen bereitstellt. Dies bedeutet, dass die Standard-instance einer Variablenschriftart mit TrueType-Gliederungen nur herkömmliche OpenType-Tabellen verwendet, die in älteren Software ohne Unterstützung für variable Schriftarten unterstützt werden. In einer Variablenschriftart mit CFF-Konturen wird die Tabelle "CFF" jedoch durch die Tabelle "CFF2" ersetzt, die die Standardgliederungsdaten und die zugeordneten Variationsdaten in einer Tabelle kapselt. CFF-Daten werden von einem separaten Rasterisierer verarbeitet, der für TrueType-Daten verwendet wird, und eine "CFF2"-Tabelle erfordert einen aktualisierten CFF-Rasterizer, der "CFF2" unterstützt. Eine "CFF2"-Tabelle kann nicht von älteren CFF-Rasterizern verarbeitet werden. Für eine variable Schriftart mit CFF-Gliederungsdaten bedeutet dies, dass selbst die Standard-instance in älteren Software nicht funktioniert. 

Im Windows 10 Creators Update unterstützt DirectWrite keine Variablenschriftarten mit CFF-Gliederungsdaten mithilfe der Tabelle "CFF2". 

Verwenden von OpenType-Variablenschriftarten

OpenType-Variablenschriftarten können einfach zu verwenden sein, wobei die aktuellen Einschränkungen beachtet werden, die oben aufgeführt sind:

  • Derzeit werden nur benannte Instanzen einer Variablenschriftart unterstützt.
  • Derzeit werden nur Variablenschriftarten unterstützt, die TrueType-Glyphengliederungsdaten (nicht CFF-Konturen) verwenden. 
  • Für Schriftarten, die andere Achsen der Entwurfsvariation als Gewichtung, Stretch oder Stil verwenden, werden benannte Instanzen in das WSS-Familienmodell projiziert, was dazu führen kann, dass einige benannte Instanzen als separate Familien angezeigt werden (wie es in der Vergangenheit bei nicht variablen Schriftarten der Fall war). Um dies zu unterstützen, müssen variable Schriftarten über eine Tabelle "STAT" verfügen, die entsprechende Achsenwertuntertabellen enthält.
  • Benannte Instanzen von Variablenschriftarten werden in DirectWrite-APIs unterstützt, aber wenn bestimmte Vorgänge in älteren Implementierungen ausgeführt werden, die variable Schriftarten nicht unterstützen, können diese zu falschen Ergebnissen führen. 
  • Bestimmte DirectWrite-APIs verwenden die DWRITE_FONT_WEIGHT-, DWRITE_FONT_STRETCH- und DWRITE_FONT_STYLE-Enumerationen zum Angeben von Gewichts-, Stretch- und Stilattributen bei der Auswahl von Gesichtern. Wenn eine variable Schriftart entsprechende Variationsachsen verwendet, aber viele benannte Instanzen aufweist, die eine genauere Granularität erfordern, können nicht alle benannten Instanzen in diesen APIs ausgewählt werden.

OpenType-Variablenschriftarten, die diesen Anforderungen entsprechen, können wie andere OpenType-Schriftarten über die Windows-Shell installiert werden und auch in benutzerdefinierten Schriftarten verwendet werden, die von einer App erstellt wurden.  

Bei der Installation im System werden alle benannten Instanzen einer Variablenschriftart in den Schriftartsatz eingeschlossen, der durch Aufrufen der IDWriteFontFamily3::GetSystemFontSet-Methode zurückgegeben wird. Beachten Sie, dass ein Schriftartsatz eine flache Liste ohne eine Hierarchie zur Familiengruppierung ist, aber jedes Element im Satz eine Familiennameneigenschaft hat, die auf dem WSS-Familienmodell basiert. Der Schriftartsatz kann mithilfe der IDWriteFontSet::GetMatchingFonts-Methoden nach einer bestimmten Variablenschriftart namens instance gefiltert werden. Wenn Sie jedoch die GetMatchingFonts-Überladung verwenden, die einen familyName verwendet, muss der angegebene familyName den Namen verwenden, der dem WSS-Schriftfamilienmodell entspricht. Die vollständige Liste der WSS-kompatiblen Familiennamen in einem Schriftartensatz kann mithilfe der IDWriteFontSet::GetPropertyValues-Methoden mithilfe von DWRITE_FONT_PROPERTY_ID_FAMILY_NAME abgerufen werden.  

Auf ähnliche Weise werden alle benannten Instanzen einer Variablenschriftart in der Schriftartauflistung dargestellt, die von der IDWriteFactory::GetSystemFontCollection-Methode zurückgegeben wird. Da es sich bei den Elementen einer Schriftartensammlung um Schriftfamilien handelt, die auf dem WSS-Modell basieren, können die benannten Instanzen einer Variablenschriftart in einer Auflistung als Member von zwei oder mehr Schriftartfamilien dargestellt werden. Wenn die IDWriteFontCollection::FindFamilyName-Methode verwendet wird, muss der familyName-Parameter ein WSS-kompatibler Familienname sein. Um alle WSS-kompatiblen Familiennamen aus einer Schriftartensammlung zu finden, kann eine App jede Familie durchlaufen und IDWriteFontFamily::GetFamilyNames aufrufen, obwohl es einfacher sein kann, einen entsprechenden Schriftartsatz abzurufen und die GetPropertyValues-Methode wie oben beschrieben zu verwenden. 

Beim Arbeiten mit benutzerdefinierten Schriftarten können verschiedene Ansätze verwendet werden, die im Thema Benutzerdefinierte Schriftartensätze beschrieben werden, um einen Schriftartsatz zu erstellen. Zum Hinzufügen einer variablen Schriftart zu einem benutzerdefinierten Schriftartsatz wird die IDWriteFontSetBuilder1::AddFontFile-Methode empfohlen, da sie variable Schriftarten unterstützt und alle benannten Instanzen einer Variablenschrift in einem einzigen Aufruf hinzu fügt. Es gibt derzeit keine Möglichkeit, einzelne benannte Instanzen einer benutzerdefinierten Variablenschriftart mithilfe der IDWriteFontSetBuilder::AddFontFaceReference-Methoden zu einem Schriftartensatz hinzuzufügen, da es keine Möglichkeit gibt, einen Schriftsichtverweis zu erstellen, der angibt, welche der benannten Instanzen aus einer Variablenschriftdatei vorgesehen ist. Dies bedeutet, dass es derzeit keine Möglichkeit gibt, benannte Instanzen einer benutzerdefinierten Schriftart zu einem benutzerdefinierten Schriftartsatz mit zugewiesenen benutzerdefinierten Eigenschaften hinzuzufügen. Dies wiederum bedeutet, dass benutzerdefinierte Variablenschriftarten derzeit nicht einfach in Verbindung mit DirectWrite-APIs für Remoteschriftarten verwendet werden können. Wenn benannte Instanzen einer Variablenschriftart in einem Systemschriftartensatz enthalten sind, sind jedoch bereits Schriftsichtverweise für jede benannte instance vorhanden, und diese können benutzerdefinierten Schriftartsätzen hinzugefügt werden, einschließlich der Verwendung benutzerdefinierter Eigenschaftenwerte. Weitere Informationen finden Sie im Thema Benutzerdefinierte Schriftartsätze. 

Bei der Arbeit mit Variablenschriftarten sind die DirectWrite DWRITE_FONT_WEIGHT- und DWRITE_FONT_STRETCH-Enumerationen eng mit den in der OpenType-Spezifikation definierten Änderungsachsen für Gewicht und Breite verbunden, sind aber nicht identisch. Erstens unterstützt die numerische Skalierung für jede Variationsachse immer Bruchwerte, während fontWeight und fontStretch ganze Zahlen verwenden. Die OpenType-Gewichtungsachsenskala verwendet Werte zwischen 1 und 1000, was auch von fontWeight unterstützt wird. Daher ist die Änderung von einem Wert der Variationsgewichtsachse zu fontWeight relativ gering: Der für eine benannte instance gemeldete fontWeight kann von dem genauen Wert gerundet werden, der zum Definieren des benannten instance innerhalb der Schriftart verwendet wird. Der Unterschied zwischen DirectWrite fontStretch und der OpenType-Breitenachsenskala ist größer: DirectWrite verwendet Werte von 1 bis 9, wobei die Werte usWidthClass der OpenType OS/2-Tabelle folgen, während die OpenType-Breitenachsenskala positive Werte verwendet, die einen Prozentsatz der normalen Breite darstellen. Die UsWidthClass-Dokumentation in der OpenType-Spezifikation bietet eine Zuordnung zwischen Werten 1 bis 9 und Prozent der Normalwerte. Der fontStretch-Wert, der für einen benannten instance gemeldet wird, kann beim Konvertieren von Breitenachsenwerten eine Rundung beinhalten. 

Beim Erstellen eines IDWriteTextFormat müssen eine Schriftartsammlung und WSS-kompatible Schriftarteigenschaften (Familienname, Gewicht, Stretch und Stil) angegeben werden. Dies gilt auch beim Festlegen von Schriftartformatierungseigenschaften für einen IDWriteTextLayout-Textbereich . Die Eigenschaften können von einem IDWriteFontFace3-Objekt oder von IDWriteFont- und IDWriteFontFamily-Objekten abgerufen werden, die eine bestimmte benannte instance darstellen. Wie oben beschrieben, können die von den Methoden GetWeight und GetStretch zurückgegebenen Werte gerundete Näherungswerte für die tatsächlichen Achsenwerte sein, die zum Definieren des benannten instance verwendet werden, aber DirectWrite zuordnen die Kombination der Eigenschaften dem gewünschten benannten instance. 

Wenn eine App IDWriteFontFallbackBuilder zum Erstellen von Fallbackdaten für benutzerdefinierte Schriftarten verwendet, werden Familien für Zeichenbereichszuordnungen mit WSS-kompatiblen Familiennamen angegeben. Das Schriftartfallback in DirectWrite basiert auf Familien mit DirectWrite Auswahl einer Variante innerhalb einer Fallbackfamilie, die der Variante der Startfamilie am nächsten entspricht. Bei Varianten, die andere Dimensionen als Gewicht, Stretch und Stil umfassen, können DirectWrite derzeit solche Varianten innerhalb einer Fallbackfamilie nicht auswählen, es sei denn, benutzerdefinierte Fallbackdaten wurden speziell erstellt, um Fallbackzuordnungen für Familien bereitzustellen, die bestimmte Nicht-WSS-Attribute aufweisen, z. B. "Caption"-Größenvarianten.