locked
How to determine the number of characters that fit into a directWrite textLayout out or drawText with layoutrect?

    Question

  • Let's say I have the following:

    dwriteFactory->CreateTextLayout( text->Data(), text->Length(), textFormat.Get(), bounds.right, bounds.bottom, &textLayout);

    m_d2dContext->BeginDraw();

    m_d2dContext->DrawTextLayout(
    D2D1::Point2F(0, 0),
    textLayout.Get(),
    m_brush.Get(),
    D2D1_DRAW_TEXT_OPTIONS_NONE);

    m_d2dContext->EndDraw();

    How could I determine how many characters would fit into that bound region?
    As far I can tell, metrics only give you width & height back, as overhangMetrics does.

    Friday, November 15, 2013 10:45 PM

All replies

  • There is no way to query how many characters will fit. The number that will fit depends on the characters and their order.

    You would need to calculate this the other direction. You can measure a proposed set of characters to see how much room they need. Add or subtract characters until you find a close enough fit.

    --Rob

    Saturday, November 16, 2013 5:38 AM
    Owner
  • Hi Rob,

    thanks for pointing me in the right direction. I've got it working so far but since I'm new to either c++ and directx I don't know if the following is the right way to do it... may be there's a better way?

    The textformat is defined outside the for loop:

    for (const wchar_t c : text) { temp += c;

    dwriteFactory->CreateTextLayout( temp.c_str(), temp.length(), textFormat.Get(), width, height, &textLayout);

    m_d2dContext->DrawTextLayout( D2D1::Point2F(0, 0), textLayout.Get(), m_brush.Get(), D2D1_DRAW_TEXT_OPTIONS_NONE); textLayout->GetMetrics(&metrics); // Do metrics stuff here } }

    So I create a new textlayout in each loop with the string to be drawn extended by one character. As mentioned... it works, but I don't know if this is the right way to do it

    EDIT: I just figured out that beginDraw and endDraw isn't needed for the calculations only, so I removed that from the loop.


    • Edited by SW_Andy Sunday, November 17, 2013 9:18 PM
    Sunday, November 17, 2013 8:50 PM
  • Ok, I simplified it even more, because the DrawTextLayout wasn't also needed:

    for (const wchar_t c : text) {
    			temp += c;			
    			dwriteFactory->CreateTextLayout(
    				temp.c_str(),
    				temp.length(),
    				textFormat.Get(),
    				width,
    				height,
    				&textLayout);
    
    			textLayout->GetMetrics(&metrics);
    			// Do metrics stuff here
    		}
    
    	}
    But I'm a bit concerned by the CreateTextLayout each iteration. Is there a way to just edit/update a part of it (e.g. just the text and length of it)?

    Sunday, November 17, 2013 9:56 PM
  • Anybody knows if there's a faster way to iterate trough the letters and measure them?
    Wednesday, November 20, 2013 8:56 AM