juanferrer
juanferrer

Reputation: 1250

Is is possible to determine the character set of a Font?

I am printing the name of every font installed using the font, except when that font would render the name unreadable (i.e. symbols), where I use the default font (Segoe UI).

Now, I'm trying the following and found something that I can't understand:

var installedFonts = new System.Drawing.Text.InstalledFontCollection().Families;

foreach (var family in installedFonts)
{
    var font = new Font(family, 12);
    if (font.GdiCharSet == 2) // Symbols font
    {
        // Print using default font
    }
    else // Readable font
    {
        // Print using font
    }
}

It never prints using the default font. Furthermore, every font's GdiCharSet returns 1, even when the font is using a different character set. Reading a bit more thoroughly, it says:

This property returns 1, unless a different character set is specified in the Font(String, Single, FontStyle, GraphicsUnit, Byte) constructor.

So, apparently I am not creating the font correctly, because I don't specify a Byte value (I'm using a different constructor altogether). This makes me think there is another way (the "actual" way) to know the CharSet value of a font. But I can't find it anywhere. Does anyone know how I can find out this?


As a side note, Notepad manages to do it. Format > Font... opens the font selector. You can see that it displays the character set used under Script.

enter image description here

Upvotes: 2

Views: 2363

Answers (1)

Tommaso Belluzzo
Tommaso Belluzzo

Reputation: 23675

You should use the GetTextMetrics function (https://msdn.microsoft.com/en-us/library/windows/desktop/dd144941(v=vs.85).aspx). When called using interop, it retrieves the following structure:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
internal struct TEXTMETRIC
{
   public int tmHeight;
   public int tmAscent;
   public int tmDescent;
   public int tmInternalLeading;
   public int tmExternalLeading;
   public int tmAveCharWidth;
   public int tmMaxCharWidth;
   public int tmWeight;
   public int tmOverhang;
   public int tmDigitizedAspectX;
   public int tmDigitizedAspectY;
   public char tmFirstChar;
   public char tmLastChar;
   public char tmDefaultChar;
   public char tmBreakChar;
   public byte tmItalic;
   public byte tmUnderlined;
   public byte tmStruckOut;
   public byte tmPitchAndFamily;
   public byte tmCharSet;
}

The last member of the struct, tmCharSet, is what you are looking for:

The character set of the font. The character set can be one of the following values: ANSI_CHARSET BALTIC_CHARSET CHINESEBIG5_CHARSET DEFAULT_CHARSET EASTEUROPE_CHARSET GB2312_CHARSET GREEK_CHARSET HANGUL_CHARSET MAC_CHARSET OEM_CHARSET RUSSIAN_CHARSET SHIFTJIS_CHARSET SYMBOL_CHARSET TURKISH_CHARSET VIETNAMESE_CHARSET ...

Following this link, you can find a simple implementation of the necessary code.

Upvotes: 2

Related Questions