Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 119934a

Browse files
committed
Separate the handling of dvi fonts in the pdf backend
Don't mix filenames and dvi font names as keys of the same dict.
1 parent 2e19a61 commit 119934a

1 file changed

Lines changed: 53 additions & 38 deletions

File tree

lib/matplotlib/backends/backend_pdf.py

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)