Skip to content

Commit 9a9dc05

Browse files
committed
Define CharSet and FirstChar/LastChar
In Type-1 font subsets.
1 parent 7dd6af5 commit 9a9dc05

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

lib/matplotlib/backends/backend_pdf.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import sys
2020
import time
2121
import types
22+
import typing as T
2223
import warnings
2324
import zlib
2425

@@ -989,24 +990,12 @@ def _embedTeXFont(self, fontinfo):
989990
_log.debug('Embedding TeX font %s - fontinfo=%s',
990991
fontinfo.dvifont.texname, fontinfo.__dict__)
991992

992-
# Widths
993-
widthsObject = self.reserveObject('font widths')
994-
tfm = fontinfo.dvifont._tfm
995-
# convert from TeX's 12.20 representation to 1/1000 text space units.
996-
widths = [(1000 * metrics.tex_width) >> 20
997-
if (metrics := tfm.get_metrics(char)) else 0
998-
for char in range(max(tfm._glyph_metrics, default=-1) + 1)]
999-
self.writeObject(widthsObject, widths)
1000-
1001993
# Font dictionary
1002994
fontdictObject = self.reserveObject('font dictionary')
1003-
fontdict = {
995+
fontdict: dict[str, T.Any] = {
1004996
'Type': Name('Font'),
1005997
'Subtype': Name('Type1'),
1006-
'FirstChar': 0,
1007-
'LastChar': len(widths) - 1,
1008-
'Widths': widthsObject,
1009-
}
998+
}
1010999

10111000
# Encoding (if needed)
10121001
if fontinfo.encodingfile is not None:
@@ -1035,7 +1024,8 @@ def _embedTeXFont(self, fontinfo):
10351024
chars = self._character_tracker.used[fontinfo.dvifont.fname]
10361025
t1font = t1font.subset(chars)
10371026
fontdict['BaseFont'] = Name(t1font.prop['FontName'])
1038-
1027+
fc = fontdict['FirstChar'] = min(t1font.prop['Encoding'].keys(), default=0)
1028+
lc = fontdict['LastChar'] = max(t1font.prop['Encoding'].keys(), default=255)
10391029
# Font descriptors may be shared between differently encoded
10401030
# Type-1 fonts, so only create a new descriptor if there is no
10411031
# existing descriptor for this font.
@@ -1047,7 +1037,15 @@ def _embedTeXFont(self, fontinfo):
10471037
self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
10481038
fontdict['FontDescriptor'] = fontdesc
10491039

1040+
# Use TeX Font Metrics file to get glyph widths (TeX uses its 12.20 fixed point
1041+
# representation and we want 1/1000 text space units)
1042+
tfm = fontinfo.dvifont._tfm
1043+
widths = [(1000 * metrics.tex_width) >> 20
1044+
if (metrics := tfm.get_metrics(char)) else 0
1045+
for char in range(fc, lc + 1)]
1046+
fontdict['Widths'] = (widthsObject := self.reserveObject('glyph widths')),
10501047
self.writeObject(fontdictObject, fontdict)
1048+
self.writeObject(widthsObject, widths)
10511049
return fontdictObject
10521050

10531051
def createType1Descriptor(self, t1font, fontfile):
@@ -1087,6 +1085,14 @@ def createType1Descriptor(self, t1font, fontfile):
10871085

10881086
ft2font = get_font(fontfile)
10891087

1088+
encoding = t1font.prop['Encoding']
1089+
charset = ''.join(
1090+
sorted(
1091+
f'/{c}' for c in encoding.values()
1092+
if c != '.notdef'
1093+
)
1094+
)
1095+
10901096
descriptor = {
10911097
'Type': Name('FontDescriptor'),
10921098
'FontName': Name(t1font.prop['FontName']),
@@ -1100,6 +1106,7 @@ def createType1Descriptor(self, t1font, fontfile):
11001106
'FontFile': fontfileObject,
11011107
'FontFamily': t1font.prop['FamilyName'],
11021108
'StemV': 50, # TODO
1109+
'CharSet': charset,
11031110
# (see also revision 3874; but not all TeX distros have AFM files!)
11041111
# 'FontWeight': a number where 400 = Regular, 700 = Bold
11051112
}

0 commit comments

Comments
 (0)