Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b576e6

Browse files
authored
Merge pull request#18517 from anntzer/pdfkern
Include kerning when outputting pdf strings.
2 parents03a542e +1e1883b commit3b576e6

File tree

6 files changed

+49
-27
lines changed

6 files changed

+49
-27
lines changed

‎lib/matplotlib/_text_layout.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
Text layouting utilities.
33
"""
44

5+
importdataclasses
6+
57
from .ft2fontimportKERNING_DEFAULT,LOAD_NO_HINTING
68

79

10+
LayoutItem=dataclasses.make_dataclass(
11+
"LayoutItem", ["char","glyph_idx","x","prev_kern"])
12+
13+
814
deflayout(string,font,*,kern_mode=KERNING_DEFAULT):
915
"""
1016
Render *string* with *font*. For each character in *string*, yield a
@@ -26,13 +32,13 @@ def layout(string, font, *, kern_mode=KERNING_DEFAULT):
2632
x_position : float
2733
"""
2834
x=0
29-
last_glyph_idx=None
35+
prev_glyph_idx=None
3036
forcharinstring:
3137
glyph_idx=font.get_char_index(ord(char))
32-
kern= (font.get_kerning(last_glyph_idx,glyph_idx,kern_mode)
33-
iflast_glyph_idxisnotNoneelse0)/64
38+
kern= (font.get_kerning(prev_glyph_idx,glyph_idx,kern_mode)/64
39+
ifprev_glyph_idxisnotNoneelse0.)
3440
x+=kern
3541
glyph=font.load_glyph(glyph_idx,flags=LOAD_NO_HINTING)
36-
yieldglyph_idx,x
42+
yieldLayoutItem(char,glyph_idx,x,kern)
3743
x+=glyph.linearHoriAdvance/65536
38-
last_glyph_idx=glyph_idx
44+
prev_glyph_idx=glyph_idx

‎lib/matplotlib/backends/backend_pdf.py

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,21 +2281,23 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
22812281
# complication is avoided, but of course, those fonts can not be
22822282
# subsetted.)
22832283
else:
2284-
singlebyte_chunks= []# List of (start_x, list-of-1-byte-chars).
2285-
multibyte_glyphs= []# List of (start_x, glyph_index).
2286-
prev_was_singlebyte=False
2287-
forchar, (glyph_idx,glyph_x)inzip(
2288-
s,
2289-
_text_layout.layout(s,font,kern_mode=KERNING_UNFITTED)):
2290-
iford(char)<=255:
2291-
ifprev_was_singlebyte:
2292-
singlebyte_chunks[-1][1].append(char)
2293-
else:
2294-
singlebyte_chunks.append((glyph_x, [char]))
2295-
prev_was_singlebyte=True
2284+
# List of (start_x, [prev_kern, char, char, ...]), w/o zero kerns.
2285+
singlebyte_chunks= []
2286+
# List of (start_x, glyph_index).
2287+
multibyte_glyphs= []
2288+
prev_was_multibyte=True
2289+
foritemin_text_layout.layout(
2290+
s,font,kern_mode=KERNING_UNFITTED):
2291+
iford(item.char)<=255:
2292+
ifprev_was_multibyte:
2293+
singlebyte_chunks.append((item.x, []))
2294+
ifitem.prev_kern:
2295+
singlebyte_chunks[-1][1].append(item.prev_kern)
2296+
singlebyte_chunks[-1][1].append(item.char)
2297+
prev_was_multibyte=False
22962298
else:
2297-
multibyte_glyphs.append((glyph_x,glyph_idx))
2298-
prev_was_singlebyte=False
2299+
multibyte_glyphs.append((item.x,item.glyph_idx))
2300+
prev_was_multibyte=True
22992301
# Do the rotation and global translation as a single matrix
23002302
# concatenation up front
23012303
self.file.output(Op.gsave)
@@ -2307,10 +2309,15 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23072309
self.file.output(Op.begin_text,
23082310
self.file.fontName(prop),fontsize,Op.selectfont)
23092311
prev_start_x=0
2310-
forstart_x,charsinsinglebyte_chunks:
2312+
forstart_x,kerns_or_charsinsinglebyte_chunks:
23112313
self._setup_textpos(start_x,0,0,prev_start_x,0,0)
2312-
self.file.output(self.encode_string(''.join(chars),fonttype),
2313-
Op.show)
2314+
self.file.output(
2315+
# See pdf spec "Text space details" for the 1000/fontsize
2316+
# (aka. 1000/T_fs) factor.
2317+
[-1000*next(group)/fontsizeiftp==float# a kern
2318+
elseself.encode_string("".join(group),fonttype)
2319+
fortp,groupinitertools.groupby(kerns_or_chars,type)],
2320+
Op.showkern)
23142321
prev_start_x=start_x
23152322
self.file.output(Op.end_text)
23162323
# Then emit all the multibyte characters, one at a time.

‎lib/matplotlib/backends/backend_ps.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,9 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
584584
self.set_font(ps_name,prop.get_size_in_points())
585585

586586
thetext='\n'.join(
587-
'%f 0 m /%s glyphshow'% (x,font.get_glyph_name(glyph_idx))
588-
forglyph_idx,xin_text_layout.layout(s,font))
587+
'{:f} 0 m /{:s} glyphshow'
588+
.format(item.x,font.get_glyph_name(item.glyph_idx))
589+
foritemin_text_layout.layout(s,font))
589590
self._pswriter.write(f"""\
590591
gsave
591592
{x:f}{y:f} translate
Binary file not shown.

‎lib/matplotlib/tests/test_backend_pdf.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,11 @@ def test_empty_rasterized():
271271
fig,ax=plt.subplots()
272272
ax.plot([], [],rasterized=True)
273273
fig.savefig(io.BytesIO(),format="pdf")
274+
275+
276+
@image_comparison(['kerning.pdf'])
277+
deftest_kerning():
278+
fig=plt.figure()
279+
s="AVAVAVAVAVAVAVAV€AAVV"
280+
fig.text(0,.25,s,size=5)
281+
fig.text(0,.75,s,size=20)

‎lib/matplotlib/textpath.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ def get_glyphs_with_font(self, font, s, glyph_map=None,
149149

150150
xpositions= []
151151
glyph_ids= []
152-
forchar, (_,x)inzip(s,_text_layout.layout(s,font)):
153-
char_id=self._get_char_id(font,ord(char))
152+
foritemin_text_layout.layout(s,font):
153+
char_id=self._get_char_id(font,ord(item.char))
154154
glyph_ids.append(char_id)
155-
xpositions.append(x)
155+
xpositions.append(item.x)
156156
ifchar_idnotinglyph_map:
157157
glyph_map_new[char_id]=font.get_path()
158158

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp