You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从System.Windows.Media.FontFamily获取Panose字体族类型?

获取System.Windows.Media.FontFamily的Panose字体族类型的优化方案

我需要通过Panose字体族类型筛选字体,目前使用GDI32的GetOutlineTextMetricsA方法来获取该类型,调用代码如下:

[System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
private static extern int GetOutlineTextMetricsA(IntPtr hdc, int cbData, IntPtr lpOtm);

我的起始对象是来自System.Windows.Media.Fonts.SystemFontFamilies的System.Windows.Media.FontFamily,但找不到直接获取其hDC的方法,只能通过对比Media.FontFamily.Source与Drawing.FontFamily.Name,将其映射到System.Drawing.FontFamily.Families中的对应对象。这种名称匹配的方式并不完美,仅能匹配约90%的字体。

获取到Drawing.FontFamily后,我会将其转换为Drawing.Font,再通过以下代码获取Panose字体族类型:

遍历Media字体集合的代码:

foreach (Media.FontFamily font in Media.Fonts.SystemFontFamilies.OrderBy(_ => _.Source))

遍历Drawing字体集合的代码:

System.Collections.IEnumerator fontIter = Draw.FontFamily.Families.OrderBy(_ => _.Name).GetEnumerator();

创建Drawing.Font实例的代码:

Draw.Font drawFont = new Draw.Font(drawFamily, 9.0F);

获取Panose字体族类型的核心方法:

enum PanoseFontFamilyTypes
{
    PAN_ANY = 0, PAN_NO_FIT = 1, PAN_FAMILY_TEXT_DISPLAY = 2, PAN_FAMILY_SCRIPT = 3,
    PAN_FAMILY_DECORATIVE = 4, PAN_FAMILY_PICTORIAL = 5
}

public PanoseFontFamilyTypes PanoseFontFamilyType(Draw.Font font)
{
    byte bFamilyType = 0;
    IntPtr hdc = (IntPtr)0;
    IntPtr hFontOld;

    try
    {
        hdc = GraphTool.GetHdc();
        hFontOld = SelectObject(hdc, font.ToHfont());
        int bufSize = GetOutlineTextMetricsA(hdc, 0, (IntPtr)0);
        IntPtr lpOtm = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(bufSize);
        System.Runtime.InteropServices.Marshal.WriteInt32(lpOtm, bufSize);
        int success = GetOutlineTextMetricsA(hdc, bufSize, lpOtm);
        if (success != 0)
        {
            int offset = 61;
            bFamilyType = System.Runtime.InteropServices.Marshal.ReadByte(lpOtm, offset);
        }

        System.Runtime.InteropServices.Marshal.FreeCoTaskMem(lpOtm);

        SelectObject(hdc, hFontOld);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Message: {ex.Message}\r\nStackTrace:\r\n{ex.StackTrace}", "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    finally
    {
        GraphTool.ReleaseHdc(hdc);
    }

    return (PanoseFontFamilyTypes)bFamilyType;
}

现寻求更简洁的解决方案,优先级如下:

理想方案

  • 直接从System.Windows.Media.FontFamily获取hDC
  • 无需导入GDI方法,直接获取OUTLINETEXTMETRICS结构体
  • 完全不依赖System.Drawing.FontFamily及GDI导入方法,直接获取Panose字体族类型

退而求其次的方案

找到比名称匹配更可靠的System.Windows.Media.FontFamily与System.Drawing.FontFamily映射方式

内容的提问来源于stack exchange,提问作者Nottoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:55:31