32
32
RendererBase )
33
33
from matplotlib .backends .backend_mixed import MixedModeRenderer
34
34
from matplotlib .figure import Figure
35
- from matplotlib .font_manager import findfont , get_font
35
+ from matplotlib .font_manager import (
36
+ findfont , get_font , fontManager as _fontManager
37
+ )
36
38
from matplotlib ._afm import AFM
37
39
from matplotlib .ft2font import (FIXED_WIDTH , ITALIC , LOAD_NO_SCALE ,
38
40
LOAD_NO_HINTING , KERNING_UNFITTED , FT2Font )
@@ -925,20 +927,28 @@ def fontName(self, fontprop):
925
927
"""
926
928
927
929
if isinstance (fontprop , str ):
928
- filename = fontprop
930
+ filenames = [ fontprop ]
929
931
elif mpl .rcParams ['pdf.use14corefonts' ]:
930
- filename = findfont (
931
- fontprop , fontext = 'afm' , directory = RendererPdf ._afm_font_dir )
932
+ filenames = _fontManager ._find_fonts_by_props (
933
+ fontprop , fontext = 'afm' , directory = RendererPdf ._afm_font_dir
934
+ )
932
935
else :
933
- filename = findfont (fontprop )
934
-
935
- Fx = self .fontNames .get (filename )
936
- if Fx is None :
937
- Fx = next (self ._internal_font_seq )
938
- self .fontNames [filename ] = Fx
939
- _log .debug ('Assigning font %s = %r' , Fx , filename )
940
-
941
- return Fx
936
+ filenames = _fontManager ._find_fonts_by_props (fontprop )
937
+ first_Fx = None
938
+ for fname in filenames :
939
+ Fx = self .fontNames .get (fname )
940
+ if not first_Fx :
941
+ first_Fx = Fx
942
+ if Fx is None :
943
+ Fx = next (self ._internal_font_seq )
944
+ self .fontNames [fname ] = Fx
945
+ _log .debug ('Assigning font %s = %r' , Fx , fname )
946
+ if not first_Fx :
947
+ first_Fx = Fx
948
+
949
+ # find_fontsprop's first value always adheres to
950
+ # findfont's value, so technically no behaviour change
951
+ return first_Fx
942
952
943
953
def dviFontName (self , dvifont ):
944
954
"""
@@ -1204,7 +1214,6 @@ def get_char_width(charcode):
1204
1214
width = font .load_char (
1205
1215
s , flags = LOAD_NO_SCALE | LOAD_NO_HINTING ).horiAdvance
1206
1216
return cvt (width )
1207
-
1208
1217
with warnings .catch_warnings ():
1209
1218
# Ignore 'Required glyph missing from current font' warning
1210
1219
# from ft2font: here we're just building the widths table, but
@@ -2389,22 +2398,27 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
2389
2398
# the regular text show command (TJ) with appropriate kerning between
2390
2399
# chunks, whereas multibyte characters use the XObject command (Do).
2391
2400
else :
2392
- # List of (start_x, [prev_kern, char, char, ...]), w/o zero kerns.
2401
+ # List of (ft_object, start_x, [prev_kern, char, char, ...]),
2402
+ # w/o zero kerns.
2393
2403
singlebyte_chunks = []
2394
- # List of (start_x, glyph_index).
2404
+ # List of (ft_object, start_x, glyph_index).
2395
2405
multibyte_glyphs = []
2396
2406
prev_was_multibyte = True
2407
+ prev_font = font
2397
2408
for item in _text_helpers .layout (
2398
2409
s , font , kern_mode = KERNING_UNFITTED ):
2399
2410
if _font_supports_glyph (fonttype , ord (item .char )):
2400
- if prev_was_multibyte :
2401
- singlebyte_chunks .append ((item .x , []))
2411
+ if prev_was_multibyte or item .ft_object != prev_font :
2412
+ singlebyte_chunks .append ((item .ft_object , item .x , []))
2413
+ prev_font = item .ft_object
2402
2414
if item .prev_kern :
2403
- singlebyte_chunks [- 1 ][1 ].append (item .prev_kern )
2404
- singlebyte_chunks [- 1 ][1 ].append (item .char )
2415
+ singlebyte_chunks [- 1 ][2 ].append (item .prev_kern )
2416
+ singlebyte_chunks [- 1 ][2 ].append (item .char )
2405
2417
prev_was_multibyte = False
2406
2418
else :
2407
- multibyte_glyphs .append ((item .x , item .glyph_idx ))
2419
+ multibyte_glyphs .append (
2420
+ (item .ft_object , item .x , item .glyph_idx )
2421
+ )
2408
2422
prev_was_multibyte = True
2409
2423
# Do the rotation and global translation as a single matrix
2410
2424
# concatenation up front
@@ -2414,10 +2428,12 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
2414
2428
- math .sin (a ), math .cos (a ),
2415
2429
x , y , Op .concat_matrix )
2416
2430
# Emit all the 1-byte characters in a BT/ET group.
2417
- self . file . output ( Op . begin_text ,
2418
- self .file .fontName ( prop ), fontsize , Op .selectfont )
2431
+
2432
+ self .file .output ( Op .begin_text )
2419
2433
prev_start_x = 0
2420
- for start_x , kerns_or_chars in singlebyte_chunks :
2434
+ for ft_object , start_x , kerns_or_chars in singlebyte_chunks :
2435
+ ft_name = self .file .fontName (ft_object .fname )
2436
+ self .file .output (ft_name , fontsize , Op .selectfont )
2421
2437
self ._setup_textpos (start_x , 0 , 0 , prev_start_x , 0 , 0 )
2422
2438
self .file .output (
2423
2439
# See pdf spec "Text space details" for the 1000/fontsize
@@ -2429,8 +2445,10 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
2429
2445
prev_start_x = start_x
2430
2446
self .file .output (Op .end_text )
2431
2447
# Then emit all the multibyte characters, one at a time.
2432
- for start_x , glyph_idx in multibyte_glyphs :
2433
- self ._draw_xobject_glyph (font , fontsize , glyph_idx , start_x , 0 )
2448
+ for ft_object , start_x , glyph_idx in multibyte_glyphs :
2449
+ self ._draw_xobject_glyph (
2450
+ ft_object , fontsize , glyph_idx , start_x , 0
2451
+ )
2434
2452
self .file .output (Op .grestore )
2435
2453
2436
2454
def _draw_xobject_glyph (self , font , fontsize , glyph_idx , x , y ):
0 commit comments