问题来源
如何在 matplotlib 中使用中文字体是老问题了,相关文章非常多。
前几天有人问我 如何知道中文字体名称和实际文件的对应关系 时,才想起来原来没思考过这个问题,只能让他记住字体与文件的对应关系或者去 fonts 目录查看。
**难道真的就没有稍微自动化、智能化的查看支持matplotlib 的字体名称与文件的对应关系的方法? **
问题解决步骤
matplotlib 与字体相关的模块是 font_manager ,观察源码 font_manager.py 可知:
1. matplotlib支持哪种类型的字体?
def get_fontext_synonyms(fontext):
"""
Return a list of file extensions extensions that are synonyms for
the given file extension *fileext*.
"""
return {
\'afm\': [\'afm\'],
\'otf\': [\'otf\', \'ttc\', \'ttf\'],
\'ttc\': [\'otf\', \'ttc\', \'ttf\'],
\'ttf\': [\'otf\', \'ttc\', \'ttf\'],
}[fontext]
由此可知 matplotlib 只支持 ttf 和 afm 字体。
- ‘ttf\': TrueType and OpenType fonts (.ttf, .ttc, .otf)
- ‘afm\': Adobe Font Metrics (.afm)
2. matplotlib如何查找系统字体?
findSystemFonts 模块函数的作用是查找系统字体。def findSystemFonts(fontpaths=None, fontext=\'ttf\'): -->list
参数 fontext 默认值为 \'ttf\' ,另外还支持值 \'afm\' 。
参数 fontpaths 默认值是 None 。
对于 fontpaths 有两种种情况。
fontpaths 为 None
函数会判断操作系统,如果是Windows,调用函数 win32InstalledFonts ,如果不是Windows,调用函数 get_fontconfig_fonts 。
对于Windows,函数 win32InstalledFonts 到以下路径查找。
# OS Font paths
MSFolders = \
r\'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\'
MSFontDirectories = [
r\'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\',
r\'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts\']
MSUserFontDirectories = [
str(Path.home() / \'AppData/Local/Microsoft/Windows/Fonts\'),
str(Path.home() / \'AppData/Roaming/Microsoft/Windows/Fonts\'),
]
对于 非Windows 操作系统,函数 get_fontconfig_fonts 主要依托 fontconfig 包(即 fc- list 命令)查找字体,要求 fontconfig>=2.7 。
fontpaths 不为 None
当 fontpaths 不为 None 时,通过 list_fonts() 函数查找字体。
**list_fonts() 函数其实一个通用的按路径、扩展名递归遍历文件路径的函数。 **
def list_fonts(directory, extensions):
"""
Return a list of all fonts matching any of the extensions, found
recursively under the directory.
"""
extensions = ["." + ext for ext in extensions]
return [os.path.join(dirpath, filename)
# os.walk ignores access errors, unlike Path.glob.
for dirpath, _, filenames in os.walk(directory)
for filename in filenames
if Path(filename).suffix.lower() in extensions]
3.matplotlib如何查找matplotlib自带字体?
安装 matplotlib 时,会在 site-packages\matplotlib\mpl-data\fonts 目录放置一系列字体。
通过源码可知 fonts 目录下有 \'ttf\', \'afm\', \'pdfcorefonts\' 3个子目录。
paths = [cbook._get_data_path(\'fonts\', subdir)
for subdir in [\'ttf\', \'afm\', \'pdfcorefonts\']]
In [1]: import matplotlib.cbook as cbook
In [2]: paths = [cbook._get_data_path(\'fonts\', subdir) for subdir in [\'ttf\', \'afm\', \'pdfcorefonts\']]
In [3]: paths
Out[4]:
[WindowsPath(\'c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/ttf\'),
WindowsPath(\'c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/afm\'),
WindowsPath(\'c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts\')]
4.matplotlib如何生成字体列表?
FontManager 类是 matplotlib 管理字体的重要类,是一个单例类。 FontManager 实例在构造后会创建一个ttf 字体列表和一个 afm 字体列表,并会缓存他们的字体属性。
下面简单看看 ttflist 、 afmlist 列表的元素的属性。
In [1]: import matplotlib.font_manager as mf
In [2]: ttflist=mf.FontManager().ttflist
In [3]: vars(ttflist[0])
Out[3]:
{\'fname\': \'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSansMono-BoldOblique.ttf\',
\'name\': \'DejaVu Sans Mono\',
\'style\': \'oblique\',
\'variant\': \'normal\',
\'weight\': 700,
\'stretch\': \'normal\',
\'size\': \'scalable\'}
In [4]: len(ttflist)
Out[4]: 252
In [5]: afmlist=mf.FontManager().afmlist
In [6]: vars(afmlist[0])
Out[6]:
{\'fname\': \'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\afm\\pagko8a.afm\',
\'name\': \'ITC Avant Garde Gothic\',
\'style\': \'italic\',
\'variant\': \'normal\',
\'weight\': \'book\',
\'stretch\': \'normal\',
\'size\': \'scalable\'}
In [7]: len(afmlist)
Out[7]: 60
5.matplotlib的字体属性缓存在哪里?
前面了解到 matplotlib 会缓存字体属性那在什么位置呢?
根据源码可知,字体缓存的所在目录是 .matplotlib ,缓存文件是 fontlist-v330.json
(文件名与版本有关)。在某些老版本的 matplotlib 中字体缓存文件名是 fontList.cache 。
_fmcache = os.path.join(
mpl.get_cachedir(), \'fontlist-v{}.json\'.format(FontManager.__version__))
In [1]: import matplotlib
In [2]: matplotlib.get_cachedir()
Out[2]: \'C:\\Users\\Administrator\\.matplotlib\'
6. 怎么知道哪些字体是中文字体?
虽然在前面已经知道 matplotlib 会把系统字体和自带字体信息存放在 ttflist 和 afmlist
中,但是在这些字体信息中也不容易确定哪些是中文字体。
通过资料查找有3种方法:
查看Windows的 fonts 系统目录中显示的字体名称和文件名属性。 这种方法效率太低!
通过注册表项 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts] 查看字体名和字体文件名称映射。这种方法一些系统字体仍然看不到汉字名称。
根据第1种方法想到了去查字体文件的元数据,Python相关的库有两个: fonttools ,作者是老爹Guido的弟弟 Just van Rossum ; TTFQuery ,基于 fonttools 的TTF包,只能查看 TTF 文件而且最后更新日期是2012年。
TTFQery 项目地址 [ https://pypi.org/project/TTFQuery/
](https://pypi.org/project/TTFQuery/)
源码中有些小问题,源码不算复杂,直接修改。
import sys
from fontTools.ttLib import TTFont
from fontTools.ttLib.ttCollection import TTCollection
UNICODE_ENCODINGS = {0: \'Unicode 1.0 semantics\',
1: \'Unicode 1.1 semantics\',
2: \'Unicode 1.1 semantics\',
3: \'Unicode 2.0 and onwards semantics, Unicode BMP only (cmap subtable formats 0, 4, 6).\',
4: \'Unicode 2.0 and onwards semantics, Unicode full repertoire (cmap subtable formats 0, 4, 6, 10, 12).\',
5: \'Unicode Variation Sequences (cmap subtable format 14).\',
6: \'Unicode Variation Sequences (cmap subtable format 14).\'}
WINDOWS_ENCODINGS = {0: \'Symbol\',
1: \'Unicode BMP(UCS-2)\',
2: \'ShiftJIS\',
3: \'PRC\',
4: \'Big5\',
5: \'Wansung\',
6: \'Johab\',
7: \'Reserved\',
8: \'Reserved\',
9: \'Reserved\',
10: \'Unicode UCS-4\'}
WINDOWS_LANGUAGES = {1025: \'Arabic/Saudi Arabia\',
1026: \'Bulgarian/Bulgaria\',
1027: \'Catalan/Catalan\',
1028: \'Chinese/Taiwan\',
1029: \'Czech/Czech Republic\',
1030: \'Danish/Denmark\',
1031: \'German/Germany\',
1032: \'Greek/Greece\',
1033: \'English/United States\',
1034: \'Spanish (Traditional Sort)/Spain\',
1035: \'Finnish/Finland\',
1036: \'French/France\',
1037: \'Hebrew/Israel\',
1038: \'Hungarian/Hungary\',
1039: \'Icelandic/Iceland\',
1040: \'Italian/Italy\',
1041: \'Japanese/Japan\',
1042: \'Korean/Korea\',
1043: \'Dutch/Netherlands\',
1044: \'Norwegian (Bokmal)/Norway\',
1045: \'Polish/Poland\',
1046: \'Portuguese/Brazil\',
1047: \'Romansh/Switzerland\',
1048: \'Romanian/Romania\',
1049: \'Russian/Russia\',
1050: \'Croatian/Croatia\',
1051: \'Slovak/Slovakia\',
1052: \'Albanian/Albania\',
1053: \'Swedish/Sweden\',
1054: \'Thai/Thailand\',
1055: \'Turkish/Turkey\',
1056: \'Urdu/Islamic Republic of Pakistan\',
1057: \'Indonesian/Indonesia\',
1058: \'Ukrainian/Ukraine\',
1059: \'Belarusian/Belarus\',
1060: \'Slovenian/Slovenia\',
1061: \'Estonian/Estonia\',
1062: \'Latvian/Latvia\',
1063: \'Lithuanian/Lithuania\',
1064: \'Tajik (Cyrillic)/Tajikistan\',
1066: \'Vietnamese/Vietnam\',
1067: \'Armenian/Armenia\',
1068: \'Azeri (Latin)/Azerbaijan\',
1069: \'Basque/Basque\',
1070: \'Upper Sorbian/Germany\',
1071: \'Macedonian (FYROM)/Former Yugoslav Republic of Macedonia\',
1074: \'Setswana/South Africa\',
1076: \'isiXhosa/South Africa\',
1077: \'isiZulu/South Africa\',
1078: \'Afrikaans/South Africa\',
1079: \'Georgian/Georgia\',
1080: \'Faroese/Faroe Islands\',
1081: \'Hindi/India\',
1082: \'Maltese/Malta\',
1083: \'Sami (Northern)/Norway\',
1086: \'Malay/Malaysia\',
1087: \'Kazakh/Kazakhstan\',
1088: \'Kyrgyz/Kyrgyzstan\',
1089: \'Kiswahili/Kenya\',
1090: \'Turkmen/Turkmenistan\',
1091: \'Uzbek (Latin)/Uzbekistan\',
1092: \'Tatar/Russia\',
1093: \'Bengali/India\',
1094: \'Punjabi/India\',
1095: \'Gujarati/India\',
1096: \'Odia (formerly Oriya)/India\',
1097: \'Tamil/India\',
1098: \'Telugu/India\',
1099: \'Kannada/India\',
1100: \'Malayalam/India\',
1101: \'Assamese/India\',
1102: \'Marathi/India\',
1103: \'Sanskrit/India\',
1104: \'Mongolian (Cyrillic)/Mongolia\',
1105: \'Tibetan/PRC\',
1106: \'Welsh/United Kingdom\',
1107: \'Khmer/Cambodia\',
1108: \'Lao/Lao P.D.R.\',
1110: \'Galician/Galician\',
1111: \'Konkani/India\',
1114: \'Syriac/Syria\',
1115: \'Sinhala/Sri Lanka\',
1117: \'Inuktitut/Canada\',
1118: \'Amharic/Ethiopia\',
1121: \'Nepali/Nepal\',
1122: \'Frisian/Netherlands\',
1123: \'Pashto/Afghanistan\',
1124: \'Filipino/Philippines\',
1125: \'Divehi/Maldives\',
1128: \'Hausa (Latin)/Nigeria\',
1130: \'Yoruba/Nigeria\',
1131: \'Quechua/Bolivia\',
1132: \'Sesotho sa Leboa/South Africa\',
1133: \'Bashkir/Russia\',
1134: \'Luxembourgish/Luxembourg\',
1135: \'Greenlandic/Greenland\',
1136: \'Igbo/Nigeria\',
1144: \'Yi/PRC\',
1146: \'Mapudungun/Chile\',
1148: \'Mohawk/Mohawk\',
1150: \'Breton/France\',
1152: \'Uighur/PRC\',
1153: \'Maori/New Zealand\',
1154: \'Occitan/France\',
1155: \'Corsican/France\',
1156: \'Alsatian/France\',
1157: \'Yakut/Russia\',
1158: "K\'iche/Guatemala",
1159: \'Kinyarwanda/Rwanda\',
1160: \'Wolof/Senegal\',
1164: \'Dari/Afghanistan\',
2049: \'Arabic/Iraq\',
2052: "Chinese/People\'s Republic of China",
2055: \'German/Switzerland\',
2057: \'English/United Kingdom\',
2058: \'Spanish/Mexico\',
2060: \'French/Belgium\',
2064: \'Italian/Switzerland\',
2067: \'Dutch/Belgium\',
2068: \'Norwegian (Nynorsk)/Norway\',
2070: \'Portuguese/Portugal\',
2074: \'Serbian (Latin)/Serbia\',
2077: \'Sweden/Finland\',
2092: \'Azeri (Cyrillic)/Azerbaijan\',
2094: \'Lower Sorbian/Germany\',
2107: \'Sami (Northern)/Sweden\',
2108: \'Irish/Ireland\',
2110: \'Malay/Brunei Darussalam\',
2115: \'Uzbek (Cyrillic)/Uzbekistan\',
2117: \'Bengali/Bangladesh\',
2128: "Mongolian (Traditional)/People\'s Republic of China",
2141: \'Inuktitut (Latin)/Canada\',
2143: \'Tamazight (Latin)/Algeria\',
2155: \'Quechua/Ecuador\',
3073: \'Arabic/Egypt\',
3076: \'Chinese/Hong Kong S.A.R.\',
3079: \'German/Austria\',
3081: \'English/Australia\',
3082: \'Spanish (Modern Sort)/Spain\',
3084: \'French/Canada\',
3098: \'Serbian (Cyrillic)/Serbia\',
3131: \'Sami (Northern)/Finland\',
3179: \'Quechua/Peru\',
4097: \'Arabic/Libya\',
4100: \'Chinese/Singapore\',
4103: \'German/Luxembourg\',
4105: \'English/Canada\',
4106: \'Spanish/Guatemala\',
4108: \'French/Switzerland\',
4122: \'Croatian (Latin)/Bosnia and Herzegovina\',
4155: \'Sami (Lule)/Norway\',
5121: \'Arabic/Algeria\',
5124: \'Chinese/Macao S.A.R.\',
5127: \'German/Liechtenstein\',
5129: \'English/New Zealand\',
5130: \'Spanish/Costa Rica\',
5132: \'French/Luxembourg\',
5146: \'Bosnian (Latin)/Bosnia and Herzegovina\',
5179: \'Sami (Lule)/Sweden\',
6145: \'Arabic/Morocco\',
6153: \'English/Ireland\',
6154: \'Spanish/Panama\',
6156: \'French/Principality of Monaco\',
6170: \'Serbian (Latin)/Bosnia and Herzegovina\',
6203: \'Sami (Southern)/Norway\',
7169: \'Arabic/Tunisia\',
7177: \'English/South Africa\',
7178: \'Spanish/Dominican Republic\',
7194: \'Serbian (Cyrillic)/Bosnia and Herzegovina\',
7227: \'Sami (Southern)/Sweden\',
8193: \'Arabic/Oman\',
8201: \'English/Jamaica\',
8202: \'Spanish/Venezuela\',
8218: \'Bosnian (Cyrillic)/Bosnia and Herzegovina\',
8251: \'Sami (Skolt)/Finland\',
9217: \'Arabic/Yemen\',
9225: \'English/Caribbean\',
9226: \'Spanish/Colombia\',
9275: \'Sami (Inari)/Finland\',
10241: \'Arabic/Syria\',
10249: \'English/Belize\',
10250: \'Spanish/Peru\',
11265: \'Arabic/Jordan\',
11273: \'English/Trinidad and Tobago\',
11274: \'Spanish/Argentina\',
12289: \'Arabic/Lebanon\',
12297: \'English/Zimbabwe\',
12298: \'Spanish/Ecuador\',
13313: \'Arabic/Kuwait\',
13321: \'English/Republic of the Philippines\',
13322: \'Spanish/Chile\',
14337: \'Arabic/U.A.E.\',
14346: \'Spanish/Uruguay\',
15361: \'Arabic/Bahrain\',
15370: \'Spanish/Paraguay\',
16385: \'Arabic/Qatar\',
16393: \'English/India\',
16394: \'Spanish/Bolivia\',
17417: \'English/Malaysia\',
17418: \'Spanish/El Salvador\',
18441: \'English/Singapore\',
18442: \'Spanish/Honduras\',
19466: \'Spanish/Nicaragua\',
20490: \'Spanish/Puerto Rico\',
21514: \'Spanish/United States\'}
MACINTOSH_ENCODINGS = {0: \'Roman\',
1: \'Japanese\',
2: \'Chinese\',
3: \'Korean\',
4: \'Arabic\',
5: \'Hebrew\',
6: \'Greek\',
7: \'Russian\',
8: \'RSymbol\',
9: \'Devanagari\',
10: \'Gurmukhi\',
11: \'Gujarati\',
12: \'Oriya\',
13: \'Bengali\',
14: \'Tamil\',
15: \'Telugu\',
16: \'Kannada\',
17: \'Malayalam\',
18: \'Sinhalese\',
19: \'Burmese\',
20: \'Khmer\',
21: \'Thai\',
22: \'Laotian\',
23: \'Georgian\',
24: \'Armenian\',
25: \'Chinese\',
26: \'Tibetan\',
27: \'Mongolian\',
28: \'Geez\',
29: \'Slavic\',
30: \'Vietnamese\',
31: \'Sindhi\',
32: \'Uninterpreted\'}
MACINTOSH_LANGUAGES = {0: \'English\',
1: \'French\',
2: \'German\',
3: \'Italian\',
4: \'Dutch\',
5: \'Swedish\',
6: \'Spanish\',
7: \'Danish\',
8: \'Portuguese\',
9: \'Norwegian\',
10: \'Hebrew\',
11: \'Japanese\',
12: \'Arabic\',
13: \'Finnish\',
14: \'Inuktitut\',
15: \'Icelandic\',
16: \'Maltese\',
17: \'Turkish\',
18: \'Croatian\',
19: \'Chinese (Traditional)\',
20: \'Urdu\',
21: \'Hindi\',
22: \'Thai\',
23: \'Korean\',
24: \'Lithuanian\',
25: \'Polish\',
26: \'Hungarian\',
27: \'Estonian\',
28: \'Latvian\',
29: \'Sami\',
30: \'Faroese\',
31: \'Farsi/Persian\',
32: \'Russian\',
33: \'Chinese (Simplified)\',
34: \'Flemish\',
35: \'Irish Gaelic\',
36: \'Albanian\',
37: \'Romanian\',
38: \'Czech\',
39: \'Slovak\',
40: \'Slovenian\',
41: \'Yiddish\',
42: \'Serbian\',
43: \'Macedonian\',
44: \'Bulgarian\',
45: \'Ukrainian\',
46: \'Byelorussian\',
47: \'Uzbek\',
48: \'Kazakh\',
49: \'Azerbaijani (Cyrillic script)\',
50: \'Azerbaijani (Arabic script)\',
51: \'Armenian\',
52: \'Georgian\',
53: \'Moldavian\',
54: \'Kirghiz\',
55: \'Tajiki\',
56: \'Turkmen\',
57: \'Mongolian (Mongolian script)\',
58: \'Mongolian (Cyrillic script)\',
59: \'Pashto\',
60: \'Kurdish\',
61: \'Kashmiri\',
62: \'Sindhi\',
63: \'Tibetan\',
64: \'Nepali\',
65: \'Sanskrit\',
66: \'Marathi\',
67: \'Bengali\',
68: \'Assamese\',
69: \'Gujarati\',
70: \'Punjabi\',
71: \'Oriya\',
72: \'Malayalam\',
73: \'Kannada\',
74: \'Tamil\',
75: \'Telugu\',
76: \'Sinhalese\',
77: \'Burmese\',
78: \'Khmer\',
79: \'Lao\',
80: \'Vietnamese\',
81: \'Indonesian\',
82: \'Tagalong\',
83: \'Malay (Roman script)\',
84: \'Malay (Arabic script)\',
85: \'Amharic\',
86: \'Tigrinya\',
87: \'Galla\',
88: \'Somali\',
89: \'Swahili\',
90: \'Kinyarwanda/Ruanda\',
91: \'Rundi\',
92: \'Nyanja/Chewa\',
93: \'Malagasy\',
94: \'Esperanto\',
128: \'Welsh\',
129: \'Basque\',
130: \'Catalan\',
131: \'Latin\',
132: \'Quenchua\',
133: \'Guarani\',
134: \'Aymara\',
135: \'Tatar\',
136: \'Uighur\',
137: \'Dzongkha\',
138: \'Javanese (Roman script)\',
139: \'Sundanese (Roman script)\',
140: \'Galician\',
141: \'Afrikaans\',
142: \'Breton\',
144: \'Scottish Gaelic\',
145: \'Manx Gaelic\',
146: \'Irish Gaelic (with dot above)\',
147: \'Tongan\',
148: \'Greek (polytonic)\',
149: \'Greenlandic\',
150: \'Azerbaijani (Roman script)\'}
ISO_IDS = {
0: \'7-bit ASCII\',
1: \'ISO 10646\',
2: \'ISO 8859-1\'
}
CUSTOMS = {}
PLATFORMS = {0: {\'name\': \'Unicode\',
\'encodings\': UNICODE_ENCODINGS,
\'languages\': UNICODE_ENCODINGS},
1: {\'name\': \'Macintosh\',
\'encodings\': MACINTOSH_ENCODINGS,
\'languages\': MACINTOSH_LANGUAGES},
2: {\'name\': \'ISO [deprecated]\',
\'encodings\': ISO_IDS,
\'languages\': ISO_IDS},
3: {\'name\': \'Windows\',
\'encodings\': WINDOWS_ENCODINGS,
\'languages\': WINDOWS_LANGUAGES},
4: {\'name\': \'Custom\',
\'encodings\': CUSTOMS,
\'languages\': CUSTOMS}}
NAME_TABLE = {0: \'Copyright Notice\',
1: \'Font Family\',
2: \'SubFamily\',
3: \'Unique Font Identifier\',
4: \'Full Font Name\',
5: \'Version\',
6: \'PostScript Name\',
7: \'Trademark\',
8: \'Manufacturer Name\',
9: \'Designer\',
10: \'Description\',
11: \'Vendor URL\',
12: \'Designer URL\',
13: \'License Description\',
14: \'License Info URL\',
15: \'Reserved\',
16: \'Typographic Family\',
17: \'Typographic SubFamily\',
18: \'Compatible Full\',
19: \'Sample Text\',
20: \'PostScript CID findfont name\',
21: \'WWS Family Name\',
22: \'WWS SubFamily Name\',
23: \'Light Background Pallete\',
24: \'Dark Background Pallete\',
25: \'Variations PostScript Name Prefix\'}
ENCODINGS = {
"Roman": \'latin_1\'
}
def parse_meta(font):
"""The main meta parsing function. Thanks to Fonttools library."""
data = {}
for nti in font[\'name\'].names:
key = nti.nameID
platform_data = PLATFORMS[nti.platformID]
if platform_data[\'name\'] == \'Custom\':
encoding = {\'id\': 0, \'value\': \'Custom\'}
language = {\'id\': 0, \'value\': \'Custom\'}
else:
encoding = {\'id\': nti.platEncID,
\'value\': platform_data[\'encodings\'].get(nti.platEncID, "Unknown")}
language = {\'id\': nti.langID,
\'value\': platform_data[\'languages\'].get(nti.langID, "Unknown")}
name_str = nti.toStr()
field = NAME_TABLE.get(nti.nameID, False)
if not field:
if 26 <= nti.nameID <= 255:
field = \'Reserved [{}]\'.format(nti.nameID)
elif 256 <= nti.nameID:
field = \'Font Specific[{}]\'.format(nti.nameID)
data[key] = {"field": field,
"value": name_str,
"encoding": encoding,
"language": language
}
return data
def get_font_name(data, language=None):
language_name = data.get(4).get(\'language\').get(\'value\')
font_full_name = data.get(4).get(\'value\')
if language is None:
return font_full_name
else:
if language in language_name:
return font_full_name
if __name__ == \'__main__\':
from pathlib import Path
import matplotlib.font_manager as fm
ttflist=fm.FontManager().ttflist
for f in ttflist:
if Path(f.fname).suffix.lower()==\'.ttf\':
# 输出字体元数据中语言包含有中文的TTF字体
data = parse_meta(TTFont(f.fname))
out_ttf = get_font_name(data,\'Chinese\')
if out_ttf:
print(f.fname,f.name,out_ttf)
elif Path(f.fname).suffix.lower()==\'.ttc\':
# 输出所有TTC字体中包含的字体名称信息
ttc = TTCollection(f.fname)
for ttf in ttc:
ttc_data = parse_meta(ttf)
out_ttc = get_font_name(ttc_data,\'Chinese\')
if out_ttc:
print(f.fname,f.name,out_ttc)
ttc 文件很特殊,它是多个 ttf 文件集合,常用字体 宋体 、 微软雅黑 等在Windows10中都是 ttc
文件,而且奇怪的是很多语言信息不是中文的ttc字体也可以显示中文。
```python
