รับรายการฟอนต์ทั้งหมดที่มีอักขระเฉพาะ


8

ใน macOS Sierra ฉันต้องการรับรายการแบบอักษรทั้งหมดที่ใช้ได้ (มีสัญลักษณ์สำหรับ) อักขระ Unicode เฉพาะ มีวิธีการทำเช่นนั้นไม่ว่าจะผ่านเครื่องมือหรือ Commandline หรือการเขียนโปรแกรมหรือไม่?

ตอนนี้นี่คือสิ่งที่ฉันสามารถทำได้:

  1. ภายใต้การตั้งค่าระบบ→แป้นพิมพ์→แป้นพิมพ์มีตัวเลือก "แสดงแป้นพิมพ์และตัวแสดงอิโมจิในแถบเมนู" แสดงแป้นพิมพ์ ที่ฉันเปิดไว้ สิ่งนี้ช่วยให้เมนูที่มุมบนขวาของหน้าจอถัดจากเวลาและวันที่
  2. ในเมนูนั้นฉันเลือก "แสดง Emoji และสัญลักษณ์" (ซึ่งฉันคิดว่าก่อนหน้านี้เรียกว่า "Character Viewer"):

แสดง Emoji และสัญลักษณ์

  1. ที่นี่ฉันสามารถค้นหาอักขระและภายใต้ "การเปลี่ยนแปลงแบบอักษร" ฉันสามารถคลิกที่การแสดงผลแต่ละอันและดูแบบอักษรที่เกี่ยวข้อง:

รูปแบบตัวอักษร

สิ่งนี้สามารถใช้งานได้เมื่อมีแบบอักษรไม่กี่ตัวที่มีอักขระ แต่ไม่สะดวก (ต้องคลิกและคัดลอกจำนวนมาก) เมื่อรายการแบบอักษรมีขนาดใหญ่ สิ่งที่ฉันต้องการคือการรับรายชื่อของแบบอักษรทั้งหมดในรูปแบบข้อความที่คัดลอกได้

ฉันจะทำสิ่งนั้นได้อย่างไร ฉันยินดีและยินดีที่จะเขียนรหัสในกรณีที่จำเป็น

คำตอบ:


6

ยังไม่ชัดเจนสำหรับฉันว่าจะทำโดย macOS เองได้อย่างไร แต่ในระหว่างนี้นี่คือสิ่งที่ฉันทำ

โซลูชันที่ฉันพบทั้งหมดอยู่ในรูปแบบต่อไปนี้:

  1. รับรายการของแบบอักษรทั้งหมดที่มี
  2. วนรอบรายการเพื่อค้นหาแบบอักษรที่มีอักขระที่เลือก

การแสดงแบบอักษรทั้งหมด

ตามที่คำถามนี้มีสองวิธี (บวกหนึ่งในสามฉันพบที่นี่ ):

  1. system_profiler SPFontsDataTypeซึ่งคุณสามารถเพิ่ม-xmlเพื่อรับเอาต์พุตใน XML

  2. fc-listซึ่งสามารถใช้รูปแบบ ( :เป็นรูปแบบที่ว่างเปล่าที่ตรงกับแบบอักษรทั้งหมด) และตัวระบุรูปแบบ

  3. instally python-fontconfigแล้วเรียกimport fontconfig; fontconfig.query()ได้รับรายชื่อของเส้นทางแบบอักษร

เปรียบเทียบทั้งสองวิธี (ฉันเขียนสิ่งนี้ก่อนที่ฉันจะสังเกตเห็นวิธีที่สาม) น่าสนใจ:

  • ความเร็ว: บนคอมพิวเตอร์ของฉันและสำหรับชุดแบบอักษรของฉันfc-listใช้เวลาประมาณ 24 วินาทีในครั้งแรกและ 0.04 วินาทีในแต่ละครั้งหลังจากนั้นในขณะที่system_profilerใช้เวลาประมาณ 3 วินาทีในแต่ละครั้ง

  • ความครอบคลุม: ในระบบปัจจุบันของฉันsystem_profilerรายการ 702 แบบอักษรในขณะที่fc-listรายการ 770: ทั้งหมด 702 บวก 68 เพิ่มเติม ในอีกด้านหนึ่งsystem_profilerดูเหมือนว่าจะเป็น "ทางการ" และตรงกับแบบอักษรที่ปรากฏในสมุดแบบอักษรคนที่ปรากฏใน "การเปลี่ยนแปลงแบบอักษร" ในตัวแสดงอักขระ / สัญลักษณ์ (ตามคำถาม) เมนูใน TextEdit เป็นต้นในทางกลับกันอย่างน้อยแบบอักษรบางส่วนที่พลาดไปนั้นเป็นแบบอักษรที่ใช้งานได้อย่างแท้จริง ซึ่งรวมถึงแบบอักษร 5 ตัว/Library/Fonts/{Athelas.ttc,Charter.ttc,Marion.ttc,Seravek.ttc,SuperClarendon.ttc}ที่คุณสามารถค้นหาหน้าเว็บออนไลน์ที่สับสน (เช่นนี้และนี่ ) แต่ยังรวม/Library/Fonts/{DIN Alternate Bold.ttf,DIN Condensed Bold.ttf,Iowan Old Style.ttc}ถึง 57 จาก 177 Noto Sans ด้วยแบบอักษรที่ฉันติดตั้งบนระบบของฉัน ตัวอย่างเช่นฉันได้ติดตั้ง Noto Sans Brahmi แต่แบบอักษรนี้ไม่ปรากฏในสมุดแบบอักษรหรือใน "รูปแบบตัวอักษร" เมื่อฉันค้นหาตัวอักษร Brahmi (พูด𑀅) แต่มันใช้ใน TextEdit (และแสดงในของฉัน เบราว์เซอร์) fc-listไม่ว่าเหตุผลสำหรับความแปลกประหลาดนี้ฉันมีความสุขที่ฉันจะได้รับรายการเต็มรูปแบบด้วย

  • ใช้งานง่าย: ด้วยวิธีใดวิธีหนึ่งจึงจำเป็นต้องมีการแยกวิเคราะห์เล็กน้อย ด้วยfc-listฉันสามารถระบุรูปแบบ (เช่นfc-list --format="%{family}\n%{file}\n%{lang}\n\n"แต่ฉันไม่พบการอ้างอิงสำหรับชื่อของฟิลด์!); กับsystem_profilerฉันสามารถอย่างใดอย่างหนึ่งเพียง grep สำหรับLocation:หรือส่งออกไปยัง XML และแยกของ XML (ตัวอย่างกับxml.etree.ElementTree , กับ plistlib )

แบบอักษรนี้ครอบคลุมถึงตัวละครนี้หรือไม่?

อย่างไรก็ตามเราได้รับรายชื่อของฟอนต์ถัดไปเราต้องตรวจสอบว่าตัวละครนั้นครอบคลุมในฟอนต์ที่เฉพาะเจาะจงหรือไม่ (กำหนดโดยชื่อหรือพา ธ ) อีกวิธีที่ฉันค้นพบ:

  • ใช้หนึ่งในการผูก FreeType สำหรับ Python นั้นมีfreetype-pyแต่ฉันหาวิธีใช้ไม่ได้ในเวลาไม่กี่นาที

  • ทิ้งตาราง cmap ของแบบอักษรด้วยttx / fonttoolsจากนั้นวนซ้ำตาราง นี่เป็นสิ่งที่ทำได้และฉันใช้การถ่ายโอนข้อมูลหลายครั้ง (คนเดียวสามารถttx foo.ttfรับfoo.ttxไฟล์ xml ซึ่งเป็นแบบที่มนุษย์อ่านได้) แต่สำหรับกรณีการใช้งานนี้ (การค้นหาแบบอักษรทั้งหมด) มันไม่ได้ดีที่สุด วินาทีต่อแบบอักษร

  • ตารางค้นหา CMAP จากห้องสมุดที่เขียนว่า: use Font::TTF::Fontใน Perl , from fontTools.ttLib import TTFontหลาม - นี้จะเป็นสิ่งที่ชอบ

    def has_char(font_path, c):
        """Does font at `font_path` contain the character `c`?"""
        from fontTools.ttLib import TTFont
        from fontTools.unicode import Unicode
        try:
            font = TTFont(font_path)
            for table in font['cmap'].tables:
                for char_code, glyph_name in table.cmap.items():
                    if char_code == ord(c):
                        font.close()
                        return True
        except Exception as e:
            print('Error while looking at font %s: %s' % (font_path, e))
            pass
        return False
    

    น่าเสียดายที่มันล้มเหลวในแบบอักษรมากเกินไปที่จะเป็นประโยชน์

  • หากคุณใช้โซลูชัน python-fontconfigมีวิธีhas_charใช้ดังนี้font = fontconfig.FcFont(path); return font.has_char(c)

สรุป

ฉันสิ้นสุดการใช้โซลูชันจากที่นี่ซึ่งฉันเขียนใหม่เบา ๆ เพื่อให้มันน้อยที่สุด:

#!/usr/bin/env python

def find_fonts(c):
    """Finds fonts containing  the (Unicode) character c."""
    import fontconfig
    fonts = fontconfig.query()
    for path in sorted(fonts):
        font = fontconfig.FcFont(path)
        if font.has_char(c):
            yield path

if __name__ == '__main__':
    import sys
    search = sys.argv[1]
    char = search.decode('utf-8') if isinstance(search, bytes) else search
    for path in find_fonts(char):
        print(path)

ตัวอย่างการใช้งาน:

% python3 find_fonts.py 'ಠ'
/Library/Fonts/Arial Unicode.ttf
/Library/Fonts/Kannada MN.ttc
/Library/Fonts/Kannada MN.ttc
/Library/Fonts/Kannada Sangam MN.ttc
/Library/Fonts/Kannada Sangam MN.ttc
/System/Library/Fonts/LastResort.ttf
/Users/shreevatsa/Library/Fonts/Kedage-b.TTF
/Users/shreevatsa/Library/Fonts/Kedage-i.TTF
/Users/shreevatsa/Library/Fonts/Kedage-n.TTF
/Users/shreevatsa/Library/Fonts/Kedage-t.TTF
/Users/shreevatsa/Library/Fonts/NotoSansKannada-Bold.ttf
/Users/shreevatsa/Library/Fonts/NotoSansKannada-Regular.ttf
/Users/shreevatsa/Library/Fonts/NotoSansKannadaUI-Bold.ttf
/Users/shreevatsa/Library/Fonts/NotoSansKannadaUI-Regular.ttf
/Users/shreevatsa/Library/Fonts/NotoSerifKannada-Bold.ttf
/Users/shreevatsa/Library/Fonts/NotoSerifKannada-Regular.ttf
/Users/shreevatsa/Library/Fonts/akshar.ttf

(ทำงานได้กับทั้งสองอย่างpython3และอะไรpython2ก็ตามที่pythonคุณมีใช้เวลาประมาณ 29 วินาทีบนคอมพิวเตอร์ของฉันสำหรับชุดฟอนต์ที่ฉันติดตั้ง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.