How can I force a winforms app to use the fonts/fontsizes I specify on every machine? I have a c# app where the font seem to change in size on a different machine, and it's not a resolution thig. This is on windows 7 with a c# app. Is there a way to force the font size I want or do the user os fonts always overrule?
views:
46answers:
2You cannot do more than specify the font size you prefer. If the user chooses to use great font sizes (125% / 150%) or the magnifier, your font size will increase.
Font sizes are specified in points. One point is 1/72 inches. The problem is that this needs to jive with the rest of Windows Forms where almost anything is specified in pixels. The issue is how many pixels make a point. That depends on your video adapter's dots-per-inch setting.
The traditional setting is 96 dots per inch. So if you ask for a 9 point font, you'll get one that's 9 / 72 * 96 = 12 pixels high. As long as the client area of a control is at least 12 pixels high, the text displayed inside of it won't be clipped.
The video adapter's DPI setting can be changed however. They made it kinda difficult in XP, you had to go into the Display applet's Advanced setting to do so. It got a lot easier in Vista, there's a direct link to it with a nice ruler and whatnot.
The next common setting is 120 DPI, 125% more dots per inch. That 9 point font now needs 9 / 72 * 120 = 15 pixels. If the original control that displays that text is still at 12 pixels, the text is going to get clipped. Basically, the descenders are sheared off.
So to fix that, the Control.Size property of the controls in the form need to change. They need to be scaled to accommodate the larger DPI setting. Windows Forms readily supports that. It is the Form.AutoScaleMode, available since .NET 2.0. When you set it to something else than None then automatic code inside Windows Forms kicks in that compensates for the difference between the machine that designed the form and the machine that displays the form. In the 120 DPI case, it will make the form and the controls bigger. So that they can display text without it getting clipped.
But, there's a complication. Changing the DPI setting is great for fonts. TrueType is awesome technology, capable of rendering good looking type at any size. But rescaling doesn't work very well for images that contain line art. They get stray extra pixels or get fuzzy when you rescale them.
Back to fonts: clearly if you change the DPI setting of the monitor, the user would expect the fonts to follow suit. That certainly worked that way back in the XP days. If you change the video adapter's DPI setting, you get a prompt to reboot the operating system. That was important back then because there were lots of program that used device fonts, not TrueType fonts. Non-scalable fonts. New fonts got activated that match the DPI setting. A larger value for video DPI is thus matched with a larger system base font size.
Around the same time, some kind of genius at Microsoft, since assassinated, came up with a Really Good Idea. People that live in East Asia have a writing system based on characters. Intricate glyphs that need lots of pixels to show the details. 12 pixels at 96 DPI does not leave a lot of room to make a good looking Chinese or Korean glyph. Increasing the DPI obviously improves that, but at the cost of having fuzzy images. The Idea: increase the system base font size but don't change the video DPI.
Now there's a new problem however: how to auto-scale the UI. You can see this back in the values you can assign to the AutoScaleMode property, either Font or DPI. Which one is correct for the target machine is not easily guessable. Font is normally the better choice since you want to make sure that text isn't clipped. However, if you want to make sure that images display at the right size, then you want DPI. When you want both then you are stuck between a rock and a hard place, one you can't get out of unless the system base font size matches the video DPI setting.