GeezerVison is showing github.com — Implment loading of any font in a collection · matplotlib/matplotlib@4133fba
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/matplotlib/font_manager.py +21-4Lines changed: 21 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -310,6 +310,19 @@ def findSystemFonts(fontpaths=None, fontext='ttf'): | 310 | 310 | return [fname for fname in fontfiles if os.path.exists(fname)] | 311 | 311 |
| 312 | 312 |
| | 313 | +class FontPath(str): | | 314 | + __match_args__ = ('path', 'face_index') | | 315 | + | | 316 | + def __new__(cls, path, face_index): | | 317 | + ret = super().__new__(cls, path) | | 318 | + ret.face_index = face_index | | 319 | + return ret | | 320 | + | | 321 | + @property | | 322 | + def path(self): | | 323 | + return str(self) | | 324 | + | | 325 | + | 313 | 326 | @dataclasses.dataclass(frozen=True) | 314 | 327 | class FontEntry: | 315 | 328 | """ | @@ -1542,7 +1555,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default, | 1542 | 1555 | # actually raised. | 1543 | 1556 | return cbook._ExceptionInfo(ValueError, "No valid font could be found") | 1544 | 1557 |
| 1545 | | - return _cached_realpath(result) | | 1558 | + return FontPath(_cached_realpath(result), best_font.index) | 1546 | 1559 |
| 1547 | 1560 |
| 1548 | 1561 | @_api.deprecated("3.11") | @@ -1618,8 +1631,9 @@ def get_font(font_filepaths, hinting_factor=None): | 1618 | 1631 |
| 1619 | 1632 | Parameters | 1620 | 1633 | ---------- | 1621 | | - font_filepaths : Iterable[str, Path, bytes, tuple[str | Path | bytes, int]], \ | 1622 | | -str, Path, bytes, tuple[str | Path | bytes, int] | | 1634 | + font_filepaths : Iterable[str, Path, bytes, FontPath, \ | | 1635 | +tuple[str | Path | bytes, int, FontPath]], \ | | 1636 | +str, Path, bytes, FontPath, tuple[str | Path | bytes, int] | 1623 | 1637 | Relative or absolute paths to the font files to be used. | 1624 | 1638 |
| 1625 | 1639 | If a single string, bytes, or `pathlib.Path`, then it will be treated | @@ -1635,14 +1649,17 @@ def get_font(font_filepaths, hinting_factor=None): | 1635 | 1649 |
| 1636 | 1650 | """ | 1637 | 1651 | match font_filepaths: | | 1652 | + case FontPath(path, index): | | 1653 | + paths = ((_cached_realpath(path), index), ) | 1638 | 1654 | case str() | Path() | bytes() as path: | 1639 | 1655 | paths = ((_cached_realpath(path), 0), ) | 1640 | 1656 | case (str() | Path() | bytes() as path, int() as index): | 1641 | 1657 | paths = ((_cached_realpath(path), index), ) | 1642 | 1658 | case _: | 1643 | 1659 | paths = tuple( | 1644 | 1660 | (_cached_realpath(fname[0]), fname[1]) if isinstance(fname, tuple) | 1645 | | - else (_cached_realpath(fname), 0) | | 1661 | + else (_cached_realpath(fname.path), fname.face_index) | | 1662 | + if isinstance(fname, FontPath) else (_cached_realpath(fname), 0) | 1646 | 1663 | for fname in font_filepaths) | 1647 | 1664 |
| 1648 | 1665 | hinting_factor = mpl._val_or_rc(hinting_factor, 'text.hinting_factor') | |
Collapse file Copy file name to clipboardExpand all lines: lib/matplotlib/font_manager.pyi +9-2Lines changed: 9 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -28,6 +28,13 @@ def _get_fontconfig_fonts() -> list[Path]: ... | 28 | 28 | def findSystemFonts( | 29 | 29 | fontpaths: Iterable[str | os.PathLike | Path] | None = ..., fontext: str = ... | 30 | 30 | ) -> list[str]: ... | | 31 | + | | 32 | +class FontPath(str): | | 33 | + face_index: int | | 34 | + def __new__(cls: type[str], path: str, face_index: int) -> FontPath: ... | | 35 | + @property | | 36 | + def path(self) -> str: ... | | 37 | + | 31 | 38 | @dataclass | 32 | 39 | class FontEntry: | 33 | 40 | fname: str = ... | @@ -117,12 +124,12 @@ class FontManager: | 117 | 124 | directory: str | None = ..., | 118 | 125 | fallback_to_default: bool = ..., | 119 | 126 | rebuild_if_missing: bool = ..., | 120 | | - ) -> str: ... | | 127 | + ) -> FontPath: ... | 121 | 128 | def get_font_names(self) -> list[str]: ... | 122 | 129 |
| 123 | 130 | def is_opentype_cff_font(filename: str) -> bool: ... | 124 | 131 | def get_font( | 125 | | - font_filepaths: Iterable[str | Path | bytes | FontFace] | str | Path | bytes | FontFace, | | 132 | + font_filepaths: Iterable[str | Path | bytes | FontFace | FontPath] | str | Path | bytes | FontFace | FontPath, | 126 | 133 | hinting_factor: int | None = ..., | 127 | 134 | ) -> ft2font.FT2Font: ... | 128 | 135 |
| |
Collapse file Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_font_manager.py +6-2Lines changed: 6 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -122,8 +122,12 @@ def test_find_ttc(): | 122 | 122 | pytest.skip("Font wqy-zenhei.ttc may be missing") | 123 | 123 | # All fonts from this collection should have loaded as well. | 124 | 124 | for name in ["WenQuanYi Zen Hei Mono", "WenQuanYi Zen Hei Sharp"]: | 125 | | - assert findfont(FontProperties(family=[name]), | 126 | | - fallback_to_default=False) == fontpath | | 125 | + subfontpath = findfont(FontProperties(family=[name]), fallback_to_default=False) | | 126 | + assert subfontpath.path == fontpath.path | | 127 | + assert subfontpath.face_index != fontpath.face_index | | 128 | + subfont = get_font(subfontpath) | | 129 | + assert subfont.fname == subfontpath.path | | 130 | + assert subfont.face_index == subfontpath.face_index | 127 | 131 | fig, ax = plt.subplots() | 128 | 132 | ax.text(.5, .5, "\N{KANGXI RADICAL DRAGON}", fontproperties=fp) | 129 | 133 | for fmt in ["raw", "svg", "pdf", "ps"]: | |
|