如何绘制文本
若要使用 Direct2D 绘制文本,请使用 ID2D1RenderTarget::D rawText 方法处理具有单一格式的文本。 或者,将 ID2D1RenderTarget::D rawTextLayout 方法用于多种格式、高级 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 对象一次,并且每次必须重新绘制文本时重复使用它,则性能会提高,因为系统不必再次测量和布局文本。
在使用 DrawTextLayout 方法之前,必须使用 IDWriteFactory 创建 IDWriteTextFormat 和 IDWriteTextLayout 对象。 创建这些对象后,调用 DrawTextLayout 方法。
有关详细信息和示例,请参阅 文本格式和布局 概述。
相关主题