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

Fix: add Linux and custom font directories #1039

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/dev/analysis/txt-font-typeface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ Verdana to Arial. This aspect of a font is its *typeface*, as opposed to its
size (e.g. 18 points) or style (e.g. bold, italic).


.. admonition:: Custom fonts folder

|pp| will search for font files on each OS default directories. A list of custom folders can also be specified by setting the ``PYTHON_PPTX_FONT_DIRECTORY`` environment variable to a colon-separated list of the paths of each fonts folder.


Minimum viable feature
----------------------

Expand Down
11 changes: 11 additions & 0 deletions docs/user/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,14 @@ Dependencies
* lxml
* Pillow
* XlsxWriter (to use charting features)


.. admonition:: Note: font availability on Linux

On most Linux distros, default PowerPoint fonts are typically unavailable. Thus, you should install them manually by either:

- Installing ``ttf-mscorefonts-installer`` package (on Ubuntu).
- Copying font files from the ``C:\Windows\Fonts`` folder of an existing Windows machine.
- Manually installing the fonts following `this guide <https://wiki.debian.org/ppviewerFonts>`_.


40 changes: 36 additions & 4 deletions src/pptx/text/fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,26 @@ def _font_directories(cls):
Return a sequence of directory paths likely to contain fonts on the
current platform.
"""

font_dirs = []

# Colon-separated list of paths for python-pptx to find fonts
CUSTOM_DIRS_VAR_NAME = 'PYTHON_PPTX_FONT_DIRECTORY'
custom_dirs = os.getenv(CUSTOM_DIRS_VAR_NAME)

# Check it is not None, empty or whitespace
if custom_dirs and custom_dirs.strip():
font_dirs.extend(custom_dirs.split(':'))

if sys.platform.startswith("darwin"):
return cls._os_x_font_directories()
if sys.platform.startswith("win32"):
return cls._windows_font_directories()
raise OSError("unsupported operating system")
font_dirs.extend(cls._os_x_font_directories())
elif sys.platform.startswith("linux"):
font_dirs.extend(cls._linux_font_directories())
elif sys.platform.startswith("win32"):
font_dirs.extend(cls._windows_font_directories())
else:
raise OSError("unsupported operating system")
return font_dirs

@classmethod
def _iter_font_files_in(cls, directory):
Expand Down Expand Up @@ -84,6 +99,23 @@ def _os_x_font_directories(cls):
)
return os_x_font_dirs

@classmethod
def _linux_font_directories(cls):
"""
Return a sequence of directory paths in which fonts are
likely to be located on most Linux.
"""
linux_font_dirs = [
"/usr/share/fonts",
"/usr/local/share/fonts",
]
home = os.environ.get("HOME")
if home is not None:
linux_font_dirs.extend(
[os.path.join(home, ".local", "share", "fonts"), os.path.join(home, ".fonts")]
)
return linux_font_dirs

@classmethod
def _windows_font_directories(cls):
"""
Expand Down