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

Skip to content

Commit b932575

Browse files
authored
Merge pull request #20615 from sauerburger/font-42-kerning
Font 42 kerning
2 parents ed4f814 + 67aea08 commit b932575

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

lib/matplotlib/backends/backend_pdf.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,20 @@ def encode_string(self, s, fonttype):
22362236
return s.encode('cp1252', 'replace')
22372237
return s.encode('utf-16be', 'replace')
22382238

2239+
@staticmethod
2240+
def _font_supports_char(fonttype, char):
2241+
"""
2242+
Returns True if the font is able to provided the char in a PDF
2243+
2244+
For a Type 3 font, this method returns True only for single-byte
2245+
chars. For Type 42 fonts this method always returns True.
2246+
"""
2247+
if fonttype == 3:
2248+
return ord(char) <= 255
2249+
if fonttype == 42:
2250+
return True
2251+
raise NotImplementedError()
2252+
22392253
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
22402254
# docstring inherited
22412255

@@ -2270,26 +2284,27 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
22702284
}
22712285
self.file._annotations[-1][1].append(link_annotation)
22722286

2273-
# If fonttype != 3 emit the whole string at once without manual
2274-
# kerning.
2275-
if fonttype != 3:
2287+
# If fonttype is neither 3 nor 42, emit the whole string at once
2288+
# without manual kerning.
2289+
if fonttype not in [3, 42]:
22762290
self.file.output(Op.begin_text,
22772291
self.file.fontName(prop), fontsize, Op.selectfont)
22782292
self._setup_textpos(x, y, angle)
22792293
self.file.output(self.encode_string(s, fonttype),
22802294
Op.show, Op.end_text)
22812295

2282-
# There is no way to access multibyte characters of Type 3 fonts, as
2283-
# they cannot have a CIDMap. Therefore, in this case we break the
2284-
# string into chunks, where each chunk contains either a string of
2285-
# consecutive 1-byte characters or a single multibyte character.
2286-
# A sequence of 1-byte characters is broken into multiple chunks to
2287-
# adjust the kerning between adjacent chunks. Each chunk is emitted
2288-
# with a separate command: 1-byte characters use the regular text show
2289-
# command (TJ) with appropriate kerning between chunks, whereas
2290-
# multibyte characters use the XObject command (Do). (If using Type
2291-
# 42 fonts, all of this complication is avoided, but of course,
2292-
# subsetting those fonts is complex/hard to implement.)
2296+
# A sequence of characters is broken into multiple chunks. The chunking
2297+
# serves two purposes:
2298+
# - For Type 3 fonts, there is no way to access multibyte characters,
2299+
# as they cannot have a CIDMap. Therefore, in this case we break
2300+
# the string into chunks, where each chunk contains either a string
2301+
# of consecutive 1-byte characters or a single multibyte character.
2302+
# - A sequence of 1-byte characters is split into chunks to allow for
2303+
# kerning adjustments between consecutive chunks.
2304+
#
2305+
# Each chunk is emitted with a separate command: 1-byte characters use
2306+
# the regular text show command (TJ) with appropriate kerning between
2307+
# chunks, whereas multibyte characters use the XObject command (Do).
22932308
else:
22942309
# List of (start_x, [prev_kern, char, char, ...]), w/o zero kerns.
22952310
singlebyte_chunks = []
@@ -2298,7 +2313,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
22982313
prev_was_multibyte = True
22992314
for item in _text_helpers.layout(
23002315
s, font, kern_mode=KERNING_UNFITTED):
2301-
if ord(item.char) <= 255:
2316+
if self._font_supports_char(fonttype, item.char):
23022317
if prev_was_multibyte:
23032318
singlebyte_chunks.append((item.x, []))
23042319
if item.prev_kern:
Binary file not shown.

lib/matplotlib/tests/test_text.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,10 @@ def test_parse_math():
741741
ax.text(0, 0, r"$ \wrong{math} $", parse_math=True)
742742
with pytest.raises(ValueError, match='Unknown symbol'):
743743
fig.canvas.draw()
744+
745+
746+
@image_comparison(['text_pdf_font42_kerning.pdf'], style='mpl20')
747+
def test_pdf_font42_kerning():
748+
plt.rcParams['pdf.fonttype'] = 42
749+
plt.figure()
750+
plt.figtext(0.1, 0.5, "ATAVATAVATAVATAVATA", size=30)

0 commit comments

Comments
 (0)