如何从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
相关产品推荐
相关产品推荐

