Condividi tramite


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
    );