Compartilhar via


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