The simplest and most reliable approach is simply to request text metrics from the layout itself, as one of the two things for which it was designed: drawing and measuring. You must create an IDWriteTextLayout using text format and call GetMetrics to get DWRITE_TEXT_METRICS::height . I assume that you are using ID2D1RenderTarget::DrawText and passing in a text format, so you may not have created the layout directly, but calling DrawText similar to calling CreateTextLayout yourself and then DrawTextLayout .
Remember that going through the lower levels to get this answer ( IDWriteFontFace , etc.) makes certain assumptions that a common text-ready text control should not assume, for example, assuming that the base font will be used and that all lines are the same. height. As long as all characters are present in this base font, this will work (chances are you mostly display English, so everything looks good), but add some CJK or RTL or emoji languages ββ(which is the base font) like Times New Roman, of course, does not support), and the line height will increase or decrease in accordance with the replacement of fonts. GDI resizes the replaced fonts so that they fit the base height of the font, but this leads to poorly compressed letters in languages ββsuch as Thai and Tibetan, which need more space for lifting and lowering. IDWriteTextLayout and other layouts like those found in WPF / Word keep all glyphs of fonts of the same em size, which means that they are better placed when they are next to each other; but that means the row height is variable.
If you simply draw each line of text, as if they were all the same height, you can see overlapping between glyphs and heterogeneous baselines between the lines, or clipping at the top and bottom of the control. Thus, the ideal thing is to use the actual height of each row; but if you want them all to be the same height (or if that complicates the control too much), then at least set the explicit line spacing using SetLineSpacing with DWRITE_LINE_SPACING_UNIFORM equal to the base font - so the baselines are evenly distributed.
Although for the curious, IDWriteTextLayout calculates the line height as the maximum of all run heights on this line, and the height of one run (with the same font and em size) simply uses the project metrics: ascent + descent, plus any occurring lineGap to be present (most fonts set this value to zero, but Gabriola is a good example of a big line break). Note that all em sizes are indicated in DIP (which with typical 96DPI means 1: 1, DIP exactly == pixels), and not in dots (1/72 of an inch).
(ascent + descent + lineGap) * emSize / designUnitsPerEm
Dwayne robinson
source share