10000 Add a helper for directly output pdf streams. · matplotlib/matplotlib@1921fef · GitHub
[go: up one dir, main page]

Skip to content

Commit 1921fef

Browse files
committed
Add a helper for directly output pdf streams.
Also, such directly output streams don't need an explicitly set Length, as the stream outputter will fill in that entry itself. This is why e.g. the invalid entry for toUnicodeMapObject (where Length was set to unicode_cmap rather than len(unicode_cmap)) was not a problem: it was overwritten in endStream().
1 parent c072e3a commit 1921fef

File tree

1 file changed

+23
-37
lines changed

1 file changed

+23
-37
lines changed

lib/matplotlib/backends/backend_pdf.py

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,11 @@ def endStream(self):
849849
self.currentstream.end()
850850
self.currentstream = None
851851

852+
def outputStream(self, ref, data, *, extra=None):
853+
self.beginStream(ref.id, None, extra)
854+
self.currentstream.write(data)
855+
self.endStream()
856+
852857
def _write_annotations(self):
853858
for annotsObject, annotations in self._annotations:
854859
self.writeObject(annotsObject, annotations)
@@ -1053,13 +1058,10 @@ def createType1Descriptor(self, t1font, fontfile):
10531058

10541059
self.writeObject(fontdescObject, descriptor)
10551060

1056-
self.beginStream(fontfileObject.id, None,
1057-
{'Length1': len(t1font.parts[0]),
1058-
'Length2': len(t1font.parts[1]),
1059-
'Length3': 0})
1060-
self.currentstream.write(t1font.parts[0])
1061-
self.currentstream.write(t1font.parts[1])
1062-
self.endStream()
1061+
self.outputStream(fontfileObject, b"".join(t1font.parts[:2]),
1062+
extra={'Length1': len(t1font.parts[0]),
1063+
'Length2': len(t1font.parts[1]),
1064+
'Length3': 0})
10631065

10641066
return fontdescObject
10651067

@@ -1182,13 +1184,13 @@ def get_char_width(charcode):
11821184
charprocs = {}
11831185
for charname in sorted(rawcharprocs):
11841186
stream = rawcharprocs[charname]
1185-
charprocDict = {'Length': len(stream)}
1187+
charprocDict = {}
11861188
# The 2-byte characters are used as XObjects, so they
11871189
# need extra info in their dictionary
11881190
if charname in multi_byte_chars:
1189-
charprocDict['Type'] = Name('XObject')
1190-
charprocDict['Subtype'] = Name('Form')
1191-
charprocDict['BBox'] = bbox
1191+
charprocDict = {'Type': Name('XObject'),
1192+
'Subtype': Name('Form'),
1193+
'BBox': bbox}
11921194
# Each glyph includes bounding box information,
11931195
# but xpdf and ghostscript can't handle it in a
11941196
# Form XObject (they segfault!!!), so we remove it
@@ -1197,9 +1199,7 @@ def get_char_width(charcode):
11971199
# value.
11981200
stream = stream[stream.find(b"d1") + 2:]
11991201
charprocObject = self.reserveObject('charProc')
1200-
self.beginStream(charprocObject.id, None, charprocDict)
1201-
self.currentstream.write(stream)
1202-
self.endStream()
1202+
self.outputStream(charprocObject, stream, extra=charprocDict)
12031203

12041204
# Send the glyphs with ccode > 255 to the XObject dictionary,
12051205
# and the others to the font itself
@@ -1267,12 +1267,9 @@ def embedTTFType42(font, characters, descriptor):
12671267

12681268
# Make fontfile stream
12691269
descriptor['FontFile2'] = fontfileObject
1270-
self.beginStream(
1271-
fontfileObject.id,
1272-
self.reserveObject('length of font stream'),
1273-
{'Length1': fontdata.getbuffer().nbytes})
1274-
self.currentstream.write(fontdata.getvalue())
1275-
self.endStream()
1270+
self.outputStream(
1271+
fontfileObject, fontdata.getvalue(),
1272+
extra={'Length1': fontdata.getbuffer().nbytes})
12761273

12771274
# Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap
12781275
# at the same time
@@ -1331,10 +1328,9 @@ def embedTTFType42(font, characters, descriptor):
13311328
rawcharprocs = _get_pdf_charprocs(filename, glyph_ids)
13321329
for charname in sorted(rawcharprocs):
13331330
stream = rawcharprocs[charname]
1334-
charprocDict = {'Length': len(stream)}
1335-
charprocDict['Type'] = Name('XObject')
1336-
charprocDict['Subtype'] = Name('Form')
1337-
charprocDict['BBox'] = bbox
1331+
charprocDict = {'Type': Name('XObject'),
1332+
'Subtype': Name('Form'),
1333+
'BBox': bbox}
13381334
# Each glyph includes bounding box information,
13391335
# but xpdf and ghostscript can't handle it in a
13401336
# Form XObject (they segfault!!!), so we remove it
@@ -1343,27 +1339,17 @@ def embedTTFType42(font, characters, descriptor):
13431339
# value.
13441340
stream = stream[stream.find(b"d1") + 2:]
13451341
charprocObject = self.reserveObject('charProc')
1346-
self.beginStream(charprocObject.id, None, charprocDict)
1347-
self.currentstream.write(stream)
1348-
self.endStream()
1342+
self.outputStream(charprocObject, stream, extra=charprocDict)
13491343

13501344
name = self._get_xobject_glyph_name(filename, charname)
13511345
self.multi_byte_charprocs[name] = charprocObject
13521346

13531347
# CIDToGIDMap stream
13541348
cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be")
1355-
self.beginStream(cidToGidMapObject.id,
1356-
None,
1357-
{'Length': len(cid_to_gid_map)})
1358-
self.currentstream.write(cid_to_gid_map)
1359-
self.endStream()
1349+
self.outputStream(cidToGidMapObject, cid_to_gid_map)
13601350

13611351
# ToUnicode CMap
1362-
self.beginStream(toUnicodeMapObject.id,
1363-
None,
1364-
{'Length': unicode_cmap})
1365-
self.currentstream.write(unicode_cmap)
1366-
self.endStream()
1352+
self.outputStream(toUnicodeMapObject, unicode_cmap)
13671353

13681354
descriptor['MaxWidth'] = max_width
13691355

0 commit comments

Comments
 (0)
0