@@ -841,10 +841,16 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
841841
842842 if not found_symbol :
843843 if self .cm_fallback :
844- warn ("Substituting with a symbol from Computer Modern." ,
845- MathTextWarning )
846- return self .cm_fallback ._get_glyph (
847- fontname , 'it' , sym , fontsize )
844+ if isinstance (self .cm_fallback , BakomaFonts ):
845+ warn ("Substituting with a symbol from Computer Modern." ,
846+ MathTextWarning )
847+ if (fontname in ('it' , 'regular' ) and
848+ isinstance (self .cm_fallback , StixFonts )):
849+ return self .cm_fallback ._get_glyph (
850+ 'rm' , font_class , sym , fontsize )
851+ else :
852+ return self .cm_fallback ._get_glyph (
853+ fontname , 'it' , sym , fontsize )
848854 else :
849855 if fontname in ('it' , 'regular' ) and isinstance (self , StixFonts ):
850856 return self ._get_glyph ('rm' , font_class , sym , fontsize )
@@ -870,6 +876,56 @@ def get_sized_alternatives_for_symbol(self, fontname, sym):
870876 fontname , sym )
871877 return [(fontname , sym )]
872878
879+ class DejaVuFonts (UnicodeFonts ):
880+ use_cmex = False
881+
882+ def __init__ (self , * args , ** kwargs ):
883+ # This must come first so the backend's owner is set correctly
884+ if isinstance (self , DejaVuSerifFonts ):
885+ self .cm_fallback = StixFonts (* args , ** kwargs )
886+ else :
887+ self .cm_fallback = StixSansFonts (* args , ** kwargs )
888+ TruetypeFonts .__init__ (self , * args , ** kwargs )
889+ self .fontmap = {}
890+ # Include Stix sized alternatives for glyphs
891+ self ._fontmap .update ({
892+ 0 : 'STIXGeneral' ,
893+ 1 : 'STIXSizeOneSym' ,
894+ 2 : 'STIXSizeTwoSym' ,
895+ 3 : 'STIXSizeThreeSym' ,
896+ 4 : 'STIXSizeFourSym' ,
897+ 5 : 'STIXSizeFiveSym' })
898+ for key , name in six .iteritems (self ._fontmap ):
899+ fullpath = findfont (name )
900+ self .fontmap [key ] = fullpath
901+ self .fontmap [name ] = fullpath
902+
903+ class DejaVuSerifFonts (DejaVuFonts ):
904+ """
905+ A font handling class for the DejaVu Serif fonts
906+
907+ If a glyph is not found it will fallback to Stix Serif
908+ """
909+ _fontmap = { 'rm' : 'DejaVu Serif' ,
910+ 'it' : 'DejaVu Serif:italic' ,
911+ 'bf' : 'DejaVu Serif:weight=bold' ,
912+ 'sf' : 'DejaVu Sans' ,
913+ 'tt' : 'DejaVu Sans Mono' ,
914+ }
915+
916+ class DejaVuSansFonts (DejaVuFonts ):
917+ """
918+ A font handling class for the DejaVu Sans fonts
919+
920+ If a glyph is not found it will fallback to Stix Sans
921+ """
922+ _fontmap = { 'rm' : 'DejaVu Sans' ,
923+ 'it' : 'DejaVu Sans:italic' ,
924+ 'bf' : 'DejaVu Sans:weight=bold' ,
925+ 'sf' : 'DejaVu Sans' ,
926+ 'tt' : 'DejaVu Sans Mono' ,
927+ }
928+
873929class StixFonts (UnicodeFonts ):
874930 """
875931 A font handling class for the STIX fonts.
@@ -1178,46 +1234,54 @@ def get_underline_thickness(self, font, fontsize, dpi):
11781234SCRIPT_SPACE = {'cm' : 0.075 ,
11791235 'stix' : 0.10 ,
11801236 'stixsans' : 0.05 ,
1181- 'arevsans' : 0.05 }
1237+ 'dejavuserif' : 0.05 ,
1238+ 'dejavusans' : 0.05 }
11821239## Percentage of x-height that sub/superscripts drop below the baseline
11831240SUBDROP = {'cm' : 0.2 ,
11841241 'stix' : 0.4 ,
11851242 'stixsans' : 0.4 ,
1186- 'arevsans' : 0.4 }
1243+ 'dejavuserif' : 0.4 ,
1244+ 'dejavusans' : 0.4 }
11871245# Percentage of x-height that superscripts are raised from the baseline
11881246SUP1 = {'cm' : 0.45 ,
11891247 'stix' : 0.8 ,
11901248 'stixsans' : 0.8 ,
1191- 'arevsans' : 0.7 }
1249+ 'dejavuserif' : 0.7 ,
1250+ 'dejavusans' : 0.7 }
11921251# Percentage of x-height that subscripts drop below the baseline
11931252SUB1 = {'cm' : 0.2 ,
11941253 'stix' : 0.3 ,
11951254 'stixsans' : 0.3 ,
1196- 'arevsans' : 0.3 }
1255+ 'dejavuserif' : 0.3 ,
1256+ 'dejavusans' : 0.3 }
11971257# Percentage of x-height that subscripts drop below the baseline when a
11981258# superscript is present
11991259SUB2 = {'cm' : 0.3 ,
12001260 'stix' : 0.6 ,
12011261 'stixsans' : 0.5 ,
1202- 'arevsans' : 0.5 }
1262+ 'dejavuserif' : 0.5 ,
1263+ 'dejavusans' : 0.5 }
12031264# Percentage of x-height that sub/supercripts are offset relative to the
12041265# nucleus edge for non-slanted nuclei
12051266DELTA = {'cm' : 0.075 ,
12061267 'stix' : 0.05 ,
12071268 'stixsans' : 0.025 ,
1208- 'arevsans' : 0.025 }
1269+ 'dejavuserif' : 0.025 ,
1270+ 'dejavusans' : 0.025 }
12091271# Additional percentage of last character height above 2/3 of the x-height that
12101272# supercripts are offset relative to the subscript for slanted nuclei
12111273DELTASLANTED = {'cm' : 0.3 ,
12121274 'stix' : 0.3 ,
12131275 'stixsans' : 0.6 ,
1214- 'arevsans' : 0.2 }
1276+ 'dejavuserif' : 0.2 ,
1277+ 'dejavusans' : 0.2 }
12151278# Percentage of x-height that supercripts and subscripts are offset for
12161279# integrals
12171280DELTAINTEGRAL = {'cm' : 0.3 ,
12181281 'stix' : 0.3 ,
12191282 'stixsans' : 0.3 ,
1220- 'arevsans' : 0.3 }
1283+ 'dejavuserif' : 0.1 ,
1284+ 'dejavusans' : 0.1 }
12211285
12221286class MathTextWarning (Warning ):
12231287 pass
@@ -2676,19 +2740,6 @@ def is_slanted(self, nucleus):
26762740 return nucleus .is_slanted ()
26772741 return False
26782742
2679- def _get_fontset_name (self ):
2680- fs = rcParams ['mathtext.fontset' ]
2681- # If a custom fontset is used, check if it is Arev Sans, otherwise use
2682- # CM parameters.
2683- if fs == 'custom' :
2684- if (rcParams ['mathtext.rm' ] == 'sans' and
2685- rcParams ['font.sans-serif' ][0 ].lower () == 'Arev Sans' .lower ()):
2686- fs = 'arevsans'
2687- else :
2688- fs = 'cm'
2689-
2690- return fs
2691-
26922743 def subsuper (self , s , loc , toks ):
26932744 assert (len (toks )== 1 )
26942745
@@ -2811,7 +2862,9 @@ def subsuper(self, s, loc, toks):
28112862
28122863 # Handle regular sub/superscripts
28132864
2814- fs = self ._get_fontset_name ()
2865+ fs = rcParams ['mathtext.fontset' ]
2866+ if fs == 'custom' :
2867+ fs = 'dejavusans'
28152868
28162869 lc_height = last_char .height
28172870 lc_baseline = 0
@@ -3056,10 +3109,12 @@ class MathTextParser(object):
30563109 }
30573110
30583111 _font_type_mapping = {
3059- 'cm' : BakomaFonts ,
3060- 'stix' : StixFonts ,
3061- 'stixsans' : StixSansFonts ,
3062- 'custom' : UnicodeFonts
3112+ 'cm' : BakomaFonts ,
3113+ 'dejavuserif' : DejaVuSerifFonts ,
3114+ 'dejavusans' : DejaVuSansFonts ,
3115+ 'stix' : StixFonts ,
3116+ 'stixsans' : StixSansFonts ,
3117+ 'custom' : UnicodeFonts
30633118 }
30643119
30653120 def __init__ (self , output ):
@@ -3100,8 +3155,8 @@ def parse(self, s, dpi = 72, prop = None):
31003155 font_output = fontset_class (prop , backend )
31013156 else :
31023157 raise ValueError (
3103- "mathtext.fontset must be either 'cm', 'stix ', "
3104- "'stixsans', or 'custom'" )
3158+ "mathtext.fontset must be either 'cm', 'dejavuserif ', "
3159+ "'dejavusans', 'stix', ' stixsans', or 'custom'" )
31053160
31063161 fontsize = prop .get_size_in_points ()
31073162
0 commit comments