@@ -491,11 +491,10 @@ def __init__(self, filename, metadata=None):
491491 self .infoDict = {k : v for (k , v ) in self .infoDict .items ()
492492 if v is not None }
493493
494- # fontNames maps filenames/dvi names to internal font names;
495- # dvi font names have an entry in dviFontInfo
496- self .fontNames = {}
494+ self .fontNames = {} # maps filenames to internal font names
497495 self .nextFont = 1 # next free internal font name
498- self .dviFontInfo = {} # information on dvi fonts
496+ self .dviFontInfo = {} # maps dvi font names to embedding information
497+ self .texFontMap = None # maps TeX font names to PostScript fonts
499498 # differently encoded Type-1 fonts may share the same descriptor
500499 self .type1Descriptors = {}
501500 self .used_characters = {}
@@ -638,11 +637,11 @@ def endStream(self):
638637 def fontName (self , fontprop ):
639638 """
640639 Select a font based on fontprop and return a name suitable for
641- Op.selectfont. If fontprop is a string or bytestring , it will
642- be interpreted as the filename or dvi name of the font.
640+ Op.selectfont. If fontprop is a string, it will be interpreted
641+ as the filename of the font.
643642 """
644643
645- if isinstance (fontprop , ( str , bytes ) ):
644+ if isinstance (fontprop , six . string_types ):
646645 filename = fontprop
647646 elif rcParams ['pdf.use14corefonts' ]:
648647 filename = findfont (
@@ -664,18 +663,55 @@ def fontName(self, fontprop):
664663
665664 return Fx
666665
666+ def dviFontName (self , dvifont ):
667+ """
668+ Given a dvi font object, return a name suitable for Op.selectfont.
669+ This registers the font information in self.dviFontInfo if not yet
670+ registered.
671+ """
672+
673+ dvi_info = self .dviFontInfo .get (dvifont .texname )
674+ if dvi_info is not None :
675+ return dvi_info .pdfname
676+
677+ # lazy-load texFontMap, it takes a while to parse
678+ # and usetex is a relatively rare use case
679+ if self .texFontMap is None :
680+ self .texFontMap = \
681+ dviread .PsfontsMap (dviread .find_tex_file ('pdftex.map' ))
682+
683+ psfont = self .texFontMap [dvifont .texname ]
684+ if psfont .filename is None :
685+ raise ValueError (
686+ ("No usable font file found for {0} (TeX: {1}). "
687+ "The font may lack a Type-1 version." )
688+ .format (psfont .psname , dvifont .texname ))
689+
690+ pdfname = Name ('F%d' % self .nextFont )
691+ self .nextFont += 1
692+ matplotlib .verbose .report (
693+ 'Assigning font {0} = {1} (dvi)' .format (pdfname , dvifont .texname ),
694+ 'debug' )
695+ self .dviFontInfo [dvifont .texname ] = Bunch (
696+ dvifont = dvifont ,
697+ pdfname = pdfname ,
698+ fontfile = psfont .filename ,
699+ basefont = psfont .psname ,
700+ encodingfile = psfont .encoding ,
701+ effects = psfont .effects )
702+ return pdfname
703+
667704 def writeFonts (self ):
668705 fonts = {}
706+ for dviname , info in sorted (self .dviFontInfo .items ()):
707+ Fx = info .pdfname
708+ matplotlib .verbose .report ('Embedding Type-1 font %s from dvi'
709+ % dviname , 'debug' )
710+ fonts [Fx ] = self .embedTeXFont (info )
669711 for filename in sorted (self .fontNames ):
670712 Fx = self .fontNames [filename ]
671713 matplotlib .verbose .report ('Embedding font %s' % filename , 'debug' )
672- if filename in self .dviFontInfo :
673- # a Type 1 font from a dvi file;
674- # the filename is really the TeX name
675- matplotlib .verbose .report ('Writing Type-1 font' , 'debug' )
676- fonts [Fx ] = self .embedTeXFont (filename ,
677- self .dviFontInfo [filename ])
678- elif filename .endswith ('.afm' ):
714+ if filename .endswith ('.afm' ):
679715 # from pdf.use14corefonts
680716 matplotlib .verbose .report ('Writing AFM font' , 'debug' )
681717 fonts [Fx ] = self ._write_afm_font (filename )
@@ -700,9 +736,9 @@ def _write_afm_font(self, filename):
700736 self .writeObject (fontdictObject , fontdict )
701737 return fontdictObject
702738
703- def embedTeXFont (self , texname , fontinfo ):
739+ def embedTeXFont (self , fontinfo ):
704740 msg = ('Embedding TeX font {0} - fontinfo={1}'
705- .format (texname , fontinfo .__dict__ ))
741+ .format (fontinfo . dvifont . texname , fontinfo .__dict__ ))
706742 matplotlib .verbose .report (msg , 'debug' )
707743
708744 # Widths
@@ -1572,7 +1608,6 @@ def __init__(self, file, image_dpi, height, width):
15721608 self .gc = self .new_gc ()
15731609 self .mathtext_parser = MathTextParser ("Pdf" )
15741610 self .image_dpi = image_dpi
1575- self .tex_font_map = None
15761611
15771612 def finalize (self ):
15781613 self .file .output (* self .gc .finalize ())
@@ -1598,12 +1633,6 @@ def check_gc(self, gc, fillcolor=None):
15981633 gc ._fillcolor = orig_fill
15991634 gc ._effective_alphas = orig_alphas
16001635
1601- def tex_font_mapping (self , texfont ):
1602- if self .tex_font_map is None :
1603- self .tex_font_map = \
1604- dviread .PsfontsMap (dviread .find_tex_file ('pdftex.map' ))
1605- return self .tex_font_map [texfont ]
1606-
16071636 def track_characters (self , font , s ):
16081637 """Keeps track of which characters are required from
16091638 each font."""
@@ -1896,21 +1925,7 @@ def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
18961925 oldfont , seq = None , []
18971926 for x1 , y1 , dvifont , glyph , width in page .text :
18981927 if dvifont != oldfont :
1899- pdfname = self .file .fontName (dvifont .texname )
1900- if dvifont .texname not in self .file .dviFontInfo :
1901- psfont = self .tex_font_mapping (dvifont .texname )
1902- if psfont .filename is None :
1903- self .file .broken = True
1904- raise ValueError (
1905- ("No usable font file found for %s (%s). "
1906- "The font may lack a Type-1 version." )
1907- % (psfont .psname , dvifont .texname ))
1908- self .file .dviFontInfo [dvifont .texname ] = Bunch (
1909- fontfile = psfont .filename ,
1910- basefont = psfont .psname ,
1911- encodingfile = psfont .encoding ,
1912- effects = psfont .effects ,
1913- dvifont = dvifont )
1928+ pdfname = self .file .dviFontName (dvifont )
19141929 seq += [['font' , pdfname , dvifont .size ]]
19151930 oldfont = dvifont
19161931 # We need to convert the glyph numbers to bytes, and the easiest
0 commit comments