diff --git a/docs/dev/analysis/txt-font-typeface.rst b/docs/dev/analysis/txt-font-typeface.rst index 556a3c71..b27d9fab 100644 --- a/docs/dev/analysis/txt-font-typeface.rst +++ b/docs/dev/analysis/txt-font-typeface.rst @@ -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 ---------------------- diff --git a/docs/user/install.rst b/docs/user/install.rst index b376d58e..3b5c7ea7 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -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 `_. + + diff --git a/src/pptx/text/fonts.py b/src/pptx/text/fonts.py index 5ae054a8..78e836d5 100644 --- a/src/pptx/text/fonts.py +++ b/src/pptx/text/fonts.py @@ -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): @@ -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): """