D3DXFONT and length of string

Started by
9 comments, last by SunTzu 17 years, 2 months ago
I have created a font using D3DXCreateFont, and I am paaing a height and width variable. I then use DrawText, and I am passing the number of characters with str.length() I would like to be able to get the length of the string in pixels on the screen, not only for the Rect but also for adding more text to the same line. Using str.width() * height doesnt seem to work right, because it seems that some characters different width than other characters. How can I get this length?
signature? I ain't signin nuthin!
Advertisement
This is whatI do - maybe there is a better way.

After calling D3DXCreateFont(), I get the HDC of the font and use that to get an array of widths for characters from ' ' to '~'. Store that along with the font pointer for use in figuring out string widths in pixels.

Here is some simplified code

D3DXCreateFontIndirect(m_pDevice, &(f->desc), &(f->font));f->font->PreloadCharacters(' ', '~');HDC hdc = f->font->GetDC(); if (!GetCharWidth32(hdc, ' ', '~', f->widths)) {  ABC w[95];  GetCharABCWidths(hdc, ' ', '~', w);  for (int i = 0; i < 95; ++i) f->widths = w.abcA + w.abcB + w.abcC;}


GetCharWidth32() only works for non-true type.
GetCharABCWidths() only works for true type.

ID3DXFONT's DrawString method returns a RECT describing the area the text was drawn in. This is useful for calculating string widths.

If you want to just calculate the width without actually drawing, you can pass a CALCRECT flag to the function, that makes it skip drawing and just return the RECT it would have drawn to. Check the DX Docs for more information.

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
ID3DXFont::DrawText supports the DT_CALCRECT format-flag, which causes the function not to render any text, but calculate the minimum-bounding-RECT and return it.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
I recall that there was some issues around DrawText / DT_CALCRECT and how it handles spaces. Sometimes the space character would be counted with a width of 0. I don't recall the exact cases - its been a while. Possibly its even fixed now :p
This is all I can find in the docs on DT_CALCRECT

"Determines the width and height of the rectangle. If there are multiple lines of text, ID3DXFont::DrawText uses the width of the rectangle pointed to by the pRect parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, ID3DXFont::DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, ID3DXFont::DrawText returns the height of the formatted text but does not draw the text."

I dont understand how to use this. It does not draw the text? Do I call it twice then? Or do I say Rect rct=font->DrawText(/my,params,and,stuff,DT_CALCRECT)? I tried those 2 ways but no luck yet :) Can someone please show me an example of its use?

[Edit] I want to thank you madox for your solution also. I am still looking at it, but there are some things in it that I don't yet understand, and I am learning its different parts also :)
signature? I ain't signin nuthin!
With the DT_CALCRECT flag set it will not draw the text, you have to make another call with out the flag set to draw it.

Ideally you use the version with DT_CALCRECT before you are ready to render, to ensure text is spaced out appropriately so it doesn't overlap, and making sure it doesn't go off screen.

For example:
I have used this to ensure text doesn't overlap or go off screen in a window that displays images with their name. Since the images may be bigger or smaller than the width of the text I need to know the texts width to make sure things are spaced out.
Raven Software :: Tools Programmer
[Ravensoft] [My Site] [Full Sail]
OK thanks. This dosen't seem to be what im looking for then. My text and string length changes during runtime. I need to know the length of the text in real time. I did try calling it twice during my render, but just got a blank screen.I can't find an example of it anywhere. I think I will use madox's method, I just need to break it down a little. I have a bad habit of having to understand every little thing before I use somthing :)
Thanks everybody.
signature? I ain't signin nuthin!
Quote:Original post by oldskoolPunk
OK thanks. This dosen't seem to be what im looking for then. My text and string length changes during runtime. I need to know the length of the text in real time. I did try calling it twice during my render, but just got a blank screen.I can't find an example of it anywhere. I think I will use madox's method, I just need to break it down a little. I have a bad habit of having to understand every little thing before I use somthing :)
Thanks everybody.
You can still call it at runtime. Something like this (Semi-psuedo-code):

RECT rc;pFont->DrawText(&rc, ..., DT_CALCRECT); // Might want DT_SINGLELINE too// rc now contains the size of the text. Width in pixels is rc.right-rc.left// Adjust rect if neededpFont->DrawText(&rc, ..., 0); // Actually draw the text this time
Thanks, man, it works!
I tried this before, and it didn't work (no text was displayed). Well, you have to fill rect.top and rect.left , I wasn't doing this.

Thanks Evil Steve and everyone else.
signature? I ain't signin nuthin!

This topic is closed to new replies.

Advertisement