Trouver la meilleure police pour rendre un codet

Comment find la police appropriée pour rendre les points de code unicode?

gnome-terminal trouve que des caractères comme «🉃 ⼼ 😻🕲🝤» peuvent être rendus avec des fonts comme Symbola plutôt qu'avec ma police de caractères ou avec le codepoint-in-square fallback ( ). Comment ?

Ce n'est pas nécessairement la meilleure méthode, et ce n'est pas facile à utiliser, mais il est facile de travailler: voici un script Python pour le faire.

Installez la bibliothèque Python-fontconfig . Soit l'get à partir de votre dissortingbution (p.ex. sudo apt-get install python-fontconfig sur Debian et dérivés) ou l'installer dans votre directory personnel ( pip install --user python-fontconfig) . Ensuite, vous pouvez exécuter ce script (enregistrez-le comme fc-search-codepoint dans un directory de votre PATH , par exemple ~/bin et exécutez-le):

 #!/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.comstack(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) 

Exemple d'utilisation:

 $ fc-search-codepoint 🉃⼼😻🕲🝤 $ echo $? 1 

Je n'ai pas de police avec tous ces caractères.

 $ fc-search-codepoint U+1F64D /usr/share/fonts/truetype/unifont/unifont_upper.ttf /usr/share/fonts/truetype/unifont/unifont_upper_csur.ttf 

En fin de count, gnome-terminal utilise fontconfig pour (entre autres):

… find efficacement et rapidement les fonts dont vous avez besoin parmi l'set des fonts que vous avez installées, même si vous avez installé des milliers de fonts …

Dans la documentation de l' API, vous pouvez find des fonctions pour interroger les plages de caractères des fonts et pour les opérations sur les plages de caractères, mais la documentation est tellement cryptique que je ne pourrais jamais comprendre comment différents sets de fonctions se rapportent les uns aux autres. Si je devais plonger plus profondément, je préférerais regarder des exemples d'utilisation dans d'autres logiciels, peut-être vte (la bibliothèque d'émulation de terminal utilisée dans gnome-terminal).

Une autre bibliothèque entre vte et fontconfig est pango "… une bibliothèque pour la layout et le rendu du text, en mettant l'accent sur l'internationalisation …" . Maintenant que j'y pense, ça sonne comme celui qui contient la plupart de la logique que vous searchz.

La fonctionnalité de couverture des caractères dans pango est implémentée par les maps de couverture ( "Il est souvent nécessaire dans Pango de déterminer si une police particulière peut représenter un caractère particulier, et aussi comment elle peut bien représenter ce caractère. Le PangoCoverage est une structure de données utilisée pour représenter cette information. " ), mais il y a probablement plus de détails compliqués impliqués dans la décision quel glyphe à rendre avec quelle police. Je suppose que VTE s'appuie sur pango pour rendre les strings avec les fonts appropriées, tandis que pango utilise fontconfig (ou d'autres fonts supscopes) pour find la police la plus appropriée en fonction de la logique de pango et / ou du backend.

En utilisant fontconfig,

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

par exemple

 > fc-list ':charset=2713 2717' 

affiche tous les noms de files de police contenant ✓ et ✗.

Pour get le code correspondant à l'utilisation du caractère (par exemple)

 > printf "%x" \'✓ 

Pris set,

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

J'ai modifié le code pour vérifier si une police contient tous les caractères d'une certaine string. Cela peut donc être appelé par fc-search-codepoint "$fontname" "$ssortingng" et renvoie le code de sortie 0 en cas de succès ou 1 sinon. Les noms de police peuvent être récupérés à partir de fc-query /path/to/FontSandMonoBoldOblique.ttf ou de la police convert -list font . Je l'utilise pour vérifier si une string sélectionnée par l'user peut être rendue avec la police sélectionnée par l'user et si la command échoue, une police de secours est utilisée.

 #!/usr/bin/env python2 import re import sys import os import fontconfig if len(sys.argv) < 3: print("Usage: " + sys.argv[0] + " 'Fontname-Bold' 'Ssortingng to check'") sys.exit(0) font_name = sys.argv[1].decode('utf-8') ssortingng = 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 ssortingng): sys.exit(0) else: sys.exit(1) print >> sys.stderr, "font not found: " + font_name + " " + font_style sys.exit(1)