19
19
platforms, so if a font is installed, it is much more likely to be
20
20
found.
21
21
"""
22
- from __future__ import absolute_import , division , print_function
23
-
24
- import six
25
22
26
23
"""
27
24
KNOWN ISSUES
34
31
- setWeights function needs improvement
35
32
- 'light' is an invalid weight value, remove it.
36
33
- update_fonts not implemented
37
-
38
- Authors : John Hunter <[email protected] >
39
-
40
- Michael Droettboom <[email protected] >
41
- Copyright : John Hunter (2004,2005), Paul Barrett (2004,2005)
42
- License : matplotlib license (PSF compatible)
43
- The font directory code is from ttfquery,
44
- see license/LICENSE_TTFQUERY.
45
34
"""
46
35
47
36
from collections import Iterable
@@ -180,22 +169,17 @@ def win32FontDirectory():
180
169
181
170
If the key is not found, $WINDIR/Fonts will be returned.
182
171
"""
172
+ import winreg
183
173
try :
184
- from six .moves import winreg
185
- except ImportError :
186
- pass # Fall through to default
187
- else :
174
+ user = winreg .OpenKey (winreg .HKEY_CURRENT_USER , MSFolders )
188
175
try :
189
- user = winreg .OpenKey (winreg .HKEY_CURRENT_USER , MSFolders )
190
- try :
191
- try :
192
- return winreg .QueryValueEx (user , 'Fonts' )[0 ]
193
- except OSError :
194
- pass # Fall through to default
195
- finally :
196
- winreg .CloseKey (user )
176
+ return winreg .QueryValueEx (user , 'Fonts' )[0 ]
197
177
except OSError :
198
178
pass # Fall through to default
179
+ finally :
180
+ winreg .CloseKey (user )
181
+ except OSError :
182
+ pass # Fall through to default
199
183
return os .path .join (os .environ ['WINDIR' ], 'Fonts' )
200
184
201
185
@@ -207,7 +191,8 @@ def win32InstalledFonts(directory=None, fontext='ttf'):
207
191
'afm'.
208
192
"""
209
193
210
- from six .moves import winreg
194
+ import winreg
195
+
211
196
if directory is None :
212
197
directory = win32FontDirectory ()
213
198
@@ -225,7 +210,7 @@ def win32InstalledFonts(directory=None, fontext='ttf'):
225
210
for j in range (winreg .QueryInfoKey (local )[1 ]):
226
211
try :
227
212
key , direc , tp = winreg .EnumValue (local , j )
228
- if not isinstance (direc , six . string_types ):
213
+ if not isinstance (direc , str ):
229
214
continue
230
215
# Work around for https://bugs.python.org/issue25778, which
231
216
# is fixed in Py>=3.6.1.
@@ -275,19 +260,12 @@ def _call_fc_list():
275
260
'This may take a moment.' ))
276
261
timer .start ()
277
262
try :
278
- out = subprocess .check_output ([str ( 'fc-list' ) , '--format=%{file}\\ n' ])
263
+ out = subprocess .check_output (['fc-list' , '--format=%{file}\\ n' ])
279
264
except (OSError , subprocess .CalledProcessError ):
280
265
return []
281
266
finally :
282
267
timer .cancel ()
283
- fnames = []
284
- for fname in out .split (b'\n ' ):
285
- try :
286
- fname = six .text_type (fname , sys .getfilesystemencoding ())
287
- except UnicodeDecodeError :
288
- continue
289
- fnames .append (fname )
290
- return fnames
268
+ return [os .fsdecode (fname ) for fname in out .split (b'\n ' )]
291
269
292
270
293
271
def get_fontconfig_fonts (fontext = 'ttf' ):
@@ -329,7 +307,7 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
329
307
for f in get_fontconfig_fonts (fontext ):
330
308
fontfiles .add (f )
331
309
332
- elif isinstance (fontpaths , six . string_types ):
310
+ elif isinstance (fontpaths , str ):
333
311
fontpaths = [fontpaths ]
334
312
335
313
for path in fontpaths :
@@ -340,24 +318,6 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
340
318
return [fname for fname in fontfiles if os .path .exists (fname )]
341
319
342
320
343
- @cbook .deprecated ("2.1" )
344
- def weight_as_number (weight ):
345
- """
346
- Return the weight property as a numeric value. String values
347
- are converted to their corresponding numeric value.
348
- """
349
- if isinstance (weight , six .string_types ):
350
- try :
351
- weight = weight_dict [weight .lower ()]
352
- except KeyError :
353
- weight = 400
354
- elif weight in range (100 , 1000 , 100 ):
355
- pass
356
- else :
357
- raise ValueError ('weight not a valid integer' )
358
- return weight
359
-
360
-
361
321
class FontEntry (object ):
362
322
"""
363
323
A class for storing Font properties. It is used when populating
@@ -497,9 +457,9 @@ def afmFontProperty(fontpath, font):
497
457
498
458
# Styles are: italic, oblique, and normal (default)
499
459
500
- if font .get_angle () != 0 or name . lower (). find ( 'italic' ) >= 0 :
460
+ if font .get_angle () != 0 or 'italic' in name . lower () :
501
461
style = 'italic'
502
- elif name . lower (). find ( 'oblique' ) >= 0 :
462
+ elif 'oblique' in name . lower () :
503
463
style = 'oblique'
504
464
else :
505
465
style = 'normal'
@@ -520,12 +480,11 @@ def afmFontProperty(fontpath, font):
520
480
# and ultra-expanded.
521
481
# Relative stretches are: wider, narrower
522
482
# Child value is: inherit
523
- if fontname .find ('narrow' ) >= 0 or fontname .find ('condensed' ) >= 0 or \
524
- fontname .find ('cond' ) >= 0 :
525
- stretch = 'condensed'
526
- elif fontname .find ('demi cond' ) >= 0 :
483
+ if 'demi cond' in fontname :
527
484
stretch = 'semi-condensed'
528
- elif fontname .find ('wide' ) >= 0 or fontname .find ('expanded' ) >= 0 :
485
+ elif 'narrow' in fontname or 'cond' in fontname :
486
+ stretch = 'condensed'
487
+ elif 'wide' in fontname or 'expanded' in fontname :
529
488
stretch = 'expanded'
530
489
else :
531
490
stretch = 'normal'
@@ -587,7 +546,7 @@ def createFontList(fontfiles, fontext='ttf'):
587
546
except UnicodeError :
588
547
_log .info ("Cannot handle unicode filenames" )
589
548
continue
590
- except IOError :
549
+ except OSError :
591
550
_log .info ("IO error - cannot open font file %s" , fpath )
592
551
continue
593
552
try :
@@ -665,7 +624,7 @@ def __init__(self,
665
624
weight = None ,
666
625
stretch = None ,
667
626
size = None ,
668
- fname = None , # if this is set, it's a hardcoded filename to use
627
+ fname = None , # if set, it's a hardcoded filename to use
669
628
_init = None # used only by copy()
670
629
):
671
630
self ._family = _normalize_font_family (rcParams ['font.family' ])
@@ -681,7 +640,7 @@ def __init__(self,
681
640
self .__dict__ .update (_init .__dict__ )
682
641
return
683
642
684
- if isinstance (family , six . string_types ):
643
+ if isinstance (family , str ):
685
644
# Treat family as a fontconfig pattern if it is the only
686
645
# parameter provided.
687
646
if (style is None and
@@ -731,23 +690,20 @@ def get_family(self):
731
690
732
691
def get_name (self ):
733
692
"""
734
- Return the name of the font that best matches the font
735
- properties.
693
+ Return the name of the font that best matches the font properties.
736
694
"""
737
695
return get_font (findfont (self )).family_name
738
696
739
697
def get_style (self ):
740
698
"""
741
- Return the font style. Values are: 'normal', 'italic' or
742
- 'oblique'.
699
+ Return the font style. Values are: 'normal', 'italic' or 'oblique'.
743
700
"""
744
701
return self ._slant
745
702
get_slant = get_style
746
703
747
704
def get_variant (self ):
748
705
"""
749
- Return the font variant. Values are: 'normal' or
750
- 'small-caps'.
706
+ Return the font variant. Values are: 'normal' or 'small-caps'.
751
707
"""
752
708
return self ._variant
753
709
@@ -812,8 +768,7 @@ def set_family(self, family):
812
768
813
769
def set_style (self , style ):
814
770
"""
815
- Set the font style. Values are: 'normal', 'italic' or
816
- 'oblique'.
771
+ Set the font style. Values are: 'normal', 'italic' or 'oblique'.
817
772
"""
818
773
if style is None :
819
774
style = rcParams ['font.style' ]
@@ -911,7 +866,7 @@ def set_fontconfig_pattern(self, pattern):
911
866
support for it to be enabled. We are merely borrowing its
912
867
pattern syntax for use here.
913
868
"""
914
- for key , val in six . iteritems ( self ._parse_fontconfig_pattern (pattern )):
869
+ for key , val in self ._parse_fontconfig_pattern (pattern ). items ( ):
915
870
if type (val ) == list :
916
871
getattr (self , "set_" + key )(val [0 ])
917
872
else :
@@ -922,22 +877,6 @@ def copy(self):
922
877
return FontProperties (_init = self )
923
878
924
879
925
- @cbook .deprecated ("2.1" )
926
- def ttfdict_to_fnames (d ):
927
- """
928
- flatten a ttfdict to all the filenames it contains
929
- """
930
- fnames = []
931
- for named in six .itervalues (d ):
932
- for styled in six .itervalues (named ):
933
- for variantd in six .itervalues (styled ):
934
- for weightd in six .itervalues (variantd ):
935
- for stretchd in six .itervalues (weightd ):
936
- for fname in six .itervalues (stretchd ):
937
- fnames .append (fname )
938
- return fnames
939
-
940
-
941
880
class JSONEncoder (json .JSONEncoder ):
942
881
def default (self , o ):
943
882
if isinstance (o , FontManager ):
@@ -971,9 +910,10 @@ def json_dump(data, filename):
971
910
with open (filename , 'w' ) as fh :
972
911
try :
973
912
json .dump (data , fh , cls = JSONEncoder , indent = 2 )
974
- except IOError as e :
913
+ except OSError as e :
975
914
warnings .warn ('Could not save font_manager cache ' , e )
976
915
916
+
977
917
def json_load (filename ):
978
918
"""Loads a data structure as JSON from the named file.
979
919
Handles FontManager and its fields."""
@@ -983,10 +923,8 @@ def json_load(filename):
983
923
984
924
985
925
def _normalize_font_family (family ):
986
- if isinstance (family , six .string_types ):
987
- family = [six .text_type (family )]
988
- elif isinstance (family , Iterable ):
989
- family = [six .text_type (f ) for f in family ]
926
+ if isinstance (family , str ):
927
+ family = [family ]
990
928
return family
991
929
992
930
@@ -1205,14 +1143,14 @@ def score_weight(self, weight1, weight2):
1205
1143
The result is 0.0 if both weight1 and weight 2 are given as strings
1206
1144
and have the same value.
1207
1145
1208
- Otherwise, the result is the absolute value of the difference between the
1209
- CSS numeric values of *weight1* and *weight2*, normalized
1210
- between 0.05 and 1.0.
1146
+ Otherwise, the result is the absolute value of the difference between
1147
+ the CSS numeric values of *weight1* and *weight2*, normalized between
1148
+ 0.05 and 1.0.
1211
1149
"""
1212
1150
1213
- # exact match of the weight names ( e.g. weight1 == weight2 == "regular")
1214
- if (isinstance (weight1 , six . string_types ) and
1215
- isinstance (weight2 , six . string_types ) and
1151
+ # exact match of the weight names, e.g. weight1 == weight2 == "regular"
1152
+ if (isinstance (weight1 , str ) and
1153
+ isinstance (weight2 , str ) and
1216
1154
weight1 == weight2 ):
1217
1155
return 0.0
1218
1156
try :
@@ -1399,26 +1337,22 @@ def fc_match(pattern, fontext):
1399
1337
stdout = subprocess .PIPE ,
1400
1338
stderr = subprocess .PIPE )
1401
1339
output = pipe .communicate ()[0 ]
1402
- except ( OSError , IOError ) :
1340
+ except OSError :
1403
1341
return None
1404
1342
1405
1343
# The bulk of the output from fc-list is ascii, so we keep the
1406
1344
# result in bytes and parse it as bytes, until we extract the
1407
1345
# filename, which is in sys.filesystemencoding().
1408
1346
if pipe .returncode == 0 :
1409
- for fname in output .split (b'\n ' ):
1410
- try :
1411
- fname = six .text_type (fname , sys .getfilesystemencoding ())
1412
- except UnicodeDecodeError :
1413
- continue
1347
+ for fname in map (os .fsdecode , output .split (b'\n ' )):
1414
1348
if os .path .splitext (fname )[1 ][1 :] in fontexts :
1415
1349
return fname
1416
1350
return None
1417
1351
1418
1352
_fc_match_cache = {}
1419
1353
1420
1354
def findfont (prop , fontext = 'ttf' ):
1421
- if not isinstance (prop , six . string_types ):
1355
+ if not isinstance (prop , str ):
1422
1356
prop = prop .get_fontconfig_pattern ()
1423
1357
cached = _fc_match_cache .get (prop )
1424
1358
if cached is not None :
0 commit comments