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

Skip to content

Commit 1f4c70f

Browse files
committed
use_tex in pdf backend: don't use AFM files,
which are not there in some TeX distros svn path=/trunk/matplotlib/; revision=3901
1 parent 0ae61bf commit 1f4c70f

2 files changed

Lines changed: 36 additions & 98 deletions

File tree

lib/matplotlib/backends/backend_pdf.py

Lines changed: 26 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -500,70 +500,15 @@ def embedType1(self, filename, fontinfo):
500500
finally:
501501
fh.close()
502502

503-
fh = open(fontinfo.afmfile, 'rb')
504-
matplotlib.verbose.report(
505-
'Reading metrics from ' + fontinfo.afmfile, 'debug')
506-
try:
507-
afmdata = AFM(fh)
508-
finally:
509-
fh.close()
510-
511503
font = FT2Font(filename)
512-
font.attach_file(fontinfo.afmfile)
513504

514505
widthsObject, fontdescObject, fontdictObject, fontfileObject = \
515506
[ self.reserveObject(n) for n in
516507
('font widths', 'font descriptor',
517508
'font dictionary', 'font file') ]
518509

519-
_, _, fullname, familyname, weight, italic_angle, fixed_pitch, \
520-
ul_position, ul_thickness = font.get_ps_font_info()
521-
522-
if fontinfo.encodingfile is not None:
523-
enc = dviread.Encoding(fontinfo.encodingfile)
524-
widths = []
525-
for ch in enc:
526-
try:
527-
widths.append(afmdata.get_width_from_char_name(ch))
528-
except KeyError:
529-
matplotlib.verbose.report(
530-
'No width for %s in %s' % (ch, fullname), 'debug-annoying')
531-
widths.append(0)
532-
533-
differencesArray = [ Name(ch) for ch in enc ]
534-
differencesArray = [ 0 ] + differencesArray
535-
firstchar = 0
536-
lastchar = len(differencesArray) - 2
537-
else:
538-
widths = [ None for i in range(256) ]
539-
for ch in range(256):
540-
try:
541-
widths[ch] = afmdata.get_width_char(ch, isord=True)
542-
except KeyError:
543-
pass
544-
not_None = [ch for ch in range(256)
545-
if widths[ch] is not None]
546-
firstchar = not_None[0]
547-
lastchar = not_None[-1]
548-
widths = widths[firstchar:lastchar+1]
549-
for i,w in enumerate(widths):
550-
if w is None: widths[i] = 0
551-
552-
differencesArray = [ ]
553-
need_idx = True
554-
for ch in range(firstchar, lastchar+1):
555-
try:
556-
name = afmdata.get_name_char(ch, isord=True)
557-
if need_idx:
558-
differencesArray.append(ch)
559-
need_idx = False
560-
differencesArray.append(Name(name))
561-
except KeyError:
562-
matplotlib.verbose.report(
563-
'No name for glyph %d in %s' % (ch, fullname),
564-
'debug-annoying')
565-
need_idx = True
566-
510+
firstchar = 0
511+
lastchar = len(fontinfo.widths) - 1
567512

568513
fontdict = {
569514
'Type': Name('Font'),
@@ -575,15 +520,22 @@ def embedType1(self, filename, fontinfo):
575520
'FontDescriptor': fontdescObject,
576521
}
577522

578-
fontdict.update({
579-
'Encoding': { 'Type': Name('Encoding'),
580-
'Differences': differencesArray },
581-
})
523+
if fontinfo.encodingfile is not None:
524+
enc = dviread.Encoding(fontinfo.encodingfile)
525+
differencesArray = [ Name(ch) for ch in enc ]
526+
differencesArray = [ 0 ] + differencesArray
527+
fontdict.update({
528+
'Encoding': { 'Type': Name('Encoding'),
529+
'Differences': differencesArray },
530+
})
531+
532+
_, _, fullname, familyname, weight, italic_angle, fixed_pitch, \
533+
ul_position, ul_thickness = font.get_ps_font_info()
582534

583535
flags = 0
584536
if fixed_pitch: flags |= 1 << 0 # fixed width
585537
if 0: flags |= 1 << 1 # TODO: serif
586-
if 1: flags |= 1 << 2 # TODO: symbolic
538+
if 1: flags |= 1 << 2 # TODO: symbolic (most TeX fonts are)
587539
else: flags |= 1 << 5 # non-symbolic
588540
if italic_angle: flags |= 1 << 6 # italic
589541
if 0: flags |= 1 << 16 # TODO: all caps
@@ -598,33 +550,17 @@ def embedType1(self, filename, fontinfo):
598550
'ItalicAngle': italic_angle,
599551
'Ascent': font.ascender,
600552
'Descent': font.descender,
601-
'CapHeight': 1000, # default guess if missing from AFM file
602-
'XHeight': afmdata.get_xheight(),
553+
'CapHeight': 1000, # TODO: find this out
554+
'XHeight': 500, # TODO: this one too
603555
'FontFile': fontfileObject,
604556
'FontFamily': familyname,
557+
'StemV': 50, # TODO
558+
# (see also revision 3874; but not all TeX distros have AFM files!)
605559
#'FontWeight': a number where 400 = Regular, 700 = Bold
606560
}
607-
try:
608-
descriptor['CapHeight'] = afmdata.get_capheight()
609-
except KeyError:
610-
pass
611-
612-
# StemV is obligatory in PDF font descriptors but optional in
613-
# AFM files. The collection of AFM files in my TeX Live 2007
614-
# collection has values ranging from 22 to 219, with both
615-
# median and mode 50, so if the AFM file is silent, I'm
616-
# guessing 50. -JKS
617-
StemV = afmdata.get_vertical_stem_width()
618-
if StemV is None: StemV = 50
619-
descriptor['StemV'] = StemV
620-
621-
# StemH is entirely optional:
622-
StemH = afmdata.get_horizontal_stem_width()
623-
if StemH is not None:
624-
descriptor['StemH'] = StemH
625561

626562
self.writeObject(fontdictObject, fontdict)
627-
self.writeObject(widthsObject, widths)
563+
self.writeObject(widthsObject, fontinfo.widths)
628564
self.writeObject(fontdescObject, descriptor)
629565

630566
t1font = type1font.Type1Font(filename)
@@ -1470,16 +1406,13 @@ def mytrans(x1, y1, x=x, y=y, a=angle / 180.0 * pi):
14701406
oldfont, seq = None, []
14711407
for x1, y1, dvifont, glyph, width in page.text:
14721408
if dvifont != oldfont:
1473-
fontinfo = self.tex_font_mapping(dvifont.texname)
1474-
pdfname = self.file.fontName(fontinfo.filename)
1475-
if not fontinfo.afm:
1476-
matplotlib.verbose.report(
1477-
'RendererPdf.draw_tex: No AFM file found for %s (%s)' \
1478-
% (dvifont.texname, fontinfo.filename),
1479-
'helpful')
1480-
self.file.fontInfo[pdfname] = Bunch(
1481-
encodingfile=fontinfo.encoding,
1482-
afmfile=fontinfo.afm)
1409+
psfont = self.tex_font_mapping(dvifont.texname)
1410+
pdfname = self.file.fontName(psfont.filename)
1411+
if self.file.fontInfo.get(pdfname, None) is None:
1412+
self.file.fontInfo[pdfname] = Bunch(
1413+
encodingfile=psfont.encoding,
1414+
widths=dvifont.widths,
1415+
dvifont=dvifont)
14831416
seq += [['font', pdfname, dvifont.size]]
14841417
oldfont = dvifont
14851418
seq += [['text', x1, y1, [chr(glyph)], x1+width]]

lib/matplotlib/dviread.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def _output(self):
8484
e = 0 # zero depth
8585
else: # glyph
8686
x,y,font,g,w = elt
87-
h = _mul2012(font._scale, font._tfm.height[g])
87+
h = _mul2012(font._scale, font._tfm.height[g])
8888
e = _mul2012(font._scale, font._tfm.depth[g])
8989
minx = min(minx, x)
9090
miny = min(miny, y - h)
@@ -380,19 +380,21 @@ def _post_post(self):
380380

381381
class DviFont(object):
382382
"""
383-
Object that holds a font's texname and size and supports comparison.
383+
Object that holds a font's texname and size, supports comparison,
384+
and knows the widths of glyphs in the same units as the AFM file.
384385
There are also internal attributes (for use by dviread.py) that
385386
are _not_ used for comparison.
386387
387388
The size is in Adobe points (converted from TeX points).
388389
"""
389-
__slots__ = ('texname', 'size', '_scale', '_vf', '_tfm')
390+
__slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
390391

391392
def __init__(self, scale, tfm, texname, vf):
392393
self._scale, self._tfm, self.texname, self._vf = \
393394
scale, tfm, texname, vf
394-
# TODO: would it make more sense to have the size in dpi units?
395395
self.size = scale * (72.0 / (72.27 * 2**16))
396+
self.widths = [ (1000*tfm.width.get(char, 0)) >> 20
397+
for char in range(0, max(tfm.width)) ]
396398

397399
def __eq__(self, other):
398400
return self.__class__ == other.__class__ and \
@@ -402,6 +404,10 @@ def __ne__(self, other):
402404
return not self.__eq__(other)
403405

404406
def _width_of(self, char):
407+
"""
408+
Width of char in dvi units. For internal use by dviread.py.
409+
"""
410+
405411
width = self._tfm.width.get(char, None)
406412
if width is not None:
407413
return _mul2012(width, self._scale)
@@ -598,7 +604,6 @@ def __getitem__(self, texname):
598604
fn, enc = result.filename, result.encoding
599605
if fn is not None and not fn.startswith('/'):
600606
result.filename = find_tex_file(fn)
601-
result.afm = find_tex_file(fn[:-4] + '.afm')
602607
if enc is not None and not enc.startswith('/'):
603608
result.encoding = find_tex_file(result.encoding)
604609
return result

0 commit comments

Comments
 (0)