MeasureString

Jan 20, 2014 at 11:39 PM
Thanks for the great code!
I'm having one issue though.

MeasureString doesn't seem to return correct values, which flags am I supposed to use?

This is my current code, rect has some impossible high values for .Bottom and .Right
    FW1_RECTF layoutRect;
    layoutRect.Left = rect.Top = 0;
    layoutRect.Bottom = 1080;
    layoutRect.Right = 1920;

    FW1_RECTF rect = pFontWrapper->MeasureString(L"test test test", L"Arial", 14.0f, &layoutRect, FW1_ANALYZEONLY);
Jan 21, 2014 at 1:15 PM
Edited Jan 21, 2014 at 1:16 PM
I put another function together, I'm just wondering about the performance of this.
At least it's working ;)
const Drawing::Size Font::MeasureText(const std::string &text)
{
    IDWriteFactory *pDWriteFactory;
    pFontWrapper->GetDWriteFactory(&pDWriteFactory);

    IDWriteTextFormat *pTextFormat;
    pDWriteFactory->CreateTextFormat(fontFamily, NULL, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_OBLIQUE, DWRITE_FONT_STRETCH_NORMAL, FontSize, L"", &pTextFormat);

    IDWriteTextLayout *pTextLayout;
    pDWriteFactory->CreateTextLayout(StringToWCHAR(text), text.length(), pTextFormat, 0.0f, 0.0f, &pTextLayout);
    pTextLayout->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);

    pDWriteFactory->Release();

    DWRITE_OVERHANG_METRICS overhangMetrics;
    pTextLayout->GetOverhangMetrics(&overhangMetrics);

    return Drawing::Size(overhangMetrics.right - overhangMetrics.left, overhangMetrics.bottom - overhangMetrics.top);
}
Coordinator
Jan 21, 2014 at 2:28 PM
Thanks for reporting, I will investigate what might cause it.

The library does exactly the same calls as you do, but doesn't recreate the text-format each time (but still recreates the text-layout). It also attempts to place the rect so it covers exactly the pixels drawn if drawing the string (with left and right coordinates instead of width). Performance is reasonable, but it's ofcourse best to cache the size and update when the string changes.
Marked as answer by arnibold on 1/21/2014 at 7:27 AM
Coordinator
Jan 21, 2014 at 2:39 PM
The bug was that the library ignores the layout-rect and assumes the text is drawn with FW1_NOWORDWRAP, so it only works if the text is drawn at X, Y and not when it's drawn with a box..
I'll update it when I have time, thanks again :)
Marked as answer by arnibold on 1/21/2014 at 7:27 AM
Coordinator
Jan 21, 2014 at 2:45 PM
Also, for exact coordinates you want to add overhangMetrics.right + overhangMetrics.left, and not subtract them, though usually there's no overhang so it won't matter. If you would want to measure strings with a layout-box (not 0.0f for width/height in CreateTextLayout) then also add the width/height to the size.
Marked as answer by arnibold on 1/21/2014 at 7:27 AM
Jan 21, 2014 at 6:43 PM
Edited Jan 21, 2014 at 6:45 PM
But when only looking for the exact Width and Height of a string, then subtraction is the way to go (if there would ever be an overhang), isn't it?

Or is it
left & top = X & Y position
right & bottom = width & height
Coordinator
Jan 21, 2014 at 6:52 PM
Overhang coordinates always extend away from the character, even on the left side, so addition yields the correct result.

From http://msdn.microsoft.com/en-us/library/windows/desktop/dd368109%28v=vs.85%29.aspx
Positive overhangs indicate that the visible area extends outside the layout box or inline object, while negative values mean there is whitespace inside.