Title: Get font size in pixels in C#
One oddity of the Font class is that its Size property returns font size in the units that were used to create the font. The Font class's Unit property tells you the units used to create the font, but if you need the font's size in a particular units (such as pixels) you need to handle several possible cases when converting the font's size.
The example Draw smooth text in a GraphicsPath in C# uses the following code to avoid having to convert the font's size.
// Use a big font.
private void Form1_Load(object sender, EventArgs e)
{
this.AutoScaleMode = AutoScaleMode.None;
this.Font = new Font("Times New Roman", 30,
FontStyle.Bold, GraphicsUnit.Pixel);
}
This code uses pixels to define the form's font. Later the program uses the following code to add a string to a GraphicsPath object.
path.AddString("DrawPath Normal", this.Font.FontFamily,
(int)this.Font.Style, this.Font.Size, new Point(10, y),
string_format);
The AddString method defines the font's size in pixels. Because the form's Load event handler defined the font's size in pixels, this code can use this.Font.Size for the sized passed to the AddString method.
This example uses a different technique. Instead of creating the font using the unit pixels, it uses the Font object's SizeInPoints property to get the font's size in points and then converts those to pixels.
// Draw text samples.
private void Form1_Paint(object sender, PaintEventArgs e)
{
const string txt = "Sample Text";
int y = 10;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
e.Graphics.DrawString(txt, this.Font, Brushes.Green, 10, y);
y += this.Font.Height;
using (StringFormat string_format = new StringFormat())
{
string_format.Alignment = StringAlignment.Near;
string_format.LineAlignment = StringAlignment.Near;
// Get the form's font size in pixels no matter
// what unit was used to create the font.
float size_in_pixels =
this.Font.SizeInPoints / 72 * e.Graphics.DpiX;
using (GraphicsPath path = new GraphicsPath())
{
path.AddString(txt, this.Font.FontFamily,
(int)this.Font.Style, size_in_pixels, new Point(10, y),
string_format);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(Brushes.Green, path);
}
}
}
The key line of code above is highlighted in blue. By definition a printer's point is 1/72nd of an inch. The code gets the font's size in points and divides by 72 to get inches. It then multiplies by the screen's resolution in dots (pixels) per inch to get the size in pixels. It uses that size to add the string to the GraphicsPath object.
The results given by the Graphics object's DrawString method and the GraphicsPath object are almost exactly alike. In this example the DrawString method uses the TextRenderingHint value AntiAlias. If you use AntiAliasGridFit, you get slightly better kerning (inter-character spacing) so that gives a nicer result, but then a string's width doesn't match the result given by the GraphicsPath object as well.
Download the example to experiment with it and to see additional details.
|