DWriteCore の概要

DWriteCore は、DirectWriteWindows App SDK 実装です (DirectWrite は、高品質のテキスト レンダリング、解像度に依存しないアウトライン フォント、Unicode テキストとレイアウトの完全サポートのための DirectX API です)。 DWriteCore は、DirectWrite Windows 10 Version 1809 (10.0;ビルド 17763)。 DWriteCore では、DirectWriteと同じ API が実装され、このトピックで説明するようにいくつか追加されています。

この入門トピックでは、DWriteCore とは何かについて説明し、それを開発環境とプログラムにインストールする方法を示します。

既にDirectWriteを使用しているアプリの場合、DWriteCore に切り替える場合は最小限の変更が必要です。

  • Windows アプリ SDK パッケージへの参照を追加します。
  • の代わりに をdwrite_3.h含めますdwrite_core.h
  • の代わりに DWrite.libリンクDWriteCore.libします。
  • DWriteCreateFactory の代わりに DWriteCoreCreateFactory を呼び出します。

その代わりに、アプリはWindows アプリ SDKの利点を得られます。つまり、顧客が実行している Windows のバージョンに関係なく、最新の API と機能にアクセスできます。

ヒント

アクティブな開発における DirectX コンポーネントの説明とリンクについては、 ブログ投稿「DirectX ランディング ページ」を参照してください。

DWriteCore の価値提案

DirectWrite自体は、直接呼び出しまたは Direct2D 経由のいずれを使用する場合でも、ほとんどのアプリで Windows で選択できるフォント レンダリング ツールとなる豊富な機能をサポートしています。 DirectWriteには、デバイスに依存しないテキスト レイアウト システム、高品質のサブピクセル Microsoft ClearType テキスト レンダリング、ハードウェア高速テキスト、マルチフォーマット テキスト、高度な OpenType® 文字体裁機能、幅広い言語サポート、GDI 互換のレイアウトとレンダリングが含まれます。 DirectWriteは、Windows Vista SP2 以降で使用でき、フォント リソースが 1 つだけのフォントにスタイル、重み、その他の属性を適用できる可変フォントなどのより高度な機能が含まれるように、長年にわたって進化してきました。

しかし、DirectWriteの寿命が長いため、開発の進歩により、古いバージョンの Windows が遅れる傾向があります。 さらに、プレミア テキスト レンダリング テクノロジとしてのDirectWriteの状態は Windows のみに制限されているため、クロスプラットフォーム アプリケーションは独自のテキスト レンダリング スタックを記述するか、サード パーティのソリューションに依存します。

DWriteCore は、ライブラリをシステムから削除し、サポートされているすべてのエンドポイントを対象とすることで、バージョン機能の孤立とクロスプラットフォーム互換性の基本的な問題を解決します。 そのために、DWriteCore をWindows アプリ SDKに統合しました。

DWriteCore が開発者としてWindows アプリ SDKに提供する主な価値は、多くの (最終的にはすべての) DirectWrite機能へのアクセスを提供するということです。 DWriteCore のすべての機能は、どの機能がどのバージョンで動作する可能性があるかに関する違いなしに、すべての下位レベルのバージョンで同じように機能します。

DWriteCore デモ アプリ - DWriteCoreGallery

DWriteCore は、 DWriteCoreGallery サンプル アプリを使用して示されています。このアプリは、ダウンロードして調査することができます。

DWriteCore の概要

DWriteCore は、Windows アプリ SDKの一部です。 このセクションでは、DWriteCore を使用してプログラミングするための開発環境を設定する方法について説明します。

Windows App SDK 用のツールをインストールする

Windows App SDK 用のツールをインストールする」を参照してください。

新しいプロジェクトを作成する

Visual Studio で、 空のアプリ Packaged (デスクトップの WinUI 3) プロジェクト テンプレートから新しいプロジェクトを作成します。 そのプロジェクト テンプレートは、言語 C++ を選択して見つけることができます。platform: Windows アプリ SDK;プロジェクトの種類: Desktop

詳細については、「 WinUI 3 のプロジェクト テンプレート」を参照してください。

Microsoft.ProjectReunion.DWrite NuGet パッケージをインストールする

Visual Studio で、[プロジェクト>] [NuGet パッケージの管理] の順にクリックします。>検索ボックスに「Microsoft.ProjectReunion.DWrite」と入力するか貼り付け、検索結果の項目を選択し、[インストール] をクリックしてそのプロジェクトのパッケージをインストールします。

または、DWriteCoreGallery サンプル アプリから始めます

または、DWriteCoreGallery サンプル アプリ プロジェクトから始めて DWriteCore を使用してプログラムし、そのプロジェクトに基づいて開発を行うことができます。 その後、そのサンプル プロジェクトから既存のソース コード (またはファイル) を自由に削除し、新しいソース コード (またはファイル) をプロジェクトに追加できます。

プロジェクトで DWriteCore を使用する

DWriteCore を使用したプログラミングの詳細については、このトピックで後述する 「DWriteCore を使用したプログラミング 」セクションを参照してください。

DWriteCore のリリース フェーズ

DWriteCore へのDirectWriteの移植は、複数の Windows リリース サイクルにまたがる十分に大きなプロジェクトです。 そのプロジェクトはフェーズに分割され、それぞれがリリースで提供される機能のチャンクに対応します。

DWriteCore の現在のリリースの機能

DWriteCore は、Windows アプリ SDKの一部です。 これには、開発者が DWriteCore を使用するために必要な基本的なツールが含まれています。これには、次の機能が含まれます。

バナー機能はカラー フォントです。 カラー フォントを使用すると、単純な単一色以外の高度な色機能でフォントをレンダリングできます。 たとえば、カラー フォントは、絵文字やツール バー アイコン フォントをレンダリングする機能を高めるものです (後者は Office で使用されます)。 カラー フォントはWindows 8.1で最初に導入されましたが、Windows 10 バージョン 1607 (Anniversary Update) で機能が大幅に拡張されました。

フォント キャッシュとメモリ内フォント ローダーのクリーンアップに関する作業により、フォントの読み込み時間が短縮され、メモリが向上します。

これらの機能を使用すると、可変フォントなど、DirectWriteの最新のコア機能の一部をすぐに利用できます。 可変フォントは、DirectWriteのお客様にとって最も重要な機能の 1 つです。

DirectWrite開発者としての皆様への招待

DWriteCore は、他のWindows アプリ SDK コンポーネントと共に、開発者のフィードバックをオープンにして開発されます。 DWriteCore の調査を開始し、Windows アプリ SDK GitHub リポジトリで機能開発に関する分析情報や要求を提供することをお勧めします。

DWriteCore を使用したプログラミング

DirectWriteと同様に、IDWriteFactory インターフェイスを使用して、COM ライト API を使用して DWriteCore をプログラムします。

DWriteCore を使用するには、ヘッダー ファイルを含める dwrite_core.h 必要があります。

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

ヘッダー ファイルは dwrite_core.h 、最初にトークン DWRITE_COREを定義してから、ヘッダー ファイルを dwrite_3.h 含めます。 DWRITE_CORE トークンは重要です。これは、その後に含まれるヘッダーを指示して、すべてのDirectWrite API を使用できるようにするためです。 プロジェクトに が含まれる dwrite_core.hと、先に進み、コードの記述、ビルド、実行を行うことができます。

DWriteCore の新しい API または異なる API

DWriteCore API サーフェスは、DirectWriteの場合とほとんど同じです。 ただし、現時点では DWriteCore にのみ存在する新しい API が少数あります。

ファクトリ オブジェクトを作成する

DWriteCoreCreateFactory free 関数では、個々の DWriteCore オブジェクトの後続の作成に使用されるファクトリ オブジェクトが作成されます。

DWriteCoreCreateFactory は、DirectWrite のシステム バージョンによってエクスポートされる DWriteCreateFactory 関数と機能的に同じです。 DWriteCore 関数には、あいまいさを避けるために別の名前があります。

制限付きファクトリ オブジェクトを作成する

DWRITE_FACTORY_TYPE列挙には、制限付きファクトリを示す新しい定数 (DWRITE_FACTORY_TYPE_ISOLATED2) があります。 制限付きファクトリは、分離されたファクトリよりもロックダウンされます。 クロスプロセスまたは永続的なフォント キャッシュとは何もやり取りしません。 さらに、このファクトリから返されるシステム フォント コレクションには、既知のフォントのみが含まれます。 DWriteCoreCreateFactory free 関数を呼び出すときに、DWRITE_FACTORY_TYPE_ISOLATED2を使用して制限付きファクトリ オブジェクトを作成する方法を次に示します。

// 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())
  )
);

DWRITE_FACTORY_TYPE_ISOLATED2をサポートしていない古いバージョンのDirectWriteに渡すと、DWriteCreateFactoryE_INVALIDARGを返します。

システム メモリ ビットマップへのグリフの描画

DirectWriteには、システム メモリ内のビットマップへのグリフのレンダリングをサポートするビットマップ レンダー ターゲット インターフェイスがあります。 ただし、現在、基になるピクセル データにアクセスする唯一の方法は GDI 経由であるため、API はクロスプラットフォームでは使用できません。 これは、ピクセル データを取得するメソッドを追加することで簡単に修正できます。

そのため、DWriteCore には IDWriteBitmapRenderTarget2 インターフェイスとそのメソッド IDWriteBitmapRenderTarget2::GetBitmapData が導入されています。 このメソッドは、新しい構造体である DWRITE_BITMAP_DATA_BGRA32 型の パラメーター (へのポインター) を受け取ります。

アプリケーションでは、 IDWriteGdiInterop::CreateBitmapRenderTarget を呼び出してビットマップ レンダー ターゲットを作成します。 Windows では、ビットマップ レンダー ターゲットは、GDI デバイスに依存しないビットマップ (DIB) が選択された GDI メモリ DC をカプセル化します。 IDWriteBitmapRenderTarget::D rawGlyphRun は、グリフを DIB にレンダリングします。 DirectWrite GDI を経由せずにグリフ自体をレンダリングします。 その後、アプリケーションはビットマップ レンダー ターゲットから HDC を取得し、 BitBlt を使用してピクセルをウィンドウ HDC にコピーできます。

Windows 以外のプラットフォームでは、アプリケーションでビットマップ レンダー ターゲットを作成することはできますが、 HDC も DIB もないシステム メモリ配列をカプセル化するだけです。 HDC を使用しない場合、アプリケーションがビットマップ ピクセルを取得してコピーしたり、使用したりするには、別の方法が必要です。 Windows でも、実際のピクセル データを取得すると便利な場合があります。現在の方法を次のコード例に示します。

// 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);
}

DWriteCore と DirectWrite のその他の API の違い

スタブのみであるか、Windows 以外のプラットフォームでは動作が若干異なる API がいくつかあります。 たとえば、IDWriteGdiInterop::CreateFontFaceFromHdc は、GDI のない HDC などがないため、Windows 以外のプラットフォームでE_NOTIMPLを返します。

最後に、DirectWriteと一緒に使用される他の特定の Windows API があります (Direct2D は注目すべき例です)。 ただし、現時点では、Direct2D と DWriteCore は相互運用されません。 たとえば、 DWriteCore を使用して IDWriteTextLayout を作成し、それを D2D1RenderTarget::D rawTextLayout に渡すと、その呼び出しは失敗します。