コードポイントのレンダリングに最適なフォントを探す

コードポイントのレンダリングに最適なフォントを探す

Unicodeコードポイントをレンダリングするのに適したフォントを見つける方法は?

gnome-terminal«のような文字を探します。

答え1

フォント構成を使用し、

> 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フォントの設定図書館。ディストリビューション(sudo apt-get install python-fontconfigDebianやその派生など)からインポートするか、ホームディレクトリ()にインストールします。その後、このスクリプトを実行できます(たとえば、通常のディレクトリにpip install --user python-fontconfig)保存して実行可能にします)。fc-search-codepointPATH~/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端末の使用フォント構成(何よりも):

...何千ものフォントがインストールされていても、インストールされているフォントコレクション内で効率的かつ迅速に必要なフォントを見つける...

内部にAPIドキュメントフォントの文字範囲を照会し、文字範囲で作業する関数を見つけることができますが、文書があまりにも秘密であるため、さまざまな関数のセットがどのように関連しているかはまったくわかりません。より深く掘り下げるには、他のソフトウェアの使用例を見てみましょう。静脈血栓塞栓症(gnome-terminalで使用される端末エミュレーションライブラリ)。

途中で別の図書館静脈血栓塞栓症そしてフォント構成はいパンゴ 「…国際化に重点を置いてテキストを配置してレンダリングするためのライブラリ…」。今考えてみると、あなたが求めるロジックのほとんどがここに含まれているようです。

pangoの文字カバレッジ機能は、次のように実装されています。書く「Pangoでは、特定のフォントが特定の文字を表すことができるかどうか、およびその文字をどの程度まで表現できるかを確認する必要があることがよくあります。PangoCoverageは、その情報を表すために使用されるデータ構造です。」)、しかし、どのフォントをどの文字の形でレンダリングするかを決定するには、より複雑な詳細があるかもしれません。私の考えでは静脈血栓塞栓症頼るパンゴ適切なフォントで文字列をレンダリングパンゴ使用フォント構成(または他のサポートされているフォントのバックエンド)さまざまなロジックに基づいて最も適切なフォントを見つけます。パンゴ自体および/またはバックエンド。

答え4

フォントに特定の文字列のすべての文字が含まれていることを確認するようにコードを変更しました。したがって、これを呼び出してfc-search-codepoint "$fontname" "$string"成功時に終了コード0を返し、そうでなければ1を返すことができます。フォント名はfc-query /path/to/FontSandMonoBoldOblique.ttfImagemagickまたは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)

関連情報