找到呈现代码点的最佳字体

Nop*_*ope 19 fonts unicode

如何找到合适的字体来呈现 unicode 代码点?

gnome-terminal找到像 «?» 这样的字符 可以使用 Symbola 之类的字体呈现,而不是我的终端字体或方格代码点后备 ()。如何 ?

小智 19

使用字体配置,

> fc-list ':charset=<hex_code1> <hex_code2>'
Run Code Online (Sandbox Code Playgroud)

例如

> fc-list ':charset=2713 2717'
Run Code Online (Sandbox Code Playgroud)

将显示任何包含 ? 和 ?。

获取对应于字符使用的代码点(例如)

> printf "%x" \'?
2713>
Run Code Online (Sandbox Code Playgroud)

这将使用有点模糊功能 的的POSIXprintf实用工具

如果前导字符是单引号或双引号,则该值应是单引号或双引号之后字符的底层代码集中的数值。

综合起来,

> printf '%x' \'? | xargs -I{} fc-list ":charset={}"
Run Code Online (Sandbox Code Playgroud)

这使用xargs -I标志来替换{}来自stdin. 所以这实际上归结为:

> fc-list ":charset=2713"
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您需要一个 [`2.11.91`](https://wiki.freedesktop.org/www/Software/fontconfig/Devel/) 或 [稍后](https://bugs.conf) 的 `fontconfig` 版本。 freedesktop.org/show_bug.cgi?id=7597)。 (3认同)
  • 惊人的!我长期以来一直在寻找这方面的信息。请注意,您还可以指定范围以及单个字符,以便查找具有所有方框图字符的所有字体,例如: `fc-list --format='%{postscriptname}\n' ':charset= 2500-257F'` (3认同)

Gil*_*il' 16

这不一定是最好的方法,它肯定不是用户友好的,但它很容易上手:这里有一个 Python 脚本来做到这一点。

安装Python-fontconfig库。从您的发行版(例如sudo apt-get install python-fontconfig在 Debian 和衍生产品上)获取它或将其安装在您的主目录中(pip install --user python-fontconfig)。然后您可以运行此脚本(将其保存fc-search-codepoint在您的 目录中PATH,例如,通常~/bin,并使其可执行):

#!/usr/bin/env python2
import re, sys
import fontconfig
if len(sys.argv) < 1:
    print('''Usage: ''' + sys.argv[0] + '''CHARS [REGEX]
Print the names of available fonts containing the code point(s) CHARS.
If CHARS contains multiple characters, they must all be present.
Alternatively you can use U+xxxx to search for a single character with
code point xxxx (hexadecimal digits).
If REGEX is specified, the font name must match this regular expression.''')
    sys.exit(0)
characters = sys.argv[1]
if characters.startswith('U+'):
    characters = unichr(int(characters[2:], 16))
else:
    characters = characters.decode(sys.stdout.encoding)
regexp = re.compile(sys.argv[2] if len(sys.argv) > 2 else '')

font_names = fontconfig.query()
found = False
for name in font_names:
    if not re.search(regexp, name): continue
    font = fontconfig.FcFont(name)
    if all(font.has_char(c) for c in characters):
        print(name)
        found = True

sys.exit(0 if found else 1)
Run Code Online (Sandbox Code Playgroud)

用法示例:

$ fc-search-codepoint ?
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

我没有所有这些字符的任何字体。

$ fc-search-codepoint U+1F64D
/usr/share/fonts/truetype/unifont/unifont_upper.ttf
/usr/share/fonts/truetype/unifont/unifont_upper_csur.ttf
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常有用的脚本!但是,它仅兼容 python2,我认为完全做到可移植性有点令人讨厌。你介意至少根据 PEP 394 将 `#!/usr/bin/env python` 更改为 `#!/usr/bin/env python2`。 (2认同)

art*_*rtm 2

最终 gnome-terminal 使用fontconfig来(除其他外):

...即使您已经安装了数千种字体,也可以在已安装的字体集中高效快速地找到所需的字体...

API 文档中,您可以找到用于查询字体字符范围和对字符范围进行操作的函数,但该文档是如此神秘,以至于我永远无法弄清楚不同的函数集如何相互关联。如果我需要更深入地研究,我宁愿查看其他软件中的使用示例,也许是vte(gnome-terminal 中使用的终端仿真库)。

vtefontconfig之间的另一个库是pango “...一个用于布局和渲染文本的库,重点是国际化...”。现在我想起来了,它听起来包含了你所追求的大部分逻辑。

pango 中的字符覆盖功能是通过覆盖图实现的(“在 Pango 中通常需要确定特定字体是否可以表示特定字符​​,以及它可以如何很好地表示该字符。PangoCoverage 是一种数据结构,用于来表示该信息。”),但是在决定用什么字体呈现什么字形时可能涉及更复杂的细节。我猜想VTE依赖pango用适当的字体渲染字符串,而pango使用fontconfig(或其他支持的字体后端)根据pango本身和/或后端的各种逻辑来找到最合适的字体。