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

Skip to content

Added _repr_html_ for fonts #21904

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 9 commits into from
Dec 16, 2021
Merged
24 changes: 23 additions & 1 deletion lib/matplotlib/font_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
# - setWeights function needs improvement
# - 'light' is an invalid weight value, remove it.

from base64 import b64encode
import dataclasses
from functools import lru_cache
from io import BytesIO
import json
import logging
from numbers import Number
Expand Down Expand Up @@ -380,6 +382,22 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
return [fname for fname in fontfiles if os.path.exists(fname)]


def fontentry_helper_repr_png_(fontent):
from matplotlib.figure import Figure # Circular import.
fig = Figure()
font_path = Path(fontent.fname) if fontent.fname != '' else None
fig.text(0, 0, fontent.name, font=font_path)
with BytesIO() as buf:
fig.savefig(buf, bbox_inches='tight', transparent=True)
return buf.getvalue()


def fontentry_helper_repr_html_(fontent):
png_stream = fontentry_helper_repr_png_(fontent)
png_b64 = b64encode(png_stream).decode()
return f"<img src=\"data:image/png;base64, {png_b64}\" />"


FontEntry = dataclasses.make_dataclass(
'FontEntry', [
('fname', str, dataclasses.field(default='')),
Expand All @@ -395,7 +413,11 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
A class for storing Font properties.

It is used when populating the font lookup dictionary.
"""})
""",
'_repr_html_': lambda self: fontentry_helper_repr_html_(self),
'_repr_png_': lambda self: fontentry_helper_repr_png_(self),
}
)


def ttfFontProperty(font):
Expand Down
26 changes: 23 additions & 3 deletions lib/matplotlib/tests/test_font_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import multiprocessing
import os
from pathlib import Path
from PIL import Image
import shutil
import subprocess
import sys
Expand All @@ -11,9 +12,10 @@
import pytest

from matplotlib.font_manager import (
findfont, findSystemFonts, FontProperties, fontManager, json_dump,
json_load, get_font, is_opentype_cff_font, MSUserFontDirectories,
_get_fontconfig_fonts, ft2font, ttfFontProperty, cbook)
findfont, findSystemFonts, FontEntry, FontProperties, fontManager,
json_dump, json_load, get_font, is_opentype_cff_font,
MSUserFontDirectories, _get_fontconfig_fonts, ft2font,
ttfFontProperty, cbook)
from matplotlib import pyplot as plt, rc_context

has_fclist = shutil.which('fc-list') is not None
Expand Down Expand Up @@ -268,6 +270,24 @@ def test_fontcache_thread_safe():
f"{proc.returncode}.")


def test_fontentry_dataclass():
fontent = FontEntry(name='font-name')

png = fontent._repr_png_()
img = Image.open(BytesIO(png))
assert img.width > 0
assert img.height > 0

html = fontent._repr_html_()
assert html.startswith("<img src=\"data:image/png;base64")


def test_fontentry_dataclass_invalid_path():
with pytest.raises(FileNotFoundError):
fontent = FontEntry(fname='/random', name='font-name')
fontent._repr_html_()


@pytest.mark.skipif(sys.platform == 'win32', reason='Linux or OS only')
def test_get_font_names():
paths_mpl = [cbook._get_data_path('fonts', subdir) for subdir in ['ttf']]
Expand Down