WPF:如何从 Fonts.SystemFontFamilies 中过滤掉非罗马字体?
我知道如何使用几行 XAML 创建 WPF 字体选择器,绑定到 Fonts.SystemFontFamilies
(感谢 Norris Cheng 的出色博文),但我不知道如何过滤掉所有国际和其他非罗马字母字体系列。我的用户不太可能需要“Mongolian Baiti”、“Microsoft Uighur”,甚至“Webdings”,当这些字体出现在列表中时,他们就更难找到他们使用的字体想。
从 SystemFontFamilies
可以访问的对象上是否有任何属性可以用来将非符号罗马字母字体系列与其他字体系列分开?
编辑:我想使用的信息可在 Windows 7 字体控制面板的“设计用途”字段中找到。该字段中的字符串包含“Latin”(表示对拉丁字母应用程序有用的字体)、“国际”字体的其他语言名称(例如,“Mongolian Baiti”是“Mongolian”)以及“Symbol”(表示 Wingdings 等字体)。 “类别”字段对于区分“显示”字体和“文本”字体也很有用。不幸的是,我无法找出从代码中获取此信息的任何方法,我什至无法弄清楚它在 OpenType 规范。我的猜测是 OpenType 脚本标签 或 语言标签。
I know how to create a WPF font picker with a few lines of XAML, binding to Fonts.SystemFontFamilies
(thanks to Norris Cheng's excellent blog post), but I can't figure out how to filter out all the international and other non-Roman-alphabet font families. My users aren't likely to need "Mongolian Baiti", "Microsoft Uighur", or even "Webdings", and when those are in the list it makes it harder for them to find the fonts they do want.
Are there any properties on the objects reachable from SystemFontFamilies
that I can use to separate the non-symbol Roman-alphabet font families from the rest?
EDIT: The information I would like to use is available in the Windows 7 Fonts control panel, in the "Designed for" field. This strings in this field contain "Latin" for fonts useful for Latin-alphabet applications, other language names for "international" fonts ('Mongolian Baiti' is 'Mongolian', for example), and "Symbol" for fonts like Wingdings. The "Category" field also looks useful for separating 'display' fonts from 'text' fonts. Unfortunately, I can't figure out any way to get this information from code, and I can't even figure out where it is in the OpenType spec. My guess is that the OpenType script tags or language tags are involved.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
字体中没有明确的信息来明确定义它是否可读为“罗马”。
您可以借助字形分析来查看字体涵盖的 Unicode 范围。这可以让您了解字体涵盖哪些语言。然而,这也有问题,例如:
字形分析也许可以用来缩小范围,但你可能会得到误报。
更新
我必须在自己的应用程序中处理字体列表,所以不能不管这个! :)
实际上可以通过 GlyphTypeface.Symbol 属性(这对我来说是新的)。因此,通过这个和一些字形分析,以下解决方案应该可以解决问题。
然而,它仍然会找到“Mongolian Baiti”(它是“Baiti”而不是咖喱风格中的“Balti”:)),因为它有拉丁字符的字形,所以它仍然是“罗马”字体,具体取决于您如何定义它。事实上,我的系统上的所有非符号字体都至少具有拉丁字符范围,因此拉丁字形测试实际上并不排除任何字体。
您对“蒙古白提”的具体反对意见是什么?您希望如何自动排除它(例如,不使用手动维护的排除列表)?
更新 2
您可以尝试根据字体对扩展拉丁字符的支持来过滤字体,方法是包含
Latin Extended-A
和Latin Extended-B< 的过滤器/code> 范围。使用
Latin Extended-A
和Latin Extended-B
进行过滤会留下很少的字体,但仅对Latin Extended-A
进行过滤仍然会留下相当多的字体很多字体。它还会自动删除Mongolian Baiti
,因为它仅支持Latin-1
和Latin-1 Supplement
。这种分析是否能给出理想的结果是非常主观的。需要尝试的东西:
同样,非常主观,但以下将提供支持拉丁字形以及国际货币字符子集的字体:
更新 3
除了您的问题编辑之外,还有一个版本将与 Windows 7 一起使用。它利用 Window 7 的隐藏字体功能(如 @Rick Sladkey 所指出的),该功能默认隐藏那些被认为对当前用户的区域设置无用的字体。它还将排除符号字体:
There is no explicit information in a font that defines unambiguously whether it is readable as "Roman" or not.
You could resort to glyph analysis to see what Unicode ranges a font covered. This could give you a clue as to what languages a font covered. However, this has problems too, e.g.:
Glyph analysis could be applied to narrow things down perhaps, but you could get false positives.
Update
I have to deal with font lists in my own application, so couldn't leave this one alone! :)
It is actually possible to derive whether a font is a symbol font via the GlyphTypeface.Symbol property (which is new to me). Therefore with this and a bit of glyph analysis, the following solution should do the trick.
It will however still find "Mongolian Baiti" (and it's "Baiti" not "Balti" as in the curry style :)) as this has glyphs for Latin characters so it still is a "Roman" font depending on how you define this. As a matter of fact all non-Symbol fonts on my system have at least the Latin character range, so the Latin glyph test doesn't actually exclude any fonts.
What is your particular objection to "Mongolian Baiti", and how do you expect to automatically exclude it (without using a manually maintained exclusion list for example)?
Update 2
You could experiment with filtering out fonts based on what support they have for extended Latin characters by including filters for
Latin Extended-A
andLatin Extended-B
ranges. Filtering with bothLatin Extended-A
andLatin Extended-B
leaves very few fonts left, but just filtering onLatin Extended-A
still leaves quite a lot of fonts. It also automatically removesMongolian Baiti
as this only has support forLatin-1
andLatin-1 Supplement
.Whether this sort of analysis gives desirable results is highly subjective. Something to experiment with though:
Again, highly subjective, but the following will give fonts that support Latin glyphs plus a sub-set of international currency characters:
Update 3
Further to your question edit here is a version that will work with Windows 7. It leverages Window 7's hidden font feature (as pointed out by @Rick Sladkey) which by default hides fonts that are not considered to be useful for the current user's locale setting. It will also exclude symbol fonts:
我认为如果您不亲自提供的话,您永远不会找到此类信息。字体规范本身不提供此信息,所以我想这意味着您不走运。您最好的选择是确定您认为最终用户“可接受”的字体列表。
I don't think that you are ever going to find that type of information without providing it yourself. Font specifications themselves don't provide this information, so I guess this means you are out of luck. Your best bet is to determine a list of fonts that you deem 'acceptable' for your end users.
我找不到一种简单可靠的方法来做到这一点。我认为最好的解决方案是遵循 Windows 7 提供的字体隐藏状态。这样用户可以隐藏/显示他们认为合适的字体,但也可以隐藏所有不适合其所在地区的字体。不幸的是,没有记录的 API 可以查明字体是否隐藏,但您可以使用注册表设置。
这里有一篇文章解释了如何做到这一点:
I could not find an easy reliable way to do this. I think the best solution is to honor the hidden state of fonts as provided by Windows 7. This way users can hide/show fonts as they see fit but also hide all fonts inappropriate for their region. Unfortunately there is no documented API to find out if a font is hidden or not but you can use a registry setting.
Here is an article that explains how to do it: