¿Cómo encontrar la fuente adecuada para representar puntos de código Unicode?
gnome-terminal
encontrar que personajes como «
Respuesta1
Usando fontconfig,
> fc-list ':charset=<hex_code1> <hex_code2>'
p.ej
> fc-list ':charset=2713 2717'
mostrará cualquier nombre de archivo de fuente que contenga ✓ y ✗.
Para obtener el punto de código correspondiente al uso del carácter (por ejemplo)
> printf "%x" \'✓
2713>
Esto utiliza uncaracterística algo oscura
delprintf
Utilidad POSIX:
Si el carácter inicial es una comilla simple o doble, el valor será el valor numérico en el conjunto de códigos subyacente del carácter que sigue a la comilla simple o doble.
Tomados en conjunto,
> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"
Esto usa la xargs
-I
bandera para reemplazar {}
con nombres de stdin
. Entonces, esto efectivamente se reduce a:
> fc-list ":charset=2713"
Respuesta2
Este no es necesariamente el mejor método, y seguro que no es fácil de usar, pero es fácil empezar a trabajar: aquí hay un script de Python para hacerlo.
Instala elPython-fontconfigbiblioteca. Consíguelo desde tu distribución (por ejemplo, sudo apt-get install python-fontconfig
en Debian y derivados) o instálalo en tu directorio de inicio ( pip install --user python-fontconfig)
. Luego puedes ejecutar este script (guárdalo fc-search-codepoint
en un directorio de tu PATH
, por ejemplo, normalmente ~/bin
, y hazlo ejecutable):
#!/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)
Uso de ejemplo:
$ fc-search-codepoint
Respuesta3
En última instancia, usos de gnome-terminalconfiguración de fuentea (entre otras cosas):
...encuentre eficiente y rápidamente las fuentes que necesita entre el conjunto de fuentes que ha instalado, incluso si ha instalado miles de fuentes...
En elDocumentación APIpuedes encontrar funciones para consultar rangos de caracteres de fuentes y para operaciones en rangos de caracteres, pero la documentación es tan críptica que nunca pude entender cómo se relacionan entre sí los diferentes conjuntos de funciones. Si necesitara profundizar más, preferiría mirar ejemplos de uso en otro software, tal vezvte(la biblioteca de emulación de terminal utilizada en gnome-terminal).
Otra biblioteca en el mediovteyconfiguración de fuenteespango "...una biblioteca para maquetación y renderizado de textos, con énfasis en la internacionalización...". Ahora que lo pienso, parece que contiene la mayor parte de la lógica que buscas.
La funcionalidad de cobertura de personajes en pango se implementa mediantemapas de cobertura("A menudo es necesario en Pango determinar si una fuente en particular puede representar un carácter en particular, y también qué tan bien puede representar ese carácter. PangoCoverage es una estructura de datos que se utiliza para representar esa información".), pero probablemente haya detalles más complicados involucrados en decidir qué glifo representar con qué fuente. SupongoTEVse basa enpangopara representar cadenas con fuentes apropiadas mientraspangousosconfiguración de fuente(u otro backend de fuente compatible) para encontrar la fuente más apropiada según varios elementos de lógica enpangoen sí mismo y/o el backend.
Respuesta4
Modifiqué el código para verificar si una fuente contiene todos los caracteres de una determinada cadena. Entonces se puede llamar a esto fc-search-codepoint "$fontname" "$string"
y devuelve el código de salida 0 en caso de éxito o 1 en caso contrario. Los nombres de las fuentes se pueden recuperar de fc-query /path/to/FontSandMonoBoldOblique.ttf
Imagemagick's convert -list font
. Lo uso para verificar si una cadena seleccionada por el usuario se puede representar con la fuente seleccionada por el usuario y, si el comando falla, se usa una fuente alternativa.
#!/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)