Отрисовка на GDI Surface
В некоторых случаях может потребоваться отображать DirectWrite текст на поверхности GDI. Интерфейс IDWriteBitmapRenderTarget инкапсулирует растровое изображение и контекст устройства для отрисовки текста. Вы создаете IDWriteBitmapRenderTarget с помощью метода IDWriteGdiInterop::CreateBitmapRenderTarget , как показано в следующем коде.
if (SUCCEEDED(hr))
{
hr = g_pGdiInterop->CreateBitmapRenderTarget(hdc, r.right, r.bottom, &g_pBitmapRenderTarget);
}
Для отрисовки с помощью IDWriteBitmapRenderTarget необходимо реализовать пользовательский интерфейс обратного вызова отрисовщика текста, производный от интерфейса IDWriteTextRenderer . Необходимо реализовать методы для рисования выполнения глифа, подчеркивания, зачеркивания, встроенных объектов и т. д. Полный список методов см. на странице справочника IDWriteTextRenderer . Не все методы должны быть реализованы, они могут просто возвращать E_NOTIMPL, и рисование будет продолжаться.
Затем можно нарисовать текст с помощью метода IDWriteTextLayout::D raw и передать интерфейс обратного вызова, реализованный в качестве параметра. Метод IDWriteTextLayout::D raw вызывает методы пользовательского обратного вызова отрисовщика, который вы предоставляете. Методы DrawGlyphRun, DrawUnderline, DrawInlineObject и DrawStrikethrough выполняют функции рисования.
В реализации DrawGlyphRun вызовите метод IDWriteBitmapRenderTarget::D rawGlyphRun для рисования глифов. Отрисовка подчеркивающих, зачеркивающих и встроенных объектов должна выполняться пользовательским отрисовщиком.
IDWriteBitmapRenderTarget::D rawGlyphRun имеет необязательный параметр RECT out, содержащий границы области, в которой был нарисован текст. Эти сведения можно использовать для задания ограничивающего прямоугольника для контекста устройства с помощью функции SetBoundsRect , предоставляемой GDI. Ниже приведен пример реализации метода DrawGlyphRun пользовательского отрисовщика.
STDMETHODIMP GdiTextRenderer::DrawGlyphRun(
__maybenull void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_MEASURING_MODE measuringMode,
__in DWRITE_GLYPH_RUN const* glyphRun,
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
IUnknown* clientDrawingEffect
)
{
HRESULT hr = S_OK;
// Pass on the drawing call to the render target to do the real work.
RECT dirtyRect = {0};
hr = pRenderTarget_->DrawGlyphRun(
baselineOriginX,
baselineOriginY,
measuringMode,
glyphRun,
pRenderingParams_,
RGB(0,200,255),
&dirtyRect
);
return hr;
}
Интерфейс IDWriteBitmapRenderTarget отрисовывается в контексте устройства (DC) в памяти. Дескриптор для этого контроллера домена можно получить с помощью метода IDWriteBitmapRenderTarget::GetMemoryDC . Как только рисование будет выполнено, память контроллера домена объекта IDWriteBitmapRenderTarget должна быть скопирована в целевую поверхность GDI.
Ограничивающий прямоугольник можно получить с помощью функции GetBoundsRect, а затем использовать ограничивающий прямоугольник с функцией BitBlt, чтобы скопировать отрисованный DirectWrite текст из контроллера домена памяти на поверхность GDI, как показано в следующем коде.
// Transfer from DWrite's rendering target to the window.
BitBlt(
hdc,
0, 0,
size.cx, size.cy,
memoryHdc,
0, 0,
SRCCOPY | NOMIRRORBITMAP
);