How do I get all installed fixed-width fonts?

10,114

Solution 1

Have a look at:

http://www.pinvoke.net/default.aspx/Structures/LOGFONT.html

Use one of the structures in there, then loop over families, instantiating a Font, and getting the LogFont value and checking lfPitchAndFamily.

The following code is written on the fly and untested, but something like the following should work:

foreach (FontFamily ff in System.Drawing.FontFamily.Families)
{
    if (ff.IsStyleAvailable(FontStyle.Regular))
    {
        Font font = new Font(ff, 10);
        LOGFONT lf = new LOGFONT();
        font.ToLogFont(lf);
        if (lf.lfPitchAndFamily ^ 1)
        {
            do stuff here......
        }
    }
}

Solution 2

Unfortunately ToLogFont function does not fill lfPitchAndFamily field to correct values. In my case it's always 0.

One approximation to detect which fonts might be fixed is the following

    foreach ( FontFamily ff in FontFamily.Families ) {
            if ( ff.IsStyleAvailable( FontStyle.Regular ) ) {
                float diff;
                using ( Font font = new Font( ff, 16 ) ) {
                    diff = TextRenderer.MeasureText( "WWW", font ).Width - TextRenderer.MeasureText( "...", font ).Width;
                }
                if ( Math.Abs( diff ) < float.Epsilon * 2 ) {
                    Debug.WriteLine( ff.ToString() );
                }
            }

        }

Keep in mind that they are several false positives, for example Wingdings

Solution 3

AFAIK you can't do it using BCL libraries only. You have to use WinAPI interop.

You need to analyze 2 lowest bits of LOGFONT.lfPitchAndFamily member. There is a constant FIXED_PITCH (means that font is fixed-width) that can be used as a bit mask for lfPitchAndFamily.

Here is a useful article:

Enumerating Fonts

Enumerating fonts can be a little confusing, and unless you want to enumerate all fonts on your system, can be a little more difficult than MSDN suggests. This article will explain exactly the steps you need to use to find every fixed-width font on your system, and also enumerate every possible size for each individual font.

Share:
10,114
Nidonocu
Author by

Nidonocu

A strange creature that enjoys web and desktop development, not to mention unhealthy amounts of Halo. One of those rare entities that enjoys both code and UI design.

Updated on July 28, 2022

Comments

  • Nidonocu
    Nidonocu almost 2 years

    I'm wondering if there are any simple ways to get a list of all fixed-width (monospaced) fonts installed on a user's system in C#?

    I'm using .net 3.5 so have access to the WPF System.Windows.Media namespace and LINQ to get font information, but I'm not sure what I'm looking for.

    I want to be able to provide a filtered list of monospaced fonts and/or pick out monospaced fonts from a larger list of fonts (as seen in the VS options dialog).