Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Font size discrepancy in .NET GDI+?

I am wracking my brains in trying to understand the discrepancy between the font sizes users select or specify (for example, using a FontDialog) and the em-size reported by the Font class in .NET.

For example:

using (FontDialog dlg = new FontDialog()) {
    if (dlg.ShowDialog() == DialogResult.OK) {
        Console.WriteLine("Selected font size: " + dlg.Font.SizeInPoints.ToString("0.##"));
    }
}

Using the above code, you will get some confusing results:

Selecting 11 in the dialog produces 11.25

Selecting 12 in the dialog produces 12

Selecting 14 in the dialog produces 14.25

Selecting 16 in the dialog produces 15.75

This behaviour occurs regardless of the font you choose. As you can see from above, there is no pattern in the discrepancy, it seems to vary randomly between +0.25 and -0.25.

I get around this in user interfaces by only ever displaying the font size as a rounded whole number, but I swear that I have seen word processing/DTP packages that allow users to select fractional font sizes - and these packages do not show the above behaviour when interacting with Windows font dialog boxes.

Can anyone provide a rational explanation for this? Is there a best practice technique for displaying the font size in a UI? How about when the user wants a fractional size such as '10.5'?

like image 792
Bradley Smith Avatar asked Aug 23 '10 05:08

Bradley Smith


2 Answers

Consider these tidbits:

  • An inch, as a result of however these things are decided in history, contains 72 points.
  • Usually people are running Windows at a logical resolution of 96 dots per inch.
  • Hmm, OK, we've got points, inches, and dots--three units to deal with here.
  • GDI wants to know how many dots to draw, and the user is selecting points.
  • Finally, the ratio of 72 points per inch / 96 dots per inch = 0.75 points per dot.

That 0.75 is unfortunate! It means that if we allow the user to choose points straight up, then the ideal rendering would draw on just part of a logical dot. It'd be nice if we could snap the entire rendering up or down to the nearest whole logical dot.

Ready? Here we go!


  • 11:
    • 11 points / 72 points per inch = 0.153 inches * 96 dots per inch = 14.667 dots, BARF!
    • Let's round up to 15 dots,
    • SO then 15 dots / 96 dots per inch * 72 points per inch = 11.25 points.

  • 12:
    • 12 / 72 * 96 = 16 dots.
    • I can live with that, no fudging necessary.

  • 16:
    • 16 / 72 * 96 = 21.3333, BARF!
    • Let's round down to 21 dots / 96 * 72 = 15.75, much nicer.

You get the idea.

Remember that these numbers will change if the user changes their logical resolution (96 dpi, 120 dpi, etc.)

like image 85
Nicholas Piasecki Avatar answered Oct 21 '22 17:10

Nicholas Piasecki


there is no pattern in the discrepancy

As you can see, font sizes happen in increments of 0.75.

Edit: You can fine tune sizes if you do not use the font dialog, but the results I suspect will be less pleasing than the 'preferred' sizes.

like image 23
leppie Avatar answered Oct 21 '22 18:10

leppie