Unicode コードポイントをレンダリングするための適切なフォントを見つけるにはどうすればよいでしょうか?
gnome-terminal
「
答え1
fontconfigを使用すると、
> fc-list ':charset=<hex_code1> <hex_code2>'
例えば
> fc-list ':charset=2713 2717'
✓ と ✗ を含むフォントファイル名が表示されます。
文字に対応するコードポイントを取得するには、次のようにします(例)
> printf "%x" \'✓
2713>
これは、あまり知られていない機能
のPOSIXprintf
ユーティリティ:
先頭の文字が一重引用符または二重引用符の場合、値は一重引用符または二重引用符に続く文字の基になるコードセット内の数値になります。
まとめると、
> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"
これは、 フラグを使用して の名前にxargs
-I
置き換えます。つまり、実質的には次のようになります。{}
stdin
> fc-list ":charset=2713"
答え2
これは必ずしも最良の方法ではなく、ユーザーフレンドリーではありませんが、動作させるのは簡単です。これを行うための Python スクリプトを以下に示します。
インストールPython フォント設定ライブラリ。ディストリビューション (Debian やその派生版など) から入手するかsudo apt-get install python-fontconfig
、ホーム ディレクトリ ( ) にインストールします。その後、このスクリプトを実行します (のディレクトリ(通常は )に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)
使用例:
$ fc-search-codepoint
答え3
最終的にgnome-terminalはフォント設定(とりわけ)以下
...何千ものフォントをインストールしている場合でも、インストールしたフォント セットの中から必要なフォントを効率的かつ迅速に見つけることができます...
の中にAPIドキュメントフォントの文字範囲を照会したり、文字範囲を操作する関数は見つかりますが、ドキュメントが難解すぎて、さまざまな関数セットが互いにどのように関連しているかがわかりません。もっと深く調べる必要がある場合は、他のソフトウェアでの使用例を見るほうがよいでしょう。仮想(gnome-terminal で使用される端末エミュレーション ライブラリ)。
中間にある別の図書館仮想そしてフォント設定はパンゴ 「...国際化を重視したテキストのレイアウトとレンダリングのためのライブラリ...」考えてみると、それはあなたが求めているロジックの大部分を含んでいるように思えます。
パンゴの文字カバレッジ機能は、カバレッジマップ(「Pango では、特定のフォントが特定の文字を表現できるかどうか、またその文字をどの程度正確に表現できるかを判断することがしばしば必要になります。PangoCoverage は、その情報を表すために使用されるデータ構造です。」)ですが、どのグリフをどのフォントでレンダリングするかを決めるには、もっと複雑な詳細が関係していると思います。静脈血栓塞栓症依存しているパンゴ適切なフォントで文字列をレンダリングしながらパンゴ用途フォント設定(またはサポートされている他のフォントバックエンド)を使用して、さまざまなロジックに基づいて最も適切なフォントを見つけます。パンゴそれ自体および/またはバックエンド。
答え4
フォントに特定の文字列のすべての文字が含まれているかどうかを確認するためにコードを変更しました。これは から呼び出すことができfc-search-codepoint "$fontname" "$string"
、成功した場合は終了コード 0 を返し、そうでない場合は 1 を返します。フォント名は、fc-query /path/to/FontSandMonoBoldOblique.ttf
または Imagemagick のから取得できますconvert -list font
。これを使用して、ユーザーが選択した文字列をユーザーが選択したフォントでレンダリングできるかどうかを確認し、コマンドが失敗した場合はフォールバック フォントを使用します。
#!/usr/bin/env python2
import re
import sys
import os
import fontconfig
if len(sys.argv) < 3:
print("Usage: " + sys.argv[0] + " 'Fontname-Bold' 'String to check'")
sys.exit(0)
font_name = sys.argv[1].decode('utf-8')
string = sys.argv[2].decode('utf-8')
if '-' in font_name:
font_name = font_name.split('-')
font_style = font_name[-1]
font_name = ''.join(font_name[:-1])
else:
font_style = ""
font_names = fontconfig.query()
for name in font_names:
font = fontconfig.FcFont(name)
if not len(font.family) > 0:
continue
for item in font.family:
if item[1] == unicode(font_name):
if len(font_style) == 0:
match = "yes"
else:
for item in font.style:
if item[1] == unicode(font_style):
match = "yes"
try:
match
except NameError:
continue
if all(font.has_char(c) for c in string):
sys.exit(0)
else:
sys.exit(1)
print >> sys.stderr, "font not found: " + font_name + " " + font_style
sys.exit(1)