From 5fc955939dd074beea4554b6e2b668061fb46073 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 16 Jul 2025 04:42:42 -0400 Subject: [PATCH] Don't set a default size for FT2Font In the interest of handling non-scalable fonts and reducing font initialization, drop the default size from the `FT2Font` constructor. Non-scalable fonts are sometimes used for bitmap-backed emoji fonts. When we start supporting collection fonts (`.ttc`), then setting a size is a waste, as we will just need to read the count of fonts within. The renderer method `Renderer.draw_text` always sets a size immediately after creating the font object, so this doesn't affect anything in most cases. Only the direct `FT2Font` tests need changes. --- doc/api/next_api_changes/behavior/30318-ES.rst | 9 +++++++++ lib/matplotlib/tests/test_ft2font.py | 7 ++++++- src/ft2font.cpp | 6 ------ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 doc/api/next_api_changes/behavior/30318-ES.rst diff --git a/doc/api/next_api_changes/behavior/30318-ES.rst b/doc/api/next_api_changes/behavior/30318-ES.rst new file mode 100644 index 000000000000..805901dcb21d --- /dev/null +++ b/doc/api/next_api_changes/behavior/30318-ES.rst @@ -0,0 +1,9 @@ +FT2Font no longer sets a default size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the interest of handling non-scalable fonts and reducing font initialization, the +`.FT2Font` constructor no longer sets a default size. Non-scalable fonts are sometimes +used for bitmap-backed emoji fonts. + +If metrics are important (i.e., if you are loading character glyphs, or setting a text +string), then explicitly call `.FT2Font.set_size` beforehand. diff --git a/lib/matplotlib/tests/test_ft2font.py b/lib/matplotlib/tests/test_ft2font.py index 0dc0667d0e84..b39df1f52996 100644 --- a/lib/matplotlib/tests/test_ft2font.py +++ b/lib/matplotlib/tests/test_ft2font.py @@ -188,8 +188,8 @@ def test_ft2font_clear(): def test_ft2font_set_size(): file = fm.findfont('DejaVu Sans') - # Default is 12pt @ 72 dpi. font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=1) + font.set_size(12, 72) font.set_text('ABabCDcd') orig = font.get_width_height() font.set_size(24, 72) @@ -757,6 +757,7 @@ def test_ft2font_get_kerning(left, right, unscaled, unfitted, default): def test_ft2font_set_text(): file = fm.findfont('DejaVu Sans') font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font.set_size(12, 72) xys = font.set_text('') np.testing.assert_array_equal(xys, np.empty((0, 2))) assert font.get_width_height() == (0, 0) @@ -778,6 +779,7 @@ def test_ft2font_set_text(): def test_ft2font_loading(): file = fm.findfont('DejaVu Sans') font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font.set_size(12, 72) for glyph in [font.load_char(ord('M')), font.load_glyph(font.get_char_index(ord('M')))]: assert glyph is not None @@ -818,11 +820,13 @@ def test_ft2font_drawing(): expected *= 255 file = fm.findfont('DejaVu Sans') font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font.set_size(12, 72) font.set_text('M') font.draw_glyphs_to_bitmap(antialiased=False) image = font.get_image() np.testing.assert_array_equal(image, expected) font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font.set_size(12, 72) glyph = font.load_char(ord('M')) image = np.zeros(expected.shape, np.uint8) font.draw_glyph_to_bitmap(image, -1, 1, glyph, antialiased=False) @@ -832,6 +836,7 @@ def test_ft2font_drawing(): def test_ft2font_get_path(): file = fm.findfont('DejaVu Sans') font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font.set_size(12, 72) vertices, codes = font.get_path() assert vertices.shape == (0, 2) assert codes.shape == (0, ) diff --git a/src/ft2font.cpp b/src/ft2font.cpp index ca8881d98c50..1d03ecf10b56 100644 --- a/src/ft2font.cpp +++ b/src/ft2font.cpp @@ -221,12 +221,6 @@ FT2Font::FT2Font(FT_Open_Args &open_args, if (open_args.stream != nullptr) { face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; } - try { - set_size(12., 72.); // Set a default fontsize 12 pt at 72dpi. - } catch (...) { - FT_Done_Face(face); - throw; - } // Set fallbacks std::copy(fallback_list.begin(), fallback_list.end(), std::back_inserter(fallbacks)); }