Title: Set font size to fit a label in C#
This program uses the following method to calculate the largest font size that the Label can use while still allowing the sample text to fit.
// Return the largest font size that lets the text fit.
private float GetFontSize(Label label, string text,
int margin, float min_size, float max_size)
{
// Only bother if there's text.
if (text.Length == 0) return min_size;
// See how much room we have, allowing a bit
// for the Label's internal margin.
int wid = label.DisplayRectangle.Width - margin;
int hgt = label.DisplayRectangle.Height - margin;
// Make a Graphics object to measure the text.
using (Graphics gr = label.CreateGraphics())
{
while (max_size - min_size > 0.1f)
{
float pt = (min_size + max_size) / 2f;
using (Font test_font =
new Font(label.Font.FontFamily, pt))
{
// See if this font is too big.
SizeF text_size =
gr.MeasureString(text, test_font);
if ((text_size.Width > wid) ||
(text_size.Height > hgt))
max_size = pt;
else
min_size = pt;
}
}
return min_size;
}
}
If the text is blank, the method simply returns the minimum allowed font size.
The the text is non-blank, the method uses a binary search to find the best font size. It calculates the font size halfway between min_size and max_size and creates a font with that average size.
The method then uses the test font to measure the text. If the text is taller or wider than the Label control's display area, the method decreases max_size to make the program look for a smaller font size. If the text isn't bigger than display area, the code increases min_size to make the program look for a larger font size.
When min_size and max_size are within 0.1 of each other, the program returns min_size.
Note that some fonts adjust character positions slightly so the measured font size isn't exactly the same as the size used by the Label control. That means if you don't include a big enough margin, the text may not quite fit.
Also note that the Label control seems to cheat when the font size is really small (under around 9 point). Then the control seems to use a font different from the one that is used by a Graphics object drawing the same text with the same font. That makes the code fail to correctly measure the text as it would be drawn by the Label. You can avoid that problem if you set min_size no smaller than 9 point.
When the text in the form's TextBox changes or when you resize the sample Label, the program calls the following method to display the sample text.
// Display the sample text as large as possible.
private void ShowSample()
{
string text = txtSample.Text;
if (text.Length == 0) return;
float font_size = GetFontSize(
lblSample, text, 10, 1, 1000);
lblFontSize.Text = font_size.ToString("0.0");
lblSample.Font = new Font(lblSample.Font.FontFamily, font_size);
lblSample.Text = text;
}
This code gets the entered text and then calls GetFontSize. It sets the Label control's font to the returned font size and then displays the sample text.
Download the example to experiment with it and to see additional details.
|