Skip to content

Commit 4f2d77d

Browse files
authored
Merge pull request #6977 from jkseppan/dvi-ascii
Handle dvi font names as ASCII bytestrings
2 parents 45895e6 + 6fbced0 commit 4f2d77d

File tree

6 files changed

+306
-204
lines changed

6 files changed

+306
-204
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Changes to PDF backend methods
2+
``````````````````````````````
3+
4+
The methods `embedTeXFont` and `tex_font_mapping` of
5+
`matplotlib.backend_pdf.PdfFile` have been removed.
6+
It is unlikely that external users would have called
7+
these methods, which are related to the font system
8+
internal to the PDF backend.

doc/api/dviread.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@ dviread
88
.. automodule:: matplotlib.dviread
99
:members:
1010
:undoc-members:
11+
:exclude-members: Dvi
12+
:show-inheritance:
13+
14+
.. autoclass:: matplotlib.dviread.Dvi
15+
:members: __iter__,close
1116
:show-inheritance:

lib/matplotlib/backends/backend_pdf.py

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

Comments
 (0)