Eseguire il rendering in una superficie GDI
In alcuni casi, può essere necessario visualizzare DirectWrite testo in una superficie GDI. L'interfaccia IDWriteBitmapRenderTarget incapsula una bitmap e un contesto di dispositivo in cui eseguire il rendering del testo. Per creare un IDWriteBitmapRenderTarget , usare il metodo IDWriteGdiInterop::CreateBitmapRenderTarget , come illustrato nel codice seguente.
if (SUCCEEDED(hr))
{
hr = g_pGdiInterop->CreateBitmapRenderTarget(hdc, r.right, r.bottom, &g_pBitmapRenderTarget);
}
Per eseguire il rendering con un IDWriteBitmapRenderTarget, è necessario implementare un'interfaccia di callback del renderer di testo personalizzata derivata dall'interfaccia IDWriteTextRenderer . È necessario implementare i metodi per disegnare una sequenza di glifi, sottolineatura, barrato, oggetti inline e così via. Per un elenco completo dei metodi, vedere la pagina di riferimento IDWriteTextRenderer . Non tutti i metodi devono essere implementati, possono semplicemente restituire E_NOTIMPL e il disegno continuerà.
È quindi possibile disegnare il testo usando il metodo IDWriteTextLayout::D raw e passando l'interfaccia di callback implementata come parametro. Il metodo IDWriteTextLayout::D raw chiama i metodi del callback del renderer personalizzato fornito. I metodi DrawGlyphRun, DrawUnderline, DrawInlineObject e DrawStrikethrough eseguono le funzioni di disegno.
Nell'implementazione di DrawGlyphRun chiamare il metodo IDWriteBitmapRenderTarget::D rawGlyphRun per disegnare i glifi. Il rendering degli oggetti sottolineati, barrati e inline deve essere eseguito dal renderer personalizzato.
IDWriteBitmapRenderTarget::D rawGlyphRun ha un parametro RECT out facoltativo che contiene i limiti dell'area in cui è stato disegnato il testo. È possibile usare queste informazioni per impostare il rettangolo di delimitazione per il contesto di dispositivo con la funzione SetBoundsRect fornita da GDI. Il codice seguente è un'implementazione di esempio del metodo DrawGlyphRun di un renderer personalizzato.
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;
}
L'interfaccia IDWriteBitmapRenderTarget esegue il rendering in memoria di un contesto di dispositivo (DC). Per ottenere un handle per questo controller di dominio, usare il metodo IDWriteBitmapRenderTarget::GetMemoryDC . Non appena viene eseguito il disegno, il controller di dominio di memoria dell'oggetto IDWriteBitmapRenderTarget deve essere copiato nella superficie GDI di destinazione.
È possibile recuperare il rettangolo di delimitazione usando la funzione GetBoundsRect, quindi usare il rettangolo di delimitazione con la funzione BitBlt per copiare il testo di cui è stato eseguito il rendering DirectWrite testo dal controller di dominio di memoria alla superficie GDI, come illustrato nel codice seguente.
// Transfer from DWrite's rendering target to the window.
BitBlt(
hdc,
0, 0,
size.cx, size.cy,
memoryHdc,
0, 0,
SRCCOPY | NOMIRRORBITMAP
);