Renderizar em um Surface GDI
Em alguns casos, convém exibir DirectWrite texto em uma superfície GDI. A interface IDWriteBitmapRenderTarget encapsula um bitmap e o contexto do dispositivo para renderizar texto. Você cria um IDWriteBitmapRenderTarget usando o método IDWriteGdiInterop::CreateBitmapRenderTarget , conforme mostrado no código a seguir.
if (SUCCEEDED(hr))
{
hr = g_pGdiInterop->CreateBitmapRenderTarget(hdc, r.right, r.bottom, &g_pBitmapRenderTarget);
}
Para renderizar com um IDWriteBitmapRenderTarget, você deve implementar uma interface de retorno de chamada do renderizador de texto personalizada derivada da interface IDWriteTextRenderer . Você deve implementar métodos para desenhar uma execução de glifo, sublinhado, tachado, objetos embutidos e assim por diante. Para obter uma lista completa dos métodos, consulte a página de referência IDWriteTextRenderer . Nem todos os métodos devem ser implementados, eles podem apenas retornar E_NOTIMPL e o desenho continuará.
Em seguida, você pode desenhar o texto usando o método IDWriteTextLayout::D raw e passando a interface de retorno de chamada implementada como um parâmetro. O método IDWriteTextLayout::D raw chama os métodos do retorno de chamada do renderizador personalizado que você fornece. Os métodos DrawGlyphRun, DrawUnderline, DrawInlineObject e DrawStrikethrough executam as funções de desenho.
Na implementação do Método DrawGlyphRun, chame o método IDWriteBitmapRenderTarget::D rawGlyphRun para desenhar os glifos. A renderização dos objetos sublinhados, tachados e embutidos deve ser feita pelo renderizador personalizado.
IDWriteBitmapRenderTarget::D rawGlyphRun tem um parâmetro RECT out opcional que contém os limites da área em que o texto foi desenhado. Você pode usar essas informações para definir o retângulo delimitador para o contexto do dispositivo com a função SetBoundsRect fornecida pela GDI. O código a seguir é um exemplo de implementação do método DrawGlyphRun de um renderizador personalizado.
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;
}
A interface IDWriteBitmapRenderTarget é renderizada em um DC (contexto de dispositivo) na memória. Você obtém um identificador para esse DC usando o método IDWriteBitmapRenderTarget::GetMemoryDC . Assim que o desenho tiver sido executado, o DC de memória do objeto IDWriteBitmapRenderTarget deverá ser copiado para a superfície GDI de destino.
Você pode recuperar o retângulo delimitador usando a função GetBoundsRect e, em seguida, usar o retângulo delimitador com a função BitBlt para copiar o texto DirectWrite renderizado do DC de memória para a superfície GDI, conforme mostrado no código a seguir.
// Transfer from DWrite's rendering target to the window.
BitBlt(
hdc,
0, 0,
size.cx, size.cy,
memoryHdc,
0, 0,
SRCCOPY | NOMIRRORBITMAP
);