From d94a6a526fcae5e29381d66624b216e8c255a0c0 Mon Sep 17 00:00:00 2001 From: kshramt Date: Tue, 24 Jan 2017 11:40:38 +0900 Subject: [PATCH 1/7] The font with the same weight name as the user specified weight name should have the highest priority FiraSans-Hair, which is very thin, and FiraSans-Regular has the same numeric weight, 400, and thus they have the same priority for the previous `score_weight` implementation. However, it is clear that if an user set `rcParams["weight"] = "regular"`, the user wants FiraSans-Regular, not FiraSans-Hair. --- lib/matplotlib/font_manager.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index 3e9a164d1458..47b718e83abc 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -346,6 +346,7 @@ def findSystemFonts(fontpaths=None, fontext='ttf'): return [fname for fname in fontfiles if os.path.exists(fname)] +@cbook.deprecated("2.1") def weight_as_number(weight): """ Return the weight property as a numeric value. String values @@ -435,17 +436,12 @@ def ttfFontProperty(font): else: variant = 'normal' - # Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), - # 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) - # lighter and bolder are also allowed. - weight = next((w for w in weight_dict if sfnt4.find(w) >= 0), None) if not weight: if font.style_flags & ft2font.BOLD: - weight = 700 + weight = "bold" else: - weight = 400 - weight = weight_as_number(weight) + weight = "normal" # Stretch can be absolute and relative # Absolute stretches are: ultra-condensed, extra-condensed, condensed, @@ -511,11 +507,7 @@ def afmFontProperty(fontpath, font): else: variant = 'normal' - # Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), - # 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) - # lighter and bolder are also allowed. - - weight = weight_as_number(font.get_weight().lower()) + weight = font.get_weight().lower() # Stretch can be absolute and relative # Absolute stretches are: ultra-condensed, extra-condensed, condensed, @@ -855,7 +847,6 @@ def set_weight(self, weight): except ValueError: if weight not in weight_dict: raise ValueError("weight is invalid") - weight = weight_dict[weight] self._weight = weight def set_stretch(self, stretch): @@ -1203,10 +1194,19 @@ def score_weight(self, weight1, weight2): """ Returns a match score between *weight1* and *weight2*. - The result is the absolute value of the difference between the + The result is 0.0 if both weight1 and weight 2 are given as strings + and have the same value. + + Otherwise, the result is the absolute value of the difference between the CSS numeric values of *weight1* and *weight2*, normalized - between 0.0 and 1.0. + between 0.05 and 1.0. """ + + # exact match of the weight names (e.g. weight1 == weight2 == "regular") + if (isinstance(weight1, six.string_types) and + isinstance(weight2, six.string_types) and + weight1 == weight2): + return 0.0 try: weightval1 = int(weight1) except ValueError: @@ -1215,7 +1215,7 @@ def score_weight(self, weight1, weight2): weightval2 = int(weight2) except ValueError: weightval2 = weight_dict.get(weight2, 500) - return abs(weightval1 - weightval2) / 1000.0 + return 0.95*(abs(weightval1 - weightval2) / 1000.0) + 0.05 def score_size(self, size1, size2): """ From 30031b5df16eec296cc7b9d189b9e7083d92c39d Mon Sep 17 00:00:00 2001 From: kshramt Date: Mon, 30 Jan 2017 21:16:52 +0900 Subject: [PATCH 2/7] Add tests --- lib/matplotlib/tests/test_font_manager.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index 90785e8f4985..9b3a23a6083f 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -31,6 +31,20 @@ def test_font_priority(): assert cmap[8729] == 30 +def test_ttflist_weight(): + assert all(isinstance(f.weight, six.string_types) + for f in fontManager.ttflist) + + +def test_score_weight(): + assert (0 == + fontManager.score_weight("regular", "regular") == + fontManager.score_weight("bold", "bold") < + fontManager.score_weight("normal", "regular") == + fontManager.score_weight(400, 400) < + fontManager.score_weight("normal", "bold")) + + def test_json_serialization(): # on windows, we can't open a file twice, so save the name and unlink # manually... From 97e7dacf0515c8cc781de5f2ca3043c2dce48b36 Mon Sep 17 00:00:00 2001 From: kshramt Date: Sun, 26 Feb 2017 11:24:38 +0900 Subject: [PATCH 3/7] Address comments - https://github.com/matplotlib/matplotlib/pull/7931#discussion_r103075439 - https://github.com/matplotlib/matplotlib/pull/7931#discussion_r103075468 --- lib/matplotlib/font_manager.py | 4 ++-- lib/matplotlib/tests/test_font_manager.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index 47b718e83abc..c25e7704f5ca 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -1204,8 +1204,8 @@ def score_weight(self, weight1, weight2): # exact match of the weight names (e.g. weight1 == weight2 == "regular") if (isinstance(weight1, six.string_types) and - isinstance(weight2, six.string_types) and - weight1 == weight2): + isinstance(weight2, six.string_types) and + weight1 == weight2): return 0.0 try: weightval1 = int(weight1) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index 9b3a23a6083f..7e3a761b376e 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -40,8 +40,9 @@ def test_score_weight(): assert (0 == fontManager.score_weight("regular", "regular") == fontManager.score_weight("bold", "bold") < - fontManager.score_weight("normal", "regular") == - fontManager.score_weight(400, 400) < + fontManager.score_weight(400, 400) == + # "normal" and "regular" have the same numerical weight + fontManager.score_weight("normal", "regular") < fontManager.score_weight("normal", "bold")) From 8a10efcbf713b33cd1a2655b9af26d7b5d063087 Mon Sep 17 00:00:00 2001 From: kshramt Date: Sun, 26 Feb 2017 12:37:34 +0900 Subject: [PATCH 4/7] An inferred weight should be stored as a numeric value to gain lower priority (this commit is a partial revert of d94a6a526fcae5e29381d66624b216e8c255a0c0) --- lib/matplotlib/font_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index c25e7704f5ca..4d77e1da373c 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -439,9 +439,9 @@ def ttfFontProperty(font): weight = next((w for w in weight_dict if sfnt4.find(w) >= 0), None) if not weight: if font.style_flags & ft2font.BOLD: - weight = "bold" + weight = 700 else: - weight = "normal" + weight = 400 # Stretch can be absolute and relative # Absolute stretches are: ultra-condensed, extra-condensed, condensed, From 91075a30cf44e579ce61976f0f158cdc8f452fb9 Mon Sep 17 00:00:00 2001 From: kshramt Date: Sun, 26 Feb 2017 13:09:50 +0900 Subject: [PATCH 5/7] Address a comment --- lib/matplotlib/tests/test_font_manager.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index 7e3a761b376e..a58067df99a7 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -37,13 +37,11 @@ def test_ttflist_weight(): def test_score_weight(): - assert (0 == - fontManager.score_weight("regular", "regular") == - fontManager.score_weight("bold", "bold") < - fontManager.score_weight(400, 400) == - # "normal" and "regular" have the same numerical weight - fontManager.score_weight("normal", "regular") < - fontManager.score_weight("normal", "bold")) + assert 0 == fontManager.score_weight("regular", "regular") + assert 0 == fontManager.score_weight("bold", "bold") + assert 0 < fontManager.score_weight(400, 400) < fontManager.score_weight("normal", "bold") + assert 0 < fontManager.score_weight("normal", "regular") < fontManager.score_weight("normal", "bold") + assert fontManager.score_weight("normal", "regular") == fontManager.score_weight(400, 400) def test_json_serialization(): From a7026e0026f097d374ffba24c83b9cacf33cd182 Mon Sep 17 00:00:00 2001 From: kshramt Date: Sun, 26 Feb 2017 13:37:39 +0900 Subject: [PATCH 6/7] Remove a test following 8a10efcbf713b33cd1a2655b9af26d7b5d063087 --- lib/matplotlib/tests/test_font_manager.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index a58067df99a7..aebe2f38f404 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -31,11 +31,6 @@ def test_font_priority(): assert cmap[8729] == 30 -def test_ttflist_weight(): - assert all(isinstance(f.weight, six.string_types) - for f in fontManager.ttflist) - - def test_score_weight(): assert 0 == fontManager.score_weight("regular", "regular") assert 0 == fontManager.score_weight("bold", "bold") From 42b16599cc92b92b36bed7d98a6c44b35406539b Mon Sep 17 00:00:00 2001 From: kshramt Date: Sun, 26 Feb 2017 14:00:18 +0900 Subject: [PATCH 7/7] PEP8 --- lib/matplotlib/tests/test_font_manager.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index aebe2f38f404..8adf601322fc 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -34,9 +34,12 @@ def test_font_priority(): def test_score_weight(): assert 0 == fontManager.score_weight("regular", "regular") assert 0 == fontManager.score_weight("bold", "bold") - assert 0 < fontManager.score_weight(400, 400) < fontManager.score_weight("normal", "bold") - assert 0 < fontManager.score_weight("normal", "regular") < fontManager.score_weight("normal", "bold") - assert fontManager.score_weight("normal", "regular") == fontManager.score_weight(400, 400) + assert (0 < fontManager.score_weight(400, 400) < + fontManager.score_weight("normal", "bold")) + assert (0 < fontManager.score_weight("normal", "regular") < + fontManager.score_weight("normal", "bold")) + assert (fontManager.score_weight("normal", "regular") == + fontManager.score_weight(400, 400)) def test_json_serialization():