Benutzerdefinierte Schriftartenkombinationen
In diesem Thema werden verschiedene Möglichkeiten beschrieben, wie Sie benutzerdefinierte Schriftarten in Ihrer App verwenden können.
- Einführung
- Übersicht über die APIs
- Wichtige Begriffe
- Schriftarten und Schriftartdateiformate
- Schriftartensätze und Schriftartensammlungen
-
Gängige Szenarios
- Erstellen eines Schriftartensatzes mithilfe beliebiger Schriftarten im lokalen Dateisystem
- Erstellen eines Schriftartensatzes mithilfe bekannter Schriftarten im lokalen Dateisystem
- Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe bekannter Remoteschriftarten im Web
- Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe von in den Arbeitsspeicher geladenen Schriftdaten
- Erweiterte Szenarien
Einführung
In den meisten Fällen verwenden Apps die Schriftarten, die lokal auf dem System installiert sind. DirectWrite ermöglicht den Zugriff auf diese Schriftarten mithilfe der Methoden IDWriteFactory3::GetSystemFontSet oder IDWriteFactory::GetSystemFontCollection. In einigen Fällen möchten Apps möglicherweise auch Schriftarten verwenden, die als Teil von Windows 10, die derzeit jedoch nicht auf dem aktuellen System installiert sind. Auf solche Schriftarten kann über den Windows-Schriftartendienst zugegriffen werden, indem die GetSystemFontSet-Methode verwendet wird, oder durch Aufrufen von IDWriteFactory3::GetSystemFontCollection , wobei includeDownloadableFonts auf TRUE festgelegt ist.
In einigen Anwendungsszenarien müssen Apps jedoch Schriftarten verwenden, die nicht im System installiert sind und nicht vom Windows-Schriftartendienst bereitgestellt werden. Im Folgenden sind Beispiele für solche Szenarien aufgeführt:
- Schriftarten werden als Ressourcen in eine App-Binärdatei eingebettet.
- Schriftartdateien werden in einem App-Paket gebündelt und auf dem Datenträger im Installationsordner der App gespeichert.
- Die App ist ein Tool zur Entwicklung von Schriftarten, das vom Benutzer angegebene Schriftartdateien laden muss.
- Schriftarten sind in Dokumentdateien eingebettet, die in der App angezeigt oder bearbeitet werden können.
- Die App verwendet Schriftarten, die von einem öffentlichen Webfontdienst abgerufen wurden.
- Die App verwendet Schriftartdaten, die über ein privates Netzwerkprotokoll gestreamt werden.
DirectWrite stellt APIs für die Arbeit mit benutzerdefinierten Schriftarten in diesen und ähnlichen Szenarien bereit. Die benutzerdefinierten Schriftartdaten stammen möglicherweise aus Dateien im lokalen Dateisystem. von cloudbasierten Remotequellen, auf die über HTTP zugegriffen wird; oder aus beliebigen Quellen, nachdem sie in einen Speicherpuffer geladen wurden.
Hinweis
Während DirectWrite apIs für die Arbeit mit benutzerdefinierten Schriftarten seit Windows 7 bereitgestellt hat, wurden neuere APIs in Windows 10 und erneut in der Windows 10 Creators Update (Vorschaubuild 15021 oder höher) hinzugefügt, die die Implementierung mehrerer der genannten Szenarien vereinfachen. Dieses Thema konzentriert sich auf APIs, die in Fenster 10 verfügbar sind. Informationen zu Anwendungen, die mit früheren Windows-Versionen funktionieren müssen, finden Sie unter Benutzerdefinierte Schriftartsammlungen (Windows 7/8).
Übersicht über die APIs
Dieses Thema konzentriert sich auf funktionen, die von den folgenden APIs bereitgestellt werden:
- IDWriteFontSet-Schnittstelle
- IDWriteFontSetBuilder-Schnittstelle
- IDWriteFontSetBuilder1-Schnittstelle
- IDWriteFontFaceReference-Schnittstelle
- IDWriteFontFile-Schnittstelle
- IDWriteFactory::CreateFontFileReference-Methode
- IDWriteFactory::CreateCustomFontFileReference-Methode
- IDWriteFactory3::CreateFontFaceReference-Methoden
- DWRITE_FONT_PROPERTY Struktur
- DWRITE_FONT_PROPERTY_ID-Enumeration
- IDWriteFontFileLoader-Schnittstelle
- IDWriteFactory::RegisterFontFileLoader-Methode
- IDWriteFactory::UnregisterFontFileLoader-Methode
- IDWriteFactory5::CreateInMemoryFontFileLoader-Methode
- IDWriteInMemoryFontFileLoader-Schnittstelle
- IDWriteFactory5::CreateHttpFontFileLoader-Methode
- IDWriteRemoteFontFileLoader-Schnittstelle
- IDWriteFontDownloadQueue-Schnittstelle
- IDWriteFontDownloadListener-Schnittstelle
- IDWriteFontFileStream-Schnittstelle
- IDWriteRemoteFontFileStream-Schnittstelle
- IDWriteAsyncResult-Schnittstelle
- IDWriteFactory5::AnalyzeContainerType-Methode
- IDWriteFactory5::UnpackFontFile-Methode
Wichtige Begriffe
Um die DirectWrite APIs für die Arbeit mit benutzerdefinierten Schriftarten zu verstehen, kann es hilfreich sein, das konzeptionelle Modell zu verstehen, das diesen APIs zugrunde steht. Wichtige Konzepte werden hier beschrieben.
Wenn DirectWrite ein tatsächliches Textlayout oder -rendering durchführt, muss er auf die tatsächlichen Schriftartdaten zugreifen. Ein Schriftartensichtobjekt enthält tatsächliche Schriftartdaten, die im lokalen System vorhanden sein müssen. Für andere Vorgänge, z. B. die Überprüfung der Verfügbarkeit einer bestimmten Schriftart oder das Anzeigen von Schriftartauswahlen für einen Benutzer, ist jedoch nur ein Verweis auf eine bestimmte Schriftart erforderlich, nicht die tatsächlichen Schriftartdaten selbst. In DirectWrite enthält ein Schriftartenreferenzobjekt nur die Informationen, die zum Suchen und Instanziieren einer Schriftart erforderlich sind. Da der Schriftsichtverweis keine tatsächlichen Daten enthält, können DirectWrite schriftartengesichtsweisen Verweise verarbeiten, für die sich die tatsächlichen Daten an einem Remotenetzwerkstandort befinden und wenn die tatsächlichen Daten lokal sind.
Bei einem Schriftartensatz handelt es sich um einen Satz von Schriftsichtsverweisen zusammen mit bestimmten grundlegenden Informationseigenschaften, die zum Verweisen auf die Schriftart oder zum Vergleichen mit anderen Schriftarten wie dem Familiennamen oder einem Schriftgewichtungswert verwendet werden können. Die tatsächlichen Daten für die verschiedenen Schriftarten können lokal oder remote oder eine Mischung sein.
Ein Schriftartensatz kann verwendet werden, um ein entsprechendes Schriftartensammlungsobjekt abzurufen. Weitere Informationen finden Sie weiter unten unter Schriftartensätze und Schriftartensammlungen.
Die IDWriteFontSet-Schnittstelle stellt Methoden bereit, mit denen Eigenschaftenwerte wie Familienname oder Schriftgewichtung oder Schriftartsichtsverweise, die mit bestimmten Eigenschaftswerten übereinstimmen, abfragen können. Nach dem Filtern auf eine bestimmte Auswahl kann eine instance der IDWriteFontFaceReference-Schnittstelle mit Methoden zum Herunterladen (wenn die tatsächlichen Schriftartdaten derzeit entfernt sind) abgerufen werden, um das entsprechende IDWriteFontFace3-Objekt abzurufen, das für Layout und Rendering verwendet werden kann.
Die IDWriteFontFile-Schnittstelle ist jedem Schriftarten- oder Schriftartsichtsverweis zugrunde. Dies stellt den Speicherort einer Schriftartdatei dar und besteht aus zwei Komponenten: einem Schriftartdateiladeprogramm und einem Schriftartdateischlüssel. Das Schriftartdateiladeprogramm (IDWriteFontFileLoader) wird verwendet, um bei Bedarf eine Datei zu öffnen, und gibt einen Datenstrom mit den Daten (IDWriteFontFileStream) zurück. Je nach Ladeprogramm befinden sich die Daten möglicherweise in einem lokalen Dateipfad, einem Remote-URL oder in einem Speicherpuffer. Der Schlüssel ist ein vom Ladeprogramm definierter Wert, der die Datei innerhalb des Ladeprogrammkontexts eindeutig identifiziert, sodass der Ladeprogramm die Daten suchen und einen Stream dafür erstellen kann.
Benutzerdefinierte Schriftarten können ganz einfach zu einem benutzerdefinierten Schriftartensatz hinzugefügt werden, der wiederum zum Filtern oder Organisieren von Schriftartinformationen für Zwecke wie das Erstellen einer Benutzeroberfläche für die Schriftartenauswahl verwendet werden kann. Der Schriftartensatz kann auch verwendet werden, um eine Schriftartensammlung für die Verwendung in APIs auf höherer Ebene wie IDWriteTextFormat und IDWriteTextLayout zu erstellen. Die IDWriteFontSetBuilder-Schnittstelle kann verwendet werden, um einen benutzerdefinierten Schriftartensatz zu erstellen, der mehrere benutzerdefinierte Schriftarten enthält. Es kann auch verwendet werden, um einen benutzerdefinierten Schriftartensatz zu erstellen, der benutzerdefinierte Schriftarten mit vom System bereitgestellten Schriftarten kombiniert. oder bei der Schriftarten mit verschiedenen Quellen für die tatsächlichen Daten kombiniert werden – lokaler Speicher, Remote-URLs und Arbeitsspeicher.
Wie bereits erwähnt, kann ein Schriftartengesichtsverweis auf Schriftartdaten in einer Remotequelle verweisen, aber die Daten müssen lokal sein, um ein Schriftartsichtsobjekt abzurufen, das für Layout und Rendering verwendet werden kann. Das Herunterladen von Remotedaten erfolgt über eine Warteschlange zum Herunterladen von Schriftarten. Apps können die IDWriteFontDownloadQueue-Schnittstelle verwenden, um Anforderungen zum Herunterladen von Remoteschriftarten in die Warteschlange zu stellen, um den Downloadprozess zu initiieren, und um ein IDWriteFontDownloadListener-Objekt zu registrieren, um maßnahmen zu ergreifen, wenn der Downloadvorgang abgeschlossen ist.
Für die meisten der hier beschriebenen Schnittstellen stellt DirectWrite Systemimplementierungen bereit. Die einzige Ausnahme ist die IDWriteFontDownloadListener-Schnittstelle , die eine App implementiert, um appspezifische Aktionen auszuführen, wenn Remoteschriftarten lokal heruntergeladen wurden. Apps haben möglicherweise Grund, ihre eigenen benutzerdefinierten Implementierungen für bestimmte andere Schnittstellen bereitzustellen, obwohl dies nur in bestimmten, erweiterten Szenarien erforderlich wäre. Beispielsweise müsste eine App eine benutzerdefinierte Implementierung der IDWriteFontFileLoader-Schnittstelle bereitstellen, um Schriftartdateien im lokalen Speicher zu verarbeiten, die das WOFF2-Containerformat verwenden. Weitere Details werden unten angegeben.
Schriftarten und Schriftartdateiformate
Ein weiteres wichtiges Konzept, das hilfreich zu verstehen ist, ist die Beziehung zwischen einzelnen Schriftarten und Schriftartdateien, die diese enthalten. Die Idee einer OpenType-Schriftartdatei (TTF oder OTF), die eine einzelne Schriftart enthält, ist bekannt. Das OpenType-Schriftartformat ermöglicht jedoch auch eine OpenType-Schriftartensammlung (TTC oder OTC), bei der es sich um eine einzelne Datei handelt, die mehrere Schriftarten enthält. OpenType-Sammlungsdateien werden häufig für große Schriftarten verwendet, die eng miteinander verbunden sind und identische Werte für bestimmte Schriftartdaten aufweisen: Durch Kombinieren der Schriftarten in einer einzelnen Datei können die allgemeinen Daten dedupliziert werden. Aus diesem Grund muss ein Schrift- oder Schriftsichtsverweis nicht nur auf eine Schriftartdatei (oder eine entsprechende Datenquelle) verweisen, sondern auch einen Schriftartindex innerhalb dieser Datei angeben, für den allgemeinen Fall, in dem die Datei eine Sammlungsdatei sein kann.
Bei Schriftarten, die im Web verwendet werden, werden Schriftartdaten häufig in bestimmte Containerformate gepackt, WOFF oder WOFF2, die eine gewisse Komprimierung der Schriftartdaten und ein gewisses Maß an Schutz vor Piraterie und Verletzung von Schriftartlizenzen bieten. Funktionell entspricht eine WOFF- oder WOFF2-Datei einer OpenType-Schriftart oder Einer Schriftsammlungsdatei, aber die Daten werden in einem anderen Format codiert, das entpackt werden muss, bevor sie verwendet werden können.
Bestimmte DirectWrite-APIs können einzelne Schriftflächen behandeln, während andere APIs Dateien behandeln können, die OpenType-Sammlungsdateien enthalten können, die mehrere Gesichter enthalten. Ebenso behandeln bestimmte APIs nur Rohdaten im OpenType-Format, während andere APIs die Containerformate gepackt, WOFF und WOFF2 verarbeiten können. Diese Details finden Sie in der folgenden Diskussion.
Schriftartsätze und Schriftartsammlungen
Einige Anwendungen können implementiert werden, um mit Schriftarten zu arbeiten, die die IDWriteFontCollection-Schnittstelle verwenden. Zwischen einer Schriftartsammlung und einem Schriftartensatz besteht eine direkte Korrespondenz. Jede Schriftart kann dieselben Schriftarten enthalten, aber sie weisen eine andere organization auf. Aus jeder Schriftartsammlung kann ein entsprechender Schriftsatz abgerufen werden und umgekehrt.
Wenn Sie mit einer Reihe benutzerdefinierter Schriftarten arbeiten, ist es am einfachsten, eine Schriftartsatz-Generatorschnittstelle zu verwenden, um einen benutzerdefinierten Schriftartensatz zu erstellen, und dann eine Schriftartsammlung abzurufen, nachdem der Schriftartensatz erstellt wurde. Der Prozess zum Erstellen eines benutzerdefinierten Schriftartsatzes wird unten ausführlich beschrieben. Um eine IDWriteFontCollection1-Schnittstelle aus einem Schriftartensatz abzurufen, wird die IDWriteFactory3::CreateFontCollectionFromFontSet-Methode verwendet.
Wenn die App über ein Auflistungsobjekt verfügt und einen entsprechenden Schriftartsatz abrufen muss, kann dies mithilfe der IDWriteFontCollection1::GetFontSet-Methode erfolgen.
Häufige Szenarien
In diesem Abschnitt werden einige der häufigsten Szenarien beschrieben, die benutzerdefinierte Schriftartensätze betreffen:
- Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe beliebiger Schriftarten an Pfaden im lokalen Dateisystem.
- Erstellen eines benutzerdefinierten Schriftartsatzes mithilfe bekannter Schriftarten (möglicherweise im Paket mit der App), die im lokalen Dateisystem gespeichert sind.
- Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe bekannter Remoteschriftarten im Web.
- Erstellen eines benutzerdefinierten Schriftartsatzes mithilfe von Schriftartdaten, die in den Arbeitsspeicher geladen werden.
Vollständige Implementierungen für diese Szenarien werden im Beispiel für benutzerdefinierte Schriftartsätze DirectWrite bereitgestellt. Dieses Beispiel veranschaulicht auch ein erweitertes Szenario für die Verarbeitung von Schriftartdaten, die in WOFF- oder WOFF2-Containerformaten gepackt sind. Dies wird unten erläutert.
Erstellen eines Schriftartsatzes mithilfe beliebiger Schriftarten im lokalen Dateisystem
Wenn Sie mit einer beliebigen Gruppe von Schriftartdateien im lokalen Speicher arbeiten, ist die IDWriteFontSetBuilder1::AddFontFile-Methode praktisch, da sie in einem einzelnen Aufruf alle Schriftflächen innerhalb einer OpenType-Schriftsammlungsdatei sowie alle Instanzen für eine OpenType-Variable-Schriftart verarbeiten kann. Dies ist im Windows 10 Creators Update (Vorschaubuild 15021 oder höher) verfügbar und wird empfohlen, wann immer verfügbar.
Um diese Methode zu verwenden, verwenden Sie den folgenden Prozess.
- 1. Erstellen Sie zunächst die IDWriteFactory5-Schnittstelle :
- Erstellen Sie für jede Schriftartdatei im lokalen Dateisystem ein IDWriteFontFile , das darauf verweist:
- Nachdem alle Dateien dem Schriftartsatz-Generator hinzugefügt wurden, kann der benutzerdefinierte Schriftartsatz erstellt werden:
IDWriteFactory5* pDWriteFactory;
HRESULT hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory5),
reinterpret_cast<IUnknown**>(&pDWriteFactory)
);
2. Verwenden Sie die Factory, um die IDWriteFontSetBuilder1-Schnittstelle abzurufen:
IDWriteFontSetBuilder1* pFontSetBuilder;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder);
}
IDWriteFontFile* pFontFile;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile);
}
4. Fügen Sie das IDWriteFontFile-Objekt mithilfe der AddFontFile-Methode zum Schriftartsatz-Generator hinzu:
hr = pFontSetBuilder->AddFontFile(pFontFile);
Wenn der im Aufruf von CreateFontFileReference angegebene Dateipfad auf eine andere als eine unterstützte OpenType-Datei verweist, gibt der Aufruf von AddFontFile einen Fehler zurück, DWRITE_E_FILEFORMAT.
IDWriteFontSet* pFontSet;
hr = pFontSetBuilder->CreateFontSet(&pFontSet);
Wenn die App unter Windows 10 Versionen vor dem Windows 10 Creators Update ausgeführt werden muss, ist die AddFontFile-Methode nicht verfügbar. Die Verfügbarkeit kann erkannt werden, indem Sie eine IDWriteFactory3-Schnittstelle erstellen und dann QueryInterface verwenden, um zu versuchen, eine IDWriteFactory5-Schnittstelle abzurufen: Wenn dies erfolgreich ist, sind auch die IDWriteFontSetBuilder1-Schnittstelle und die AddFontFile-Methode verfügbar.
Wenn die AddFontFile-Methode nicht verfügbar ist, muss die IDWriteFontSetBuilder::AddFontFaceReference-Methode verwendet werden, um einzelne Schriftflächen hinzuzufügen. Um OpenType-Schriftartsammlungsdateien zuzulassen, die mehrere Gesichter enthalten, kann die IDWriteFontFile::Analyze-Methode verwendet werden, um die Anzahl der in der Datei enthaltenen Gesichter zu bestimmen. Der Prozess sieht wie folgt aus.
- 1. Erstellen Sie zunächst die IDWriteFactory3-Schnittstelle :
- Verwenden Sie die Factory, um die IDWriteFontSetBuilder-Schnittstelle abzurufen:
- Erstellen Sie für jede Schriftartdatei wie oben ein IDWriteFontFile:
- Nachdem alle Gesichter dem Schriftartsatz-Generator hinzugefügt wurden, erstellen Sie den benutzerdefinierten Schriftartensatz, wie oben gezeigt.
IDWriteFactory3* pDWriteFactory;
HRESULT hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory5),
reinterpret_cast<IUnknown**>(&pDWriteFactory)
);
IDWriteFontSetBuilder* pFontSetBuilder;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateFontSetBuilder(&pFontSetBuilder);
}
IDWriteFontFile* pFontFile;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateFontFileReference(pFilePath, /* lastWriteTime*/ nullptr, &pFontFile);
}
Anstatt die Datei direkt zum Schriftartsatz-Generator hinzuzufügen, müssen wir die Anzahl der Gesichter bestimmen und einzelne IDWriteFontFaceReference-Objekte erstellen.
4. Verwenden Sie die Analyze-Methode , um die Anzahl der Gesichter in der Datei abzurufen.
BOOL isSupported;
DWRITE_FONT_FILE_TYPE fileType;
UINT32 numberOfFonts;
hr = pFontFile->Analyze(&isSupported, &fileType, /* face type */ nullptr, &numberOfFonts);
Die Analyze-Methode legt auch Werte für die Parameter isSupported und fileType fest. Wenn die Datei kein unterstütztes Format ist, ist isSupported FALSE, und die entsprechende Aktion, z. B. das Ignorieren der Datei, kann ausgeführt werden.
5. Schleife über die Anzahl der Schriftarten, die im parameter numberOfFonts festgelegt sind. Erstellen Sie innerhalb der Schleife eine IDWriteFontFaceReference für jedes Datei-Index-Paar, und fügen Sie es dem Schriftartensatz-Generator hinzu.
for (uint32_t fontIndex = 0; fontIndex < numberOfFonts; fontIndex++)
{
IDWriteFontFaceReference* pFontFaceReference;
hr = pDWriteFactory->CreateFontFaceReference(pFontFile, fontIndex, DWRITE_FONT_SIMULATIONS_NONE, &pFontFaceReference);
if (SUCCEEDED(hr))
{
hr = pFontSetBuilder->AddFontFaceReference(pFontFaceReference);
}
}
Eine App kann so konzipiert werden, dass sie die bevorzugte AddFontFile-Methode verwendet, wenn sie auf dem Windows 10 Creators Update ausgeführt wird, aber bei der Ausführung mit früheren Windows 10 Versionen die AddFontFaceReference-Methode verwenden. Testen Sie die Verfügbarkeit der IDWriteFactory5-Schnittstelle , wie oben beschrieben, und verzweigen Sie dann entsprechend. Dieser Ansatz wird im Beispiel für benutzerdefinierte Schriftartsätze DirectWrite veranschaulicht.
Erstellen eines Schriftartsatzes mithilfe bekannter Schriftarten im lokalen Dateisystem
Wie oben erwähnt, ist jeder Schriftzeichenverweis in einem Schriftartensatz bestimmten Informationseigenschaften zugeordnet, z. B. Familienname und Schriftstärke. Wenn benutzerdefinierte Schriftarten mithilfe der oben aufgeführten API-Aufrufe einem Schriftartsatz-Generator hinzugefügt werden, werden diese Informationseigenschaften direkt aus den tatsächlichen Schriftartdaten abgerufen, die beim Hinzufügen der Schriftart gelesen werden. Wenn eine App jedoch in einigen Situationen über eine andere Informationsquelle zu einer Schriftart verfügt, kann sie ihre eigenen benutzerdefinierten Werte für diese Eigenschaften bereitstellen.
Angenommen, eine App bündelt einige Schriftarten, die für die Darstellung bestimmter Benutzeroberflächenelemente innerhalb der App verwendet werden. Manchmal, z. B. bei einer neuen App-Version, müssen die spezifischen Schriftarten, die die App für diese Elemente verwendet, möglicherweise geändert werden. Wenn die App über codierte Verweise auf die spezifischen Schriftarten verfügt, muss jeder dieser Verweise geändert werden, wenn eine Schriftart durch eine andere ersetzt wird. Wenn die App stattdessen benutzerdefinierte Eigenschaften verwendet, um funktionale Aliase basierend auf dem Typ des gerenderten Elements oder Texts zuzuweisen, ordnet jeder Alias an einer bestimmten Stelle einer bestimmten Schriftart zu und verwendet dann die Aliase in allen Kontexten, in denen Schriftarten erstellt und bearbeitet werden. Das Ersetzen einer Schriftart durch eine andere erfordert nur das Ändern einer Stelle, an der der Alias einer bestimmten Schriftart zugeordnet ist.
Benutzerdefinierte Werte für Informationseigenschaften können zugewiesen werden, wenn die IDWriteFontSetBuilder::AddFontFaceReference-Methode aufgerufen wird. Die Methode hierfür lautet wie folgt: dies kann für jede Windows 10 Version verwendet werden.
Wie oben gezeigt, rufen Sie zunächst die Schnittstellen IDWriteFactory3 und IDWriteFontSet ab. Erstellen Sie für jedes hinzuzufügende benutzerdefinierte Schriftartengesicht ein IDWriteFontFaceReference, wie oben gezeigt. Bevor dies dem Schriftartsatz-Generator hinzugefügt wird (innerhalb der Schleife in Schritt 5, oben gezeigt), definiert die App jedoch die zu verwendenden benutzerdefinierten Eigenschaftswerte.
Ein Satz benutzerdefinierter Eigenschaftenwerte wird mithilfe eines Arrays von DWRITE_FONT_PROPERTY-Strukturen definiert. Jede dieser Eigenschaften identifiziert eine bestimmte Eigenschaft aus der DWRITE_FONT_PROPERTY_ID-Enumeration und den entsprechenden Eigenschaftswert, der verwendet werden soll.
Beachten Sie, dass alle Eigenschaftswerte als Zeichenfolgen zugewiesen werden. Wenn diese später benutzern angezeigt werden, können alternative Werte für eine bestimmte Eigenschaft für verschiedene Sprachen festgelegt werden, dies ist jedoch nicht erforderlich. Beachten Sie außerdem, dass, wenn benutzerdefinierte Eigenschaftswerte von der App festgelegt werden, nur die angegebenen Werte innerhalb des Schriftartsatzes verwendet werden. DirectWrite werden keine Werte direkt von der Schriftart für Informationseigenschaften abgeleitet, die in einem Schriftartsatz verwendet werden.
Im folgenden Beispiel werden benutzerdefinierte Werte für drei Informationseigenschaften definiert: Familienname, vollständiger Name und Schriftgewichtung.
DWRITE_FONT_PROPERTY props[] =
{
{ DWRITE_FONT_PROPERTY_ID_FAMILY_NAME, L"My Icon Font", L"en-US" },
{ DWRITE_FONT_PROPERTY_ID_FULL_NAME, L"My Icon Font", L"en-US" },
{ DWRITE_FONT_PROPERTY_ID_WEIGHT, L"400", nullptr }
};
Nachdem Sie das gewünschte Array von Eigenschaftenwerten für eine Schriftart definiert haben, rufen Sie AddFontFaceRefence auf, und übergeben Sie das Eigenschaftenarray sowie den Schriftsichtverweis.
hr = pFontSetBuilder->AddFontFaceReference(pFontFaceReference, props, ARRAYSIZE(props));
Nachdem alle benutzerdefinierten Schriftflächen dem Schriftartsatz-Generator zusammen mit den benutzerdefinierten Eigenschaften hinzugefügt wurden, erstellen Sie den benutzerdefinierten Schriftartsatz, wie oben gezeigt.
Erstellen eines benutzerdefinierten Schriftartsatzes mithilfe bekannter Remoteschriftarten im Web
Benutzerdefinierte Eigenschaften sind wichtig für die Arbeit mit Remoteschriftarten. Jeder Schriftsichtverweis muss über einige Informationseigenschaften verfügen, um die Schriftart zu charakterisieren und von anderen Schriftarten zu unterscheiden. Da die Schriftartdaten für Remoteschriftarten nicht lokal sind, können DirectWrite Eigenschaften nicht direkt aus den Schriftartdaten ableiten. Daher müssen Eigenschaften explizit angegeben werden, wenn dem Schriftartsatz-Generator eine Remoteschriftart hinzugefügt wird.
Die Sequenz der API-Aufrufe zum Hinzufügen von Remoteschriftarten zu einem Schriftartensatz ähnelt der Sequenz, die im vorherigen Szenario beschrieben wurde. Da die Schriftartdaten jedoch remote sind, unterscheiden sich die Vorgänge, die für das Lesen der tatsächlichen Schriftartdaten erforderlich sind, von denen beim Arbeiten mit Dateien im lokalen Speicher. Für diese Situation wurde eine neue Schnittstelle auf niedrigerer Ebene, IDWriteRemoteFontFileLoader, in der Windows 10 Creators Update hinzugefügt.
Um das Remoteschriftdateiladeprogramm verwenden zu können, muss er zuerst bei einer DirectWrite Factory registriert werden. Der Ladevorgang muss von der App so lange gehalten werden, wie die ihr zugeordneten Schriftarten verwendet werden. Sobald die Schriftarten nicht mehr verwendet werden und die Factory irgendwann zerstört wird, muss der Ladevorgang aufgehoben werden. Dies kann im Destruktor für die Klasse erfolgen, die das Ladeprogrammobjekt besitzt. Diese Schritte werden unten gezeigt.
Die Methode zum Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe von Remoteschriftarten lautet wie folgt: hierfür ist die Windows 10 Creators Update erforderlich.
- 1. Erstellen Sie wie oben gezeigt eine IDWriteFactory5-Schnittstelle.
2. Erstellen Sie eine IDWriteFontSetBuilder-Schnittstelle , wie oben gezeigt.
3. Verwenden Sie die Factory, um einen IDWriteRemoteFontFileLoader abzurufen.
- Definieren Sie benutzerdefinierte Eigenschaften für die Schriftart, wie oben gezeigt.
- Fügen Sie den Schriftartensichtsverweis zusammen mit benutzerdefinierten Eigenschaften dem Schriftartensatz-Generator hinzu, wie oben gezeigt.
- Nachdem alle Schriftarten dem Schriftartensatz-Generator hinzugefügt wurden, erstellen Sie den Schriftartensatz, wie oben gezeigt.
- Wenn die Remoteschriftarten nicht mehr verwendet werden, heben Sie die Registrierung des Remoteschriftdateiladeprogramms auf.
IDWriteRemoteFontFileLoader* pRemoteFontFileLoader;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateHttpFontFileLoader(
/* referrerURL */ nullptr,
/* extraHeaders */ nullptr,
&pRemoteFontFileLoader
);
}
Dadurch wird eine vom System bereitgestellte Implementierung der Remoteschriftdateiladeschnittstelle zurückgegeben, die HTTP-Interaktionen zum Herunterladen von Schriftartdaten im Auftrag der App verarbeiten kann. Eine Verweis-URL oder zusätzliche Header können angegeben werden, wenn dies vom Schriftartdienst oder von Diensten erforderlich ist, die die Quelle für die Schriftarten sind.
Wichtig
Sicherheitshinweis: Wenn versucht wird, eine Remoteschriftart abzurufen, besteht die Möglichkeit, dass ein Angreifer den beabsichtigten Server, der aufgerufen wird, zu spoofen. In diesem Fall würden die Ziel- und Verweis-URLs und Headerdetails dem Angreifer offengelegt. App-Entwickler sind dafür verantwortlich, dieses Risiko zu minimieren. Die Verwendung des HTTPS-Protokolls anstelle von HTTP wird empfohlen.
Ein einzelnes Remoteschriftdateiladeprogramm kann für mehrere Schriftarten verwendet werden, obwohl unterschiedliche Ladeprogramme verwendet werden können, wenn Schriftarten von mehreren Diensten abgerufen werden, die unterschiedliche Anforderungen an Referrer-URL oder zusätzliche Header haben.
4. Registrieren Sie das Remoteschriftdateiladeprogramm bei der Factory.
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->RegisterFontFileLoader(pRemoteFontFileLoader);
}
Ab diesem Punkt ähneln die Schritte zum Erstellen des benutzerdefinierten Schriftartensatzes denen, die für bekannte, lokale Schriftartdateien beschrieben werden, mit zwei wichtigen Ausnahmen. Zunächst wird das IDWriteFontFile-Objekt mithilfe der Remoteschriftdateiladeschnittstelle und nicht mit der Factory erstellt. Zweitens kann die Analyze-Methode nicht verwendet werden, da die Schriftartdaten nicht lokal sind. Stattdessen muss die App wissen, ob es sich bei der Remoteschriftartdatei um eine OpenType-Schriftsammlungsdatei handelt, und wenn ja, muss sie wissen, welche Schriftarten in der Sammlung sie verwenden wird, und den Jeweiligen Index. Daher sind die verbleibenden Schritte wie folgt:
5. Verwenden Sie für jede Remoteschriftartdatei die Benutzeroberfläche zum Laden von Remoteschriftdateien, um eine IDWriteFontFile-Datei zu erstellen. Geben Sie dabei die URL an, die für den Zugriff auf die Schriftartdatei erforderlich ist.
IDWriteFontFile* pFontFile;
hr = pRemoteFontFileLoader->CreateFontFileReferenceFromUrl(
pDWriteFactory,
/* baseUrl */ L"https://github.com/",
/* fontFileUrl */ L"winjs/winjs/blob/master/src/fonts/Symbols.ttf?raw=true",
&pFontFile
);
Beachten Sie, dass die vollständige URL im fontFileUrl-Parameter angegeben oder in basis- und relative Teile aufgeteilt werden kann. Wenn eine Basis-URL angegeben wird, muss die Verkettung der BaseUrl- und fontFileUrl-Werte die vollständige URL bereitstellen – DirectWrite stellt kein zusätzliches Trennzeichen bereit.
Wichtig
Sicherheits-/Leistungshinweis: Wenn versucht wird, eine Remoteschriftart abzurufen, gibt es keine Garantie, dass Windows eine Antwort vom Server erhält. In einigen Fällen antwortet ein Server möglicherweise mit dem Fehler Datei nicht gefunden auf eine ungültige relative URL, reagiert aber nicht mehr, wenn er mehrere ungültige Anforderungen empfängt. Wenn der Server nicht antwortet, tritt bei Windows ein Timeout auf. Dies kann jedoch einige Minuten dauern, wenn mehrere Abrufe initiiert werden. Sie sollten so viel tun, wie Sie können, um sicherzustellen, dass URLs gültig sind, wenn Aufrufe erfolgen.
Beachten Sie auch, dass die URL auf eine unformatierte OpenType-Schriftartdatei (TTF, OTF, TTC, OTC) verweisen kann, aber auch auf Schriftarten in einer WOFF- oder WOFF2-Containerdatei verweisen kann. Wenn auf eine WOFF- oder WOFF2-Datei verwiesen wird, entpackt die DirectWrite Implementierung des Remoteschriftdateiladeprogramms automatisch die Schriftartdaten aus der Containerdatei.
6. Erstellen Sie für jeden Schriftartsichtsindex in der zu verwendenden Remoteschriftdatei eine IDWriteFontFaceReference.
IDWriteFontFaceReference* pFontFaceReference;
hr = pDWriteFactory->CreateFontFaceReference(pFontFile, /* faceIndex */ 0, DWRITE_FONT_SIMULATIONS_NONE, &pFontFaceReference);
hr = pDWriteFactory->UnregisterFontFileLoader(pRemoteFontFileLoader);
Nachdem ein benutzerdefinierter Schriftartensatz mit benutzerdefinierten Remoteschriftarten erstellt wurde, enthält der Schriftartensatz Verweise und Informationseigenschaften für die Remoteschriftarten, aber die tatsächlichen Daten sind weiterhin remote. DirectWrite Unterstützung für Remoteschriftarten ermöglicht es, einen Schriftsichtverweis im Schriftartensatz beizubehalten und eine Schriftart für die Verwendung im Layout und Rendering auszuwählen, aber dass die tatsächlichen Daten erst heruntergeladen werden, wenn eine tatsächliche Notwendigkeit besteht, sie zu verwenden, z. B. wenn das Textlayout ausgeführt wird.
Eine App kann einen Ansatz im Voraus verfolgen, indem sie anfordert, dass DirectWrite die Schriftartdaten herunterladen und dann auf die Bestätigung eines erfolgreichen Downloads warten, bevor mit der Verarbeitung der Schriftart begonnen wird. Ein Netzwerkdownload impliziert jedoch eine gewisse Latenz mit unvorhersehbarer Dauer, und der Erfolg ist ebenfalls ungewiss. Aus diesem Grund ist es in der Regel besser, einen anderen Ansatz zu wählen, sodass Layout und Rendering zunächst mithilfe alternativer oder fallbackschriftarten ausgeführt werden können, die bereits lokal sind, während gleichzeitig der Download der gewünschten Remoteschriftart angefordert wird, und dann die Ergebnisse aktualisiert werden, sobald die gewünschte Schriftart heruntergeladen wurde.
Um anzufordern, dass die gesamte Schriftart heruntergeladen wird, bevor sie verwendet wird, kann die IDWriteFontFaceReference::EnqueueFontDownloadRequest-Methode verwendet werden. Wenn die Schriftart sehr groß ist, wird möglicherweise nur ein Teil der Daten für die Verarbeitung bestimmter Zeichenfolgen benötigt. DirectWrite stellt zusätzliche Methoden bereit, die verwendet werden können, um Teile der Schriftartdaten anzufordern, die für bestimmte Inhalte erforderlich sind, EnqueueCharacterDownloadRequest und EnqueueGlyphDownloadRequest.
Angenommen, der Ansatz, der in der App verfolgt werden soll, besteht darin, die Verarbeitung zunächst mithilfe lokaler, alternativer oder Fallbackschriftarten zu ermöglichen. Die IDWriteFontFallback::MapCharacters-Methode kann verwendet werden, um lokale Fallbackschriftarten zu identifizieren. Außerdem wird automatisch eine Anforderung zum Herunterladen der bevorzugten Schriftart in die Warteschlange gestellt. Wenn IDWriteTextLayout verwendet wird und ein Teil oder der gesamte Text im Layout mithilfe eines Remoteschriftartenverweis formatiert ist, verwendet DirectWrite automatisch die MapCharacters-Methode, um lokale Fallbackschriftarten abzurufen und eine Anforderung zum Herunterladen der Remoteschriftdaten in die Warteschlange zu stellen.
DirectWrite verwaltet für jede Factory eine Warteschlange zum Herunterladen von Schriftarten, und die Anforderungen, die mit den oben genannten Methoden durchgeführt werden, werden dieser Warteschlange hinzugefügt. Die Warteschlange zum Herunterladen von Schriftarten kann mithilfe der IDWriteFactory3::GetFontDownloadQueue-Methode abgerufen werden.
Wenn eine Downloadanforderung gestellt wird, die Schriftdaten jedoch bereits lokal sind, führt dies zu einem No-Op: Der Downloadwarteschlange wird nichts hinzugefügt. Eine App kann überprüfen, ob die Warteschlange leer ist oder ausstehende Downloadanforderungen vorhanden sind, indem sie die IDWriteFontDownloadQueue::IsEmpty-Methode aufruft .
Nachdem Remoteschriftartenanforderungen zur Warteschlange hinzugefügt wurden, muss der Downloadvorgang initiiert werden. Wenn Remoteschriftarten in IDWriteTextLayout verwendet werden, wird der Download automatisch initiiert, wenn die App IDWriteTextLayout-Methoden aufruft, die Layout- oder Renderingvorgänge erzwingen, z. B. die GetLineMetrics- oder Draw-Methoden. In anderen Szenarien muss die App den Download direkt initiieren, indem IDWriteFontDownloadQueue::BeginDownloadDownload aufgerufen wird.
Wenn ein Download abgeschlossen ist, liegt es an der App, geeignete Aktionen auszuführen– mit ausstehenden Vorgängen oder wiederholten Vorgängen, die ursprünglich mit Fallbackschriftarten ausgeführt wurden. (Wenn das Textlayout DirectWrite verwendet wird, kann IDWriteTextLayout3::InvalidateLayout verwendet werden, um die temporären Ergebnisse zu löschen, die mithilfe von Fallbackschriftarten berechnet wurden.) Damit die App benachrichtigt wird, wenn der Downloadvorgang abgeschlossen ist, und geeignete Maßnahmen ergreifen kann, muss die App eine Implementierung der IDWriteFontDownloadListener-Schnittstelle bereitstellen und diese an den BeginDownload-Aufruf übergeben.
Wichtig
Sicherheits-/Leistungshinweis: Wenn versucht wird, eine Remoteschriftart abzurufen, gibt es keine Garantie, dass Windows eine Antwort vom Server erhält. Wenn der Server nicht antwortet, tritt für Windows ein Timeout auf. Dies kann jedoch einige Minuten dauern, wenn mehrere Remoteschriftarten abgerufen werden, aber ein Fehler auftritt. Der BeginDownload-Aufruf wird sofort zurückgegeben. Apps sollten die Benutzeroberfläche nicht blockieren, während sie auf den Aufruf von IDWriteFontDownloadListener::D ownloadCompleted warten.
Beispielimplementierungen dieser Interaktionen mit der DirectWrite-Warteschlange zum Herunterladen von Schriftarten und der IDWriteFontDownloadListener-Schnittstelle finden Sie im Beispiel DirectWrite Benutzerdefinierte Schriftartensätze und auch im Beispiel DirectWrite Herunterladbare Schriftarten.
Erstellen eines benutzerdefinierten Schriftartensatzes mithilfe von in den Arbeitsspeicher geladenen Schriftdaten
Ebenso wie sich die Vorgänge auf niedriger Ebene zum Lesen von Daten aus einer Schriftartdatei für Dateien auf einem lokalen Datenträger von Remotedateien im Web unterscheiden, gilt dies auch für Schriftartdaten, die in einen Speicherpuffer geladen werden. Im Windows 10 Creators Update IDWriteInMemoryFontFileLoader wurde eine neue Low-Level-Schnittstelle für die Verarbeitung von In-Memory-Schriftdaten hinzugefügt.
Wie bei einem Remote-Schriftartdateiladeprogramm muss zunächst ein In-Memory-Schriftartdateiladeprogramm bei einer DirectWrite Factory registriert werden. Das Ladeprogramm muss von der App so lange gehalten werden, wie die ihr zugeordneten Schriftarten verwendet werden. Sobald die Schriftarten nicht mehr verwendet werden, und zu einem bestimmten Zeitpunkt, bevor die Factory zerstört wird, muss die Registrierung des Ladeprogramms aufgehoben werden. Dies kann im Destruktor für die Klasse erfolgen, die das Ladeprogrammobjekt besitzt. Diese Schritte werden unten gezeigt.
Wenn die App über separate Informationen zu den durch die Daten dargestellten Schriftarten verfügt, kann sie einem Schriftartensatz-Generator mit angegebenen benutzerdefinierten Eigenschaften einzelne Schriftartensichtsverweise hinzufügen. Da sich die Schriftdaten jedoch im lokalen Speicher befinden, ist dies nicht erforderlich. DirectWrite können die Daten direkt lesen, um die Eigenschaftswerte abzuleiten.
DirectWrite geht davon aus, dass die Schriftartdaten im OpenType-Format unformatiert vorliegen, was einer OpenType-Datei (TTF, OTF, TTC, OTC) entspricht, aber nicht im Arbeitsspeicher als auf dem Datenträger. Die Daten dürfen nicht im WOFF- oder WOFF2-Containerformat vorliegen. Die Daten können eine OpenType-Schriftartsammlung darstellen. Wenn keine benutzerdefinierten Eigenschaften verwendet werden, kann die IDWriteFontSetBuilder1::AddFontFile-Methode verwendet werden, um alle Schriftarten in den Daten in einem einzigen Aufruf hinzuzufügen.
Ein wichtiger Aspekt für das In-Memory-Szenario ist die Lebensdauer der Daten. Wenn für DirectWrite ein Zeiger auf den Puffer bereitgestellt wird, ohne dass ein Besitzer vorhanden ist, erstellt DirectWrite eine Kopie der Daten in einen neuen Speicherpuffer, den sie besitzen wird. Um das Kopieren von Daten und zusätzliche Speicherbelegung zu vermeiden, kann die App ein Datenbesitzerobjekt übergeben, das IUnknown implementiert und den Speicherpuffer besitzt, der die Schriftartdaten enthält. Durch die Implementierung dieser Schnittstelle können DirectWrite der Referenzanzahl des Objekts hinzufügen und so die Lebensdauer der eigenen Daten sicherstellen.
Die Methode zum Erstellen eines benutzerdefinierten Schriftartensatzes mit In-Memory-Schriftartdaten lautet wie folgt: Hierfür ist die Windows 10 Creators Update erforderlich. Dabei wird ein von der App implementiertes Datenbesitzerobjekt angenommen, das IUnknown implementiert und außerdem Über Methoden verfügt, die einen Zeiger auf den Speicherpuffer und die Größe des Puffers zurückgeben.
- 1. Erstellen Sie wie oben gezeigt eine IDWriteFactory5-Schnittstelle.
2. Erstellen Sie eine [**IDWriteFontSetBuilder1**](/windows/win32/api/dwrite_3/nn-dwrite_3-idwritefontsetbuilder1)-Schnittstelle, wie oben gezeigt.
3. Verwenden Sie die Factory, um einen IDWriteInMemoryFontFileLoader abzurufen.
IDWriteInMemoryFontFileLoader* pInMemoryFontFileLoader;
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->CreateInMemoryFontFileLoader(&pInMemoryFontFileLoader);
}
Dadurch wird eine vom System bereitgestellte Implementierung der In-Memory-Schnittstelle für das Laden von Schriftartdateien zurückgegeben.
4. Registrieren Sie den In-Memory-Schriftartdateiladeprogramm bei der Factory.
if (SUCCEEDED(hr))
{
hr = pDWriteFactory->RegisterFontFileLoader(pInMemoryFontFileLoader);
}
5. Verwenden Sie für jede In-Memory-Schriftartdatei das In-Memory-Schriftartdateiladeprogramm, um eine IDWriteFontFile-Datei zu erstellen.
IDWriteFontFile* pFontFile;
hr = pInMemoryFontFileLoader->CreateInMemoryFontFileReference(
pDWriteFactory,
pFontDataOwner->fontData /* returns void* */,
pFontDataOwner->fontDataSize /* returns UINT32 */,
pFontDataOwner /* ownerObject, owns the memory with font data and implements IUnknown */,
&pFontFile
);
6. Fügen Sie das IDWriteFontFile-Objekt dem Schriftartensatz-Generator mithilfe der AddFontFile-Methode hinzu, wie oben gezeigt. Bei Bedarf kann die App stattdessen einzelne IDWriteFontFaceReference-Objekte basierend auf idWriteFontFile erstellen, optional benutzerdefinierte Eigenschaften für jeden Schriftartengesichtsverweis definieren und dann den Schriftsichtverweis mit benutzerdefinierten Eigenschaften dem Schriftartensatz mithilfe der AddFontFaceReference-Methode hinzufügen, wie oben gezeigt.
7. Nachdem alle Schriftarten dem Schriftartensatz-Generator hinzugefügt wurden, erstellen Sie den benutzerdefinierten Schriftartensatz, wie oben gezeigt.
8. Wenn die In-Memory-Schriftarten nicht mehr verwendet werden, heben Sie die Registrierung des In-Memory-Schriftartdateiladeprogramms auf.
hr = pDWriteFactory->UnregisterFontFileLoader(pInMemoryFontFileLoader);
Erweiterte Szenarien
Einige Apps haben möglicherweise spezielle Anforderungen, die eine erweiterte Verarbeitung erfordern, als oben beschrieben.
Kombinieren von Schriftartsätzen
Einige Apps müssen möglicherweise einen Schriftartensatz erstellen, der eine Kombination von Elementen aus anderen Schriftartensätzen enthält. Beispielsweise kann eine App einen Schriftartensatz erstellen, der alle auf dem System installierten Schriftarten mit einer Auswahl benutzerdefinierter Schriftarten kombiniert oder installierte Schriftarten kombiniert, die bestimmte Kriterien erfüllen, mit anderen Schriftarten. DirectWrite verfügt über APIs, um die Bearbeitung und Kombination von Schriftsätzen zu unterstützen.
Um zwei oder mehr Schriftartensätze zu kombinieren, fügt die IDWriteFontSetBuilder::AddFontSet-Methode alle Schriftarten in einem bestimmten Schriftartensatz hinzu, die einem Schriftartensatz-Generator in einem einzigen Aufruf hinzugefügt werden sollen. Wenn nur bestimmte Schriftarten aus einem vorhandenen Schriftartensatz im neuen Schriftartensatz verwendet werden sollen, kann die IDWriteFontSet::GetMatchingFonts-Methode verwendet werden, um ein neues Schriftartensatzobjekt abzuleiten, das gefiltert wurde, um nur Schriftarten einzuschließen, die den angegebenen Eigenschaften entsprechen. Diese Methoden bieten eine einfache Möglichkeit, einen benutzerdefinierten Schriftartensatz zu erstellen, der Schriftarten aus zwei oder mehr vorhandenen Schriftartensätzen kombiniert.
Verwenden von lokalen WOFF- oder WOFF2-Schriftartdaten
Wenn eine App Über Schriftartdateien im lokalen Dateisystem oder in einem Speicherpuffer verfügt, sie aber das WOFF- oder WOFF2-Containerformat verwendet, stellt DirectWrite (Windows 10 Creator Update oder höher) eine Methode zum Entpacken des Containerformats idWriteFactory5::UnpackFontFile bereit, das einen IDWriteFontFileStream zurückgibt.
Die App benötigt jedoch eine Möglichkeit, den IDWriteFontFileStream in ein Schriftartdateiladeobjekt zu übertragen. Eine Möglichkeit besteht darin, eine benutzerdefinierte IDWriteFontFileLoader-Implementierung zu erstellen, die den Stream umschließt. Wie bei anderen Schriftartdateiladeprogrammen muss diese vor der Verwendung registriert und die Registrierung aufgehoben werden, bevor die Factory den Gültigkeitsbereich überschreitet.
Wenn das benutzerdefinierte Ladeprogramm auch mit unformatierten (nicht gepackten) Schriftartdateien verwendet wird, muss die App auch eine benutzerdefinierte Implementierung der IDWriteFontFileStream-Schnittstelle für die Verarbeitung dieser Dateien bereitstellen. Es gibt jedoch einfachere Möglichkeiten, apIs zu verwenden, die oben beschrieben wurden, um unformatierte Schriftartdateien zu verarbeiten. Die Notwendigkeit einer benutzerdefinierten Streamimplementierung kann vermieden werden, indem separate Codepfade für gepackte Schriftartdateien im Vergleich zu unformatierten Schriftartdateien verwendet werden.
Nachdem ein benutzerdefiniertes Schriftartdateiladeobjekt erstellt wurde, werden die gepackten Schriftdateidaten dem Ladeprogramm mit appspezifischen Mitteln hinzugefügt. Das Ladeprogramm kann mehrere Schriftartdateien verarbeiten, von denen jede mithilfe eines app-definierten Schlüssels identifiziert wird, der für DirectWrite undurchsichtig ist. Nachdem dem Ladeprogramm eine gepackte Schriftartdatei hinzugefügt wurde, wird die IDWriteFactory::CreateCustomFontFileReference-Methode verwendet, um ein IDWriteFontFile basierend auf diesem Ladeprogramm für die durch einen bestimmten Schlüssel identifizierten Schriftartdaten abzurufen.
Das eigentliche Entpacken der Schriftartdaten kann durchgeführt werden, wenn Schriftarten dem Ladeprogramm hinzugefügt werden, aber auch in der IDWriteFontFileLoader::CreateStreamFromKey-Methode, die DirectWrite aufruft, wenn die Schriftartdaten zum ersten Mal gelesen werden müssen.
Nachdem ein IDWriteFontFile-Objekt erstellt wurde, werden die verbleibenden Schritte zum Hinzufügen der Schriftarten zu einem benutzerdefinierten Schriftartensatz wie oben beschrieben ausgeführt.
Eine Implementierung mit diesem Ansatz wird im Beispiel für benutzerdefinierte Schriftartensätze DirectWrite veranschaulicht.
Verwenden DirectWrite Remoteschriftartenmechanismen mit benutzerdefinierter Low-Level-Netzwerkimplementierung
Die DirectWrite Mechanismen für die Behandlung von Remoteschriftarten können in Mechanismen auf höherer Ebene unterteilt werden– mit Schriftartsätzen, die Schriftsichtverweise für Remoteschriftarten enthalten, der Überprüfung der Lokalität der Schriftartdaten und der Verwaltung der Warteschlange für Schriftartdownloadanforderungen – und den Mechanismen auf niedrigerer Ebene, die den tatsächlichen Download behandeln. Einige Apps möchten möglicherweise die übergeordneten Remoteschriftartenmechanismen verwenden, erfordern aber auch benutzerdefinierte Netzwerkinteraktionen, z. B. die Kommunikation mit Servern über andere Protokolle als HTTP.
In dieser Situation muss eine App eine benutzerdefinierte Implementierung der IDWriteRemoteFontFileLoader-Schnittstelle erstellen, die auf die erforderliche Weise mit anderen Schnittstellen auf niedrigerer Ebene interagiert. Die App muss auch benutzerdefinierte Implementierungen dieser Schnittstellen auf niedrigerer Ebene bereitstellen: IDWriteRemoteFontFileStream und IDWriteAsyncResult. Diese drei Schnittstellen verfügen über Rückrufmethoden, die DirectWrite während Downloadvorgängen aufrufen.
Wenn IDWriteFontDownloadQueue::BeginDownload aufgerufen wird, führt DirectWrite Abfragen zum Standort der Daten an den Remoteschriftdateiladeer durch und fordert den Remotestream an. Wenn die Daten nicht lokal sind, wird die BeginDownload-Methode des Datenstroms aufgerufen. Die Streamimplementierung sollte bei diesem Aufruf nicht blockiert werden, sondern sollte sofort zurückgegeben werden, indem ein IDWriteAsyncResult-Objekt zurückgegeben wird, das das Wartehandle bereitstellt, DirectWrite verwendet wird, um auf den asynchronen Downloadvorgang zu warten. Die benutzerdefinierte Streamimplementierung ist für die Verarbeitung der Remotekommunikation verantwortlich. Wenn das Vervollständigungsereignis aufgetreten ist, ruft DirectWrite IDWriteAsyncResult::GetResult auf, um das Ergebnis des Vorgangs zu bestimmen. Wenn das Ergebnis erfolgreich ist, wird erwartet, dass nachfolgende ReadFragment-Aufrufe des Datenstroms für die heruntergeladenen Bereiche erfolgreich sind.
Wichtig
Sicherheits-/Leistungshinweis: Wenn versucht wird, eine Remoteschriftart abzurufen, besteht das Potenzial für einen Angreifer im Allgemeinen, den beabsichtigten Server zu spoofen, der aufgerufen wird, oder dass der Server möglicherweise nicht reagiert. Wenn Sie benutzerdefinierte Netzwerkinteraktionen implementieren, haben Sie möglicherweise eine größere Kontrolle über Entschärfungen als beim Umgang mit Servern von Drittanbietern. Es liegt jedoch an Ihnen, geeignete Abhilfemaßnahmen zu erwägen, um die Offenlegung von Informationen oder denial-of-Service zu vermeiden. Es werden sichere Protokolle wie HTTPS empfohlen. Außerdem sollten Sie ein Timeout erstellen, damit das Ereignishandle, das an DirectWrite zurückgegeben wird, irgendwann festgelegt wird.
Unterstützende Szenarien in früheren Windows-Versionen
Die beschriebenen Szenarien können in DirectWrite früheren Versionen von Windows unterstützt werden, erfordern jedoch eine viel mehr benutzerdefinierte Implementierung seitens der App mithilfe der eingeschränkteren APIs, die vor Windows 10 verfügbar waren. Weitere Informationen finden Sie unter Benutzerdefinierte Schriftartsammlungen (Windows 7/8).