8000 Use selectfont instead of findfont + scalefont + setfont in PostScript. by anntzer · Pull Request #18894 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Use selectfont instead of findfont + scalefont + setfont in PostScript. #18894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/next_api_changes/behavior/18894-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
``RendererPS.set_font`` is no longer a no-op in AFM mode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It now sets the current PostScript font in all cases.
65 changes: 18 additions & 47 deletions lib/matplotlib/backends/backend_ps.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,8 @@ def set_linedash(self, offset, seq, store=True):
self.linedash = (offset, seq)

def set_font(self, fontname, fontsize, store=True):
if mpl.rcParams['ps.useafm']:
return
if (fontname, fontsize) != (self.fontname, self.fontsize):
out = ("/%s findfont\n"
"%1.3f scalefont\n"
"setfont\n" % (fontname, fontsize))
self._pswriter.write(out)
self._pswriter.write(f"/{fontname} {fontsize:1.3f} selectfont\n")
if store:
self.fontname = fontname
self.fontsize = fontsize
Expand Down Expand Up @@ -616,65 +611,43 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
if ismath == 'TeX':
return self.draw_tex(gc, x, y, s, prop, angle)

elif ismath:
if ismath:
return self.draw_mathtext(gc, x, y, s, prop, angle)

elif mpl.rcParams['ps.useafm']:
self.set_color(*gc.get_rgb())

if mpl.rcParams['ps.useafm']:
font = self._get_font_afm(prop)
fontname = font.get_fontname()
fontsize = prop.get_size_in_points()
scale = 0.001 * fontsize
scale = 0.001 * prop.get_size_in_points()

thisx = 0
last_name = None
lines = []
last_name = None # kerns returns 0 for None.
xs_names = []
for c in s:
name = uni2type1.get(ord(c), f"uni{ord(c):04X}")
try:
width = font.get_width_from_char_name(name)
except KeyError:
name = 'question'
width = font.get_width_char('?')
if last_name is not None:
kern = font.get_kern_dist_from_name(last_name, name)
else:
kern = 0
kern = font.get_kern_dist_from_name(last_name, name)
last_name = name
thisx += kern * scale

lines.append('%f 0 m /%s glyphshow' % (thisx, name))

xs_names.append((thisx, name))
thisx += width * scale

thetext = "\n".join(lines)
self._pswriter.write(f"""\
gsave
/{fontname} findfont
{fontsize} scalefont
setfont
{x:f} {y:f} translate
{angle:f} rotate
{thetext}
grestore
""")

else:
font = self._get_font_ttf(prop)
font.set_text(s, 0, flags=LOAD_NO_HINTING)
self._character_tracker.track(font, s)
xs_names = [(item.x, font.get_glyph_name(item.glyph_idx))
for item in _text_layout.layout(s, font)]

self.set_color(*gc.get_rgb())
ps_name = (font.postscript_name
.encode('ascii', 'replace').decode('ascii'))
self.set_font(ps_name, prop.get_size_in_points())

thetext = '\n'.join(
'{:f} 0 m /{:s} glyphshow'
.format(item.x, font.get_glyph_name(item.glyph_idx))
for item in _text_layout.layout(s, font))
self._pswriter.write(f"""\
self.set_color(*gc.get_rgb())
ps_name = (font.postscript_name
.encode("ascii", "replace").decode("ascii"))
self.set_font(ps_name, prop.get_size_in_points())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this here means the font change will happen before the gsave, which is flipped from how it worked in the useafm case before this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's fine, and in fact that's how set_font is supposed to work (its save parameter basically assumes that it is setting the font globally (outside of any gsave block) so that it know when it needs to reset the font or not.

thetext = "\n".join(f"{x:f} 0 m /{name:s} glyphshow"
for x, name in xs_names)
self._pswriter.write(f"""\
gsave
{x:f} {y:f} translate
{angle:f} rotate
Expand Down Expand Up @@ -702,9 +675,7 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
if (font.postscript_name, fontsize) != lastfont:
lastfont = font.postscript_name, fontsize
self._pswriter.write(
f"/{font.postscript_name} findfont\n"
f"{fontsize} scalefont\n"
f"setfont\n")
f"/{font.postscript_name} {fontsize} selectfont\n")
symbol_name = (
font.get_name_char(chr(num)) if isinstance(font, AFM) else
font.get_glyph_name(font.get_char_index(num)))
Expand Down
0