Introduction
Sometimes when I work with fonts, I get some questions which are not as obvious as I would like them to be. Let’s check some of them.
Using the Code
Q: How to identify a monospaced font?
A: It’s not such a simple question as it may seem. You can find the following advice in Google search results: describe
the LOGFONT
class in your project and use
the ToLogFont
method to convert the font to a corresponding object. After that (as legend has it), the first
bit in the IfPitchAndFamily
field
should identify if the font is monospaced. So, this is sh*t! Nowadays the field is always
equal to zero.
Sometimes and somewhere this option worked, but it doesn’t work now. In real life, you have to use a not very pretty, but very efficient solution as:
public static bool IsMonospace(Font font)
{
return Math.Abs(graphics.MeasureString("iii", font).Width -
graphics.MeasureString("WWW", font).Width) < 1e-3;
}
Q: How to define the size of a string when using this font?
A: We will need Graphics
which will be used to draw, and namely its MeasureString
method. Pass the drawn text and used font to it and it gets the string size.
Q: What if I need to get the size of a definite part of a string?
A: You can do it with the Graphics.MeasureCharacterRanges
method.
But at first (and there is a good sample in MSDN), it is necessary to set target intervals of the characters with the StringFormat.SetMeasurableCharacterRanges
method. This method has an amazing limitation, you can’t pass more than 32 intervals to it.
Q: This method gets too big boundaries. They include not only the characters but also some space near it. What to do?
A: Actually the regions that you get contain the symbols in
a way they are listed in the initial font – together with a little space next to it. There is no neat way to get exact boundaries. You will have to
create a picture with the target characters and review it pixel-by-pixel (just don’t use Bitmap.GetPixel
, it’s too time consuming, there are quicker methods) and find extreme characters of the string
.
Q: I created a font by using its string name, got no exceptions. Is there such
a font in the system?
A: Not always. The Font
class constructor tries to get the most closely matching font (to its consideration) for this name. It’s better to check if the correct font was created:
var font = new Font(fontName, 12);
vat isExist = font.Name == fontName;
And it would also be good to check if the font family you use is able to support your FontStyle
:
var fontFamily = new FontFamily(fontName);
isExist &= fontFamily.IsStyleAvailable(fontStyle);