8000 Font weight warning if found font sufficiently different by colt-1 · Pull Request #15615 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Font weight warning if found font sufficiently different #15615

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/api/next_api_changes/behaviour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ did nothing, when passed an unsupported value. It now raises a ``ValueError``.
`.Axis.set_tick_params` (and the higher level `.axes.Axes.tick_params` and
`.pyplot.tick_params`) used to accept any value for ``which`` and silently
did nothing, when passed an unsupported value. It now raises a ``ValueError``.

``font_manager.findfont`` now warns of +-100 weight difference of selected font vs found font
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fonts are mapped from string to number. If the best-matched font is over 100 less than or
greater than the chosen font, a warning will be logged.
13 changes: 11 additions & 2 deletions lib/matplotlib/font_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
'extra bold': 800,
'black': 900,
}

def map_weight_name_to_score(weight):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be private

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say private, I think of other language access modifiers. In Python would that be just making this a class method?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just prepend an underscore to its name.

return weight if isinstance(weight, Number) else weight_dict[weight]

font_family_aliases = {
'serif',
'sans-serif',
Expand Down Expand Up @@ -1147,8 +1151,8 @@ def score_weight(self, weight1, weight2):
# exact match of the weight names, e.g. weight1 == weight2 == "regular"
if cbook._str_equal(weight1, weight2):
return 0.0
w1 = weight1 if isinstance(weight1, Number) else weight_dict[weight1]
w2 = weight2 if isinstance(weight2, Number) else weight_dict[weight2]
w1 = map_weight_name_to_score(weight1)
w2 = map_weight_name_to_score(weight2)
return 0.95 * (abs(w1 - w2) / 1000) + 0.05

def score_size(self, size1, size2):
Expand Down Expand Up @@ -1275,6 +1279,11 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
best_font = font
if score == 0:
break
if best_font is not None:
if abs(map_weight_name_to_score(prop.get_weight())
- map_weight_name_to_score(best_font.weight)) > 100:
_log.warning('findfont: Failed to find font weight %s, '
+ 'now using %s.', prop.get_weight(), best_font.weight)

if best_font is None or best_score >= 10.0:
if fallback_to_default:
Expand Down
24 changes: 23 additions & 1 deletion lib/matplotlib/tests/test_font_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from matplotlib.font_manager import (
findfont, findSystemFonts, FontProperties, fontManager, json_dump,
json_load, get_font, get_fontconfig_fonts, is_opentype_cff_font,
MSUserFontDirectories, _call_fc_list)
MSUserFontDirectories, _call_fc_list, map_weight_name_to_score, weight_dict)
from matplotlib import pyplot as plt, rc_context

has_fclist = shutil.which('fc-list') is not None
Expand Down Expand Up @@ -199,3 +199,25 @@ def test_fork():
_model_handler(0) # Make sure the font cache is filled.
ctx = multiprocessing.get_context("fork")
ctx.Pool(processes=2).map(_model_handler, range(2))

def test_map_weights():
assert map_weight_name_to_score('ultralight') == 100
assert map_weight_name_to_score('light') == 200
assert map_weight_name_to_score('normal') == 400
assert map_weight_name_to_score('regular') == 400
assert map_weight_name_to_score('book') == 400
assert map_weight_name_to_score('medium') == 500
assert map_weight_name_to_score('roman') == 500
assert map_weight_name_to_score('semibold') == 600
assert map_weight_name_to_score('demibold') == 600
assert map_weight_name_to_score('demi') == 600
assert map_weight_name_to_score('bold') == 700
assert map_weight_name_to_score('heavy') == 800
assert map_weight_name_to_score('extra bold') == 800
assert map_weight_name_to_score('black') == 900

def test_font_match_warning():
with warnings.catch_warnings(record=True) as warns:
font = findfont(FontProperties(family=["PingFang SC"], weight=900))
assert len(warns) == 2

0