Font.MeasureString questions

Started by
8 comments, last by AvengerDr 16 years, 9 months ago
Hi there, I'm having some problems with the MeasureString method of the D3D Font object. I found out that for that method the string "a" and "a " are the same (whitespaces at the end of the string are not counted). BUT, oddly enough "j " and "j" are not the same, because for the letter j (and some others too), whitespaces are counted. It probably is a bug... Also there seems no way to compute the length of a whitespace.. This was done using arial 20pt as the font. My question is: what is exactly going on behind the scenes when I call this method? Is it rendering the text onto a texture and then returning the rectangle? If it stores the length of the characters in some way, is there a way to access those values without computing them (again?) myself? Also, does the method PreloadCharacters/Glpyh really help? It doesn't seem to do anything... Thanks in advance!
--Avengers UTD Chronicles - My game development blog
Advertisement
Unfortunately, I don't have any answers for you, outside of the fact that I did report this to the D3D team a while ago and provided them examples. They replied to the extent of saying they'd look into it, but that the last I heard of it :(
"Game Programming" in an of itself does not exist. We learn to program and then use that knowledge to make games.
I don't have the answer to your question but I can tell you a little workaround i found.

i. Choose one character measure its width and store it in some variable, say 'x'
ii. Use MeasureString to find x's width and store it in some variable, say 'y'.
iii. When calling MeasureString append x temporarily to your text and afterwards subtract y from the rectanlge width.

Examle:
Rectangle r = Font.MeasureString(sprite,text + x,textFormat,Color.Black.ToArgb());
r.Width -= y;

This works since MeasureString only ignores trailing blanks. And by following this workaround there are never any trailing blanks.
Thanks for the replies. Another useful workaround would be to measure the width of characters that can be typed (from ASCII code 33 to 100 something, I don't remember exactly). In the end, with a small computation you can measure the whitespace lenght too (ie like you said measure first "." and then " ." for example, so the whitespace lenght would be " .".Width - ".".Width). And when you need to measure the length of a string you can simply call a method that converts the string to a char array and loops through it, adding the individual character length (found on the lookup table computed earlier) to the total sum, without having to call Font.MeasureString.

I think that in certain cirmustances there's nothing else you can do beside knowing how much a certain character is wide. For example, if you are allowing mouse placement of the caret, you need to know that.. So I decided to do it once and for all :)

Anyway, Annoyed, how are you rendering text in your GUI? Through the sprite interface or not?
--Avengers UTD Chronicles - My game development blog
Quote:Original post by AvengerDr
Anyway, Annoyed, how are you rendering text in your GUI? Through the sprite interface or not?
Using regular Win32/GDI methods isn't too difficult but I doubt it'll be friendly via .NET!

I imagine MeasureString is just a managed wrapper over GetTextExtentPoint32(), so you could try P/Invoking it directly. I don't remember having any problems using it in my GUI renderer.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

What you present is indeed a more solid solution, I havent come to mouse placing caret my self, so my simple workaround works for now :)

If you mean that I include a sprite as an argument to the DrawText call instead of null, then yes i do.
Yes I asked you if you place your text drawing calls between sprite.Begin() and End() calls. I was asking that because I wanted to know if the sprite interface is doing something "silly" like recreating the vertexbuffer each frame. Because many GUIs avoid using that in favor of "manual" text rendering.
--Avengers UTD Chronicles - My game development blog
That I do.
Also i strive to have a single Begin and End call per render loop, that is I render all text objects rather than having a Begin End call for each.
Which you likely already know, that is the main point for using a sprite. If not then the Font will use the D3DX's "own" sprite and call Begin End for each DrawText call.

But for my part ... I hardly notice any difference.
Here is an interesting article that compares different string measuring methods and has a program at the bottom you can play with to see them in action.

http://msdn.microsoft.com/msdnmag/issues/06/03/TextRendering/default.aspx
Thanks!
Who knows what exactly is the sprite interface doing when it is used through Begin/End calls()? Because I'd like to know if it'd worthwhile to spend some time in developing a "manual" text renderer. I had a look at the source code of Cegui# and they have implemented a system which does just that..
--Avengers UTD Chronicles - My game development blog

This topic is closed to new replies.

Advertisement