Sign in to follow this  

Font/char sizes in C#

This topic is 3861 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 For learning purpose I'm writing my own font renderer in C#. I.e. render a font to texture and also store some data about where each char is placed. The thing is that when I render/draw the character I can't seem to get the exact width of the char. I've tested with both "Graphics.MeasureCharacterRanges" and "Graphics.MeasureString", but none of them seems to fit my purpose. E.g. The "tail" of a '9' or a 'j' in some fonts is not included in the returned width in the methods described above. Any pointers would be appriciated. Thanks

Share this post


Link to post
Share on other sites
Does this work?


private Size MeasureString(string str, int maxWidth, Font font)
{
Graphics g = this.CreateGraphics();
SizeF strRectSizeF = g.MeasureString(str, font, maxWidth);
g.Dispose();

return new Size(
(int)Math.Ceiling(strRectSizeF.Width),
(int)Math.Ceiling(strRectSizeF.Height));
}

Share this post


Link to post
Share on other sites
Nope... sry

The thing is that, since I wrote my last post I figured that I need all metric info about each char. Stuff like:
Minimal bounding box, acent, descent, height, width and some sort of "pivot point?".
I don't know the correct term (instead of "pivot point"), but I meen something like how far from peceeding char this char should be placed. This depends very much from each char and is not as simple as the width since a char like e.g. 'j' or '9' may have its "tail" to be drawn under the preceeding char.

I know how to get acent, descent and height. I could calculate the bounding box by drawing each char to a separete surface, but I guess it couldbe done more easy.

Hope someone can rephrase the above to understandable english... ;)

Thanks

Share this post


Link to post
Share on other sites
I want to reiterate that a good font renderer is an EXTREMELY complicated task. So complicated in fact that even amoung current in use libraries very few of them are actually good enough to compete with the best of them. In fact, one of the main advances in KDE / Gnome over the last few years has been finally getting decent font / type support. The went for YEARS with terrible text rendering. I would estimate a pretty good font rendering system at more than 6 man-months for an absolute savant genious in the field, and more like 10 man years of work for the average development team (this is a case where single-minded passion and vision can outperform sheer force of numbers - like in art). Either way the math and complexity are very high.

Now, a minimal, barely usefull font renderer, for learning purposes, should be doable in about a week or two, depending on what features you want.

But yes, you will need all that crazy stuff you are mentining.

This is the reason that nearly ALL games written in the mid 1990s used simply bitmapped fonts where the only coding distinct per letter was width ... and occasionally some special hard-coded character pair kernings added when testing revealed the text was just too ugly.

The general case is at least 10 times more complicated than any single specific case.

Share this post


Link to post
Share on other sites
Tanks for your time... :)

I figure that I havn't been that clear.

I'm not actually trying to build a font renderer in the sense of RENDER each char (I use Graphics.DrawString for that).
What I want is to create a texture containing all chars in a font. Then I will use that texture together with some font data within my game in order to draw text.

However, if I want any given font to look nice I need to get at least some of that "crazy stuff". Or more exact, with some work from my part I only need the "pivot point" of each char.

The problem can be shaken down to: I want to draw astring char by char and with a nice/correct spacing between the chars.

Kindof example:
I want: "Hello world..."
I don't want: "H e ll o w o r l d. . . "

Thanks

Share this post


Link to post
Share on other sites
There doesn't seem to be a proper way to determine the exact pixel boundaries of a Font using System.Drawing.Font and related classes. But there are at least two solutions out there you can use to check out how other people did it:

--

As far as I can tell, whoever wrote the XNA Font Sample on the XNA site just accepted that fact and used a for loop to scan each character for empty pixels to find the smallest bounding box. He then simple saves the position of the top left corner of the bounding box discovered this way as a "hot spot" and offsets the bitmaps by this "hot spot" when the characters are rendered to the screen.

The source code is here (look in the content pipeline project, the code that arranges the character bitmaps on the texture is in there):
http://creators.xna.com/Headlines/developmentaspx/archive/2007/02/13/Font-Sample.aspx

--

My own solution was to ignore System.Drawing and just use the FreeType library instead. FreeType provides you with everything you need, including character widths and kerning informations.

The source code for my solution can be downloaded here (again, look in the content pipeline importer - it's a C++/CLI project for bridging FreeType (C) and XNA (.NET / C#)):
http://www.nuclex.org/project/fonts

-Markus-

Share this post


Link to post
Share on other sites

This topic is 3861 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this