@@ -493,7 +493,8 @@ def __init__(self, filename, metadata=None):
493493
494494 self .fontNames = {} # maps filenames to internal font names
495495 self .nextFont = 1 # next free internal font name
496- 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
497498 # differently encoded Type-1 fonts may share the same descriptor
498499 self .type1Descriptors = {}
499500 self .used_characters = {}
@@ -637,10 +638,10 @@ def fontName(self, fontprop):
637638 """
638639 Select a font based on fontprop and return a name suitable for
639640 Op.selectfont. If fontprop is a string, it will be interpreted
640- as the filename (or dvi name) of the font.
641+ as the filename of the font.
641642 """
642643
643- if is_string_like (fontprop ):
644+ if isinstance (fontprop , six . string_types ):
644645 filename = fontprop
645646 elif rcParams ['pdf.use14corefonts' ]:
646647 filename = findfont (
@@ -662,21 +663,62 @@ def fontName(self, fontprop):
662663
663664 return Fx
664665
666+ @property
667+ def texFontMap (self ):
668+ # lazy-load texFontMap, it takes a while to parse
669+ # and usetex is a relatively rare use case
670+ if self ._texFontMap is None :
671+ self ._texFontMap = dviread .PsfontsMap (
672+ dviread .find_tex_file ('pdftex.map' ))
673+
674+ return self ._texFontMap
675+
676+ def dviFontName (self , dvifont ):
677+ """
678+ Given a dvi font object, return a name suitable for Op.selectfont.
679+ This registers the font information in self.dviFontInfo if not yet
680+ registered.
681+ """
682+
683+ dvi_info = self .dviFontInfo .get (dvifont .texname )
684+ if dvi_info is not None :
685+ return dvi_info .pdfname
686+
687+ psfont = self .texFontMap [dvifont .texname ]
688+ if psfont .filename is None :
689+ raise ValueError (
690+ ("No usable font file found for {0} (TeX: {1}). "
691+ "The font may lack a Type-1 version." )
692+ .format (psfont .psname , dvifont .texname ))
693+
694+ pdfname = Name ('F%d' % self .nextFont )
695+ self .nextFont += 1
696+ matplotlib .verbose .report (
697+ 'Assigning font {0} = {1} (dvi)' .format (pdfname , dvifont .texname ),
698+ 'debug' )
699+ self .dviFontInfo [dvifont .texname ] = Bunch (
700+ dvifont = dvifont ,
701+ pdfname = pdfname ,
702+ fontfile = psfont .filename ,
703+ basefont = psfont .psname ,
704+ encodingfile = psfont .encoding ,
705+ effects = psfont .effects )
706+ return pdfname
707+
665708 def writeFonts (self ):
666709 fonts = {}
710+ for dviname , info in sorted (self .dviFontInfo .items ()):
711+ Fx = info .pdfname
712+ matplotlib .verbose .report ('Embedding Type-1 font %s from dvi'
713+ % dviname , 'debug' )
714+ fonts [Fx ] = self ._embedTeXFont (info )
667715 for filename in sorted (self .fontNames ):
668716 Fx = self .fontNames [filename ]
669717 matplotlib .verbose .report ('Embedding font %s' % filename , 'debug' )
670718 if filename .endswith ('.afm' ):
671719 # from pdf.use14corefonts
672720 matplotlib .verbose .report ('Writing AFM font' , 'debug' )
673721 fonts [Fx ] = self ._write_afm_font (filename )
674- elif filename in self .dviFontInfo :
675- # a Type 1 font from a dvi file;
676- # the filename is really the TeX name
677- matplotlib .verbose .report ('Writing Type-1 font' , 'debug' )
678- fonts [Fx ] = self .embedTeXFont (filename ,
679- self .dviFontInfo [filename ])
680722 else :
681723 # a normal TrueType font
682724 matplotlib .verbose .report ('Writing TrueType font' , 'debug' )
@@ -698,9 +740,9 @@ def _write_afm_font(self, filename):
698740 self .writeObject (fontdictObject , fontdict )
699741 return fontdictObject
700742
701- def embedTeXFont (self , texname , fontinfo ):
702- msg = ('Embedding TeX font ' + texname + ' - fontinfo=' +
703- repr ( fontinfo .__dict__ ))
743+ def _embedTeXFont (self , fontinfo ):
744+ msg = ('Embedding TeX font {0} - fontinfo={1}'
745+ . format ( fontinfo . dvifont . texname , fontinfo .__dict__ ))
704746 matplotlib .verbose .report (msg , 'debug' )
705747
706748 # Widths
@@ -1571,7 +1613,6 @@ def __init__(self, file, image_dpi, height, width):
15711613 self .gc = self .new_gc ()
15721614 self .mathtext_parser = MathTextParser ("Pdf" )
15731615 self .image_dpi = image_dpi
1574- self .tex_font_map = None
15751616
15761617 def finalize (self ):
15771618 self .file .output (* self .gc .finalize ())
@@ -1597,12 +1638,6 @@ def check_gc(self, gc, fillcolor=None):
15971638 gc ._fillcolor = orig_fill
15981639 gc ._effective_alphas = orig_alphas
15991640
1600- def tex_font_mapping (self , texfont ):
1601- if self .tex_font_map is None :
1602- self .tex_font_map = \
1603- dviread .PsfontsMap (dviread .find_tex_file ('pdftex.map' ))
1604- return self .tex_font_map [texfont ]
1605-
16061641 def track_characters (self , font , s ):
16071642 """Keeps track of which characters are required from
16081643 each font."""
@@ -1895,21 +1930,7 @@ def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
18951930 oldfont , seq = None , []
18961931 for x1 , y1 , dvifont , glyph , width in page .text :
18971932 if dvifont != oldfont :
1898- pdfname = self .file .fontName (dvifont .texname )
1899- if dvifont .texname not in self .file .dviFontInfo :
1900- psfont = self .tex_font_mapping (dvifont .texname )
1901- if psfont .filename is None :
1902- self .file .broken = True
1903- raise ValueError (
1904- ("No usable font file found for %s (%s). "
1905- "The font may lack a Type-1 version." )
1906- % (psfont .psname , dvifont .texname ))
1907- self .file .dviFontInfo [dvifont .texname ] = Bunch (
1908- fontfile = psfont .filename ,
1909- basefont = psfont .psname ,
1910- encodingfile = psfont .encoding ,
1911- effects = psfont .effects ,
1912- dvifont = dvifont )
1933+ pdfname = self .file .dviFontName (dvifont )
19131934 seq += [['font' , pdfname , dvifont .size ]]
19141935 oldfont = dvifont
19151936 # We need to convert the glyph numbers to bytes, and the easiest
0 commit comments