
Wie finde ich die passende Schriftart zum Rendern von Unicode-Codepunkten?
gnome-terminal
finden, dass Zeichen wie «
Antwort1
Mit fontconfig,
> fc-list ':charset=<hex_code1> <hex_code2>'
z.B
> fc-list ':charset=2713 2717'
zeigt alle Schriftdateinamen an, die ✓ und ✗ enthalten.
Um den Codepunkt zu erhalten, der dem Zeichen entspricht, verwenden Sie (zum Beispiel)
> printf "%x" \'✓
2713>
Dabei wird einetwas obskure Funktion
desPOSIX- printf
Dienstprogramm:
Wenn das führende Zeichen ein einfaches oder doppeltes Anführungszeichen ist, muss der Wert der numerische Wert im zugrunde liegenden Codesatz des auf das einfache oder doppelte Anführungszeichen folgenden Zeichens sein.
Zusammen genommen,
> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"
Dabei wird die xargs
-I
Flagge zum Ersetzen {}
durch Namen aus verwendet stdin
. Im Endeffekt läuft es also auf Folgendes hinaus:
> fc-list ":charset=2713"
Antwort2
Dies ist nicht unbedingt die beste Methode und sicher nicht benutzerfreundlich, aber es lässt sich leicht damit arbeiten: Hier ist ein Python-Skript dafür.
Installiere dasPython-SchriftkonfigurationBibliothek. Entweder holen Sie es sich von Ihrer Distribution (z. B. sudo apt-get install python-fontconfig
bei Debian und Derivaten) oder installieren Sie es in Ihrem Home-Verzeichnis ( pip install --user python-fontconfig)
. Dann können Sie dieses Skript ausführen (speichern Sie es als fc-search-codepoint
in einem Verzeichnis auf Ihrem PATH
, z. B. typischerweise ~/bin
, und machen Sie es ausführbar):
#!/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)
Anwendungsbeispiel:
$ fc-search-codepoint
Antwort3
Letztendlich verwendet Gnome-TerminalSchriftartkonfigurationum (unter anderem):
...finden Sie effizient und schnell die Schriftarten, die Sie benötigen, unter den installierten Schriftarten, selbst wenn Sie Tausende von Schriftarten installiert haben...
ImAPI-DokumentationSie können Funktionen zum Abfragen von Zeichenbereichen von Schriftarten und für Operationen mit Zeichenbereichen finden, aber die Dokumentation ist so kryptisch, dass ich nie herausfinden konnte, wie verschiedene Funktionssätze miteinander in Beziehung stehen. Wenn ich tiefer eintauchen müsste, würde ich mir lieber Anwendungsbeispiele in anderer Software ansehen, vielleichtvte(die im Gnome-Terminal verwendete Terminalemulationsbibliothek).
Eine weitere Bibliothek zwischendurchvteUndSchriftartkonfigurationIstpango „... eine Bibliothek zum Layouten und Rendern von Texten mit Schwerpunkt auf Internationalisierung …“. Wenn ich darüber nachdenke, klingt es so, als ob es den größten Teil der Logik enthält, nach der Sie suchen.
Die Charakterabdeckungsfunktionalität in Pango wird implementiert durchAbdeckungskarten(„In Pango muss häufig ermittelt werden, ob eine bestimmte Schriftart ein bestimmtes Zeichen darstellen kann und wie gut sie dieses Zeichen darstellen kann. PangoCoverage ist eine Datenstruktur, die zur Darstellung dieser Informationen verwendet wird.“), aber es gibt wahrscheinlich kompliziertere Details, die entscheiden, welche Glyphe mit welcher Schriftart dargestellt werden soll. Ich schätzeVTEberuht aufpangoum Strings mit passenden Schriftarten darzustellen, währendpangoVerwendetSchriftartkonfiguration(oder ein anderes unterstütztes Font-Backend), um die am besten geeignete Schriftart basierend auf verschiedenen Logikelementen zu finden inpangoselbst und/oder das Backend.
Antwort4
Ich habe den Code geändert, um zu prüfen, ob eine Schriftart alle Zeichen einer bestimmten Zeichenfolge enthält. Dies kann also aufgerufen werden fc-search-codepoint "$fontname" "$string"
und gibt bei Erfolg den Exit-Code 0 und andernfalls 1 zurück. Die Schriftartnamen können von fc-query /path/to/FontSandMonoBoldOblique.ttf
oder von Imagemagick abgerufen werden convert -list font
. Ich verwende es, um zu prüfen, ob eine vom Benutzer ausgewählte Zeichenfolge mit der vom Benutzer ausgewählten Schriftart gerendert werden kann, und wenn der Befehl fehlschlägt, wird eine Ersatzschriftart verwendet.
#!/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)