OpenType-Variablenschriftarten

In diesem Thema werden OpenType-Variable-Schriftarten, deren Unterstützung in DirectWrite und Direct2D beschrieben und wie sie in Ihrer App verwendet werden. 

Was sind OpenType-Variable-Schriftarten?

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

Eine OpenType-Variable-Schriftart kann eine kontinuierliche Variation ihres Designs entlang einer oder mehrerer unabhängigen Achsen definieren, z. B. Gewicht oder Breite:

 

Shows an OpenType variable font using the letter 'G' and showing different variations along a horizontal width axis and a vertical weight axis.

Ein Schriftartentwickler bestimmt eine Reihe von Variationsachsen, die in einer bestimmten Schriftart verwendet werden sollen. Diese Achsen können eine Reihe bekannter (oder "registrierter") Achsen der Variation enthalten, z. B. Gewicht und Breite, aber sie können auch beliebige, benutzerdefinierte Achsen enthalten, die vom Schriftartentwickler definiert sind.  

Durch Auswählen einer Reihe von Variationsachsen für eine Schriftart definiert der Schriftartentwickler einen abstrakten, ndimensionalen Raum der Entwurfsvariation für die Schriftart. Textmodulen können potenziell jede Position oder "Instanz" innerhalb dieses kontinuierlichen Raums angeben, um Text zu erstellen und zu rendern. 

Der Schriftartentwickler kann auch Namen für bestimmte Instanzen innerhalb des Entwurfsvariationsbereichs auswählen und zuweisen; diese werden als "benannte Instanzen" bezeichnet. Beispielsweise kann eine Schriftart mit Gewichtsvariation eine kontinuierliche Variation zwischen sehr hellen 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 Format der Variablenschriftart OpenType verwendet Datentabellen, die in herkömmlichen OpenType-Schriftarten gefunden wurden, sowie bestimmte zusätzliche Tabellen, die beschreiben, wie sich die Werte verschiedener Datenelemente für verschiedene Instanzen ändern. Das Format bestimmt eine Variationsinstanz als "Standardinstanz", die traditionelle Tabellen verwendet, um Standardwerte abzurufen. Alle anderen Instanzen hängen von den Standarddaten und anderen Deltadaten ab. Beispielsweise kann eine Tabelle "glyf" eine Bezier-Kurve-Beschreibung einer Nominal-Glyph-Form haben, die für die Standardinstanz verwendet wird, während eine Tabelle "gvar" beschreibt, wie die Bezier-Steuerelementpunkte für die Glyphen für andere Instanzen angepasst werden. Ähnlich können andere Schriftartwerte einen Nennwert plus Deltadaten aufweisen, die beschreiben, wie sich diese Werte für verschiedene Instanzen ändern; z. B. X-Höhe und andere schriftartweite Metriken oder Glyphenspezifische Markierungsankerpositionen und Kerninganpassungen. 

Da variable Schriftarten eine beliebige Reihe von Variationsachsen unterstützen können, benötigen sie ein erweiterbares Modell von Schriftfamilien, die direkt darauf zurückzuführen sind, wie Schriftartendesigner Familien von Schriftarten erstellen: eine Schriftartfamilie wird durch einen Familiennamen und bestimmte Designeigenschaften definiert, die konstant sind, mit einer beliebigen Zahl (bestimmt durch den Schriftartentwickler) von Möglichkeiten, wie das Design variieren kann. Eine Schriftartfamilie kann mit Varianten für Gewicht erstellt werden, aber eine andere Schriftartfamilie kann mit Varianten für x-Height, Serifengröße, "Funkheit" oder was auch immer der Schriftartentwickler wünschen. In diesem Modell wird eine Schriftzeichenauswahl am besten mithilfe der allgemeinen oder "bevorzugten" oder "typografischen" oder "typografischen", Familiennamen plus einer Reihe von Schlüsselwertpaaren beschrieben, die jeweils eine Art von Variation und spezifischen Wert darstellen, wobei die Arten der Variation im Allgemeinen eine erweiterbare Gruppe sein. Diese allgemeine Vorstellung einer Schriftartfamilie kann auf traditionelle, nicht variable Schriftarten sowie auf variable Schriftarten angewendet werden. Unter diesem allgemeinen typografischen Familienmodell kann beispielsweise eine Familie "Selawik VF" Varianten für Gewicht, optische Größe und Serifendesign mit Instanzen wie "Semilight Banner Sans" haben. 

Einige vorhandene Softwareimplementierungen, einschließlich vorhandener DirectWrite-APIs, können jedoch unter Annahme eines eingeschränkteren Modells von Schriftartfamilien entwickelt werden. Einige Anwendungen können beispielsweise davon ausgehen, dass eine Schriftartfamilie in den meisten Fällen Reguläre, Fett, Italic und Bold Italic-Varianten aufweisen kann. Die vorhandenen IDWriteFontCollection- und IDWriteFontFamily-Schnittstellen übernehmen eine Gewichtung/Stretch/Style ("WSS")-Familienmodell, wodurch 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ürde die optische Größe und serifenachse nicht als familieninterne Achsen der Variation im WSS-Modell behandelt werden. 

Die vollständige Unterstützung für variable Schriftarten erfordert APIs, mit denen ein Familienmitglied mit potenziell mehreren Parametern angegeben werden kann, wie von der Schriftart bestimmt. Vorhandene API-Designs können jedoch teilweise Unterstützung für variable Schriftarten bereitstellen, indem die benannten Instanzen, die in einer variablen Schriftart definiert sind, in die mehr eingeschränkten Schriftartenmodelle projiziert werden. Im vorherigen Beispiel könnte "Selawik VF Semilight Banner Sans" in das WSS-Modell als "Selawik VF Banner Sans"-Familie mit "Semilight" als Gewichtsvariante projiziert werden. 

Ein weiteres Beispiel ist eine typografische Schriftfamilie wie Sitka mit Gewicht und optischer Größe. Benannte Varianten in der Familie umfassen Sitka Text Regular und Sitka Banner Bold (plus viele andere). Der typografische Familienname ist "Sitka", während die Gesichtsnamen für diese Varianten im typografischen Familienmodell "Text Regular" und "Banner Fett" sein würden. Die vier Member- und WSS Familienmodelle dürfen keine optischen Größenvarianten innerhalb einer Familie zulassen, und so müssen optische Größenunterschiede wie Familienebenen unterschieden werden. In der folgenden Tabelle wird veranschaulicht, wie eine Auswahl von Schriftarten aus der typografischen Familie Sitka im WSS Familienmodell behandelt werden würde:

Typografisches Familienmodell

WSS Familienmodell

Familie

Gesichtserkennung

Familie

Gesichtserkennung

Sitka

Regulärer Text

Sitka-Text

Regulär

Sitka

Banner fett

Sitka-Banner

Fett

Sitka

Beschriftungs-Italic

Sitka-Beschriftung

Kursiv

 

Die Projektion von Namen aus einem typografischen Familienmodell auf das WSS Familienmodell kann auf nicht variable Schriftarten angewendet werden und auf die benannten Instanzen von Variablenschriftarten. Dies kann jedoch für andere nicht benannte Instanzen aus dem kontinuierlichen Entwurfsvariationsbereich einer variablen Schriftart nicht ausgeführt werden. Aus diesem Grund erfordert die Unterstützung für die vollständige Funktionalität von variablen Schriftarten APIs, die auf Gesichter in einer typografischen Familie in Bezug auf eine nicht konfigurierte Gruppe von Variationsachsen und Achsenwerten verweisen. 

Unterstützung der OpenType-Variablenschriftart in DirectWrite

Seit der Veröffentlichung des Windows 10 Creators Update ist das OpenType-Variable-Schriftartformat immer noch sehr neu, und Schriftartanbieter, Plattformen und Apps befinden sich weiterhin im Prozess der Implementierung des neuen Formats. Dieses Update stellt eine anfängliche Implementierung für dieses Format in DirectWrite bereit. 

DirectWrite Internen wurden aktualisiert, um OpenType-Variable-Schriftarten zu unterstützen. Mit aktuellen APIs unterstützt dies alle benannten Instanzen einer Variablenschriftart. Diese Unterstützung kann für vollständige Workflows verwendet werden – von der Aufzählung der benannten Instanzen, der Auswahl einer benannten Instanz, der Verwendung im Layout und der Gestaltung, zum Rendern und Drucken. Für die Vorteile von Apps, die auch GDI-Textinterop für bestimmte Vorgänge verwenden, wurde ähnliche Unterstützung auch in vorhandenen GDI-APIs hinzugefügt. 

Im Windows 10 Creators Update unterstützt DirectWrite keine beliebigen Instanzen, die die Fortlaufendvariationsfähigkeit von Variablenschriftarten nutzen.

In vielen Vorgängen kann das Verhalten in DirectWrite benannter Instanzen einer variablen Schriftart nicht von dem Verhalten nicht variabler Schriftarten unterschieden werden. Da die Unterstützung über vorhandene DirectWrite-APIs bereitgestellt wird, können die benannten Instanzen variabler Schriftarten sogar in vielen vorhandenen DirectWrite-Apps ohne Änderungen funktionieren. Ausnahmen können jedoch in bestimmten Situationen gelten:

  • Wenn eine App Schriftartdaten direkt für bestimmte Vorgänge verarbeitet. Wenn beispielsweise eine App glyphengliederungsdaten direkt aus der Schriftartdatei liest, um bestimmte visuelle Effekte zu erstellen.
  • Wenn eine App eine Drittanbieterbibliothek für bestimmte Vorgänge verwendet. Wenn eine App beispielsweise DirectWrite für das Layout verwendet, um endgültige Glyphenindizes und Positionen abzurufen, aber dann eine Drittanbieterbibliothek zum Rendern verwendet.
  • Wenn eine App Schriftartdaten in ein Dokument einbetten oder auf andere Weise Schriftartdaten an einen nachgelagerten Prozess übergeben.

Wenn Vorgänge mithilfe von Implementierungen ausgeführt werden, die keine variablen Schriftarten unterstützen, werden diese Vorgänge möglicherweise nicht zu den erwarteten Ergebnissen führen. Beispielsweise können Glyphenpositionen für eine benannte Instanz der Variablenschriftart berechnet werden, aber die Glyphen können mit einer anderen benannten Instanz gerendert werden. Je nach Anwendungsimplementierung funktionieren die Ergebnisse möglicherweise in einigen Kontexten, aber nicht in anderen Kontexten, in denen andere Bibliotheken verwendet werden können. Text kann z. B. auf dem Bildschirm korrekt angezeigt werden, aber nicht beim Drucken. Wenn End-to-End-Workflows nur mit DirectWrite implementiert werden, kann das richtige Verhalten für benannte Instanzen einer variablen Schriftart erwartet werden. 

Da vorhandene DirectWrite APIs die Gesichtsauswahl mithilfe des Gewichts-/Stretch/Formatvorlagenmodells unterstützen, werden die benannten Instanzen von Schriftarten, die andere Variationsachsen verwenden, aus dem allgemeinen, typografischen Familienmodell in das WSS modell projiziert, wie oben beschrieben. Dies basiert auf einer variablen Schriftart, einschließlich einer Tabelle "Formatattribute" ('STAT') mit Achsenwert-Untertabellen, die DWrite verwendet, um Gesichtsnamentoken zu unterscheiden, die Gewichtung, Zieh- oder Formatattribute von Token angeben, die auf andere Variationsachsen beziehen.  

Wenn eine variable Schriftart keine Tabelle 'STAT' enthält, wie für variable Schriftarten durch die OpenType-Spezifikation erforderlich, behandelt DirectWrite die Schriftart als nicht variable Schriftart, die nur die Standardinstanz enthält.  

Wenn eine Schriftart eine Tabelle "STAT" enthält, aber keine entsprechenden Achsenwert-Untertabellen enthält, kann dies zu unerwarteten Ergebnissen führen, z. B. mit mehreren Gesichtern, die identische Gesichtsnamen haben. Diese Schriftarten werden zu diesem Zeitpunkt nicht unterstützt. 

Mit der OpenType-Spezifikation können Glyphengliederungsdaten in einem von zwei Formaten dargestellt werden: Verwenden einer "glyf"-Tabelle, die TrueType-Gliederungs- und Hintingformat verwendet oder eine "CFF"-Tabelle verwendet, die die Darstellung "Compact Font Format" (CFF) verwendet. In einer Variablenschriftart mit TrueType-Gliederungen wird die Tabelle "glyf" weiterhin verwendet und wird mit einer "gvar"-Tabelle ergänzt, die die Variationsdaten für die Gliederungen bereitstellt. Dies bedeutet, dass die Standardinstanz einer Variablenschriftart mit TrueType-Gliederungen nur herkömmliche OpenType-Tabellen verwendet wird, die in älteren Software unterstützt werden, die keine variable Schriftart unterstützt. In einer variablen Schriftart mit CFF-Gliederungen wird die Tabelle "CFF" jedoch durch die Tabelle "CFF2" ersetzt, die die Standardgliederungsdaten und die zugehörigen Variationsdaten in einer Tabelle kapselt. CFF-Daten werden von einem separaten Rasterizer verarbeitet, der für TrueType-Daten verwendet wird, und eine "CFF2"-Tabelle erfordert eine aktualisierte CFF-Rasterizer, die über "CFF2"-Unterstützung verfügt. Eine "CFF2"-Tabelle kann nicht von älteren CFF-Rasterizern verarbeitet werden. Für eine variable Schriftart mit CFF-Gliederungsdaten bedeutet dies, dass auch die Standardinstanz nicht in älteren Software funktioniert. 

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

Verwenden von OpenType-Variablenschriftarten

OpenType variable Schriftarten können einfach zu verwenden sein, beachten Sie die oben aufgeführten aktuellen Einschränkungen:

  • Nur benannte Instanzen einer Variablenschriftart werden zu diesem Zeitpunkt unterstützt.
  • Nur variable Schriftarten, die TrueType-Glyphengliederungsdaten (nicht CFF-Gliederungen) verwenden, werden zu diesem Zeitpunkt unterstützt. 
  • Bei Schriftarten, die andere Achsen von Entwurfsvariablen als Gewicht, Zieh- oder Formatvorlage verwenden, werden benannte Instanzen in das WSS Familienmodell projiziert, was dazu führen kann, dass einige benannte Instanzen als separate Familien erscheinen (wie in der Vergangenheit für nicht variable Schriftarten). Um dies zu unterstützen, müssen variable Schriftarten über eine Tabelle "STAT" verfügen, die geeignete Untertabellen für Achsenwerte enthält.
  • Benannte Instanzen von Variablenschriftarten werden in DirectWrite APIs unterstützt, aber wenn bestimmte Vorgänge in älteren Implementierungen ausgeführt werden, die keine Variablenschriftarten unterstützen, können diese falsche Ergebnisse erzeugen. 
  • Bestimmte DirectWrite-APIs verwenden die DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH und DWRITE_FONT_STYLE Enumerationen zum Angeben von Gewichts-, Stretch- und Formatvorlagenattributen beim Auswählen von Gesichtern. Wenn eine variable Schriftart entsprechende Variationsachsen verwendet, aber viele benannte Instanzen enthält, die eine feinere Granularität erfordern, sind nicht alle benannten Instanzen in diesen APIs auswählbar.

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

Wenn sie im System installiert sind, werden alle benannten Instanzen einer Variablenschriftart in den schriftartensatz eingeschlossen, der durch Aufrufen der IDWriteFontFamily3::GetSystemFontSet-Methode zurückgegeben wird. Beachten Sie, dass es sich bei einem Schriftsatz um eine flache Liste ohne Familiengruppierungshierarchie handelt, aber jedes Element im Satz verfügt über eine Familiennameneigenschaft basierend auf dem WSS Familienmodell. Der Schriftartsatz kann mithilfe der METHODEN IDWriteFontSet::GetMatchingFonts nach einer bestimmten Variablenschriftart gefiltert werden. Wenn Sie die GetMatchingFonts-Überladung verwenden, die jedoch 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.  

Ebenso werden alle benannten Instanzen einer Variablenschriftart in der schriftart dargestellt, die von der IDWriteFactory::GetSystemFontCollection-Methode zurückgegeben wird. Da die Elemente einer Schriftartsammlung Schriftartenfamilien basierend auf dem WSS Modell sind, können die benannten Instanzen einer Variablenschriftart in einer Auflistung als Mitglieder von zwei oder mehr Schriftfamilien 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 Schriftartsammlung zu finden, kann eine App jede Familie durchlaufen und IDWriteFontFamily::GetFamilyNames aufrufen, obwohl es möglicherweise einfacher ist, einen entsprechenden Schriftartsatz abzurufen und die GetPropertyValues-Methode wie oben beschrieben zu verwenden. 

Beim Arbeiten mit benutzerdefinierten Schriftarten können verschiedene Im Thema "Benutzerdefinierte Schriftartensätze " beschriebene Ansätze verwendet werden, um einen Schriftartensatz zu erstellen. Um einer benutzerdefinierten Schriftart eine variable Schriftart hinzuzufügen, wird die IDWriteFontSetBuilder1::AddFontFile-Methode empfohlen, da sie variable Schriftarten unterstützt und alle benannten Instanzen einer Variablenschriftart in einem einzigen Aufruf hinzufügen wird. Es gibt derzeit keine Möglichkeit, einzelne benannte Instanzen einer benutzerdefinierten Variablenschriftart zu einem Schriftartensatz mithilfe der IDWriteFontSetBuilder::AddFontFaceReference-Methoden hinzuzufügen, da keine Möglichkeit besteht, einen Schriftartenbezug zu erstellen, der angibt, welche benannten Instanzen aus einer Variablenschriftdatei angegeben werden. Dies bedeutet, dass derzeit keine Möglichkeit besteht, benannte Instanzen einer benutzerdefinierten Schriftart zu einem benutzerdefinierten Schriftartsatz mit zugewiesenen benutzerdefinierten Eigenschaften hinzuzufügen. Das bedeutet wiederum, dass benutzerdefinierte Variablenschriftarten derzeit nicht problemlos in Verbindung mit DirectWrite-APIs für Remoteschriftarten verwendet werden können. Wenn benannte Instanzen einer Variablenschriftart in einem Systemschriftsatz enthalten sind, ist jedoch bereits Schriftartenbezüge für jede benannte Instanz vorhanden, und diese können zu benutzerdefinierten Schriftartensätzen hinzugefügt werden, einschließlich der Verwendung von benutzerdefinierten Eigenschaftswerten. Weitere Informationen finden Sie im Thema "Benutzerdefinierte Schriftartensätze". 

Beim Arbeiten mit Variablenschriftarten sind die DirectWrite DWRITE_FONT_WEIGHT und DWRITE_FONT_STRETCH Enumerationen eng mit den in der OpenType-Spezifikation definierten Gewichts- und Breitenvariationsachsen verbunden, sind jedoch nicht identisch. Zuerst unterstützt die numerische Skalierung für jede Variationsachse immer Bruchwerte, während fontWeight und fontStretch ganze Zahlen verwenden. Die Skalierung der OpenType-Gewichtsachse verwendet Werte von 1 bis 1000, die auch von fontWeight unterstützt wird. Daher ist die Änderung von einem Größenachsenwert für Variationen in fontWeight relativ geringfügig: Das für eine benannte Instanz gemeldete FontWeight kann von dem genauen Wert gerundet werden, der zum Definieren der benannten Instanz innerhalb der Schriftart verwendet wird. Der Unterschied zwischen DirectWrite fontStretch und der Skalierung der OpenType-Breite ist größer: DirectWrite Werte von 1 bis 9 verwendet, gefolgt von den usWidthClass-Werten der OpenType OS/2-Tabelle, während die Skalierung der OpenType-Breite positive Werte verwendet, die einen Prozentsatz der normalen Breite darstellen. Die usWidthClass-Dokumentation in der OpenType-Spezifikation stellt eine Zuordnung zwischen Werten 1 bis 9 und Prozent normaler Werte bereit. Der für eine benannte Instanz gemeldete FontStretch-Wert kann beim Konvertieren von Größen der Breiteachse gerundet werden. 

Beim Erstellen einer IDWriteTextFormat muss eine Schriftartsammlung und WSS kompatible Schriftarteigenschaften (Familienname, Gewicht, Stretch und Stil) angegeben werden. Dies gilt auch beim Festlegen von Schriftartformatierungseigenschaften in einem IDWriteTextLayout-Textbereich . Die Eigenschaften können aus einem IDWriteFontFace3-Objekt oder aus IDWriteFont- und IDWriteFontFamily-Objekten abgerufen werden, die eine bestimmte benannte Instanz darstellen. Wie oben beobachtet, können die von den Methoden GetWeight und GetStretch zurückgegebenen Werte für die tatsächlichen Achsenwerte gerundet werden, die zum Definieren der benannten Instanz verwendet werden, aber DirectWrite die Kombination von Eigenschaften wieder der gewünschten benannten Instanz zuordnen. 

Wenn eine App IDWriteFontFallbackBuilder zum Erstellen benutzerdefinierter Schriftarten-Fallbackdaten verwendet, werden Familien für Zeichenbereichszuordnungen mit WSS kompatiblen Familiennamen angegeben. Der Schriftfallback innerhalb DirectWrite basiert auf Familien mit DirectWrite Auswahl einer Variante innerhalb einer Fallbackfamilie, die eine nächste Übereinstimmung für die Variante der Startfamilie darstellt. Bei Varianten, die andere Dimensionen als Gewicht, Stretch und Format enthalten, kann DirectWrite derzeit keine solchen Varianten innerhalb einer Fallbackfamilie 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"-optische Größenvarianten.