From 980fbee43bc4a16f196e7d3e5efe9e3798c24259 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 19 Dec 2017 11:27:51 -0800 Subject: [PATCH 1/2] Add missing decode() in svg font embedding path. Otherwise, rcParams["svg.fonttype"] = "svgfont"; title("foo"); savefig("/tmp/test.svg") fails (on Py3) with File ".../backend_svg.py", line 86, in escape_attrib s = s.replace("&", "&") TypeError: a bytes-like object is required, not 'str' The encoding of entry 1, 0, 0, 4 in the sfnt table is macroman (https://www.freetype.org/freetype2/docs/reference/ft2-truetype_tables.html#TT_MAC_ID_XXX). Note that after the fix is applied, the resulting svg file still appears to be unopenable by inkscape, so the fix is not complete, but hopefully a step in the correct direction. --- lib/matplotlib/backends/backend_svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index bf09351655a0..4140c60c1587 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -506,7 +506,7 @@ def _write_svgfonts(self): font = get_font(font_fname) font.set_size(72, 72) sfnt = font.get_sfnt() - writer.start('font', id=sfnt[(1, 0, 0, 4)]) + writer.start('font', id=sfnt[1, 0, 0, 4].decode("macroman")) writer.element( 'font-face', attrib={ From dfc856afa485072a8e294be54a7eb6799b403cb3 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 19 Dec 2017 14:23:49 -0800 Subject: [PATCH 2/2] Style changes. --- lib/matplotlib/backends/backend_pdf.py | 4 ++-- lib/matplotlib/backends/backend_ps.py | 5 ++--- lib/matplotlib/backends/backend_svg.py | 2 +- lib/matplotlib/font_manager.py | 4 ++-- lib/matplotlib/textpath.py | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index f84b3d539afd..9a3e80bb32e4 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -1146,10 +1146,10 @@ def embedTTFType42(font, characters, descriptor): # You are lost in a maze of TrueType tables, all different... sfnt = font.get_sfnt() try: - ps_name = sfnt[(1, 0, 0, 6)].decode('macroman') # Macintosh scheme + ps_name = sfnt[1, 0, 0, 6].decode('mac_roman') # Macintosh scheme except KeyError: # Microsoft scheme: - ps_name = sfnt[(3, 1, 0x0409, 6)].decode('utf-16be') + ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be') # (see freetype/ttnameid.h) ps_name = ps_name.encode('ascii', 'replace') ps_name = Name(ps_name) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index a2bb35d3e5bc..3c0303864948 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -696,10 +696,9 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): self.set_color(*gc.get_rgb()) sfnt = font.get_sfnt() try: - ps_name = sfnt[(1,0,0,6)].decode('macroman') + ps_name = sfnt[1, 0, 0, 6].decode('mac_roman') except KeyError: - ps_name = sfnt[(3,1,0x0409,6)].decode( - 'utf-16be') + ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be') ps_name = ps_name.encode('ascii', 'replace').decode('ascii') self.set_font(ps_name, prop.get_size_in_points()) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 4140c60c1587..21030bc6e136 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -506,7 +506,7 @@ def _write_svgfonts(self): font = get_font(font_fname) font.set_size(72, 72) sfnt = font.get_sfnt() - writer.start('font', id=sfnt[1, 0, 0, 4].decode("macroman")) + writer.start('font', id=sfnt[1, 0, 0, 4].decode("mac_roman")) writer.element( 'font-face', attrib={ diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index bb0a056d284e..ed4d4740afb0 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -411,11 +411,11 @@ def ttfFontProperty(font): sfnt2 = sfnt.get((1,0,0,2)) sfnt4 = sfnt.get((1,0,0,4)) if sfnt2: - sfnt2 = sfnt2.decode('macroman').lower() + sfnt2 = sfnt2.decode('mac_roman').lower() else: sfnt2 = '' if sfnt4: - sfnt4 = sfnt4.decode('macroman').lower() + sfnt4 = sfnt4.decode('mac_roman').lower() else: sfnt4 = '' if sfnt4.find('oblique') >= 0: diff --git a/lib/matplotlib/textpath.py b/lib/matplotlib/textpath.py index dfedd2c2b88b..a02d83e93779 100644 --- a/lib/matplotlib/textpath.py +++ b/lib/matplotlib/textpath.py @@ -67,9 +67,9 @@ def _get_char_id(self, font, ccode): """ sfnt = font.get_sfnt() try: - ps_name = sfnt[(1, 0, 0, 6)].decode('macroman') + ps_name = sfnt[1, 0, 0, 6].decode('mac_roman') except KeyError: - ps_name = sfnt[(3, 1, 0x0409, 6)].decode('utf-16be') + ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be') char_id = urllib_quote('%s-%x' % (ps_name, ccode)) return char_id