34
34
from collections import Iterable
35
35
from functools import lru_cache
36
36
import json
37
+ import logging
37
38
import os
38
39
from pathlib import Path
39
40
import subprocess
40
41
import sys
41
42
from threading import Timer
42
43
import warnings
43
- import logging
44
44
45
45
from matplotlib import afm , cbook , ft2font , rcParams , get_cachedir
46
46
from matplotlib .fontconfig_pattern import (
130
130
]
131
131
132
132
if not USE_FONTCONFIG and sys .platform != 'win32' :
133
- home = os .environ .get ('HOME' )
134
- if home is not None :
135
- # user fonts on OSX
136
- path = os .path .join (home , 'Library' , 'Fonts' )
137
- OSXFontDirectories .append (path )
138
- path = os .path .join (home , '.fonts' )
139
- X11FontDirectories .append (path )
133
+ OSXFontDirectories .append (str (Path .home () / "Library/Fonts" ))
134
+ X11FontDirectories .append (str (Path .home () / ".fonts" ))
140
135
141
136
142
137
def get_fontext_synonyms (fontext ):
@@ -161,26 +156,20 @@ def list_fonts(directory, extensions):
161
156
162
157
163
158
def win32FontDirectory ():
164
- """
159
+ r """
165
160
Return the user-specified font directory for Win32. This is
166
161
looked up from the registry key::
167
162
168
- \\ \\ HKEY_CURRENT_USER\\ Software\\ Microsoft\\ Windows\\ CurrentVersion\\ Explorer\\ Shell Folders\ \ Fonts
163
+ \\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Fonts
169
164
170
165
If the key is not found, $WINDIR/Fonts will be returned.
171
166
"""
172
167
import winreg
173
168
try :
174
- user = winreg .OpenKey (winreg .HKEY_CURRENT_USER , MSFolders )
175
- try :
169
+ with winreg .OpenKey (winreg .HKEY_CURRENT_USER , MSFolders ) as user :
176
170
return winreg .QueryValueEx (user , 'Fonts' )[0 ]
177
- except OSError :
178
- pass # Fall through to default
179
- finally :
180
- winreg .CloseKey (user )
181
171
except OSError :
182
- pass # Fall through to default
183
- return os .path .join (os .environ ['WINDIR' ], 'Fonts' )
172
+ return os .path .join (os .environ ['WINDIR' ], 'Fonts' )
184
173
185
174
186
175
def win32InstalledFonts (directory = None , fontext = 'ttf' ):
@@ -198,33 +187,23 @@ def win32InstalledFonts(directory=None, fontext='ttf'):
198
187
199
188
fontext = get_fontext_synonyms (fontext )
200
189
201
- key , items = None , set ()
190
+ items = set ()
202
191
for fontdir in MSFontDirectories :
203
192
try :
204
- local = winreg .OpenKey (winreg .HKEY_LOCAL_MACHINE , fontdir )
205
- except OSError :
206
- continue
207
- if not local :
208
- return list_fonts (directory , fontext )
209
- try :
210
- for j in range (winreg .QueryInfoKey (local )[1 ]):
211
- try :
193
+ with winreg .OpenKey (winreg .HKEY_LOCAL_MACHINE , fontdir ) as local :
194
+ for j in range (winreg .QueryInfoKey (local )[1 ]):
212
195
key , direc , tp = winreg .EnumValue (local , j )
213
196
if not isinstance (direc , str ):
214
197
continue
215
198
# Work around for https://bugs.python.org/issue25778, which
216
199
# is fixed in Py>=3.6.1.
217
200
direc = direc .split ("\0 " , 1 )[0 ]
218
- if not os .path .dirname (direc ):
219
- direc = os .path .join (directory , direc )
220
- direc = os .path .abspath (direc ).lower ()
221
- if os .path .splitext (direc )[1 ][1 :] in fontext :
222
- items .add (direc )
223
- except (EnvironmentError , MemoryError , WindowsError ):
224
- continue
225
- return list (items )
226
- finally :
227
- winreg .CloseKey (local )
201
+ path = Path (directory , direc ).resolve ()
202
+ if path .suffix .lower () in fontext :
203
+ items .add (str (path ))
204
+ return list (items )
205
+ except (OSError , MemoryError ):
206
+ continue
228
207
return None
229
208
230
209
@@ -261,7 +240,7 @@ def get_fontconfig_fonts(fontext='ttf'):
261
240
"""
262
241
fontext = get_fontext_synonyms (fontext )
263
242
return [fname for fname in _call_fc_list ()
264
- if os . path . splitext (fname )[ 1 ] [1 :] in fontext ]
243
+ if Path (fname ). suffix [1 :] in fontext ]
265
244
266
245
267
246
def findSystemFonts (fontpaths = None , fontext = 'ttf' ):
@@ -277,31 +256,21 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
277
256
278
257
if fontpaths is None :
279
258
if sys .platform == 'win32' :
280
- fontdir = win32FontDirectory ()
281
-
282
- fontpaths = [fontdir ]
259
+ fontpaths = [win32FontDirectory ()]
283
260
# now get all installed fonts directly...
284
- for f in win32InstalledFonts (fontdir ):
285
- base , ext = os .path .splitext (f )
286
- if len (ext )> 1 and ext [1 :].lower () in fontexts :
287
- fontfiles .add (f )
261
+ fontfiles .update (win32InstalledFonts (fontext = fontext ))
288
262
else :
289
263
fontpaths = X11FontDirectories
264
+ fontfiles .update (get_fontconfig_fonts (fontext ))
290
265
# check for OS X & load its fonts if present
291
266
if sys .platform == 'darwin' :
292
- for f in OSXInstalledFonts (fontext = fontext ):
293
- fontfiles .add (f )
294
-
295
- for f in get_fontconfig_fonts (fontext ):
296
- fontfiles .add (f )
267
+ fontfiles .update (OSXInstalledFonts (fontext = fontext ))
297
268
298
269
elif isinstance (fontpaths , str ):
299
270
fontpaths = [fontpaths ]
300
271
301
272
for path in fontpaths :
302
- files = list_fonts (path , fontexts )
303
- for fname in files :
304
- fontfiles .add (os .path .abspath (fname ))
273
+ fontfiles .update (map (os .path .abspath , list_fonts (path , fontexts )))
305
274
306
275
return [fname for fname in fontfiles if os .path .exists (fname )]
307
276
@@ -1225,16 +1194,12 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
1225
1194
else :
1226
1195
fontlist = self .ttflist
1227
1196
1228
- if directory is not None :
1229
- directory = os .path .normcase (directory )
1230
-
1231
1197
best_score = 1e64
1232
1198
best_font = None
1233
1199
1234
1200
for font in fontlist :
1235
1201
if (directory is not None and
1236
- os .path .commonprefix ([os .path .normcase (font .fname ),
1237
- directory ]) != directory ):
1202
+ Path (directory ) not in Path (font .fname ).parents ):
1238
1203
continue
1239
1204
# Matching family should have highest priority, so it is multiplied
1240
1205
# by 10.0
0 commit comments