Skip to content

Font and text overhaul #30161

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

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8caff88
Remove ttconv backwards-compatibility code
anntzer May 3, 2025
c44db77
Fix center of rotation with rotation_mode='anchor'
Nov 26, 2024
f1cdc19
Merge pull request #29199 from WPurre/fixing-rotation-bug
QuLogic Jun 10, 2025
41cc933
Remove fallback code for glyph indices
QuLogic Jun 12, 2025
7dafe63
Merge pull request #30145 from QuLogic/remove-ttconv
QuLogic Jun 19, 2025
67d1a02
Merge pull request #30168 from QuLogic/no-glyph-fallback
QuLogic Jun 19, 2025
bb9aae4
Merge branch 'main' into text-overhaul
QuLogic Jun 19, 2025
a7fd524
Merge branch 'main' into text-overhaul
QuLogic Jul 7, 2025
389373e
ci: Preload existing test images from text-overhaul-figures branch
QuLogic Jun 30, 2025
4d47644
Merge pull request #30231 from QuLogic/preload-ci
QuLogic Jul 8, 2025
a018606
Add typing to AFM parser
QuLogic Jun 3, 2025
aff20cf
ci: Fix image preload with multiple conflicts
QuLogic Jul 8, 2025
572540d
Merge pull request #30274 from QuLogic/fix-preload
QuLogic Jul 9, 2025
f231f2e
Merge pull request #30134 from QuLogic/afm-typing
QuLogic Jul 9, 2025
7b4d725
Remove kerning_factor from tests
QuLogic Mar 28, 2025
8255ae2
Set text hinting to defaults
QuLogic Apr 9, 2025
89c054d
Update FreeType to 2.13.3
QuLogic Mar 27, 2025
7787153
Bump minimum meson-python to 0.13.2
QuLogic Apr 23, 2025
972a821
ci: Purge Strawberry Perl from Windows builders
QuLogic Jul 2, 2025
8839576
Merge branch 'main' into text-overhaul
QuLogic Jul 16, 2025
5fc9559
Don't set a default size for FT2Font
QuLogic Jul 16, 2025
7dae1e5
Merge pull request #30319 from QuLogic/ft2font-size
tacaswell Jul 16, 2025
7a628e5
Deprecate font_manager.is_opentype_cff_font
QuLogic Jul 18, 2025
42c108a
Deprecate setting text kerning factor to any non-None value
QuLogic Jul 17, 2025
3a0a773
TYP: Make glyph indices distinct from character codes
QuLogic Jun 3, 2025
c6e6904
Fix kerning of mathtext
QuLogic Jun 6, 2025
733cd7d
Update test images for previous changes
QuLogic Jul 24, 2025
56308af
Merge pull request #30143 from QuLogic/character-glyph-types
tacaswell Jul 31, 2025
a7f8e9b
Update test images for font/text overhaul
QuLogic Jul 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 20 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ install:
- micromamba env create -f environment.yml python=%PYTHON_VERSION% pywin32
- micromamba activate mpl-dev

before_test:
- git config --global user.name 'Matplotlib'
- git config --global user.email 'nobody@matplotlib.org'
- git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures
- git merge --no-commit text-overhaul-figures || true
# If there are any conflicts in baseline images, then pick "ours",
# which should be the updated images in the PR.
- ps: |
$conflicts = git diff --name-only --diff-filter=U `
lib/matplotlib/tests/baseline_images `
lib/mpl_toolkits/*/tests/baseline_images
if ($conflicts) {
git checkout --ours -- $conflicts
git add -- $conflicts
}
git status
# If committing fails, there were conflicts other than the baseline images,
# which should not be allowed to happen, and should fail the build.
- git commit -m "Preload test images from branch text-overhaul-figures"

test_script:
# Now build the thing..
- set LINK=/LIBPATH:%cd%\lib
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/cibuildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ jobs:
name: cibw-sdist
path: dist/

- name: Purge Strawberry Perl
if: startsWith(matrix.os, 'windows-')
run: Remove-Item -Recurse C:\Strawberry

- name: Build wheels for CPython 3.14
uses: pypa/cibuildwheel@95d2f3a92fbf80abe066b09418bbf128a8923df2 # v3.0.1
with:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,25 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Preload test images
run: |
git config --global user.name 'Matplotlib'
git config --global user.email 'nobody@matplotlib.org'
git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures
git merge --no-commit text-overhaul-figures || true
# If there are any conflicts in baseline images, then pick "ours",
# which should be the updated images in the PR.
conflicts=$(git diff --name-only --diff-filter=U \
lib/matplotlib/tests/baseline_images \
lib/mpl_toolkits/*/tests/baseline_images)
if [ -n "${conflicts}" ]; then
git checkout --ours -- ${conflicts}
git add -- ${conflicts}
fi
# If committing fails, there were conflicts other than the baseline images,
# which should not be allowed to happen, and should fail the build.
git commit -m 'Preload test images from branch text-overhaul-figures'

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ repos:
- id: check-docstring-first
exclude: lib/matplotlib/typing.py # docstring used for attribute flagged by check
- id: end-of-file-fixer
exclude_types: [svg]
exclude_types: [diff, svg]
- id: mixed-line-ending
- id: name-tests-test
args: ["--pytest-test-first"]
- id: no-commit-to-branch # Default is master and main.
- id: trailing-whitespace
exclude_types: [svg]
exclude_types: [diff, svg]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
hooks:
Expand Down
19 changes: 19 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ stages:
architecture: 'x64'
displayName: 'Use Python $(python.version)'

- bash: |
git config --global user.name 'Matplotlib'
git config --global user.email 'nobody@matplotlib.org'
git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures
git merge --no-commit text-overhaul-figures || true
# If there are any conflicts in baseline images, then pick "ours",
# which should be the updated images in the PR.
conflicts=$(git diff --name-only --diff-filter=U \
lib/matplotlib/tests/baseline_images \
lib/mpl_toolkits/*/tests/baseline_images)
if [ -n "${conflicts}" ]; then
git checkout --ours -- ${conflicts}
git add -- ${conflicts}
fi
# If committing fails, there were conflicts other than the baseline images,
# which should not be allowed to happen, and should fail the build.
git commit -m 'Preload test images from branch text-overhaul-figures'
displayName: Preload test images

- bash: |
choco install ninja
displayName: 'Install dependencies'
Expand Down
9 changes: 9 additions & 0 deletions doc/api/next_api_changes/behavior/30318-ES.rst
Original file line number Diff line number Diff line change
@@ -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.
7 changes: 7 additions & 0 deletions doc/api/next_api_changes/deprecations/30322-ES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Font kerning factor is deprecated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Due to internal changes to support complex text rendering, the kerning factor on fonts is
no longer used. Setting the ``text.kerning_factor`` rcParam (which existed only for
backwards-compatibility) to any value other than None is deprecated, and the rcParam will
be removed in the future.
4 changes: 4 additions & 0 deletions doc/api/next_api_changes/deprecations/30329-ES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``font_manager.is_opentype_cff_font`` is deprecated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is no replacement.
7 changes: 7 additions & 0 deletions doc/api/next_api_changes/development/30143-ES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Glyph indices now typed distinctly from character codes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, character codes and glyph indices were both typed as `int`, which means you
could mix and match them erroneously. While the character code can't be made a distinct
type (because it's used for `chr`/`ord`), typing glyph indices as a distinct type means
these can't be fully swapped.
29 changes: 9 additions & 20 deletions doc/users/prev_whats_new/whats_new_3.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,15 @@ triangle meshes.

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

.. plot::

import matplotlib.pyplot as plt

# Use old kerning values:
plt.rcParams['text.kerning_factor'] = 6
fig, ax = plt.subplots()
ax.text(0.0, 0.05, 'BRAVO\nAWKWARD\nVAT\nW.Test', fontsize=56)
ax.set_title('Before (text.kerning_factor = 6)')

Note how the spacing between characters is uniform between their bounding boxes
(above). With corrected kerning (below), slanted characters (e.g., AV or VA)
will be spaced closer together, as well as various other character pairs,
depending on font support (e.g., T and e, or the period after the W).
Due to an error in how kerning adjustments were applied, previous versions of Matplotlib
would under-correct kerning. This version will now correctly apply kerning (for fonts
supported by FreeType). To restore the old behavior (e.g., for test images), you may set
the ``text.kerning_factor`` rcParam to 6 (instead of 0). Other values have undefined
behavior.

With corrected kerning (below), slanted characters (e.g., AV or VA) will be spaced closer
together, as well as various other character pairs, depending on font support (e.g., T
and e, or the period after the W).

.. plot::

Expand Down
13 changes: 11 additions & 2 deletions extern/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ else
# must match the value in `lib/matplotlib.__init__.py`. Also update the docs
# in `docs/devel/dependencies.rst`. Bump the cache key in
# `.circleci/config.yml` when changing requirements.
LOCAL_FREETYPE_VERSION = '2.6.1'
LOCAL_FREETYPE_VERSION = '2.13.3'

freetype_proj = subproject(
f'freetype-@LOCAL_FREETYPE_VERSION@',
default_options: ['default_library=static'])
default_options: [
'default_library=static',
'brotli=disabled',
'bzip2=disabled',
'harfbuzz=disabled',
'mmap=auto',
'png=disabled',
'tests=disabled',
'zlib=internal',
])
freetype_dep = freetype_proj.get_variable('freetype_dep')
endif

Expand Down
4 changes: 3 additions & 1 deletion lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,8 @@ def __setitem__(self, key, val):
f"a list of valid parameters)") from err
except ValueError as ve:
raise ValueError(f"Key {key}: {ve}") from None
if key == "text.kerning_factor" and cval is not None:
_api.warn_deprecated("3.11", name="text.kerning_factor", obj_type="rcParam")
self._set(key, cval)

def __getitem__(self, key):
Expand Down Expand Up @@ -1329,7 +1331,7 @@ def _val_or_rc(val, *rc_names):
def _init_tests():
# The version of FreeType to install locally for running the tests. This must match
# the value in `meson.build`.
LOCAL_FREETYPE_VERSION = '2.6.1'
LOCAL_FREETYPE_VERSION = '2.13.3'

from matplotlib import ft2font
if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or
Expand Down
Loading
Loading