Calculating how many lines of text will fit in a given window, Directwrite & Direct2d

Proposed Calculating how many lines of text will fit in a given window, Directwrite & Direct2d

  • Friday, February 18, 2011 5:31 PM
     
     

    I'm designing a text control using Directwrite, and I want to figure out how many lines of text will fit in a window.

    Right now the formula I'm using looks like:

     

    lines_in_window = windowheight/txtformat->GetFontSize();

     

    /*

    windowheight is rc.bottom - rc.top, with the values of

    rc filled in by GetClientRect()

     

    txtformat is an IDWriteTextFormat* created with a font size

    of "16.0f"

    */

     

    The results dependent on that formula seem to be off by about 1/3 (too many lines are scrolled on page up/down, etc.), and I'm not really sure where the error is coming from.

    Maybe the measurement types are mismatched? I've tried getting the window height with prt->GetSize().height for the height, as well as getting the font size from the format's GetFontSize() function, but the results are identical.

    The line spacing value I get from IDWriteTextLayout's GetLineSpacing() function is always 0, so I haven't bothered taking it into account in the formula.

    The automatic word-wrapping of the IDWriteTextLayout I'm using to put text to the render target doesn't seem to be responsible for the error, either, since I've tried switching it on and off to no effect.

All Replies

  • Friday, February 18, 2011 10:03 PM
     
     
    For the benefit of those who may stumble across this problem in the future: when using IDWriteTextFormat::GetFontSize(), the font size is given as a point size and must be converted into pixels before being used in screen size calculations.
  • Friday, July 13, 2012 5:01 AM
     
     
    Font size is DIP's (1/96 inch), where at 96 DPI, 1 DIP = 1 pixel. So for most desktops (and if no scaling is applied), the font size is essentially just pixels. To convert old points (1/72 inch) to DIPs, use x dips = y pts * 96 / 72.

    Dwayne Robinson

  • Friday, July 13, 2012 5:06 AM
     
     Proposed
    The font em size is not the same as the line height, and what you're actually wanting is line height. Many fonts at the same 'size' have different line heights because their ascent and descent values (above and below the baseline) differ. So since the line height depends on the font being used, the most reliable way to estimate this is to call IDWriteTextLayout::GetMetrics and use DWRITE_TEXT_METRICS::height, or call IDWriteTextLayout::GetLineMetrics and use DWRITE_LINE_METRICS::height. For this call, you can just create an empty layout with the IDWriteTextFormat you intend to use. Note that font fallback (if you mixed multiple languages together) can complicate the calculation, but it's still a reasonable estimate, and it's a perfectly accurate value if you know all the text ahead of time will be present in the font you are using (such as simple English in a console-like window).

    Dwayne Robinson