ユニコードコードポイントをレンダリングするための適切なフォントを見つける方法は?
gnome-terminal
"????⼼????????????"のような文字を見つけます端末フォントやコードポイントインスクエアフォールバック(????)ではなく、Symbolaなどのフォントでレンダリングできます。どうやって ?
これは必ずしも最良の方法であるとは限らず、ユーザーフレンドリーでもありませんが、簡単に機能します。これを行うPythonスクリプトを次に示します。
Python-fontconfig ライブラリをインストールします。ディストリビューションから入手するか(たとえば、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 ????⼼????????????
$ echo $?
1
これらのすべての文字を含むフォントはありません。
$ fc-search-codepoint U+1F64D
/usr/share/fonts/truetype/unifont/unifont_upper.ttf
/usr/share/fonts/truetype/unifont/unifont_upper_csur.ttf
Fontconfigを使用して、
> fc-list ':charset=<hex_code1> <hex_code2>'
例えば.
> fc-list ':charset=2713 2717'
✓とcontainingを含むフォントファイル名が表示されます。
文字の使用に対応するコードポイントを取得するには(たとえば)
> printf "%x" \'✓
2713>
これは POSIX printf
ユーティリティ の ややあいまいな機能 を使用します:
先頭の文字が単一引用符または二重引用符である場合、値は、単一引用符または二重引用符に続く文字の基になるコードセット内の数値になります。
一緒に取られて、
> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"
これは、xargs
-I
フラグを使用して、{}
をstdin
の名前に置き換えます。つまり、これは実質的に次のようになります。
> fc-list ":charset=2713"
フォントに特定の文字列のすべての文字が含まれているかどうかを確認するようにコードを変更しました。したがって、これは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)