ยังไม่ชัดเจนสำหรับฉันว่าจะทำโดย macOS เองได้อย่างไร แต่ในระหว่างนี้นี่คือสิ่งที่ฉันทำ
โซลูชันที่ฉันพบทั้งหมดอยู่ในรูปแบบต่อไปนี้:
- รับรายการของแบบอักษรทั้งหมดที่มี
- วนรอบรายการเพื่อค้นหาแบบอักษรที่มีอักขระที่เลือก
การแสดงแบบอักษรทั้งหมด
ตามที่คำถามนี้มีสองวิธี (บวกหนึ่งในสามฉันพบที่นี่ ):
system_profiler SPFontsDataType
ซึ่งคุณสามารถเพิ่ม-xml
เพื่อรับเอาต์พุตใน XML
fc-list
ซึ่งสามารถใช้รูปแบบ ( :
เป็นรูปแบบที่ว่างเปล่าที่ตรงกับแบบอักษรทั้งหมด) และตัวระบุรูปแบบ
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 วินาทีบนคอมพิวเตอร์ของฉันสำหรับชุดฟอนต์ที่ฉันติดตั้ง)