यूनिकोड कोडपॉइंट्स रेंडर करने के लिए उपयुक्त फ़ॉन्ट कैसे खोजें?
gnome-terminalयह जान लें कि «🉃 ⼼ 😻🕲🝤» जैसे पात्रों को मेरे टर्मिनल फॉन्ट या कोडपॉइंट-इन-स्क्वायर फॉलबैक (????) के बजाय सिमबोला जैसे फोंट के साथ प्रदान किया जा सकता है। कैसे ?
यूनिकोड कोडपॉइंट्स रेंडर करने के लिए उपयुक्त फ़ॉन्ट कैसे खोजें?
gnome-terminalयह जान लें कि «🉃 ⼼ 😻🕲🝤» जैसे पात्रों को मेरे टर्मिनल फॉन्ट या कोडपॉइंट-इन-स्क्वायर फॉलबैक (????) के बजाय सिमबोला जैसे फोंट के साथ प्रदान किया जा सकता है। कैसे ?
जवाबों:
यह जरूरी नहीं कि सबसे अच्छा तरीका है, और यह सुनिश्चित है कि यह उपयोगकर्ता के अनुकूल नहीं है, लेकिन यह काम करना आसान है: इसे करने के लिए एक पायथन स्क्रिप्ट है।
Python-fontconfig लाइब्रेरी स्थापित करें । या तो इसे अपने वितरण से प्राप्त करें (जैसे sudo apt-get install python-fontconfigडेबियन और डेरिवेटिव पर) या इसे अपने घर निर्देशिका में स्थापित करें ( 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 🉃⼼😻🕲🝤
$ echo $?
1
मेरे पास इन सभी पात्रों के साथ कोई फ़ॉन्ट नहीं है।
$ fc-search-codepoint U+1F64D
/usr/share/fonts/truetype/unifont/unifont_upper.ttf
/usr/share/fonts/truetype/unifont/unifont_upper_csur.ttf
#!/usr/bin/env pythonकरने के लिए #!/usr/bin/env python2के रूप में प्रति पीईपी 394
python3भी काम करने के लिए बनाया जा सकता है; मैंने इस उत्तर के निचले भाग में इसका एक छोटा संस्करण लिखा है ।
Fontconfig का उपयोग करना,
> fc-list ':charset=<hex_code1> <hex_code2>'
जैसे
> fc-list ':charset=2713 2717'
✗ और ✓ युक्त किसी भी फ़ॉन्ट फ़ाइल नाम को प्रदर्शित करेगा।
वर्ण उपयोग के लिए कोडपॉइंट प्राप्त करने के लिए (उदाहरण के लिए)
> printf "%x" \'✓
2713>
यह POSIX उपयोगिता
की कुछ अस्पष्ट सुविधा का उपयोग करता है :printf
यदि अग्रणी चरित्र एकल-उद्धरण या डबल-उद्धरण है, तो मूल्य एकल-उद्धरण या डबल-उद्धरण के बाद वर्ण के अंतर्निहित कोडसेट में संख्यात्मक मान होगा।
एक साथ लिया,
> printf '%x' \'✓ | xargs -I{} fc-list ":charset={}"
यह xargs -Iध्वज का उपयोग {}नामों से बदलने के लिए करता है stdin। तो यह प्रभावी रूप से करने के लिए नीचे फोड़े:
> fc-list ":charset=2713"
printfऔर /bin/printfन ही समर्थन करते हैं कि
fc-list --format='%{postscriptname}\n' ':charset=2500-257F'
अंतत: सूक्ति-टर्मिनल फ़ॉन्टकंफिग का उपयोग करता है (अन्य बातों के अलावा):
... कुशलता से और जल्दी से आपके द्वारा स्थापित किए गए फोंट के सेट के बीच फोंट की आवश्यकता है, भले ही आपने हजारों फोंट स्थापित किए हों ...
में API दस्तावेज़ आप क्वेरी फोंट चरित्र वर्गों के समक्ष और चरित्र सीमाओं पर संचालन के लिए कार्य करता है पा सकते हैं, लेकिन प्रलेखन इतना गुप्त है कि मैं कभी यह पता लगाने कैसे कार्यों के विभिन्न सेट एक दूसरे से संबंधित सकता है। अगर मुझे गहराई से गोता लगाने की ज़रूरत है, तो मैं अन्य सॉफ़्टवेयर में उपयोग के उदाहरणों पर ध्यान दूंगा , शायद वीटीई (गनोम-टर्मिनल में प्रयुक्त टर्मिनल इम्यूलेशन लाइब्रेरी)।
बीच में एक और पुस्तकालय वी T ई और fontconfig है Pango "... बिछाने और पाठ के प्रतिपादन अंतर्राष्ट्रीयकरण पर जोर देने के साथ, के लिए एक पुस्तकालय ..." । अब जब मैं इसके बारे में सोचता हूं, तो यह लगता है कि आपके तर्क के बाद अधिकांश को समाहित किया जाए।
पंगो में चरित्र कवरेज की कार्यक्षमता कवरेज मानचित्रों द्वारा कार्यान्वित की जाती है ( "यह निर्धारित करने के लिए पंगो में अक्सर आवश्यक होता है कि क्या कोई विशेष फ़ॉन्ट किसी विशेष वर्ण का प्रतिनिधित्व कर सकता है, और यह भी कि वह उस चरित्र का कितना अच्छा प्रतिनिधित्व कर सकता है। PangoCoverage एक डेटा संरचना है जिसका उपयोग किया जाता है। उस जानकारी का प्रतिनिधित्व करने के लिए। " ), लेकिन संभवतः अधिक जटिल विवरण हैं जो यह तय करते हैं कि ग्लिफ़ को किस फ़ॉन्ट के साथ प्रस्तुत करना है। मुझे लगता है कि VTE पर निर्भर करता है Pango उचित फ़ॉन्ट के साथ तार रेंडर करने के लिए है, जबकि Pango का उपयोग करता है कि fontconfig (या अन्य समर्थित फ़ॉन्ट बैकएंड) में तर्क का pieced विभिन्न के आधार पर सबसे उपयुक्त फ़ॉन्ट खोजने के लिए Pango ही और / या बैकएंड।
मैंने यह जांचने के लिए कोड को बदल दिया है कि क्या किसी फ़ॉन्ट में एक निश्चित स्ट्रिंग के सभी वर्ण हैं। तो यह कहा जा सकता है fc-search-codepoint "$fontname" "$string"और यह सफलता या अन्यथा पर निकास कोड 0 वापस करता है। फ़ॉन्ट नाम से fc-query /path/to/FontSandMonoBoldOblique.ttfया 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)