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

Skip to content

Commit cb5cb9c

Browse files
committed
Use class form of data classes
When these were added in #20118, we had no type annotations, so it made sense to use the functional form. Now that we do, there's no reason not to use the class form. Also, as `FontEntry` has gained more methods, the functional form looks less clear.
1 parent 18bfd1e commit cb5cb9c

File tree

4 files changed

+50
-53
lines changed

4 files changed

+50
-53
lines changed

doc/api/font_manager_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
.. automodule:: matplotlib.font_manager
66
:members:
7+
:exclude-members: FontEntry
78
:undoc-members:
89
:show-inheritance:
910

lib/matplotlib/_text_helpers.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
Low-level text helper utilities.
33
"""
44

5+
from __future__ import annotations
6+
57
import dataclasses
68

79
from . import _api
8-
from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING
10+
from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING, FT2Font
911

1012

11-
LayoutItem = dataclasses.make_dataclass(
12-
"LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"])
13+
@dataclasses.dataclass(frozen=True)
14+
class LayoutItem:
15+
ft_object: FT2Font
16+
char: str
17+
glyph_idx: int
18+
x: float
19+
prev_kern: float
1320

1421

1522
def warn_on_missing_glyph(codepoint, fontnames):
@@ -38,9 +45,10 @@ def warn_on_missing_glyph(codepoint, fontnames):
3845

3946
def layout(string, font, *, kern_mode=KERNING_DEFAULT):
4047
"""
41-
Render *string* with *font*. For each character in *string*, yield a
42-
(glyph-index, x-position) pair. When such a pair is yielded, the font's
43-
glyph is set to the corresponding character.
48+
Render *string* with *font*.
49+
50+
For each character in *string*, yield a LayoutItem instance. When such an instance
51+
is yielded, the font's glyph is set to the corresponding character.
4452
4553
Parameters
4654
----------
@@ -53,8 +61,7 @@ def layout(string, font, *, kern_mode=KERNING_DEFAULT):
5361
5462
Yields
5563
------
56-
glyph_index : int
57-
x_position : float
64+
LayoutItem
5865
"""
5966
x = 0
6067
prev_glyph_idx = None

lib/matplotlib/backends/backend_pdf.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,8 +2378,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23782378
multibyte_glyphs = []
23792379
prev_was_multibyte = True
23802380
prev_font = font
2381-
for item in _text_helpers.layout(
2382-
s, font, kern_mode=KERNING_UNFITTED):
2381+
for item in _text_helpers.layout(s, font, kern_mode=KERNING_UNFITTED):
23832382
if _font_supports_glyph(fonttype, ord(item.char)):
23842383
if prev_was_multibyte or item.ft_object != prev_font:
23852384
singlebyte_chunks.append((item.ft_object, item.x, []))
@@ -2389,9 +2388,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
23892388
singlebyte_chunks[-1][2].append(item.char)
23902389
prev_was_multibyte = False
23912390
else:
2392-
multibyte_glyphs.append(
2393-
(item.ft_object, item.x, item.glyph_idx)
2394-
)
2391+
multibyte_glyphs.append((item.ft_object, item.x, item.glyph_idx))
23952392
prev_was_multibyte = True
23962393
# Do the rotation and global translation as a single matrix
23972394
# concatenation up front

lib/matplotlib/font_manager.py

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
# - setWeights function needs improvement
2626
# - 'light' is an invalid weight value, remove it.
2727

28+
from __future__ import annotations
29+
2830
from base64 import b64encode
2931
from collections import namedtuple
3032
import copy
@@ -41,7 +43,6 @@
4143
import subprocess
4244
import sys
4345
import threading
44-
from typing import Union
4546

4647
import matplotlib as mpl
4748
from matplotlib import _api, _afm, cbook, ft2font
@@ -304,42 +305,35 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
304305
return [fname for fname in fontfiles if os.path.exists(fname)]
305306

306307

307-
def _fontentry_helper_repr_png(fontent):
308-
from matplotlib.figure import Figure # Circular import.
309-
fig = Figure()
310-
font_path = Path(fontent.fname) if fontent.fname != '' else None
311-
fig.text(0, 0, fontent.name, font=font_path)
312-
with BytesIO() as buf:
313-
fig.savefig(buf, bbox_inches='tight', transparent=True)
314-
return buf.getvalue()
315-
316-
317-
def _fontentry_helper_repr_html(fontent):
318-
png_stream = _fontentry_helper_repr_png(fontent)
319-
png_b64 = b64encode(png_stream).decode()
320-
return f"<img src=\"data:image/png;base64, {png_b64}\" />"
321-
322-
323-
FontEntry = dataclasses.make_dataclass(
324-
'FontEntry', [
325-
('fname', str, dataclasses.field(default='')),
326-
('name', str, dataclasses.field(default='')),
327-
('style', str, dataclasses.field(default='normal')),
328-
('variant', str, dataclasses.field(default='normal')),
329-
('weight', Union[str, int], dataclasses.field(default='normal')),
330-
('stretch', str, dataclasses.field(default='normal')),
331-
('size', str, dataclasses.field(default='medium')),
332-
],
333-
namespace={
334-
'__doc__': """
308+
@dataclasses.dataclass(frozen=True)
309+
class FontEntry:
310+
"""
335311
A class for storing Font properties.
336312
337313
It is used when populating the font lookup dictionary.
338-
""",
339-
'_repr_html_': lambda self: _fontentry_helper_repr_html(self),
340-
'_repr_png_': lambda self: _fontentry_helper_repr_png(self),
341-
}
342-
)
314+
"""
315+
316+
fname: str = ''
317+
name: str = ''
318+
style: str = 'normal'
319+
variant: str = 'normal'
320+
weight: str | int = 'normal'
321+
stretch: str = 'normal'
322+
size: str = 'medium'
323+
324+
def _repr_html_(self) -> str:
325+
png_stream = self._repr_png_()
326+
png_b64 = b64encode(png_stream).decode()
327+
return f"<img src=\"data:image/png;base64, {png_b64}\" />"
328+
329+
def _repr_png_(self) -> bytes:
330+
from matplotlib.figure import Figure # Circular import.
331+
fig = Figure()
332+
font_path = Path(self.fname) if self.fname != '' else None
333+
fig.text(0, 0, self.name, font=font_path)
334+
with BytesIO() as buf:
335+
fig.savefig(buf, bbox_inches='tight', transparent=True)
336+
return buf.getvalue()
343337

344338

345339
def ttfFontProperty(font):
@@ -926,8 +920,7 @@ def default(self, o):
926920
try:
927921
# Cache paths of fonts shipped with Matplotlib relative to the
928922
# Matplotlib data path, which helps in the presence of venvs.
929-
d["fname"] = str(
930-
Path(d["fname"]).relative_to(mpl.get_data_path()))
923+
d["fname"] = str(Path(d["fname"]).relative_to(mpl.get_data_path()))
931924
except ValueError:
932925
pass
933926
return d
@@ -944,10 +937,9 @@ def _json_decode(o):
944937
r.__dict__.update(o)
945938
return r
946939
elif cls == 'FontEntry':
947-
r = FontEntry.__new__(FontEntry)
948-
r.__dict__.update(o)
949-
if not os.path.isabs(r.fname):
950-
r.fname = os.path.join(mpl.get_data_path(), r.fname)
940+
if not os.path.isabs(o['fname']):
941+
o['fname'] = os.path.join(mpl.get_data_path(), o['fname'])
942+
r = FontEntry(**o)
951943
return r
952944
else:
953945
raise ValueError("Don't know how to deserialize __class__=%s" % cls)

0 commit comments

Comments
 (0)