Jump to content
  • Advertisement
Sign in to follow this  
AvengerDr

Font.MeasureString questions

This topic is 4152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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 :(

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!