Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Get all available fonts on the system using MatPlotLib and FontTools with Python 3.8
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 22 16:16:46 2020
@author: ToshY
One of the more "reliable" ways to check for fonts on the current system with the help of MatPlotLib (and FontTools).
Returns list of dictonaries, where each dictonary denotes a single font, with a Path object, the name, the font family
and the style.
Tested on Win10 & Ubu18.04 with Python 3.8.3 + Matplotlib 3.3.2 + FontTools 4.16.1
"""
from matplotlib import font_manager
from pathlib import Path
from fontTools.ttLib import TTFont
from contextlib import redirect_stderr
def get_font_name(font_path):
font = TTFont(font_path, ignoreDecompileErrors=True)
with redirect_stderr(None):
names = font['name'].names
details = {}
for x in names:
if x.langID in [0, 1033, 1041]:
try:
details[x.nameID] = x.toUnicode()
except UnicodeDecodeError:
details[x.nameID] = x.string.decode(errors='ignore')
continue
return {'name':details[4],'family':details[1],'style':details[2]}
fonts = []
for x in font_manager.findSystemFonts():
pfont = Path(x)
if pfont.suffix.lower() in ['.ttc']:
continue
fonts.append({'path': pfont.resolve()})
# For some reason findSystemFonts returns duplicates (atleast on Win10)
unique_font_list = list({v['path']:v for v in fonts}.values())
fonts_unique = []
for y in unique_font_list:
fonts_unique.append({**y, **get_font_name(str(list(y.values())[0]))})
available_fonts = sorted(fonts_unique, key=lambda k: k['name'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment