Skip to content
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

Improve ImageFont.freetype support for XDG directories on Linux #8135

Merged
merged 12 commits into from
Jun 22, 2024
1 change: 1 addition & 0 deletions Tests/test_imagefont.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@
# catching syntax like errors
monkeypatch.setattr(sys, "platform", platform)
if platform == "linux":
monkeypatch.setenv("XDG_DATA_HOME", "/home/__pillow__/.local/share")

Check warning on line 567 in Tests/test_imagefont.py

View check run for this annotation

Codecov / codecov/patch

Tests/test_imagefont.py#L567

Added line #L567 was not covered by tests
mamg22 marked this conversation as resolved.
Show resolved Hide resolved
monkeypatch.setenv("XDG_DATA_DIRS", "/usr/share/:/usr/local/share/")

def fake_walker(path: str) -> list[tuple[str, list[str], list[str]]]:
Expand Down
8 changes: 8 additions & 0 deletions docs/releasenotes/10.4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecat
API Changes
===========

ImageFont.truetype
^^^^^^^^^^^^^^^^^^

:py:func:`~PIL.ImageFont.truetype` now searches for fonts in the directory indicated
by the ``XDG_DATA_HOME`` environment variable in addition to those specified in
``XDG_DATA_DIRS``. Additionally, the default for ``XDG_DATA_DIRS`` has been updated
to match the freedesktop spec.
mamg22 marked this conversation as resolved.
Show resolved Hide resolved

TODO
^^^^

Expand Down
32 changes: 22 additions & 10 deletions src/PIL/ImageFont.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,15 @@

:param font: A filename or file-like object containing a TrueType font.
If the file is not found in this filename, the loader may also
search in other directories, such as the :file:`fonts/`
directory on Windows or :file:`/Library/Fonts/`,
:file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
macOS.
search in other directories, such as:

* The :file:`fonts/` directory on Windows,
* :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/`
and :file:`~/Library/Fonts/` on macOS.
* :file:`~/.local/share/fonts`, :file:`/usr/local/share/fonts`,
and :file:`/usr/share/fonts` on Linux; or those specified by
the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables
for user-installed and system-wide fonts, respectively.

:param size: The requested size, in pixels.
:param index: Which font face to load (default is first available face).
Expand Down Expand Up @@ -837,12 +842,19 @@
if windir:
dirs.append(os.path.join(windir, "fonts"))
elif sys.platform in ("linux", "linux2"):
lindirs = os.environ.get("XDG_DATA_DIRS")
if not lindirs:
# According to the freedesktop spec, XDG_DATA_DIRS should
# default to /usr/share
lindirs = "/usr/share"
dirs += [os.path.join(lindir, "fonts") for lindir in lindirs.split(":")]
data_home = os.environ.get("XDG_DATA_HOME")
if not data_home:

Check warning on line 846 in src/PIL/ImageFont.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageFont.py#L845-L846

Added lines #L845 - L846 were not covered by tests
# The freedesktop spec defines the following default directory for
# when XDG_DATA_HOME is unset or empty. This user-level directory
# takes precedence over system-level directories.
data_home = os.path.expanduser("~/.local/share")
dirs.append(os.path.join(data_home, "fonts"))

Check warning on line 851 in src/PIL/ImageFont.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageFont.py#L850-L851

Added lines #L850 - L851 were not covered by tests

data_dirs = os.environ.get("XDG_DATA_DIRS")
if not data_dirs:

Check warning on line 854 in src/PIL/ImageFont.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageFont.py#L853-L854

Added lines #L853 - L854 were not covered by tests
# Similarly, defaults are defined for the system-level directories
data_dirs = "/usr/local/share:/usr/share"
dirs += [os.path.join(ddir, "fonts") for ddir in data_dirs.split(":")]

Check warning on line 857 in src/PIL/ImageFont.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageFont.py#L856-L857

Added lines #L856 - L857 were not covered by tests
elif sys.platform == "darwin":
dirs += [
"/Library/Fonts",
Expand Down
Loading