adigostin
adigostin

Reputation: 638

How to create a font with precise character height in Windows Forms?

In my program I need to generate a bitmap with all digit characters (0..9) laid from left to right, plus a few other characters.

The user will select from the UI:

  1. the desired font, and
  2. the desired character height in pixels.

So I want to create a Bitmap, then a Graphics from this bitmap, then draw the digits one by one to this bitmap, and then save it to disk.

What I couldn't figure out in hours: How do I create a font with the correct size so that the digit '0' has the height given by the user?

I played with all the parameters in the Font constructor, with properties of StringFormat, with MeasureString/MeasureText/MeasureCharacterRanges, I tried creating the font with the native CreateFont() via P/Invoke (with positive/negative nHeight). All parameters called "size" or "height" seem to indicate the size of some hypothetical character that's much larger than '0'.

I did read the theory with line height, em height, ascent, descent etc. There seem to be no notion for the real height of a character, without padding and spacing and so on

Again my question: Given the font name and the desired pixel height for the '0' glyph, how can I create a font which draws that glyph with the required height?

I would appreciate any guidance.

LATER EDIT Some more details about my project: It's an embedded device with a big display, and I need to provide an easy way for the designers to to generate and try out bitmap fonts of their liking. A Windows tool that generates such bitmap fonts seemed like a good solution to me.

Upvotes: 2

Views: 2366

Answers (2)

someone3x7
someone3x7

Reputation: 11

While I wasn't far off the mark with what I posted here earlier, it didn't actually work. In banging my head against this I found it interesting to note that graphics.MeasureString("M", ...) reports a height far larger than graphics.MeasureString("MM", ...). In calculating the font sizes by hand I've found the first(which correlates with GetEMSize's response) is actually the full line size. In the end I came to realize the actual character sizes of the digits aren't required to correlate to any of the metrics, whether real or .net.

Upvotes: 1

pstrjds
pstrjds

Reputation: 17428

I believe you could use this Font Constructor to specify the GraphicsUnit to be pixels. Then it should create the font with the appropriate size.

Adding test code - edit accordingly for your case and don't judge for style, I just wanted something I could paste in LINQPad and would produce an image.

using (var font = new Font("Arial",10,FontStyle.Regular, GraphicsUnit.Pixel))
using (var image = new Bitmap(30, 15))
using (var graphics = Graphics.FromImage(image))
{
    graphics.FillRectangle(Brushes.White, new Rectangle(0, 0, 30, 15));
    graphics.DrawString("Ay", font, Brushes.Black, 0, 0);
    image.Save(@"E:\test.bmp", ImageFormat.Bmp);
}

Remember when setting size by Pixels that all characters in the Font need to fit in that range, meaning letters with a descender and letters with an ascender.

Upvotes: 0

Related Questions