Condividi tramite


Eseguire il rendering in una superficie GDI

In alcuni casi, potresti voler visualizzare DirectWrite testo su una superficie GDI. L'interfaccia IDWriteBitmapRenderTarget incapsula una bitmap e un contesto di dispositivo in cui eseguire il rendering del testo. Crea un IDWriteBitmapRenderTarget usando 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 metodi per disegnare una sequenza di glifi, una sottolineatura, un barrato, oggetti in linea e così via. Per un elenco completo dei metodi, vedere la pagina di riferimento IDWriteTextRenderer. Non tutti i metodi devono essere implementati, ma possono semplicemente restituire E_NOTIMPLe il disegno continuerà.

È quindi possibile disegnare il testo usando il metodo IDWriteTextLayout::Draw e passando l'interfaccia di callback che hai implementato come parametro. Il metodo IDWriteTextLayout::Draw chiama i metodi del callback del renderer personalizzato che fornisci. Le DrawGlyphRun, DrawUnderline, DrawInlineObject, e DrawStrikethrough eseguono le funzioni di disegno.

Nell'implementazione di DrawGlyphRun, chiamare il metodo IDWriteBitmapRenderTarget::DrawGlyphRun per disegnare i glifi. Il rendering degli oggetti sottolineati, barrati e in linea deve essere eseguito dal renderer personalizzato.

IDWriteBitmapRenderTarget::DrawGlyphRun 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 DC, usa il metodo IDWriteBitmapRenderTarget::GetMemoryDC. Non appena viene eseguito il disegno, il DC 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 DirectWrite dal DC 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
    );