@@ -198,11 +198,63 @@ def validate_fontsize(s):
198198 except ValueError :
199199 raise ValueError ('not a valid font size' )
200200
201- def validate_mathtext_font (s ):
202- s = eval (s )
203- if type (s ) in (list , tuple ) and len (s ) == 3 :
204- return s
205- raise ValueError ('Mathtext font specifier must be a 3-tuple of (family, weight, style)' )
201+ class FontPropertiesProxy :
202+ # In order to build a FontProperties object, various rcParams must
203+ # already be known in order to set default values. That means a
204+ # FontProperties object can not be created from a config file,
205+ # since it depends on other values in the same config file. This
206+ # proxy class is used as a temporary storage area for the settings
207+ # in the config file, and the full FontProperties class is created
208+ # only when the class is first used. It is defined here rather than
209+ # in font_manager.py to avoid a cyclical import.
210+ def __init__ (self ,
211+ family = None ,
212+ style = None ,
213+ variant = None ,
214+ weight = None ,
215+ stretch = None ,
216+ size = None ,
217+ fname = None , # if this is set, it's a hardcoded filename to use
218+ ):
219+ self .__family = family
220+ self .__style = style
221+ self .__variant = variant
222+ self .__weight = weight
223+ self .__stretch = stretch
224+ self .__size = size
225+ self .__fname = fname
226+
227+ self .__child = None
228+
229+ def __get_child (self ):
230+ if self .__child is None :
231+ from font_manager import FontProperties
232+ self .__child = FontProperties (
233+ family = self .__family ,
234+ style = self .__style ,
235+ variant = self .__variant ,
236+ weight = self .__weight ,
237+ stretch = self .__stretch ,
238+ size = self .__size ,
239+ fname = self .__fname )
240+ return self .__child
241+
242+ def __getattr__ (self , attr ):
243+ return getattr (self .__get_child (), attr )
244+
245+ def validate_font_properties (s ):
246+ parsed = False
247+ try :
248+ prop = eval (u'FontProperties(%s)' % s ,
249+ {}, {'FontProperties' : FontPropertiesProxy })
250+ except :
251+ pass
252+ else :
253+ parsed = isinstance (prop , FontPropertiesProxy )
254+ if not parsed :
255+ raise ValueError (
256+ 'Mathtext font specifier must be a set of arguments to the FontProperty constructor.' )
257+ return prop
206258
207259validate_markup = ValidateInStrings (
208260 'markup' ,
@@ -366,12 +418,12 @@ def __call__(self, s):
366418 'text.fontsize' : ['medium' , validate_fontsize ],
367419 'text.markup' : ['plain' , validate_markup ],
368420
369- 'mathtext.cal' : [( 'cursive' , 'normal' , 'normal' ), validate_mathtext_font ],
370- 'mathtext.rm' : [( 'serif' , 'normal' , 'normal' ), validate_mathtext_font ],
371- 'mathtext.tt' : [( 'monospace' , 'normal' , 'normal' ), validate_mathtext_font ],
372- 'mathtext.it' : [( 'serif' , 'normal' , 'italic' ), validate_mathtext_font ],
373- 'mathtext.bf' : [( 'serif' , 'bold' , 'normal' ), validate_mathtext_font ],
374- 'mathtext.sf' : [( 'sans-serif' , 'normal' , 'normal' ), validate_mathtext_font ],
421+ 'mathtext.cal' : [FontPropertiesProxy ([ 'cursive' ] ), validate_font_properties ],
422+ 'mathtext.rm' : [FontPropertiesProxy ([ 'serif' ] ), validate_font_properties ],
423+ 'mathtext.tt' : [FontPropertiesProxy ([ 'monospace' ] ), validate_font_properties ],
424+ 'mathtext.it' : [FontPropertiesProxy ([ 'serif' ], style = 'oblique' ), validate_font_properties ],
425+ 'mathtext.bf' : [FontPropertiesProxy ([ 'serif' ], weight = 'bold' ), validate_font_properties ],
426+ 'mathtext.sf' : [FontPropertiesProxy ([ 'sans-serif' ] ), validate_font_properties ],
375427 'mathtext.use_cm' : [True , validate_bool ],
376428 'mathtext.fallback_to_cm' : [True , validate_bool ],
377429
0 commit comments