Search code examples
c++windowsgdidirect2ddirectwrite

DirectWrite GDI interop: Simple way to draw text using an `IDWriteFontFace`


I have a device context which has some font selected into it, and I would like to DrawText on an ID2D1RenderTarget.

Currently, I go the following route to acchieve this:

  • Obtain an IDWriteFontFace via CreateFontFaceFromHdc.
  • Obtain an IDWriteFont from the IDWriteFontFace via the default system font collection (which I get via GetSystemFontCollection - see the next step).
  • Obtain an IDWriteTextFormat via CreateTextFormat, supplying the parameters specified in the IDWriteFont and specifying nullptr as fontCollection, indicating that I would like to use the default system font collection.
  • Pass the IDWriteTextFormat to DrawText.

What I find strange about this is that I already have an IDWriteFontFace in the first step, and apparently have to "go back" and ask a font collection for an IDWriteFont, just to pass that to a DrawTextFormat, which can then be used to DrawText. This seems unnecessarily complicated - especially since to draw the text, the system probably has to go down to a IDWriteFontFace anyway, right?

I found DrawGlyphRun, but this takes e.g. a baselineOrigin, which I would have to compute beforehand (not to mention the glyphRun itself).

Isn't there a simpler way to draw text onto an ID2D1RenderTarget if I already have an IDWriteFontFace?


Solution

  • That's the only way, like you described. You go back to construct text format instance, and then use it for DirectWrite-style rendering. DrawGlyphRun is a low level method, you can use it of course, but you'll have to implement a lot of layout logic yourself, and that's something to avoid. Generally speaking DrawText is the least efficient method of rendering with Direct2D, better way is to create layout object once and use it every time you need to redraw.