如何繪製文字

若要使用 Direct2D 繪製文字,請使用具有單一格式之文字的 ID2D1RenderTarget::D rawText 方法。 或者,使用 ID2D1RenderTarget::DrawTextLayout 方法,以進行多種格式、進階 OpenType 功能或點擊測試。 這些方法會使用 DirectWrite API 來提供高品質的文字顯示。

DrawText 方法

若要繪製具有單一格式的文字,請使用 DrawText 方法。 若要使用此方法,請先使用 IDWriteFactory 來建立 IDWriteTextFormat 實例。

下列程式代碼會建立 IDWriteTextFormat 物件,並將它儲存在 m_pTextFormat 變數中。

// Create resources which are not bound
// to any device. Their lifetime effectively extends for the
// duration of the app. These resources include the Direct2D and
// DirectWrite factories,  and a DirectWrite Text Format object
// (used for identifying particular font characteristics).
//
HRESULT DemoApp::CreateDeviceIndependentResources()
{
    static const WCHAR msc_fontName[] = L"Verdana";
    static const FLOAT msc_fontSize = 50;
    HRESULT hr;

    // Create a Direct2D factory.
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);

    if (SUCCEEDED(hr))
    {        
        // Create a DirectWrite factory.
        hr = DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(m_pDWriteFactory),
            reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create a DirectWrite text format object.
        hr = m_pDWriteFactory->CreateTextFormat(
            msc_fontName,
            NULL,
            DWRITE_FONT_WEIGHT_NORMAL,
            DWRITE_FONT_STYLE_NORMAL,
            DWRITE_FONT_STRETCH_NORMAL,
            msc_fontSize,
            L"", //locale
            &m_pTextFormat
            );
    }
    if (SUCCEEDED(hr))
    {
        // Center the text horizontally and vertically.
        m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
        
        m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
    }

    return hr;
}

由於 IDWriteFactory 和 IDWriteTextFormat 是與裝置無關的資源,因此,您可以透過只建立它們一次來改善應用程式的效能,而不是在每次繪製畫面時重新建立。

建立文字格式對象之後,即可將它與轉譯目標搭配使用。 下列程式代碼會使用轉譯目標 DrawText 方法繪製文字(m_pRenderTarget 變數)。

//  Called whenever the application needs to display the client
//  window. This method writes "Hello, World"
//
//  Note that this function will automatically discard device-specific
//  resources if the Direct3D device disappears during function
//  invocation, and will recreate the resources the next time it's
//  invoked.
//
HRESULT DemoApp::OnRender()
{
    HRESULT hr;

    hr = CreateDeviceResources();

    if (SUCCEEDED(hr))
    {
        static const WCHAR sc_helloWorld[] = L"Hello, World!";

        // Retrieve the size of the render target.
        D2D1_SIZE_F renderTargetSize = m_pRenderTarget->GetSize();

        m_pRenderTarget->BeginDraw();

        m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());

        m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

        m_pRenderTarget->DrawText(
            sc_helloWorld,
            ARRAYSIZE(sc_helloWorld) - 1,
            m_pTextFormat,
            D2D1::RectF(0, 0, renderTargetSize.width, renderTargetSize.height),
            m_pBlackBrush
            );

        hr = m_pRenderTarget->EndDraw();

        if (hr == D2DERR_RECREATE_TARGET)
        {
            hr = S_OK;
            DiscardDeviceResources();
        }
    }

    return hr;
}

DrawTextLayout 方法

DrawTextLayout 方法會轉譯 IDWriteTextLayout 物件。 使用此方法可以將多種格式套用至文字區塊(例如,為部分文字加上底線)、使用進階 OpenType 功能,以及執行點擊測試支援。

DrawTextLayout 方法也提供重複繪製相同文字的效能優點。 IDWriteTextLayout 物件在建立時會測量和排版其文字。 如果您只建立 IDWriteTextLayout 物件,並在每次重新繪製文字時重複使用它,則效能會改善,因為系統不需要測量並重新配置文字。

您必須先使用 IDWriteFactory,才能使用 DrawTextLayout 方法來建立 IDWriteTextFormat 和 IDWriteTextLayout 物件。 建立這些對象之後,請呼叫 DrawTextLayout 方法。

如需詳細資訊和範例,請參閱 文字格式設定和版面配置 概觀。

DrawText

DrawTextLayout

IDWriteTextFormat

IDWriteTextLayout

文字格式設定和版面配置