Vue d’ensemble de DWriteCore

DWriteCore est l’implémentation SDK d'application Windows de DirectWrite (DirectWrite est l’API DirectX pour le rendu de texte de haute qualité, les polices de plan indépendantes de la résolution et la prise en charge du texte Unicode complet et de la disposition). DWriteCore est une forme de DirectWrite qui s’exécute sur des versions de Windows jusqu’à Windows 10, version 1809 (10.0 ; Build 17763). DWriteCore implémente la même API que DirectWrite, avec quelques ajouts comme décrit dans cette rubrique.

Cette rubrique d’introduction décrit ce qu’est DWriteCore et montre comment l’installer dans votre environnement de développement et le programmer.

Pour une application qui utilise déjà DirectWrite, le passage à DWriteCore nécessite des modifications minimales :

  • Ajoutez une référence au package SDK d'application Windows.
  • Inclure dwrite_core.h au lieu de dwrite_3.h.
  • Lier DWriteCore.lib au lieu de DWrite.lib.
  • Appelez DWriteCoreCreateFactory au lieu de DWriteCreateFactory.

En retour, l’application bénéficie des avantages de SDK d'application Windows, à savoir l’accès aux API et fonctionnalités les plus récentes, quelle que soit la version de Windows exécutée par votre client.

Conseil

Pour obtenir des descriptions et des liens vers les composants DirectX en développement actif, consultez le billet de blog Page d’accueil DirectX.

Proposition de valeur de DWriteCore

DirectWrite lui-même prend en charge un large éventail de fonctionnalités qui en fait l’outil de rendu des polices de choix sur Windows pour la plupart des applications, que ce soit par le biais d’appels directs ou via Direct2D. DirectWrite comprend un système de disposition de texte indépendant de l’appareil, un rendu de texte Microsoft ClearType sous-pixel de haute qualité, du texte accéléré sur le matériel, du texte multiformat, des fonctionnalités avancées de typographie OpenType®, une prise en charge large de la langue, ainsi que la disposition et le rendu compatibles GDI. DirectWrite est disponible depuis Windows Vista SP2, et il a évolué au fil des ans pour inclure des fonctionnalités plus avancées telles que les polices variables, ce qui vous permet d’appliquer des styles, des pondérations et d’autres attributs à une police avec une seule ressource de police.

En raison de la longue durée de vie de DirectWrite, les progrès du développement ont tendance à laisser les anciennes versions de Windows derrière. En outre, DirectWrite status en tant que technologie de rendu de texte de premier plan est limitée uniquement à Windows, ce qui laisse aux applications multiplateformes soit écrire leur propre pile de rendu de texte, soit s’appuyer sur des solutions tierces.

DWriteCore résout les problèmes fondamentaux liés à l’orphelin des fonctionnalités de version et à la compatibilité multiplateforme en supprimant la bibliothèque du système et en ciblant tous les points de terminaison pris en charge possibles. À cette fin, nous avons intégré DWriteCore dans SDK d'application Windows.

La principale valeur que DWriteCore vous donne, en tant que développeur, dans SDK d'application Windows est qu’il fournit l’accès à de nombreuses (et éventuellement à toutes) fonctionnalités DirectWrite. Toutes les fonctionnalités de DWriteCore fonctionnent de la même façon sur toutes les versions de niveau inférieur sans aucune disparité quant aux fonctionnalités qui peuvent fonctionner sur quelles versions.

Application de démonstration DWriteCore : DWriteCoreGallery

DWriteCore est démontré par le biais de l’exemple d’application DWriteCoreGallery , que vous pouvez maintenant télécharger et étudier.

Bien démarrer avec DWriteCore

DWriteCore fait partie du SDK d'application Windows. Cette section explique comment configurer votre environnement de développement pour la programmation avec DWriteCore.

Installer des outils pour le SDK d’application Windows

Consultez Installer des outils pour le SDK d’application Windows.

Création d'un projet

Dans Visual Studio, créez un projet à partir du modèle de projet Application vide, empaquetée (WinUI 3 in Desktop). Vous pouvez trouver ce modèle de projet en choisissant langue : C++; plateforme : SDK d'application Windows ; type de projet : Bureau.

Pour plus d’informations, consultez Modèles de projet pour WinUI 3.

Installer le package NuGet Microsoft.ProjectReunion.DWrite

Dans Visual Studio, cliquez sur Project>Manage NuGet Packages...>Parcourez, tapez ou collez Microsoft.ProjectReunion.DWrite dans la zone de recherche, sélectionnez l’élément dans les résultats de recherche, puis cliquez sur Installer pour installer le package pour ce projet.

Vous pouvez également commencer par l’exemple d’application DWriteCoreGallery

Vous pouvez également programmer avec DWriteCore en commençant par l’exemple de projet d’application DWriteCoreGallery et baser votre développement sur ce projet. Vous pouvez ensuite supprimer tout code source (ou fichiers) existant de cet exemple de projet et ajouter tout nouveau code source (ou fichiers) au projet.

Utiliser DWriteCore dans votre projet

Pour plus d’informations sur la programmation avec DWriteCore, consultez la section Programmation avec DWriteCore plus loin dans cette rubrique.

Phases de publication de DWriteCore

Le portage de DirectWrite vers DWriteCore est un projet suffisamment volumineux pour couvrir plusieurs cycles de publication Windows. Ce projet est divisé en phases, chacune correspondant à un segment de fonctionnalités fournie dans une version.

Fonctionnalités de la version actuelle de DWriteCore

DWriteCore fait partie du SDK d'application Windows. Il contient les outils de base dont vous, en tant que développeur, avez besoin pour utiliser DWriteCore, y compris les fonctionnalités suivantes.

Une fonctionnalité de bannière est les polices de couleur. Les polices de couleur vous permettent de restituer vos polices avec des fonctionnalités de couleur plus sophistiquées au-delà des couleurs simples. Par exemple, les polices de couleur sont ce qui permet de restituer les polices d’emoji et d’icône de barre d’outils (cette dernière étant utilisée par Office, par exemple). Les polices de couleur ont été introduites pour la première fois dans Windows 8.1, mais la fonctionnalité a été fortement développée dans Windows 10, version 1607 (mise à jour anniversaire).

Le travail sur le nettoyage du cache de polices et le chargeur de polices en mémoire permettent d’accélérer le chargement des polices et d’améliorer la mémoire.

Avec ces fonctionnalités, vous pouvez immédiatement commencer à exploiter certaines des fonctionnalités de base modernes de DirectWrite, telles que les polices variables. Les polices variables sont l’une des fonctionnalités les plus importantes pour DirectWrite clients.

Notre invitation à vous en tant que développeur DirectWrite

DWriteCore, ainsi que d’autres composants SDK d'application Windows, seront développés avec ouverture aux commentaires des développeurs. Nous vous invitons à commencer à explorer DWriteCore et à fournir des insights ou des demandes sur le développement de fonctionnalités sur notre dépôt GitHub SDK d'application Windows.

Programmation avec DWriteCore

Tout comme avec DirectWrite, vous programmez avec DWriteCore via son API COM-light, via l’interface IDWriteFactory.

Pour utiliser DWriteCore, il est nécessaire d’inclure le fichier d’en-tête dwrite_core.h .

// pch.h
...
// DWriteCore header file.
#include <dwrite_core.h>

Le dwrite_core.h fichier d’en-tête définit d’abord le jeton DWRITE_CORE, puis il inclut le fichier d’en-tête dwrite_3.h . Le jeton DWRITE_CORE est important, car il dirige les en-têtes ultérieurement inclus pour mettre toutes les API DirectWrite à votre disposition. Une fois que votre projet a inclus dwrite_core.h, vous pouvez continuer et écrire du code, générer et exécuter.

API nouvelles ou différentes pour DWriteCore

La surface de l’API DWriteCore est en grande partie la même que pour DirectWrite. Mais il existe un petit nombre de nouvelles API qui se trouvent uniquement dans DWriteCore à l’heure actuelle.

Créer un objet de fabrique

La fonction libre DWriteCoreCreateFactory crée un objet de fabrique qui est utilisé pour la création ultérieure d’objets DWriteCore individuels.

DWriteCoreCreateFactory est fonctionnellement identique à la fonction DWriteCreateFactory exportée par la version système de DirectWrite. La fonction DWriteCore a un nom différent pour éviter toute ambiguïté.

Créer un objet de fabrique restreint

L’énumération DWRITE_FACTORY_TYPE a une nouvelle constante, DWRITE_FACTORY_TYPE_ISOLATED2, indiquant une fabrique restreinte. Une usine restreinte est plus verrouillée qu’une usine isolée. Il n’interagit pas avec un cache de polices inter-processus ni persistant de quelque manière que ce soit. En outre, la collection de polices système retournée par cette fabrique inclut uniquement des polices connues. Voici comment utiliser DWRITE_FACTORY_TYPE_ISOLATED2 pour créer un objet de fabrique restreint lorsque vous appelez la fonction libre DWriteCoreCreateFactory .

// Create a factory that doesn't interact with any cross-process nor
// persistent cache state.
winrt::com_ptr<::IDWriteFactory7> spFactory;
winrt::check_hresult(
  ::DWriteCoreCreateFactory(
    DWRITE_FACTORY_TYPE_ISOLATED2,
    __uuidof(spFactory),
    reinterpret_cast<IUnknown**>(spFactory.put())
  )
);

Si vous passez DWRITE_FACTORY_TYPE_ISOLATED2 à une version antérieure de DirectWrite qui ne la prend pas en charge, DWriteCreateFactory retourne E_INVALIDARG.

Dessin de glyphes dans une image bitmap de mémoire système

DirectWrite dispose d’une interface cible de rendu bitmap qui prend en charge le rendu des glyphes en bitmap dans la mémoire système. Toutefois, actuellement, la seule façon d’accéder aux données de pixels sous-jacentes consiste à passer par GDI, et donc l’API n’est pas utilisable sur plusieurs plateformes. Cela est facilement corrigé en ajoutant une méthode pour récupérer les données de pixels.

Ainsi, DWriteCore introduit l’interface IDWriteBitmapRenderTarget2 et sa méthode IDWriteBitmapRenderTarget2::GetBitmapData. Cette méthode prend un paramètre de type (pointeur vers) DWRITE_BITMAP_DATA_BGRA32, qui est un nouveau struct.

Votre application crée une cible de rendu bitmap en appelant IDWriteGdiInterop::CreateBitmapRenderTarget. Sur Windows, une cible de rendu bitmap encapsule un contrôleur de domaine de mémoire GDI avec un bitmap indépendant de l’appareil (DIB) GDI sélectionné. IDWriteBitmapRenderTarget::D rawGlyphRun affiche les glyphes dans la DIB. DirectWrite restitue les glyphes lui-même sans passer par GDI. Votre application peut ensuite obtenir le HDC à partir de la cible de rendu bitmap et utiliser BitBlt pour copier les pixels dans une fenêtre HDC.

Sur les plateformes autres que Windows, votre application peut toujours créer une cible de rendu bitmap, mais elle encapsule simplement un tableau de mémoire système sans HDC ni DIB. Sans HDC, votre application doit disposer d’un autre moyen d’obtenir les pixels bitmap afin qu’elle puisse les copier ou les utiliser. Même sur Windows, il est parfois utile d’obtenir les données de pixels réelles, et nous montrons la façon actuelle de le faire dans l’exemple de code ci-dessous.

// pch.h
#pragma once

#include <windows.h>
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>

// WinMain.cpp
#include "pch.h"
#include <dwrite_core.h>
#pragma comment(lib, "Gdi32")

class TextRenderer
{
    DWRITE_BITMAP_DATA_BGRA32 m_targetBitmapData;

public:
    void InitializeBitmapData(winrt::com_ptr<IDWriteBitmapRenderTarget> const& renderTarget)
    {
        // Query the bitmap render target for the new interface. 
        winrt::com_ptr<IDWriteBitmapRenderTarget2> renderTarget2;
        renderTarget2 = renderTarget.try_as<IDWriteBitmapRenderTarget2>();

        if (renderTarget2)
        {
            // IDWriteBitmapRenderTarget2 exists, so we can get the bitmap the easy way. 
            winrt::check_hresult(renderTarget2->GetBitmapData(OUT & m_targetBitmapData));
        }
        else
        {
            // We're using an older version that doesn't implement IDWriteBitmapRenderTarget2, 
            // so we have to get the bitmap by going through GDI. First get the bitmap handle. 
            HDC hdc = renderTarget->GetMemoryDC();
            winrt::handle dibHandle{ GetCurrentObject(hdc, OBJ_BITMAP) };
            winrt::check_bool(bool{ dibHandle });

            // Call a GDI function to fill in the DIBSECTION structure for the bitmap. 
            DIBSECTION dib;
            winrt::check_bool(GetObject(dibHandle.get(), sizeof(dib), &dib));

            m_targetBitmapData.width = dib.dsBm.bmWidth;
            m_targetBitmapData.height = dib.dsBm.bmHeight;
            m_targetBitmapData.pixels = static_cast<uint32_t*>(dib.dsBm.bmBits);
        }
    }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
    TextRenderer textRenderer;
    winrt::com_ptr<IDWriteBitmapRenderTarget> renderTarget{ /* ... */ };
    textRenderer.InitializeBitmapData(renderTarget);
}

Autres différences d’API entre DWriteCore et DirectWrite

Il existe quelques API qui sont soit des stubs uniquement, soit se comportent un peu différemment sur les plateformes non Windows. Par exemple, IDWriteGdiInterop::CreateFontFaceFromHdc retourne E_NOTIMPL sur les plateformes non Windows, car il n’existe pas de HDC sans GDI.

Enfin, il existe d’autres API Windows qui sont généralement utilisées avec DirectWrite (Direct2D étant un exemple notable). Toutefois, actuellement, Direct2D et DWriteCore n’interagissent pas. Par exemple, si vous créez un IDWriteTextLayout à l’aide de DWriteCore et que vous le transmettez à D2D1RenderTarget::D rawTextLayout, cet appel échoue.