c++winapidirectwrite

How to initialize Directwrite IDWriteTextLayout properly in a Direct2D window


I'm trying to write text to my ID2D1HwndRenderTarget* renderTarget-window using Directwrite. That works good and text appears where it should. But i have the feeling i'm doing something wrong in Graphics::DrawMyText. I think I should create my IDWriteTextLayout* textLayout also in the Graphics::Initialisation but if I do that, i cannot alter the text const wchar_t* wszText anymore. At least, I did not find any helper function in IDWriteTextLayout interface

So is it correct to create and release my IDWriteTextLayout all the time, or is there a way I only have to create it once like the other interfaces?

#include<dwrite.h>

class Graphics
{
    IDWriteFactory* writeFactory;
    IDWriteTextLayout* textLayout;
    IDWriteTextFormat* textFormat; 
}

Graphics() // constructor
{
    writeFactory = NULL;
    textLayout = NULL;
    textFormat = NULL; 
}

Graphics::~Graphics() // destructor
{
    if (writeFactory) writeFactory->Release();
    if (textLayout) textLayout->Release();
    if (textFormat) textFormat->Release();
}

bool Graphics::Initialise(HWND windowsHandle)
{
    res = writeFactory->CreateTextFormat(
    L"Lucida Console",
    NULL,
    DWRITE_FONT_WEIGHT_REGULAR,
    DWRITE_FONT_STYLE_NORMAL,
    DWRITE_FONT_STRETCH_NORMAL,
    10.0f,
    L"en-us",
    &textFormat
    );
    if (res != S_OK) return false;

    return true;
}

void Graphics::DrawMyText(const wchar_t* wszText, float x, float y, float boxWidth,
                          float boxHeight, float r, float g, float b, float a)
{
    writeFactory->CreateTextLayout(wszText, (UINT32)wcslen(wszText), textFormat,
                                   boxWidth, boxHeight, &textLayout);
    brush->SetColor(D2D1::ColorF(r, g, b, a));
    renderTarget->DrawTextLayout(D2D1::Point2F(x, y), textLayout, brush);
    textLayout->Release(); // don't forget this one to prevent memory leaks
}

Solution

  • The text of a DWrite layout is indeed fixed, your choices are either to create (and release) layout objects or go the much harder route of using IDWriteTextAnalyzer (along with IDWriteTextAnalysisSource/IDWriteTextAnalysisSink). It would have been nice if the text of a layout were mutable but MS simply didn't make that choice.