.Net枚举winforms字体样式?
我一直在寻找一种使用 .Net 框架列出给定字体的有效字体样式的方法(即使我必须 pinvoke gdi32 或其他一些 API),因为并非所有字体都属于 System.Drawing.FontStyle 枚举值(粗体、斜体、常规、删除线、下划线)。不符合要求的字体的一个完美示例是 Segoe UI,它是 TrueType Microsoft 字体,字体样式为:Regular、Semibold、Light、Bold、Italic 和 BoldItalic。另一个例子是 Arial,它有:常规、窄体、斜体、粗体、粗斜体、窄粗体、窄粗斜体和窄斜体。
在 Windows 7 中(也可能是 Vista,但我没有机器可以检查),当您打开资源管理器并浏览到 %SystemRoot%\Fonts 时,您将看到一个名为“字体样式”的列,其中列出了所有可用的样式对于每种字体,这告诉我肯定有一种方法可以做到这一点,至少通过 API 调用。
最终,我希望枚举 FontFamily 列表,然后列出每个系列的每种字体样式。下面是列出所有字体系列的示例代码,如果有人可以提供帮助列出每个系列可用的字体样式,我将不胜感激。如果我的做法是错误的,我绝对愿意接受建议。
Drawing.Text.InstalledFontCollection ifc = new Drawing.Text.InstalledFontCollection();
foreach ( FontFamily ff in ifc.Families )
{
Console.WriteLine(ff.ToString());
// Something like this would be nice, but AFAIK nothing similar exists
/*
foreach ( FontStyle style in ff.Styles )
Console.WriteLine(style.ToString());
*/
}
I have been searching around for a way to list the valid font styles for a given font using the .Net framework (even if I have to pinvoke gdi32 or some other API) since not all fonts fall into the System.Drawing.FontStyle enum values (Bold, Italic, Regular, Strikeout, Underline). A perfect example of a font that does not fit the bill is Segoe UI, which is a TrueType Microsoft font, with font styles of: Regular, Semibold, Light, Bold, Italic, and BoldItalic. Another example is Arial which has: Regular, Narrow, Italic, Bold, Bold Italic, Narrow Bold, Narrow Bold Italic, and Narrow Italic.
In Windows 7 (probably vista as well, but I don't have a machine to check) when you open explorer and browse to %SystemRoot%\Fonts you will see a column called "Font style" which lists out all of the available styles for each font, which tells me that there is definitely a way to do this, at the very least through API calls.
Ultimately, I am looking to enumerate the FontFamily list, and then list out every font style for each family. Below is sample code for listing out all of the font families, if anyone could provide assistance for listing the font styles available for each family, I would appreciate it. If I am going about this the wrong way, I am definitely open to suggestions.
Drawing.Text.InstalledFontCollection ifc = new Drawing.Text.InstalledFontCollection();
foreach ( FontFamily ff in ifc.Families )
{
Console.WriteLine(ff.ToString());
// Something like this would be nice, but AFAIK nothing similar exists
/*
foreach ( FontStyle style in ff.Styles )
Console.WriteLine(style.ToString());
*/
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好的,下面将有很多代码。主要是因为 TTF 结构和 TTF 文件的 Endianess。该代码最初不是我的,它来自一些来源,我已将其移植到 VB.NET 并更改了一些内容。有关获取字体名称的 C++ 版本,请参阅此页面。
此代码读取已安装字体的注册表(无论是在 %windir%\fonts 还是其他地方),过滤以仅获取具有 .ttf 扩展名的字体(例如 .fon 和 .ttc 被忽略),然后将这些字体文件路径传递给一个例程,
GetFontDetails
,读取并获取字体名称 (uNameID #1) 和字体子系列(又名样式,uNameID #2)。如果您有兴趣获得更多属性,请转到名称 - 命名表 在 Microsoft 的 Typography 网站上,然后在浏览器中搜索名称 ID。然后它将字体名称、字体子系列和字体路径踢出到控制台窗口。创建一个新的 VB.NET 控制台应用程序并将以下内容粘贴到 Module1 代码中,然后按 F5。
话不多说:
Okay, this is going to be a lot of code below. Primarily, it is because of the TTF structures and Endianess of TTF files. The code is not originally mine, it's come from a few sources that I've ported to VB.NET and changed a few things around. See this page for a C++ version that gets the font name.
This code reads through the registry for installed fonts (whether in %windir%\fonts or elsewhere), filters to only get ones with the .ttf extension (e.g. .fon and .ttc are ignored) and then it passes these font file paths to a routine,
GetFontDetails
, that reads through and gets the Font Name (uNameID #1) and Font Sub Family (aka Style, uNameID #2). If you are interested in getting more properties than those, go to name - Naming Table on Microsoft's Typography website and search in your browser for Name IDs. It then kicks out the Font Name, Font SubFamily and Font Path to the Console window.Create a new VB.NET Console app and paste the below in over Module1 code and press F5.
Without further ado:
谢谢御宅族和大家...
为任何感兴趣的人获取 Otaku 的代码并将其移植到 c#...但没有获得 OTF 更新。主要变化只是字节数组调整(VB pads 数组)、lambda 表达式和通常的语法更改...
HTH
戴夫
Thanks Otaku and All...
Took Otaku's code and ported to c# for any one that is interested...but didn't get to the OTF update. Main changes were just byte array adjustments (VB pads arrays), lambda expressions and the usual syntax changes...
HTH
Dave
我发现自己和这里的每个人都处于同一条船上。我们都想要神奇的原生字体对话框分组行为,但没有 API 来支持它!
不幸的是,当前的答案做了与 GDI+ 和 System.Drawing 相同的事情:将
Segoe UI Semibold
或Arial Black
隔离到它们自己的单字体系列中,并失去与Segoe UI
和Arial
。我想这使它成为 Arial 家族的害群之马......我启动了一个开源项目来解决这个问题和 OTF/TTC 解析并提供一个很好的 API。它可以处理我扔给它的所有极端情况。请随意复制或修改代码。你
的代码示例变成:
如果你真的是这样感兴趣的是将样式应用于现有字体对象:
您也不限于已安装的字体。要从字体文件中解析字体,请使用
TypgraphicFont.FromFile
。感谢 Todd Main 的开拓。
I found myself in the same boat as everyone here. We all want that magical native font dialog grouping behaviour, and there are no APIs to support it!
Unfortunately the current answer did the same thing that GDI+ and System.Drawing do: isolate
Segoe UI Semibold
orArial Black
into single-font families of their own and lose the connection withSegoe UI
andArial
. I guess that makes it the Black sheep of the Arial family...I started an open source project to resolve this and the OTF/TTC parsing and to provide a nice API. It handles all the corner cases I threw at it. Feel free to copy or modify the code. https://github.com/jnm2/TypographicFonts
Your code example becomes:
If what you're really interested in is applying a style to an existing font object:
You aren't restricted to installed fonts, either. To parse fonts from a font file, use
TypographicFont.FromFile
.Thanks to Todd Main for pioneering.
如何使用 FontFamily.IsStyleAvailable 来检查每个字体系列的字体样式是否可用。您可以检查感兴趣的字体样式(如果可用),然后列出支持的样式。
How about using FontFamily.IsStyleAvailable to check if the font style is available or not for each font family. You can check in interested font styles (if available) and then list supported styles.
Dave,注释掉这个版本检查:
对我有用,我现在也可以获得 .otf 字体名称...
还添加了几个 ToLower(s)
我安装的一些字体全部大写,导致 == 子句找到由于 ttf == TTF 比较,什么也没有。
希望它对任何人都有帮助!
Dave, commenting out this version check:
did the trick for me, i can get .otf font names too now...
Also added a couple of ToLower(s)
Some of my installed fonts where all in caps causing the == clause finds nothing because of the ttf == TTF comparison.
Hope it helps anyone!