检查FontFamily是否为TrueType

时间:2015-09-11 17:08:44

标签: c# fonts c++-cli true-type-fonts

是否可以使用C#,C ++ / CLI或P /调用WinAPI来确定某个字体系列是TrueType字体?

最后我想得到一些像这样的结果

bool result1 = CheckIfIsTrueType(new FontFamily("Consolas")); //returns true
bool result2 = CheckIfIsTrueType(new FontFamily("Arial")); // returns true
bool result3 = CheckIfIsTrueType(new FontFamily("PseudoSaudi")); // returns false
bool result4 = CheckIfIsTrueType(new FontFamily("Ubuntu")); // returns true
bool result5 = CheckIfIsTrueType(new FontFamily("Purista")); // returns false

当然结果取决于目标操作系统及其字体......

2 个答案:

答案 0 :(得分:2)

它有处理异常的开销,但如果提供的字体不是TrueType,则FontFamily constructor会抛出ArgumentException

public bool CheckIfIsTrueType(string font)
{
    try
    {
        var ff = new FontFamily(font)
    }
    catch(ArgumentException ae)
    {
        // this is also thrown if a font is not found
        if(ae.Message.Contains("TrueType"))
            return false;        

        throw;
    }
    return true;
}

深入研究FontFamily构造函数,它调用外部GDIPlus函数GdipCreateFontFamilyFromName

[DllImport("Gdiplus", SetLastError=true, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Unicode)] // 3 = Unicode
internal static extern int GdipCreateFontFamilyFromName(string name, HandleRef fontCollection, out IntPtr FontFamily);

如果字体不是真正的字体,则返回16的代码。因此,您可以绕过异常的开销:

public bool CheckIfIsTrueType(string name)
{
    IntPtr fontfamily = IntPtr.Zero;
    IntPtr nativeFontCollection = IntPtr.Zero ;

    int status = GdipCreateFontFamilyFromName(name, new HandleRef(null, nativeFontCollection), out fontfamily);

    if(status != 0)
        if(status == 16)  // not true type font)
            return false;
        else
            throw new ArgumentException("GDI Error occurred creating Font");

    return true;
}

显然你可能想要为代码使用一个常量枚举,可以找到here,并抛出更好的异常

答案 1 :(得分:1)

如果目标操作系统是Windows 10,则执行D Stanley的C#示例代码不会出现异常。仅Windows 7会抛出该异常。Windows8和Windows 10上的GDI +支持带有Adobe CFF轮廓的OTF字体。请参阅此链接底部的表-> https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-creating-a-private-font-collection-use