Skip to content

Commit c4fcd7b

Browse files
committed
Deprecate setting text kerning factor to any non-0 value
This factor existed only to preserve test images, but as of matplotlib#29816, it is set to 0 (i.e., disabled and providing default behaviour). In the future, with libraqm, it will have no effect no matter its setting (because we won't be applying kerning ourselves at all.)
1 parent 7dae1e5 commit c4fcd7b

File tree

6 files changed

+37
-26
lines changed

6 files changed

+37
-26
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Font kerning factor is deprecated
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Due to internal changes to support complex text rendering, the kerning factor on fonts is
5+
no longer used. Setting the ``text.kerning_factor`` rcParam (which existed only for
6+
backwards-compatibility) to any value other than 0 is deprecated, and the rcParam will be
7+
removed in the future.

doc/users/prev_whats_new/whats_new_3.2.0.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ triangle meshes.
5252

5353
Kerning adjustments now use correct values
5454
------------------------------------------
55-
Due to an error in how kerning adjustments were applied, previous versions of
56-
Matplotlib would under-correct kerning. This version will now correctly apply
57-
kerning (for fonts supported by FreeType). To restore the old behavior (e.g.,
58-
for test images), you may set :rc:`text.kerning_factor` to 6 (instead of 0).
59-
Other values have undefined behavior.
55+
Due to an error in how kerning adjustments were applied, previous versions of Matplotlib
56+
would under-correct kerning. This version will now correctly apply kerning (for fonts
57+
supported by FreeType). To restore the old behavior (e.g., for test images), you may set
58+
the ``text.kerning_factor`` rcParam to 6 (instead of 0). Other values have undefined
59+
behavior.
6060

6161
.. plot::
6262

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,9 @@
306306
#text.hinting_factor: 1 # Specifies the amount of softness for hinting in the
307307
# horizontal direction. A value of 1 will hint to full
308308
# pixels. A value of 2 will hint to half pixels etc.
309-
#text.kerning_factor: 0 # Specifies the scaling factor for kerning values. This
310-
# is provided solely to allow old test images to remain
311-
# unchanged. Set to 6 to obtain previous behavior.
312-
# Values other than 0 or 6 have no defined meaning.
309+
#text.kerning_factor: None # Specifies the scaling factor for kerning values. Values
310+
# other than 0, 6, or None have no defined meaning.
311+
# This setting is deprecated.
313312
#text.antialiased: True # If True (default), the text will be antialiased.
314313
# This only affects raster outputs.
315314
#text.parse_math: True # Use mathtext if there is an even number of unescaped

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ def _convert_validator_spec(key, conv):
10421042
"text.hinting": ["default", "no_autohint", "force_autohint",
10431043
"no_hinting", "auto", "native", "either", "none"],
10441044
"text.hinting_factor": validate_int,
1045-
"text.kerning_factor": validate_int,
1045+
"text.kerning_factor": validate_int_or_None,
10461046
"text.antialiased": validate_bool,
10471047
"text.parse_math": validate_bool,
10481048

lib/matplotlib/tests/test_ft2font.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ def test_ft2font_invalid_args(tmp_path):
168168
# kerning_factor argument.
169169
with pytest.raises(TypeError, match='incompatible constructor arguments'):
170170
ft2font.FT2Font(file, _kerning_factor=1.3)
171+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
172+
match='text.kerning_factor rcParam was deprecated .+ 3.11'):
173+
ft2font.FT2Font(file, _kerning_factor=123)
171174

172175

173176
def test_ft2font_clear():
@@ -188,7 +191,7 @@ def test_ft2font_clear():
188191

189192
def test_ft2font_set_size():
190193
file = fm.findfont('DejaVu Sans')
191-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=1)
194+
font = ft2font.FT2Font(file, hinting_factor=1)
192195
font.set_size(12, 72)
193196
font.set_text('ABabCDcd')
194197
orig = font.get_width_height()
@@ -717,7 +720,7 @@ def test_ft2font_get_sfnt_table(font_name, header):
717720
def test_ft2font_get_kerning(left, right, unscaled, unfitted, default):
718721
file = fm.findfont('DejaVu Sans')
719722
# With unscaled, these settings should produce exact values found in FontForge.
720-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
723+
font = ft2font.FT2Font(file, hinting_factor=1)
721724
font.set_size(100, 100)
722725
assert font.get_kerning(font.get_char_index(ord(left)),
723726
font.get_char_index(ord(right)),
@@ -756,7 +759,7 @@ def test_ft2font_get_kerning(left, right, unscaled, unfitted, default):
756759

757760
def test_ft2font_set_text():
758761
file = fm.findfont('DejaVu Sans')
759-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
762+
font = ft2font.FT2Font(file, hinting_factor=1)
760763
font.set_size(12, 72)
761764
xys = font.set_text('')
762765
np.testing.assert_array_equal(xys, np.empty((0, 2)))
@@ -778,7 +781,7 @@ def test_ft2font_set_text():
778781

779782
def test_ft2font_loading():
780783
file = fm.findfont('DejaVu Sans')
781-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
784+
font = ft2font.FT2Font(file, hinting_factor=1)
782785
font.set_size(12, 72)
783786
for glyph in [font.load_char(ord('M')),
784787
font.load_glyph(font.get_char_index(ord('M')))]:
@@ -819,13 +822,13 @@ def test_ft2font_drawing():
819822
])
820823
expected *= 255
821824
file = fm.findfont('DejaVu Sans')
822-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
825+
font = ft2font.FT2Font(file, hinting_factor=1)
823826
font.set_size(12, 72)
824827
font.set_text('M')
825828
font.draw_glyphs_to_bitmap(antialiased=False)
826829
image = font.get_image()
827830
np.testing.assert_array_equal(image, expected)
828-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
831+
font = ft2font.FT2Font(file, hinting_factor=1)
829832
font.set_size(12, 72)
830833
glyph = font.load_char(ord('M'))
831834
image = np.zeros(expected.shape, np.uint8)
@@ -835,7 +838,7 @@ def test_ft2font_drawing():
835838

836839
def test_ft2font_get_path():
837840
file = fm.findfont('DejaVu Sans')
838-
font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0)
841+
font = ft2font.FT2Font(file, hinting_factor=1)
839842
font.set_size(12, 72)
840843
vertices, codes = font.get_path()
841844
assert vertices.shape == (0, 2)

src/ft2font_wrapper.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,6 @@ const char *PyFT2Font_init__doc__ = R"""(
432432
.. warning::
433433
This API is both private and provisional: do not use it directly.
434434
435-
_kerning_factor : int, optional
436-
Used to adjust the degree of kerning.
437-
438-
.. warning::
439-
This API is private: do not use it directly.
440-
441435
_warn_if_used : bool, optional
442436
Used to trigger missing glyph warnings.
443437
@@ -448,11 +442,19 @@ const char *PyFT2Font_init__doc__ = R"""(
448442
static PyFT2Font *
449443
PyFT2Font_init(py::object filename, long hinting_factor = 8,
450444
std::optional<std::vector<PyFT2Font *>> fallback_list = std::nullopt,
451-
int kerning_factor = 0, bool warn_if_used = false)
445+
std::optional<int> kerning_factor = std::nullopt,
446+
bool warn_if_used = false)
452447
{
453448
if (hinting_factor <= 0) {
454449
throw py::value_error("hinting_factor must be greater than 0");
455450
}
451+
if (kerning_factor) {
452+
auto api = py::module_::import("matplotlib._api");
453+
auto warn = api.attr("warn_deprecated");
454+
warn("since"_a="3.11", "name"_a="text.kerning_factor", "obj_type"_a="rcParam");
455+
} else {
456+
kerning_factor = 0;
457+
}
456458

457459
PyFT2Font *self = new PyFT2Font();
458460
self->x = nullptr;
@@ -500,7 +502,7 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8,
500502
self->x = new FT2Font(open_args, hinting_factor, fallback_fonts, ft_glyph_warn,
501503
warn_if_used);
502504

503-
self->x->set_kerning_factor(kerning_factor);
505+
self->x->set_kerning_factor(*kerning_factor);
504506

505507
return self;
506508
}
@@ -1605,7 +1607,7 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
16051607
PyFT2Font__doc__)
16061608
.def(py::init(&PyFT2Font_init),
16071609
"filename"_a, "hinting_factor"_a=8, py::kw_only(),
1608-
"_fallback_list"_a=py::none(), "_kerning_factor"_a=0,
1610+
"_fallback_list"_a=py::none(), "_kerning_factor"_a=py::none(),
16091611
"_warn_if_used"_a=false,
16101612
PyFT2Font_init__doc__)
16111613
.def("clear", &PyFT2Font_clear, PyFT2Font_clear__doc__)

0 commit comments

Comments
 (0)