Отрисовать на поверхность GDI
В некоторых случаях вам может понадобиться возможность отображать текст 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::Draw, передав интерфейс обратного вызова, который вы реализовали, в качестве параметра. Метод IDWriteTextLayout::Draw вызывает методы предоставленного обратного вызова пользовательского отрисовщика. Методы рисования DrawGlyphRun, DrawUnderline, DrawInlineObjectи DrawStrikethrough выполняют функции рисования.
В вашей реализации DrawGlyphRunвызовите метод IDWriteBitmapRenderTarget::DrawGlyphRun для рисования глифов. Отрисовка подчеркивания, зачеркнутого и встроенного объектов должна выполняться пользовательским отрисовщиком.
IDWriteBitmapRenderTarget::DrawGlyphRun имеет необязательный выходной параметр RECT, содержащий границы области, где был нарисован текст. Эти сведения можно использовать для задания ограничивающего прямоугольника для контекста устройства с помощью функции 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 из DC памяти на поверхность GDI, как показано в следующем коде.
// Transfer from DWrite's rendering target to the window.
BitBlt(
hdc,
0, 0,
size.cx, size.cy,
memoryHdc,
0, 0,
SRCCOPY | NOMIRRORBITMAP
);