Найдите лучший шрифт для рендеринга кодовой точки

Это отображает значок уведомления, который указывает, что у Вас в настоящее время есть полномочия суперпользователя в некоторых ситуациях. Добавьте область уведомлений к панели для содержания значка вместо этого.

16
15.10.2014, 19:54
4 ответа

В конечном счете, гном-терминал использует fontconfig to (среди прочего):

... эффективно и быстро находит нужные вам шрифты среди установленного вами набора, даже если вы установили тысячи шрифтов....

В документации API можно найти функции для запроса диапазонов символов шрифтов и для операций с диапазонами символов, но документация настолько загадочна, что я никогда не мог понять, как различные наборы функций соотносятся друг с другом. Если бы мне понадобилось погрузиться глубже, я бы предпочёл взглянуть на примеры использования в других программах, возможно vte (библиотека эмуляции терминала, используемая в gnome-терминале).

Другая библиотека между vte и fontconfig - это pango "...библиотека для выкладывания и вывода текста, с акцентом на интернационализацию...". Теперь, когда я думаю об этом, это звучит так, как будто она содержит большую часть логики, за которой вы охотитесь.

Функциональность покрытия символов в Pango реализована с помощью карт покрытия () () "В Pango часто необходимо определить, может ли определенный шрифт представлять определенный символ, а также насколько хорошо он может представлять этот символ. PangoCoverage - это структура данных, которая используется для представления этой информации"), но, вероятно, есть более сложные детали, связанные с решением, какой глиф изображать с помощью какого шрифта. Я полагаю, что VTE полагается на pango для отображения строк с соответствующими шрифтами, в то время как pango использует fontconfig (или другой поддерживаемый шрифт бэкэнда), чтобы найти наиболее подходящий шрифт, основанный на различных фрагментах логики в pango самом и/или бэкэнде.

3
27.01.2020, 19:48

Это не обязательно лучший метод, и он, конечно, неудобен для пользователя, но с ним легко приступить к работе: вот скрипт 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)

Пример использования:

$ fc-search-codepoint                             
14
27.01.2020, 19:48

Я изменил код, чтобы проверить, содержит ли шрифт все символы определенной строки. Таким образом, это может быть вызвано fc-search-codepoint "$fontname" "$string" и возвращает код выхода 0 в случае успеха или 1 в противном случае. Имена шрифтов можно получить из fc-query /path/to/FontSandMonoBoldOblique.ttf или convert -list font от Imagemagick. Я использую его, чтобы проверить, может ли строка, выбранная пользователем, отображаться с выбранным пользователем шрифтом, и если команда не работает, используется резервный шрифт.

#!/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)
1
27.01.2020, 19:48

Использование fontconfig,

> fc-list ':charset=<hex_code1> <hex_code2>'

напр.

> fc-list ':charset=2713 2717'

отобразит все имена файлов шрифтов, содержащие ✓ и ✗.

Чтобы получить кодовую точку, соответствующую символу, используйте (, например)

> printf "%x" \'✓
2713>

Здесь используется несколько непонятная функция утилиты POSIX printf:

If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote.

В совокупности

> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"

При этом используется флагxargs-Iдля замены {}именами из stdin. Таким образом, это фактически сводится к:

> fc-list ":charset=2713"
22
27.01.2020, 19:48

Теги

Похожие вопросы