कोडपॉइंट रेंडर करने के लिए सबसे अच्छा फ़ॉन्ट खोजें


16

यूनिकोड कोडपॉइंट्स रेंडर करने के लिए उपयुक्त फ़ॉन्ट कैसे खोजें?

gnome-terminalयह जान लें कि «🉃 ⼼ 😻🕲🝤» जैसे पात्रों को मेरे टर्मिनल फॉन्ट या कोडपॉइंट-इन-स्क्वायर फॉलबैक (????) के बजाय सिमबोला जैसे फोंट के साथ प्रदान किया जा सकता है। कैसे ?


जवाबों:


14

यह जरूरी नहीं कि सबसे अच्छा तरीका है, और यह सुनिश्चित है कि यह उपयोगकर्ता के अनुकूल नहीं है, लेकिन यह काम करना आसान है: इसे करने के लिए एक पायथन स्क्रिप्ट है।

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

1
यह एक बहुत ही उपयोगी स्क्रिप्ट है! हालाँकि, यह केवल python2 अनुरूप है, और मुझे लगता है कि यह वास्तव में पोर्टेबल करने के लिए थोड़ा बुरा है। आप बदल रहा है कम से कम आपत्ति तो नहीं #!/usr/bin/env pythonकरने के लिए #!/usr/bin/env python2के रूप में प्रति पीईपी 394
Zulan

1
इस उत्तर के लिए धन्यवाद! यह बहुत मददगार था। मुझे यकीन है कि ओएस या सिस्टम लाइब्रेरी जो फॉन्टबैकबैक को लागू करते हैं, कुछ अधिक कुशल हैं, लेकिन यह काम करता है। @Zulan इसे python3भी काम करने के लिए बनाया जा सकता है; मैंने इस उत्तर के निचले भाग में इसका एक छोटा संस्करण लिखा है ।
श्रीवत्सआर

5

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"

2
ध्यान दें कि आपको इसके एक संस्करण की आवश्यकता fontconfigहै 2.11.91या बाद में
नथानिएल एम। बीवर

1
ध्यान दें कि पानी का छींटा printfऔर /bin/printfन ही समर्थन करते हैं कि
स्टीवन पेनी

1
बहुत बढ़िया! मैं लंबे समय से इस पर जानकारी ढूंढ रहा था। ध्यान दें कि आप श्रेणियों के साथ-साथ एकल वर्णों को भी निर्दिष्ट कर सकते हैं, इसलिए उन सभी फोंट को खोजने के लिए जिनमें सभी बॉक्स-ड्रॉइंग वर्ण हैं, उदाहरण के लिए:fc-list --format='%{postscriptname}\n' ':charset=2500-257F'
नील मैथ्यू

3

अंतत: सूक्ति-टर्मिनल फ़ॉन्टकंफिग का उपयोग करता है (अन्य बातों के अलावा):

... कुशलता से और जल्दी से आपके द्वारा स्थापित किए गए फोंट के सेट के बीच फोंट की आवश्यकता है, भले ही आपने हजारों फोंट स्थापित किए हों ...

में API दस्तावेज़ आप क्वेरी फोंट चरित्र वर्गों के समक्ष और चरित्र सीमाओं पर संचालन के लिए कार्य करता है पा सकते हैं, लेकिन प्रलेखन इतना गुप्त है कि मैं कभी यह पता लगाने कैसे कार्यों के विभिन्न सेट एक दूसरे से संबंधित सकता है। अगर मुझे गहराई से गोता लगाने की ज़रूरत है, तो मैं अन्य सॉफ़्टवेयर में उपयोग के उदाहरणों पर ध्यान दूंगा , शायद वीटीई (गनोम-टर्मिनल में प्रयुक्त टर्मिनल इम्यूलेशन लाइब्रेरी)।

बीच में एक और पुस्तकालय वी T ई और fontconfig है Pango "... बिछाने और पाठ के प्रतिपादन अंतर्राष्ट्रीयकरण पर जोर देने के साथ, के लिए एक पुस्तकालय ..." । अब जब मैं इसके बारे में सोचता हूं, तो यह लगता है कि आपके तर्क के बाद अधिकांश को समाहित किया जाए।

पंगो में चरित्र कवरेज की कार्यक्षमता कवरेज मानचित्रों द्वारा कार्यान्वित की जाती है ( "यह निर्धारित करने के लिए पंगो में अक्सर आवश्यक होता है कि क्या कोई विशेष फ़ॉन्ट किसी विशेष वर्ण का प्रतिनिधित्व कर सकता है, और यह भी कि वह उस चरित्र का कितना अच्छा प्रतिनिधित्व कर सकता है। PangoCoverage एक डेटा संरचना है जिसका उपयोग किया जाता है। उस जानकारी का प्रतिनिधित्व करने के लिए। " ), लेकिन संभवतः अधिक जटिल विवरण हैं जो यह तय करते हैं कि ग्लिफ़ को किस फ़ॉन्ट के साथ प्रस्तुत करना है। मुझे लगता है कि VTE पर निर्भर करता है Pango उचित फ़ॉन्ट के साथ तार रेंडर करने के लिए है, जबकि Pango का उपयोग करता है कि fontconfig (या अन्य समर्थित फ़ॉन्ट बैकएंड) में तर्क का pieced विभिन्न के आधार पर सबसे उपयुक्त फ़ॉन्ट खोजने के लिए Pango ही और / या बैकएंड।


1

मैंने यह जांचने के लिए कोड को बदल दिया है कि क्या किसी फ़ॉन्ट में एक निश्चित स्ट्रिंग के सभी वर्ण हैं। तो यह कहा जा सकता है 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.